firmware/br-ext-chip-ambarella/board/s3l/kernel/patches/0000-ambarella-s3l-linux-3....

137648 lines
4.4 MiB
Raw Blame History

diff --git a/Documentation/arm/ambarella/self-refresh.txt b/Documentation/arm/ambarella/self-refresh.txt
new file mode 100644
index 00000000..209b8eea
--- /dev/null
+++ b/Documentation/arm/ambarella/self-refresh.txt
@@ -0,0 +1,140 @@
+
+Copyright (C) 2016-2019, Ambarella, Inc.
+Author: Cao Rongrong <rrcao@ambarella.com>
+
+
+Introduction
+============
+
+The kernel supports up to four system sleep states generically.
+From shallowest to deepest, they are:
+1) freeze: Suspend-To-Idle / ACPI S0
+2) standby: Standby / Power-On Suspend / ACPI S1
+3) mem: Suspend-To-RAM / Self-Refresh / STR / ACPI S3
+4) disk: Suspend-To-Disk / STD / ACPI S4
+
+For details, pelase see Documentation/powr/states.txt
+
+Here we just talk about "mem", i.e., Self-Refresh (abbreviated as SR).
+
+In short words, when system is in SR, all the HWs except for DRAM and PWC are
+powered off.
+
+
+
+SR and DRAM
+============
+
+At present we can support SR with DDR3 and LPDDR3, other DRAM types are not
+tested, yet.
+
+One of the differences between DDR3 and LPDDR3 is that DDR3 has a "RESET" pin
+while LPDDR3 doesn't have. When entering into SR, the "RESET" pin must be pulled
+high. Unfortunately, when in SR state, the SoC will be powered off and pull the
+the "RESET" pin low, so we have to add a workaround with the help of HW design,
+i.e., using a GPIO to control the triode to cut off the "RESET" signal to DRAM.
+
+Different boards design may use different GPIO, and both BST and Kernel need to
+know which GPIO is used to cut off the "RESET" signal.
+1) For BST, we define the GPIO in .ini file by "DRAM_RESET_CTRL_GPIO",
+ please see "ini" section below.
+2) For Kernel, we define the GPIO in .dts file by "ambarella,dram-reset-ctrl",
+ please see "Device Tree" section below.
+
+Note:
+ Although LPDDR3 doesn't have the "RESET" pin, you also need to define the GPIO
+ in .ini file, because this GPIO definition, i.e., "DRAM_RESET_CTRL_GPIO", also
+ acts as another role, that is, tell BST to support SR.
+ In other words, if "DRAM_RESET_CTRL_GPIO" is NOT defined in .ini file, BST will
+ boot system directly, but not check if it's cold boot or resume from SR when
+ powered on.
+ For LPDDR3, you can define "DRAM_RESET_CTRL_GPIO" as any meaningful GPIO as
+ long as this GPIO does not affect system booting.
+
+[!!!IMPORTANT!!!]
+ IF SELF-REFRESH IS NOT USED, "DRAM_RESET_CTRL_GPIO" MUST BE REMOVED FROM .ini
+ FILE, OTHERWISE SYSTEM MAY NOT BOOT UP OR REBOOT SUCCESSFULLY.
+
+
+
+SR and PWC (Power Control)
+==========================
+
+SR must co-work with PWC, and there are two options to use PWC:
+1) internal PWC, but not all SoCs have internal PWC
+2) external PWC (MCU)
+PS: for those SoCs without internal PWC, you have to use external MCU.
+
+If the board design is to use external MCU for power sequence control, the SoC
+needs to communicate with the MCU through a GPIO, and the protocol is:
+1) SoC keeps the GPIO high 100ms to notify MCU to enter self-refresh. After
+100ms, SoC should keep the GPIO low.
+2) MCU notifies SoC the state after powered up:
+2.1) if cold boot, MCU keeps the GPIO high.
+2.2) if resume from SR, MCU keeps the GPIO low.
+
+Different boards design may use different GPIO, and both BST and Kernel need to
+know which GPIO is used to communicate with the external MCU.
+1) For BST, we define the GPIO in .ini file by "MCU_NOTIFY_GPIO",
+ please see "ini" section below.
+2) For Kernel, we define the GPIO in .dts file by "ambarella,gpio-notify-mcu",
+ please see "Device Tree" section below.
+
+Note:
+ It's allowed to either use two separate GPIOs or use one GPIO to communicate
+ between SoC and MCU, it's determined by the MCU firmware.
+
+
+
+Driver Configuration
+====================
+
+Power management options --->
+ [*] Suspend to RAM and standby
+ [*] User space wakeup sources interface
+ (100) Maximum number of user space wakeup sources (0 = no limit)
+ -*- Device power management core functionality
+
+
+
+Device Tree
+===========
+
+Please see Documentation/devicetree/bindings/arm/ambarella.txt
+ -> 2) - Informational node -> ii) /chosen
+
+
+
+ini
+===
+
+In .ini file, there are two fields related to SR:
+
+1) "DRAM_RESET_CTRL_GPIO", e.g., <DRAM_RESET_CTRL_GPIO value="5"/>
+ No matter DDR3 or LPDDR3, this field has to be set as long as SR is used.
+ Please see the "Note" in "SR and DRAM" section.
+
+2) "MCU_NOTIFY_GPIO", e.g., <MCU_NOTIFY_GPIO value="33"/>
+ This filed need to be set only when external MCU is used. If using internal
+ PWC, this filed must NOT be set.
+
+
+
+Usage
+=====
+
+1) Entering into SR
+root@/#echo mem > /sys/power/state
+
+2) Resume from SR by power button
+Press the button directly
+
+3) Resume from SR by RTC
+root@/#echo enabled > /sys/class/rtc/rtc0/device/power/wakeup
+root@/#rtcwake -s 10 -m mem
+PS:
+ a) this is available only when using internal PWC.
+ b) rtc,wakeup has to be added into rtc node in DTS.
+
+
+
diff --git a/Documentation/devicetree/bindings/arm/ambarella.txt b/Documentation/devicetree/bindings/arm/ambarella.txt
new file mode 100644
index 00000000..64a25fbf
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/ambarella.txt
@@ -0,0 +1,1434 @@
+Ambarella Platforms Device Tree Bindings
+----------------------------------------
+
+(c) 2013 Cao Rongrong <rrcao@ambarella.com>, Ambarella,Inc.
+
+
+Table of Contents
+=================
+
+ I - Introduction
+
+ II - Ambarella Node definiton
+ 1) - Root node
+ 2) - Informational node
+ 3) - CPUS node
+ 4) - TWD node
+ 5) - APB/AHB/AXI/RCT node
+ 6) - TIMER node
+ 7) - INTERRUPT node
+ 8) - DMA node
+ 9) - NAND node
+ 10) - SPINOR node
+ 11) - I2S node
+ 12) - UDC node
+ 13) - EHCI/OHCI node
+ 14) - SD/MMC node
+ 15) - ETHERNET node
+ 16) - SPI node
+ 17) - SLAVE SPI node
+ 18) - USBPHY node
+ 19) - PINCTRL node
+ 20) - GPIO node
+ 21) - UART node
+ 22) - I2C node
+ 23) - I2CMUX node
+ 24) - PWM node
+ 25) - ADC node
+ 26) - IR node
+ 27) - WDT node
+ 28) - RTC node
+ 29) - CRYPTO node
+ 30) - IAV node
+ 31) - SOUND node
+
+ III - Misc Node definition
+ 1) - BOGUS BUS node
+ 2) - GPIO KEY node
+ 3) - ADC KEY node
+ 4) - PWM BACKLIGHT node
+
+
+
+I - Introduction
+++++++++++++++++
+
+
+1) Reference
+------------
+ a) Documentation/devicetree/booting-without-of.txt
+ b) Documentation/devicetree/usage-model.txt
+ c) http://devicetree.org/Device_Tree_Usage
+ d) https://wiki.freebsd.org/FlattenedDeviceTree
+ e) http://xillybus.com/tutorials/device-tree-zynq-1
+
+2) Abbreviations
+----------------
+ a) FDT: Flattened Device Tree
+ b) OF: Open Firmware
+ c) DTS: Device Tree Source
+ d) DTB: Device Tree Blob
+ e) DTC: Device Tree Compiler
+
+3) Summary
+----------
+Device Tree is essentially a data structure in byte code format (that is, not
+human-readable) which contains information that is helpful to the kernel when
+booting up. The boot loader copies that chunk of data into a known address in
+the RAM before jumping to the kernel's entry point.
+
+The device tree comes in three forms:
+ DTS: the source of FDT, which is a plain txt file.
+ DTB: the binary blob of FDT, which will be copied to RAM.
+ /proc/device-tree: a file system in a running Linux, normally for debug.
+
+In a normal flow, the DTS file is edited and compiled into a DTB file using a
+special compiler named DTC. You can find DTC in the Linux kernel sources, or
+download it by "git clone git://www.jdl.com/software/dtc.git dtc".
+
+For Ambarella, the DTS for specific board is:
+ $PROJECT/ambarella/boards/$BOARD/bsp/$BOARD.dts
+which will include the DTS for specific ambarella SoC chip:
+ arch/arm/boot/dts/ambarella-$SoC.dtsi
+Normally, it's NOT recommended to modify the DTS for ambarella SoC chip.
+
+
+II - Node definiton
++++++++++++++++++++
+
+
+1) - Root node
+==============
+
+
+i) Properties
+-------------
+Required properties:
+- model: "Ambarella <SoC> <BOARD>", can be modified according to the board.
+- compatible: should be "ambarella,<SoC>";
+- interrupt-parent: <&intc>, or <&gic>, See Interrupt below for more detail.
+
+ii) Example
+----------
+/ {
+ model = "Ambarella S2L Hawthorn Board";
+ compatible = "ambarella,hawthorn", "ambarella,s2l";
+ interrupt-parent = <&intc>;
+ }
+
+
+2) - Informational node
+========================
+
+
+i) /aliases
+-----------
+Please see http://devicetree.org/Device_Tree_Usage#aliases_Node
+
+ii) /chosen
+-----------
+Please see http://devicetree.org/Device_Tree_Usage#chosen_Node
+ Documentation/devicetree/booting-without-of.txt
+
+iii) /memory
+------------
+ Please see Documentation/devicetree/booting-without-of.txt
+ For Ambarella, the /memory node will be overwritten in Amboot.
+
+iv) Example
+-----------
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ nand = &nand0;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ spi0 = &spi0;
+ spi1 = &spi1;
+ spinor = &spinor0;
+ ethernet0 = &mac0;
+ };
+
+ /* the memory node will be overwritten in Amboot,
+ * here is just the default value. */
+ memory {
+ device_type = "memory";
+ reg = <0x00200000 0x07e00000>; /* 126M */
+ };
+
+ chosen {
+ bootargs = "console=ttyS0 ubi.mtd=lnx root=ubi0:rootfs rw rootfstype=ubifs init=/linuxrc";
+ };
+
+
+3) - CPUS node
+==============
+
+
+i) Reference
+------------
+Please see Documentation/devicetree/bindings/arm/cpus.txt
+
+ii) Properties
+- amb,core-div: this prop should be 1 or 2, this specified the divide of gclk_core from pll_out_core,
+ for s2e and s5, this value should be 1; and for s2l, s3l, this should be 2. If you don't add this prop,
+ the divide for gclk_core is 2 as default.
+- cpufreq_tbl: Table of frequencies gclk_cortex and gclk_core could be transitioned
+ into, in the unit of nanoseconds.
+- clock-latency: Specify the possible maximum transition latency for clock, in
+ unit of nanoseconds.
+
+
+4) - TWD node
+=============
+
+
+i) Reference
+------------
+Please see Documentation/devicetree/bindings/arm/twd.txt
+
+ii) Description
+---------------
+This node is only available for SoC chip that supports per-cpu local timer,
+i.e., S2.
+
+
+5) - APB/AHB/AXI/RCT node
+=========================
+
+
+i) Summary
+----------
+The apb/ahb/axi/rct nodes represent the BUS inside the SoC, each node may
+contain many device nodes which connect to the corresponding bus.
+PS: RCT is not a real bus, just means a serial of registers address space.
+
+ii) Properties
+--------------
+Required properties:
+- compatible: should be "simple-bus".
+- #address-cells: should be 1.
+- #size-cells: should be 1.
+- reg: address range of the registers in each bus.
+- ranges:
+
+
+6) - TIMER node
+===============
+
+
+i) Properties
+-------------
+Required properties:
+- compatible: should be
+ a) "ambarella,clock-source": for timer used as clock source.
+ b) "ambarella,clock-event": for timer used as clock event.
+- reg : specifies base physical address and size of the registers. The last
+ pair for the timer-ctrl register which is shared by all of the timers.
+- interrupts: the interrupt for this timer.
+- ctrl-offset: bit offset in timer-ctrl reg for this timer.
+
+ii) Example
+-----------
+ timer7: timer@e800b064 {
+ compatible = "ambarella,clock-source";
+ reg = <0xe800b064 0x10 0xe800b030 0x4>;
+ interrupts = <62 0x1>;
+ ctrl-offset = <24>; /* bit offset in timer-ctrl reg */
+ };
+
+
+7) - INTERRUPT node
+===================
+
+
+i) Reference
+------------
+Please see Documentation/devicetree/bindings/interrupt-control/interrupts.txt
+
+ii) Properties
+--------------
+a) Ambarella VIC:
+Required properties:
+- compatible: should be "ambarella,vic".
+- interrupt-controller: marks the node as an interrupt controller
+- #interrupt-cells: should be 2, specifies the number of cells to define the
+ interrupts. The first cell defines the index of the interrupt within the
+ controller, while the second cell is used to specify any of the following
+ flags:
+ 1 = low-to-high edge triggered.
+ 2 = high-to-low edge triggered.
+ 4 = active high level-sensitive.
+ 8 = active low level-sensitive.
+- reg: specifies base physical address and size of the registers.
+
+b) GIC:
+Please see Documentation/devicetree/bindings/arm/gic.txt
+
+iii) Example
+------------
+a) Ambarella VIC:
+ intc: interrupt-controller@e0003000 {
+ compatible = "ambarella,vic";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0xe0003000 0x1000>,
+ <0xe0010000 0x1000>,
+ <0xe001c000 0x1000>;
+ };
+
+b) GIC:
+ gic: interrupt-controller@f0001000 {
+ compatible = "arm,cortex-a9-gic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0xf0001000 0x1000>,
+ <0xf0000100 0x0100>;
+ };
+
+
+8) - DMA node
+=============
+
+
+i) Properties
+-------------
+Required properties:
+- compatible: should be "ambarella,dma".
+- reg: specifies base physical address and size of the registers.
+- interrupts: the interrupt for the DMA controller.
+- #dma-cells: Must be at least 1. Used to provide DMA controller
+ specific information. See DMA client binding below for
+ more details.
+- dma-channels: Number of DMA channels supported by the controller.
+- dma-requests: Number of DMA requests signals supported by the
+ controller.
+- dma-trans-type: specifies the dma channel use type.
+ 0 for memcpy, 1 for slave.
+
+Optional properties:
+- amb,copy-align: specifies alignment requirement for previous chips.
+- amb,support-prs: should be specified for SoC that supports PAUSE/RESUME/STOP.
+- dma-channel-sel: should be specified for Soc that support dma channel sel.
+ different value is used for selecting the device.
+ e.g., 0 for ssi0_tx, 1 for ssi0_rx, 10 for i2s_tx, 11 for i2s_rx.
+
+ii) Example
+-----------
+ dma@e0005000 {
+ compatible = "ambarella,dma";
+ reg = <0xe0005000 0x1000>;
+ interrupts = <15 0x4>;
+ #dma-cells = <2>;
+ dma-channels = <8>;
+ dma-requests = <12>;
+ dma-trans-type = <1 1 0 0 1 1 1 1>; /* 0-memcpy ,1-slave*/
+ dma-channel-sel = <4 5 0 0 8 9 11 10>;
+ };
+
+
+9) - NAND node
+==============
+
+
+i) Reference
+------------
+Please see Documentation/devicetree/bindings/mtd/nand.txt
+
+ii) Properties
+--------------
+Required properties:
+- compatible: should be "ambarella,nand".
+- #address-cells: should be 1.
+- #size-cells: should be 1.
+- reg: specifies base physical address and size of the registers.
+- interrupts: the interrupt for the NAND controller.
+
+Optional properties:
+- nand-on-flash-bbt: please see Reference.
+- amb,enable-wp: specifies to enable write protection
+- amb,no-bch: should be specified for SoC without BCH supported.
+- amb,use-2x-pll: should be specified only for A5S.
+- amb,soft-ecc: specifies to use software ECC instead of hardware ECC, the
+ value should be as:
+ 1 = 1 bit software ECC
+ 6 = 6 bit software ECC
+ 8 = 8 bit software ECC
+- amb,timing: an integer array with size 6, the array is used to specify the
+ NAND timing, like tcls/tals/tcs/..., which can be found in NAND datasheet.
+ Please note that this property is provided by Amboot in runtime.
+
+iii) Subnode
+------------
+Please see Documentation/devicetree/bindings/mtd/partition.txt, and please
+note that the subnodes for partitions are provided by Amboot in runtime.
+
+iv) Example
+-----------
+ nand0: nand@e0001000 {
+ compatible = "ambarella,nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xe0001000 0x1000>, /* fio reg address */
+ <0xe0012000 0x1000>, /* fdma reg address */
+ <0xe0000000 0x4>; /* fifo base */
+ interrupts = <16 0x4>, /* fio_cmd_irq */
+ <17 0x4>, /* fio_dma_irq */
+ <33 0x4>; /* fdma_irq */
+ nand-on-flash-bbt;
+ /* amb,soft-ecc = <1>; */
+ /* amb,enable-wp; */
+ };
+
+
+10) - SPINOR node
+=================
+
+
+i) Properties
+-------------
+Required properties:
+- compatible: should be "ambarella,spinor".
+- reg: specifies base physical address and size of the registers.
+
+ii) Example
+-----------
+ spinor0: spinor@e0031000 {
+ compatible = "ambarella,spinor";
+ reg = <0xe0031000 0x2ff>, /* spi nor controller */
+ <0xe0005300 0x20>; /* dma reg */
+ };
+
+
+11) - I2S node
+==============
+
+
+i) Properties
+-------------
+Required properties:
+- compatible: should be "ambarella,i2s".
+- reg: specifies base physical address and size of the registers.
+- pinctrl-names: should contain only one value - "default".
+- pinctrl-0: pin control group to be used for this controller.
+- amb,i2s-channels: should be one of these values: 2, 4, 6.
+- amb,default-mclk: specifies the initial mclk frequency in HZ.
+
+ii) Example
+-----------
+ i2s0: i2s@e001a000 {
+ compatible = "ambarella,i2s";
+ reg = <0xe001a000 0x1000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_pins>;
+ amb,i2s-channels = <2>;
+ amb,default-mclk = <12288000>;
+ };
+
+
+12) - UDC node
+==============
+
+
+i) Properties
+-------------
+Required properties:
+- compatible: should be "ambarella,udc".
+- reg: specifies base physical address and size of the registers.
+- interrupts: the interrupt for the UDC controller.
+- amb,usbphy: specifies the phandle to USB PHY.
+
+Optional properties:
+- amb,dma-addr-fix: should be specified only for S2.
+
+ii) Example
+-----------
+ udc@e0006000 {
+ compatible = "ambarella,udc";
+ reg = <0xe0006000 0x2000 0xec1702cc 0x4>;
+ interrupts = <4 0x4>;
+ amb,usbphy = <&usbphy>;
+ };
+
+
+13) - EHCI/OHCI node
+====================
+
+
+i) Properties
+-------------
+Required properties:
+- compatible: should be "ambarella,ehci", or "ambarella,ohci".
+- reg: specifies base physical address and size of the registers.
+- interrupts: the interrupt for the EHCI/OHCI controller.
+- amb,usbphy: specifies the phandle to USB PHY.
+
+Optional properties:
+- amb,dma-addr-fix: should be specified only for S2.
+
+ii) Example
+-----------
+ ehci@e0018000 {
+ compatible = "ambarella,ehci";
+ reg = <0xe0018000 0x1000>;
+ interrupts = <39 0x4>;
+ amb,usbphy = <&usbphy>;
+ };
+
+ ohci@e0019000 {
+ compatible = "ambarella,ohci";
+ reg = <0xe0019000 0x1000>;
+ interrupts = <44 0x4>;
+ amb,usbphy = <&usbphy>;
+ status = "disabled";
+ };
+
+
+14) - SD/MMC node
+=================
+
+
+i) Reference
+------------
+Please see Documentation/devicetree/bindings/mmc/mmc.txt
+
+ii) Properties
+--------------
+Required properties:
+- compatible: should be "ambarella,sdmmc".
+- reg: specifies base physical address and size of the registers.
+- #address-cells: should be 1.
+- #size-cells: should be 0.
+- interrupts: the interrupt for the SD controller.
+- amb,clk-name: specifies the PLL name of this SD controller, should be one
+ of these strings: "gclk_sd", "gclk_sdio", "gclk_sdxc".
+- amb,wait-tmo: specifies the timeout in millisecond to wait for CMD complete.
+- amb,switch-vol-tmo: specifies the timeout to enable clk after switch voltage
+ from 3.3v to 1.8v.
+- amb,max-blk-size: specifies the maximal block size, should be multiple of 4k.
+
+Optional properties:
+- amb,dma-addr-fix: should be specified only for S2.
+- amb,soft-phy: should be specified for SD controllers to adjust timing base on
+ SD phy.
+- amb,phy-timing: an integer array which is used to specify the SD phy timing,
+ the size of the array is different according to corresponding phy register
+ for each chips or SD controllers, and the values are gotten by SD shmoo in
+ Amboot.
+ For the SD controller to ajust timing base on SD controller, like S3L and later
+ chip, the array is orgnized as: <mode SD_DELAY_SEL_L SD_DELAY_SEL_H>;
+ For the SD controller to ajust timing base on SD phy, like S2E SD0, S2L, S3L, the
+ array is orgnized as: <mode phy_ctrl0_val latency_ctrl_val>;
+ For the SD controller only supporting ms delay mux, like S2E SD1, the array
+ is orgnized as: <mode ms_delay_ctrl_mask ms_delay_ctrl_val>;
+ Here mode is the ORed value of SD card working modes like sdr104, ddr50 and
+ etc., and the later 2 items are values written to corresponding phy registers.
+ Following is the definition of each bits for mode:
+ bit0: specify the default phy timing setting, so bit0 must be reserved as 1, and
+ followed by default phy timing setting. PS: it's a MUST to define the default phy
+ timing setting with bit0 set, and it MUST be placed in the first row.
+ bit1: MMC HS; bit2: SD HS;
+ bit3: SDR12; bit4: SDR25; bit5: SDR50; bit6: SDR104; bit7: DDR50
+ bit8: MMC HS200
+ In fact, the definition for each bit of mode comes from the following
+ definition which are defined in include/linux/mmc/host.h:
+ #define MMC_TIMING_LEGACY 0
+ #define MMC_TIMING_MMC_HS 1
+ #define MMC_TIMING_SD_HS 2
+ #define MMC_TIMING_UHS_SDR12 3
+ #define MMC_TIMING_UHS_SDR25 4
+ #define MMC_TIMING_UHS_SDR50 5
+ #define MMC_TIMING_UHS_SDR104 6
+ #define MMC_TIMING_UHS_DDR50 7
+ #define MMC_TIMING_MMC_HS200 8
+
+Example for ajusting timing base sd controller on s3l platform:
+ sdmmc0: sdmmc0@e0002000 {
+ compatible = "ambarella,sdmmc";
+ reg = <0xe0002000 0x1000>,
+ <0xe0001000 0x80>;/* fio reg address */
+ amb,max-blk-size = <131072>; /* valid value: 4K<<n */
+ amb,soft-phy;
+ amb,phy-timing = <0x00000007 0x00000000 0x00000000>,/*HS 50M and 25M*/
+ /*sdr25 50M,sdr50 100M,sdr104 120M*/
+ <0x00000078 0x10410400 0x00904104>,
+ <0x00000080 0x38E38E00 0x0238E38E>;/*DDR50 50M*/
+ slot@0 {
+
+ };
+ };
+
+
+Example for ajusting timing base sd phy on s3l platform:
+ sdmmc0: sdmmc0@e0002000 {
+ compatible = "ambarella,sdmmc";
+ reg = <0xe0002000 0x1000>,
+ <0xe0001000 0x80>;/* fio reg address */
+ <0xec1704c0 0x8>;/*should specify the phy register*/
+
+ amb,soft-phy;
+ amb,phy-timing = <0x00000001 0x04070000 0x00000000>,
+ /*sdr12 24M,sdr25 50M,sdr50 100M*/
+ <0x00000038 0x00000003 0x00001111>,
+ <0x00000040 0x00000005 0x00002222>,/*sdr104 200M*/
+ <0x00000080 0x000C0005 0x00000000>;/*ddr50 50M*/
+ slot@0 {
+
+ };
+ };
+
+iii) Subnode
+------------
+The SD/MMC node should contain subnodes which represent the slot belong to
+this controller.
+
+The unit address of subnodes should be its index of the slot. And the subnode
+should contain the following properties.
+- reg: index of the slot, normally the same as the unit address.
+- global-id: specify the global id for each slot, it should be unique for all
+ of the slots.
+- amb,fixed-cd: should be specified if no cd pin, 0: no sd card, 1: sd card is
+always present
+- amb,fixed-wp: should be specified if no wp pin, 0: write-able, 1: read-only
+- amb,caps-adma: should be specified if hardware supports ADMA.
+- amb,caps-ddr: should be specified if hardware supports DDR.
+- no-1-8-v: should be specified if the slot don't have 1.8V circuit.
+- v18-gpios: specifies the GPIO to switch to the 1.8V power if existed.
+- pwr-gpios: specifies the GPIO to turn on/off the power for the SD/MMC card.
+- amb,force-gpio: force the SD/MMC pins to switch to GPIO mode when in idle,
+ should be specified only for A5S SDIO slot.
+- pinctrl-names: should contain only one value - "default".
+- pinctrl-0: pin control group to be used for this controller.
+- properties provided by Kernel, please see Reference above.
+
+iv) Example
+-----------
+ sdmmc0@e0002000 {
+ compatible = "ambarella,sdmmc";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe0002000 0x1000>,
+ <0xe0001000 0x80>; /* fio reg address */
+ interrupts = <18 0x4>;
+ amb,clk-name = "gclk_sd";
+ amb,wait-tmo = <2500>; /* in millisecond */
+ amb,max-blk-size = <131072>; /* valid value: 4K<<n */
+
+ slot@0 {
+ reg = <0>;
+ max-frequency = <48000000>;
+ bus-width = <8>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_pins_8bit>;
+ amb,caps-adma;
+ cap-sdio-irq;
+ };
+ };
+
+
+15) - ETHERNET node
+===================
+
+
+i) Properties
+-------------
+Required properties:
+- compatible: should be "ambarella,eth".
+- #address-cells: should be 1.
+- #size-cells: should be 0.
+- reg: specifies base physical address and size of the registers.
+- interrupts: the interrupt for the ethernet controller.
+
+Optional properties:
+- pwr-gpios: specifies the GPIO to control PHY power.
+- rst-gpios: specifies the GPIO to reset PHY.
+- amb,support-gmii: should be specified if hardware supports GMII.
+- amb,tx-ring-size: specifies the Tx ring buffer size.
+- amb,rx-ring-size: specifies the Rx ring buffer size.
+- amb,fixed-speed: should be specified if connecting without PHY.
+- amb,ipc-tx: should be specified if hardware supports Tx checksum.
+- amb,ipc-rx: should be specified if hardware supports Rx checksum.
+- amb,dump-tx: specifies to dump Tx buffer, for debug purpose.
+- amb,dump-rx: specifies to dump Rx buffer, for debug purpose.
+- amb,dump-rx-free: specifies to free buffer after dumped.
+- amb,dump-rx-all: specifies to dump all buffers without filter.
+- amb,mdio-gpio: specifies using mdio gpio to access phy.
+- amb,clk-src: specifies the clk source for gtx_clk, 0:external clk, 1:internal clk.
+- amb,clk-invert: specifies to invert the clk for ethernet, 0: no invert, 1: invert
+- amb,clk-dir: specifies the ref clk direction from PHY, 1: set direction of xx_enet_clk_rx as output from ambarella chip,
+ 0: set direction of xx_enet_clk_rx as output from external phy.
+ii) Example
+-----------
+ mac0: ethernet@e000e000 {
+ compatible = "ambarella,eth";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe000e000 0x2000>;
+ interrupts = <27 0x4>;
+ amb,tx-ring-size = <32>;
+ amb,rx-ring-size = <64>;
+ amb,ipc-tx;
+ amb,ipc-rx;
+ };
+
+
+16) - SPI node
+===============
+
+
+i) Reference
+------------
+Please see Documentation/devicetree/bindings/spi/spi-bus.txt
+
+
+ii) Properties
+--------------
+Required properties:
+- compatible: should be "ambarella,spi".
+- #address-cells: should be 1.
+- #size-cells: should be 0.
+- reg: specifies base physical address and size of the registers.
+- interrupts: the interrupt for the SPI controller.
+- amb,clk-freq: specifies the PLL frequence in HZ.
+- amb,msb-first-only: HW only supports msb first tx/rx, for A5S/S2/S2E, please
+ set this flag.
+- cs-gpios: gpios chip select. Please see Reference for detailed.
+
+Optional properties:
+- amb,dma-used: use dma for TX/RX, only can be specified if SPI channel
+ supports dma mode.
+- dmas: specify dma channel
+- dma-names: specify dma channel name.
+
+iii) Subnode
+------------
+The SPI node can contain subnodes which represent the spi devices connected
+to this SPI controller. If any valid subnode are available, the SPI drivers
+will proble them automatically.
+
+The subnodes should contain the following properties.
+- compatible: name of the SPI device, should match the name of its drivers.
+- reg: index of the SPI device, normally the same as the unit address.
+- properties provided by Kernel: please see Reference.
+
+iv) Example
+-----------
+ spi0: spi@e0020000 {
+ compatible = "ambarella,spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe0020000 0x1000>;
+ interrupts = <35 0x4>;
+ amb,clk-name = "gclk_ssi_ahb";
+ amb,clk-freq = <54000000>;
+ cs-gpios = <&gpio 37 0>, <&gpio 38 0>, <&gpio 23 0>;
+
+ sensor: sensor@0 {
+ compatible = "ambarella,sensor";
+ reg = <0>;
+ spi-max-frequency = <1000000>;
+ spi-cpha;
+ spi-cpol;
+ };
+ };
+
+
+17) - SLAVE SPI node
+====================
+
+
+i) Properties
+-------------
+Required properties:
+- compatible: should be "ambarella,spi-slave".
+- reg: specifies base physical address and size of the registers.
+- interrupts: the interrupt for the slave spi controller.
+
+ii) Example
+-----------
+ spi_slave@e0026000 {
+ compatible = "ambarella,spi-slave";
+ reg = <0xe0026000 0x1000>;
+ interrupts = <38 0x4>;
+ };
+
+
+18) - USBPHY node
+=================
+
+
+i) Properties
+-------------
+Required properties:
+- compatible: should be "ambarella,usbphy".
+- reg: specifies base physical address and size of the registers.
+
+Optional properties:
+- amb,host-phy-num: specifies the PHY number used for host.
+- amb,owner-mask: Mask IDDIG0, should be specified for S2L.
+- amb,owner-invert: the owner bit for USB PHY is inverted, should be specified
+ for S2L.
+- amb,ocp-polarity: specifies the polarity of over current protection pin.
+- id-gpios: specifies the input GPIO used for OTG detection.
+- md-gpios: specifies the output GPIO to control external circuit to switch to
+ host mode or device mode.
+- hub-gpios: specifies the GPIO to reset the usb hub.
+
+ii) Example
+-----------
+ usbphy: usbphy@ec170050 {
+ compatible = "ambarella,usbphy";
+ reg = <0xec170050 0x4 0xe001b00c 0x4 0xec1702c0 0x4>;
+ amb,host-phy-num = <2>;
+ amb,owner-offset = <0x1001>;
+ };
+
+
+19) - PINCTRL node
+==================
+
+
+i) Reference
+------------
+Please see Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
+
+ii) Description
+---------------
+The pins controlled by Ambarella SoC chip are organized in banks, each bank
+has 32 pins. Each pin has at least 2 multiplexing functions, and generally,
+the first function is GPIO.
+
+The PINCTRL node acts as a container for an arbitrary number of subnodes. And
+these subnodes will fall into two categories.
+One is for GPIO, please see the "GPIO node" section for detail, and another one
+is to set up a group of pins for a function, both pin configurations(TODO) and
+mux selection, and it's called group node in the binding document.
+
+
+iii) Properties
+---------------
+Required properties:
+- compatible: should be "ambarella,pinctrl", "simple-bus".
+- #address-cells: should be 1.
+- #size-cells: should be 0.
+- reg: specifies base physical address and size of the registers.
+- #gpio-range-cells: should be 3.
+
+Optional properties:
+- reg-names: "gpio0", "gpio1", ... , "gpioN", ["iomux"], should be specified
+ if the SoC supports IOMUX, e.g., S2L.
+
+
+iv) Subnode
+-----------
+On Ambarella SoC chip, there is no hardware pin group. The pin group in this
+binding only means a group of pins put together for particular peripheral to
+work in particular function. That said, the group node should include all the
+pins needed for one function rather than having these pins defined in several
+group nodes. It also means each of "pinctrl-*" phandle in client device node
+should only have one group node pointed in there.
+
+Required subnode-properties:
+- reg: Should be the index of the group nodes for same function.
+- amb,pinmux-ids: an integer array. Each integer in the array specifies a pin
+ with given mux function, with pin id and mux packed as:
+ mux << 12 | pin id
+ Here mux means function of this pin, and pin id is identical to gpio id. For
+ the SoC supporting IOMUX, like S2L, the maximal value of mux is 5. However,
+ for the SoC not supporting IOMUX, like A5S, S2, the third or fourth function
+ is selected by other "virtual pins" setting. Here the "virtual pins" means
+ there is no real hardware pins mapping to the corresponding register address.
+ So the registers for the "virtual pins" can be used for the selection of 3rd
+ or 4th function for other real pins.
+- amb,pinconf-ids: an integer array. Each integer in the array specifies a pin
+ with given configuration, with pin id and config packed as:
+ config << 16 | pin id
+ Here config is used to configure pull up/down and drive strength of the pin,
+ and it's orgnization is:
+ bit1~0: 00: pull down, 01: pull up, 1x: clear pull up/down
+ bit2: reserved
+ bit3: 0: leave pull up/down as default value, 1: config pull up/down
+ bit5~4: drive strength value, 0: 2mA, 1: 4mA, 2: 8mA, 3: 12mA
+ bit6: reserved
+ bit7: 0: leave drive strength as default value, 1: config drive strength
+
+v) Example
+----------
+ pinctrl: pinctrl@e8009000 {
+ compatible = "ambarella,pinctrl", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe8009000 0x1000>,
+ <0xe800a000 0x1000>,
+ <0xe800e000 0x1000>,
+ <0xe8010000 0x1000>,
+ <0xe8016000 0x1000>;
+ reg-names = "gpio0", "gpio1", "gpio2", "gpio3", "iomux";
+ #gpio-range-cells = <3>;
+
+ uart0_pins: uart0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1027 0x1028>;
+ };
+
+ sdmmc0_pins_4bit: sdmmc0@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x2039 0x203a 0x203b 0x203c
+ 0x2049 0x204a 0x204b 0x204c>;
+ amb,pinconf-ids = <0x090039 0xb0003a 0xaa003b 0x00003c>;
+ };
+ }
+
+In this example, uart0_pins defines a group of pins used by uart0 controller,
+according to the definition, uart0 uses 2 pins which are pin39(0x27) and
+pin40(0x28), i.e., GPIO39 and GPIO40. And, pin39/pin40 use function 1.
+And, sdmmc0_pins_4bit defines a group of pins used by sd0 controller, according
+to the definition, sd0 uses 8 pins. And pin57 enables pull up, pin58 configure
+drive strength to 12mA, pin59 clear pull up/down and configure drive strength
+to 8mA, pin60 leave pull up/down and drive strength as default value.
+
+
+20) - GPIO node
+===============
+
+
+i) Reference
+------------
+Please see Documentation/devicetree/bindings/gpio/gpio.txt
+
+ii) Description
+---------------
+The Ambarella GPIO controller is part of Ambarella PIN controller. The GPIOs
+are organized in bank. Each port consists of 32 GPIOs.
+
+As the GPIO controller is embedded in the PIN controller and all the GPIO
+ports share the same IO space with PIN controller, the GPIO node will be
+represented as sub-nodes of Ambarella PINCTRL node.
+
+iii) Properties
+---------------
+Required properties:
+- compatible: should be "ambarella,gpio".
+- interrupts: the interrupts for each GPIO bank.
+- gpio-controller : marks the device node as a gpio controller.
+- #gpio-cells : should be two. The first cell is the pin number and the second
+ cell is used to specify the gpio polarity:
+ 0 = active high.
+ 1 = active low.
+- gpio-ranges: speicify the ranges that may be handled by the pin controller.
+- interrupt-controller: marks the device node as an interrupt controller.
+- #interrupt-cells : should be 2. The first cell is the GPIO number. The second
+ cell bits[3:0] is used to specify trigger type and level flags:
+ 1 = low-to-high edge triggered.
+ 2 = high-to-low edge triggered.
+ 4 = active high level-sensitive.
+ 8 = active low level-sensitive.
+
+iv) Example
+-----------
+ gpio: gpio@0 {
+ compatible = "ambarella,gpio";
+ /* gpio interrupts to vic */
+ interrupts = <10 0x4 11 0x4 30 0x4 29 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl 0 0 128>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+v) GPIO user nodes example
+--------------------------
+ spi0: spi@e0020000 {
+ ......
+ cs-gpios = <&gpio 37 0>, <&gpio 38 0>, <&gpio 23 0>;
+ ......
+ };
+
+ DESCRIPTION:
+ cs-gpios = GPIO properties name;
+ &gpio = phandle to the GPIO controller node;
+ 37/38/39 = the GPIO id;
+ 0 = normal polarity.
+ Please see Reference for detailed.
+
+
+21) - UART node
+===============
+
+
+i) Properties
+-------------
+Required properties:
+- compatible: should be "ambarella,uart".
+- reg: specifies base physical address and size of the registers.
+- interrupts: the interrupt for this uart.
+- pinctrl-names: should contain only one value - "default".
+- pinctrl-0: pin control group to be used for this controller.
+
+Optional properties:
+- amb,tx-fifo-fix: should be specified for A7L, iONE and A8
+- amb,msr-used: use Modem Status Register, should be specified for non-UART0.
+- amb,less-reg: registers like FIFO status register are NOT provided, should be
+ specified for A5S.
+- amb,txdma-used: use dma for transmitting, should be specified if uart hardware
+ supports dma mode.
+- amb,rxdma-used: use dma for receiving, should be specified if uart hardware
+ supports dma mode.
+
+ii) Example
+-----------
+ uart0: uart@e8005000 {
+ compatible = "ambarella,uart";
+ reg = <0xe8005000 0x1000>;
+ interrupts = <9 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ status = "ok";
+ /* amb,tx-fifo-fix; */
+ };
+
+
+22) - I2C node
+==============
+
+
+i) Properties
+-------------
+Required properties:
+- compatible: should be "ambarella,i2c".
+- #address-cells: should be 1.
+- #size-cells: should be 0.
+- reg: specifies base physical address and size of the registers.
+- interrupts: the interrupt for this i2c.
+- pinctrl-names: should contain only one value - "default".
+- pinctrl-0: pin control group to be used for this controller.
+- clock-frequency: desired I2C bus clock frequency in Hz, [1000, 400000].
+- amb,i2c-class:
+ a) 0x81: normal I2C controller
+ b) 0x08: I2C controller dedicated to HDMI
+- amb,turbo-mode: use turbo(FIFO) write mode, batched data will be write into FIFO
+directly, but there're 2 restriction for this mode:
+ 1) FIFO mode will ignore device ACK.
+ 2) FIFO mode can only write less than or equal to 61 data(FIFO depth) into FIFO at a time.
+- amb,duty-cycle: the duty cycle of clock, and the value can be:
+ 0 = duty cycle 1:1, this is the default setting.
+ 1 = duty cycle 2:3.
+ 2 = duty cycle 1:2.
+- amb,stretch-scl: extend the SCL clock to tune START/STOP setup and hold timing,
+ the default value is 1 if this option is not specified.
+
+ii) Subnode
+-----------
+The I2C node can contain subnodes which represent the I2C devices connected
+to this I2C controller. If any valid subnode are available, the I2C drivers
+will proble them automatically.
+
+The unit address of subnodes should be its device address in I2C bus. And the
+subnode should contain the following properties.
+- compatible: name of I2C device, should match the name of its drivers.
+- reg: device address in the I2C bus, normally the same as the unit address.
+
+iii) Example
+------------
+ i2c0: i2c@e8003000 {
+ compatible = "ambarella,i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe8003000 0x1000>;
+ interrupts = <19 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ clock-frequency = <100000>;
+ amb,i2c-class = <0x81>;
+ amb,turbo-mode;
+ amb,duty-cycle = <0>;
+ amb,stretch-scl = <1>;
+ status = "ok";
+
+ ak4642: codec@12 {
+ compatible = "ambarella,ak4642";
+ reg = <0x12>;
+ gpios = <&pca9539 4 0x0>;
+ };
+ };
+
+
+23) - I2CMUX node
+=================
+
+
+i) Reference
+------------
+Please see Documentation/devicetree/bindings/i2c/i2c-mux-pinctrl.txt
+
+ii) Description
+---------------
+This node is only available for SoC chip that supports I2C Mux, i.e., A5S.
+
+
+24) - PWM node
+==============
+
+
+i) Reference
+------------
+Please see Documentation/devicetree/bindings/pwm/pwm.txt
+
+ii) Properties
+--------------
+Required properties:
+- compatible: should be "ambarella,pwm".
+- reg: specifies base physical address and size of the registers.
+- #pwm-cells: should be 3.
+
+iii) Example
+----------
+ pwm: pwm@e8008000 {
+ compatible = "ambarella,pwm";
+ reg = <0xe8008000 0x1000>;
+ #pwm-cells = <3>;
+ };
+
+iv) PWM user nodes example
+--------------------------
+ backlight {
+ ......
+ pwms = <&pwm 2 40000 0>;
+ ......
+ };
+
+ DESCRIPTION:
+ pwms = PWM properties name;
+ &pwm = phandle to the PWM controller node;
+ 2 = the PWM number or channel;
+ 4000 = the PWM period in nanoseconds.
+ 0 = normal polarity
+ Please see Reference for detailed.
+
+
+25) - ADC node
+==============
+
+
+i) Properties
+-------------
+
+Required properties:
+- compatible: should be "ambarella,adc".
+- reg: specifies base physical address and size of the registers.
+- interrupts: the interrupt for adc.
+- clock-frequency: desired ADC clock frequency in Hz.
+- amb,polling-mode: specified if ADC is working in polling mode, must be
+ specified for A5S.
+
+Optional properties:
+- amb,print-key: print Key code when key is pressed, for debug purpose.
+
+ii) Example
+-----------
+ adc@e801d000 {
+ compatible = "ambarella,adc";
+ reg = <0xe801d000 0x1000>;
+ interrupts = <34 0x4>;
+ clock-frequency = <3000000>;
+ };
+
+iii) Note
+---------
+For coding easily purpose, we re-order the channel number for A5S.
+Please see the ADC address definition in PRM for details.
+
+26) - IR node
+=============
+
+
+i) Properties
+-------------
+- compatible: should be "ambarella,ir".
+- reg: specifies base physical address and size of the registers.
+- interrupts: the interrupt for ir.
+- pinctrl-names: should contain only one value - "default".
+- pinctrl-0: pin control group to be used for this controller.
+- amb,keymap: the key-code to be reported when the key is pressed. Each entry
+ is organized as <IRcode Keycode>.
+
+Optional properties:
+- amb,protocol: ir protocol, use NEC protocol if not specified.
+ a) 0: NEC protocol
+ b) 1: PANASONIC protocol
+ c) 2: SONY protocol
+ d) 3: PHILIPS protocol
+- amb,print-key: print IR code when key is pressed, for debug purpose.
+
+ii) Example
+-----------
+ ir@e8006000 {
+ compatible = "ambarella,ir";
+ reg = <0xe8006000 0x1000>;
+ interrupts = <22 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_pins>;
+ amb,keymap =
+ <0x0100bcbd 116>, /* KEY_POWER */
+ <0x01000405 115>, /* KEY_VOLUMEUP */
+ <0x01008485 114>; /* KEY_VOLUMEDOWN */
+ /* amb,print-key; */
+ };
+
+
+27) - WDT node
+==============
+
+
+i) Properties
+-------------
+Required properties:
+- compatible: should be "ambarella,wdt".
+- reg: specifies base physical address and size of the registers.
+- interrupts: the interrupt for wdt, normally not used.
+- timeout-sec: the watchdog timeout in seconds.
+- amb,non-bootstatus: don't support to report boot status, should be
+ specified only for A5S.
+
+ii) Example
+-----------
+ wdt@e800c000 {
+ compatible = "ambarella,wdt";
+ reg = <0xe800c000 0x1000>;
+ /* interrupts = <21 0x4>; */
+ timeout-sec = <15>;
+ };
+
+
+28) - RTC node
+==============
+
+
+i) Properties
+-------------
+Required properties:
+- compatible: should be "ambarella,rtc".
+- reg: specifies base physical address and size of the registers.
+
+Optional properties:
+- amb,is-limited: should be specified only for A5S.
+
+ii) Example
+-----------
+ rtc@e8015000 {
+ compatible = "ambarella,rtc-v2";
+ reg = <0xe8015000 0x1000>;
+ };
+
+
+29) - CRYPTO node
+=================
+
+
+i) Properties
+-------------
+Required properties:
+- compatible: should be "ambarella,crypto".
+- reg: specifies base physical address and size of the registers.
+- interrupts: the interrupt for crypto.
+- interrupt-names: the name for each interrupt.
+
+Optional properties:
+- amb,cap-md5-sha1: should be specified if hardwar supports md5 and sha1.
+- amb,data-swap: should be specified if hardware needs to swap data.
+- amb,reg-64bit: should be specified if hardware has 64bit register.
+- amb,binary-mode: should be specified if hardware needs binary mode.
+
+ii) Example
+-----------
+ crypto@f0020000 {
+ compatible = "ambarella,crypto";
+ reg = <0xf0020000 0x8000>;
+ interrupts = <88 0x1>, <87 0x1>, <86 0x1>, <89 0x1>;
+ interrupt-names = "aes-irq", "des-irq", "md5-irq", "sha1-irq";
+ amb,cap-md5-sha1;
+ amb,data-swap;
+ amb,reg-64bit;
+ };
+
+
+30) - IAV node
+==============
+
+
+i) Properties
+-------------
+Required properties:
+- compatible: should be "ambarella,iav".
+
+ii) Subnode
+-----------
+The IAV node may contain subnodes which represent the VIN controller, whose
+name must be vincN (N = 0, 1).
+
+And the optional properties of subnodes:
+- vinrst-gpios: specifies the GPIO to reset VIN.
+- vinpwr-gpios: specifies the GPIO to control the power of VIN.
+
+iii) Example
+------------
+ iav {
+ compatible = "ambarella,iav";
+
+ /* node for vin controller */
+ vinc0 {
+ vinrst-gpios = <&pca9539 7 0>;
+ vinpwr-gpios = <&gpio 8 1>, <&gpio 9 1>, <&gpio 10 1>;/
+ };
+
+
+31) - SOUND node
+================
+
+
+i) Properties
+-------------
+Required properties:
+- compatible: board name, should match the name in ALSA board driver.
+- amb,model: board description.
+- amb,i2s-controllers: specifies the phandle to I2S controller.
+- amb,audio-codec: specifies the phandle to audio codec.
+- amb,dai_fmt: specifies the mode of codec and cpu. If it is 0, the mode is I2S, otherwise it is DSP mode.
+- amb,clk_fmt:
+ 0 : mclk, bclk provided by cpu
+ 1 : bclk provide by cpu, mclk is not used
+ 2 : mclk provided by cpu, bclk is provided by codec
+There are four type of connection:
+clk_fmt=0:
+cpu : codec:
+ MCLK ------> MCKI
+ BCLK ------> BICK
+ LRCK ------> LRCK
+clk_fmt=1:
+cpu : codec:
+ MCLK is not used
+ BCLK ------> BICK
+ LRCK ------> LRCK
+clk_fmt=2:
+cpu : codec:
+ MCLK ------> MCKI
+ BCLK <------ BICK
+ LRCK <------ LRCK
+There are one connection we are not used, it is like clk_fmt=0,but power on the codec PLL.
+It is a waster of power, so we do not use it.
+
+- amb,codec-name: specifies the name of the codec.
+- amb,stream-name: specifies the name of the stream.
+- amb,codec-dai-name: specifies the DAI name within the codec, it must be consistent with the codec driver.
+- amb,audio-routing: specifies the route map for audio codec.
+usage:
+ amb,audio-routing = "sink", source", /*This is route 0*/
+ "sink", "source"; /*This is route 1*/
+ sink and source dapm widget should be based on codec driver and our board.
+ dapm widget on board:
+ "Mic internal": board internal Mic, used to connect Mic of codec.
+ "Mic external": used to connect Mic of codec with the external Mic of our board.
+ "Line In": used to connect to line in of codec dapm widget.
+ "Line Out": used to connect line out of codec dapm widget.
+ "HP Jack": used to connect the headphone of codec dapm widget.
+ "Speaker": used to connect the speaker of codec dapm widget.
+
+ii) Example
+-----------
+ sound {
+ compatible = "ambarella,audio-board";
+ amb,model = "ak4642 @ Ambarella";
+ amb,i2s-controllers = <&i2s0>;
+ amb,audio-codec = <&ak4642>;
+ amb,dai_fmt = <0>;
+ amb,codec-name = "ak4642";
+ amb,stream-name = "ak4642 PCM";
+ amb,codec-dai-name = "ak4642-hifi";
+ amb,audio-routing = "LIN1", "Mic internal",
+ "RIN1", "Mic internal",
+ "LIN2", "Line In",
+ "RIN2", "Line In",
+ "Line Out", "LOUT",
+ "Line Out", "ROUT",
+ "HP Jack", "HPL",
+ "HP Jack", "HPR",
+ "Speaker", "SPP",
+ "Speaker", "SPN";
+ };
+
+
+III - Misc Node definition
+++++++++++++++++++++++++++
+
+
+1) - BOGUS BUS node
+====================
+
+i) Purpose
+----------
+No real meaning, just make the name of devices under bogus bus more reasonable.
+
+
+
+2) - GPIO KEY node
+===================
+
+i) Reference
+------------
+Please see Documentation/devicetree/bindings/gpio/gpio_keys.txt
+
+
+
+3) - ADC KEY node
+====================
+
+
+i) Properties
+-------------
+
+Required properties:
+- compatible: should be "ambarella,input_adckey".
+- amb,keymap: the key-code to be reported when the key is pressed. Each entry
+ is organized as <ADC Keycode>, where ADC is packed as:
+ channel << 28 | high_level << 16 | low_level
+ Note: the resolution of ADC is 12 bits. And please see the "Note" in "ADC node".
+
+ii) Example
+-----------
+ input_adckey {
+ compatible = "ambarella,input_adckey";
+ amb,keymap =
+ /* channel 1 */
+ <0x1fff0c1c 0>, /* KEY_RESERVED */
+ <0x1c1c0a8c 373>, /* KEY_MODE */
+ <0x19600708 111>, /* KEY_DELETE */
+ <0x154603e8 167>, /* KEY_RECORD */
+ <0x1320012c 211>, /* KEY_HP */
+ <0x10c80000 212>, /* KEY_CAMERA */
+ /* channel 3 */
+ <0x3fff0c1c 0>, /* KEY_RESERVED */
+ <0x3c1c0af0 139>, /* KEY_MENU */
+ <0x3af007d0 106>, /* KEY_RIGHT */
+ <0x37d003e8 105>, /* KEY_LEFT */
+ <0x33e80190 108>, /* KEY_DOWN */
+ <0x31900000 103>; /* KEY_UP */
+ };
+
+
+
+4) - PWM BACKLIGHT node
+========================
+
+i) Reference
+------------
+Please see Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt
+
+ii) Properties
+--------------
+Required properties:
+- reg: specifies the pwm channel, no real meaning, just make the device name
+ more reasonable. It take effect only when putting the PWM BACKLIGHT node under
+ bogus_bus node.
+
diff --git a/Documentation/devicetree/bindings/gpio/gpio-pcf857x.txt b/Documentation/devicetree/bindings/gpio/gpio-pcf857x.txt
new file mode 100644
index 00000000..d63194a2
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-pcf857x.txt
@@ -0,0 +1,71 @@
+* PCF857x-compatible I/O expanders
+
+The PCF857x-compatible chips have "quasi-bidirectional" I/O lines that can be
+driven high by a pull-up current source or driven low to ground. This combines
+the direction and output level into a single bit per line, which can't be read
+back. We can't actually know at initialization time whether a line is configured
+(a) as output and driving the signal low/high, or (b) as input and reporting a
+low/high value, without knowing the last value written since the chip came out
+of reset (if any). The only reliable solution for setting up line direction is
+thus to do it explicitly.
+
+Required Properties:
+
+ - compatible: should be one of the following.
+ - "maxim,max7328": For the Maxim MAX7378
+ - "maxim,max7329": For the Maxim MAX7329
+ - "nxp,pca8574": For the NXP PCA8574
+ - "nxp,pca8575": For the NXP PCA8575
+ - "nxp,pca9670": For the NXP PCA9670
+ - "nxp,pca9671": For the NXP PCA9671
+ - "nxp,pca9672": For the NXP PCA9672
+ - "nxp,pca9673": For the NXP PCA9673
+ - "nxp,pca9674": For the NXP PCA9674
+ - "nxp,pca9675": For the NXP PCA9675
+ - "nxp,pcf8574": For the NXP PCF8574
+ - "nxp,pcf8574a": For the NXP PCF8574A
+ - "nxp,pcf8575": For the NXP PCF8575
+ - "ti,tca9554": For the TI TCA9554
+
+ - reg: I2C slave address.
+
+ - gpio-controller: Marks the device node as a gpio controller.
+ - #gpio-cells: Should be 2. The first cell is the GPIO number and the second
+ cell specifies GPIO flags, as defined in <dt-bindings/gpio/gpio.h>. Only the
+ GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags are supported.
+
+Optional Properties:
+
+ - lines-initial-states: Bitmask that specifies the initial state of each
+ line. When a bit is set to zero, the corresponding line will be initialized to
+ the input (pulled-up) state. When the bit is set to one, the line will be
+ initialized the the low-level output state. If the property is not specified
+ all lines will be initialized to the input state.
+
+ The I/O expander can detect input state changes, and thus optionally act as
+ an interrupt controller. When the expander interrupt line is connected all the
+ following properties must be set. For more information please see the
+ interrupt controller device tree bindings documentation available at
+ Documentation/devicetree/bindings/interrupt-controller/interrupts.txt.
+
+ - interrupt-controller: Identifies the node as an interrupt controller.
+ - #interrupt-cells: Number of cells to encode an interrupt source, shall be 2.
+ - interrupt-parent: phandle of the parent interrupt controller.
+ - interrupts: Interrupt specifier for the controllers interrupt.
+
+
+Please refer to gpio.txt in this directory for details of the common GPIO
+bindings used by client devices.
+
+Example: PCF8575 I/O expander node
+
+ pcf8575: gpio@20 {
+ compatible = "nxp,pcf8575";
+ reg = <0x20>;
+ interrupt-parent = <&irqpin2>;
+ interrupts = <3 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
diff --git a/Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt b/Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt
new file mode 100644
index 00000000..011679f1
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt
@@ -0,0 +1,18 @@
+* AsahiKASEI AK8975 magnetometer sensor
+
+Required properties:
+
+ - compatible : should be "asahi-kasei,ak8975"
+ - reg : the I2C address of the magnetometer
+
+Optional properties:
+
+ - gpios : should be device tree identifier of the magnetometer DRDY pin
+
+Example:
+
+ak8975@0c {
+ compatible = "asahi-kasei,ak8975";
+ reg = <0x0c>;
+ gpios = <&gpj0 7 0>;
+};
diff --git a/Documentation/devicetree/bindings/mfd/tps6507x.txt b/Documentation/devicetree/bindings/mfd/tps6507x.txt
old mode 100755
new mode 100644
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index d4195124..ec41ea75 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -221,6 +221,7 @@ config ARM_PATCH_PHYS_VIRT
default y
depends on !XIP_KERNEL && MMU
depends on !ARCH_REALVIEW || !SPARSEMEM
+ depends on !PLAT_AMBARELLA || PLAT_AMBARELLA_A8
help
Patch phys-to-virt and virt-to-phys translation functions at
boot and module load time according to the position of the
@@ -298,6 +299,20 @@ config ARCH_MULTIPLATFORM
select SPARSE_IRQ
select USE_OF
+config ARCH_AMBARELLA
+ bool "Ambarella"
+ depends on MMU
+ select ARCH_HAS_CPUFREQ
+ select NEED_MACH_GPIO_H
+ select NEED_MACH_IO_H
+ select NEED_MACH_MEMORY_H
+ select PLAT_AMBARELLA
+ select USE_OF
+ select PINCTRL
+ select PINCTRL_AMB
+ help
+ Support for Ambarella Media Processor.
+
config ARCH_INTEGRATOR
bool "ARM Ltd. Integrator family"
select ARCH_HAS_CPUFREQ
@@ -917,6 +932,8 @@ endmenu
#
source "arch/arm/mach-mvebu/Kconfig"
+source "arch/arm/mach-ambarella/Kconfig"
+
source "arch/arm/mach-at91/Kconfig"
source "arch/arm/mach-bcm/Kconfig"
@@ -1603,6 +1620,7 @@ config HZ
ARCH_S5PV210 || ARCH_EXYNOS4
default AT91_TIMER_HZ if ARCH_AT91
default SHMOBILE_TIMER_HZ if ARCH_SHMOBILE
+ default AMBARELLA_TIMER_HZ if PLAT_AMBARELLA
default 100
config SCHED_HRTICK
@@ -2229,6 +2247,9 @@ config ARCH_SUSPEND_POSSIBLE
config ARM_CPU_SUSPEND
def_bool PM_SLEEP
+config ARCH_HIBERNATION_POSSIBLE
+ def_bool y
+
endmenu
source "net/Kconfig"
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 1d41908d..c9b909ac 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -81,6 +81,10 @@ choice
prompt "Kernel low-level debugging port"
depends on DEBUG_LL
+ config AMBARELLA_DEBUG_LL_UART0
+ bool "Kernel low-level debugging on Ambarella UART0"
+ depends on ARCH_AMBARELLA
+
config AT91_DEBUG_LL_DBGU0
bool "Kernel low-level debugging on rm9200, 9260/9g20, 9261/9g10 and 9rl"
depends on HAVE_AT91_DBGU0
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 7d4ce431..3d8fbe28 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -25,6 +25,9 @@ GZFLAGS :=-9
# Never generate .eh_frame
KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm)
+# Never enable unaligned-access in kernel
+KBUILD_CFLAGS += $(call cc-option,-mno-unaligned-access)
+
# Do not use arch/arm/defconfig - it's always outdated.
# Select a platform tht is kept up-to-date
KBUILD_DEFCONFIG := versatile_defconfig
@@ -143,8 +146,11 @@ textofs-$(CONFIG_ARCH_MSM7X30) := 0x00208000
textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000
textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000
+textofs-$(CONFIG_PLAT_AMBARELLA) := $(CONFIG_AMBARELLA_TEXTOFS)
+
# Machine directory name. This list is sorted alphanumerically
# by CONFIG_* macro name.
+machine-$(CONFIG_ARCH_AMBARELLA) += ambarella
machine-$(CONFIG_ARCH_AT91) += at91
machine-$(CONFIG_ARCH_BCM) += bcm
machine-$(CONFIG_ARCH_BCM2835) += bcm2835
diff --git a/arch/arm/boot/dts/ambarella-a5s.dtsi b/arch/arm/boot/dts/ambarella-a5s.dtsi
new file mode 100644
index 00000000..9c191189
--- /dev/null
+++ b/arch/arm/boot/dts/ambarella-a5s.dtsi
@@ -0,0 +1,483 @@
+/*
+ * Copyright (C) 2013 Ambarella,Inc. - http://www.ambarella.com/
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "ambarella,a5s";
+ interrupt-parent = <&intc>;
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ nand = &nand0;
+ emmc = &sdmmc0;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ spi0 = &spi0;
+ spi1 = &spi1;
+ ethernet0 = &mac0;
+ };
+
+ /* the memory node will be overwritten in Amboot,
+ * here is just the default value. */
+ memory {
+ device_type = "memory";
+ reg = <0xc0200000 0x07e00000>; /* 126M */
+ };
+
+ chosen {
+ linux,stdout-path = &uart0;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,arm1136";
+ reg = <0>;
+ };
+ };
+
+ apb@70000000 { /* APB */
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x70000000 0x01000000>;
+ ranges;
+
+ timer2: timer@7000b010 {
+ compatible = "ambarella,clock-source";
+ reg = <0x7000b010 0x10 0x7000b030 0x4>;
+ interrupts = <13 0x1>;
+ ctrl-offset = <4>; /* bit offset in timer-ctrl reg */
+ };
+
+ timer3: timer@7000b020 {
+ compatible = "ambarella,clock-event";
+ reg = <0x7000b020 0x10 0x7000b030 0x4>;
+ interrupts = <14 0x1>;
+ ctrl-offset = <8>; /* bit offset in timer-ctrl reg */
+ };
+
+ uart0: uart@70005000 {
+ compatible = "ambarella,uart";
+ reg = <0x70005000 0x1000>;
+ interrupts = <9 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ amb,less-reg;
+ status = "ok";
+ };
+
+ uart1: uart@7001f000 {
+ compatible = "ambarella,uart";
+ reg = <0x7001f000 0x1000>;
+ interrupts = <25 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ amb,less-reg;
+ amb,msr-used; /* use Modem Status Register */
+ status = "disabled";
+ };
+
+ i2c0: i2c@70003000 {
+ compatible = "ambarella,i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70003000 0x1000>;
+ interrupts = <19 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ clock-frequency = <100000>;
+ amb,i2c-class = <0x81>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@70007000 {
+ compatible = "ambarella,i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70007000 0x1000>;
+ interrupts = <36 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+ clock-frequency = <100000>;
+ amb,i2c-class = <0x08>;
+ status = "disabled";
+ };
+
+ i2cmux {
+ compatible = "i2c-mux-pinctrl";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c-parent = <&i2c0>;
+
+ pinctrl-names = "i2c2", "idle";
+ pinctrl-0 = <&i2c2_pins>;
+ pinctrl-1 = <&i2c2_pins_idle>;
+
+ i2c@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ spi0: spi@70002000 {
+ compatible = "ambarella,spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70002000 0x1000>;
+ interrupts = <20 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins>;
+ amb,clk-freq = <13500000>;
+ amb,msb-first-only;
+ };
+
+ spi1: spi@7000f000 {
+ compatible = "ambarella,spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x7000f000 0x1000>;
+ interrupts = <41 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pins>;
+ amb,clk-freq = <13500000>;
+ amb,msb-first-only;
+ };
+
+ spi_slave@7001e000 {
+ compatible = "ambarella,spi-slave";
+ reg = <0x7001e000 0x1000>;
+ interrupts = <26 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi_slave_pins>;
+ amb,id = <0>;
+ };
+
+ adc@7000d000 {
+ compatible = "ambarella,adc";
+ reg = <0x7000d000 0x1000>;
+ interrupts = <34 0x4>;
+ clock-frequency = <3000000>;
+ amb,polling-mode;
+ };
+
+ ir@70006000 {
+ compatible = "ambarella,ir";
+ reg = <0x70006000 0x1000>;
+ interrupts = <22 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_pins>;
+ };
+
+ wdt@7000c000 {
+ compatible = "ambarella,wdt";
+ reg = <0x7000c000 0x1000>;
+ /* interrupts = <21 0x4>; */
+ timeout-sec = <15>;
+ amb,non-bootstatus;
+ };
+
+ rtc@7000d000 {
+ compatible = "ambarella,rtc";
+ reg = <0x7000d000 0x1000>;
+ amb,is-limited;
+ };
+
+ pwm: pwm@70004000 {
+ compatible = "ambarella,pwm";
+ reg = <0x70004000 0x1000 0x70008000 0x10>;
+ #pwm-cells = <3>;
+ };
+
+ pinctrl: pinctrl@70009000 {
+ compatible = "ambarella,pinctrl", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70009000 0x1000>,
+ <0x7000a000 0x1000>,
+ <0x7000e000 0x1000>;
+ reg-names = "gpio0", "gpio1", "gpio2";
+ #gpio-range-cells = <3>;
+
+ gpio: gpio@0 {
+ compatible = "ambarella,gpio";
+ /* gpio interrupts to vic */
+ interrupts = <10 0x4 11 0x4 30 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl 0 0 96>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ uart0_pins: uart0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x100e 0x100f>;
+ };
+
+ uart1_pins: uart1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1032 0x1034>,
+ /* virtual pins, just for config */
+ <0x1021 0x0022>;
+ };
+
+ uart1_flow_pins: uart1_flow@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1033 0x1035>,
+ /* virtual pins, just for config */
+ <0x0021 0x1022>;
+ };
+
+ nand0_pins: nand0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1027>; /* just WP is shared with GPIO */
+ };
+
+ i2c0_pins: i2c0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1000 0x1001>;
+ };
+
+ i2c1_pins: i2c1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1056 0x1057>;
+ };
+
+ i2c2_pins: i2c2@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1024>;
+ };
+
+ i2c2_pins_idle: i2c2_idle@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x0024>;
+ };
+
+ ir_pins: ir0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1023>;
+ };
+
+ i2s0_pins: i2s0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x104d 0x104e 0x104f 0x1050 0x1051>,
+ /* virtual pins, just for config */
+ <0x003f>;
+ };
+
+ pwm0_pins: pwm0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x102d>;
+ };
+
+ pwm1_pins: pwm1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x102e>;
+ };
+
+ pwm2_pins: pwm2@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1032>;
+ };
+
+ pwm3_pins: pwm3@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1033>;
+ };
+
+ pwm5_pins: pwm5@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1010>;
+ };
+
+ sdio_pins: sdio@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1045 0x1046 0x1047
+ 0x1048 0x1049 0x104a>;
+ };
+
+ sdio_pins_idle: sdio_idle@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x0045 0x0046 0x0047
+ 0x0048 0x0049 0x004a>;
+ };
+
+ spi0_pins: spi0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1002 0x1003 0x1004>;
+ };
+
+ spi1_pins: spi1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1058 0x1059 0x105A>;
+ };
+
+ spi_slave_pins: spi_slave@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1032 0x1033 0x1034 0x1035>,
+ /* virtual pins, just for
+ configuration purpose.*/
+ <0x0021 0x1022>;
+ };
+ };
+ };
+
+ ahb@60000000 { /* AHB */
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x60000000 0x01000000>;
+ ranges;
+
+ intc: interrupt-controller@60003000 {
+ compatible = "ambarella,vic";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x60003000 0x1000>,
+ <0x60010000 0x1000>;
+ };
+
+ dma: dma@60005000 {
+ compatible = "ambarella,dma";
+ reg = <0x60005000 0x1000>;
+ interrupts = <15 0x4>;
+ #dma-cells = <2>;
+ dma-channels = <4>;
+ dma-requests = <4>;
+ dma-trans-type = <0 1 1 0>; /* 0-memcpy ,1-slave*/
+ amb,copy-align = <3>;
+ };
+
+ nand0: nand@60001000 {
+ compatible = "ambarella,nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x60001000 0x1000>, /* fio reg address */
+ <0x60012000 0x1000>, /* fdma reg address */
+ <0x60000000 0x4>; /* fifo base */
+ interrupts = <16 0x4>, /* fio_cmd_irq */
+ <17 0x4>, /* fio_dma_irq */
+ <33 0x4>; /* fdma_irq */
+ pinctrl-names = "default";
+ pinctrl-0 = <&nand0_pins>;
+ amb,enable-wp;
+ amb,no-bch;
+ amb,use-2x-pll;
+ nand-on-flash-bbt;
+ };
+
+ i2s0: i2s@6000a000 {
+ compatible = "ambarella,i2s";
+ reg = <0x6000a000 0x1000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_pins>;
+ amb,i2s-channels = <2>;
+ amb,default-mclk = <12288000>;
+ dmas = <&dma 1 1>,
+ <&dma 0 1>;
+ dma-names = "tx", "rx";
+ };
+
+ udc@60006000 {
+ compatible = "ambarella,udc";
+ reg = <0x60006000 0x2000 0x70170088 0x4>;
+ interrupts = <4 0x4>;
+ amb,usbphy = <&usbphy>;
+ };
+
+ sdmmc0: sdmmc0@60002000 {
+ compatible = "ambarella,sdmmc";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x60002000 0x1000>,
+ <0x60001000 0x80>; /* fio reg address */
+ interrupts = <18 0x4>;
+ amb,clk-name = "gclk_sd";
+ amb,wait-tmo = <10000>; /* in millisecond */
+ amb,switch_vol_tmo = <20>;
+ amb,max-blk-size = <524288>; /* valid value: 4K<<n */
+ status = "disabled";
+
+ slot@0 {
+ reg = <0>;
+ global-id = <0>;
+ max-frequency = <24000000>;
+ bus-width = <4>;
+ cap-sdio-irq;
+ no-1-8-v;
+ };
+
+ slot@1 {
+ reg = <1>;
+ global-id = <1>;
+ max-frequency = <24000000>;
+ bus-width = <4>;
+ cap-sdio-irq;
+ no-1-8-v;
+
+ amb,force-gpio;
+ pinctrl-names = "work", "idle";
+ pinctrl-0 = <&sdio_pins>;
+ pinctrl-1 = <&sdio_pins_idle>;
+ };
+ };
+
+ mac0: ethernet@6000e000 {
+ compatible = "ambarella,eth";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x6000e000 0x2000>;
+ interrupts = <27 0x4>;
+ amb,tx-ring-size = <32>;
+ amb,rx-ring-size = <64>;
+ };
+
+ crypto@60014000 {
+ compatible = "ambarella,crypto";
+ reg = <0x60014000 0x1000>;
+ interrupts = <45 0x1>, <46 0x1>;
+ interrupt-names = "aes-irq", "des-irq";
+ amb,binary-mode;
+ };
+ };
+
+ rct@70170000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x70170000 0x1000>;
+ ranges;
+
+ usbphy: usbphy@70170050 {
+ compatible = "ambarella,usbphy";
+ reg = <0x70170050 0x4>;
+ };
+ };
+
+ iav {
+ compatible = "ambarella,iav";
+ };
+
+ bogus_bus {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dummycodec: codec@0 {
+ compatible = "ambarella,dummycodec";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/ambarella-s2.dtsi b/arch/arm/boot/dts/ambarella-s2.dtsi
new file mode 100644
index 00000000..d9674e2d
--- /dev/null
+++ b/arch/arm/boot/dts/ambarella-s2.dtsi
@@ -0,0 +1,577 @@
+/*
+ * Copyright (C) 2013 Ambarella,Inc. - http://www.ambarella.com/
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "ambarella,s2";
+ interrupt-parent = <&gic>;
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ nand = &nand0;
+ sd0 = &sdmmc0;
+ sd1 = &sdmmc1;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ spi0 = &spi0;
+ ethernet0 = &mac0;
+ };
+
+ /* the memory node will be overwritten in Amboot,
+ * here is just the default value. */
+ memory {
+ device_type = "memory";
+ reg = <0x00200000 0x07e00000>; /* 126M */
+ };
+
+ chosen {
+ linux,stdout-path = &uart0;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ };
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <1>;
+ };
+ };
+
+ gic: interrupt-controller@f0001000 {
+ compatible = "arm,cortex-a9-gic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0xf0001000 0x1000>,
+ <0xf0000100 0x0100>;
+ };
+
+ apb@70000000 { /* APB */
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x70000000 0x01000000>;
+ ranges;
+
+ timer7: timer@7000b064 {
+ compatible = "ambarella,clock-source";
+ reg = <0x7000b064 0x10 0x7000b030 0x4>;
+ interrupts = <0 108 0x1>;
+ ctrl-offset = <24>; /* bit offset in timer-ctrl reg */
+ };
+
+ timer8: timer@7000b074 {
+ compatible = "ambarella,clock-event";
+ reg = <0x7000b074 0x10 0x7000b030 0x4>;
+ interrupts = <0 109 0x1>;
+ ctrl-offset = <28>; /* bit offset in timer-ctrl reg */
+ };
+
+ /* local_timer is not used, just for debug purpose */
+ local_timer: timer@7000b054 {
+ compatible = "ambarella,local-clock-event";
+ reg = <0x7000b054 0x10 0x7000b030 0x4 0x7000b044 0x10 0x7000b030 0x4>;
+ interrupts = <0 107 0x1 0 106 0x1>;
+ ctrl-offset = <20 16>; /* bit offset in timer-ctrl reg */
+ };
+
+ uart0: uart@70005000 {
+ compatible = "ambarella,uart";
+ reg = <0x70005000 0x100>;
+ interrupts = <0 9 0x04>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ status = "ok";
+ /* amb,tx-fifo-fix; */
+ };
+
+ uart1: uart@7001f000 {
+ compatible = "ambarella,uart";
+ reg = <0x7001f000 0x100>;
+ interrupts = <0 25 0x04>;
+ status = "disabled";
+ amb,msr-used; /* use Modem Status Register */
+ /* amb,tx-fifo-fix; */
+ };
+
+ uart2: uart@70014000 {
+ compatible = "ambarella,uart";
+ reg = <0x70014000 0x100>;
+ interrupts = <0 91 0x04>;
+ status = "disabled";
+ amb,msr-used; /* use Modem Status Register */
+ /* amb,tx-fifo-fix; */
+ };
+
+ uart3: uart@70015000 {
+ compatible = "ambarella,uart";
+ reg = <0x70015000 0x100>;
+ interrupts = <0 92 0x04>;
+ status = "disabled";
+ amb,msr-used; /* use Modem Status Register */
+ /* amb,tx-fifo-fix; */
+ };
+
+ i2c0: i2c@70003000 {
+ compatible = "ambarella,i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70003000 0x1000>;
+ interrupts = <0 19 0x04>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ clock-frequency = <100000>;
+ amb,i2c-class = <0x81>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@70007000 {
+ compatible = "ambarella,i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70007000 0x1000>;
+ interrupts = <0 36 0x04>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+ clock-frequency = <100000>;
+ amb,i2c-class = <0x08>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@70013000 {
+ compatible = "ambarella,i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70013000 0x1000>;
+ interrupts = <0 90 0x04>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+ clock-frequency = <100000>;
+ amb,i2c-class = <0x81>;
+ status = "disabled";
+ };
+
+ spi0: spi@70002000 {
+ compatible = "ambarella,spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70002000 0x1000>;
+ interrupts = <0 20 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins>;
+ amb,clk-freq = <60000000>;
+ amb,msb-first-only;
+ };
+
+ spi_slave@7001e000 {
+ compatible = "ambarella,spi-slave";
+ reg = <0x7001e000 0x1000>;
+ interrupts = <0 26 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi_slave_pins>;
+ };
+
+ adc@7000d000 {
+ compatible = "ambarella,adc";
+ reg = <0x7000d000 0x1000>;
+ interrupts = <0 34 0x4>;
+ clock-frequency = <3000000>;
+ };
+
+ ir@70006000 {
+ compatible = "ambarella,ir";
+ reg = <0x70006000 0x1000>;
+ interrupts = <0 22 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_pins>;
+ };
+
+ wdt@7000c000 {
+ compatible = "ambarella,wdt";
+ reg = <0x7000c000 0x1000>;
+ /* interrupts = <0 101 0x4>; */
+ timeout-sec = <15>;
+ };
+
+ rtc@7000d000 {
+ compatible = "ambarella,rtc";
+ reg = <0x7000d000 0x1000>;
+ };
+
+ pwm: pwm@70004000 {
+ compatible = "ambarella,pwm";
+ reg = <0x70004000 0x1000 0x70008000 0x10>;
+ #pwm-cells = <3>;
+ };
+
+ pinctrl: pinctrl@70009000 {
+ compatible = "ambarella,pinctrl", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70009000 0x1000>,
+ <0x7000a000 0x1000>,
+ <0x7000e000 0x1000>,
+ <0x70010000 0x1000>,
+ <0x70011000 0x1000>;
+ reg-names = "gpio0", "gpio1", "gpio2", "gpio3", "gpio4";
+ #gpio-range-cells = <3>;
+
+ gpio: gpio@0 {
+ compatible = "ambarella,gpio";
+ /* gpio interrupts to vic */
+ interrupts = <0 10 0x04>,
+ <0 11 0x04>,
+ <0 30 0x04>,
+ <0 29 0x04>,
+ <0 48 0x04>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl 0 0 160>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ uart0_pins: uart0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x100e 0x100f>;
+ };
+
+ uart1_pins: uart1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1034 0x1035>,
+ /* virtual pins, just for configuration purpose */
+ <0x1021 0x0022 0x1032 0x1033 0x1034 0x1035>;
+ };
+
+ uart1_4pins: uart1_4pins@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1032 0x1033 0x1034 0x1035>,
+ /* virtual pins, just for configuration purpose */
+ <0x1021 0x0022 0x1032 0x1033 0x1034 0x1035>;
+ };
+
+ uart2_pins: uart2@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x100a 0x1012>;
+ };
+
+ uart3_pins: uart3@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1013 0x1014>;
+ };
+
+ nand0_pins: nand0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1027>; /* just WP is shared with GPIO */
+ };
+
+ sdmmc0_pins: sdmmc0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1041 0x1042 0x1043 0x1044>;
+ };
+
+ sdmmc1_pins_1bit: sdmmc1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1045 0x1046 0x1047
+ 0x104b 0x104c>;
+ };
+
+ sdmmc1_pins_4bit: sdmmc1@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x1045 0x1046 0x1047 0x1048
+ 0x1049 0x104a 0x104b 0x104c>;
+ };
+
+ eth_pins:eth0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1008 0x101c 0x101d 0x101e 0x101f
+ 0x1028 0x1029 0x102a 0x102b 0x102c
+ 0x102f 0x1030 0x1052 0x1053 0x105c
+ 0x105d 0x105e 0x105f 0x107c 0x107d
+ 0x107e 0x107f 0x1080 0x1088 0x1089
+ 0x108a>;
+ };
+
+ i2c0_pins: i2c0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1000 0x1001>;
+ };
+
+ i2c1_pins: i2c1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1056 0x1057>;
+ };
+
+ i2c2_pins: i2c2@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1024 0x1025>;
+ };
+
+ ir_pins: ir0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1023>;
+ };
+
+ i2s0_pins: i2s0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x104d 0x104e 0x104f 0x1050 0x1051>,
+ /* virtual pins, just for configuration purpose.*/
+ <0x0064 0x0065>;
+ };
+
+ usb_host_pins: uhc0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1007 0x1009>,
+ /* virtual pins, just for configuration purpose.
+ EHCI_PRT_PWR and APP_PRT_OVCURR share the hw
+ mode with SPI enable pin. */
+ <0x1060 0x1061>;
+ };
+
+ pwm0_pins: pwm0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x102d>;
+ };
+
+ pwm1_pins: pwm1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x102e>;
+ };
+
+ pwm2_pins: pwm2@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1032>,
+ /* virtual pins, just for
+ configuration purpose.*/
+ <0x0021 0x0022>;
+ };
+
+ pwm3_pins: pwm3@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1033>,
+ /* virtual pins, just for
+ configuration purpose.*/
+ <0x0022 0x0003>;
+ };
+
+ pwm5_pins: pwm5@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1010>;
+ };
+
+ spi0_pins: spi0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1002 0x1003 0x1004>;
+ };
+
+ spi_slave_pins: spi_slave@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1032 0x1033 0x1034 0x1035>,
+ /* virtual pins, just for
+ configuration purpose.*/
+ <0x0021 0x1022>;
+ };
+ };
+ };
+
+ ahb@60000000 { /* AHB */
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x60000000 0x01000000>;
+ ranges;
+
+ dma: dma@60005000 {
+ compatible = "ambarella,dma";
+ reg = <0x60005000 0x1000>;
+ interrupts = <0 15 0x4>;
+ #dma-cells = <2>;
+ dma-channels = <5>;
+ dma-requests = <5>;
+ dma-trans-type = <0 1 1 1 1>; /* 0-memcpy ,1-slave*/
+ amb,copy-align = <3>;
+ };
+
+ nand0: nand@60001000 {
+ compatible = "ambarella,nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x60001000 0x1000>, /* fio reg address */
+ <0x60012000 0x1000>, /* fdma reg address */
+ <0x60000000 0x4>; /* fifo base */
+ interrupts = <0 16 0x04>, /* fio_cmd_irq */
+ <0 17 0x04>, /* fio_dma_irq */
+ <0 33 0x04>; /* fdma_irq */
+ pinctrl-names = "default";
+ pinctrl-0 = <&nand0_pins>;
+ nand-on-flash-bbt;
+ amb,enable-wp;
+ };
+
+ i2s0: i2s@6000a000 {
+ compatible = "ambarella,i2s";
+ reg = <0x6000a000 0x1000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_pins>;
+ amb,i2s-channels = <2>;
+ amb,default-mclk = <12288000>;
+ dmas = <&dma 1 1>,
+ <&dma 0 1>;
+ dma-names = "tx", "rx";
+ };
+
+ udc@60006000 {
+ compatible = "ambarella,udc";
+ reg = <0x60006000 0x2000 0x70170088 0x4>;
+ interrupts = <0 4 0x04>;
+ amb,usbphy = <&usbphy>;
+ amb,dma-addr-fix;
+ };
+
+ ehci@60018000 {
+ compatible = "ambarella,ehci";
+ reg = <0x60018000 0x1000>;
+ interrupts = <0 73 0x04>;
+ amb,usbphy = <&usbphy>;
+ };
+
+ ohci@60019000 {
+ compatible = "ambarella,ohci";
+ reg = <0x60019000 0x1000>;
+ interrupts = <0 89 0x04>;
+ amb,usbphy = <&usbphy>;
+ status = "disabled";
+ };
+
+ sdmmc0: sdmmc0@60002000 {
+ compatible = "ambarella,sdmmc";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x60002000 0x1000>,
+ <0x60001000 0x80>, /* fio reg address */
+ <0x701701d0 0x4>;
+ interrupts = <0 18 0x4>;
+ amb,clk-name = "gclk_sd";
+ amb,wait-tmo = <10000>; /* in millisecond */
+ amb,switch_vol_tmo = <20>;
+ amb,max-blk-size = <524288>; /* valid value: 4K<<n */
+ amb,phy-timing = <0x00000001 0xe3e0e3e0 0x00000000>,
+ <0x00000080 0xe3e0e3e0 0x00071c00>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc0_pins>;
+
+ slot@0 {
+ reg = <0>;
+ global-id = <0>;
+ max-frequency = <48000000>;
+ bus-width = <8>;
+ amb,caps-ddr;
+ cap-sdio-irq;
+ };
+ };
+
+ sdmmc1: sdmmc1@6000c000 {
+ compatible = "ambarella,sdmmc";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x6000c000 0x1000>,
+ <0x60001000 0x80>, /* fio reg address */
+ <0x701701d0 0x4>;
+ interrupts = <0 52 0x4>;
+ amb,dma-addr-fix;
+ amb,clk-name = "gclk_sdio";
+ amb,wait-tmo = <10000>; /* in millisecond */
+ amb,switch_vol_tmo = <20>;
+ amb,max-blk-size = <524288>; /* valid value: 4K<<n */
+ amb,phy-timing = <0x00000001 0x1c1f1c1f 0x00000000>,
+ <0x00000080 0x1c1f1c1f 0x00e0e000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_pins_4bit>;
+
+ slot@0 {
+ reg = <0>;
+ global-id = <1>;
+ max-frequency = <48000000>;
+ bus-width = <4>;
+ amb,caps-ddr;
+ cap-sdio-irq;
+ };
+ };
+
+ mac0: ethernet@6000e000 {
+ compatible = "ambarella,eth";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x6000e000 0x2000>;
+ interrupts = <0 27 0x4>;
+ amb,support-gmii;
+ amb,tx-ring-size = <64>;
+ amb,rx-ring-size = <64>;
+ amb,ipc-rx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&eth_pins>;
+ };
+ };
+
+ axi@f0000000 { /* AXI */
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xf0000000 0x00030000>;
+ ranges;
+
+ crypto@f0020000 {
+ compatible = "ambarella,crypto";
+ reg = <0xf0020000 0x8000>;
+ interrupts = <0 122 0x1>, <0 121 0x1>, <0 120 0x1>, <0 123 0x1>;
+ interrupt-names = "aes-irq", "des-irq", "md5-irq", "sha1-irq";
+ amb,cap-md5-sha1;
+ amb,data-swap;
+ amb,reg-64bit;
+ };
+ };
+
+ rct@70170000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x70170000 0x1000>;
+ ranges;
+
+ usbphy: usbphy@70170050 {
+ compatible = "ambarella,usbphy";
+ reg = <0x70170050 0x4 0x6001b00c 0x4 0x70170088 0x4>;
+ amb,host-phy-num = <1>;
+ };
+ };
+
+ iav {
+ compatible = "ambarella,iav";
+ };
+
+ bogus_bus {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dummycodec: codec@0 {
+ compatible = "ambarella,dummycodec";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/ambarella-s2e.dtsi b/arch/arm/boot/dts/ambarella-s2e.dtsi
new file mode 100644
index 00000000..cfd40dad
--- /dev/null
+++ b/arch/arm/boot/dts/ambarella-s2e.dtsi
@@ -0,0 +1,632 @@
+/*
+ * Copyright (C) 2013 Ambarella,Inc. - http://www.ambarella.com/
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "ambarella,s2e";
+ interrupt-parent = <&intc>;
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ nand = &nand0;
+ sd0 = &sdmmc0;
+ sd1 = &sdmmc1;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ spi0 = &spi0;
+ spi1 = &spi1;
+ ethernet0 = &mac0;
+ };
+
+ /* the memory node will be overwritten in Amboot,
+ * here is just the default value. */
+ memory {
+ device_type = "memory";
+ reg = <0x00200000 0x07e00000>; /* 126M */
+ };
+
+ chosen {
+ linux,stdout-path = &uart0;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ amb,core-div = <1>;
+ clock-latency = <100000>;
+ /* the highest frequency is gotten in runtime */
+ cpufreq_tbl = < /*core_clk cortex_clk*/
+ 24000 24000
+ 108000 504000>;
+ cpu@a00 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0xa00>;
+ };
+ cpu@a01 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0xa01>;
+ };
+ };
+
+ apb@70000000 { /* APB */
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x70000000 0x01000000>;
+ ranges;
+
+ timer7: timer@7000b064 {
+ compatible = "ambarella,clock-source";
+ reg = <0x7000b064 0x10 0x7000b030 0x4>;
+ interrupts = <62 0x1>;
+ ctrl-offset = <24>; /* bit offset in timer-ctrl reg */
+ };
+
+ timer8: timer@7000b074 {
+ compatible = "ambarella,clock-event";
+ reg = <0x7000b074 0x10 0x7000b030 0x4>;
+ interrupts = <63 0x1>;
+ ctrl-offset = <28>; /* bit offset in timer-ctrl reg */
+ };
+
+ /* timer6 and timer5 */
+ local_timer: timer@7000b054 {
+ compatible = "ambarella,local-clock-event";
+ reg = <0x7000b054 0x10 0x7000b030 0x4 0x7000b044 0x10 0x7000b030 0x4>;
+ interrupts = <61 0x1 60 0x1>;
+ ctrl-offset = <20 16>; /* bit offset in timer-ctrl reg */
+ };
+
+ uart0: uart@70005000 {
+ compatible = "ambarella,uart";
+ reg = <0x70005000 0x100>;
+ interrupts = <9 0x04>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ status = "ok";
+ /* amb,tx-fifo-fix; */
+ };
+
+ uart1: uart@7001f000 {
+ compatible = "ambarella,uart";
+ reg = <0x7001f000 0x100>;
+ interrupts = <25 0x04>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ status = "ok";
+ amb,msr-used; /* use Modem Status Register */
+ amb,txdma-used;
+ amb,rxdma-used;
+ /* amb,tx-fifo-fix; */
+ };
+
+ uart2: uart@70014000 {
+ compatible = "ambarella,uart";
+ reg = <0x70014000 0x100>;
+ interrupts = <91 0x04>;
+ status = "disabled";
+ amb,msr-used; /* use Modem Status Register */
+ /* amb,tx-fifo-fix; */
+ };
+
+ uart3: uart@70015000 {
+ compatible = "ambarella,uart";
+ reg = <0x70015000 0x100>;
+ interrupts = <92 0x04>;
+ status = "disabled";
+ amb,msr-used; /* use Modem Status Register */
+ /* amb,tx-fifo-fix; */
+ };
+
+ i2c0: i2c@70003000 {
+ compatible = "ambarella,i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70003000 0x1000>;
+ interrupts = <19 0x04>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ clock-frequency = <100000>;
+ amb,i2c-class = <0x81>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@70007000 {
+ compatible = "ambarella,i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70007000 0x1000>;
+ interrupts = <36 0x04>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+ clock-frequency = <100000>;
+ amb,i2c-class = <0x08>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@70013000 {
+ compatible = "ambarella,i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70013000 0x1000>;
+ interrupts = <90 0x04>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+ clock-frequency = <100000>;
+ amb,i2c-class = <0x81>;
+ status = "disabled";
+ };
+
+ spi0: spi@70002000 {
+ compatible = "ambarella,spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70002000 0x1000>;
+ interrupts = <20 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins>;
+ amb,clk-freq = <60000000>;
+ amb,msb-first-only;
+ };
+
+ spi_slave@7001e000 {
+ compatible = "ambarella,spi-slave";
+ reg = <0x7001e000 0x1000>;
+ interrupts = <26 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi_slave_pins>;
+ status = "disabled";
+ };
+
+ adc@7000d000 {
+ compatible = "ambarella,adc";
+ reg = <0x7000d000 0x1000>;
+ interrupts = <34 0x4>;
+ clock-frequency = <3000000>;
+ };
+
+ ir@70006000 {
+ compatible = "ambarella,ir";
+ reg = <0x70006000 0x1000>;
+ interrupts = <22 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_pins>;
+ };
+
+ wdt@7000c000 {
+ compatible = "ambarella,wdt";
+ reg = <0x7000c000 0x1000>;
+ /* interrupts = <21 0x4>; */
+ timeout-sec = <15>;
+ };
+
+ rtc@7000d000 {
+ compatible = "ambarella,rtc";
+ reg = <0x7000d000 0x1000>;
+ rtc,wakeup;
+ };
+
+ pwm: pwm@70004000 {
+ compatible = "ambarella,pwm";
+ reg = <0x70004000 0x1000 0x70008000 0x10>;
+ #pwm-cells = <3>;
+ };
+
+ pinctrl: pinctrl@70009000 {
+ compatible = "ambarella,pinctrl", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70009000 0x1000>,
+ <0x7000a000 0x1000>,
+ <0x7000e000 0x1000>,
+ <0x70010000 0x1000>,
+ <0x70011000 0x1000>;
+ reg-names = "gpio0", "gpio1", "gpio2", "gpio3", "gpio4";
+ #gpio-range-cells = <3>;
+
+ gpio: gpio@0 {
+ compatible = "ambarella,gpio";
+ /* gpio interrupts to vic */
+ interrupts = <10 0x04>,
+ <11 0x04>,
+ <30 0x04>,
+ <29 0x04>,
+ <48 0x04>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl 0 0 160>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ uart0_pins: uart0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x100e 0x100f>;
+ };
+
+ uart1_pins: uart1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1034 0x1035>,
+ /* virtual pins, just for configuration purpose */
+ <0x1021 0x0022 0x1032 0x1033>;
+ };
+
+ uart1_4pins: uart1_4pins@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1032 0x1033 0x1034 0x1035>,
+ /* virtual pins, just for configuration purpose */
+ <0x1021 0x0022>;
+ };
+
+ uart2_pins: uart2@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x100a 0x1012>;
+ };
+
+ uart3_pins: uart3@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1013 0x1014>;
+ };
+
+ nand0_pins: nand0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1027>; /* just WP is shared with GPIO */
+ };
+
+ sdmmc0_pins: sdmmc0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1041 0x1042 0x1043 0x1044>;
+ };
+
+ sdmmc1_pins_1bit: sdmmc1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1045 0x1046 0x1047
+ 0x104b 0x104c>;
+ };
+
+ sdmmc1_pins_4bit: sdmmc1@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x1045 0x1046 0x1047 0x1048
+ 0x1049 0x104a 0x104b 0x104c>;
+ };
+
+ eth_pins: eth0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1008 0x101c 0x101d 0x101e 0x101f
+ 0x1028 0x1029 0x102a 0x102b 0x102c
+ 0x102f 0x1030 0x1052 0x1053 0x105c
+ 0x105d 0x105e 0x105f 0x107c 0x107d
+ 0x107e 0x107f 0x1080 0x1088 0x1089
+ 0x108a>;
+ };
+
+ i2c0_pins: i2c0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1000 0x1001>;
+ };
+
+ i2c1_pins: i2c1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1056 0x1057>;
+ };
+
+ i2c2_pins: i2c2@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1024 0x1025>,
+ /* virtual pins, just for configuration purpose */
+ <0x1011>;
+ };
+
+ ir_pins: ir0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1023>;
+ };
+
+ i2s0_pins: i2s0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x104d 0x104e 0x104f 0x1050 0x1051>,
+ /* virtual pins, just for configuration purpose.*/
+ <0x0064 0x0065>;
+ };
+
+ usb_host_pins: uhc0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1007 0x1009>,
+ /* virtual pins, just for configuration purpose.
+ EHCI_PRT_PWR and APP_PRT_OVCURR share the hw
+ mode with SPI enable pin. */
+ <0x1060 0x1061>;
+ };
+
+ pwm0_pins: pwm0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x102d>;
+ };
+
+ pwm1_pins: pwm1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x102e>;
+ };
+
+ pwm2_pins: pwm2@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1032>,
+ /* virtual pins, just for
+ configuration purpose.*/
+ <0x0021 0x0022>;
+ };
+
+ pwm3_pins: pwm3@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1033>,
+ /* virtual pins, just for
+ configuration purpose.
+ <0x0022>: kernel may throw out error,
+ ignore it.*/
+ <0x0022 0x0023>;
+ };
+
+ pwmVD_pins: pwmVD@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1010>;
+ };
+
+ spi0_pins: spi0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1002 0x1003 0x1004>;
+ };
+
+ spi1_pins: spi1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1058 0x1059 0x105A>;
+ };
+
+ spi_slave_pins: spi_slave@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1032 0x1033 0x1034 0x1035>,
+ /* virtual pins, just for
+ configuration purpose.*/
+ <0x0021 0x1022>;
+ };
+ };
+ };
+
+ ahb@60000000 { /* AHB */
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x60000000 0x01000000>;
+ ranges;
+
+ intc: interrupt-controller@60003000 {
+ compatible = "ambarella,vic";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x60003000 0x1000>,
+ <0x60010000 0x1000>,
+ <0x6001c000 0x1000>;
+ };
+
+ dma: dma@60005000 {
+ compatible = "ambarella,dma";
+ reg = <0x60005000 0x1000>;
+ interrupts = <15 0x4>;
+ #dma-cells = <2>;
+ dma-channels = <8>;
+ dma-requests = <8>;
+ dma-trans-type = <1 1 1 1 1 1 1 1>; /* 0-memcpy ,1-slave*/
+ amb,copy-align = <0>;
+ /* support pause/resume/stop */
+ amb,support-prs;
+ };
+
+ nand0: nand@60001000 {
+ compatible = "ambarella,nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x60001000 0x1000>, /* fio reg address */
+ <0x60012000 0x1000>, /* fdma reg address */
+ <0x60000000 0x4>; /* fifo base */
+ interrupts = <16 0x04>, /* fio_cmd_irq */
+ <17 0x04>, /* fio_dma_irq */
+ <33 0x04>; /* fdma_irq */
+ pinctrl-names = "default";
+ pinctrl-0 = <&nand0_pins>;
+ nand-on-flash-bbt;
+ amb,enable-wp;
+ /* amb,soft-ecc = <1>; */
+ };
+
+ spinor0: spinor@6000d000 {
+ compatible = "ambarella,spinor";
+ reg = <0x6000d000 0x2ff>, /* spi nor controller */
+ <0x60005300 0x20>; /* dma reg */
+ status = "disabled";
+ };
+
+ spi1: spi@6001f000 {
+ compatible = "ambarella,spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x6001f000 0x1000>;
+ interrupts = <53 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pins>;
+ amb,clk-freq = <54000000>;
+ status = "disabled";
+ };
+
+ i2s0: i2s@6000a000 {
+ compatible = "ambarella,i2s";
+ reg = <0x6000a000 0x1000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_pins>;
+ amb,i2s-channels = <2>;
+ amb,default-mclk = <12288000>;
+ dmas = <&dma 2 1>,
+ <&dma 1 1>;
+ dma-names = "tx", "rx";
+ };
+
+ udc@60006000 {
+ compatible = "ambarella,udc";
+ reg = <0x60006000 0x2000 0x70170088 0x4>;
+ interrupts = <4 0x04>;
+ amb,usbphy = <&usbphy>;
+ };
+
+ ehci@60018000 {
+ compatible = "ambarella,ehci";
+ reg = <0x60018000 0x1000>;
+ interrupts = <73 0x04>;
+ amb,usbphy = <&usbphy>;
+ };
+
+ ohci@60019000 {
+ compatible = "ambarella,ohci";
+ reg = <0x60019000 0x1000>;
+ interrupts = <89 0x04>;
+ amb,usbphy = <&usbphy>;
+ };
+
+ sdmmc0: sdmmc0@60002000 {
+ compatible = "ambarella,sdmmc";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x60002000 0x1000>,
+ <0x60001000 0x80>, /* fio reg address */
+ <0x70170340 0x8>;
+ interrupts = <18 0x4>;
+ amb,clk-name = "gclk_sd";
+ amb,wait-tmo = <10000>; /* in millisecond */
+ amb,switch_vol_tmo = <20>;
+ amb,max-blk-size = <524288>; /* valid value: 4K<<n */
+ amb,auto-tuning;
+ amb,phy-type = <0>;/*0:rct phy, 1: sd controller phy, 2: for s2e*/
+ amb,phy-timing = <0x00000001 0x04070000 0x00000000>,
+ <0x000000a4 0x00000005 0x00001111>,
+ <0x00000040 0x00000001 0x00001111>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc0_pins>;
+
+ slot@0 {
+ reg = <0>;
+ global-id = <0>;
+ max-frequency = <50000000>;
+ bus-width = <8>;
+ amb,caps-adma;
+ cap-sdio-irq;
+ };
+ };
+
+ sdmmc1: sdmmc1@6000c000 {
+ compatible = "ambarella,sdmmc";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x6000c000 0x1000>,
+ <0x60001000 0x80>, /* fio reg address */
+ <0x701701d0 0x4>;
+ interrupts = <52 0x4>;
+ amb,clk-name = "gclk_sdio";
+ amb,wait-tmo = <10000>; /* in millisecond */
+ amb,switch_vol_tmo = <20>;
+ amb,max-blk-size = <524288>; /* valid value: 4K<<n */
+ amb,auto-tuning;
+ amb,phy-type = <2>;/*0:rct phy, 1: sd controller phy, 2: for s2e*/
+ amb,phy-timing = <0x00000001 0x1c1f1c1f 0x00000000>,
+ <0x00000080 0x1c1f1c1f 0x00e0e000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_pins_4bit>;
+
+ slot@0 {
+ reg = <0>;
+ global-id = <1>;
+ max-frequency = <50000000>;
+ bus-width = <4>;
+ amb,caps-adma;
+ cap-sdio-irq;
+ };
+ };
+
+ mac0: ethernet@6000e000 {
+ compatible = "ambarella,eth";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x6000e000 0x2000>;
+ interrupts = <27 0x4>;
+ amb,support-gmii;
+ amb,tx-ring-size = <64>;
+ amb,rx-ring-size = <64>;
+ amb,ipc-rx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&eth_pins>;
+ };
+ };
+
+ axi@f0000000 { /* AXI */
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xf0000000 0x00030000>;
+ ranges;
+
+ crypto@f0020000 {
+ compatible = "ambarella,crypto";
+ reg = <0xf0020000 0x8000>;
+ interrupts = <44 0x1>, <45 0x1>, <47 0x1>, <88 0x1>;
+ interrupt-names = "aes-irq", "des-irq", "md5-irq", "sha1-irq";
+ amb,cap-md5-sha1;
+ amb,data-swap;
+ amb,reg-64bit;
+ };
+ l2-cache@f0002000 {
+ compatible = "arm,pl310-cache";
+ reg = <0xf0002000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ arm,tag_latency = <3 3 3>;
+ arm,data_latency = <3 3 3>;
+ };
+ };
+
+ rct@70170000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x70170000 0x1000>;
+ ranges;
+
+ usbphy: usbphy@70170050 {
+ compatible = "ambarella,usbphy";
+ reg = <0x70170050 0x4 0x6001b00c 0x4 0x70170088 0x4>;
+ amb,host-phy-num = <1>;
+ };
+ };
+
+ iav {
+ compatible = "ambarella,iav";
+ };
+
+ bogus_bus {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dummycodec: codec@0 {
+ compatible = "ambarella,dummycodec";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/ambarella-s2l.dtsi b/arch/arm/boot/dts/ambarella-s2l.dtsi
new file mode 100644
index 00000000..50fa4cbf
--- /dev/null
+++ b/arch/arm/boot/dts/ambarella-s2l.dtsi
@@ -0,0 +1,776 @@
+/*
+ * Copyright (C) 2013 Ambarella,Inc. - http://www.ambarella.com/
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "ambarella,s2l";
+ interrupt-parent = <&intc>;
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ nand = &nand0;
+ sd0 = &sdmmc0;
+ sd1 = &sdmmc1;
+ sd2 = &sdmmc2;
+ spinor = &spinor0;
+ spinand = &spinand0;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ spi0 = &spi0;
+ spi1 = &spi1;
+ ethernet0 = &mac0;
+ };
+
+ /* the memory node will be overwritten in Amboot,
+ * here is just the default value. */
+ memory {
+ device_type = "memory";
+ reg = <0x00200000 0x07e00000>; /* 126M */
+ };
+
+ chosen {
+ linux,stdout-path = &uart0;
+ /* the gpio used to disconnect RESET signal to
+ * dram, used for self-refresh, can be overwritten. */
+ ambarella,dram-reset-ctrl = <5>;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-latency = <100000>;
+ /* the highest frequency is gotten in runtime */
+ cpufreq_tbl = < /*core_clk cortex_clk*/
+ 24000 96000
+ 108000 504000>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ };
+ };
+
+ apb@e8000000 { /* APB */
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xe8000000 0x01000000>;
+ ranges;
+
+ timer7: timer@e800b064 {
+ compatible = "ambarella,clock-source";
+ reg = <0xe800b064 0x10 0xe800b030 0x4>;
+ interrupts = <62 0x1>;
+ ctrl-offset = <24>; /* bit offset in timer-ctrl reg */
+ };
+
+ timer8: timer@e800b074 {
+ compatible = "ambarella,clock-event";
+ reg = <0xe800b074 0x10 0xe800b030 0x4>;
+ interrupts = <63 0x1>;
+ ctrl-offset = <28>; /* bit offset in timer-ctrl reg */
+ };
+
+ uart0: uart@e8005000 {
+ compatible = "ambarella,uart";
+ reg = <0xe8005000 0x1000>;
+ interrupts = <9 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ status = "ok";
+ /* amb,tx-fifo-fix; */
+ };
+
+ i2c0: i2c@e8003000 {
+ compatible = "ambarella,i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe8003000 0x1000>;
+ interrupts = <19 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ clock-frequency = <100000>;
+ amb,i2c-class = <0x81>;
+ /* amb,duty-cycle = <0>; */
+ status = "disabled";
+ };
+
+ i2c1: i2c@e8001000 {
+ compatible = "ambarella,i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe8001000 0x1000>;
+ interrupts = <51 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+ clock-frequency = <100000>;
+ amb,i2c-class = <0x08>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@e8007000 {
+ compatible = "ambarella,i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe8007000 0x1000>;
+ interrupts = <36 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+ clock-frequency = <100000>;
+ amb,i2c-class = <0x81>;
+ status = "disabled";
+ };
+
+ adc@e801d000 {
+ compatible = "ambarella,adc";
+ reg = <0xe801d000 0x1000>;
+ interrupts = <34 0x4>;
+ clock-frequency = <3000000>;
+ };
+
+ ir@e8006000 {
+ compatible = "ambarella,ir";
+ reg = <0xe8006000 0x1000>;
+ interrupts = <22 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_pins>;
+ };
+
+ wdt@e800c000 {
+ compatible = "ambarella,wdt";
+ reg = <0xe800c000 0x1000>;
+ /* interrupts = <21 0x4>; */
+ timeout-sec = <15>;
+ };
+
+ rtc@e8015000 {
+ compatible = "ambarella,rtc";
+ reg = <0xe8015000 0x1000>;
+ rtc,wakeup;
+ };
+
+ pwm: pwm@e8008000 {
+ compatible = "ambarella,pwm";
+ reg = <0xe8008000 0x1000>;
+ #pwm-cells = <3>;
+ };
+
+ pinctrl: pinctrl@e8009000 {
+ compatible = "ambarella,pinctrl", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe8009000 0x1000>,
+ <0xe800a000 0x1000>,
+ <0xe800e000 0x1000>,
+ <0xe8010000 0x1000>,
+ <0xe8016000 0x1000>;
+ reg-names = "gpio0", "gpio1", "gpio2", "gpio3", "iomux";
+ #gpio-range-cells = <3>;
+
+ gpio: gpio@0 {
+ compatible = "ambarella,gpio";
+ /* gpio interrupts to vic */
+ interrupts = <10 0x4 11 0x4 30 0x4 29 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl 0 0 128>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ uart0_pins: uart0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1027 0x1028>;
+ };
+
+ uart1_pins_a: uart1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x2001 0x2002>;
+ };
+
+ uart1_pins_b: uart1@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x200f 0x2010>;
+ };
+
+ uart1_pins_c: uart1@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x2013 0x2014>;
+ };
+
+ uart1_pins_d: uart1@3 {
+ reg = <3>;
+ amb,pinmux-ids = <0x3022 0x3023>;
+ };
+
+ uart1_pins_e: uart1@4 {
+ reg = <4>;
+ amb,pinmux-ids = <0x2027 0x2028>;
+ };
+
+ uart1_flow_pins_a: uart1_flow@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x2003 0x2004>;
+ };
+
+ uart1_flow_pins_b: uart1_flow@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x5005 0x5006>;
+ };
+
+ uart1_flow_pins_c: uart1_flow@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x2011 0x2012>;
+ };
+
+ uart1_flow_pins_d: uart1_flow@3 {
+ reg = <3>;
+ amb,pinmux-ids = <0x3015 0x3016>;
+ };
+
+ uart1_flow_pins_e: uart1_flow@4 {
+ reg = <4>;
+ amb,pinmux-ids = <0x3024 0x3025>;
+ };
+
+ nand0_pins: nand0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x2036 0x2037 0x2038 0x203d
+ 0x203e 0x203f 0x2040 0x2041
+ 0x2042 0x2043 0x2044 0x2045
+ 0x2046 0x2047 0x2048>;
+ };
+
+ spinor0_pins: spinor0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x3037 0x3038 0x303d 0x303e
+ 0x303f 0x3040 0x3041 0x3042
+ 0x3043 0x3044 0x3045 0x3046
+ 0x3047>;
+ };
+
+ sdmmc0_cd_pin: sdmmc0_cd@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x203b>;
+ };
+
+ sdmmc0_wp_pin: sdmmc0_wp@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x203c>;
+ };
+
+ sdmmc0_pins_1bit: sdmmc0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x2039 0x203a 0x2049>;
+ };
+
+ sdmmc0_pins_4bit: sdmmc0@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x2039 0x203a 0x2049
+ 0x204a 0x204b 0x204c>;
+ };
+
+ sdmmc0_pins_8bit: sdmmc0@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x2039 0x203a 0x2049 0x204a 0x204b
+ 0x204c 0x204d 0x204e 0x204f 0x2050>;
+ };
+
+ sdmmc1_cd_pin: sdmmc1_cd@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x2057>;
+ };
+
+ sdmmc1_wp_pin: sdmmc1_wp@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x2058>;
+ };
+
+ sdmmc1_pins_1bit: sdmmc1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x2051 0x2052 0x2053>;
+ };
+
+ sdmmc1_pins_4bit: sdmmc1@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x2051 0x2052 0x2053
+ 0x2054 0x2055 0x2056>;
+ };
+
+ sdmmc2_cd_pin: sdmmc2_cd@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x5008>;
+ };
+
+ sdmmc2_wp_pin: sdmmc2_wp@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x5009>;
+ };
+
+ sdmmc2_pins_1bit: sdmmc2@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x5007 0x500a 0x5012>;
+ };
+
+ sdmmc2_pins_4bit: sdmmc2@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x5007 0x500a 0x500b
+ 0x500c 0x500d 0x5012>;
+ };
+
+ sdmmc2_pins_8bit: sdmmc2@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x5007 0x500a 0x500b 0x500c 0x500d
+ 0x500e 0x500f 0x5010 0x5011 0x5012>;
+ };
+
+ eth_pins: eth0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x4019 0x401a 0x102e 0x102f
+ 0x1030 0x1031 0x1032 0x1033
+ 0x1034 0x1035>;
+ };
+
+ i2c0_pins: i2c0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x101b 0x101c>;
+ };
+
+ i2c1_pins: i2c1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x101d 0x101e>;
+ };
+
+ i2c2_pins: i2c2@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x101f 0x1020>;
+ };
+
+ ir_pins: ir0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1021>;
+ };
+
+ i2s0_pins: i2s0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1029 0x102a 0x102b 0x102c 0x102d>;
+ };
+
+ usb_host0_pins: uhc0@0 { /* USB0: host/device configurable */
+ reg = <0>;
+ amb,pinmux-ids = <0x1002 0x1004>;
+ };
+
+ usb_host1_pins: uhc1@0 { /* USB1: host only */
+ reg = <0>;
+ amb,pinmux-ids = <0x1001 0x1003>;
+ };
+
+ pwm0_pins_a: pwm0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x4007>;
+ };
+
+ pwm0_pins_b: pwm0@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x5013>;
+ };
+
+ pwm0_pins_c: pwm0@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x1071>;
+ };
+
+ pwm1_pins_a: pwm1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1005>;
+ };
+
+ pwm1_pins_b: pwm1@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x4008>;
+ };
+
+ pwm1_pins_c: pwm1@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x5014>;
+ };
+
+ pwm1_pins_d: pwm1@3 {
+ reg = <3>;
+ amb,pinmux-ids = <0x5017>;
+ };
+
+ pwm2_pins_a: pwm2@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1006>;
+ };
+
+ pwm2_pins_b: pwm2@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x4009>;
+ };
+
+ pwm2_pins_c: pwm2@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x5015>;
+ };
+
+ pwm3_pins_a: pwm3@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x400a>;
+ };
+
+ pwm3_pins_b: pwm3@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x200e>;
+ };
+
+ pwm3_pins_c: pwm3@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x5016>;
+ };
+
+ spi_slave_pins_a: spi_slave@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x4022 0x4023 0x4024 0x4025>;
+ };
+
+ spi_slave_pins_b: spi_slave@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x3013 0x3014 0x3015 0x3016>;
+ };
+
+ spi0_pins: spi0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1022 0x1023 0x1024>;
+ };
+
+ spi1_pins_a: spi1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x2007 0x2008 0x2009>;
+ };
+
+ spi1_pins_b: spi1@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x402e 0x402f 0x4030>;
+ };
+ };
+ };
+
+ ahb@e0000000 { /* AHB */
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xe0000000 0x01000000>;
+ ranges;
+
+ intc: interrupt-controller@e0003000 {
+ compatible = "ambarella,vic";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0xe0003000 0x1000>,
+ <0xe0010000 0x1000>,
+ <0xe001c000 0x1000>;
+ };
+
+ dma: dma@e0005000 {
+ compatible = "ambarella,dma";
+ reg = <0xe0005000 0x1000>;
+ interrupts = <15 0x4>;
+ #dma-cells = <2>;
+ dma-channels = <8>;
+ dma-requests = <12>;
+ dma-trans-type = <1 1 0 0 1 1 1 1>; /* 0-memcpy ,1-slave*/
+ amb,copy-align = <0>;
+ };
+
+ nand0: nand@e0001000 {
+ compatible = "ambarella,nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xe0001000 0x1000>, /* fio reg address */
+ <0xe0012000 0x1000>, /* fdma reg address */
+ <0xe0000000 0x4>; /* fifo base */
+ interrupts = <16 0x4>, /* fio_cmd_irq */
+ <17 0x4>, /* fio_dma_irq */
+ <33 0x4>; /* fdma_irq */
+ pinctrl-names = "default";
+ pinctrl-0 = <&nand0_pins>;
+ nand-on-flash-bbt;
+ amb,enable-wp;
+ /* amb,soft-ecc = <1>; */
+ };
+
+ spinor0: spinor@e0031000 {
+ compatible = "ambarella,spinor";
+ reg = <0xe0031000 0x2ff>, /* spi nor controller */
+ <0xe0005300 0x20>; /* dma reg */
+ pinctrl-names = "default";
+ pinctrl-0 = <&spinor0_pins>;
+ status = "disabled";
+ };
+
+ spinand0: spinand@e0031000 {
+ compatible = "ambarella,spinand";
+ reg = <0xe0031000 0x2ff>, /* spi nor controller */
+ <0xe0005300 0x20>; /* dma reg */
+ pinctrl-names = "default";
+ pinctrl-0 = <&spinor0_pins>;
+ status = "disabled";
+ };
+
+ uart1: uart@e0032000 {
+ compatible = "ambarella,uart";
+ reg = <0xe0032000 0x1000>;
+ interrupts = <25 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins_b &uart1_flow_pins_c>;
+ status = "disabled";
+ amb,msr-used; /* use Modem Status Register */
+ amb,txdma-used;
+ amb,rxdma-used;
+ /* amb,tx-fifo-fix; */
+ /* need to select pinctrl setup in board dts */
+ };
+
+ i2s0: i2s@e001a000 {
+ compatible = "ambarella,i2s";
+ reg = <0xe001a000 0x1000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_pins>;
+ amb,i2s-channels = <2>;
+ amb,default-mclk = <12288000>;
+ dmas = <&dma 5 1>,
+ <&dma 4 1>;
+ dma-names = "tx", "rx";
+ };
+
+ udc@e0006000 {
+ compatible = "ambarella,udc";
+ reg = <0xe0006000 0x2000 0xec1702cc 0x4>;
+ interrupts = <4 0x4>;
+ amb,usbphy = <&usbphy>;
+ };
+
+ ehci@e0018000 {
+ compatible = "ambarella,ehci";
+ reg = <0xe0018000 0x1000>;
+ interrupts = <39 0x4>;
+ amb,usbphy = <&usbphy>;
+ };
+
+ ohci@e0019000 {
+ compatible = "ambarella,ohci";
+ reg = <0xe0019000 0x1000>;
+ interrupts = <44 0x4>;
+ amb,usbphy = <&usbphy>;
+ };
+
+ sdmmc0: sdmmc0@e0002000 {
+ compatible = "ambarella,sdmmc";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe0002000 0x1000>,
+ <0xe0001000 0x80>, /* fio reg address */
+ <0xec1704c0 0x8>;
+ interrupts = <18 0x4>;
+ amb,clk-name = "gclk_sd";
+ amb,wait-tmo = <10000>; /* in millisecond */
+ amb,switch_vol_tmo = <20>;
+ amb,max-blk-size = <131072>; /* valid value: 4K<<n */
+ amb,auto-tuning;
+ amb,phy-type = <0>;/*0:rct phy, 1: sd controller phy, 2: for s2e*/
+ amb,phy-timing = <0x00000001 0x04070000 0x00000000>,
+ <0x00000040 0x00000001 0x00001111>,/*for sdr104 200M*/
+ <0x000000A4 0x00000005 0x00001111>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc0_pins_8bit &sdmmc0_cd_pin &sdmmc0_wp_pin>;
+
+ slot@0 {
+ reg = <0>;
+ global-id = <0>;
+ max-frequency = <50000000>;
+ bus-width = <8>;
+ amb,caps-adma;
+ amb,caps-ddr;
+ cap-sdio-irq;
+ };
+ };
+
+ sdmmc1: sdmmc1@e000c000 {
+ compatible = "ambarella,sdmmc";
+ reg = <0xe000c000 0x1000>,
+ <0xe0001000 0x80>; /* fio reg address */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <52 0x4>;
+ amb,clk-name = "gclk_sdio";
+ amb,wait-tmo = <10000>; /* in millisecond */
+ amb,switch_vol_tmo = <20>;
+ amb,max-blk-size = <131072>; /* valid value: 4K<<n */
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_pins_4bit &sdmmc1_cd_pin &sdmmc1_wp_pin>;
+ status = "disabled";
+
+ slot@0 {
+ reg = <0>;
+ global-id = <1>;
+ max-frequency = <50000000>;
+ bus-width = <4>;
+ amb,caps-adma;
+ cap-sdio-irq;
+ };
+ };
+
+ sdmmc2: sdmmc2@e001f000 {
+ compatible = "ambarella,sdmmc";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe001f000 0x1000>,
+ <0xe0001000 0x80>; /* fio reg address */
+ interrupts = <20 0x4>;
+ amb,clk-name = "gclk_sdxc";
+ amb,wait-tmo = <10000>; /* in millisecond */
+ amb,switch_vol_tmo = <20>;
+ amb,max-blk-size = <131072>; /* valid value: 4K<<n */
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc2_pins_8bit &sdmmc2_cd_pin &sdmmc2_wp_pin>;
+ status = "disabled";
+
+ slot@0 {
+ reg = <0>;
+ global-id = <2>;
+ max-frequency = <50000000>;
+ bus-width = <8>;
+ amb,caps-adma;
+ cap-sdio-irq;
+ };
+ };
+
+ mac0: ethernet@e000e000 {
+ compatible = "ambarella,eth";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe000e000 0x2000>;
+ interrupts = <27 0x4>;
+ amb,tx-ring-size = <32>;
+ amb,rx-ring-size = <64>;
+ amb,ipc-tx;
+ amb,ipc-rx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&eth_pins>;
+ };
+
+ spi0: spi@e0020000 {
+ compatible = "ambarella,spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe0020000 0x1000>;
+ interrupts = <35 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins>;
+ amb,clk-freq = <54000000>;
+ amb,dma-used;
+ dmas = <&dma 0 1>,
+ <&dma 1 1>;
+ dma-names = "tx", "rx";
+ };
+
+ spi1: spi@e0021000 {
+ compatible = "ambarella,spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe0021000 0x1000>;
+ interrupts = <37 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pins_a>;
+ amb,clk-freq = <54000000>;
+ status = "disabled";
+ };
+
+ spi_slave@e0026000 {
+ compatible = "ambarella,spi-slave";
+ reg = <0xe0026000 0x1000>;
+ interrupts = <38 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi_slave_pins_a>;
+ status = "disabled";
+ };
+ };
+
+ axi@f0000000 { /* AXI */
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xf0000000 0x00030000>;
+ ranges;
+
+ crypto@f0020000 {
+ compatible = "ambarella,crypto";
+ reg = <0xf0020000 0x8000>;
+ interrupts = <88 0x1>, <87 0x1>, <86 0x1>, <89 0x1>;
+ interrupt-names = "aes-irq", "des-irq", "md5-irq", "sha1-irq";
+ amb,cap-md5-sha1;
+ amb,data-swap;
+ amb,reg-64bit;
+ };
+ l2-cache@f0002000 {
+ compatible = "arm,pl310-cache";
+ reg = <0xf0002000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ /* l2 cache latency use default setting */
+ /* arm,tag_latency = <1 2 1>; */
+ /* arm,data_latency = <1 3 1>; */
+ };
+ };
+
+ rct@ec170000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xec170000 0x1000>;
+ ranges;
+
+ usbphy: usbphy@ec170050 {
+ compatible = "ambarella,usbphy";
+ reg = <0xec170050 0x4 0xe001b00c 0x4 0xec1702c0 0x4>;
+ amb,host-phy-num = <2>;
+ amb,owner-mask;
+ amb,owner-invert;
+ };
+ };
+
+ iav {
+ compatible = "ambarella,iav";
+ };
+
+ bogus_bus {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dummycodec: codec@0 {
+ compatible = "ambarella,dummycodec";
+ };
+ };
+
+ amba_lens {
+ compatible = "ambarella,lens";
+ interrupts = <12 0x1>, /* zoom_timer_irq */
+ <13 0x1>, /* focus_timer_irq */
+ <14 0x1>; /* iris_timer_irq */
+ };
+
+};
diff --git a/arch/arm/boot/dts/ambarella-s3.dtsi b/arch/arm/boot/dts/ambarella-s3.dtsi
new file mode 100644
index 00000000..7d2e6d5f
--- /dev/null
+++ b/arch/arm/boot/dts/ambarella-s3.dtsi
@@ -0,0 +1,703 @@
+/*
+ * Copyright (C) 2013 Ambarella,Inc. - http://www.ambarella.com/
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "ambarella,s3";
+ interrupt-parent = <&intc>;
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ nand = &nand0;
+ spinor = &spinor0;
+ sd0 = &sdmmc0;
+ sd1 = &sdmmc1;
+ sd2 = &sdmmc2;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ spi0 = &spi0;
+ spi1 = &spi1;
+ ethernet0 = &mac0;
+ };
+
+ /* the memory node will be overwritten in Amboot,
+ * here is just the default value. */
+ memory {
+ device_type = "memory";
+ reg = <0x00200000 0x07e00000>; /* 126M */
+ };
+
+ chosen {
+ linux,stdout-path = &uart0;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu@a00 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0xa00>;
+ };
+ cpu@a01 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0xa01>;
+ };
+ };
+
+ apb@e8000000 { /* APB */
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xe8000000 0x01000000>;
+ ranges;
+
+ timer7: timer@e800b064 {
+ compatible = "ambarella,clock-source";
+ reg = <0xe800b064 0x10 0xe800b030 0x4>;
+ interrupts = <13 0x1>;
+ ctrl-offset = <24>; /* bit offset in timer-ctrl reg */
+ };
+
+ timer8: timer@e800b074 {
+ compatible = "ambarella,clock-event";
+ reg = <0xe800b074 0x10 0xe800b030 0x4>;
+ interrupts = <14 0x1>;
+ ctrl-offset = <28>; /* bit offset in timer-ctrl reg */
+ };
+
+ /* timer06 and timer16 */
+ local_timer: timer@e800b054 {
+ compatible = "ambarella,local-clock-event";
+ reg = <0xe800b054 0x10 0xe800b030 0x4 0xe800f054 0x10 0xe800f030 0x4>;
+ interrupts = <12 0x1 28 0x1>;
+ ctrl-offset = <20 20>; /* bit offset in timer-ctrl reg */
+ };
+
+ uart0: uart@e8005000 {
+ compatible = "ambarella,uart";
+ reg = <0xe8005000 0x1000>;
+ interrupts = <108 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ status = "ok";
+ /* amb,tx-fifo-fix; */
+ };
+
+ i2c0: i2c@e8003000 {
+ compatible = "ambarella,i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe8003000 0x1000>;
+ interrupts = <85 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ clock-frequency = <100000>;
+ amb,i2c-class = <0x81>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@e8001000 {
+ compatible = "ambarella,i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe8001000 0x1000>;
+ interrupts = <84 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+ clock-frequency = <100000>;
+ amb,i2c-class = <0x08>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@e8007000 {
+ compatible = "ambarella,i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe8007000 0x1000>;
+ interrupts = <83 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+ clock-frequency = <100000>;
+ amb,i2c-class = <0x81>;
+ status = "disabled";
+ };
+
+ adc@e801d000 {
+ compatible = "ambarella,adc";
+ reg = <0xe801d000 0x1000>;
+ interrupts = <103 0x4>;
+ clock-frequency = <3000000>;
+ };
+
+ ir@e8006000 {
+ compatible = "ambarella,ir";
+ reg = <0xe8006000 0x1000>;
+ interrupts = <86 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_pins>;
+ };
+
+ wdt@e800c000 {
+ compatible = "ambarella,wdt";
+ reg = <0xe800c000 0x1000>;
+ /* interrupts = <105 0x4>; */
+ timeout-sec = <15>;
+ };
+
+ rtc@e8015000 {
+ compatible = "ambarella,rtc";
+ reg = <0xe8015000 0x1000>;
+ };
+
+ pwm: pwm@e8008000 {
+ compatible = "ambarella,pwm";
+ reg = <0xe8008000 0x1000>;
+ #pwm-cells = <3>;
+ };
+
+ pinctrl: pinctrl@e8009000 {
+ compatible = "ambarella,pinctrl", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe8009000 0x1000>,
+ <0xe800a000 0x1000>,
+ <0xe800e000 0x1000>,
+ <0xe8010000 0x1000>,
+ <0xe8011000 0x1000>,
+ <0xe800d000 0x1000>,
+ <0xe8014000 0x1000>,
+ <0xe8016000 0x1000>;
+ reg-names = "gpio0", "gpio1", "gpio2", "gpio3",
+ "gpio4", "gpio5", "gpio6", "iomux";
+ #gpio-range-cells = <3>;
+
+ gpio: gpio@0 {
+ compatible = "ambarella,gpio";
+ /* gpio interrupts to vic */
+ interrupts = <124 0x4>, <123 0x4>, <122 0x4>,
+ <121 0x4>, <120 0x4>, <119 0x4>,
+ <118 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl 0 0 224>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ uart0_pins: uart0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1024 0x1025>;
+ };
+
+ uart1_pins_a: uart1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x2008 0x2009>;
+ };
+
+ uart1_pins_b: uart1@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x301b 0x301c>;
+ };
+
+ uart1_pins_c: uart1@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x10c3 0x10c4>;
+ };
+
+ uart1_flow_pins_a: uart1_flow@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x200a 0x200b>;
+ };
+
+ uart1_flow_pins_b: uart1_flow@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x301d 0x301e>;
+ };
+
+ uart1_flow_pins_c: uart1_flow@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x10c5 0x10c6>;
+ };
+
+ nand0_pins: nand0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x2073 0x2074 0x2075 0x207a
+ 0x207b 0x207c 0x207d 0x207e
+ 0x207f 0x2080 0x2081 0x2082
+ 0x2083 0x2084 0x2085>;
+ };
+
+ spinor0_pins: spinor0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x3076 0x3077 0x3078 0x3079
+ 0x307d 0x307e 0x307f 0x3080
+ 0x3081 0x3082 0x3083 0x3084
+ 0x3086 0x3087 0x3088 0x3089
+ 0x308c>;
+ };
+
+ sdmmc0_pins_1bit: sdmmc0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x2076 0x2077 0x2078 0x2079
+ 0x2086 0x209a>;
+ };
+
+ sdmmc0_pins_4bit: sdmmc0@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x2076 0x2077 0x2078 0x2079
+ 0x2086 0x2087 0x2088 0x2089
+ 0x209a>;
+ };
+
+ sdmmc0_pins_8bit: sdmmc0@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x2076 0x2077 0x2078 0x2079
+ 0x2086 0x2087 0x2088 0x2089
+ 0x208a 0x208b 0x208c 0x208d
+ 0x209a>;
+ };
+
+ sdmmc1_pins_1bit: sdmmc1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x5000 0x5001 0x5002 0x5003
+ 0x5004>;
+ };
+
+ sdmmc1_pins_4bit: sdmmc1@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x5000 0x5001 0x5002 0x5003
+ 0x5004 0x5005 0x5006 0x5007>;
+ };
+
+ sdmmc2_pins_1bit: sdmmc2@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x208e 0x208f 0x2090 0x2094
+ 0x2095 0x209b>;
+ };
+
+ sdmmc2_pins_4bit: sdmmc2@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x208e 0x208f 0x2090 0x2091
+ 0x2092 0x2093 0x2094 0x2095
+ 0x209b>;
+ };
+
+ sdmmc2_pins_8bit: sdmmc2@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x208e 0x208f 0x2090 0x2091
+ 0x2092 0x2093 0x2094 0x2095
+ 0x2096 0x2097 0x2098 0x2099
+ 0x209b>;
+ };
+
+ eth_gmii_pins: eth0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x102b 0x102c 0x102d 0x102e 0x102f
+ 0x1030 0x1031 0x1032 0x1033 0x1034
+ 0x1035 0x1036 0x1037 0x1038 0x1039
+ 0x103a 0x103b 0x103c 0x103d 0x103e
+ 0x103f 0x1040 0x1041 0x1042 0x1043
+ 0x1044 0x1045 0x1046>;
+ };
+
+ eth_mii_pins: eth0@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x202b 0x202c 0x202d 0x202e 0x202f
+ 0x2030 0x2035 0x2036 0x2037 0x2038
+ 0x203d 0x203e 0x203f 0x2040 0x2041
+ 0x2042 0x2043 0x2044 0x2045 0x2046>;
+ };
+
+ eth_rmii_pins: eth0@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x302b 0x302d 0x302e 0x3035 0x3036
+ 0x303f 0x3041 0x3042 0x3043 0x3044
+ 0x3045 0x3046>;
+ };
+
+ eth_rgmii_pins: eth0@3 {
+ reg = <3>;
+ amb,pinmux-ids = <0x402b 0x402d 0x402e 0x402f 0x4030
+ 0x4035 0x4036 0x4037 0x4038 0x403f
+ 0x4043 0x4044 0x4045 0x4046>;
+ };
+
+ i2c0_pins: i2c0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1014 0x1015>;
+ };
+
+ i2c1_pins: i2c1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1016 0x1017>;
+ };
+
+ i2c2_pins: i2c2@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1018 0x1019>;
+ };
+
+ spi0_pins: spi0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x101b 0x101c 0x101d>;
+ };
+
+ spi1_pins_a: spi1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x2000 0x2001 0x2002>;
+ };
+
+ spi1_pins_b: spi1@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x20c3 0x20c4 0x20c5>;
+ };
+
+ spi_slave_pins: spi_slave@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1020 0x1021 0x1022 0x1023>;
+ };
+
+ ir_pins: ir0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x101a>;
+ };
+
+ i2s0_pins: i2s0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1026 0x1027 0x1028 0x1029 0x102a>;
+ };
+
+ usb_host0_pins_a: uhc0@0 { /* USB0: host/device configurable */
+ reg = <0>;
+ amb,pinmux-ids = <0x300c 0x300e>;
+ };
+
+ usb_host0_pins_b: uhc0@1 { /* USB0: host/device configurable */
+ reg = <1>;
+ amb,pinmux-ids = <0x204b 0x204d>;
+ };
+
+ usb_host1_pins_a: uhc1@0 { /* USB1: host only */
+ reg = <0>;
+ amb,pinmux-ids = <0x300d 0x300f>;
+ };
+
+ usb_host1_pins_b: uhc1@1 { /* USB1: host only */
+ reg = <1>;
+ amb,pinmux-ids = <0x204c 0x204e>;
+ };
+
+ pwm0_pins_a: pwm0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x4004>;
+ };
+
+ pwm0_pins_b: pwm0@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x10bc>;
+ };
+
+ pwm1_pins: pwm1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x4005>;
+ };
+
+ pwm2_pins: pwm2@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x4006>;
+ };
+
+ pwm3_pins: pwm3@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x4007>;
+ };
+ };
+ };
+
+ ahb@e0000000 { /* AHB */
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xe0000000 0x01000000>;
+ ranges;
+
+ intc: interrupt-controller@e0003000 {
+ compatible = "ambarella,vic";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0xe0003000 0x1000>,
+ <0xe0010000 0x1000>,
+ <0xe001c000 0x1000>,
+ <0xe0011000 0x1000>;
+ };
+
+ dma: dma@e0005000 {
+ compatible = "ambarella,dma";
+ reg = <0xe0005000 0x1000>;
+ interrupts = <69 0x4>;
+ #dma-cells = <2>;
+ dma-channels = <8>;
+ dma-requests = <14>;
+ dma-trans-type = <1 1 0 0 1 1 1 1>; /* 0-memcpy ,1-slave*/
+ dma-channel-sel = <0 1 0 0 8 9 11 10>;
+ amb,copy-align = <0>;
+ /* support pause/resume/stop */
+ amb,support-prs;
+ };
+
+ nand0: nand@e0001000 {
+ compatible = "ambarella,nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xe0001000 0x1000>, /* fio reg address */
+ <0xe0012000 0x1000>, /* fdma reg address */
+ <0xe0000000 0x4>; /* fifo base */
+ interrupts = <72 0x4>, /* fio_cmd_irq */
+ <73 0x4>, /* fio_dma_irq */
+ <70 0x4>; /* fdma_irq */
+ pinctrl-names = "default";
+ pinctrl-0 = <&nand0_pins>;
+ nand-on-flash-bbt;
+ amb,enable-wp;
+ /* amb,soft-ecc = <1>; */
+ };
+
+ spinor0: spinor@e0031000 {
+ compatible = "ambarella,spinor";
+ reg = <0xe0031000 0x2ff>, /* spi nor controller */
+ <0xe0005300 0x20>; /* dma reg */
+ pinctrl-names = "default";
+ pinctrl-0 = <&spinor0_pins>;
+ status = "disabled";
+ };
+
+ uart1: uart@e0032000 {
+ compatible = "ambarella,uart";
+ reg = <0xe0032000 0x1000>;
+ interrupts = <82 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins_c &uart1_flow_pins_c>;
+ status = "disabled";
+ amb,msr-used; /* use Modem Status Register */
+ amb,txdma-used;
+ amb,rxdma-used;
+ /* amb,tx-fifo-fix; */
+ /* need to select pinctrl setup in board dts */
+ };
+
+ i2s0: i2s@e001a000 {
+ compatible = "ambarella,i2s";
+ reg = <0xe001a000 0x1000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_pins>;
+ amb,i2s-channels = <2>;
+ amb,default-mclk = <12288000>;
+ dmas = <&dma 5 1>,
+ <&dma 4 1>;
+ dma-names = "tx", "rx";
+ };
+
+ udc@e0006000 {
+ compatible = "ambarella,udc";
+ reg = <0xe0006000 0x2000 0xec1702cc 0x4>;
+ interrupts = <68 0x4>;
+ amb,usbphy = <&usbphy>;
+ };
+
+ ehci@e0018000 {
+ compatible = "ambarella,ehci";
+ reg = <0xe0018000 0x1000>;
+ interrupts = <66 0x4>;
+ amb,usbphy = <&usbphy>;
+ };
+
+ ohci@e0019000 {
+ compatible = "ambarella,ohci";
+ reg = <0xe0019000 0x1000>;
+ interrupts = <67 0x4>;
+ amb,usbphy = <&usbphy>;
+ };
+
+ sdmmc0: sdmmc0@e0002000 {
+ compatible = "ambarella,sdmmc";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe0002000 0x1000>,
+ <0xe0001000 0x80>; /* fio reg address */
+ interrupts = <77 0x4>;
+ amb,clk-name = "gclk_sd";
+ amb,wait-tmo = <10000>; /* in millisecond */
+ amb,switch_vol_tmo = <100>;
+ amb,max-blk-size = <131072>; /* valid value: 4K<<n */
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc0_pins_8bit>;
+
+ slot@0 {
+ reg = <0>;
+ global-id = <0>;
+ max-frequency = <48000000>;
+ bus-width = <8>;
+ amb,caps-adma;
+ cap-sdio-irq;
+ };
+ };
+
+ sdmmc1: sdmmc1@e000c000 {
+ compatible = "ambarella,sdmmc";
+ reg = <0xe000c000 0x1000>,
+ <0xe0001000 0x80>; /* fio reg address */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <76 0x4>;
+ amb,clk-name = "gclk_sdio";
+ amb,wait-tmo = <10000>; /* in millisecond */
+ amb,switch_vol_tmo = <100>;
+ amb,max-blk-size = <131072>; /* valid value: 4K<<n */
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_pins_4bit>;
+ status = "disabled";
+
+ slot@0 {
+ reg = <0>;
+ global-id = <1>;
+ max-frequency = <48000000>;
+ bus-width = <4>;
+ amb,caps-adma;
+ cap-sdio-irq;
+ };
+ };
+
+ sdmmc2: sdmmc2@e001f000 {
+ compatible = "ambarella,sdmmc";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe001f000 0x1000>,
+ <0xe0001000 0x80>; /* fio reg address */
+ interrupts = <75 0x4>;
+ amb,clk-name = "gclk_sdxc";
+ amb,wait-tmo = <10000>; /* in millisecond */
+ amb,switch_vol_tmo = <100>;
+ amb,max-blk-size = <131072>; /* valid value: 4K<<n */
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc2_pins_8bit>;
+ status = "disabled";
+
+ slot@0 {
+ reg = <0>;
+ global-id = <2>;
+ max-frequency = <12000000>;
+ bus-width = <8>;
+ amb,caps-adma;
+ cap-sdio-irq;
+ };
+ };
+
+ mac0: ethernet@e000e000 {
+ compatible = "ambarella,eth";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe000e000 0x2000>;
+ interrupts = <65 0x4>;
+ amb,tx-ring-size = <32>;
+ amb,rx-ring-size = <64>;
+ amb,ipc-tx;
+ amb,ipc-rx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&eth_gmii_pins>;
+ };
+
+ spi0: spi@e0020000 {
+ compatible = "ambarella,spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe0020000 0x1000>;
+ interrupts = <80 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins>;
+ amb,clk-freq = <54000000>;
+ dmas = <&dma 0 1>,
+ <&dma 1 1>;
+ dma-names = "tx", "rx";
+ };
+
+ spi1: spi@e0021000 {
+ compatible = "ambarella,spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe0021000 0x1000>;
+ interrupts = <79 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pins_a>;
+ amb,clk-freq = <54000000>;
+ status = "disabled";
+ };
+
+ spi_slave@e0026000 {
+ compatible = "ambarella,spi-slave";
+ reg = <0xe0026000 0x1000>;
+ interrupts = <81 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi_slave_pins>;
+ status = "disabled";
+ };
+ };
+
+ axi@f0000000 { /* AXI */
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xf0000000 0x00030000>;
+ ranges;
+
+ crypto@f0020000 {
+ compatible = "ambarella,crypto";
+ reg = <0xf0020000 0x8000>;
+ interrupts = <111 0x1>, <112 0x1>, <113 0x1>, <110 0x1>;
+ interrupt-names = "aes-irq", "des-irq", "md5-irq", "sha1-irq";
+ amb,cap-md5-sha1;
+ amb,data-swap;
+ amb,reg-64bit;
+ };
+ };
+
+ rct@ec170000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xec170000 0x1000>;
+ ranges;
+
+ usbphy: usbphy@ec170050 {
+ compatible = "ambarella,usbphy";
+ reg = <0xec170050 0x4 0xe001b00c 0x4 0xec1702c0 0x4>;
+ amb,host-phy-num = <2>;
+ amb,owner-mask;
+ amb,owner-invert;
+ };
+ };
+
+ iav {
+ compatible = "ambarella,iav";
+ };
+
+ bogus_bus {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dummycodec: codec@0 {
+ compatible = "ambarella,dummycodec";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/ambarella-s3l.dtsi b/arch/arm/boot/dts/ambarella-s3l.dtsi
new file mode 100644
index 00000000..44ebef8b
--- /dev/null
+++ b/arch/arm/boot/dts/ambarella-s3l.dtsi
@@ -0,0 +1,781 @@
+/*
+ * Copyright (C) 2013 Ambarella,Inc. - http://www.ambarella.com/
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "ambarella,s3l";
+ interrupt-parent = <&intc>;
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ nand = &nand0;
+ spinand = &spinand0;
+ spinor = &spinor0;
+ sd0 = &sdmmc0;
+ sd2 = &sdmmc2;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ spi0 = &spi0;
+ spi1 = &spi1;
+ ethernet0 = &mac0;
+ mdio-gpio0 = <&mdio0>;
+ };
+
+ /* the memory node will be overwritten in Amboot,
+ * here is just the default value. */
+ memory {
+ device_type = "memory";
+ reg = <0x00200000 0x07e00000>; /* 126M */
+ };
+
+ chosen {
+ linux,stdout-path = &uart0;
+ /* the gpio used to disconnect RESET signal to
+ * dram, used for self-refresh, can be overwritten. */
+ ambarella,dram-reset-ctrl = <5>;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-latency = <100000>;
+ /* the highest frequency is gotten in runtime */
+ cpufreq_tbl = < /*core_clk cortex_clk*/
+ 24000 96000
+ 72000 120000
+ 96000 168000
+ 108000 504000>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ };
+ };
+
+ apb@e8000000 { /* APB */
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xe8000000 0x01000000>;
+ ranges;
+
+ timer7: timer@e800b064 {
+ compatible = "ambarella,clock-source";
+ reg = <0xe800b064 0x10 0xe800b030 0x4>;
+ interrupts = <6 0x1>;
+ ctrl-offset = <24>; /* bit offset in timer-ctrl reg */
+ };
+
+ timer8: timer@e800b074 {
+ compatible = "ambarella,clock-event";
+ reg = <0xe800b074 0x10 0xe800b030 0x4>;
+ interrupts = <63 0x1>;
+ ctrl-offset = <28>; /* bit offset in timer-ctrl reg */
+ };
+
+ uart0: uart@e8005000 {
+ compatible = "ambarella,uart";
+ reg = <0xe8005000 0x1000>;
+ interrupts = <61 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ status = "ok";
+ /* amb,tx-fifo-fix; */
+ };
+
+ i2c0: i2c@e8003000 {
+ compatible = "ambarella,i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe8003000 0x1000>;
+ interrupts = <83 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ clock-frequency = <100000>;
+ amb,i2c-class = <0x81>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@e8001000 {
+ compatible = "ambarella,i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe8001000 0x1000>;
+ interrupts = <82 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+ clock-frequency = <100000>;
+ amb,i2c-class = <0x08>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@e8007000 {
+ compatible = "ambarella,i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe8007000 0x1000>;
+ interrupts = <81 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+ clock-frequency = <100000>;
+ amb,i2c-class = <0x81>;
+ status = "disabled";
+ };
+
+ adc@e801d000 {
+ compatible = "ambarella,adc";
+ reg = <0xe801d000 0x1000>;
+ interrupts = <57 0x4>;
+ clock-frequency = <3000000>;
+ };
+
+ ir@e8006000 {
+ compatible = "ambarella,ir";
+ reg = <0xe8006000 0x1000>;
+ interrupts = <84 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_pins>;
+ };
+
+ wdt@e800c000 {
+ compatible = "ambarella,wdt";
+ reg = <0xe800c000 0x1000>;
+ /* interrupts = <59 0x4>; */
+ timeout-sec = <15>;
+ };
+
+ rtc@e8015000 {
+ compatible = "ambarella,rtc";
+ reg = <0xe8015000 0x1000>;
+ interrupts = <64 0x1>;
+ rtc,wakeup;
+ };
+
+ pwm: pwm@e8008000 {
+ compatible = "ambarella,pwm";
+ reg = <0xe8008000 0x1000>;
+ #pwm-cells = <3>;
+ };
+
+ pinctrl: pinctrl@e8009000 {
+ compatible = "ambarella,pinctrl", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe8009000 0x1000>,
+ <0xe800a000 0x1000>,
+ <0xe800e000 0x1000>,
+ <0xe8010000 0x1000>,
+ <0xe8016000 0x1000>;
+ reg-names = "gpio0", "gpio1", "gpio2", "gpio3", "iomux";
+ #gpio-range-cells = <3>;
+
+ gpio: gpio@0 {
+ compatible = "ambarella,gpio";
+ /* gpio interrupts to vic */
+ interrupts = <52 0x4 51 0x4 50 0x4 49 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl 0 0 128>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ uart0_pins: uart0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1028 0x1029>;
+ };
+
+ uart1_pins_a: uart1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x2001 0x2002>;
+ };
+
+ uart1_pins_b: uart1@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x2010 0x2011>;
+ };
+
+ uart1_pins_c: uart1@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x2014 0x2015>;
+ };
+
+ uart1_pins_d: uart1@3 {
+ reg = <3>;
+ amb,pinmux-ids = <0x3023 0x3024>;
+ };
+
+ uart1_pins_e: uart1@4 {
+ reg = <4>;
+ amb,pinmux-ids = <0x2028 0x2029>;
+ };
+
+ uart1_flow_pins_a: uart1_flow@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x2003 0x2004>;
+ };
+
+ uart1_flow_pins_b: uart1_flow@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x5005 0x5006>;
+ };
+
+ uart1_flow_pins_c: uart1_flow@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x2012 0x2013>;
+ };
+
+ uart1_flow_pins_d: uart1_flow@3 {
+ reg = <3>;
+ amb,pinmux-ids = <0x2016 0x2017>;
+ };
+
+ uart1_flow_pins_e: uart1_flow@4 {
+ reg = <4>;
+ amb,pinmux-ids = <0x3025 0x3026>;
+ };
+
+ nand0_pins: nand0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x2037 0x2038 0x2039 0x203e
+ 0x203f 0x2040 0x2041 0x2042
+ 0x2043 0x2044 0x2045 0x2046
+ 0x2047 0x2048 0x2049>;
+ };
+
+ spinor0_pins: spinor0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x3038 0x3039 0x303e 0x303f
+ 0x3040 0x3041 0x3042 0x3043
+ 0x3044 0x3045 0x3046 0x3047
+ 0x3048>;
+ };
+
+ sdmmc0_cd_pin: sdmmc0_cd@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x203c>;
+ };
+
+ sdmmc0_wp_pin: sdmmc0_wp@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x203d>;
+ };
+
+ sdmmc0_pins_1bit: sdmmc0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x203a 0x203b 0x204a>;
+ };
+
+ sdmmc0_pins_4bit: sdmmc0@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x203a 0x203b 0x204a
+ 0x204b 0x204c 0x204d>;
+ };
+
+ sdmmc0_pins_8bit: sdmmc0@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x203a 0x203b 0x204a 0x204b 0x204c
+ 0x204d 0x204e 0x204f 0x2050 0x2051>;
+ };
+
+ sdmmc2_cd_pin: sdmmc2_cd@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x2058>;
+ };
+
+ sdmmc2_wp_pin: sdmmc2_wp@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x2059>;
+ };
+
+ sdmmc2_pins_1bit: sdmmc2@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x2052 0x2053 0x2054>;
+ };
+
+ sdmmc2_pins_4bit: sdmmc2@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x2052 0x2053 0x2054
+ 0x2055 0x2056 0x2057>;
+ };
+
+ sdmmc2_pins_8bit: sdmmc2@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x2052 0x2053 0x2054 0x2055 0x2056
+ 0x2057 0x205a 0x205b 0x205c 0x205d>;
+ };
+
+ rmii_pins: eth0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x102f 0x1030 0x1031 0x1032
+ 0x1033 0x1034 0x1035 0x1036>;
+ };
+
+ mii_pins: eth0@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x302f 0x3030 0x3031 0x4011
+ 0x4012 0x4013 0x4014 0x4015
+ 0x4016 0x4017 0x4018 0x3032
+ 0x3033 0x3034 0x3035 0x3036>;
+ };
+
+ mdio_gpio_pins: mdio_gpio@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x401a 0x401b>;
+ };
+
+ i2c0_pins: i2c0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x101c 0x101d>;
+ };
+
+ i2c1_pins: i2c1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x101e 0x101f>;
+ };
+
+ i2c2_pins: i2c2@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1020 0x1021>;
+ };
+
+ ir_pins: ir0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1022>;
+ };
+
+ i2s0_pins: i2s0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x102a 0x102b 0x102c 0x102d 0x102e>;
+ };
+
+ usb_host0_pins: uhc0@0 { /* USB0: host/device configurable */
+ reg = <0>;
+ amb,pinmux-ids = <0x1002 0x1004>;
+ };
+
+ pwm0_pins_a: pwm0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x4008>;
+ };
+
+ pwm0_pins_b: pwm0@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x5014>;
+ };
+
+ pwm0_pins_c: pwm0@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x1078>;
+ };
+
+ pwm1_pins_a: pwm1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1005>;
+ };
+
+ pwm1_pins_b: pwm1@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x4009>;
+ };
+
+ pwm1_pins_c: pwm1@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x5015>;
+ };
+
+ pwm1_pins_d: pwm1@3 {
+ reg = <3>;
+ amb,pinmux-ids = <0x5018>;
+ };
+
+ pwm2_pins_a: pwm2@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1006>;
+ };
+
+ pwm2_pins_b: pwm2@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x400a>;
+ };
+
+ pwm2_pins_c: pwm2@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x5016>;
+ };
+
+ pwm3_pins_a: pwm3@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x400b>;
+ };
+
+ pwm3_pins_b: pwm3@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x200f>;
+ };
+
+ pwm3_pins_c: pwm3@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x5017>;
+ };
+
+ spi_slave_pins_a: spi_slave@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x3001 0x3002 0x3003 0x3004>;
+ };
+
+ spi_slave_pins_b: spi_slave@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x3010 0x3011 0x3012 0x3013>;
+ };
+
+ spi_slave_pins_c: spi_slave@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x3014 0x3015 0x3016 0x3017>;
+ };
+
+ spi_slave_pins_d: spi_slave@3 {
+ reg = <3>;
+ amb,pinmux-ids = <0x4023 0x4024 0x4025 0x4026>;
+ };
+
+ spi_slave_pins_e: spi_slave@4 {
+ reg = <4>;
+ amb,pinmux-ids = <0x504e 0x504f 0x5050 0x5051>;
+ };
+
+ spi_slave_pins_f: spi_slave@5 {
+ reg = <5>;
+ amb,pinmux-ids = <0x5054 0x5055 0x5056 0x5057>;
+ };
+
+ spi0_pins: spi0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1023 0x1024 0x1025>;
+ };
+
+ spi1_pins_a: spi1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x2008 0x2009 0x200a>;
+ };
+
+ spi1_pins_b: spi1@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x402f 0x4030 0x4031>;
+ };
+ };
+ };
+
+ ahb@e0000000 { /* AHB */
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xe0000000 0x01000000>;
+ ranges;
+
+ intc: interrupt-controller@e0003000 {
+ compatible = "ambarella,vic";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0xe0003000 0x1000>,
+ <0xe0010000 0x1000>,
+ <0xe001c000 0x1000>;
+ };
+
+ dma: dma@e0005000 {
+ compatible = "ambarella,dma";
+ reg = <0xe0005000 0x1000>;
+ interrupts = <69 0x4>;
+ #dma-cells = <2>;
+ dma-channels = <8>;
+ dma-requests = <12>;
+ dma-trans-type = <1 1 0 0 1 1 1 1>; /* 0-memcpy ,1-slave*/
+ dma-channel-sel = <4 5 0 0 8 9 11 10>;
+ amb,copy-align = <0>;
+ /* support pause/resume/stop */
+ amb,support-prs;
+ };
+
+ nand0: nand@e0001000 {
+ compatible = "ambarella,nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xe0001000 0x1000>, /* fio reg address */
+ <0xe0012000 0x1000>, /* fdma reg address */
+ <0xe0000000 0x4>; /* fifo base */
+ interrupts = <72 0x4>, /* fio_cmd_irq */
+ <73 0x4>, /* fio_dma_irq */
+ <70 0x4>; /* fdma_irq */
+ pinctrl-names = "default";
+ pinctrl-0 = <&nand0_pins>;
+ nand-on-flash-bbt;
+ amb,enable-wp;
+ /* amb,soft-ecc = <1>; */
+ };
+
+ spinand0: spinand@e0031000 {
+ compatible = "ambarella,spinand";
+ reg = <0xe0031000 0x2ff>, /* spi nor controller */
+ <0xe0005300 0x20>; /* dma reg */
+ pinctrl-names = "default";
+ pinctrl-0 = <&spinor0_pins>;
+ status = "disabled";
+ };
+
+ spinor0: spinor@e0031000 {
+ compatible = "ambarella,spinor";
+ reg = <0xe0031000 0x2ff>, /* spi nor controller */
+ <0xe0005300 0x20>; /* dma reg */
+ pinctrl-names = "default";
+ pinctrl-0 = <&spinor0_pins>;
+ status = "disabled";
+ };
+
+ uart1: uart@e0032000 {
+ compatible = "ambarella,uart";
+ reg = <0xe0032000 0x1000>;
+ interrupts = <80 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins_c &uart1_flow_pins_d>;
+ status = "ok";
+ amb,msr-used; /* use Modem Status Register */
+ amb,txdma-used;
+ amb,rxdma-used;
+ /* amb,tx-fifo-fix; */
+ /* need to select pinctrl setup in board dts */
+ };
+
+ i2s0: i2s@e001a000 {
+ compatible = "ambarella,i2s";
+ reg = <0xe001a000 0x1000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_pins>;
+ amb,i2s-channels = <2>;
+ amb,default-mclk = <12288000>;
+ dmas = <&dma 5 1>, <&dma 4 1>;
+ dma-names = "tx", "rx";
+ };
+
+ udc@e0006000 {
+ compatible = "ambarella,udc";
+ reg = <0xe0006000 0x2000 0xec1702cc 0x4>;
+ interrupts = <68 0x4>;
+ amb,usbphy = <&usbphy>;
+ };
+
+ ehci@e0018000 {
+ compatible = "ambarella,ehci";
+ reg = <0xe0018000 0x1000>;
+ interrupts = <66 0x4>;
+ amb,usbphy = <&usbphy>;
+ };
+
+ ohci@e0019000 {
+ compatible = "ambarella,ohci";
+ reg = <0xe0019000 0x1000>;
+ interrupts = <67 0x4>;
+ amb,usbphy = <&usbphy>;
+ };
+
+ sdmmc0: sdmmc0@e0002000 {
+ compatible = "ambarella,sdmmc";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe0002000 0x1000>,
+ <0xe0001000 0x80>,/* fio reg address */
+ <0xec1704c0 0x8>; /* phy timing reg*/
+ interrupts = <75 0x4>;
+ amb,clk-name = "gclk_sd";
+ amb,wait-tmo = <10000>; /* in millisecond */
+ amb,switch-vol-tmo = <100>;
+ amb,max-blk-size = <131072>; /* valid value: 4K<<n */
+ amb,auto-tuning;
+ amb,phy-type = <0>;/*0:rct phy, 1: sd controller phy, 2: for s2e*/
+ amb,phy-timing = <0x0000001f 0x04070000 0x00000000>,
+ /*sdr50 100M,sdr104 120M*/
+ <0x00000060 0x10410400 0x00D04104>,
+ <0x00000080 0x10410400 0x02504104>;/*DDR50 50M*/
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc0_pins_8bit &sdmmc0_cd_pin &sdmmc0_wp_pin>;
+
+ slot@0 {
+ reg = <0>;
+ global-id = <0>;
+ max-frequency = <50000000>;
+ bus-width = <8>;
+ amb,caps-adma;
+ cap-sdio-irq;
+ };
+ };
+
+ sdmmc2: sdmmc2@e001f000 { /* SDXC rather than SDIO */
+ compatible = "ambarella,sdmmc";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe001f000 0x1000>,
+ <0xe0001000 0x80>,/* fio reg address */
+ <0xec1704c8 0x8>; /* phy timing reg*/
+ interrupts = <74 0x4>;
+ amb,clk-name = "gclk_sdxc";
+ amb,wait-tmo = <10000>; /* in millisecond */
+ amb,switch-vol-tmo = <100>;
+ amb,max-blk-size = <131072>; /* valid value: 4K<<n */
+ amb,auto-tuning;
+ amb,phy-type = <0>;
+ amb,phy-timing = <0x0000001f 0x04070000 0x00000000>,
+ /*sdr50 100M,sdr104 120M*/
+ <0x00000060 0x10410400 0x00D04104>,
+ <0x00000080 0x10410400 0x02504104>;/*DDR50 50M*/
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc2_pins_8bit &sdmmc2_cd_pin &sdmmc2_wp_pin>;
+
+ slot@0 {
+ reg = <0>;
+ global-id = <1>;
+ max-frequency = <50000000>;
+ bus-width = <8>;
+ amb,caps-adma;
+ cap-sdio-irq;
+ };
+ };
+
+ mac0: ethernet@e000e000 {
+ compatible = "ambarella,eth";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe000e000 0x2000>;
+ interrupts = <65 0x4>;
+ amb,tx-ring-size = <32>;
+ amb,rx-ring-size = <64>;
+ amb,ipc-tx;
+ amb,ipc-rx;
+ //amb,mdio-gpio;
+ pinctrl-names = "default";
+ //pinctrl-0 = <&rmii_pins>;
+ pinctrl-0 = <&rmii_pins &mdio_gpio_pins>;
+ };
+
+ spi0: spi@e0020000 {
+ compatible = "ambarella,spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe0020000 0x1000>;
+ interrupts = <78 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins>;
+ amb,clk-freq = <54000000>;
+ /* amb,dma-used; */
+ dmas = <&dma 0 1>, <&dma 1 1>;
+ dma-names = "tx", "rx";
+ };
+
+ spi1: spi@e0021000 {
+ compatible = "ambarella,spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe0021000 0x1000>;
+ interrupts = <77 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pins_a>;
+ amb,clk-freq = <54000000>;
+ status = "disabled";
+ };
+
+ spi_slave@e0026000 {
+ compatible = "ambarella,spi-slave";
+ reg = <0xe0026000 0x1000>;
+ interrupts = <79 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi_slave_pins_a>;
+ status = "disabled";
+ };
+ };
+
+ axi@f0000000 { /* AXI */
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xf0000000 0x00030000>;
+ ranges;
+
+ crypto@f0020000 {
+ compatible = "ambarella,crypto";
+ reg = <0xf0020000 0x8000>;
+ interrupts = <30 0x1>, <29 0x1>, <28 0x1>, <31 0x1>;
+ interrupt-names = "aes-irq", "des-irq", "md5-irq", "sha1-irq";
+ amb,cap-md5-sha1;
+ amb,data-swap;
+ amb,reg-64bit;
+ };
+
+ l2-cache@f0002000 {
+ compatible = "arm,pl310-cache";
+ reg = <0xf0002000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ /* l2 cache latency use default setting */
+ /* arm,tag_latency = <1 2 1>; */
+ /* arm,data_latency = <1 3 1>; */
+ };
+ };
+
+ rct@ec170000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xec170000 0x1000>;
+ ranges;
+
+ usbphy: usbphy@ec170050 {
+ compatible = "ambarella,usbphy";
+ reg = <0xec170050 0x4 0xe001b00c 0x4 0xec1702c0 0x4>;
+ amb,host-phy-num = <1>;
+ amb,owner-mask;
+ amb,owner-invert;
+ };
+ };
+
+ iav {
+ compatible = "ambarella,iav";
+ };
+
+ bogus_bus {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dummycodec: codec@0 {
+ compatible = "ambarella,dummycodec";
+ };
+ };
+
+ mdio0: mdio {
+ compatible = "virtual,mdio-gpio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ gpios = <&gpio 26 0
+ &gpio 27 0>;
+
+ phy@0{
+ reg = <0>;
+ };
+ };
+
+ amba_lens {
+ compatible = "ambarella,lens";
+ interrupts = <4 0x1>, /* zoom_timer_irq */
+ <1 0x1>, /* focus_timer_irq */
+ <2 0x1>; /* iris_timer_irq */
+ };
+
+};
diff --git a/arch/arm/boot/dts/ambarella-supercam.dtsi b/arch/arm/boot/dts/ambarella-supercam.dtsi
new file mode 100644
index 00000000..a0758f75
--- /dev/null
+++ b/arch/arm/boot/dts/ambarella-supercam.dtsi
@@ -0,0 +1,701 @@
+/*
+ * Copyright (C) 2013 Ambarella,Inc. - http://www.ambarella.com/
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "ambarella,s3";
+ interrupt-parent = <&intc>;
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ nand = &nand0;
+ spinor = &spinor0;
+ emmc = &sdmmc0;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ spi0 = &spi0;
+ spi1 = &spi1;
+ ethernet0 = &mac0;
+ };
+
+ /* the memory node will be overwritten in Amboot,
+ * here is just the default value. */
+ memory {
+ device_type = "memory";
+ reg = <0x00200000 0x07e00000>; /* 126M */
+ };
+
+ chosen {
+ linux,stdout-path = &uart0;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu@a00 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0xa00>;
+ };
+ cpu@a01 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0xa01>;
+ };
+ };
+
+ apb@e8000000 { /* APB */
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xe8000000 0x01000000>;
+ ranges;
+
+ timer7: timer@e800b064 {
+ compatible = "ambarella,clock-source";
+ reg = <0xe800b064 0x10 0xe800b030 0x4>;
+ interrupts = <13 0x1>;
+ ctrl-offset = <24>; /* bit offset in timer-ctrl reg */
+ };
+
+ timer8: timer@e800b074 {
+ compatible = "ambarella,clock-event";
+ reg = <0xe800b074 0x10 0xe800b030 0x4>;
+ interrupts = <14 0x1>;
+ ctrl-offset = <28>; /* bit offset in timer-ctrl reg */
+ };
+
+ /* timer06 and timer16 */
+ local_timer: timer@e800b054 {
+ compatible = "ambarella,local-clock-event";
+ reg = <0xe800b054 0x10 0xe800b030 0x4 0xe800f054 0x10 0xe800f030 0x4>;
+ interrupts = <12 0x1 28 0x1>;
+ ctrl-offset = <20 20>; /* bit offset in timer-ctrl reg */
+ };
+
+ uart0: uart@e8005000 {
+ compatible = "ambarella,uart";
+ reg = <0xe8005000 0x1000>;
+ interrupts = <108 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ status = "ok";
+ /* amb,tx-fifo-fix; */
+ };
+
+ i2c0: i2c@e8003000 {
+ compatible = "ambarella,i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe8003000 0x1000>;
+ interrupts = <85 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ clock-frequency = <100000>;
+ amb,i2c-class = <0x81>;
+ amb,bulk-num = <60>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@e8001000 {
+ compatible = "ambarella,i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe8001000 0x1000>;
+ interrupts = <84 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+ clock-frequency = <100000>;
+ amb,i2c-class = <0x08>;
+ amb,bulk-num = <60>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@e8007000 {
+ compatible = "ambarella,i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe8007000 0x1000>;
+ interrupts = <83 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+ clock-frequency = <100000>;
+ amb,i2c-class = <0x81>;
+ amb,bulk-num = <60>;
+ status = "disabled";
+ };
+
+ adc@e801d000 {
+ compatible = "ambarella,adc";
+ reg = <0xe801d000 0x1000>;
+ interrupts = <103 0x4>;
+ clock-frequency = <3000000>;
+ };
+
+ ir@e8006000 {
+ compatible = "ambarella,ir";
+ reg = <0xe8006000 0x1000>;
+ interrupts = <86 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_pins>;
+ };
+
+ wdt@e800c000 {
+ compatible = "ambarella,wdt";
+ reg = <0xe800c000 0x1000>;
+ /* interrupts = <105 0x4>; */
+ timeout-sec = <15>;
+ };
+
+ rtc@e8015000 {
+ compatible = "ambarella,rtc";
+ reg = <0xe8015000 0x1000>;
+ };
+
+ pwm: pwm@e8008000 {
+ compatible = "ambarella,pwm";
+ reg = <0xe8008000 0x1000>;
+ #pwm-cells = <3>;
+ };
+
+ pinctrl: pinctrl@e8009000 {
+ compatible = "ambarella,pinctrl", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe8009000 0x1000>,
+ <0xe800a000 0x1000>,
+ <0xe800e000 0x1000>,
+ <0xe8010000 0x1000>,
+ <0xe8011000 0x1000>,
+ <0xe800d000 0x1000>,
+ <0xe8014000 0x1000>,
+ <0xe8016000 0x1000>;
+ reg-names = "gpio0", "gpio1", "gpio2", "gpio3",
+ "gpio4", "gpio5", "gpio6", "iomux";
+ #gpio-range-cells = <3>;
+
+ gpio: gpio@0 {
+ compatible = "ambarella,gpio";
+ /* gpio interrupts to vic */
+ interrupts = <124 0x4>, <123 0x4>, <122 0x4>,
+ <121 0x4>, <120 0x4>, <119 0x4>,
+ <118 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl 0 0 224>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ uart0_pins: uart0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1024 0x1025>;
+ };
+
+ uart1_pins_a: uart1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x2008 0x2009>;
+ };
+
+ uart1_pins_b: uart1@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x301b 0x301c>;
+ };
+
+ uart1_pins_c: uart1@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x10c3 0x10c4>;
+ };
+
+ uart1_flow_pins_a: uart1_flow@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x200a 0x200b>;
+ };
+
+ uart1_flow_pins_b: uart1_flow@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x301d 0x301e>;
+ };
+
+ uart1_flow_pins_c: uart1_flow@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x10c5 0x10c6>;
+ };
+
+ nand0_pins: nand0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x2073 0x2074 0x2075 0x207a
+ 0x207b 0x207c 0x207d 0x207e
+ 0x207f 0x2080 0x2081 0x2082
+ 0x2083 0x2084 0x2085>;
+ };
+
+ spinor0_pins: spinor0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x3076 0x3077 0x3078 0x3079
+ 0x307d 0x307e 0x307f 0x3080
+ 0x3081 0x3082 0x3083 0x3084
+ 0x3086 0x3087 0x3088 0x3089
+ 0x308c>;
+ };
+
+ sdmmc0_pins_1bit: sdmmc0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x2076 0x2077 0x2078 0x2079
+ 0x2086 0x209a>;
+ };
+
+ sdmmc0_pins_4bit: sdmmc0@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x2076 0x2077 0x2078 0x2079
+ 0x2086 0x2087 0x2088 0x2089
+ 0x209a>;
+ };
+
+ sdmmc0_pins_8bit: sdmmc0@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x2076 0x2077 0x2078 0x2079
+ 0x2086 0x2087 0x2088 0x2089
+ 0x208a 0x208b 0x208c 0x208d
+ 0x209a>;
+ };
+
+ sdmmc1_pins_1bit: sdmmc1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x5000 0x5001 0x5002 0x5003
+ 0x5004>;
+ };
+
+ sdmmc1_pins_4bit: sdmmc1@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x5000 0x5001 0x5002 0x5003
+ 0x5004 0x5005 0x5006 0x5007>;
+ };
+
+ sdmmc2_pins_1bit: sdmmc2@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x208e 0x208f 0x2090 0x2094
+ 0x2095 0x209b>;
+ };
+
+ sdmmc2_pins_4bit: sdmmc2@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x208e 0x208f 0x2090 0x2091
+ 0x2092 0x2093 0x2094 0x2095
+ 0x209b>;
+ };
+
+ sdmmc2_pins_8bit: sdmmc2@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x208e 0x208f 0x2090 0x2091
+ 0x2092 0x2093 0x2094 0x2095
+ 0x2096 0x2097 0x2098 0x2099
+ 0x209b>;
+ };
+
+ eth_gmii_pins: eth0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x102b 0x102c 0x102d 0x102e 0x102f
+ 0x1030 0x1031 0x1032 0x1033 0x1034
+ 0x1035 0x1036 0x1037 0x1038 0x1039
+ 0x103a 0x103b 0x103c 0x103d 0x103e
+ 0x103f 0x1040 0x1041 0x1042 0x1043
+ 0x1044 0x1045 0x1046>;
+ };
+
+ eth_mii_pins: eth0@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x202b 0x202c 0x202d 0x202e 0x202f
+ 0x2030 0x2035 0x2036 0x2037 0x2038
+ 0x203d 0x203e 0x203f 0x2040 0x2041
+ 0x2042 0x2043 0x2044 0x2045 0x2046>;
+ };
+
+ eth_rmii_pins: eth0@2 {
+ reg = <2>;
+ amb,pinmux-ids = <0x302b 0x302d 0x302e 0x3035 0x3036
+ 0x303f 0x3041 0x3042 0x3043 0x3044
+ 0x3045 0x3046>;
+ };
+
+ eth_rgmii_pins: eth0@3 {
+ reg = <3>;
+ amb,pinmux-ids = <0x402b 0x402d 0x402e 0x402f 0x4030
+ 0x4035 0x4036 0x4037 0x4038 0x403f
+ 0x4043 0x4044 0x4045 0x4046>;
+ };
+
+ i2c0_pins: i2c0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1014 0x1015>;
+ };
+
+ i2c1_pins: i2c1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1016 0x1017>;
+ };
+
+ i2c2_pins: i2c2@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1018 0x1019>;
+ };
+
+ spi0_pins: spi0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x101b 0x101c 0x101d>;
+ };
+
+ spi1_pins_a: spi1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x2000 0x2001 0x2002>;
+ };
+
+ spi1_pins_b: spi1@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x20c3 0x20c4 0x20c5>;
+ };
+
+ spi_slave_pins: spi_slave@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1020 0x1021 0x1022 0x1023>;
+ };
+
+ ir_pins: ir0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x101a>;
+ };
+
+ i2s0_pins: i2s0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x1026 0x1027 0x1028 0x1029 0x102a>;
+ };
+
+ usb_host0_pins_a: uhc0@0 { /* USB0: host/device configurable */
+ reg = <0>;
+ amb,pinmux-ids = <0x300c 0x300e>;
+ };
+
+ usb_host0_pins_b: uhc0@1 { /* USB0: host/device configurable */
+ reg = <1>;
+ amb,pinmux-ids = <0x204b 0x204d>;
+ };
+
+ usb_host1_pins_a: uhc1@0 { /* USB1: host only */
+ reg = <0>;
+ amb,pinmux-ids = <0x300d 0x300f>;
+ };
+
+ usb_host1_pins_b: uhc1@1 { /* USB1: host only */
+ reg = <1>;
+ amb,pinmux-ids = <0x204c 0x204e>;
+ };
+
+ pwm0_pins_a: pwm0@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x4004>;
+ };
+
+ pwm0_pins_b: pwm0@1 {
+ reg = <1>;
+ amb,pinmux-ids = <0x10bc>;
+ };
+
+ pwm1_pins: pwm1@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x4005>;
+ };
+
+ pwm2_pins: pwm2@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x4006>;
+ };
+
+ pwm3_pins: pwm3@0 {
+ reg = <0>;
+ amb,pinmux-ids = <0x4007>;
+ };
+ };
+ };
+
+ ahb@e0000000 { /* AHB */
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xe0000000 0x01000000>;
+ ranges;
+
+ intc: interrupt-controller@e0003000 {
+ compatible = "ambarella,vic";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0xe0003000 0x1000>,
+ <0xe0010000 0x1000>,
+ <0xe001c000 0x1000>,
+ <0xe0011000 0x1000>;
+ };
+
+ dma: dma@e0005000 {
+ compatible = "ambarella,dma";
+ reg = <0xe0005000 0x1000>;
+ interrupts = <69 0x4>;
+ #dma-cells = <2>;
+ dma-channels = <8>;
+ dma-requests = <14>;
+ dma-trans-type = <1 1 0 0 1 1 1 1>; /* 0-memcpy ,1-slave*/
+ amb,copy-align = <0>;
+ /* support pause/resume/stop */
+ amb,support-prs;
+ };
+
+ nand0: nand@e0001000 {
+ compatible = "ambarella,nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xe0001000 0x1000>, /* fio reg address */
+ <0xe0012000 0x1000>, /* fdma reg address */
+ <0xe0000000 0x4>; /* fifo base */
+ interrupts = <72 0x4>, /* fio_cmd_irq */
+ <73 0x4>, /* fio_dma_irq */
+ <70 0x4>; /* fdma_irq */
+ pinctrl-names = "default";
+ pinctrl-0 = <&nand0_pins>;
+ nand-on-flash-bbt;
+ amb,enable-wp;
+ /* amb,soft-ecc = <1>; */
+ };
+
+ spinor0: spinor@e0031000 {
+ compatible = "ambarella,spinor";
+ reg = <0xe0031000 0x2ff>, /* spi nor controller */
+ <0xe0005300 0x20>; /* dma reg */
+ pinctrl-names = "default";
+ pinctrl-0 = <&spinor0_pins>;
+ status = "disabled";
+ };
+
+ uart1: uart@e0032000 {
+ compatible = "ambarella,uart";
+ reg = <0xe0032000 0x1000>;
+ interrupts = <82 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins_c &uart1_flow_pins_c>;
+ status = "disabled";
+ amb,msr-used; /* use Modem Status Register */
+ amb,txdma-used;
+ amb,rxdma-used;
+ /* amb,tx-fifo-fix; */
+ /* need to select pinctrl setup in board dts */
+ };
+
+ i2s0: i2s@e001a000 {
+ compatible = "ambarella,i2s";
+ reg = <0xe001a000 0x1000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_pins>;
+ amb,i2s-channels = <2>;
+ amb,default-mclk = <12288000>;
+ };
+
+ udc@e0006000 {
+ compatible = "ambarella,udc";
+ reg = <0xe0006000 0x2000 0xec1702cc 0x4>;
+ interrupts = <68 0x4>;
+ amb,usbphy = <&usbphy>;
+ };
+
+ ehci@e0018000 {
+ compatible = "ambarella,ehci";
+ reg = <0xe0018000 0x1000>;
+ interrupts = <66 0x4>;
+ amb,usbphy = <&usbphy>;
+ };
+
+ ohci@e0019000 {
+ compatible = "ambarella,ohci";
+ reg = <0xe0019000 0x1000>;
+ interrupts = <67 0x4>;
+ amb,usbphy = <&usbphy>;
+ };
+
+ sdmmc0: sdmmc0@e0002000 {
+ compatible = "ambarella,sdmmc";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe0002000 0x1000>,
+ <0xe0001000 0x80>; /* fio reg address */
+ interrupts = <77 0x4>;
+ amb,clk-name = "gclk_sd";
+ amb,wait-tmo = <10000>; /* in millisecond */
+ amb,switch_vol_tmo = <100>;
+ amb,max-blk-size = <131072>; /* valid value: 4K<<n */
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc0_pins_8bit>;
+ status = "disabled";
+
+ slot@0 {
+ reg = <0>;
+ global-id = <0>;
+ max-frequency = <48000000>;
+ bus-width = <8>;
+ amb,caps-adma;
+ cap-sdio-irq;
+ };
+ };
+
+ sdmmc1: sdmmc1@e000c000 {
+ compatible = "ambarella,sdmmc";
+ reg = <0xe000c000 0x1000>,
+ <0xe0001000 0x80>; /* fio reg address */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <76 0x4>;
+ amb,clk-name = "gclk_sdio";
+ amb,wait-tmo = <10000>; /* in millisecond */
+ amb,switch_vol_tmo = <100>;
+ amb,max-blk-size = <131072>; /* valid value: 4K<<n */
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_pins_4bit>;
+ status = "disabled";
+
+ slot@0 {
+ reg = <0>;
+ global-id = <1>;
+ max-frequency = <48000000>;
+ bus-width = <4>;
+ amb,caps-adma;
+ cap-sdio-irq;
+ };
+ };
+
+ sdmmc2: sdmmc2@e001f000 {
+ compatible = "ambarella,sdmmc";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe001f000 0x1000>,
+ <0xe0001000 0x80>; /* fio reg address */
+ interrupts = <75 0x4>;
+ amb,clk-name = "gclk_sdxc";
+ amb,wait-tmo = <10000>; /* in millisecond */
+ amb,switch_vol_tmo = <100>;
+ amb,max-blk-size = <131072>; /* valid value: 4K<<n */
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc2_pins_8bit>;
+ status = "disabled";
+
+ slot@0 {
+ reg = <0>;
+ global-id = <2>;
+ max-frequency = <12000000>;
+ bus-width = <8>;
+ amb,caps-adma;
+ cap-sdio-irq;
+ };
+ };
+
+ mac0: ethernet@e000e000 {
+ compatible = "ambarella,eth";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe000e000 0x2000>;
+ interrupts = <65 0x4>;
+ amb,tx-ring-size = <32>;
+ amb,rx-ring-size = <64>;
+ amb,ipc-tx;
+ amb,ipc-rx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&eth_gmii_pins>;
+ };
+
+ spi0: spi@e0020000 {
+ compatible = "ambarella,spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe0020000 0x1000>;
+ interrupts = <80 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins>;
+ amb,clk-freq = <54000000>;
+ dmas = <&dma 0 1>,
+ <&dma 1 1>;
+ dma-names = "tx", "rx";
+ };
+
+ spi1: spi@e0021000 {
+ compatible = "ambarella,spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe0021000 0x1000>;
+ interrupts = <79 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pins_b>;
+ amb,clk-freq = <54000000>;
+ status = "ok";
+ };
+
+ spi_slave@e0026000 {
+ compatible = "ambarella,spi-slave";
+ reg = <0xe0026000 0x1000>;
+ interrupts = <81 0x4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi_slave_pins>;
+ status = "disabled";
+ };
+ };
+
+ axi@f0000000 { /* AXI */
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xf0000000 0x00030000>;
+ ranges;
+
+ crypto@f0020000 {
+ compatible = "ambarella,crypto";
+ reg = <0xf0020000 0x8000>;
+ interrupts = <111 0x1>, <112 0x1>, <113 0x1>, <110 0x1>;
+ interrupt-names = "aes-irq", "des-irq", "md5-irq", "sha1-irq";
+ amb,cap-md5-sha1;
+ amb,data-swap;
+ amb,reg-64bit;
+ };
+ };
+
+ rct@ec170000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xec170000 0x1000>;
+ ranges;
+
+ usbphy: usbphy@ec170050 {
+ compatible = "ambarella,usbphy";
+ reg = <0xec170050 0x4 0xe001b00c 0x4 0xec1702c0 0x4>;
+ amb,host-phy-num = <2>;
+ amb,owner-mask;
+ amb,owner-invert;
+ };
+ };
+
+ iav {
+ compatible = "ambarella,iav";
+ };
+
+ bogus_bus {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dummycodec: codec@0 {
+ compatible = "ambarella,dummycodec";
+ };
+ };
+};
diff --git a/arch/arm/configs/ambarella_a5s_defconfig b/arch/arm/configs/ambarella_a5s_defconfig
new file mode 100644
index 00000000..595c8894
--- /dev/null
+++ b/arch/arm/configs/ambarella_a5s_defconfig
@@ -0,0 +1,2176 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/arm 3.10.0 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_NEED_MACH_GPIO_H=y
+CONFIG_NEED_MACH_IO_H=y
+CONFIG_NEED_MACH_MEMORY_H=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_IRQ_WORK=y
+CONFIG_BUILDTIME_EXTABLE_SORT=y
+
+#
+# General setup
+#
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_XZ is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_DEFAULT_HOSTNAME="Ambarella"
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_FHANDLE is not set
+# CONFIG_AUDIT is not set
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# Timers subsystem
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ_COMMON=y
+# CONFIG_HZ_PERIODIC is not set
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+
+#
+# CPU/Task time and stats accounting
+#
+CONFIG_TICK_CPU_ACCOUNTING=y
+# CONFIG_IRQ_TIME_ACCOUNTING is not set
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_TREE_PREEMPT_RCU is not set
+CONFIG_TINY_PREEMPT_RCU=y
+CONFIG_PREEMPT_RCU=y
+# CONFIG_RCU_STALL_COMMON is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_RCU_BOOST is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_CGROUPS is not set
+# CONFIG_CHECKPOINT_RESTORE is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+CONFIG_UIDGID_CONVERTED=y
+# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_XZ=y
+CONFIG_RD_LZO=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_HAVE_UID16=y
+CONFIG_HOTPLUG=y
+# CONFIG_EXPERT is not set
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+# CONFIG_EMBEDDED is not set
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_JUMP_LABEL is not set
+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_OLD_SIGACTION=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_MODULE_SIG is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_BSGLIB is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_AMBPTB_PARTITION=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y
+CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_LOCK=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y
+CONFIG_ARCH_INLINE_READ_TRYLOCK=y
+CONFIG_ARCH_INLINE_READ_LOCK=y
+CONFIG_ARCH_INLINE_READ_LOCK_BH=y
+CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_READ_UNLOCK=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y
+CONFIG_ARCH_INLINE_WRITE_TRYLOCK=y
+CONFIG_ARCH_INLINE_WRITE_LOCK=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_SPIN_TRYLOCK=y
+CONFIG_INLINE_SPIN_TRYLOCK_BH=y
+CONFIG_INLINE_SPIN_LOCK=y
+CONFIG_INLINE_SPIN_LOCK_BH=y
+CONFIG_INLINE_SPIN_LOCK_IRQ=y
+CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y
+CONFIG_INLINE_SPIN_UNLOCK_BH=y
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_READ_TRYLOCK=y
+CONFIG_INLINE_READ_LOCK=y
+CONFIG_INLINE_READ_LOCK_BH=y
+CONFIG_INLINE_READ_LOCK_IRQ=y
+CONFIG_INLINE_READ_LOCK_IRQSAVE=y
+CONFIG_INLINE_READ_UNLOCK=y
+CONFIG_INLINE_READ_UNLOCK_BH=y
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_WRITE_TRYLOCK=y
+CONFIG_INLINE_WRITE_LOCK=y
+CONFIG_INLINE_WRITE_LOCK_BH=y
+CONFIG_INLINE_WRITE_LOCK_IRQ=y
+CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y
+CONFIG_INLINE_WRITE_UNLOCK=y
+CONFIG_INLINE_WRITE_UNLOCK_BH=y
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_MULTIPLATFORM is not set
+CONFIG_ARCH_AMBARELLA=y
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_LPC32XX is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C24XX is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P64X0 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_EXYNOS is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP1 is not set
+CONFIG_PLAT_AMBARELLA=y
+
+#
+# Ambarella Platform
+#
+CONFIG_PLAT_AMBARELLA_SUPPORT_VIC=y
+CONFIG_PLAT_AMBARELLA_HAVE_ARM11=y
+# CONFIG_PLAT_AMBARELLA_CORTEX is not set
+# CONFIG_PLAT_AMBARELLA_MEM_START_LOW is not set
+# CONFIG_PLAT_AMBARELLA_AHB_APB_HIGH is not set
+CONFIG_PLAT_AMBARELLA_SUPPORT_HW_CRYPTO=y
+# CONFIG_PLAT_AMBARELLA_SUPPORT_GDMA is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_CRYPT is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64 is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS is not set
+# CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_RPROC is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_IOMUX is not set
+# CONFIG_PLAT_AMBARELLA_S2 is not set
+# CONFIG_PLAT_AMBARELLA_A8 is not set
+CONFIG_PLAT_AMBARELLA_A5S=y
+# CONFIG_PLAT_AMBARELLA_A7L is not set
+# CONFIG_PLAT_AMBARELLA_S2_ARM11 is not set
+# CONFIG_PLAT_AMBARELLA_S2_CORTEX is not set
+# CONFIG_PLAT_AMBARELLA_A8_ARM11 is not set
+# CONFIG_PLAT_AMBARELLA_A8_CORTEX is not set
+# CONFIG_PLAT_AMBARELLA_S2L is not set
+
+#
+# Generic Platform Configuration
+#
+# CONFIG_AMBARELLA_RAW_BOOT is not set
+CONFIG_AMBARELLA_SUPPORT_BAPI=y
+# CONFIG_AMBARELLA_PMUSERENR_EN is not set
+
+#
+# Sys file system support
+#
+# CONFIG_AMBARELLA_SYS_CACHE_CALL is not set
+# CONFIG_AMBARELLA_SYS_BAPI_CALL is not set
+
+#
+# Proc file system support
+#
+CONFIG_AMBARELLA_PLL_PROC=y
+# CONFIG_AMBARELLA_SUPPORT_AMBENCH is not set
+
+#
+# Memory Configuration
+#
+CONFIG_AMBARELLA_PPM_SIZE=0x00200000
+CONFIG_AMBARELLA_ZRELADDR=0xC0208000
+CONFIG_AMBARELLA_TEXTOFS=0x00008000
+CONFIG_AMBARELLA_PARAMS_PHYS=0xC0200000
+CONFIG_AMBARELLA_INITRD_PHYS=0xC0A00000
+# CONFIG_AMBARELLA_IO_MAP is not set
+# CONFIG_AMBARELLA_PPM_UNCACHED is not set
+CONFIG_AMBARELLA_TIMER_HZ=100
+CONFIG_AMBARELLA_TIMER_HIGHRES=y
+CONFIG_AMBARELLA_EXT_IRQ_NUM=64
+CONFIG_AMBARELLA_EXT_GPIO_NUM=64
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_KEYBOARD_GPIO_POLLED is not set
+# CONFIG_PLAT_SPEAR is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_V6=y
+CONFIG_CPU_32v6=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_ABRT_EV6=y
+CONFIG_CPU_PABRT_V6=y
+CONFIG_CPU_CACHE_V6=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V6=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+CONFIG_CPU_USE_DOMAINS=y
+
+#
+# Processor Features
+#
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+# CONFIG_CACHE_L2X0 is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_NR_BANKS=8
+CONFIG_MULTI_IRQ_HANDLER=y
+# CONFIG_ARM_ERRATA_326103 is not set
+# CONFIG_ARM_ERRATA_411920 is not set
+# CONFIG_ARM_ERRATA_364296 is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_VMSPLIT_3G is not set
+CONFIG_VMSPLIT_2G=y
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_ARCH_NR_GPIO=0
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_COUNT=y
+CONFIG_HZ=100
+CONFIG_SCHED_HRTICK=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=y
+# CONFIG_HIGHMEM is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_COMPACTION is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_CROSS_MEMORY_ATTACH is not set
+CONFIG_NEED_PER_CPU_KM=y
+# CONFIG_CLEANCACHE is not set
+# CONFIG_FRONTSWAP is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+# CONFIG_SECCOMP is not set
+CONFIG_CC_STACKPROTECTOR=y
+
+#
+# Boot options
+#
+CONFIG_USE_OF=y
+CONFIG_ATAGS=y
+# CONFIG_DEPRECATED_PARAM_STRUCT is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_ARM_APPENDED_DTB is not set
+CONFIG_CMDLINE="console=ttyS0"
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
+# CONFIG_CMDLINE_EXTEND is not set
+# CONFIG_CMDLINE_FORCE is not set
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_AUTO_ZRELADDR is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_SCRIPT=y
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_COREDUMP=y
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
+CONFIG_PM_SLEEP=y
+# CONFIG_PM_AUTOSLEEP is not set
+# CONFIG_PM_WAKELOCKS is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_CLK=y
+CONFIG_CPU_PM=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_DIAG is not set
+CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=y
+CONFIG_XFRM=y
+CONFIG_XFRM_ALGO=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=y
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+# CONFIG_IP_FIB_TRIE_STATS is not set
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
+# CONFIG_NET_IP_TUNNEL is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_NET_IPVTI is not set
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+CONFIG_INET_UDP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+CONFIG_STP=y
+CONFIG_BRIDGE=y
+CONFIG_BRIDGE_IGMP_SNOOPING=y
+CONFIG_HAVE_NET_DSA=y
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_OPENVSWITCH is not set
+# CONFIG_VSOCKETS is not set
+# CONFIG_NETLINK_MMAP is not set
+# CONFIG_NETLINK_DIAG is not set
+CONFIG_BQL=y
+# CONFIG_BPF_JIT is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+# CONFIG_BT_HIDP is not set
+
+#
+# Bluetooth device drivers
+#
+# CONFIG_BT_HCIBTSDIO is not set
+# CONFIG_BT_HCIUART is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_BT_MRVL is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_CFG80211=y
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+CONFIG_CFG80211_DEBUGFS=y
+# CONFIG_CFG80211_INTERNAL_REGDB is not set
+CONFIG_CFG80211_WEXT=y
+# CONFIG_LIB80211 is not set
+CONFIG_MAC80211=y
+CONFIG_MAC80211_HAS_RC=y
+CONFIG_MAC80211_RC_MINSTREL=y
+CONFIG_MAC80211_RC_MINSTREL_HT=y
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
+# CONFIG_MAC80211_MESH is not set
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_MESSAGE_TRACING is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
+CONFIG_RFKILL=y
+CONFIG_RFKILL_INPUT=y
+# CONFIG_RFKILL_GPIO is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+# CONFIG_NFC is not set
+CONFIG_HAVE_BPF_JIT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+CONFIG_FW_LOADER_USER_HELPER=y
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_GENERIC_CPU_DEVICES is not set
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=m
+CONFIG_REGMAP_SPI=m
+# CONFIG_DMA_SHARED_BUFFER is not set
+# CONFIG_CMA is not set
+
+#
+# Bus devices
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+# CONFIG_MTD_SWAP is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_AMBARELLA_SPI_NOR is not set
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOCG3 is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_BCH=y
+CONFIG_MTD_NAND_ECC_BCH=y
+# CONFIG_MTD_SM_COMMON is not set
+CONFIG_MTD_NAND_AMBARELLA=y
+# CONFIG_MTD_NAND_DENALI is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_DOCG4 is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_LIMIT=20
+# CONFIG_MTD_UBI_FASTMAP is not set
+# CONFIG_MTD_UBI_GLUEBI is not set
+CONFIG_DTC=y
+CONFIG_OF=y
+
+#
+# Device Tree and Open Firmware support
+#
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_OF_SELFTEST is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_DEVICE=y
+CONFIG_OF_I2C=y
+CONFIG_OF_NET=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_MTD=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_BLK_DEV_XIP=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_BLK_DEV_RBD is not set
+
+#
+# Misc devices
+#
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ATMEL_PWM is not set
+# CONFIG_DUMMY_IRQ is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ATMEL_SSC is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_APDS9802ALS is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_ISL29020 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_BH1780 is not set
+# CONFIG_SENSORS_BH1770 is not set
+# CONFIG_SENSORS_APDS990X is not set
+# CONFIG_HMC6352 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_BMP085_I2C is not set
+# CONFIG_BMP085_SPI is not set
+# CONFIG_USB_SWITCH_FSA9480 is not set
+# CONFIG_LATTICE_ECP3_CONFIG is not set
+# CONFIG_SRAM is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_EEPROM_93XX46 is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_TI_ST is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+
+#
+# Altera FPGA firmware download module
+#
+# CONFIG_ALTERA_STAPL is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_CORE=y
+# CONFIG_BONDING is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_MII=y
+# CONFIG_NET_TEAM is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_VXLAN is not set
+CONFIG_NETCONSOLE=y
+CONFIG_NETCONSOLE_DYNAMIC=y
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+
+#
+# CAIF transport drivers
+#
+
+#
+# Distributed Switch Architecture drivers
+#
+# CONFIG_NET_DSA_MV88E6XXX is not set
+# CONFIG_NET_DSA_MV88E6060 is not set
+# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
+# CONFIG_NET_DSA_MV88E6131 is not set
+# CONFIG_NET_DSA_MV88E6123_61_65 is not set
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_AMBARELLA=m
+# CONFIG_NET_VENDOR_AMBARELLA_INTEN_TUE is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_CALXEDA_XGMAC is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_DM9000 is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_ETHOC is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_AT803X_PHY is not set
+# CONFIG_AMD_PHY is not set
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_BCM87XX_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
+# CONFIG_MICREL_PHY_KSZ80X1R is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+# CONFIG_MDIO_BUS_MUX_GPIO is not set
+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
+# CONFIG_MICREL_KS8995MA is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+# CONFIG_INPUT_MATRIXKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ADP5589 is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_QT1070 is not set
+# CONFIG_KEYBOARD_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_GPIO=m
+# CONFIG_KEYBOARD_TCA6416 is not set
+# CONFIG_KEYBOARD_TCA8418 is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8333 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_MCS is not set
+# CONFIG_KEYBOARD_MPR121 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_SAMSUNG is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_BMA150 is not set
+CONFIG_INPUT_AMBARELLA_IR=m
+CONFIG_INPUT_AMBARELLA_ADC=m
+# CONFIG_INPUT_MMA8450 is not set
+# CONFIG_INPUT_MPU3050 is not set
+# CONFIG_INPUT_GP2A is not set
+# CONFIG_INPUT_GPIO_TILT_POLLED is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_KXTJ9 is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+CONFIG_INPUT_UINPUT=m
+# CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_PWM_BEEPER is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_CMA3000 is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_TTY=y
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_CONSOLE_SLEEP=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+# CONFIG_DEVKMEM is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AMBARELLA=y
+CONFIG_SERIAL_AMBARELLA_CONSOLE=y
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX310X is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_SCCNXP is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_IFX6X60 is not set
+# CONFIG_SERIAL_XILINX_PS_UART is not set
+# CONFIG_SERIAL_ARC is not set
+# CONFIG_HVC_DCC is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_MUX=y
+
+#
+# Multiplexer I2C Chip support
+#
+# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set
+# CONFIG_I2C_MUX_GPIO is not set
+# CONFIG_I2C_MUX_PCA9541 is not set
+# CONFIG_I2C_MUX_PCA954x is not set
+CONFIG_I2C_MUX_PINCTRL=y
+# CONFIG_I2C_HELPER_AUTO is not set
+# CONFIG_I2C_SMBUS is not set
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_AMBARELLA=y
+# CONFIG_I2C_CBUS_GPIO is not set
+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_SLAVE=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+CONFIG_SPI_AMBARELLA=y
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_FSL_SPI is not set
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_SC18IS602 is not set
+# CONFIG_SPI_XCOMM is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=m
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# SPI Slave Controller Drivers
+#
+# CONFIG_SPI_SLAVE_AMBARELLA is not set
+
+#
+# Qualcomm MSM SSBI bus support
+#
+# CONFIG_SSBI is not set
+# CONFIG_HSI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+# CONFIG_PTP_1588_CLOCK is not set
+
+#
+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
+#
+# CONFIG_PTP_1588_CLOCK_PCH is not set
+CONFIG_PINCTRL=y
+
+#
+# Pin controllers
+#
+CONFIG_PINMUX=y
+CONFIG_PINCONF=y
+# CONFIG_PINCTRL_SINGLE is not set
+# CONFIG_PINCTRL_EXYNOS is not set
+# CONFIG_PINCTRL_EXYNOS5440 is not set
+CONFIG_PINCTRL_AMB=y
+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIO_DEVRES=y
+CONFIG_GPIOLIB=y
+CONFIG_OF_GPIO=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_GENERIC_PLATFORM is not set
+# CONFIG_GPIO_EM is not set
+# CONFIG_GPIO_RCAR is not set
+# CONFIG_GPIO_TS5500 is not set
+# CONFIG_GPIO_GRGPIO is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_SX150X is not set
+# CONFIG_GPIO_ADP5588 is not set
+# CONFIG_GPIO_ADNP is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+# CONFIG_GPIO_74X164 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+
+#
+# USB GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_POWER_AVS is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AMBARELLA_WATCHDOG=y
+# CONFIG_DW_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_AS3711 is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_AAT2870_CORE is not set
+# CONFIG_MFD_CROS_EC is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_DA9052_SPI is not set
+# CONFIG_MFD_DA9052_I2C is not set
+# CONFIG_MFD_DA9055 is not set
+# CONFIG_MFD_MC13XXX_SPI is not set
+# CONFIG_MFD_MC13XXX_I2C is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_MFD_88PM800 is not set
+# CONFIG_MFD_88PM805 is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_MAX77686 is not set
+# CONFIG_MFD_MAX77693 is not set
+# CONFIG_MFD_MAX8907 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_MAX8997 is not set
+# CONFIG_MFD_MAX8998 is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_RETU is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_RC5T583 is not set
+# CONFIG_MFD_SEC_CORE is not set
+# CONFIG_MFD_SI476X_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SMSC is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_MFD_STMPE is not set
+# CONFIG_MFD_SYSCON is not set
+# CONFIG_MFD_TI_AM335X_TSCADC is not set
+# CONFIG_MFD_LP8788 is not set
+# CONFIG_MFD_PALMAS is not set
+# CONFIG_TPS6105X is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_MFD_TPS65090 is not set
+# CONFIG_MFD_TPS65217 is not set
+# CONFIG_MFD_TPS6586X is not set
+# CONFIG_MFD_TPS65910 is not set
+# CONFIG_MFD_TPS65912 is not set
+# CONFIG_MFD_TPS65912_I2C is not set
+# CONFIG_MFD_TPS65912_SPI is not set
+# CONFIG_MFD_TPS80031 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_TWL6040_CORE is not set
+# CONFIG_MFD_WL1273_CORE is not set
+# CONFIG_MFD_LM3533 is not set
+# CONFIG_MFD_TC3589X is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_MFD_ARIZONA_I2C is not set
+# CONFIG_MFD_ARIZONA_SPI is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X_I2C is not set
+# CONFIG_MFD_WM831X_SPI is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+CONFIG_FB_SYS_FILLRECT=y
+CONFIG_FB_SYS_COPYAREA=y
+CONFIG_FB_SYS_IMAGEBLIT=y
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+CONFIG_FB_SYS_FOPS=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_GOLDFISH is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+CONFIG_FB_AMBARELLA=y
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_FB_AUO_K190X is not set
+# CONFIG_FB_SIMPLE is not set
+# CONFIG_EXYNOS_VIDEO is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_L4F00242T03 is not set
+# CONFIG_LCD_LMS283GF05 is not set
+# CONFIG_LCD_LTV350QV is not set
+# CONFIG_LCD_ILI922X is not set
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_TDO24M is not set
+# CONFIG_LCD_VGG2432A4 is not set
+CONFIG_LCD_PLATFORM=y
+# CONFIG_LCD_S6E63M0 is not set
+# CONFIG_LCD_LD9040 is not set
+# CONFIG_LCD_AMS369FG06 is not set
+# CONFIG_LCD_LMS501KF03 is not set
+# CONFIG_LCD_HX8357 is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+# CONFIG_BACKLIGHT_PWM is not set
+# CONFIG_BACKLIGHT_ADP8860 is not set
+# CONFIG_BACKLIGHT_ADP8870 is not set
+# CONFIG_BACKLIGHT_LM3630 is not set
+# CONFIG_BACKLIGHT_LM3639 is not set
+# CONFIG_BACKLIGHT_LP855X is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=m
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+# CONFIG_LOGO is not set
+# CONFIG_FB_SSD1307 is not set
+CONFIG_SOUND=m
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_COMPRESS_OFFLOAD=m
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_SOC=m
+CONFIG_SND_SOC_DMAENGINE_PCM=y
+CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
+CONFIG_SND_AMBARELLA_SOC=m
+CONFIG_SND_AMBARELLA_SOC_I2S=m
+CONFIG_SND_AMBARELLA_BOARD=m
+CONFIG_AMBA_BOARD=m
+CONFIG_AMBARELLA_DUMMY_BOARD=m
+# CONFIG_SND_ATMEL_SOC is not set
+CONFIG_SND_SOC_I2C_AND_SPI=m
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_AMBARELLA_DUMMY=m
+CONFIG_SND_AMBARELLA_CODEC=m
+CONFIG_SND_SOC_AK4642_AMB=m
+# CONFIG_SND_SIMPLE_CARD is not set
+# CONFIG_SOUND_PRIME is not set
+
+#
+# HID support
+#
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+# CONFIG_UHID is not set
+CONFIG_HID_GENERIC=y
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=y
+# CONFIG_HID_ACRUX is not set
+CONFIG_HID_APPLE=y
+# CONFIG_HID_AUREAL is not set
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+# CONFIG_HID_PRODIKEYS is not set
+CONFIG_HID_CYPRESS=y
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_ELECOM is not set
+CONFIG_HID_EZKEY=y
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_ICADE is not set
+# CONFIG_HID_TWINHAN is not set
+CONFIG_HID_KENSINGTON=y
+# CONFIG_HID_LCPOWER is not set
+CONFIG_HID_LOGITECH=y
+# CONFIG_HID_LOGITECH_DJ is not set
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
+# CONFIG_LOGIWHEELS_FF is not set
+# CONFIG_HID_MAGICMOUSE is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_PRIMAX is not set
+# CONFIG_HID_PS3REMOTE is not set
+# CONFIG_HID_SAITEK is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SPEEDLINK is not set
+# CONFIG_HID_STEELSERIES is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TIVO is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+# CONFIG_HID_SENSOR_HUB is not set
+
+#
+# I2C HID support
+#
+# CONFIG_I2C_HID is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB_ARCH_HAS_XHCI is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_COMMON=m
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB is not set
+# CONFIG_USB_DWC3 is not set
+# CONFIG_USB_CHIPIDEA is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_PHY=y
+CONFIG_USB_AMBARELLA_PHY=y
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_OMAP_CONTROL_USB is not set
+# CONFIG_OMAP_USB3 is not set
+# CONFIG_SAMSUNG_USBPHY is not set
+# CONFIG_SAMSUNG_USB2PHY is not set
+# CONFIG_SAMSUNG_USB3PHY is not set
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ISP1301 is not set
+# CONFIG_USB_RCAR_PHY is not set
+# CONFIG_USB_ULPI is not set
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
+
+#
+# USB Peripheral Controller
+#
+# CONFIG_USB_FUSB300 is not set
+# CONFIG_USB_R8A66597 is not set
+# CONFIG_USB_PXA27X is not set
+# CONFIG_USB_MV_UDC is not set
+# CONFIG_USB_MV_U3D is not set
+# CONFIG_USB_M66592 is not set
+# CONFIG_USB_NET2272 is not set
+CONFIG_USB_AMBARELLA=m
+CONFIG_USB_LIBCOMPOSITE=m
+CONFIG_USB_F_ACM=m
+CONFIG_USB_U_SERIAL=m
+CONFIG_USB_F_SERIAL=m
+CONFIG_USB_F_OBEX=m
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
+# CONFIG_USB_G_NCM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FUNCTIONFS is not set
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_ACM_MS is not set
+# CONFIG_USB_G_MULTI is not set
+# CONFIG_USB_G_HID is not set
+# CONFIG_USB_G_DBGP is not set
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+# CONFIG_MMC_CLKGATE is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_BLOCK_MINORS=32
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+# CONFIG_SDIO_UART is not set
+CONFIG_MMC_TEST=m
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_AMBARELLA=m
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MMC_DW is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_EDAC is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_SYSTOHC=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS3232 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+CONFIG_RTC_DRV_ISL12022=y
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8523 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+# CONFIG_RTC_DRV_EM3027 is not set
+# CONFIG_RTC_DRV_RV3029C2 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T93 is not set
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+# CONFIG_RTC_DRV_RX4581 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+# CONFIG_RTC_DRV_DS2404 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_AMBARELLA=y
+# CONFIG_RTC_DRV_SNVS is not set
+
+#
+# HID Sensor RTC drivers
+#
+CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+# CONFIG_DW_DMAC is not set
+# CONFIG_TIMB_DMA is not set
+CONFIG_AMBARELLA_DMA=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_VIRT_DRIVERS is not set
+
+#
+# Virtio drivers
+#
+# CONFIG_VIRTIO_MMIO is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+# CONFIG_STAGING is not set
+
+#
+# Hardware Spinlock drivers
+#
+# CONFIG_MAILBOX is not set
+# CONFIG_IOMMU_SUPPORT is not set
+
+#
+# Remoteproc drivers
+#
+# CONFIG_STE_MODEM_RPROC is not set
+# CONFIG_RPROC_SUPPORT is not set
+# CONFIG_RPCLNT_SUPPORT is not set
+
+#
+# Rpmsg drivers
+#
+# CONFIG_PM_DEVFREQ is not set
+# CONFIG_EXTCON is not set
+# CONFIG_MEMORY is not set
+# CONFIG_IIO is not set
+CONFIG_PWM=y
+CONFIG_PWM_AMBARELLA=m
+CONFIG_IRQCHIP=y
+CONFIG_AMBARELLA_VIC=y
+# CONFIG_IPACK_BUS is not set
+# CONFIG_RESET_CONTROLLER is not set
+
+#
+# File systems
+#
+CONFIG_DCACHE_WORD_ACCESS=y
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_USE_FOR_EXT23=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_EXPORTFS=m
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_FANOTIFY=y
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_TMPFS_XATTR=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX6FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_PSTORE is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_F2FS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V2=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_SWAP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_DEBUG is not set
+# CONFIG_CEPH_FS is not set
+CONFIG_CIFS=y
+CONFIG_CIFS_STATS=y
+# CONFIG_CIFS_STATS2 is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+CONFIG_CIFS_DEBUG=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_SMB2 is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_MAC_ROMAN is not set
+# CONFIG_NLS_MAC_CELTIC is not set
+# CONFIG_NLS_MAC_CENTEURO is not set
+# CONFIG_NLS_MAC_CROATIAN is not set
+# CONFIG_NLS_MAC_CYRILLIC is not set
+# CONFIG_NLS_MAC_GAELIC is not set
+# CONFIG_NLS_MAC_GREEK is not set
+# CONFIG_NLS_MAC_ICELAND is not set
+# CONFIG_NLS_MAC_INUIT is not set
+# CONFIG_NLS_MAC_ROMANIAN is not set
+# CONFIG_NLS_MAC_TURKISH is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_PANIC_ON_OOPS is not set
+CONFIG_PANIC_ON_OOPS_VALUE=0
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+
+#
+# RCU Debugging
+#
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_LKDTM is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+CONFIG_DYNAMIC_DEBUG=y
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_TEST_STRING_HELPERS is not set
+# CONFIG_TEST_KSTRTOX is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
+CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"
+# CONFIG_PID_IN_CONTEXTIDR is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_USER is not set
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_CMAC is not set
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_CRC32 is not set
+# CONFIG_CRYPTO_GHASH is not set
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA1_ARM is not set
+CONFIG_CRYPTO_SHA256=y
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_AES_ARM is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=y
+# CONFIG_CRYPTO_USER_API_HASH is not set
+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
+CONFIG_CRYPTO_HW=y
+#CONFIG_CRYPTO_DEV_AMBARELLA=m
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_IO=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC32_SELFTEST is not set
+CONFIG_CRC32_SLICEBY8=y
+# CONFIG_CRC32_SLICEBY4 is not set
+# CONFIG_CRC32_SARWATE is not set
+# CONFIG_CRC32_BIT is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+# CONFIG_CRC8 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_XZ_DEC=y
+CONFIG_XZ_DEC_X86=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_SPARC=y
+CONFIG_XZ_DEC_BCJ=y
+# CONFIG_XZ_DEC_TEST is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_XZ=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_BCH=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_DQL=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+CONFIG_AVERAGE=y
+# CONFIG_CORDIC is not set
+# CONFIG_DDR is not set
+# CONFIG_VIRTUALIZATION is not set
diff --git a/arch/arm/configs/ambarella_a7l_defconfig b/arch/arm/configs/ambarella_a7l_defconfig
new file mode 100644
index 00000000..3fe42184
--- /dev/null
+++ b/arch/arm/configs/ambarella_a7l_defconfig
@@ -0,0 +1,2063 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/arm 3.10.0 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_NEED_MACH_GPIO_H=y
+CONFIG_NEED_MACH_IO_H=y
+CONFIG_NEED_MACH_MEMORY_H=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_IRQ_WORK=y
+CONFIG_BUILDTIME_EXTABLE_SORT=y
+
+#
+# General setup
+#
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_XZ is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_DEFAULT_HOSTNAME="Ambarella"
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_FHANDLE is not set
+# CONFIG_AUDIT is not set
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_IRQ_DOMAIN=y
+# CONFIG_IRQ_DOMAIN_DEBUG is not set
+CONFIG_KTIME_SCALAR=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# Timers subsystem
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ_COMMON=y
+# CONFIG_HZ_PERIODIC is not set
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+
+#
+# CPU/Task time and stats accounting
+#
+CONFIG_TICK_CPU_ACCOUNTING=y
+# CONFIG_IRQ_TIME_ACCOUNTING is not set
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_TREE_PREEMPT_RCU is not set
+CONFIG_TINY_PREEMPT_RCU=y
+CONFIG_PREEMPT_RCU=y
+# CONFIG_RCU_STALL_COMMON is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_RCU_BOOST is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_CGROUPS is not set
+# CONFIG_CHECKPOINT_RESTORE is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+CONFIG_UIDGID_CONVERTED=y
+# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_XZ=y
+CONFIG_RD_LZO=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_HAVE_UID16=y
+CONFIG_HOTPLUG=y
+# CONFIG_EXPERT is not set
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+# CONFIG_EMBEDDED is not set
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_JUMP_LABEL is not set
+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_OLD_SIGACTION=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_MODULE_SIG is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_BSGLIB is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_AMBPTB_PARTITION=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y
+CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_LOCK=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y
+CONFIG_ARCH_INLINE_READ_TRYLOCK=y
+CONFIG_ARCH_INLINE_READ_LOCK=y
+CONFIG_ARCH_INLINE_READ_LOCK_BH=y
+CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_READ_UNLOCK=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y
+CONFIG_ARCH_INLINE_WRITE_TRYLOCK=y
+CONFIG_ARCH_INLINE_WRITE_LOCK=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_SPIN_TRYLOCK=y
+CONFIG_INLINE_SPIN_TRYLOCK_BH=y
+CONFIG_INLINE_SPIN_LOCK=y
+CONFIG_INLINE_SPIN_LOCK_BH=y
+CONFIG_INLINE_SPIN_LOCK_IRQ=y
+CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y
+CONFIG_INLINE_SPIN_UNLOCK_BH=y
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_READ_TRYLOCK=y
+CONFIG_INLINE_READ_LOCK=y
+CONFIG_INLINE_READ_LOCK_BH=y
+CONFIG_INLINE_READ_LOCK_IRQ=y
+CONFIG_INLINE_READ_LOCK_IRQSAVE=y
+CONFIG_INLINE_READ_UNLOCK=y
+CONFIG_INLINE_READ_UNLOCK_BH=y
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_WRITE_TRYLOCK=y
+CONFIG_INLINE_WRITE_LOCK=y
+CONFIG_INLINE_WRITE_LOCK_BH=y
+CONFIG_INLINE_WRITE_LOCK_IRQ=y
+CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y
+CONFIG_INLINE_WRITE_UNLOCK=y
+CONFIG_INLINE_WRITE_UNLOCK_BH=y
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_MULTIPLATFORM is not set
+CONFIG_ARCH_AMBARELLA=y
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_LPC32XX is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C24XX is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P64X0 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_EXYNOS is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP1 is not set
+CONFIG_PLAT_AMBARELLA=y
+
+#
+# Ambarella Platform
+#
+CONFIG_PLAT_AMBARELLA_SUPPORT_VIC=y
+CONFIG_PLAT_AMBARELLA_HAVE_ARM11=y
+# CONFIG_PLAT_AMBARELLA_CORTEX is not set
+# CONFIG_PLAT_AMBARELLA_MEM_START_LOW is not set
+# CONFIG_PLAT_AMBARELLA_AHB_APB_HIGH is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_HW_CRYPTO is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI is not set
+CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC=y
+# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_CRYPT is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64 is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS is not set
+# CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_RPROC is not set
+# CONFIG_PLAT_AMBARELLA_S2 is not set
+# CONFIG_PLAT_AMBARELLA_A8 is not set
+# CONFIG_PLAT_AMBARELLA_A5S is not set
+CONFIG_PLAT_AMBARELLA_A7L=y
+# CONFIG_PLAT_AMBARELLA_S2_ARM11 is not set
+# CONFIG_PLAT_AMBARELLA_S2_CORTEX is not set
+# CONFIG_PLAT_AMBARELLA_A8_ARM11 is not set
+# CONFIG_PLAT_AMBARELLA_A8_CORTEX is not set
+# CONFIG_PLAT_AMBARELLA_S2L is not set
+
+#
+# Generic Platform Configuration
+#
+# CONFIG_AMBARELLA_RAW_BOOT is not set
+CONFIG_AMBARELLA_SUPPORT_BAPI=y
+# CONFIG_AMBARELLA_PMUSERENR_EN is not set
+
+#
+# Sys file system support
+#
+# CONFIG_AMBARELLA_SYS_CACHE_CALL is not set
+# CONFIG_AMBARELLA_SYS_BAPI_CALL is not set
+
+#
+# Proc file system support
+#
+CONFIG_AMBARELLA_PLL_PROC=y
+# CONFIG_AMBARELLA_SUPPORT_AMBENCH is not set
+
+#
+# Memory Configuration
+#
+CONFIG_AMBARELLA_PPM_SIZE=0x00200000
+CONFIG_AMBARELLA_ZRELADDR=0xC0208000
+CONFIG_AMBARELLA_TEXTOFS=0x00008000
+CONFIG_AMBARELLA_PARAMS_PHYS=0xC0200000
+CONFIG_AMBARELLA_INITRD_PHYS=0xC0A00000
+# CONFIG_AMBARELLA_IO_MAP is not set
+# CONFIG_AMBARELLA_PPM_UNCACHED is not set
+
+#
+# FIO Configuration
+#
+# CONFIG_AMBARELLA_FIO_FORCE_SDIO_GPIO is not set
+CONFIG_AMBARELLA_TIMER_HZ=100
+CONFIG_AMBARELLA_TIMER_HIGHRES=y
+CONFIG_AMBARELLA_EXT_IRQ_NUM=64
+CONFIG_AMBARELLA_EXT_GPIO_NUM=64
+
+#
+# Ambarella Board
+#
+CONFIG_MACH_AMBARELLA=y
+CONFIG_MACH_DURIAN=y
+
+#
+# Misc on Board Devices
+#
+
+#
+# Ambarella
+#
+CONFIG_AMBARELLA_VOUT=y
+
+#
+# Touch
+#
+# CONFIG_TOUCH_AMBARELLA_AK4183 is not set
+# CONFIG_TOUCH_AMBARELLA_CHACHA_MT4D is not set
+# CONFIG_TOUCH_AMBARELLA_TM1510 is not set
+# CONFIG_TOUCH_AMBARELLA_TM1726 is not set
+# CONFIG_TOUCH_AMBARELLA_TM1927 is not set
+# CONFIG_TOUCH_AMBARELLA_FT540 is not set
+# CONFIG_TOUCH_AMBARELLA_NT11001 is not set
+
+#
+# LCD
+#
+
+#
+# RTC
+#
+
+#
+# Audio Codec
+#
+# CONFIG_CODEC_AMBARELLA_WM8737 is not set
+# CONFIG_CODEC_AMBARELLA_WM8994 is not set
+# CONFIG_CODEC_AMBARELLA_ES8328 is not set
+# CONFIG_CODEC_AMBARELLA_AK4642 is not set
+
+#
+# PMIC
+#
+# CONFIG_PMIC_AMBARELLA_WM831X is not set
+
+#
+# cpufreq-dev
+#
+# CONFIG_CPUFREQ_AMBARELLA_DEVICE is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_PLAT_SPEAR is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_V6=y
+CONFIG_CPU_32v6=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_ABRT_EV6=y
+CONFIG_CPU_PABRT_V6=y
+CONFIG_CPU_CACHE_V6=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V6=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+CONFIG_CPU_USE_DOMAINS=y
+
+#
+# Processor Features
+#
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+# CONFIG_CACHE_L2X0 is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_NR_BANKS=8
+CONFIG_MULTI_IRQ_HANDLER=y
+# CONFIG_ARM_ERRATA_326103 is not set
+# CONFIG_ARM_ERRATA_411920 is not set
+# CONFIG_ARM_ERRATA_364296 is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_VMSPLIT_3G is not set
+CONFIG_VMSPLIT_2G=y
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_ARCH_NR_GPIO=0
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_COUNT=y
+CONFIG_HZ=100
+CONFIG_SCHED_HRTICK=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=y
+# CONFIG_HIGHMEM is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_COMPACTION is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_CROSS_MEMORY_ATTACH is not set
+CONFIG_NEED_PER_CPU_KM=y
+# CONFIG_CLEANCACHE is not set
+# CONFIG_FRONTSWAP is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+# CONFIG_SECCOMP is not set
+CONFIG_CC_STACKPROTECTOR=y
+
+#
+# Boot options
+#
+# CONFIG_USE_OF is not set
+CONFIG_ATAGS=y
+# CONFIG_DEPRECATED_PARAM_STRUCT is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="console=ttyS0"
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
+# CONFIG_CMDLINE_EXTEND is not set
+# CONFIG_CMDLINE_FORCE is not set
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_AUTO_ZRELADDR is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_SCRIPT=y
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_COREDUMP=y
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
+CONFIG_PM_SLEEP=y
+# CONFIG_PM_AUTOSLEEP is not set
+# CONFIG_PM_WAKELOCKS is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_CLK=y
+CONFIG_CPU_PM=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_DIAG is not set
+CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=y
+CONFIG_XFRM=y
+CONFIG_XFRM_ALGO=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=y
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+# CONFIG_IP_FIB_TRIE_STATS is not set
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
+# CONFIG_NET_IP_TUNNEL is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_NET_IPVTI is not set
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+CONFIG_INET_UDP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+CONFIG_STP=y
+CONFIG_BRIDGE=y
+CONFIG_BRIDGE_IGMP_SNOOPING=y
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_OPENVSWITCH is not set
+# CONFIG_VSOCKETS is not set
+# CONFIG_NETLINK_MMAP is not set
+# CONFIG_NETLINK_DIAG is not set
+CONFIG_BQL=y
+# CONFIG_BPF_JIT is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+# CONFIG_BT_HIDP is not set
+
+#
+# Bluetooth device drivers
+#
+# CONFIG_BT_HCIBTSDIO is not set
+# CONFIG_BT_HCIUART is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_BT_MRVL is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_CFG80211=y
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+CONFIG_CFG80211_DEBUGFS=y
+# CONFIG_CFG80211_INTERNAL_REGDB is not set
+CONFIG_CFG80211_WEXT=y
+# CONFIG_LIB80211 is not set
+CONFIG_MAC80211=y
+CONFIG_MAC80211_HAS_RC=y
+CONFIG_MAC80211_RC_MINSTREL=y
+CONFIG_MAC80211_RC_MINSTREL_HT=y
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
+# CONFIG_MAC80211_MESH is not set
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_MESSAGE_TRACING is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
+CONFIG_RFKILL=y
+CONFIG_RFKILL_INPUT=y
+# CONFIG_RFKILL_GPIO is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+# CONFIG_NFC is not set
+CONFIG_HAVE_BPF_JIT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+CONFIG_FW_LOADER_USER_HELPER=y
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_GENERIC_CPU_DEVICES is not set
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=m
+CONFIG_REGMAP_SPI=m
+# CONFIG_DMA_SHARED_BUFFER is not set
+# CONFIG_CMA is not set
+
+#
+# Bus devices
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+# CONFIG_MTD_SWAP is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOCG3 is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_BCH=y
+CONFIG_MTD_NAND_ECC_BCH=y
+# CONFIG_MTD_SM_COMMON is not set
+CONFIG_MTD_NAND_AMBARELLA=y
+# CONFIG_MTD_NAND_DENALI is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_DOCG4 is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_LIMIT=20
+# CONFIG_MTD_UBI_FASTMAP is not set
+# CONFIG_MTD_UBI_GLUEBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_BLK_DEV_XIP=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_BLK_DEV_RBD is not set
+
+#
+# Misc devices
+#
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ATMEL_PWM is not set
+# CONFIG_DUMMY_IRQ is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ATMEL_SSC is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_APDS9802ALS is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_ISL29020 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_BH1780 is not set
+# CONFIG_SENSORS_BH1770 is not set
+# CONFIG_SENSORS_APDS990X is not set
+# CONFIG_HMC6352 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_BMP085_I2C is not set
+# CONFIG_BMP085_SPI is not set
+# CONFIG_USB_SWITCH_FSA9480 is not set
+# CONFIG_LATTICE_ECP3_CONFIG is not set
+# CONFIG_SRAM is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_EEPROM_93XX46 is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_TI_ST is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+
+#
+# Altera FPGA firmware download module
+#
+# CONFIG_ALTERA_STAPL is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_NETDEVICES is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+# CONFIG_INPUT_MATRIXKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_BMA150 is not set
+CONFIG_INPUT_AMBARELLA=m
+CONFIG_INPUT_AMBARELLA_IR=y
+CONFIG_INPUT_AMBARELLA_ADC=y
+# CONFIG_INPUT_MMA8450 is not set
+# CONFIG_INPUT_MPU3050 is not set
+# CONFIG_INPUT_GP2A is not set
+# CONFIG_INPUT_GPIO_TILT_POLLED is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_KXTJ9 is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+CONFIG_INPUT_UINPUT=m
+# CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_PWM_BEEPER is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_CMA3000 is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_TTY=y
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_CONSOLE_SLEEP=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+# CONFIG_DEVKMEM is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AMBARELLA=y
+CONFIG_SERIAL_AMBARELLA_CONSOLE=y
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX310X is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_SCCNXP is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_IFX6X60 is not set
+# CONFIG_SERIAL_ARC is not set
+# CONFIG_HVC_DCC is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_MUX=y
+
+#
+# Multiplexer I2C Chip support
+#
+# CONFIG_I2C_MUX_GPIO is not set
+CONFIG_I2C_MUX_AMBARELLA=y
+# CONFIG_I2C_MUX_PCA9541 is not set
+# CONFIG_I2C_MUX_PCA954x is not set
+# CONFIG_I2C_HELPER_AUTO is not set
+# CONFIG_I2C_SMBUS is not set
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_AMBARELLA=y
+# CONFIG_I2C_CBUS_GPIO is not set
+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_SLAVE=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+CONFIG_SPI_AMBARELLA=y
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_SC18IS602 is not set
+# CONFIG_SPI_XCOMM is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=m
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# SPI Slave Controller Drivers
+#
+# CONFIG_SPI_SLAVE_AMBARELLA is not set
+
+#
+# Qualcomm MSM SSBI bus support
+#
+# CONFIG_SSBI is not set
+# CONFIG_HSI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+# CONFIG_PTP_1588_CLOCK is not set
+
+#
+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
+#
+# CONFIG_PTP_1588_CLOCK_PCH is not set
+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIO_DEVRES=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_GENERIC_PLATFORM is not set
+# CONFIG_GPIO_EM is not set
+# CONFIG_GPIO_RCAR is not set
+# CONFIG_GPIO_TS5500 is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_SX150X is not set
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+# CONFIG_GPIO_74X164 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+
+#
+# USB GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_POWER_AVS is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_CORE is not set
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AMBARELLA_WATCHDOG=y
+# CONFIG_DW_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_AS3711 is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_AAT2870_CORE is not set
+# CONFIG_MFD_CROS_EC is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_DA9052_SPI is not set
+# CONFIG_MFD_DA9052_I2C is not set
+# CONFIG_MFD_DA9055 is not set
+# CONFIG_MFD_MC13XXX_SPI is not set
+# CONFIG_MFD_MC13XXX_I2C is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_MFD_88PM800 is not set
+# CONFIG_MFD_88PM805 is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_MAX77686 is not set
+# CONFIG_MFD_MAX77693 is not set
+# CONFIG_MFD_MAX8907 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_MAX8997 is not set
+# CONFIG_MFD_MAX8998 is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_RETU is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_RC5T583 is not set
+# CONFIG_MFD_SEC_CORE is not set
+# CONFIG_MFD_SI476X_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SMSC is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_MFD_STMPE is not set
+# CONFIG_MFD_SYSCON is not set
+# CONFIG_MFD_TI_AM335X_TSCADC is not set
+# CONFIG_MFD_LP8788 is not set
+# CONFIG_MFD_PALMAS is not set
+# CONFIG_TPS6105X is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_MFD_TPS65090 is not set
+# CONFIG_MFD_TPS65217 is not set
+# CONFIG_MFD_TPS6586X is not set
+# CONFIG_MFD_TPS65910 is not set
+# CONFIG_MFD_TPS65912 is not set
+# CONFIG_MFD_TPS65912_I2C is not set
+# CONFIG_MFD_TPS65912_SPI is not set
+# CONFIG_MFD_TPS80031 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_TWL6040_CORE is not set
+# CONFIG_MFD_WL1273_CORE is not set
+# CONFIG_MFD_LM3533 is not set
+# CONFIG_MFD_TC3589X is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_MFD_ARIZONA_I2C is not set
+# CONFIG_MFD_ARIZONA_SPI is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X_I2C is not set
+# CONFIG_MFD_WM831X_SPI is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+CONFIG_FB_SYS_FILLRECT=y
+CONFIG_FB_SYS_COPYAREA=y
+CONFIG_FB_SYS_IMAGEBLIT=y
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+CONFIG_FB_SYS_FOPS=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_GOLDFISH is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+CONFIG_FB_AMBARELLA=y
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_FB_AUO_K190X is not set
+# CONFIG_EXYNOS_VIDEO is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_L4F00242T03 is not set
+# CONFIG_LCD_LMS283GF05 is not set
+# CONFIG_LCD_LTV350QV is not set
+# CONFIG_LCD_ILI922X is not set
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_TDO24M is not set
+# CONFIG_LCD_VGG2432A4 is not set
+CONFIG_LCD_PLATFORM=y
+# CONFIG_LCD_S6E63M0 is not set
+# CONFIG_LCD_LD9040 is not set
+# CONFIG_LCD_AMS369FG06 is not set
+# CONFIG_LCD_LMS501KF03 is not set
+# CONFIG_LCD_HX8357 is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+# CONFIG_BACKLIGHT_ADP8860 is not set
+# CONFIG_BACKLIGHT_ADP8870 is not set
+# CONFIG_BACKLIGHT_LM3630 is not set
+# CONFIG_BACKLIGHT_LM3639 is not set
+# CONFIG_BACKLIGHT_LP855X is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=m
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+# CONFIG_LOGO is not set
+CONFIG_SOUND=m
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_COMPRESS_OFFLOAD=m
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_SOC=m
+CONFIG_SND_AMBARELLA_SOC=m
+CONFIG_SND_AMBARELLA_SOC_I2S=m
+CONFIG_SND_AMBARELLA_BOARD=m
+CONFIG_AMBARELLA_DUMMY_BOARD=m
+# CONFIG_SND_ATMEL_SOC is not set
+CONFIG_SND_SOC_I2C_AND_SPI=m
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_AMBARELLA_DUMMY=m
+# CONFIG_SND_SIMPLE_CARD is not set
+# CONFIG_SOUND_PRIME is not set
+
+#
+# HID support
+#
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+# CONFIG_UHID is not set
+CONFIG_HID_GENERIC=y
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=y
+# CONFIG_HID_ACRUX is not set
+CONFIG_HID_APPLE=y
+# CONFIG_HID_AUREAL is not set
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+# CONFIG_HID_PRODIKEYS is not set
+CONFIG_HID_CYPRESS=y
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_ELECOM is not set
+CONFIG_HID_EZKEY=y
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_ICADE is not set
+# CONFIG_HID_TWINHAN is not set
+CONFIG_HID_KENSINGTON=y
+# CONFIG_HID_LCPOWER is not set
+CONFIG_HID_LOGITECH=y
+# CONFIG_HID_LOGITECH_DJ is not set
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
+# CONFIG_LOGIWHEELS_FF is not set
+# CONFIG_HID_MAGICMOUSE is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_PRIMAX is not set
+# CONFIG_HID_PS3REMOTE is not set
+# CONFIG_HID_SAITEK is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SPEEDLINK is not set
+# CONFIG_HID_STEELSERIES is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TIVO is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+# CONFIG_HID_SENSOR_HUB is not set
+
+#
+# I2C HID support
+#
+# CONFIG_I2C_HID is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB_ARCH_HAS_XHCI is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_COMMON=m
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB is not set
+# CONFIG_USB_DWC3 is not set
+# CONFIG_USB_CHIPIDEA is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_PHY is not set
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
+
+#
+# USB Peripheral Controller
+#
+# CONFIG_USB_FUSB300 is not set
+# CONFIG_USB_R8A66597 is not set
+# CONFIG_USB_PXA27X is not set
+# CONFIG_USB_MV_UDC is not set
+# CONFIG_USB_MV_U3D is not set
+# CONFIG_USB_M66592 is not set
+# CONFIG_USB_NET2272 is not set
+CONFIG_USB_AMBARELLA=m
+CONFIG_USB_LIBCOMPOSITE=m
+CONFIG_USB_F_ACM=m
+CONFIG_USB_U_SERIAL=m
+CONFIG_USB_F_SERIAL=m
+CONFIG_USB_F_OBEX=m
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
+# CONFIG_USB_G_NCM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FUNCTIONFS is not set
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_ACM_MS is not set
+# CONFIG_USB_G_MULTI is not set
+# CONFIG_USB_G_HID is not set
+# CONFIG_USB_G_DBGP is not set
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+# CONFIG_MMC_CLKGATE is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_BLOCK_MINORS=32
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+# CONFIG_SDIO_UART is not set
+CONFIG_MMC_TEST=m
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_AMBARELLA=m
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MMC_DW is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_EDAC is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_SYSTOHC=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS3232 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+CONFIG_RTC_DRV_ISL12022=y
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8523 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+# CONFIG_RTC_DRV_EM3027 is not set
+# CONFIG_RTC_DRV_RV3029C2 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T93 is not set
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+# CONFIG_RTC_DRV_RX4581 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+# CONFIG_RTC_DRV_DS2404 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_AMBARELLA=y
+
+#
+# HID Sensor RTC drivers
+#
+CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+# CONFIG_DW_DMAC is not set
+# CONFIG_TIMB_DMA is not set
+CONFIG_AMBARELLA_DMA=y
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_VIRT_DRIVERS is not set
+
+#
+# Virtio drivers
+#
+# CONFIG_VIRTIO_MMIO is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+# CONFIG_STAGING is not set
+
+#
+# Hardware Spinlock drivers
+#
+# CONFIG_MAILBOX is not set
+# CONFIG_IOMMU_SUPPORT is not set
+
+#
+# Remoteproc drivers
+#
+# CONFIG_STE_MODEM_RPROC is not set
+
+#
+# Rpmsg drivers
+#
+# CONFIG_PM_DEVFREQ is not set
+# CONFIG_EXTCON is not set
+# CONFIG_MEMORY is not set
+# CONFIG_IIO is not set
+# CONFIG_PWM is not set
+CONFIG_AMBARELLA_VIC=y
+CONFIG_AMBARELLA_GVIC=y
+# CONFIG_IPACK_BUS is not set
+# CONFIG_RESET_CONTROLLER is not set
+
+#
+# File systems
+#
+CONFIG_DCACHE_WORD_ACCESS=y
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_USE_FOR_EXT23=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_EXPORTFS=m
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_FANOTIFY=y
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_TMPFS_XATTR=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX6FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_PSTORE is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_F2FS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V2=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_SWAP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_DEBUG is not set
+# CONFIG_CEPH_FS is not set
+CONFIG_CIFS=y
+CONFIG_CIFS_STATS=y
+# CONFIG_CIFS_STATS2 is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+CONFIG_CIFS_DEBUG=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_SMB2 is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_MAC_ROMAN is not set
+# CONFIG_NLS_MAC_CELTIC is not set
+# CONFIG_NLS_MAC_CENTEURO is not set
+# CONFIG_NLS_MAC_CROATIAN is not set
+# CONFIG_NLS_MAC_CYRILLIC is not set
+# CONFIG_NLS_MAC_GAELIC is not set
+# CONFIG_NLS_MAC_GREEK is not set
+# CONFIG_NLS_MAC_ICELAND is not set
+# CONFIG_NLS_MAC_INUIT is not set
+# CONFIG_NLS_MAC_ROMANIAN is not set
+# CONFIG_NLS_MAC_TURKISH is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_PANIC_ON_OOPS is not set
+CONFIG_PANIC_ON_OOPS_VALUE=0
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+
+#
+# RCU Debugging
+#
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_LKDTM is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+CONFIG_DYNAMIC_DEBUG=y
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_TEST_STRING_HELPERS is not set
+# CONFIG_TEST_KSTRTOX is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
+CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"
+# CONFIG_PID_IN_CONTEXTIDR is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_USER is not set
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_CMAC is not set
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_CRC32 is not set
+# CONFIG_CRYPTO_GHASH is not set
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA1_ARM is not set
+CONFIG_CRYPTO_SHA256=y
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_AES_ARM is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=y
+# CONFIG_CRYPTO_USER_API_HASH is not set
+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_IO=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC32_SELFTEST is not set
+CONFIG_CRC32_SLICEBY8=y
+# CONFIG_CRC32_SLICEBY4 is not set
+# CONFIG_CRC32_SARWATE is not set
+# CONFIG_CRC32_BIT is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+# CONFIG_CRC8 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_XZ_DEC=y
+CONFIG_XZ_DEC_X86=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_SPARC=y
+CONFIG_XZ_DEC_BCJ=y
+# CONFIG_XZ_DEC_TEST is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_XZ=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_BCH=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_DQL=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+CONFIG_AVERAGE=y
+# CONFIG_CORDIC is not set
+# CONFIG_DDR is not set
+# CONFIG_VIRTUALIZATION is not set
diff --git a/arch/arm/configs/ambarella_a8_ramfs_ca9_a_defconfig b/arch/arm/configs/ambarella_a8_ramfs_ca9_a_defconfig
new file mode 100644
index 00000000..d759e609
--- /dev/null
+++ b/arch/arm/configs/ambarella_a8_ramfs_ca9_a_defconfig
@@ -0,0 +1,157 @@
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="/home/tjlee/git_repo/ambarella/a8/boss_sdk/output/ramfs_ca9_a/images/rootfs.cpio"
+CONFIG_INITRAMFS_COMPRESSION_GZIP=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_PROFILING=y
+CONFIG_JUMP_LABEL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_AMBARELLA=y
+CONFIG_PLAT_AMBARELLA_A8_CORTEX=y
+CONFIG_AMBARELLA_RAW_BOOT=y
+CONFIG_AMBARELLA_PMUSERENR_EN=y
+CONFIG_AMBARELLA_PLL_PROC=y
+CONFIG_AMBARELLA_PPM_SIZE=0x60000000
+CONFIG_AMBARELLA_MEMORY_SIZE=0x06000000
+CONFIG_AMBARELLA_ZRELADDR=0x10008000
+CONFIG_AMBARELLA_TEXTOFS=0x00008000
+CONFIG_AMBARELLA_PARAMS_PHYS=0x10001000
+CONFIG_AMBARELLA_INITRD_PHYS=0x10800000
+CONFIG_AMBARELLA_TIMER_HZ=1000
+CONFIG_AMBARELLA_TIMER_HIGHRES=y
+CONFIG_MACH_HYACINTH_0=y
+CONFIG_ARM_THUMBEE=y
+# CONFIG_SWP_EMULATE is not set
+CONFIG_ARM_ERRATA_751472=y
+CONFIG_SMP=y
+CONFIG_SCHED_MC=y
+CONFIG_VMSPLIT_1G=y
+CONFIG_NR_CPUS=2
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_CLEANCACHE=y
+CONFIG_FRONTSWAP=y
+CONFIG_UACCESS_WITH_MEMCPY=y
+CONFIG_CMDLINE="console=ttyS2"
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_NET_IPIP=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_ARPD=y
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+CONFIG_BRIDGE=y
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/mdev"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+# CONFIG_BLK_DEV is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_VENDOR_AMBARELLA=y
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_AMBARELLA=y
+CONFIG_SERIAL_AMBARELLA_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_VIDEO_ADV_DEBUG=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_V4L_TEST_DRIVERS=y
+# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
+# CONFIG_HID is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_RPROC_CA9_A=y
+CONFIG_RPMSG_AMBXC=y
+CONFIG_RPMSG_RSH=y
+CONFIG_RPMSG_VETH=y
+CONFIG_RPMSG_VGPIO=y
+CONFIG_FANOTIFY=y
+CONFIG_FSCACHE=y
+CONFIG_FSCACHE_STATS=y
+CONFIG_FSCACHE_HISTOGRAM=y
+CONFIG_CACHEFILES=y
+CONFIG_CACHEFILES_HISTOGRAM=y
+CONFIG_TMPFS=y
+CONFIG_CONFIGFS_FS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_FS=y
+# CONFIG_RCU_CPU_STALL_VERBOSE is not set
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_USER=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_LZO=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
diff --git a/arch/arm/configs/ambarella_a8_ramfs_ca9_b_defconfig b/arch/arm/configs/ambarella_a8_ramfs_ca9_b_defconfig
new file mode 100644
index 00000000..0cfd413c
--- /dev/null
+++ b/arch/arm/configs/ambarella_a8_ramfs_ca9_b_defconfig
@@ -0,0 +1,147 @@
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="/home/tjlee/git_repo/ambarella/a8/boss_sdk/output/ramfs_ca9_b/images/rootfs.cpio"
+CONFIG_INITRAMFS_COMPRESSION_GZIP=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_PROFILING=y
+CONFIG_JUMP_LABEL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_AMBARELLA=y
+CONFIG_PLAT_AMBARELLA_A8_CORTEX=y
+CONFIG_AMBARELLA_RAW_BOOT=y
+CONFIG_AMBARELLA_PMUSERENR_EN=y
+CONFIG_AMBARELLA_PLL_PROC=y
+CONFIG_AMBARELLA_PPM_SIZE=0x60000000
+CONFIG_AMBARELLA_MEMORY_SIZE=0x06000000
+CONFIG_AMBARELLA_ZRELADDR=0x10008000
+CONFIG_AMBARELLA_TEXTOFS=0x00008000
+CONFIG_AMBARELLA_PARAMS_PHYS=0x10001000
+CONFIG_AMBARELLA_INITRD_PHYS=0x10800000
+CONFIG_AMBARELLA_TIMER_HZ=1000
+CONFIG_AMBARELLA_TIMER_HIGHRES=y
+CONFIG_MACH_HYACINTH_1=y
+CONFIG_ARM_THUMBEE=y
+# CONFIG_SWP_EMULATE is not set
+CONFIG_ARM_ERRATA_751472=y
+CONFIG_SMP=y
+CONFIG_SCHED_MC=y
+CONFIG_VMSPLIT_1G=y
+CONFIG_NR_CPUS=2
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_CLEANCACHE=y
+CONFIG_FRONTSWAP=y
+CONFIG_UACCESS_WITH_MEMCPY=y
+CONFIG_CMDLINE="console=ttyS2"
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_NET_IPIP=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_ARPD=y
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+CONFIG_DNS_RESOLVER=y
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/mdev"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+# CONFIG_BLK_DEV is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_AMBARELLA=y
+CONFIG_SERIAL_AMBARELLA_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+# CONFIG_HID is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_RPROC_CA9_B=y
+CONFIG_RPCLNT_CA9_B=y
+CONFIG_RPMSG_VGPIO=y
+CONFIG_RPDEV_RSH=y
+CONFIG_RPDEV_VETH=y
+CONFIG_FANOTIFY=y
+CONFIG_FSCACHE=y
+CONFIG_FSCACHE_STATS=y
+CONFIG_FSCACHE_HISTOGRAM=y
+CONFIG_CACHEFILES=y
+CONFIG_CACHEFILES_HISTOGRAM=y
+CONFIG_TMPFS=y
+CONFIG_CONFIGFS_FS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_FS=y
+# CONFIG_RCU_CPU_STALL_VERBOSE is not set
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_USER=y
+CONFIG_KEYS=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_LZO=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
diff --git a/arch/arm/configs/ambarella_s2_arm11_defconfig b/arch/arm/configs/ambarella_s2_arm11_defconfig
new file mode 100644
index 00000000..7ba8aa83
--- /dev/null
+++ b/arch/arm/configs/ambarella_s2_arm11_defconfig
@@ -0,0 +1,2384 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/arm 3.10.0 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_NEED_MACH_GPIO_H=y
+CONFIG_NEED_MACH_IO_H=y
+CONFIG_NEED_MACH_MEMORY_H=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_IRQ_WORK=y
+CONFIG_BUILDTIME_EXTABLE_SORT=y
+
+#
+# General setup
+#
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_XZ is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_DEFAULT_HOSTNAME="Ambarella"
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_FHANDLE is not set
+# CONFIG_AUDIT is not set
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_IRQ_DOMAIN=y
+# CONFIG_IRQ_DOMAIN_DEBUG is not set
+CONFIG_KTIME_SCALAR=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# Timers subsystem
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ_COMMON=y
+# CONFIG_HZ_PERIODIC is not set
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+
+#
+# CPU/Task time and stats accounting
+#
+CONFIG_TICK_CPU_ACCOUNTING=y
+# CONFIG_IRQ_TIME_ACCOUNTING is not set
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_TREE_PREEMPT_RCU is not set
+CONFIG_TINY_PREEMPT_RCU=y
+CONFIG_PREEMPT_RCU=y
+# CONFIG_RCU_STALL_COMMON is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_RCU_BOOST is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_CGROUPS is not set
+# CONFIG_CHECKPOINT_RESTORE is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+CONFIG_UIDGID_CONVERTED=y
+# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_XZ=y
+CONFIG_RD_LZO=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_HAVE_UID16=y
+CONFIG_HOTPLUG=y
+# CONFIG_EXPERT is not set
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+# CONFIG_EMBEDDED is not set
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_JUMP_LABEL is not set
+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_OLD_SIGACTION=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_MODULE_SIG is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_BSGLIB is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_AMBPTB_PARTITION=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y
+CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_LOCK=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y
+CONFIG_ARCH_INLINE_READ_TRYLOCK=y
+CONFIG_ARCH_INLINE_READ_LOCK=y
+CONFIG_ARCH_INLINE_READ_LOCK_BH=y
+CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_READ_UNLOCK=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y
+CONFIG_ARCH_INLINE_WRITE_TRYLOCK=y
+CONFIG_ARCH_INLINE_WRITE_LOCK=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_SPIN_TRYLOCK=y
+CONFIG_INLINE_SPIN_TRYLOCK_BH=y
+CONFIG_INLINE_SPIN_LOCK=y
+CONFIG_INLINE_SPIN_LOCK_BH=y
+CONFIG_INLINE_SPIN_LOCK_IRQ=y
+CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y
+CONFIG_INLINE_SPIN_UNLOCK_BH=y
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_READ_TRYLOCK=y
+CONFIG_INLINE_READ_LOCK=y
+CONFIG_INLINE_READ_LOCK_BH=y
+CONFIG_INLINE_READ_LOCK_IRQ=y
+CONFIG_INLINE_READ_LOCK_IRQSAVE=y
+CONFIG_INLINE_READ_UNLOCK=y
+CONFIG_INLINE_READ_UNLOCK_BH=y
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_WRITE_TRYLOCK=y
+CONFIG_INLINE_WRITE_LOCK=y
+CONFIG_INLINE_WRITE_LOCK_BH=y
+CONFIG_INLINE_WRITE_LOCK_IRQ=y
+CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y
+CONFIG_INLINE_WRITE_UNLOCK=y
+CONFIG_INLINE_WRITE_UNLOCK_BH=y
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_MULTIPLATFORM is not set
+CONFIG_ARCH_AMBARELLA=y
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_LPC32XX is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C24XX is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P64X0 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_EXYNOS is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP1 is not set
+CONFIG_PLAT_AMBARELLA=y
+
+#
+# Ambarella Platform
+#
+CONFIG_PLAT_AMBARELLA_SUPPORT_VIC=y
+CONFIG_PLAT_AMBARELLA_HAVE_ARM11=y
+# CONFIG_PLAT_AMBARELLA_CORTEX is not set
+# CONFIG_PLAT_AMBARELLA_MEM_START_LOW is not set
+# CONFIG_PLAT_AMBARELLA_AHB_APB_HIGH is not set
+CONFIG_PLAT_AMBARELLA_SUPPORT_HW_CRYPTO=y
+# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_CRYPT is not set
+CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64=y
+# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS is not set
+# CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_RPROC is not set
+CONFIG_PLAT_AMBARELLA_S2=y
+# CONFIG_PLAT_AMBARELLA_A8 is not set
+# CONFIG_PLAT_AMBARELLA_A5S is not set
+# CONFIG_PLAT_AMBARELLA_A7L is not set
+CONFIG_PLAT_AMBARELLA_S2_ARM11=y
+# CONFIG_PLAT_AMBARELLA_S2_CORTEX is not set
+# CONFIG_PLAT_AMBARELLA_A8_ARM11 is not set
+# CONFIG_PLAT_AMBARELLA_A8_CORTEX is not set
+# CONFIG_PLAT_AMBARELLA_S2L is not set
+
+#
+# Generic Platform Configuration
+#
+# CONFIG_AMBARELLA_RAW_BOOT is not set
+CONFIG_AMBARELLA_SUPPORT_BAPI=y
+# CONFIG_AMBARELLA_PMUSERENR_EN is not set
+
+#
+# Sys file system support
+#
+# CONFIG_AMBARELLA_SYS_CACHE_CALL is not set
+# CONFIG_AMBARELLA_SYS_BAPI_CALL is not set
+
+#
+# Proc file system support
+#
+CONFIG_AMBARELLA_PLL_PROC=y
+# CONFIG_AMBARELLA_SUPPORT_AMBENCH is not set
+
+#
+# Memory Configuration
+#
+CONFIG_AMBARELLA_PPM_SIZE=0x10000000
+CONFIG_AMBARELLA_ZRELADDR=0xD0008000
+CONFIG_AMBARELLA_TEXTOFS=0x00008000
+CONFIG_AMBARELLA_PARAMS_PHYS=0xD0200000
+CONFIG_AMBARELLA_INITRD_PHYS=0xD0A00000
+# CONFIG_AMBARELLA_IO_MAP is not set
+# CONFIG_AMBARELLA_PPM_UNCACHED is not set
+
+#
+# FIO Configuration
+#
+# CONFIG_AMBARELLA_FIO_FORCE_SDIO_GPIO is not set
+CONFIG_AMBARELLA_TIMER_HZ=100
+CONFIG_AMBARELLA_TIMER_HIGHRES=y
+CONFIG_AMBARELLA_EXT_IRQ_NUM=64
+CONFIG_AMBARELLA_EXT_GPIO_NUM=64
+
+#
+# Ambarella Board
+#
+CONFIG_MACH_AMBARELLA=y
+CONFIG_MACH_GINKGO=y
+
+#
+# Misc on Board Devices
+#
+
+#
+# Ambarella
+#
+CONFIG_AMBARELLA_VOUT=y
+
+#
+# Touch
+#
+# CONFIG_TOUCH_AMBARELLA_AK4183 is not set
+# CONFIG_TOUCH_AMBARELLA_CHACHA_MT4D is not set
+# CONFIG_TOUCH_AMBARELLA_TM1510 is not set
+# CONFIG_TOUCH_AMBARELLA_TM1726 is not set
+# CONFIG_TOUCH_AMBARELLA_TM1927 is not set
+# CONFIG_TOUCH_AMBARELLA_FT540 is not set
+# CONFIG_TOUCH_AMBARELLA_NT11001 is not set
+
+#
+# LCD
+#
+
+#
+# RTC
+#
+
+#
+# Audio Codec
+#
+# CONFIG_CODEC_AMBARELLA_WM8737 is not set
+# CONFIG_CODEC_AMBARELLA_WM8994 is not set
+# CONFIG_CODEC_AMBARELLA_ES8328 is not set
+CONFIG_CODEC_AMBARELLA_AK4642=y
+
+#
+# PMIC
+#
+# CONFIG_PMIC_AMBARELLA_WM831X is not set
+
+#
+# cpufreq-dev
+#
+# CONFIG_CPUFREQ_AMBARELLA_DEVICE is not set
+CONFIG_GPIO_PCA953X=y
+# CONFIG_PLAT_SPEAR is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_V6=y
+CONFIG_CPU_32v6=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_ABRT_EV6=y
+CONFIG_CPU_PABRT_V6=y
+CONFIG_CPU_CACHE_V6=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V6=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+CONFIG_CPU_USE_DOMAINS=y
+
+#
+# Processor Features
+#
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+# CONFIG_CACHE_L2X0 is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_NR_BANKS=8
+CONFIG_MULTI_IRQ_HANDLER=y
+# CONFIG_ARM_ERRATA_326103 is not set
+# CONFIG_ARM_ERRATA_411920 is not set
+# CONFIG_ARM_ERRATA_364296 is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_VMSPLIT_3G is not set
+CONFIG_VMSPLIT_2G=y
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_ARCH_NR_GPIO=0
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_COUNT=y
+CONFIG_HZ=100
+CONFIG_SCHED_HRTICK=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=y
+# CONFIG_HIGHMEM is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_COMPACTION is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_CROSS_MEMORY_ATTACH is not set
+CONFIG_NEED_PER_CPU_KM=y
+# CONFIG_CLEANCACHE is not set
+# CONFIG_FRONTSWAP is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+# CONFIG_SECCOMP is not set
+CONFIG_CC_STACKPROTECTOR=y
+
+#
+# Boot options
+#
+# CONFIG_USE_OF is not set
+CONFIG_ATAGS=y
+# CONFIG_DEPRECATED_PARAM_STRUCT is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="console=ttyS0"
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
+# CONFIG_CMDLINE_EXTEND is not set
+# CONFIG_CMDLINE_FORCE is not set
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_AUTO_ZRELADDR is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_SCRIPT=y
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_COREDUMP=y
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
+CONFIG_PM_SLEEP=y
+# CONFIG_PM_AUTOSLEEP is not set
+# CONFIG_PM_WAKELOCKS is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_CLK=y
+CONFIG_CPU_PM=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_DIAG is not set
+CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=y
+CONFIG_XFRM=y
+CONFIG_XFRM_ALGO=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=y
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+# CONFIG_IP_FIB_TRIE_STATS is not set
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
+# CONFIG_NET_IP_TUNNEL is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_NET_IPVTI is not set
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+CONFIG_INET_UDP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+CONFIG_STP=y
+CONFIG_BRIDGE=y
+CONFIG_BRIDGE_IGMP_SNOOPING=y
+CONFIG_HAVE_NET_DSA=y
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_OPENVSWITCH is not set
+# CONFIG_VSOCKETS is not set
+# CONFIG_NETLINK_MMAP is not set
+# CONFIG_NETLINK_DIAG is not set
+CONFIG_BQL=y
+# CONFIG_BPF_JIT is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+# CONFIG_BT_HIDP is not set
+
+#
+# Bluetooth device drivers
+#
+# CONFIG_BT_HCIBTUSB is not set
+# CONFIG_BT_HCIBTSDIO is not set
+# CONFIG_BT_HCIUART is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_BT_MRVL is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_CFG80211=y
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+CONFIG_CFG80211_DEBUGFS=y
+# CONFIG_CFG80211_INTERNAL_REGDB is not set
+CONFIG_CFG80211_WEXT=y
+# CONFIG_LIB80211 is not set
+CONFIG_MAC80211=y
+CONFIG_MAC80211_HAS_RC=y
+CONFIG_MAC80211_RC_MINSTREL=y
+CONFIG_MAC80211_RC_MINSTREL_HT=y
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
+# CONFIG_MAC80211_MESH is not set
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_MESSAGE_TRACING is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
+CONFIG_RFKILL=y
+CONFIG_RFKILL_INPUT=y
+# CONFIG_RFKILL_GPIO is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+# CONFIG_NFC is not set
+CONFIG_HAVE_BPF_JIT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+CONFIG_FW_LOADER_USER_HELPER=y
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_GENERIC_CPU_DEVICES is not set
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=m
+CONFIG_REGMAP_SPI=m
+# CONFIG_DMA_SHARED_BUFFER is not set
+# CONFIG_CMA is not set
+
+#
+# Bus devices
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+# CONFIG_MTD_SWAP is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOCG3 is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_BCH=y
+CONFIG_MTD_NAND_ECC_BCH=y
+# CONFIG_MTD_SM_COMMON is not set
+CONFIG_MTD_NAND_AMBARELLA=y
+# CONFIG_MTD_NAND_DENALI is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_DOCG4 is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_LIMIT=20
+# CONFIG_MTD_UBI_FASTMAP is not set
+# CONFIG_MTD_UBI_GLUEBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_BLK_DEV_XIP=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_BLK_DEV_RBD is not set
+
+#
+# Misc devices
+#
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ATMEL_PWM is not set
+# CONFIG_DUMMY_IRQ is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ATMEL_SSC is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_APDS9802ALS is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_ISL29020 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_BH1780 is not set
+# CONFIG_SENSORS_BH1770 is not set
+# CONFIG_SENSORS_APDS990X is not set
+# CONFIG_HMC6352 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_BMP085_I2C is not set
+# CONFIG_BMP085_SPI is not set
+# CONFIG_USB_SWITCH_FSA9480 is not set
+# CONFIG_LATTICE_ECP3_CONFIG is not set
+# CONFIG_SRAM is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_EEPROM_93XX46 is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_TI_ST is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+
+#
+# Altera FPGA firmware download module
+#
+# CONFIG_ALTERA_STAPL is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=m
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_ISCSI_BOOT_SYSFS is not set
+# CONFIG_SCSI_UFSHCD is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_TARGET_CORE is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_CORE=y
+# CONFIG_BONDING is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_MII=y
+# CONFIG_NET_TEAM is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_VXLAN is not set
+CONFIG_NETCONSOLE=y
+CONFIG_NETCONSOLE_DYNAMIC=y
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+
+#
+# CAIF transport drivers
+#
+
+#
+# Distributed Switch Architecture drivers
+#
+# CONFIG_NET_DSA_MV88E6XXX is not set
+# CONFIG_NET_DSA_MV88E6060 is not set
+# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
+# CONFIG_NET_DSA_MV88E6131 is not set
+# CONFIG_NET_DSA_MV88E6123_61_65 is not set
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_AMBARELLA=m
+# CONFIG_NET_VENDOR_AMBARELLA_INTEN_TUE is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_CALXEDA_XGMAC is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_DM9000 is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_ETHOC is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+# CONFIG_AT803X_PHY is not set
+# CONFIG_AMD_PHY is not set
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_BCM87XX_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+# CONFIG_MICREL_KS8995MA is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_RTL8152 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_HSO is not set
+# CONFIG_USB_IPHETH is not set
+CONFIG_WLAN=y
+# CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_AT76C50X_USB is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_RTL8187 is not set
+# CONFIG_MAC80211_HWSIM is not set
+# CONFIG_ATH_CARDS is not set
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_BRCMFMAC is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_P54_COMMON is not set
+# CONFIG_RT2X00 is not set
+# CONFIG_RTLWIFI is not set
+# CONFIG_WL_TI is not set
+# CONFIG_ZD1211RW is not set
+# CONFIG_MWIFIEX is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+# CONFIG_INPUT_MATRIXKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_BMA150 is not set
+CONFIG_INPUT_AMBARELLA=m
+CONFIG_INPUT_AMBARELLA_IR=y
+CONFIG_INPUT_AMBARELLA_ADC=y
+# CONFIG_INPUT_MMA8450 is not set
+# CONFIG_INPUT_MPU3050 is not set
+# CONFIG_INPUT_GP2A is not set
+# CONFIG_INPUT_GPIO_TILT_POLLED is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_KXTJ9 is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+CONFIG_INPUT_UINPUT=m
+# CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_PWM_BEEPER is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_CMA3000 is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_TTY=y
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_CONSOLE_SLEEP=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+# CONFIG_DEVKMEM is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AMBARELLA=y
+CONFIG_SERIAL_AMBARELLA_CONSOLE=y
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX310X is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_SCCNXP is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_IFX6X60 is not set
+# CONFIG_SERIAL_ARC is not set
+# CONFIG_HVC_DCC is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=m
+# CONFIG_I2C_MUX is not set
+# CONFIG_I2C_HELPER_AUTO is not set
+# CONFIG_I2C_SMBUS is not set
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_AMBARELLA=y
+# CONFIG_I2C_CBUS_GPIO is not set
+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_DIOLAN_U2C is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_SLAVE=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+CONFIG_SPI_AMBARELLA=y
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_SC18IS602 is not set
+# CONFIG_SPI_XCOMM is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=m
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# SPI Slave Controller Drivers
+#
+# CONFIG_SPI_SLAVE_AMBARELLA is not set
+
+#
+# Qualcomm MSM SSBI bus support
+#
+# CONFIG_SSBI is not set
+# CONFIG_HSI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+# CONFIG_PTP_1588_CLOCK is not set
+
+#
+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
+#
+# CONFIG_PTP_1588_CLOCK_PCH is not set
+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIO_DEVRES=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_GENERIC_PLATFORM is not set
+# CONFIG_GPIO_EM is not set
+# CONFIG_GPIO_RCAR is not set
+# CONFIG_GPIO_TS5500 is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+CONFIG_GPIO_PCA953X_IRQ=y
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_SX150X is not set
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+# CONFIG_GPIO_74X164 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+
+#
+# USB GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_POWER_AVS is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_CORE is not set
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AMBARELLA_WATCHDOG=y
+# CONFIG_DW_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_AS3711 is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_AAT2870_CORE is not set
+# CONFIG_MFD_CROS_EC is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_DA9052_SPI is not set
+# CONFIG_MFD_DA9052_I2C is not set
+# CONFIG_MFD_DA9055 is not set
+# CONFIG_MFD_MC13XXX_SPI is not set
+# CONFIG_MFD_MC13XXX_I2C is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_MFD_88PM800 is not set
+# CONFIG_MFD_88PM805 is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_MAX77686 is not set
+# CONFIG_MFD_MAX77693 is not set
+# CONFIG_MFD_MAX8907 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_MAX8997 is not set
+# CONFIG_MFD_MAX8998 is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_VIPERBOARD is not set
+# CONFIG_MFD_RETU is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_RC5T583 is not set
+# CONFIG_MFD_SEC_CORE is not set
+# CONFIG_MFD_SI476X_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SMSC is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_MFD_STMPE is not set
+# CONFIG_MFD_SYSCON is not set
+# CONFIG_MFD_TI_AM335X_TSCADC is not set
+# CONFIG_MFD_LP8788 is not set
+# CONFIG_MFD_PALMAS is not set
+# CONFIG_TPS6105X is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_MFD_TPS65090 is not set
+# CONFIG_MFD_TPS65217 is not set
+# CONFIG_MFD_TPS6586X is not set
+# CONFIG_MFD_TPS65910 is not set
+# CONFIG_MFD_TPS65912 is not set
+# CONFIG_MFD_TPS65912_I2C is not set
+# CONFIG_MFD_TPS65912_SPI is not set
+# CONFIG_MFD_TPS80031 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_TWL6040_CORE is not set
+# CONFIG_MFD_WL1273_CORE is not set
+# CONFIG_MFD_LM3533 is not set
+# CONFIG_MFD_TC3589X is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_MFD_ARIZONA_I2C is not set
+# CONFIG_MFD_ARIZONA_SPI is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X_I2C is not set
+# CONFIG_MFD_WM831X_SPI is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+CONFIG_FB_SYS_FILLRECT=y
+CONFIG_FB_SYS_COPYAREA=y
+CONFIG_FB_SYS_IMAGEBLIT=y
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+CONFIG_FB_SYS_FOPS=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_SMSCUFX is not set
+# CONFIG_FB_UDL is not set
+# CONFIG_FB_GOLDFISH is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+CONFIG_FB_AMBARELLA=y
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_FB_AUO_K190X is not set
+# CONFIG_EXYNOS_VIDEO is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+# CONFIG_BACKLIGHT_GENERIC is not set
+# CONFIG_BACKLIGHT_ADP8860 is not set
+# CONFIG_BACKLIGHT_ADP8870 is not set
+# CONFIG_BACKLIGHT_LM3630 is not set
+# CONFIG_BACKLIGHT_LM3639 is not set
+# CONFIG_BACKLIGHT_LP855X is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=m
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+# CONFIG_LOGO is not set
+CONFIG_SOUND=m
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_COMPRESS_OFFLOAD=m
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
+# CONFIG_SND_USB_CAIAQ is not set
+# CONFIG_SND_USB_6FIRE is not set
+CONFIG_SND_SOC=m
+CONFIG_SND_AMBARELLA_SOC=m
+CONFIG_SND_AMBARELLA_SOC_I2S=m
+CONFIG_SND_AMBARELLA_BOARD=m
+CONFIG_AMBEVK_BOARD=m
+CONFIG_AMBARELLA_DUMMY_BOARD=m
+# CONFIG_SND_ATMEL_SOC is not set
+CONFIG_SND_SOC_I2C_AND_SPI=m
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_AMBARELLA_DUMMY=m
+CONFIG_SND_SOC_AK4642_AMB=m
+# CONFIG_SND_SIMPLE_CARD is not set
+# CONFIG_SOUND_PRIME is not set
+
+#
+# HID support
+#
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+# CONFIG_UHID is not set
+CONFIG_HID_GENERIC=y
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=y
+# CONFIG_HID_ACRUX is not set
+CONFIG_HID_APPLE=y
+# CONFIG_HID_APPLEIR is not set
+# CONFIG_HID_AUREAL is not set
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+# CONFIG_HID_PRODIKEYS is not set
+CONFIG_HID_CYPRESS=y
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_ELECOM is not set
+CONFIG_HID_EZKEY=y
+# CONFIG_HID_HOLTEK is not set
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_ICADE is not set
+# CONFIG_HID_TWINHAN is not set
+CONFIG_HID_KENSINGTON=y
+# CONFIG_HID_LCPOWER is not set
+# CONFIG_HID_LENOVO_TPKBD is not set
+CONFIG_HID_LOGITECH=y
+# CONFIG_HID_LOGITECH_DJ is not set
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
+# CONFIG_LOGIWHEELS_FF is not set
+# CONFIG_HID_MAGICMOUSE is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_PRIMAX is not set
+# CONFIG_HID_PS3REMOTE is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_SAITEK is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SPEEDLINK is not set
+# CONFIG_HID_STEELSERIES is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TIVO is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+# CONFIG_HID_SENSOR_HUB is not set
+
+#
+# USB HID support
+#
+CONFIG_USB_HID=m
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# I2C HID support
+#
+# CONFIG_I2C_HID is not set
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB_ARCH_HAS_XHCI is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_COMMON=m
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEFAULT_PERSIST=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_EHCI_AMBARELLA=y
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_OHCI_AMBARELLA=y
+# CONFIG_USB_OHCI_HCD_PLATFORM is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_RENESAS_USBHS is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_REALTEK is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_STORAGE_ENE_UB6250 is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_DWC3 is not set
+# CONFIG_USB_CHIPIDEA is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP210X is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_F81232 is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_METRO is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QCAUX is not set
+# CONFIG_USB_SERIAL_QUALCOMM is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_SYMBOL is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
+# CONFIG_USB_SERIAL_XSENS_MT is not set
+# CONFIG_USB_SERIAL_ZIO is not set
+# CONFIG_USB_SERIAL_WISHBONE is not set
+# CONFIG_USB_SERIAL_ZTE is not set
+# CONFIG_USB_SERIAL_SSU100 is not set
+# CONFIG_USB_SERIAL_QT2 is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_YUREX is not set
+# CONFIG_USB_EZUSB_FX2 is not set
+# CONFIG_USB_HSIC_USB3503 is not set
+# CONFIG_USB_PHY is not set
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
+
+#
+# USB Peripheral Controller
+#
+# CONFIG_USB_FUSB300 is not set
+# CONFIG_USB_R8A66597 is not set
+# CONFIG_USB_PXA27X is not set
+# CONFIG_USB_MV_UDC is not set
+# CONFIG_USB_MV_U3D is not set
+# CONFIG_USB_M66592 is not set
+# CONFIG_USB_NET2272 is not set
+CONFIG_USB_AMBARELLA=m
+# CONFIG_USB_DUMMY_HCD is not set
+CONFIG_USB_LIBCOMPOSITE=m
+CONFIG_USB_F_ACM=m
+CONFIG_USB_U_SERIAL=m
+CONFIG_USB_F_SERIAL=m
+CONFIG_USB_F_OBEX=m
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
+# CONFIG_USB_G_NCM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FUNCTIONFS is not set
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_ACM_MS is not set
+# CONFIG_USB_G_MULTI is not set
+# CONFIG_USB_G_HID is not set
+# CONFIG_USB_G_DBGP is not set
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+# CONFIG_MMC_CLKGATE is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_BLOCK_MINORS=32
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+# CONFIG_SDIO_UART is not set
+CONFIG_MMC_TEST=m
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_AMBARELLA=m
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MMC_DW is not set
+# CONFIG_MMC_VUB300 is not set
+# CONFIG_MMC_USHC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_EDAC is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_SYSTOHC=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS3232 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+CONFIG_RTC_DRV_ISL12022=y
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8523 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+# CONFIG_RTC_DRV_EM3027 is not set
+# CONFIG_RTC_DRV_RV3029C2 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T93 is not set
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+# CONFIG_RTC_DRV_RX4581 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+# CONFIG_RTC_DRV_DS2404 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_AMBARELLA=y
+
+#
+# HID Sensor RTC drivers
+#
+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
+CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+# CONFIG_DW_DMAC is not set
+# CONFIG_TIMB_DMA is not set
+CONFIG_AMBARELLA_DMA=y
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_VIRT_DRIVERS is not set
+
+#
+# Virtio drivers
+#
+# CONFIG_VIRTIO_MMIO is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+# CONFIG_STAGING is not set
+
+#
+# Hardware Spinlock drivers
+#
+# CONFIG_MAILBOX is not set
+# CONFIG_IOMMU_SUPPORT is not set
+
+#
+# Remoteproc drivers
+#
+# CONFIG_STE_MODEM_RPROC is not set
+
+#
+# Rpmsg drivers
+#
+# CONFIG_PM_DEVFREQ is not set
+# CONFIG_EXTCON is not set
+# CONFIG_MEMORY is not set
+# CONFIG_IIO is not set
+# CONFIG_PWM is not set
+CONFIG_AMBARELLA_VIC=y
+CONFIG_AMBARELLA_GVIC=y
+# CONFIG_IPACK_BUS is not set
+# CONFIG_RESET_CONTROLLER is not set
+
+#
+# File systems
+#
+CONFIG_DCACHE_WORD_ACCESS=y
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_USE_FOR_EXT23=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_EXPORTFS=m
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_FANOTIFY=y
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_TMPFS_XATTR=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX6FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_PSTORE is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_F2FS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V2=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_SWAP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_DEBUG is not set
+# CONFIG_CEPH_FS is not set
+CONFIG_CIFS=y
+CONFIG_CIFS_STATS=y
+# CONFIG_CIFS_STATS2 is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+CONFIG_CIFS_DEBUG=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_SMB2 is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_MAC_ROMAN is not set
+# CONFIG_NLS_MAC_CELTIC is not set
+# CONFIG_NLS_MAC_CENTEURO is not set
+# CONFIG_NLS_MAC_CROATIAN is not set
+# CONFIG_NLS_MAC_CYRILLIC is not set
+# CONFIG_NLS_MAC_GAELIC is not set
+# CONFIG_NLS_MAC_GREEK is not set
+# CONFIG_NLS_MAC_ICELAND is not set
+# CONFIG_NLS_MAC_INUIT is not set
+# CONFIG_NLS_MAC_ROMANIAN is not set
+# CONFIG_NLS_MAC_TURKISH is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_PANIC_ON_OOPS is not set
+CONFIG_PANIC_ON_OOPS_VALUE=0
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+
+#
+# RCU Debugging
+#
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_LKDTM is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+CONFIG_DYNAMIC_DEBUG=y
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_TEST_STRING_HELPERS is not set
+# CONFIG_TEST_KSTRTOX is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
+CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"
+# CONFIG_PID_IN_CONTEXTIDR is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_USER is not set
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_CMAC is not set
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_CRC32 is not set
+# CONFIG_CRYPTO_GHASH is not set
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA1_ARM is not set
+CONFIG_CRYPTO_SHA256=y
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_AES_ARM is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=y
+# CONFIG_CRYPTO_USER_API_HASH is not set
+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_DEV_AMBARELLA=m
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_IO=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC32_SELFTEST is not set
+CONFIG_CRC32_SLICEBY8=y
+# CONFIG_CRC32_SLICEBY4 is not set
+# CONFIG_CRC32_SARWATE is not set
+# CONFIG_CRC32_BIT is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+# CONFIG_CRC8 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_XZ_DEC=y
+CONFIG_XZ_DEC_X86=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_SPARC=y
+CONFIG_XZ_DEC_BCJ=y
+# CONFIG_XZ_DEC_TEST is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_XZ=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_BCH=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_DQL=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+CONFIG_AVERAGE=y
+# CONFIG_CORDIC is not set
+# CONFIG_DDR is not set
+# CONFIG_VIRTUALIZATION is not set
diff --git a/arch/arm/configs/ambarella_s2_cortex_defconfig b/arch/arm/configs/ambarella_s2_cortex_defconfig
new file mode 100644
index 00000000..1f57a220
--- /dev/null
+++ b/arch/arm/configs/ambarella_s2_cortex_defconfig
@@ -0,0 +1,2553 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/arm 3.10.73 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_NEED_MACH_GPIO_H=y
+CONFIG_NEED_MACH_IO_H=y
+CONFIG_NEED_MACH_MEMORY_H=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_IRQ_WORK=y
+CONFIG_BUILDTIME_EXTABLE_SORT=y
+
+#
+# General setup
+#
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_XZ is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_DEFAULT_HOSTNAME="Ambarella"
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_FHANDLE=y
+# CONFIG_AUDIT is not set
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_ARCH_HAS_TICK_BROADCAST=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+
+#
+# Timers subsystem
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ_COMMON=y
+# CONFIG_HZ_PERIODIC is not set
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+
+#
+# CPU/Task time and stats accounting
+#
+CONFIG_TICK_CPU_ACCOUNTING=y
+# CONFIG_IRQ_TIME_ACCOUNTING is not set
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_PREEMPT_RCU=y
+CONFIG_PREEMPT_RCU=y
+CONFIG_RCU_STALL_COMMON=y
+# CONFIG_RCU_USER_QS is not set
+CONFIG_RCU_FANOUT=32
+CONFIG_RCU_FANOUT_LEAF=16
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_RCU_BOOST is not set
+# CONFIG_RCU_NOCB_CPU is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+# CONFIG_CGROUP_FREEZER is not set
+# CONFIG_CGROUP_DEVICE is not set
+# CONFIG_CPUSETS is not set
+# CONFIG_CGROUP_CPUACCT is not set
+# CONFIG_RESOURCE_COUNTERS is not set
+CONFIG_CGROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_CFS_BANDWIDTH is not set
+# CONFIG_RT_GROUP_SCHED is not set
+# CONFIG_BLK_CGROUP is not set
+# CONFIG_CHECKPOINT_RESTORE is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_NET_NS=y
+CONFIG_UIDGID_CONVERTED=y
+# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_XZ=y
+CONFIG_RD_LZO=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_HAVE_UID16=y
+CONFIG_HOTPLUG=y
+# CONFIG_EXPERT is not set
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+# CONFIG_EMBEDDED is not set
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_JUMP_LABEL is not set
+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_OLD_SIGACTION=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_MODULE_SIG is not set
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_BSGLIB is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_AMBPTB_PARTITION=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y
+CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_LOCK=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y
+CONFIG_ARCH_INLINE_READ_TRYLOCK=y
+CONFIG_ARCH_INLINE_READ_LOCK=y
+CONFIG_ARCH_INLINE_READ_LOCK_BH=y
+CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_READ_UNLOCK=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y
+CONFIG_ARCH_INLINE_WRITE_TRYLOCK=y
+CONFIG_ARCH_INLINE_WRITE_LOCK=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_SPIN_TRYLOCK=y
+CONFIG_INLINE_SPIN_TRYLOCK_BH=y
+CONFIG_INLINE_SPIN_LOCK=y
+CONFIG_INLINE_SPIN_LOCK_BH=y
+CONFIG_INLINE_SPIN_LOCK_IRQ=y
+CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y
+CONFIG_INLINE_SPIN_UNLOCK_BH=y
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_READ_TRYLOCK=y
+CONFIG_INLINE_READ_LOCK=y
+CONFIG_INLINE_READ_LOCK_BH=y
+CONFIG_INLINE_READ_LOCK_IRQ=y
+CONFIG_INLINE_READ_LOCK_IRQSAVE=y
+CONFIG_INLINE_READ_UNLOCK=y
+CONFIG_INLINE_READ_UNLOCK_BH=y
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_WRITE_TRYLOCK=y
+CONFIG_INLINE_WRITE_LOCK=y
+CONFIG_INLINE_WRITE_LOCK_BH=y
+CONFIG_INLINE_WRITE_LOCK_IRQ=y
+CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y
+CONFIG_INLINE_WRITE_UNLOCK=y
+CONFIG_INLINE_WRITE_UNLOCK_BH=y
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y
+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_MULTIPLATFORM is not set
+CONFIG_ARCH_AMBARELLA=y
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_LPC32XX is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C24XX is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P64X0 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_EXYNOS is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP1 is not set
+CONFIG_PLAT_AMBARELLA=y
+
+#
+# Ambarella Platform
+#
+# CONFIG_PLAT_AMBARELLA_SUPPORT_VIC is not set
+CONFIG_PLAT_AMBARELLA_HAVE_ARM11=y
+CONFIG_PLAT_AMBARELLA_CORTEX=y
+CONFIG_PLAT_AMBARELLA_CORTEX_SMP=y
+# CONFIG_PLAT_AMBARELLA_LOCAL_TIMERS is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_PM is not set
+CONFIG_PLAT_AMBARELLA_MEM_START_LOW=y
+# CONFIG_PLAT_AMBARELLA_AHB_APB_HIGH is not set
+CONFIG_PLAT_AMBARELLA_SUPPORT_HW_CRYPTO=y
+CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI=y
+# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64 is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS is not set
+# CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_RPROC is not set
+CONFIG_PLAT_AMBARELLA_S2=y
+# CONFIG_PLAT_AMBARELLA_A8 is not set
+# CONFIG_PLAT_AMBARELLA_A5S is not set
+# CONFIG_PLAT_AMBARELLA_A7L is not set
+# CONFIG_PLAT_AMBARELLA_S2_ARM11 is not set
+CONFIG_PLAT_AMBARELLA_S2_CORTEX=y
+# CONFIG_PLAT_AMBARELLA_S2E is not set
+# CONFIG_PLAT_AMBARELLA_A8_ARM11 is not set
+# CONFIG_PLAT_AMBARELLA_A8_CORTEX is not set
+# CONFIG_PLAT_AMBARELLA_S2L is not set
+# CONFIG_PLAT_AMBARELLA_S3 is not set
+
+#
+# Generic Platform Configuration
+#
+# CONFIG_AMBARELLA_RAW_BOOT is not set
+# CONFIG_PLAT_AMBARELLA_LOWER_ARM_PLL is not set
+# CONFIG_AMBARELLA_SUPPORT_BAPI is not set
+# CONFIG_AMBARELLA_PMUSERENR_EN is not set
+CONFIG_PLAT_AMBARELLA_SUPPORT_GDMA=y
+
+#
+# Sys file system support
+#
+CONFIG_AMBARELLA_SYS_CACHE_CALL=y
+# CONFIG_AMBARELLA_SYS_BAPI_CALL is not set
+
+#
+# Proc file system support
+#
+CONFIG_AMBARELLA_PLL_PROC=y
+# CONFIG_AMBARELLA_SUPPORT_AMBENCH is not set
+
+#
+# Memory Configuration
+#
+CONFIG_AMBARELLA_PPM_SIZE=0x00200000
+CONFIG_AMBARELLA_ZRELADDR=0x00208000
+CONFIG_AMBARELLA_TEXTOFS=0x00008000
+CONFIG_AMBARELLA_PARAMS_PHYS=0x00200100
+CONFIG_AMBARELLA_INITRD_PHYS=0x00A00000
+# CONFIG_AMBARELLA_IO_MAP is not set
+# CONFIG_AMBARELLA_PPM_UNCACHED is not set
+CONFIG_AMBARELLA_TIMER_HZ=1000
+CONFIG_AMBARELLA_TIMER_HIGHRES=y
+CONFIG_AMBARELLA_EXT_IRQ_NUM=16
+CONFIG_AMBARELLA_EXT_GPIO_NUM=16
+CONFIG_GPIO_PCA953X=y
+# CONFIG_KEYBOARD_GPIO_POLLED is not set
+# CONFIG_PLAT_SPEAR is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_LPAE is not set
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_ARM_VIRT_EXT=y
+# CONFIG_SWP_EMULATE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_KUSER_HELPERS=y
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_CACHE_L2X0=y
+CONFIG_CACHE_PL310=y
+# CONFIG_CACHE_PL310_EARLY_BRESP is not set
+CONFIG_CACHE_PL310_PREFETCH_OFFSET=0
+# CONFIG_CACHE_PL310_FULL_LINE_OF_ZERO is not set
+# CONFIG_CACHE_PL310_DOUBLE_LINEFILL is not set
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_NR_BANKS=8
+CONFIG_MULTI_IRQ_HANDLER=y
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+# CONFIG_ARM_ERRATA_742230 is not set
+# CONFIG_ARM_ERRATA_742231 is not set
+CONFIG_PL310_ERRATA_588369=y
+# CONFIG_ARM_ERRATA_643719 is not set
+# CONFIG_ARM_ERRATA_720789 is not set
+CONFIG_PL310_ERRATA_727915=y
+# CONFIG_ARM_ERRATA_743622 is not set
+# CONFIG_ARM_ERRATA_751472 is not set
+CONFIG_PL310_ERRATA_753970=y
+CONFIG_ARM_ERRATA_754322=y
+# CONFIG_ARM_ERRATA_754327 is not set
+CONFIG_ARM_ERRATA_764369=y
+CONFIG_PL310_ERRATA_769419=y
+CONFIG_ARM_ERRATA_775420=y
+# CONFIG_ARM_ERRATA_798181 is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_HAVE_SMP=y
+CONFIG_SMP=y
+CONFIG_SMP_ON_UP=y
+CONFIG_ARM_CPU_TOPOLOGY=y
+# CONFIG_SCHED_MC is not set
+# CONFIG_SCHED_SMT is not set
+CONFIG_HAVE_ARM_SCU=y
+# CONFIG_HAVE_ARM_ARCH_TIMER is not set
+CONFIG_HAVE_ARM_TWD=y
+# CONFIG_MCPM is not set
+# CONFIG_VMSPLIT_3G is not set
+CONFIG_VMSPLIT_2G=y
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_NR_CPUS=2
+CONFIG_HOTPLUG_CPU=y
+# CONFIG_ARM_PSCI is not set
+CONFIG_LOCAL_TIMERS=y
+CONFIG_ARCH_NR_GPIO=0
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_COUNT=y
+CONFIG_HZ=1000
+CONFIG_SCHED_HRTICK=y
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=y
+# CONFIG_HIGHMEM is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_COMPACTION is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_CROSS_MEMORY_ATTACH=y
+# CONFIG_CLEANCACHE is not set
+# CONFIG_FRONTSWAP is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+# CONFIG_SECCOMP is not set
+CONFIG_CC_STACKPROTECTOR=y
+# CONFIG_XEN is not set
+
+#
+# Boot options
+#
+CONFIG_USE_OF=y
+CONFIG_ATAGS=y
+# CONFIG_DEPRECATED_PARAM_STRUCT is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_ARM_APPENDED_DTB is not set
+CONFIG_CMDLINE="console=ttyS0"
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
+# CONFIG_CMDLINE_EXTEND is not set
+# CONFIG_CMDLINE_FORCE is not set
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_AUTO_ZRELADDR is not set
+
+#
+# CPU Power Management
+#
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_SCRIPT=y
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_COREDUMP=y
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
+CONFIG_PM_SLEEP=y
+CONFIG_PM_SLEEP_SMP=y
+# CONFIG_PM_AUTOSLEEP is not set
+# CONFIG_PM_WAKELOCKS is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_CLK=y
+CONFIG_CPU_PM=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_DIAG is not set
+CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=y
+CONFIG_XFRM=y
+CONFIG_XFRM_ALGO=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=y
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+# CONFIG_IP_FIB_TRIE_STATS is not set
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
+# CONFIG_NET_IP_TUNNEL is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_NET_IPVTI is not set
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+CONFIG_INET_UDP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+CONFIG_STP=y
+CONFIG_BRIDGE=y
+CONFIG_BRIDGE_IGMP_SNOOPING=y
+CONFIG_HAVE_NET_DSA=y
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_OPENVSWITCH is not set
+# CONFIG_VSOCKETS is not set
+# CONFIG_NETLINK_MMAP is not set
+# CONFIG_NETLINK_DIAG is not set
+CONFIG_RPS=y
+CONFIG_RFS_ACCEL=y
+CONFIG_XPS=y
+# CONFIG_NETPRIO_CGROUP is not set
+CONFIG_BQL=y
+# CONFIG_BPF_JIT is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+# CONFIG_BT_HIDP is not set
+
+#
+# Bluetooth device drivers
+#
+# CONFIG_BT_HCIBTUSB is not set
+# CONFIG_BT_HCIBTSDIO is not set
+# CONFIG_BT_HCIUART is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_BT_MRVL is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_CFG80211=y
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+CONFIG_CFG80211_DEBUGFS=y
+# CONFIG_CFG80211_INTERNAL_REGDB is not set
+CONFIG_CFG80211_WEXT=y
+# CONFIG_LIB80211 is not set
+CONFIG_MAC80211=y
+CONFIG_MAC80211_HAS_RC=y
+CONFIG_MAC80211_RC_MINSTREL=y
+CONFIG_MAC80211_RC_MINSTREL_HT=y
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
+# CONFIG_MAC80211_MESH is not set
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_MESSAGE_TRACING is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
+CONFIG_RFKILL=y
+CONFIG_RFKILL_INPUT=y
+# CONFIG_RFKILL_GPIO is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+# CONFIG_NFC is not set
+CONFIG_HAVE_BPF_JIT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+CONFIG_FW_LOADER_USER_HELPER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_GENERIC_CPU_DEVICES is not set
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=m
+CONFIG_REGMAP_SPI=m
+# CONFIG_DMA_SHARED_BUFFER is not set
+# CONFIG_CMA is not set
+
+#
+# Bus devices
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+# CONFIG_MTD_SWAP is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_AMBARELLA_SPI_NOR is not set
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOCG3 is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_BCH=y
+CONFIG_MTD_NAND_ECC_BCH=y
+# CONFIG_MTD_SM_COMMON is not set
+CONFIG_MTD_NAND_AMBARELLA=y
+# CONFIG_MTD_NAND_DENALI is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_DOCG4 is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_LIMIT=20
+# CONFIG_MTD_UBI_FASTMAP is not set
+# CONFIG_MTD_UBI_GLUEBI is not set
+CONFIG_DTC=y
+CONFIG_OF=y
+
+#
+# Device Tree and Open Firmware support
+#
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_OF_SELFTEST is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_DEVICE=y
+CONFIG_OF_I2C=y
+CONFIG_OF_NET=y
+CONFIG_OF_MDIO=m
+CONFIG_OF_MTD=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_BLK_DEV_XIP=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_BLK_DEV_RBD is not set
+
+#
+# Misc devices
+#
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ATMEL_PWM is not set
+# CONFIG_DUMMY_IRQ is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ATMEL_SSC is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_APDS9802ALS is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_ISL29020 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_BH1780 is not set
+# CONFIG_SENSORS_BH1770 is not set
+# CONFIG_SENSORS_APDS990X is not set
+# CONFIG_HMC6352 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_BMP085_I2C is not set
+# CONFIG_BMP085_SPI is not set
+# CONFIG_USB_SWITCH_FSA9480 is not set
+# CONFIG_LATTICE_ECP3_CONFIG is not set
+# CONFIG_SRAM is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_EEPROM_93XX46 is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_TI_ST is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+
+#
+# Altera FPGA firmware download module
+#
+# CONFIG_ALTERA_STAPL is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=m
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_ISCSI_BOOT_SYSFS is not set
+# CONFIG_SCSI_UFSHCD is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_TARGET_CORE is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_CORE=y
+# CONFIG_BONDING is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_MII=y
+# CONFIG_NET_TEAM is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_VXLAN is not set
+CONFIG_NETCONSOLE=y
+CONFIG_NETCONSOLE_DYNAMIC=y
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+
+#
+# CAIF transport drivers
+#
+
+#
+# Distributed Switch Architecture drivers
+#
+# CONFIG_NET_DSA_MV88E6XXX is not set
+# CONFIG_NET_DSA_MV88E6060 is not set
+# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
+# CONFIG_NET_DSA_MV88E6131 is not set
+# CONFIG_NET_DSA_MV88E6123_61_65 is not set
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_AMBARELLA=m
+# CONFIG_NET_VENDOR_AMBARELLA_INTEN_TUE is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_CALXEDA_XGMAC is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_DM9000 is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_ETHOC is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+# CONFIG_AT803X_PHY is not set
+# CONFIG_AMD_PHY is not set
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_BCM87XX_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
+# CONFIG_MICREL_PHY_KSZ80X1R is not set
+# CONFIG_MDIO_BITBANG is not set
+# CONFIG_MDIO_BUS_MUX_GPIO is not set
+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
+# CONFIG_MICREL_KS8995MA is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_RTL8152 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_HSO is not set
+# CONFIG_USB_IPHETH is not set
+CONFIG_WLAN=y
+# CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_AT76C50X_USB is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_RTL8187 is not set
+# CONFIG_MAC80211_HWSIM is not set
+# CONFIG_ATH_CARDS is not set
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_BRCMFMAC is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_P54_COMMON is not set
+# CONFIG_RT2X00 is not set
+# CONFIG_RTLWIFI is not set
+# CONFIG_WL_TI is not set
+# CONFIG_ZD1211RW is not set
+# CONFIG_MWIFIEX is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+# CONFIG_INPUT_MATRIXKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ADP5589 is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_QT1070 is not set
+# CONFIG_KEYBOARD_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_GPIO=m
+# CONFIG_KEYBOARD_TCA6416 is not set
+# CONFIG_KEYBOARD_TCA8418 is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8333 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_MCS is not set
+# CONFIG_KEYBOARD_MPR121 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_SAMSUNG is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_BMA150 is not set
+CONFIG_INPUT_AMBARELLA_IR=m
+CONFIG_INPUT_AMBARELLA_ADC=m
+# CONFIG_INPUT_MMA8450 is not set
+# CONFIG_INPUT_MPU3050 is not set
+# CONFIG_INPUT_GP2A is not set
+# CONFIG_INPUT_GPIO_TILT_POLLED is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_KXTJ9 is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+CONFIG_INPUT_UINPUT=m
+# CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_PWM_BEEPER is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_CMA3000 is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_TTY=y
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_CONSOLE_SLEEP=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+# CONFIG_DEVKMEM is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AMBARELLA=y
+CONFIG_SERIAL_AMBARELLA_CONSOLE=y
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX310X is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_SCCNXP is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_IFX6X60 is not set
+# CONFIG_SERIAL_XILINX_PS_UART is not set
+# CONFIG_SERIAL_ARC is not set
+# CONFIG_HVC_DCC is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=m
+# CONFIG_I2C_MUX is not set
+# CONFIG_I2C_HELPER_AUTO is not set
+# CONFIG_I2C_SMBUS is not set
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_AMBARELLA=y
+# CONFIG_I2C_CBUS_GPIO is not set
+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_DIOLAN_U2C is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_SLAVE=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+CONFIG_SPI_AMBARELLA=y
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_FSL_SPI is not set
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_SC18IS602 is not set
+# CONFIG_SPI_XCOMM is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=m
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# SPI Slave Controller Drivers
+#
+CONFIG_SPI_SLAVE_AMBARELLA=m
+
+#
+# Qualcomm MSM SSBI bus support
+#
+# CONFIG_SSBI is not set
+# CONFIG_HSI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+# CONFIG_PTP_1588_CLOCK is not set
+
+#
+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
+#
+# CONFIG_PTP_1588_CLOCK_PCH is not set
+CONFIG_PINCTRL=y
+
+#
+# Pin controllers
+#
+CONFIG_PINMUX=y
+CONFIG_PINCONF=y
+# CONFIG_DEBUG_PINCTRL is not set
+# CONFIG_PINCTRL_SINGLE is not set
+# CONFIG_PINCTRL_EXYNOS is not set
+# CONFIG_PINCTRL_EXYNOS5440 is not set
+CONFIG_PINCTRL_AMB=y
+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIO_DEVRES=y
+CONFIG_GPIOLIB=y
+CONFIG_OF_GPIO=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_GENERIC_PLATFORM is not set
+# CONFIG_GPIO_EM is not set
+# CONFIG_GPIO_RCAR is not set
+# CONFIG_GPIO_TS5500 is not set
+# CONFIG_GPIO_GRGPIO is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+CONFIG_GPIO_PCA953X_IRQ=y
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_SX150X is not set
+# CONFIG_GPIO_ADP5588 is not set
+# CONFIG_GPIO_ADNP is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+# CONFIG_GPIO_74X164 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+
+#
+# USB GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_POWER_AVS is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AMBARELLA_WATCHDOG=y
+# CONFIG_DW_WATCHDOG is not set
+# CONFIG_MPCORE_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_AS3711 is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_AAT2870_CORE is not set
+# CONFIG_MFD_CROS_EC is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_DA9052_SPI is not set
+# CONFIG_MFD_DA9052_I2C is not set
+# CONFIG_MFD_DA9055 is not set
+# CONFIG_MFD_MC13XXX_SPI is not set
+# CONFIG_MFD_MC13XXX_I2C is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_MFD_88PM800 is not set
+# CONFIG_MFD_88PM805 is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_MAX77686 is not set
+# CONFIG_MFD_MAX77693 is not set
+# CONFIG_MFD_MAX8907 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_MAX8997 is not set
+# CONFIG_MFD_MAX8998 is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_VIPERBOARD is not set
+# CONFIG_MFD_RETU is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_RC5T583 is not set
+# CONFIG_MFD_SEC_CORE is not set
+# CONFIG_MFD_SI476X_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SMSC is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_MFD_STMPE is not set
+# CONFIG_MFD_SYSCON is not set
+# CONFIG_MFD_TI_AM335X_TSCADC is not set
+# CONFIG_MFD_LP8788 is not set
+# CONFIG_MFD_PALMAS is not set
+# CONFIG_TPS6105X is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_MFD_TPS65090 is not set
+# CONFIG_MFD_TPS65217 is not set
+# CONFIG_MFD_TPS6586X is not set
+# CONFIG_MFD_TPS65910 is not set
+# CONFIG_MFD_TPS65912 is not set
+# CONFIG_MFD_TPS65912_I2C is not set
+# CONFIG_MFD_TPS65912_SPI is not set
+# CONFIG_MFD_TPS80031 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_TWL6040_CORE is not set
+# CONFIG_MFD_WL1273_CORE is not set
+# CONFIG_MFD_LM3533 is not set
+# CONFIG_MFD_TC3589X is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_MFD_ARIZONA_I2C is not set
+# CONFIG_MFD_ARIZONA_SPI is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X_I2C is not set
+# CONFIG_MFD_WM831X_SPI is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+CONFIG_FB_SYS_FILLRECT=y
+CONFIG_FB_SYS_COPYAREA=y
+CONFIG_FB_SYS_IMAGEBLIT=y
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+CONFIG_FB_SYS_FOPS=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_SMSCUFX is not set
+# CONFIG_FB_UDL is not set
+# CONFIG_FB_GOLDFISH is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+CONFIG_FB_AMBARELLA=y
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_FB_AUO_K190X is not set
+# CONFIG_FB_SIMPLE is not set
+# CONFIG_EXYNOS_VIDEO is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=m
+# CONFIG_BACKLIGHT_ADP8860 is not set
+# CONFIG_BACKLIGHT_ADP8870 is not set
+# CONFIG_BACKLIGHT_LM3630 is not set
+# CONFIG_BACKLIGHT_LM3639 is not set
+# CONFIG_BACKLIGHT_LP855X is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=m
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+# CONFIG_LOGO is not set
+# CONFIG_FB_SSD1307 is not set
+CONFIG_SOUND=m
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_COMPRESS_OFFLOAD=m
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
+# CONFIG_SND_USB_CAIAQ is not set
+# CONFIG_SND_USB_6FIRE is not set
+CONFIG_SND_SOC=m
+CONFIG_SND_SOC_DMAENGINE_PCM=y
+CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
+CONFIG_SND_AMBARELLA_SOC=m
+CONFIG_SND_AMBARELLA_SOC_I2S=m
+CONFIG_SND_AMBARELLA_BOARD=m
+CONFIG_AMBA_BOARD=m
+CONFIG_SND_AMBARELLA_CODEC=m
+CONFIG_SND_SOC_AK4642_AMB=m
+# CONFIG_SND_SOC_AK4951_AMB is not set
+# CONFIG_SND_SOC_AK4954_AMB is not set
+# CONFIG_SND_SOC_ES8388 is not set
+# CONFIG_SND_SOC_WM8974_AMB is not set
+# CONFIG_SND_SOC_WM8940_AMB is not set
+CONFIG_SND_SOC_AMBARELLA_DUMMY=m
+# CONFIG_SND_ATMEL_SOC is not set
+CONFIG_SND_SOC_I2C_AND_SPI=m
+# CONFIG_SND_SOC_ALL_CODECS is not set
+# CONFIG_SND_SIMPLE_CARD is not set
+# CONFIG_SOUND_PRIME is not set
+
+#
+# HID support
+#
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+# CONFIG_UHID is not set
+CONFIG_HID_GENERIC=y
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=y
+# CONFIG_HID_ACRUX is not set
+CONFIG_HID_APPLE=y
+# CONFIG_HID_APPLEIR is not set
+# CONFIG_HID_AUREAL is not set
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+# CONFIG_HID_PRODIKEYS is not set
+CONFIG_HID_CYPRESS=y
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_ELECOM is not set
+CONFIG_HID_EZKEY=y
+# CONFIG_HID_HOLTEK is not set
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_ICADE is not set
+# CONFIG_HID_TWINHAN is not set
+CONFIG_HID_KENSINGTON=y
+# CONFIG_HID_LCPOWER is not set
+# CONFIG_HID_LENOVO_TPKBD is not set
+CONFIG_HID_LOGITECH=y
+# CONFIG_HID_LOGITECH_DJ is not set
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
+# CONFIG_LOGIWHEELS_FF is not set
+# CONFIG_HID_MAGICMOUSE is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_PRIMAX is not set
+# CONFIG_HID_PS3REMOTE is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_SAITEK is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SPEEDLINK is not set
+# CONFIG_HID_STEELSERIES is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TIVO is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+# CONFIG_HID_SENSOR_HUB is not set
+
+#
+# USB HID support
+#
+CONFIG_USB_HID=m
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# I2C HID support
+#
+# CONFIG_I2C_HID is not set
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB_ARCH_HAS_XHCI is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_COMMON=m
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEFAULT_PERSIST=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_EHCI_AMBARELLA=m
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_OHCI_AMBARELLA=y
+# CONFIG_USB_OHCI_HCD_PLATFORM is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_RENESAS_USBHS is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_REALTEK is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_STORAGE_ENE_UB6250 is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_DWC3 is not set
+# CONFIG_USB_CHIPIDEA is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_U1960 is not set
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP210X is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_F81232 is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_METRO is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QCAUX is not set
+# CONFIG_USB_SERIAL_QUALCOMM is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_SYMBOL is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
+# CONFIG_USB_SERIAL_XSENS_MT is not set
+# CONFIG_USB_SERIAL_ZIO is not set
+# CONFIG_USB_SERIAL_WISHBONE is not set
+# CONFIG_USB_SERIAL_ZTE is not set
+# CONFIG_USB_SERIAL_SSU100 is not set
+# CONFIG_USB_SERIAL_QT2 is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_EHSET_TEST_FIXTURE is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_YUREX is not set
+# CONFIG_USB_EZUSB_FX2 is not set
+# CONFIG_USB_HSIC_USB3503 is not set
+CONFIG_USB_PHY=y
+CONFIG_USB_AMBARELLA_PHY=y
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_OMAP_CONTROL_USB is not set
+# CONFIG_OMAP_USB3 is not set
+# CONFIG_SAMSUNG_USBPHY is not set
+# CONFIG_SAMSUNG_USB2PHY is not set
+# CONFIG_SAMSUNG_USB3PHY is not set
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ISP1301 is not set
+# CONFIG_USB_RCAR_PHY is not set
+# CONFIG_USB_ULPI is not set
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
+
+#
+# USB Peripheral Controller
+#
+# CONFIG_USB_FUSB300 is not set
+# CONFIG_USB_R8A66597 is not set
+# CONFIG_USB_PXA27X is not set
+# CONFIG_USB_MV_UDC is not set
+# CONFIG_USB_MV_U3D is not set
+# CONFIG_USB_M66592 is not set
+# CONFIG_USB_NET2272 is not set
+CONFIG_USB_AMBARELLA=m
+# CONFIG_USB_DUMMY_HCD is not set
+CONFIG_USB_LIBCOMPOSITE=m
+CONFIG_USB_F_ACM=m
+CONFIG_USB_U_SERIAL=m
+CONFIG_USB_F_SERIAL=m
+CONFIG_USB_F_OBEX=m
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
+# CONFIG_USB_G_NCM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FUNCTIONFS is not set
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_ACM_MS is not set
+# CONFIG_USB_G_MULTI is not set
+# CONFIG_USB_G_HID is not set
+# CONFIG_USB_G_DBGP is not set
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+# CONFIG_MMC_CLKGATE is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_BLOCK_MINORS=32
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+# CONFIG_SDIO_UART is not set
+CONFIG_MMC_TEST=m
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_AMBARELLA=m
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MMC_DW is not set
+# CONFIG_MMC_VUB300 is not set
+# CONFIG_MMC_USHC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_EDAC is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_SYSTOHC=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS3232 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+CONFIG_RTC_DRV_ISL12022=y
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8523 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+# CONFIG_RTC_DRV_EM3027 is not set
+# CONFIG_RTC_DRV_RV3029C2 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T93 is not set
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+# CONFIG_RTC_DRV_RX4581 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+# CONFIG_RTC_DRV_DS2404 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_AMBARELLA=y
+# CONFIG_RTC_DRV_SNVS is not set
+
+#
+# HID Sensor RTC drivers
+#
+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
+CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+# CONFIG_DW_DMAC is not set
+# CONFIG_TIMB_DMA is not set
+CONFIG_AMBARELLA_DMA=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+
+#
+# DMA Clients
+#
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_VIRT_DRIVERS is not set
+
+#
+# Virtio drivers
+#
+# CONFIG_VIRTIO_MMIO is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+# CONFIG_STAGING is not set
+
+#
+# Hardware Spinlock drivers
+#
+CONFIG_CLKSRC_OF=y
+# CONFIG_MAILBOX is not set
+# CONFIG_IOMMU_SUPPORT is not set
+
+#
+# Remoteproc drivers
+#
+# CONFIG_STE_MODEM_RPROC is not set
+# CONFIG_RPROC_SUPPORT is not set
+# CONFIG_RPCLNT_SUPPORT is not set
+
+#
+# Rpmsg drivers
+#
+# CONFIG_PM_DEVFREQ is not set
+# CONFIG_EXTCON is not set
+# CONFIG_MEMORY is not set
+# CONFIG_IIO is not set
+CONFIG_PWM=y
+CONFIG_PWM_AMBARELLA=m
+CONFIG_IRQCHIP=y
+CONFIG_ARM_GIC=y
+# CONFIG_IPACK_BUS is not set
+# CONFIG_RESET_CONTROLLER is not set
+
+#
+# File systems
+#
+CONFIG_DCACHE_WORD_ACCESS=y
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_USE_FOR_EXT23=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_EXPORTFS=y
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_FANOTIFY=y
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_TMPFS_XATTR=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX6FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_PSTORE is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_F2FS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V2=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_SWAP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_DEBUG is not set
+# CONFIG_CEPH_FS is not set
+CONFIG_CIFS=y
+CONFIG_CIFS_STATS=y
+# CONFIG_CIFS_STATS2 is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+CONFIG_CIFS_DEBUG=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_SMB2 is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_MAC_ROMAN is not set
+# CONFIG_NLS_MAC_CELTIC is not set
+# CONFIG_NLS_MAC_CENTEURO is not set
+# CONFIG_NLS_MAC_CROATIAN is not set
+# CONFIG_NLS_MAC_CYRILLIC is not set
+# CONFIG_NLS_MAC_GAELIC is not set
+# CONFIG_NLS_MAC_GREEK is not set
+# CONFIG_NLS_MAC_ICELAND is not set
+# CONFIG_NLS_MAC_INUIT is not set
+# CONFIG_NLS_MAC_ROMANIAN is not set
+# CONFIG_NLS_MAC_TURKISH is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_READABLE_ASM is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+# CONFIG_LOCKUP_DETECTOR is not set
+# CONFIG_PANIC_ON_OOPS is not set
+CONFIG_PANIC_ON_OOPS_VALUE=0
+# CONFIG_DETECT_HUNG_TASK is not set
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+# CONFIG_DEBUG_KMEMLEAK is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_ATOMIC_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_TEST_LIST_SORT is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+
+#
+# RCU Debugging
+#
+# CONFIG_PROVE_RCU_DELAY is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+CONFIG_RCU_CPU_STALL_VERBOSE=y
+# CONFIG_RCU_CPU_STALL_INFO is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_DEBUG_PER_CPU_MAPS is not set
+# CONFIG_LKDTM is not set
+# CONFIG_NOTIFIER_ERROR_INJECTION is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_RBTREE_TEST is not set
+# CONFIG_INTERVAL_TREE_TEST is not set
+CONFIG_DYNAMIC_DEBUG=y
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_TEST_STRING_HELPERS is not set
+# CONFIG_TEST_KSTRTOX is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_LL is not set
+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
+CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"
+# CONFIG_PID_IN_CONTEXTIDR is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_USER is not set
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_CMAC is not set
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_CRC32 is not set
+# CONFIG_CRYPTO_GHASH is not set
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA1_ARM is not set
+CONFIG_CRYPTO_SHA256=y
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_AES_ARM is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=y
+# CONFIG_CRYPTO_USER_API_HASH is not set
+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_DEV_AMBARELLA=m
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_IO=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC32_SELFTEST is not set
+CONFIG_CRC32_SLICEBY8=y
+# CONFIG_CRC32_SLICEBY4 is not set
+# CONFIG_CRC32_SARWATE is not set
+# CONFIG_CRC32_BIT is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+# CONFIG_CRC8 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_XZ_DEC=y
+CONFIG_XZ_DEC_X86=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_SPARC=y
+CONFIG_XZ_DEC_BCJ=y
+# CONFIG_XZ_DEC_TEST is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_XZ=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_BCH=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_CPU_RMAP=y
+CONFIG_DQL=y
+CONFIG_NLATTR=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+CONFIG_AVERAGE=y
+# CONFIG_CORDIC is not set
+# CONFIG_DDR is not set
+# CONFIG_VIRTUALIZATION is not set
diff --git a/arch/arm/configs/ambarella_s2e_defconfig b/arch/arm/configs/ambarella_s2e_defconfig
new file mode 100644
index 00000000..791f3676
--- /dev/null
+++ b/arch/arm/configs/ambarella_s2e_defconfig
@@ -0,0 +1,2744 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/arm 3.10.73 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_NEED_MACH_GPIO_H=y
+CONFIG_NEED_MACH_IO_H=y
+CONFIG_NEED_MACH_MEMORY_H=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_IRQ_WORK=y
+CONFIG_BUILDTIME_EXTABLE_SORT=y
+
+#
+# General setup
+#
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_XZ is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_DEFAULT_HOSTNAME="Ambarella"
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_FHANDLE=y
+# CONFIG_AUDIT is not set
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_ARCH_HAS_TICK_BROADCAST=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+
+#
+# Timers subsystem
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ_COMMON=y
+# CONFIG_HZ_PERIODIC is not set
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+
+#
+# CPU/Task time and stats accounting
+#
+CONFIG_TICK_CPU_ACCOUNTING=y
+# CONFIG_IRQ_TIME_ACCOUNTING is not set
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_PREEMPT_RCU=y
+CONFIG_PREEMPT_RCU=y
+CONFIG_RCU_STALL_COMMON=y
+# CONFIG_RCU_USER_QS is not set
+CONFIG_RCU_FANOUT=32
+CONFIG_RCU_FANOUT_LEAF=16
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_RCU_BOOST is not set
+# CONFIG_RCU_NOCB_CPU is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+# CONFIG_CGROUP_FREEZER is not set
+# CONFIG_CGROUP_DEVICE is not set
+# CONFIG_CPUSETS is not set
+# CONFIG_CGROUP_CPUACCT is not set
+# CONFIG_RESOURCE_COUNTERS is not set
+CONFIG_CGROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_CFS_BANDWIDTH is not set
+# CONFIG_RT_GROUP_SCHED is not set
+# CONFIG_BLK_CGROUP is not set
+# CONFIG_CHECKPOINT_RESTORE is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_NET_NS=y
+CONFIG_UIDGID_CONVERTED=y
+# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_XZ=y
+CONFIG_RD_LZO=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_HAVE_UID16=y
+CONFIG_HOTPLUG=y
+# CONFIG_EXPERT is not set
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+# CONFIG_EMBEDDED is not set
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_JUMP_LABEL is not set
+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_OLD_SIGACTION=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_MODULE_SIG is not set
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_BSGLIB is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_AMBPTB_PARTITION=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y
+CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_LOCK=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y
+CONFIG_ARCH_INLINE_READ_TRYLOCK=y
+CONFIG_ARCH_INLINE_READ_LOCK=y
+CONFIG_ARCH_INLINE_READ_LOCK_BH=y
+CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_READ_UNLOCK=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y
+CONFIG_ARCH_INLINE_WRITE_TRYLOCK=y
+CONFIG_ARCH_INLINE_WRITE_LOCK=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_SPIN_TRYLOCK=y
+CONFIG_INLINE_SPIN_TRYLOCK_BH=y
+CONFIG_INLINE_SPIN_LOCK=y
+CONFIG_INLINE_SPIN_LOCK_BH=y
+CONFIG_INLINE_SPIN_LOCK_IRQ=y
+CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y
+CONFIG_INLINE_SPIN_UNLOCK_BH=y
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_READ_TRYLOCK=y
+CONFIG_INLINE_READ_LOCK=y
+CONFIG_INLINE_READ_LOCK_BH=y
+CONFIG_INLINE_READ_LOCK_IRQ=y
+CONFIG_INLINE_READ_LOCK_IRQSAVE=y
+CONFIG_INLINE_READ_UNLOCK=y
+CONFIG_INLINE_READ_UNLOCK_BH=y
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_WRITE_TRYLOCK=y
+CONFIG_INLINE_WRITE_LOCK=y
+CONFIG_INLINE_WRITE_LOCK_BH=y
+CONFIG_INLINE_WRITE_LOCK_IRQ=y
+CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y
+CONFIG_INLINE_WRITE_UNLOCK=y
+CONFIG_INLINE_WRITE_UNLOCK_BH=y
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y
+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_MULTIPLATFORM is not set
+CONFIG_ARCH_AMBARELLA=y
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_LPC32XX is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C24XX is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P64X0 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_EXYNOS is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP1 is not set
+CONFIG_PLAT_AMBARELLA=y
+
+#
+# Ambarella Platform
+#
+CONFIG_PLAT_AMBARELLA_SUPPORT_VIC=y
+# CONFIG_PLAT_AMBARELLA_HAVE_ARM11 is not set
+CONFIG_PLAT_AMBARELLA_CORTEX=y
+CONFIG_PLAT_AMBARELLA_CORTEX_SMP=y
+CONFIG_PLAT_AMBARELLA_LOCAL_TIMERS=y
+CONFIG_PLAT_AMBARELLA_SUPPORT_PM=y
+CONFIG_PLAT_AMBARELLA_MEM_START_LOW=y
+# CONFIG_PLAT_AMBARELLA_AHB_APB_HIGH is not set
+CONFIG_PLAT_AMBARELLA_SUPPORT_HW_CRYPTO=y
+CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI=y
+CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC=y
+# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64 is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS is not set
+# CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_RPROC is not set
+# CONFIG_PLAT_AMBARELLA_S2 is not set
+# CONFIG_PLAT_AMBARELLA_A8 is not set
+# CONFIG_PLAT_AMBARELLA_A5S is not set
+# CONFIG_PLAT_AMBARELLA_A7L is not set
+# CONFIG_PLAT_AMBARELLA_S2_ARM11 is not set
+# CONFIG_PLAT_AMBARELLA_S2_CORTEX is not set
+CONFIG_PLAT_AMBARELLA_S2E=y
+# CONFIG_PLAT_AMBARELLA_A8_ARM11 is not set
+# CONFIG_PLAT_AMBARELLA_A8_CORTEX is not set
+# CONFIG_PLAT_AMBARELLA_S2L is not set
+# CONFIG_PLAT_AMBARELLA_S3 is not set
+# CONFIG_PLAT_AMBARELLA_S3L is not set
+
+#
+# Generic Platform Configuration
+#
+# CONFIG_AMBARELLA_CALC_PLL is not set
+# CONFIG_AMBARELLA_RAW_BOOT is not set
+# CONFIG_AMBARELLA_PMUSERENR_EN is not set
+CONFIG_PLAT_AMBARELLA_SUPPORT_GDMA=y
+
+#
+# Sys file system support
+#
+CONFIG_AMBARELLA_SYS_CACHE_CALL=y
+
+#
+# Proc file system support
+#
+CONFIG_AMBARELLA_PLL_PROC=y
+# CONFIG_AMBARELLA_SUPPORT_AMBENCH is not set
+
+#
+# Memory Configuration
+#
+CONFIG_AMBARELLA_PPM_SIZE=0x00200000
+CONFIG_AMBARELLA_ZRELADDR=0x00208000
+CONFIG_AMBARELLA_TEXTOFS=0x00008000
+CONFIG_AMBARELLA_PARAMS_PHYS=0x00200100
+CONFIG_AMBARELLA_INITRD_PHYS=0x00A00000
+# CONFIG_AMBARELLA_IO_MAP is not set
+# CONFIG_AMBARELLA_PPM_UNCACHED is not set
+CONFIG_AMBARELLA_TIMER_HZ=100
+CONFIG_AMBARELLA_TIMER_HIGHRES=y
+CONFIG_AMBARELLA_EXT_IRQ_NUM=16
+CONFIG_AMBARELLA_EXT_GPIO_NUM=16
+# CONFIG_AMBARELLA_SREF_FIFO_EXEC is not set
+CONFIG_GPIO_PCA953X=y
+# CONFIG_KEYBOARD_GPIO_POLLED is not set
+# CONFIG_PLAT_SPEAR is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_LPAE is not set
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_ARM_VIRT_EXT=y
+# CONFIG_SWP_EMULATE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_KUSER_HELPERS=y
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_CACHE_L2X0=y
+CONFIG_CACHE_PL310=y
+# CONFIG_CACHE_PL310_EARLY_BRESP is not set
+CONFIG_CACHE_PL310_PREFETCH_OFFSET=0
+# CONFIG_CACHE_PL310_FULL_LINE_OF_ZERO is not set
+# CONFIG_CACHE_PL310_DOUBLE_LINEFILL is not set
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_NR_BANKS=8
+CONFIG_MULTI_IRQ_HANDLER=y
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+# CONFIG_ARM_ERRATA_742230 is not set
+# CONFIG_ARM_ERRATA_742231 is not set
+CONFIG_PL310_ERRATA_588369=y
+# CONFIG_ARM_ERRATA_643719 is not set
+# CONFIG_ARM_ERRATA_720789 is not set
+CONFIG_PL310_ERRATA_727915=y
+# CONFIG_ARM_ERRATA_743622 is not set
+# CONFIG_ARM_ERRATA_751472 is not set
+# CONFIG_PL310_ERRATA_753970 is not set
+CONFIG_ARM_ERRATA_754322=y
+# CONFIG_ARM_ERRATA_754327 is not set
+CONFIG_ARM_ERRATA_764369=y
+# CONFIG_PL310_ERRATA_769419 is not set
+CONFIG_ARM_ERRATA_775420=y
+# CONFIG_ARM_ERRATA_798181 is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_HAVE_SMP=y
+CONFIG_SMP=y
+CONFIG_SMP_ON_UP=y
+CONFIG_ARM_CPU_TOPOLOGY=y
+# CONFIG_SCHED_MC is not set
+# CONFIG_SCHED_SMT is not set
+CONFIG_HAVE_ARM_SCU=y
+# CONFIG_HAVE_ARM_ARCH_TIMER is not set
+# CONFIG_MCPM is not set
+# CONFIG_VMSPLIT_3G is not set
+CONFIG_VMSPLIT_2G=y
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_NR_CPUS=2
+CONFIG_HOTPLUG_CPU=y
+# CONFIG_ARM_PSCI is not set
+CONFIG_LOCAL_TIMERS=y
+CONFIG_ARCH_NR_GPIO=0
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_COUNT=y
+CONFIG_HZ=100
+CONFIG_SCHED_HRTICK=y
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=y
+# CONFIG_HIGHMEM is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_COMPACTION is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_CROSS_MEMORY_ATTACH is not set
+# CONFIG_CLEANCACHE is not set
+# CONFIG_FRONTSWAP is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+# CONFIG_SECCOMP is not set
+CONFIG_CC_STACKPROTECTOR=y
+# CONFIG_XEN is not set
+
+#
+# Boot options
+#
+CONFIG_USE_OF=y
+CONFIG_ATAGS=y
+# CONFIG_DEPRECATED_PARAM_STRUCT is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_ARM_APPENDED_DTB is not set
+CONFIG_CMDLINE="console=ttyS0"
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
+# CONFIG_CMDLINE_EXTEND is not set
+# CONFIG_CMDLINE_FORCE is not set
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_AUTO_ZRELADDR is not set
+
+#
+# CPU Power Management
+#
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+
+#
+# ARM CPU frequency scaling drivers
+#
+# CONFIG_ARM_EXYNOS4210_CPUFREQ is not set
+# CONFIG_ARM_EXYNOS4X12_CPUFREQ is not set
+# CONFIG_ARM_EXYNOS5250_CPUFREQ is not set
+# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set
+CONFIG_ARM_AMBARALLA_CPUFREQ=y
+# CONFIG_CPU_IDLE is not set
+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_SCRIPT=y
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_COREDUMP=y
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
+CONFIG_PM_SLEEP=y
+CONFIG_PM_SLEEP_SMP=y
+# CONFIG_PM_AUTOSLEEP is not set
+# CONFIG_PM_WAKELOCKS is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_CLK=y
+CONFIG_CPU_PM=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_DIAG is not set
+CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=y
+CONFIG_XFRM=y
+CONFIG_XFRM_ALGO=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+# CONFIG_IP_FIB_TRIE_STATS is not set
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
+# CONFIG_NET_IP_TUNNEL is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+# CONFIG_BRIDGE is not set
+CONFIG_HAVE_NET_DSA=y
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_OPENVSWITCH is not set
+# CONFIG_VSOCKETS is not set
+# CONFIG_NETLINK_MMAP is not set
+# CONFIG_NETLINK_DIAG is not set
+CONFIG_RPS=y
+CONFIG_RFS_ACCEL=y
+CONFIG_XPS=y
+# CONFIG_NETPRIO_CGROUP is not set
+CONFIG_BQL=y
+# CONFIG_BPF_JIT is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+# CONFIG_BT_HIDP is not set
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIBTUSB=m
+CONFIG_BT_HCIBTSDIO=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+# CONFIG_BT_HCIUART_ATH3K is not set
+CONFIG_BT_HCIUART_LL=y
+# CONFIG_BT_HCIUART_3WIRE is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_BT_MRVL is not set
+# CONFIG_BT_ATH3K is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_CFG80211=m
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+CONFIG_CFG80211_DEBUGFS=y
+# CONFIG_CFG80211_INTERNAL_REGDB is not set
+CONFIG_CFG80211_WEXT=y
+# CONFIG_LIB80211 is not set
+CONFIG_MAC80211=m
+CONFIG_MAC80211_HAS_RC=y
+CONFIG_MAC80211_RC_MINSTREL=y
+CONFIG_MAC80211_RC_MINSTREL_HT=y
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
+# CONFIG_MAC80211_MESH is not set
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_MESSAGE_TRACING is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
+CONFIG_RFKILL=m
+CONFIG_RFKILL_INPUT=y
+# CONFIG_RFKILL_GPIO is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+# CONFIG_NFC is not set
+CONFIG_HAVE_BPF_JIT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH=""
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+CONFIG_FW_LOADER_USER_HELPER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_GENERIC_CPU_DEVICES is not set
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=m
+CONFIG_REGMAP_SPI=m
+CONFIG_DMA_SHARED_BUFFER=y
+# CONFIG_CMA is not set
+
+#
+# Bus devices
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_BLKDEVS=y
+# CONFIG_MTD_BLOCK is not set
+# CONFIG_MTD_BLOCK_RO is not set
+CONFIG_MTD_BLOCK_AMBRO=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+# CONFIG_MTD_SWAP is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_AMBARELLA_SPI_NOR is not set
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOCG3 is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_BCH=y
+CONFIG_MTD_NAND_ECC_BCH=y
+# CONFIG_MTD_SM_COMMON is not set
+CONFIG_MTD_NAND_AMBARELLA=y
+# CONFIG_MTD_SPINAND_AMBARELLA is not set
+# CONFIG_MTD_SPINAND_ONDIEECC is not set
+# CONFIG_MTD_NAND_DENALI is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_DOCG4 is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_LIMIT=20
+# CONFIG_MTD_UBI_FASTMAP is not set
+# CONFIG_MTD_UBI_GLUEBI is not set
+CONFIG_DTC=y
+CONFIG_OF=y
+
+#
+# Device Tree and Open Firmware support
+#
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_OF_SELFTEST is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_DEVICE=y
+CONFIG_OF_I2C=y
+CONFIG_OF_NET=y
+CONFIG_OF_MDIO=m
+CONFIG_OF_MTD=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_BLK_DEV_XIP=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_BLK_DEV_RBD is not set
+
+#
+# Misc devices
+#
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ATMEL_PWM is not set
+# CONFIG_DUMMY_IRQ is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ATMEL_SSC is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_APDS9802ALS is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_ISL29020 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_BH1780 is not set
+# CONFIG_SENSORS_BH1770 is not set
+# CONFIG_SENSORS_APDS990X is not set
+# CONFIG_HMC6352 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_BMP085_I2C is not set
+# CONFIG_BMP085_SPI is not set
+# CONFIG_USB_SWITCH_FSA9480 is not set
+# CONFIG_LATTICE_ECP3_CONFIG is not set
+# CONFIG_SRAM is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_EEPROM_93XX46 is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_TI_ST is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+
+#
+# Altera FPGA firmware download module
+#
+# CONFIG_ALTERA_STAPL is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=m
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_ISCSI_BOOT_SYSFS is not set
+# CONFIG_SCSI_UFSHCD is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_TARGET_CORE is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_CORE=y
+# CONFIG_BONDING is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_MII=y
+# CONFIG_NET_TEAM is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_VXLAN is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+
+#
+# CAIF transport drivers
+#
+
+#
+# Distributed Switch Architecture drivers
+#
+# CONFIG_NET_DSA_MV88E6XXX is not set
+# CONFIG_NET_DSA_MV88E6060 is not set
+# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
+# CONFIG_NET_DSA_MV88E6131 is not set
+# CONFIG_NET_DSA_MV88E6123_61_65 is not set
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_AMBARELLA=m
+CONFIG_NET_VENDOR_AMBARELLA_INTEN_TUE=y
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_CALXEDA_XGMAC is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_DM9000 is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_ETHOC is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+# CONFIG_AT803X_PHY is not set
+# CONFIG_AMD_PHY is not set
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_BCM87XX_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
+CONFIG_MICREL_PHY_KSZ80X1R=m
+# CONFIG_MDIO_BITBANG is not set
+# CONFIG_MDIO_BUS_MUX_GPIO is not set
+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
+# CONFIG_MICREL_KS8995MA is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_RTL8152 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_HSO is not set
+# CONFIG_USB_IPHETH is not set
+CONFIG_WLAN=y
+# CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_AT76C50X_USB is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_RTL8187 is not set
+# CONFIG_MAC80211_HWSIM is not set
+CONFIG_ATH_CARDS=m
+# CONFIG_ATH_DEBUG is not set
+# CONFIG_ATH9K is not set
+# CONFIG_ATH9K_HTC is not set
+# CONFIG_CARL9170 is not set
+CONFIG_ATH6KL=m
+CONFIG_ATH6KL_SDIO=m
+# CONFIG_ATH6KL_USB is not set
+# CONFIG_ATH6KL_DEBUG is not set
+# CONFIG_AR5523 is not set
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_BRCMFMAC is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_P54_COMMON is not set
+# CONFIG_RT2X00 is not set
+# CONFIG_RTLWIFI is not set
+# CONFIG_WL_TI is not set
+# CONFIG_ZD1211RW is not set
+CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
+# CONFIG_MWIFIEX_USB is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+# CONFIG_INPUT_MATRIXKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ADP5589 is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_QT1070 is not set
+# CONFIG_KEYBOARD_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_GPIO=m
+# CONFIG_KEYBOARD_TCA6416 is not set
+# CONFIG_KEYBOARD_TCA8418 is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8333 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_MCS is not set
+# CONFIG_KEYBOARD_MPR121 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_SAMSUNG is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_BMA150 is not set
+CONFIG_INPUT_AMBARELLA_IR=m
+CONFIG_INPUT_AMBARELLA_ADC=m
+# CONFIG_INPUT_MMA8450 is not set
+# CONFIG_INPUT_MPU3050 is not set
+# CONFIG_INPUT_GP2A is not set
+# CONFIG_INPUT_GPIO_TILT_POLLED is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_KXTJ9 is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+CONFIG_INPUT_UINPUT=m
+# CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_PWM_BEEPER is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_CMA3000 is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_TTY=y
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_CONSOLE_SLEEP=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+# CONFIG_DEVKMEM is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AMBARELLA=y
+CONFIG_SERIAL_AMBARELLA_CONSOLE=y
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX310X is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_SCCNXP is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_IFX6X60 is not set
+# CONFIG_SERIAL_XILINX_PS_UART is not set
+# CONFIG_SERIAL_ARC is not set
+# CONFIG_HVC_DCC is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=m
+# CONFIG_I2C_MUX is not set
+# CONFIG_I2C_HELPER_AUTO is not set
+# CONFIG_I2C_SMBUS is not set
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_AMBARELLA=y
+# CONFIG_I2C_CBUS_GPIO is not set
+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_DIOLAN_U2C is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_SLAVE=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+CONFIG_SPI_AMBARELLA=m
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_FSL_SPI is not set
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_SC18IS602 is not set
+# CONFIG_SPI_XCOMM is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=m
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# SPI Slave Controller Drivers
+#
+CONFIG_SPI_SLAVE_AMBARELLA=m
+
+#
+# Qualcomm MSM SSBI bus support
+#
+# CONFIG_SSBI is not set
+# CONFIG_HSI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+# CONFIG_PTP_1588_CLOCK is not set
+
+#
+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
+#
+# CONFIG_PTP_1588_CLOCK_PCH is not set
+CONFIG_PINCTRL=y
+
+#
+# Pin controllers
+#
+CONFIG_PINMUX=y
+CONFIG_PINCONF=y
+# CONFIG_DEBUG_PINCTRL is not set
+# CONFIG_PINCTRL_SINGLE is not set
+# CONFIG_PINCTRL_EXYNOS is not set
+# CONFIG_PINCTRL_EXYNOS5440 is not set
+CONFIG_PINCTRL_AMB=y
+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIO_DEVRES=y
+CONFIG_GPIOLIB=y
+CONFIG_OF_GPIO=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_GENERIC_PLATFORM is not set
+# CONFIG_GPIO_EM is not set
+# CONFIG_GPIO_RCAR is not set
+# CONFIG_GPIO_TS5500 is not set
+# CONFIG_GPIO_GRGPIO is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_GPIO_PCF857X=y
+# CONFIG_GPIO_SX150X is not set
+# CONFIG_GPIO_ADP5588 is not set
+# CONFIG_GPIO_ADNP is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+# CONFIG_GPIO_74X164 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+
+#
+# USB GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_POWER_AVS is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AMBARELLA_WATCHDOG=y
+# CONFIG_DW_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_AS3711 is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_AAT2870_CORE is not set
+# CONFIG_MFD_CROS_EC is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_DA9052_SPI is not set
+# CONFIG_MFD_DA9052_I2C is not set
+# CONFIG_MFD_DA9055 is not set
+# CONFIG_MFD_MC13XXX_SPI is not set
+# CONFIG_MFD_MC13XXX_I2C is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_MFD_88PM800 is not set
+# CONFIG_MFD_88PM805 is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_MAX77686 is not set
+# CONFIG_MFD_MAX77693 is not set
+# CONFIG_MFD_MAX8907 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_MAX8997 is not set
+# CONFIG_MFD_MAX8998 is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_VIPERBOARD is not set
+# CONFIG_MFD_RETU is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_RC5T583 is not set
+# CONFIG_MFD_SEC_CORE is not set
+# CONFIG_MFD_SI476X_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SMSC is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_MFD_STMPE is not set
+# CONFIG_MFD_SYSCON is not set
+# CONFIG_MFD_TI_AM335X_TSCADC is not set
+# CONFIG_MFD_LP8788 is not set
+# CONFIG_MFD_PALMAS is not set
+# CONFIG_TPS6105X is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_MFD_TPS65090 is not set
+# CONFIG_MFD_TPS65217 is not set
+# CONFIG_MFD_TPS6586X is not set
+# CONFIG_MFD_TPS65910 is not set
+# CONFIG_MFD_TPS65912 is not set
+# CONFIG_MFD_TPS65912_I2C is not set
+# CONFIG_MFD_TPS65912_SPI is not set
+# CONFIG_MFD_TPS80031 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_TWL6040_CORE is not set
+# CONFIG_MFD_WL1273_CORE is not set
+# CONFIG_MFD_LM3533 is not set
+# CONFIG_MFD_TC3589X is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_MFD_ARIZONA_I2C is not set
+# CONFIG_MFD_ARIZONA_SPI is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X_I2C is not set
+# CONFIG_MFD_WM831X_SPI is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_REGULATOR is not set
+CONFIG_MEDIA_SUPPORT=m
+
+#
+# Multimedia core support
+#
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set
+# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set
+# CONFIG_MEDIA_RADIO_SUPPORT is not set
+# CONFIG_MEDIA_RC_SUPPORT is not set
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_DEV=m
+# CONFIG_VIDEO_V4L2_SUBDEV_API is not set
+CONFIG_VIDEO_V4L2=m
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+CONFIG_VIDEOBUF2_CORE=m
+CONFIG_VIDEOBUF2_MEMOPS=m
+CONFIG_VIDEOBUF2_VMALLOC=m
+# CONFIG_VIDEO_V4L2_INT_DEVICE is not set
+# CONFIG_TTPCI_EEPROM is not set
+
+#
+# Media drivers
+#
+CONFIG_MEDIA_USB_SUPPORT=y
+
+#
+# Webcam devices
+#
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
+CONFIG_USB_GSPCA=m
+# CONFIG_USB_M5602 is not set
+# CONFIG_USB_STV06XX is not set
+# CONFIG_USB_GL860 is not set
+# CONFIG_USB_GSPCA_BENQ is not set
+# CONFIG_USB_GSPCA_CONEX is not set
+# CONFIG_USB_GSPCA_CPIA1 is not set
+# CONFIG_USB_GSPCA_ETOMS is not set
+# CONFIG_USB_GSPCA_FINEPIX is not set
+# CONFIG_USB_GSPCA_JEILINJ is not set
+# CONFIG_USB_GSPCA_JL2005BCD is not set
+# CONFIG_USB_GSPCA_KINECT is not set
+# CONFIG_USB_GSPCA_KONICA is not set
+# CONFIG_USB_GSPCA_MARS is not set
+# CONFIG_USB_GSPCA_MR97310A is not set
+# CONFIG_USB_GSPCA_NW80X is not set
+# CONFIG_USB_GSPCA_OV519 is not set
+# CONFIG_USB_GSPCA_OV534 is not set
+# CONFIG_USB_GSPCA_OV534_9 is not set
+# CONFIG_USB_GSPCA_PAC207 is not set
+# CONFIG_USB_GSPCA_PAC7302 is not set
+# CONFIG_USB_GSPCA_PAC7311 is not set
+# CONFIG_USB_GSPCA_SE401 is not set
+# CONFIG_USB_GSPCA_SN9C2028 is not set
+# CONFIG_USB_GSPCA_SN9C20X is not set
+# CONFIG_USB_GSPCA_SONIXB is not set
+# CONFIG_USB_GSPCA_SONIXJ is not set
+# CONFIG_USB_GSPCA_SPCA500 is not set
+# CONFIG_USB_GSPCA_SPCA501 is not set
+# CONFIG_USB_GSPCA_SPCA505 is not set
+# CONFIG_USB_GSPCA_SPCA506 is not set
+# CONFIG_USB_GSPCA_SPCA508 is not set
+# CONFIG_USB_GSPCA_SPCA561 is not set
+# CONFIG_USB_GSPCA_SPCA1528 is not set
+# CONFIG_USB_GSPCA_SQ905 is not set
+# CONFIG_USB_GSPCA_SQ905C is not set
+# CONFIG_USB_GSPCA_SQ930X is not set
+# CONFIG_USB_GSPCA_STK014 is not set
+# CONFIG_USB_GSPCA_STV0680 is not set
+# CONFIG_USB_GSPCA_SUNPLUS is not set
+# CONFIG_USB_GSPCA_T613 is not set
+# CONFIG_USB_GSPCA_TOPRO is not set
+# CONFIG_USB_GSPCA_TV8532 is not set
+# CONFIG_USB_GSPCA_VC032X is not set
+# CONFIG_USB_GSPCA_VICAM is not set
+# CONFIG_USB_GSPCA_XIRLINK_CIT is not set
+# CONFIG_USB_GSPCA_ZC3XX is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_USB_ZR364XX is not set
+# CONFIG_USB_STKWEBCAM is not set
+# CONFIG_USB_S2255 is not set
+# CONFIG_USB_SN9C102 is not set
+
+#
+# Webcam, TV (analog/digital) USB devices
+#
+# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_V4L_PLATFORM_DRIVERS is not set
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set
+# CONFIG_VIDEO_SH_VEU is not set
+# CONFIG_V4L_TEST_DRIVERS is not set
+
+#
+# Supported MMC/SDIO adapters
+#
+# CONFIG_CYPRESS_FIRMWARE is not set
+
+#
+# Media ancillary drivers (tuners, sensors, i2c, frontends)
+#
+CONFIG_MEDIA_SUBDRV_AUTOSELECT=y
+
+#
+# Audio decoders, processors and mixers
+#
+
+#
+# RDS decoders
+#
+
+#
+# Video decoders
+#
+
+#
+# Video and audio decoders
+#
+
+#
+# Video encoders
+#
+
+#
+# Camera sensor devices
+#
+
+#
+# Flash devices
+#
+
+#
+# Video improvement chips
+#
+
+#
+# Miscelaneous helper chips
+#
+
+#
+# Sensors used on soc_camera driver
+#
+
+#
+# Tools to develop new frontends
+#
+# CONFIG_DVB_DUMMY_FE is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+CONFIG_FB_SYS_FILLRECT=m
+CONFIG_FB_SYS_COPYAREA=m
+CONFIG_FB_SYS_IMAGEBLIT=m
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+CONFIG_FB_SYS_FOPS=m
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_SMSCUFX is not set
+# CONFIG_FB_UDL is not set
+# CONFIG_FB_GOLDFISH is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+CONFIG_FB_AMBARELLA=m
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_FB_AUO_K190X is not set
+# CONFIG_FB_SIMPLE is not set
+# CONFIG_EXYNOS_VIDEO is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=m
+# CONFIG_BACKLIGHT_ADP8860 is not set
+# CONFIG_BACKLIGHT_ADP8870 is not set
+# CONFIG_BACKLIGHT_LM3630 is not set
+# CONFIG_BACKLIGHT_LM3639 is not set
+# CONFIG_BACKLIGHT_LP855X is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=m
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_FONT_AUTOSELECT=y
+# CONFIG_LOGO is not set
+# CONFIG_FB_SSD1307 is not set
+CONFIG_SOUND=m
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_COMPRESS_OFFLOAD=m
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
+# CONFIG_SND_USB_CAIAQ is not set
+# CONFIG_SND_USB_6FIRE is not set
+CONFIG_SND_SOC=m
+CONFIG_SND_SOC_DMAENGINE_PCM=y
+CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
+CONFIG_SND_AMBARELLA_SOC=m
+CONFIG_SND_AMBARELLA_SOC_I2S=m
+CONFIG_SND_AMBARELLA_BOARD=m
+CONFIG_AMBA_BOARD=m
+CONFIG_SND_AMBARELLA_CODEC=m
+CONFIG_SND_SOC_AK4642_AMB=m
+CONFIG_SND_SOC_AK4951_AMB=m
+# CONFIG_SND_SOC_AK4954_AMB is not set
+# CONFIG_SND_SOC_AK7719_DSP is not set
+# CONFIG_SND_SOC_AK7755 is not set
+# CONFIG_SND_SOC_TLV320ADC3xxx is not set
+# CONFIG_SND_SOC_ES8388 is not set
+# CONFIG_SND_SOC_WM8974_AMB is not set
+# CONFIG_SND_SOC_WM8940_AMB is not set
+CONFIG_SND_SOC_AMBARELLA_DUMMY=m
+# CONFIG_SND_ATMEL_SOC is not set
+CONFIG_SND_SOC_I2C_AND_SPI=m
+# CONFIG_SND_SOC_ALL_CODECS is not set
+# CONFIG_SND_SIMPLE_CARD is not set
+# CONFIG_SOUND_PRIME is not set
+
+#
+# HID support
+#
+CONFIG_HID=m
+# CONFIG_HIDRAW is not set
+# CONFIG_UHID is not set
+CONFIG_HID_GENERIC=m
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=m
+# CONFIG_HID_ACRUX is not set
+CONFIG_HID_APPLE=m
+# CONFIG_HID_APPLEIR is not set
+# CONFIG_HID_AUREAL is not set
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+# CONFIG_HID_PRODIKEYS is not set
+CONFIG_HID_CYPRESS=m
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_ELECOM is not set
+CONFIG_HID_EZKEY=m
+# CONFIG_HID_HOLTEK is not set
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_ICADE is not set
+# CONFIG_HID_TWINHAN is not set
+CONFIG_HID_KENSINGTON=m
+# CONFIG_HID_LCPOWER is not set
+# CONFIG_HID_LENOVO_TPKBD is not set
+CONFIG_HID_LOGITECH=m
+# CONFIG_HID_LOGITECH_DJ is not set
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
+# CONFIG_LOGIWHEELS_FF is not set
+# CONFIG_HID_MAGICMOUSE is not set
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_PRIMAX is not set
+# CONFIG_HID_PS3REMOTE is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_SAITEK is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SPEEDLINK is not set
+# CONFIG_HID_STEELSERIES is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TIVO is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+# CONFIG_HID_SENSOR_HUB is not set
+
+#
+# USB HID support
+#
+CONFIG_USB_HID=m
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# I2C HID support
+#
+# CONFIG_I2C_HID is not set
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB_ARCH_HAS_XHCI is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEFAULT_PERSIST is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_EHCI_AMBARELLA=m
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_OHCI_AMBARELLA=y
+# CONFIG_USB_OHCI_HCD_PLATFORM is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_RENESAS_USBHS is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_REALTEK is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_STORAGE_ENE_UB6250 is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_DWC3 is not set
+# CONFIG_USB_CHIPIDEA is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_U1960 is not set
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP210X is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_F81232 is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_METRO is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QCAUX is not set
+# CONFIG_USB_SERIAL_QUALCOMM is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_SYMBOL is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
+# CONFIG_USB_SERIAL_XSENS_MT is not set
+# CONFIG_USB_SERIAL_ZIO is not set
+# CONFIG_USB_SERIAL_WISHBONE is not set
+# CONFIG_USB_SERIAL_ZTE is not set
+# CONFIG_USB_SERIAL_SSU100 is not set
+# CONFIG_USB_SERIAL_QT2 is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_EHSET_TEST_FIXTURE is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_YUREX is not set
+# CONFIG_USB_EZUSB_FX2 is not set
+# CONFIG_USB_HSIC_USB3503 is not set
+CONFIG_USB_PHY=y
+CONFIG_USB_AMBARELLA_PHY=y
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_OMAP_CONTROL_USB is not set
+# CONFIG_OMAP_USB3 is not set
+# CONFIG_SAMSUNG_USBPHY is not set
+# CONFIG_SAMSUNG_USB2PHY is not set
+# CONFIG_SAMSUNG_USB3PHY is not set
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ISP1301 is not set
+# CONFIG_USB_RCAR_PHY is not set
+# CONFIG_USB_ULPI is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
+
+#
+# USB Peripheral Controller
+#
+# CONFIG_USB_FUSB300 is not set
+# CONFIG_USB_R8A66597 is not set
+# CONFIG_USB_PXA27X is not set
+# CONFIG_USB_MV_UDC is not set
+# CONFIG_USB_MV_U3D is not set
+# CONFIG_USB_M66592 is not set
+# CONFIG_USB_NET2272 is not set
+CONFIG_USB_AMBARELLA=m
+CONFIG_USB_LIBCOMPOSITE=m
+CONFIG_USB_F_ACM=m
+CONFIG_USB_U_SERIAL=m
+CONFIG_USB_F_SERIAL=m
+CONFIG_USB_F_OBEX=m
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
+# CONFIG_USB_G_NCM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FUNCTIONFS is not set
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_ACM_MS is not set
+CONFIG_USB_G_MULTI=m
+CONFIG_USB_G_MULTI_RNDIS=y
+# CONFIG_USB_G_MULTI_CDC is not set
+# CONFIG_USB_G_HID is not set
+# CONFIG_USB_G_DBGP is not set
+# CONFIG_USB_G_WEBCAM is not set
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+# CONFIG_MMC_CLKGATE is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_BLOCK_MINORS=32
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_AMBARELLA=m
+# CONFIG_AMBARELLA_EMMC_BOOT is not set
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MMC_DW is not set
+# CONFIG_MMC_VUB300 is not set
+# CONFIG_MMC_USHC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_EDAC is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_SYSTOHC=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS3232 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_ISL12022 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8523 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+# CONFIG_RTC_DRV_EM3027 is not set
+# CONFIG_RTC_DRV_RV3029C2 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T93 is not set
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+# CONFIG_RTC_DRV_RX4581 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+# CONFIG_RTC_DRV_DS2404 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_AMBARELLA=y
+# CONFIG_RTC_DRV_SNVS is not set
+
+#
+# HID Sensor RTC drivers
+#
+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
+CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+# CONFIG_DW_DMAC is not set
+# CONFIG_TIMB_DMA is not set
+CONFIG_AMBARELLA_DMA=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+
+#
+# DMA Clients
+#
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_VIRT_DRIVERS is not set
+
+#
+# Virtio drivers
+#
+# CONFIG_VIRTIO_MMIO is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+# CONFIG_STAGING is not set
+
+#
+# Hardware Spinlock drivers
+#
+# CONFIG_MAILBOX is not set
+# CONFIG_IOMMU_SUPPORT is not set
+
+#
+# Remoteproc drivers
+#
+# CONFIG_STE_MODEM_RPROC is not set
+# CONFIG_RPROC_SUPPORT is not set
+# CONFIG_RPCLNT_SUPPORT is not set
+
+#
+# Rpmsg drivers
+#
+# CONFIG_PM_DEVFREQ is not set
+# CONFIG_EXTCON is not set
+# CONFIG_MEMORY is not set
+# CONFIG_IIO is not set
+CONFIG_PWM=y
+CONFIG_PWM_AMBARELLA=m
+CONFIG_IRQCHIP=y
+CONFIG_AMBARELLA_VIC=y
+# CONFIG_IPACK_BUS is not set
+# CONFIG_RESET_CONTROLLER is not set
+
+#
+# File systems
+#
+CONFIG_DCACHE_WORD_ACCESS=y
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+CONFIG_EXT4_FS=m
+CONFIG_EXT4_USE_FOR_EXT23=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD2=m
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=m
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_EXPORTFS=y
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_TMPFS_XATTR=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+CONFIG_SQUASHFS=y
+# CONFIG_SQUASHFS_XATTR is not set
+CONFIG_SQUASHFS_ZLIB=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX6FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_PSTORE is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_F2FS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V2=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_SWAP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_DEBUG is not set
+# CONFIG_CEPH_FS is not set
+CONFIG_CIFS=y
+CONFIG_CIFS_STATS=y
+# CONFIG_CIFS_STATS2 is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+CONFIG_CIFS_DEBUG=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_SMB2 is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_MAC_ROMAN is not set
+# CONFIG_NLS_MAC_CELTIC is not set
+# CONFIG_NLS_MAC_CENTEURO is not set
+# CONFIG_NLS_MAC_CROATIAN is not set
+# CONFIG_NLS_MAC_CYRILLIC is not set
+# CONFIG_NLS_MAC_GAELIC is not set
+# CONFIG_NLS_MAC_GREEK is not set
+# CONFIG_NLS_MAC_ICELAND is not set
+# CONFIG_NLS_MAC_INUIT is not set
+# CONFIG_NLS_MAC_ROMANIAN is not set
+# CONFIG_NLS_MAC_TURKISH is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_READABLE_ASM is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+# CONFIG_LOCKUP_DETECTOR is not set
+# CONFIG_PANIC_ON_OOPS is not set
+CONFIG_PANIC_ON_OOPS_VALUE=0
+# CONFIG_DETECT_HUNG_TASK is not set
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+# CONFIG_DEBUG_KMEMLEAK is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_ATOMIC_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_TEST_LIST_SORT is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+
+#
+# RCU Debugging
+#
+# CONFIG_PROVE_RCU_DELAY is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=21
+CONFIG_RCU_CPU_STALL_VERBOSE=y
+# CONFIG_RCU_CPU_STALL_INFO is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_DEBUG_PER_CPU_MAPS is not set
+# CONFIG_LKDTM is not set
+# CONFIG_NOTIFIER_ERROR_INJECTION is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_RBTREE_TEST is not set
+# CONFIG_INTERVAL_TREE_TEST is not set
+CONFIG_DYNAMIC_DEBUG=y
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_TEST_STRING_HELPERS is not set
+# CONFIG_TEST_KSTRTOX is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_LL is not set
+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
+CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"
+# CONFIG_PID_IN_CONTEXTIDR is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_USER is not set
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_CMAC is not set
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_CRC32 is not set
+# CONFIG_CRYPTO_GHASH is not set
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA1_ARM is not set
+CONFIG_CRYPTO_SHA256=y
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_AES_ARM is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_USER_API=y
+CONFIG_CRYPTO_USER_API_HASH=y
+CONFIG_CRYPTO_USER_API_SKCIPHER=y
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_DEV_AMBARELLA=m
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_IO=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC32_SELFTEST is not set
+CONFIG_CRC32_SLICEBY8=y
+# CONFIG_CRC32_SLICEBY4 is not set
+# CONFIG_CRC32_SARWATE is not set
+# CONFIG_CRC32_BIT is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+# CONFIG_CRC8 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_XZ_DEC=y
+# CONFIG_XZ_DEC_X86 is not set
+# CONFIG_XZ_DEC_POWERPC is not set
+# CONFIG_XZ_DEC_IA64 is not set
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+# CONFIG_XZ_DEC_SPARC is not set
+CONFIG_XZ_DEC_BCJ=y
+# CONFIG_XZ_DEC_TEST is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_XZ=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_BCH=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_CPU_RMAP=y
+CONFIG_DQL=y
+CONFIG_NLATTR=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+CONFIG_AVERAGE=y
+# CONFIG_CORDIC is not set
+# CONFIG_DDR is not set
+# CONFIG_VIRTUALIZATION is not set
diff --git a/arch/arm/configs/ambarella_s2l_defconfig b/arch/arm/configs/ambarella_s2l_defconfig
new file mode 100644
index 00000000..db360841
--- /dev/null
+++ b/arch/arm/configs/ambarella_s2l_defconfig
@@ -0,0 +1,2519 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/arm 3.10.104 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_NEED_MACH_GPIO_H=y
+CONFIG_NEED_MACH_IO_H=y
+CONFIG_NEED_MACH_MEMORY_H=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_IRQ_WORK=y
+CONFIG_BUILDTIME_EXTABLE_SORT=y
+
+#
+# General setup
+#
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_XZ is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_DEFAULT_HOSTNAME="Ambarella"
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_FHANDLE=y
+# CONFIG_AUDIT is not set
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# Timers subsystem
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ_COMMON=y
+# CONFIG_HZ_PERIODIC is not set
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+
+#
+# CPU/Task time and stats accounting
+#
+CONFIG_TICK_CPU_ACCOUNTING=y
+# CONFIG_IRQ_TIME_ACCOUNTING is not set
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_TREE_PREEMPT_RCU is not set
+CONFIG_TINY_PREEMPT_RCU=y
+CONFIG_PREEMPT_RCU=y
+# CONFIG_RCU_STALL_COMMON is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_RCU_BOOST is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+# CONFIG_CGROUP_FREEZER is not set
+# CONFIG_CGROUP_DEVICE is not set
+# CONFIG_CPUSETS is not set
+# CONFIG_CGROUP_CPUACCT is not set
+# CONFIG_RESOURCE_COUNTERS is not set
+CONFIG_CGROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_CFS_BANDWIDTH is not set
+# CONFIG_RT_GROUP_SCHED is not set
+# CONFIG_BLK_CGROUP is not set
+# CONFIG_CHECKPOINT_RESTORE is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_NET_NS=y
+CONFIG_UIDGID_CONVERTED=y
+# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_XZ=y
+CONFIG_RD_LZO=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_HAVE_UID16=y
+CONFIG_HOTPLUG=y
+# CONFIG_EXPERT is not set
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+# CONFIG_EMBEDDED is not set
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_JUMP_LABEL is not set
+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_OLD_SIGACTION=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_MODULE_SIG is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_BSGLIB is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_AMBPTB_PARTITION=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y
+CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_LOCK=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y
+CONFIG_ARCH_INLINE_READ_TRYLOCK=y
+CONFIG_ARCH_INLINE_READ_LOCK=y
+CONFIG_ARCH_INLINE_READ_LOCK_BH=y
+CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_READ_UNLOCK=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y
+CONFIG_ARCH_INLINE_WRITE_TRYLOCK=y
+CONFIG_ARCH_INLINE_WRITE_LOCK=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_SPIN_TRYLOCK=y
+CONFIG_INLINE_SPIN_TRYLOCK_BH=y
+CONFIG_INLINE_SPIN_LOCK=y
+CONFIG_INLINE_SPIN_LOCK_BH=y
+CONFIG_INLINE_SPIN_LOCK_IRQ=y
+CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y
+CONFIG_INLINE_SPIN_UNLOCK_BH=y
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_READ_TRYLOCK=y
+CONFIG_INLINE_READ_LOCK=y
+CONFIG_INLINE_READ_LOCK_BH=y
+CONFIG_INLINE_READ_LOCK_IRQ=y
+CONFIG_INLINE_READ_LOCK_IRQSAVE=y
+CONFIG_INLINE_READ_UNLOCK=y
+CONFIG_INLINE_READ_UNLOCK_BH=y
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_WRITE_TRYLOCK=y
+CONFIG_INLINE_WRITE_LOCK=y
+CONFIG_INLINE_WRITE_LOCK_BH=y
+CONFIG_INLINE_WRITE_LOCK_IRQ=y
+CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y
+CONFIG_INLINE_WRITE_UNLOCK=y
+CONFIG_INLINE_WRITE_UNLOCK_BH=y
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y
+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_MULTIPLATFORM is not set
+CONFIG_ARCH_AMBARELLA=y
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_LPC32XX is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C24XX is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P64X0 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_EXYNOS is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP1 is not set
+CONFIG_PLAT_AMBARELLA=y
+
+#
+# Ambarella Platform
+#
+CONFIG_PLAT_AMBARELLA_SUPPORT_VIC=y
+# CONFIG_PLAT_AMBARELLA_HAVE_ARM11 is not set
+CONFIG_PLAT_AMBARELLA_CORTEX=y
+# CONFIG_PLAT_AMBARELLA_CORTEX_SMP is not set
+CONFIG_PLAT_AMBARELLA_SUPPORT_PM=y
+CONFIG_PLAT_AMBARELLA_MEM_START_LOW=y
+CONFIG_PLAT_AMBARELLA_AHB_APB_HIGH=y
+CONFIG_PLAT_AMBARELLA_SUPPORT_HW_CRYPTO=y
+CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI=y
+CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC=y
+# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64 is not set
+CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS=y
+# CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_RPROC is not set
+# CONFIG_PLAT_AMBARELLA_S2 is not set
+# CONFIG_PLAT_AMBARELLA_A8 is not set
+# CONFIG_PLAT_AMBARELLA_A5S is not set
+# CONFIG_PLAT_AMBARELLA_A7L is not set
+# CONFIG_PLAT_AMBARELLA_S2_ARM11 is not set
+# CONFIG_PLAT_AMBARELLA_S2_CORTEX is not set
+# CONFIG_PLAT_AMBARELLA_S2E is not set
+# CONFIG_PLAT_AMBARELLA_A8_ARM11 is not set
+# CONFIG_PLAT_AMBARELLA_A8_CORTEX is not set
+CONFIG_PLAT_AMBARELLA_S2L=y
+# CONFIG_PLAT_AMBARELLA_S3 is not set
+# CONFIG_PLAT_AMBARELLA_S3L is not set
+
+#
+# Generic Platform Configuration
+#
+# CONFIG_AMBARELLA_CALC_PLL is not set
+# CONFIG_AMBARELLA_RAW_BOOT is not set
+# CONFIG_AMBARELLA_PMUSERENR_EN is not set
+CONFIG_PLAT_AMBARELLA_SUPPORT_GDMA=y
+
+#
+# Sys file system support
+#
+# CONFIG_AMBARELLA_SYS_CACHE_CALL is not set
+
+#
+# Proc file system support
+#
+CONFIG_AMBARELLA_PLL_PROC=y
+# CONFIG_AMBARELLA_SUPPORT_AMBENCH is not set
+
+#
+# Memory Configuration
+#
+CONFIG_AMBARELLA_PPM_SIZE=0x00200000
+CONFIG_AMBARELLA_ZRELADDR=0x00208000
+CONFIG_AMBARELLA_TEXTOFS=0x00008000
+CONFIG_AMBARELLA_PARAMS_PHYS=0x00200100
+CONFIG_AMBARELLA_INITRD_PHYS=0x00A00000
+# CONFIG_AMBARELLA_IO_MAP is not set
+# CONFIG_AMBARELLA_PPM_UNCACHED is not set
+CONFIG_AMBARELLA_TIMER_HZ=100
+CONFIG_AMBARELLA_TIMER_HIGHRES=y
+CONFIG_AMBARELLA_EXT_IRQ_NUM=16
+CONFIG_AMBARELLA_EXT_GPIO_NUM=16
+CONFIG_AMBARELLA_SREF_FIFO_EXEC=y
+CONFIG_GPIO_PCA953X=y
+# CONFIG_KEYBOARD_GPIO_POLLED is not set
+# CONFIG_PLAT_SPEAR is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_LPAE is not set
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_ARM_VIRT_EXT=y
+# CONFIG_SWP_EMULATE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_KUSER_HELPERS=y
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_CACHE_L2X0=y
+CONFIG_CACHE_PL310=y
+# CONFIG_CACHE_PL310_EARLY_BRESP is not set
+CONFIG_CACHE_PL310_PREFETCH_OFFSET=0
+# CONFIG_CACHE_PL310_FULL_LINE_OF_ZERO is not set
+# CONFIG_CACHE_PL310_DOUBLE_LINEFILL is not set
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_NR_BANKS=8
+CONFIG_MULTI_IRQ_HANDLER=y
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_PL310_ERRATA_588369=y
+# CONFIG_ARM_ERRATA_720789 is not set
+CONFIG_PL310_ERRATA_727915=y
+# CONFIG_ARM_ERRATA_743622 is not set
+# CONFIG_ARM_ERRATA_751472 is not set
+# CONFIG_PL310_ERRATA_753970 is not set
+# CONFIG_ARM_ERRATA_754322 is not set
+# CONFIG_PL310_ERRATA_769419 is not set
+# CONFIG_ARM_ERRATA_775420 is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_HAVE_ARM_ARCH_TIMER is not set
+# CONFIG_VMSPLIT_3G is not set
+CONFIG_VMSPLIT_2G=y
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0x80000000
+# CONFIG_ARM_PSCI is not set
+CONFIG_ARCH_NR_GPIO=0
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_COUNT=y
+CONFIG_HZ=100
+CONFIG_SCHED_HRTICK=y
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=y
+# CONFIG_HIGHMEM is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_COMPACTION is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_CROSS_MEMORY_ATTACH is not set
+CONFIG_NEED_PER_CPU_KM=y
+# CONFIG_CLEANCACHE is not set
+# CONFIG_FRONTSWAP is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+# CONFIG_SECCOMP is not set
+CONFIG_CC_STACKPROTECTOR=y
+# CONFIG_XEN is not set
+
+#
+# Boot options
+#
+CONFIG_USE_OF=y
+CONFIG_ATAGS=y
+# CONFIG_DEPRECATED_PARAM_STRUCT is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_ARM_APPENDED_DTB is not set
+CONFIG_CMDLINE="console=ttyS0"
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
+# CONFIG_CMDLINE_EXTEND is not set
+# CONFIG_CMDLINE_FORCE is not set
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_AUTO_ZRELADDR is not set
+
+#
+# CPU Power Management
+#
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+
+#
+# ARM CPU frequency scaling drivers
+#
+# CONFIG_ARM_EXYNOS4210_CPUFREQ is not set
+# CONFIG_ARM_EXYNOS4X12_CPUFREQ is not set
+# CONFIG_ARM_EXYNOS5250_CPUFREQ is not set
+# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set
+CONFIG_ARM_AMBARALLA_CPUFREQ=y
+# CONFIG_CPU_IDLE is not set
+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_SCRIPT=y
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_COREDUMP=y
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_HIBERNATE_CALLBACKS=y
+CONFIG_HIBERNATION=y
+CONFIG_PM_STD_PARTITION=""
+CONFIG_PM_SLEEP=y
+# CONFIG_PM_AUTOSLEEP is not set
+CONFIG_PM_WAKELOCKS=y
+CONFIG_PM_WAKELOCKS_LIMIT=100
+CONFIG_PM_WAKELOCKS_GC=y
+# CONFIG_PM_RUNTIME is not set
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+CONFIG_PM_ADVANCED_DEBUG=y
+# CONFIG_PM_TEST_SUSPEND is not set
+CONFIG_PM_SLEEP_DEBUG=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_CLK=y
+CONFIG_CPU_PM=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_DIAG is not set
+CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=y
+CONFIG_XFRM=y
+CONFIG_XFRM_ALGO=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+# CONFIG_IP_FIB_TRIE_STATS is not set
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
+# CONFIG_NET_IP_TUNNEL is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_WLAN_UPDATE_SEQ is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+# CONFIG_BRIDGE is not set
+CONFIG_HAVE_NET_DSA=y
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_OPENVSWITCH is not set
+# CONFIG_VSOCKETS is not set
+# CONFIG_NETLINK_MMAP is not set
+# CONFIG_NETLINK_DIAG is not set
+# CONFIG_NETPRIO_CGROUP is not set
+CONFIG_BQL=y
+# CONFIG_BPF_JIT is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+# CONFIG_BT_HIDP is not set
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIBTUSB=m
+CONFIG_BT_HCIBTSDIO=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+# CONFIG_BT_HCIUART_ATH3K is not set
+CONFIG_BT_HCIUART_LL=y
+# CONFIG_BT_HCIUART_3WIRE is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_BT_MRVL is not set
+# CONFIG_BT_ATH3K is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_CFG80211=m
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+CONFIG_CFG80211_DEBUGFS=y
+# CONFIG_CFG80211_INTERNAL_REGDB is not set
+CONFIG_CFG80211_WEXT=y
+# CONFIG_LIB80211 is not set
+CONFIG_MAC80211=m
+CONFIG_MAC80211_HAS_RC=y
+CONFIG_MAC80211_RC_MINSTREL=y
+CONFIG_MAC80211_RC_MINSTREL_HT=y
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
+# CONFIG_MAC80211_MESH is not set
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_MESSAGE_TRACING is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
+CONFIG_RFKILL=m
+CONFIG_RFKILL_INPUT=y
+# CONFIG_RFKILL_GPIO is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+# CONFIG_NFC is not set
+CONFIG_HAVE_BPF_JIT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH=""
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+CONFIG_FW_LOADER_USER_HELPER=y
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_GENERIC_CPU_DEVICES is not set
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=m
+CONFIG_REGMAP_SPI=m
+# CONFIG_DMA_SHARED_BUFFER is not set
+# CONFIG_CMA is not set
+
+#
+# Bus devices
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_BLKDEVS=y
+# CONFIG_MTD_BLOCK is not set
+# CONFIG_MTD_BLOCK_RO is not set
+CONFIG_MTD_BLOCK_AMBRO=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+# CONFIG_MTD_SWAP is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_AMBARELLA_SPI_NOR is not set
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOCG3 is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_BCH=y
+CONFIG_MTD_NAND_ECC_BCH=y
+# CONFIG_MTD_SM_COMMON is not set
+CONFIG_MTD_NAND_AMBARELLA=y
+# CONFIG_MTD_SPINAND_AMBARELLA is not set
+# CONFIG_MTD_NAND_DENALI is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_DOCG4 is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_LIMIT=20
+# CONFIG_MTD_UBI_FASTMAP is not set
+# CONFIG_MTD_UBI_GLUEBI is not set
+CONFIG_DTC=y
+CONFIG_OF=y
+
+#
+# Device Tree and Open Firmware support
+#
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_OF_SELFTEST is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_DEVICE=y
+CONFIG_OF_I2C=y
+CONFIG_OF_NET=y
+CONFIG_OF_MDIO=m
+CONFIG_OF_MTD=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_BLK_DEV_XIP=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_BLK_DEV_RBD is not set
+
+#
+# Misc devices
+#
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ATMEL_PWM is not set
+# CONFIG_DUMMY_IRQ is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ATMEL_SSC is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_APDS9802ALS is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_ISL29020 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_BH1780 is not set
+# CONFIG_SENSORS_BH1770 is not set
+# CONFIG_SENSORS_APDS990X is not set
+# CONFIG_HMC6352 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_BMP085_I2C is not set
+# CONFIG_BMP085_SPI is not set
+# CONFIG_USB_SWITCH_FSA9480 is not set
+# CONFIG_LATTICE_ECP3_CONFIG is not set
+# CONFIG_SRAM is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_EEPROM_93XX46 is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_TI_ST is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+
+#
+# Altera FPGA firmware download module
+#
+# CONFIG_ALTERA_STAPL is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=m
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_ISCSI_BOOT_SYSFS is not set
+# CONFIG_SCSI_UFSHCD is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_TARGET_CORE is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_CORE=y
+# CONFIG_BONDING is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_MII=y
+# CONFIG_NET_TEAM is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_VXLAN is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+
+#
+# CAIF transport drivers
+#
+
+#
+# Distributed Switch Architecture drivers
+#
+# CONFIG_NET_DSA_MV88E6XXX is not set
+# CONFIG_NET_DSA_MV88E6060 is not set
+# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
+# CONFIG_NET_DSA_MV88E6131 is not set
+# CONFIG_NET_DSA_MV88E6123_61_65 is not set
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_AMBARELLA=m
+CONFIG_NET_VENDOR_AMBARELLA_INTEN_TUE=y
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_CALXEDA_XGMAC is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_DM9000 is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_ETHOC is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+# CONFIG_AT803X_PHY is not set
+# CONFIG_AMD_PHY is not set
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_BCM87XX_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
+CONFIG_MICREL_PHY_KSZ80X1R=m
+# CONFIG_MDIO_BITBANG is not set
+# CONFIG_MDIO_BUS_MUX_GPIO is not set
+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
+# CONFIG_MICREL_KS8995MA is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_RTL8152 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_HSO is not set
+# CONFIG_USB_IPHETH is not set
+CONFIG_WLAN=y
+# CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_AT76C50X_USB is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_RTL8187 is not set
+# CONFIG_MAC80211_HWSIM is not set
+CONFIG_ATH_CARDS=m
+# CONFIG_ATH_DEBUG is not set
+# CONFIG_ATH9K is not set
+# CONFIG_ATH9K_HTC is not set
+# CONFIG_CARL9170 is not set
+CONFIG_ATH6KL=m
+CONFIG_ATH6KL_SDIO=m
+# CONFIG_ATH6KL_USB is not set
+# CONFIG_ATH6KL_DEBUG is not set
+# CONFIG_AR5523 is not set
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_BRCMFMAC is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_P54_COMMON is not set
+# CONFIG_RT2X00 is not set
+# CONFIG_RTLWIFI is not set
+# CONFIG_WL_TI is not set
+# CONFIG_ZD1211RW is not set
+CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
+# CONFIG_MWIFIEX_USB is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+# CONFIG_INPUT_MATRIXKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ADP5589 is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_QT1070 is not set
+# CONFIG_KEYBOARD_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_GPIO=m
+# CONFIG_KEYBOARD_TCA6416 is not set
+# CONFIG_KEYBOARD_TCA8418 is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8333 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_MCS is not set
+# CONFIG_KEYBOARD_MPR121 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_SAMSUNG is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_BMA150 is not set
+CONFIG_INPUT_AMBARELLA_IR=m
+CONFIG_INPUT_AMBARELLA_ADC=m
+# CONFIG_INPUT_MMA8450 is not set
+# CONFIG_INPUT_MPU3050 is not set
+# CONFIG_INPUT_GP2A is not set
+# CONFIG_INPUT_GPIO_TILT_POLLED is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_KXTJ9 is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+CONFIG_INPUT_UINPUT=m
+# CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_PWM_BEEPER is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_CMA3000 is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_TTY=y
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_CONSOLE_SLEEP=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+# CONFIG_DEVKMEM is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AMBARELLA=y
+CONFIG_SERIAL_AMBARELLA_CONSOLE=y
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX310X is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_SCCNXP is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_IFX6X60 is not set
+# CONFIG_SERIAL_XILINX_PS_UART is not set
+# CONFIG_SERIAL_ARC is not set
+# CONFIG_HVC_DCC is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=m
+# CONFIG_I2C_MUX is not set
+# CONFIG_I2C_HELPER_AUTO is not set
+# CONFIG_I2C_SMBUS is not set
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_AMBARELLA=y
+# CONFIG_I2C_CBUS_GPIO is not set
+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_DIOLAN_U2C is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_SLAVE=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+CONFIG_SPI_AMBARELLA=m
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_FSL_SPI is not set
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_SC18IS602 is not set
+# CONFIG_SPI_XCOMM is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=m
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# SPI Slave Controller Drivers
+#
+CONFIG_SPI_SLAVE_AMBARELLA=m
+
+#
+# Qualcomm MSM SSBI bus support
+#
+# CONFIG_SSBI is not set
+# CONFIG_HSI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+# CONFIG_PTP_1588_CLOCK is not set
+
+#
+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
+#
+# CONFIG_PTP_1588_CLOCK_PCH is not set
+CONFIG_PINCTRL=y
+
+#
+# Pin controllers
+#
+CONFIG_PINMUX=y
+CONFIG_PINCONF=y
+# CONFIG_PINCTRL_SINGLE is not set
+# CONFIG_PINCTRL_EXYNOS is not set
+# CONFIG_PINCTRL_EXYNOS5440 is not set
+CONFIG_PINCTRL_AMB=y
+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIO_DEVRES=y
+CONFIG_GPIOLIB=y
+CONFIG_OF_GPIO=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_GENERIC_PLATFORM is not set
+# CONFIG_GPIO_EM is not set
+# CONFIG_GPIO_RCAR is not set
+# CONFIG_GPIO_TS5500 is not set
+# CONFIG_GPIO_GRGPIO is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+CONFIG_GPIO_PCA953X_IRQ=y
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_SX150X is not set
+# CONFIG_GPIO_ADP5588 is not set
+# CONFIG_GPIO_ADNP is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+# CONFIG_GPIO_74X164 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+
+#
+# USB GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_POWER_AVS is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AMBARELLA_WATCHDOG=y
+# CONFIG_DW_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_AS3711 is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_AAT2870_CORE is not set
+# CONFIG_MFD_CROS_EC is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_DA9052_SPI is not set
+# CONFIG_MFD_DA9052_I2C is not set
+# CONFIG_MFD_DA9055 is not set
+# CONFIG_MFD_MC13XXX_SPI is not set
+# CONFIG_MFD_MC13XXX_I2C is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_MFD_88PM800 is not set
+# CONFIG_MFD_88PM805 is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_MAX77686 is not set
+# CONFIG_MFD_MAX77693 is not set
+# CONFIG_MFD_MAX8907 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_MAX8997 is not set
+# CONFIG_MFD_MAX8998 is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_VIPERBOARD is not set
+# CONFIG_MFD_RETU is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_RC5T583 is not set
+# CONFIG_MFD_SEC_CORE is not set
+# CONFIG_MFD_SI476X_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SMSC is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_MFD_STMPE is not set
+# CONFIG_MFD_SYSCON is not set
+# CONFIG_MFD_TI_AM335X_TSCADC is not set
+# CONFIG_MFD_LP8788 is not set
+# CONFIG_MFD_PALMAS is not set
+# CONFIG_TPS6105X is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_MFD_TPS65090 is not set
+# CONFIG_MFD_TPS65217 is not set
+# CONFIG_MFD_TPS6586X is not set
+# CONFIG_MFD_TPS65910 is not set
+# CONFIG_MFD_TPS65912 is not set
+# CONFIG_MFD_TPS65912_I2C is not set
+# CONFIG_MFD_TPS65912_SPI is not set
+# CONFIG_MFD_TPS80031 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_TWL6040_CORE is not set
+# CONFIG_MFD_WL1273_CORE is not set
+# CONFIG_MFD_LM3533 is not set
+# CONFIG_MFD_TC3589X is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_MFD_ARIZONA_I2C is not set
+# CONFIG_MFD_ARIZONA_SPI is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X_I2C is not set
+# CONFIG_MFD_WM831X_SPI is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+CONFIG_FB_SYS_FILLRECT=m
+CONFIG_FB_SYS_COPYAREA=m
+CONFIG_FB_SYS_IMAGEBLIT=m
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+CONFIG_FB_SYS_FOPS=m
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_SMSCUFX is not set
+# CONFIG_FB_UDL is not set
+# CONFIG_FB_GOLDFISH is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+CONFIG_FB_AMBARELLA=m
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_FB_AUO_K190X is not set
+# CONFIG_FB_SIMPLE is not set
+# CONFIG_EXYNOS_VIDEO is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=m
+# CONFIG_BACKLIGHT_ADP8860 is not set
+# CONFIG_BACKLIGHT_ADP8870 is not set
+# CONFIG_BACKLIGHT_LM3630 is not set
+# CONFIG_BACKLIGHT_LM3639 is not set
+# CONFIG_BACKLIGHT_LP855X is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=m
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_FONT_AUTOSELECT=y
+# CONFIG_LOGO is not set
+# CONFIG_FB_SSD1307 is not set
+CONFIG_SOUND=m
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_COMPRESS_OFFLOAD=m
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
+# CONFIG_SND_USB_CAIAQ is not set
+# CONFIG_SND_USB_6FIRE is not set
+CONFIG_SND_SOC=m
+CONFIG_SND_SOC_DMAENGINE_PCM=y
+CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
+CONFIG_SND_AMBARELLA_SOC=m
+CONFIG_SND_AMBARELLA_SOC_I2S=m
+CONFIG_SND_AMBARELLA_BOARD=m
+CONFIG_AMBA_BOARD=m
+CONFIG_SND_AMBARELLA_CODEC=m
+CONFIG_SND_SOC_AK4642_AMB=m
+CONFIG_SND_SOC_AK4951_AMB=m
+CONFIG_SND_SOC_AK4954_AMB=m
+# CONFIG_SND_SOC_AK7719_DSP is not set
+# CONFIG_SND_SOC_AK7755 is not set
+# CONFIG_SND_SOC_TLV320ADC3xxx is not set
+CONFIG_SND_SOC_ES8388=m
+# CONFIG_SND_SOC_ES8374 is not set
+# CONFIG_SND_SOC_WM8974_AMB is not set
+# CONFIG_SND_SOC_WM8940_AMB is not set
+# CONFIG_SND_SOC_ZL380TW is not set
+# CONFIG_SND_SOC_RT5670 is not set
+CONFIG_SND_SOC_AMBARELLA_DUMMY=m
+# CONFIG_SND_ATMEL_SOC is not set
+CONFIG_SND_SOC_I2C_AND_SPI=m
+# CONFIG_SND_SOC_ALL_CODECS is not set
+# CONFIG_SND_SIMPLE_CARD is not set
+# CONFIG_SOUND_PRIME is not set
+
+#
+# HID support
+#
+CONFIG_HID=m
+# CONFIG_HIDRAW is not set
+# CONFIG_UHID is not set
+CONFIG_HID_GENERIC=m
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=m
+# CONFIG_HID_ACRUX is not set
+CONFIG_HID_APPLE=m
+# CONFIG_HID_APPLEIR is not set
+# CONFIG_HID_AUREAL is not set
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+# CONFIG_HID_PRODIKEYS is not set
+CONFIG_HID_CYPRESS=m
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_ELECOM is not set
+CONFIG_HID_EZKEY=m
+# CONFIG_HID_HOLTEK is not set
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_ICADE is not set
+# CONFIG_HID_TWINHAN is not set
+CONFIG_HID_KENSINGTON=m
+# CONFIG_HID_LCPOWER is not set
+# CONFIG_HID_LENOVO_TPKBD is not set
+CONFIG_HID_LOGITECH=m
+# CONFIG_HID_LOGITECH_DJ is not set
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
+# CONFIG_LOGIWHEELS_FF is not set
+# CONFIG_HID_MAGICMOUSE is not set
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_PRIMAX is not set
+# CONFIG_HID_PS3REMOTE is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_SAITEK is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SPEEDLINK is not set
+# CONFIG_HID_STEELSERIES is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TIVO is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+# CONFIG_HID_SENSOR_HUB is not set
+
+#
+# USB HID support
+#
+CONFIG_USB_HID=m
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# I2C HID support
+#
+# CONFIG_I2C_HID is not set
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB_ARCH_HAS_XHCI is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEFAULT_PERSIST is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_EHCI_AMBARELLA=m
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_OHCI_AMBARELLA=y
+# CONFIG_USB_OHCI_HCD_PLATFORM is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_RENESAS_USBHS is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_REALTEK is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_STORAGE_ENE_UB6250 is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_DWC3 is not set
+# CONFIG_USB_CHIPIDEA is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_U1960 is not set
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP210X is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_F81232 is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_METRO is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QCAUX is not set
+# CONFIG_USB_SERIAL_QUALCOMM is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_SYMBOL is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
+# CONFIG_USB_SERIAL_XSENS_MT is not set
+# CONFIG_USB_SERIAL_ZIO is not set
+# CONFIG_USB_SERIAL_WISHBONE is not set
+# CONFIG_USB_SERIAL_ZTE is not set
+# CONFIG_USB_SERIAL_SSU100 is not set
+# CONFIG_USB_SERIAL_QT2 is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_EHSET_TEST_FIXTURE is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_YUREX is not set
+# CONFIG_USB_EZUSB_FX2 is not set
+# CONFIG_USB_HSIC_USB3503 is not set
+CONFIG_USB_PHY=y
+CONFIG_USB_AMBARELLA_PHY=y
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_OMAP_CONTROL_USB is not set
+# CONFIG_OMAP_USB3 is not set
+# CONFIG_SAMSUNG_USBPHY is not set
+# CONFIG_SAMSUNG_USB2PHY is not set
+# CONFIG_SAMSUNG_USB3PHY is not set
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ISP1301 is not set
+# CONFIG_USB_RCAR_PHY is not set
+# CONFIG_USB_ULPI is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
+
+#
+# USB Peripheral Controller
+#
+# CONFIG_USB_FUSB300 is not set
+# CONFIG_USB_R8A66597 is not set
+# CONFIG_USB_PXA27X is not set
+# CONFIG_USB_MV_UDC is not set
+# CONFIG_USB_MV_U3D is not set
+# CONFIG_USB_M66592 is not set
+# CONFIG_USB_NET2272 is not set
+CONFIG_USB_AMBARELLA=m
+CONFIG_USB_LIBCOMPOSITE=m
+CONFIG_USB_F_ACM=m
+CONFIG_USB_U_SERIAL=m
+CONFIG_USB_F_SERIAL=m
+CONFIG_USB_F_OBEX=m
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
+# CONFIG_USB_G_NCM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FUNCTIONFS is not set
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_AMB_STREAM is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_ACM_MS is not set
+CONFIG_USB_G_MULTI=m
+CONFIG_USB_G_MULTI_RNDIS=y
+# CONFIG_USB_G_MULTI_CDC is not set
+# CONFIG_USB_G_HID is not set
+# CONFIG_USB_G_DBGP is not set
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+# CONFIG_MMC_CLKGATE is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_BLOCK_MINORS=32
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_AMBARELLA=m
+# CONFIG_AMBARELLA_EMMC_BOOT is not set
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MMC_DW is not set
+# CONFIG_MMC_VUB300 is not set
+# CONFIG_MMC_USHC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_EDAC is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_SYSTOHC=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS3232 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+CONFIG_RTC_DRV_ISL12022=y
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8523 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+# CONFIG_RTC_DRV_EM3027 is not set
+# CONFIG_RTC_DRV_RV3029C2 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T93 is not set
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+# CONFIG_RTC_DRV_RX4581 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+# CONFIG_RTC_DRV_DS2404 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_AMBARELLA=y
+# CONFIG_RTC_DRV_SNVS is not set
+
+#
+# HID Sensor RTC drivers
+#
+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
+CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+# CONFIG_DW_DMAC is not set
+# CONFIG_TIMB_DMA is not set
+CONFIG_AMBARELLA_DMA=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+
+#
+# DMA Clients
+#
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_VIRT_DRIVERS is not set
+
+#
+# Virtio drivers
+#
+# CONFIG_VIRTIO_MMIO is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+# CONFIG_STAGING is not set
+
+#
+# Hardware Spinlock drivers
+#
+# CONFIG_MAILBOX is not set
+# CONFIG_IOMMU_SUPPORT is not set
+
+#
+# Remoteproc drivers
+#
+# CONFIG_STE_MODEM_RPROC is not set
+# CONFIG_RPROC_SUPPORT is not set
+# CONFIG_RPCLNT_SUPPORT is not set
+
+#
+# Rpmsg drivers
+#
+# CONFIG_PM_DEVFREQ is not set
+# CONFIG_EXTCON is not set
+# CONFIG_MEMORY is not set
+# CONFIG_IIO is not set
+CONFIG_PWM=y
+CONFIG_PWM_AMBARELLA=m
+CONFIG_IRQCHIP=y
+CONFIG_AMBARELLA_VIC=y
+# CONFIG_IPACK_BUS is not set
+# CONFIG_RESET_CONTROLLER is not set
+
+#
+# File systems
+#
+CONFIG_DCACHE_WORD_ACCESS=y
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_USE_FOR_EXT23=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_EXPORTFS=y
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_TMPFS_XATTR=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+CONFIG_SQUASHFS=y
+# CONFIG_SQUASHFS_XATTR is not set
+CONFIG_SQUASHFS_ZLIB=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX6FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_PSTORE is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_F2FS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V2=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_SWAP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_DEBUG is not set
+# CONFIG_CEPH_FS is not set
+CONFIG_CIFS=y
+CONFIG_CIFS_STATS=y
+# CONFIG_CIFS_STATS2 is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+CONFIG_CIFS_DEBUG=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_SMB2 is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_MAC_ROMAN is not set
+# CONFIG_NLS_MAC_CELTIC is not set
+# CONFIG_NLS_MAC_CENTEURO is not set
+# CONFIG_NLS_MAC_CROATIAN is not set
+# CONFIG_NLS_MAC_CYRILLIC is not set
+# CONFIG_NLS_MAC_GAELIC is not set
+# CONFIG_NLS_MAC_GREEK is not set
+# CONFIG_NLS_MAC_ICELAND is not set
+# CONFIG_NLS_MAC_INUIT is not set
+# CONFIG_NLS_MAC_ROMANIAN is not set
+# CONFIG_NLS_MAC_TURKISH is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_PANIC_ON_OOPS is not set
+CONFIG_PANIC_ON_OOPS_VALUE=0
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+
+#
+# RCU Debugging
+#
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_LKDTM is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+CONFIG_DYNAMIC_DEBUG=y
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_TEST_STRING_HELPERS is not set
+# CONFIG_TEST_KSTRTOX is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
+CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"
+# CONFIG_PID_IN_CONTEXTIDR is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_USER is not set
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_CMAC is not set
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_CRC32 is not set
+# CONFIG_CRYPTO_GHASH is not set
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA1_ARM is not set
+CONFIG_CRYPTO_SHA256=y
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_AES_ARM is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_USER_API=y
+CONFIG_CRYPTO_USER_API_HASH=y
+CONFIG_CRYPTO_USER_API_SKCIPHER=y
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_DEV_AMBARELLA=m
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_IO=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC32_SELFTEST is not set
+CONFIG_CRC32_SLICEBY8=y
+# CONFIG_CRC32_SLICEBY4 is not set
+# CONFIG_CRC32_SARWATE is not set
+# CONFIG_CRC32_BIT is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+# CONFIG_CRC8 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_XZ_DEC=y
+# CONFIG_XZ_DEC_X86 is not set
+# CONFIG_XZ_DEC_POWERPC is not set
+# CONFIG_XZ_DEC_IA64 is not set
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+# CONFIG_XZ_DEC_SPARC is not set
+CONFIG_XZ_DEC_BCJ=y
+# CONFIG_XZ_DEC_TEST is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_XZ=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_BCH=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_DQL=y
+CONFIG_NLATTR=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+CONFIG_AVERAGE=y
+# CONFIG_CORDIC is not set
+# CONFIG_DDR is not set
+# CONFIG_VIRTUALIZATION is not set
diff --git a/arch/arm/configs/ambarella_s3_defconfig b/arch/arm/configs/ambarella_s3_defconfig
new file mode 100644
index 00000000..c1b22151
--- /dev/null
+++ b/arch/arm/configs/ambarella_s3_defconfig
@@ -0,0 +1,2554 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/arm 3.10.0 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_NEED_MACH_GPIO_H=y
+CONFIG_NEED_MACH_IO_H=y
+CONFIG_NEED_MACH_MEMORY_H=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_IRQ_WORK=y
+CONFIG_BUILDTIME_EXTABLE_SORT=y
+
+#
+# General setup
+#
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_XZ is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_DEFAULT_HOSTNAME="Ambarella"
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_FHANDLE=y
+# CONFIG_AUDIT is not set
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_ARCH_HAS_TICK_BROADCAST=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+
+#
+# Timers subsystem
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ_COMMON=y
+# CONFIG_HZ_PERIODIC is not set
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+
+#
+# CPU/Task time and stats accounting
+#
+CONFIG_TICK_CPU_ACCOUNTING=y
+# CONFIG_IRQ_TIME_ACCOUNTING is not set
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_PREEMPT_RCU=y
+CONFIG_PREEMPT_RCU=y
+CONFIG_RCU_STALL_COMMON=y
+# CONFIG_RCU_USER_QS is not set
+CONFIG_RCU_FANOUT=32
+CONFIG_RCU_FANOUT_LEAF=16
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_RCU_BOOST is not set
+# CONFIG_RCU_NOCB_CPU is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+# CONFIG_CGROUP_FREEZER is not set
+# CONFIG_CGROUP_DEVICE is not set
+# CONFIG_CPUSETS is not set
+# CONFIG_CGROUP_CPUACCT is not set
+# CONFIG_RESOURCE_COUNTERS is not set
+CONFIG_CGROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_CFS_BANDWIDTH is not set
+# CONFIG_RT_GROUP_SCHED is not set
+# CONFIG_BLK_CGROUP is not set
+# CONFIG_CHECKPOINT_RESTORE is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_NET_NS=y
+CONFIG_UIDGID_CONVERTED=y
+# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_XZ=y
+CONFIG_RD_LZO=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_HAVE_UID16=y
+CONFIG_HOTPLUG=y
+# CONFIG_EXPERT is not set
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+# CONFIG_EMBEDDED is not set
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_JUMP_LABEL is not set
+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_OLD_SIGACTION=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_MODULE_SIG is not set
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_BSGLIB is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_AMBPTB_PARTITION=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y
+CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_LOCK=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y
+CONFIG_ARCH_INLINE_READ_TRYLOCK=y
+CONFIG_ARCH_INLINE_READ_LOCK=y
+CONFIG_ARCH_INLINE_READ_LOCK_BH=y
+CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_READ_UNLOCK=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y
+CONFIG_ARCH_INLINE_WRITE_TRYLOCK=y
+CONFIG_ARCH_INLINE_WRITE_LOCK=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_SPIN_TRYLOCK=y
+CONFIG_INLINE_SPIN_TRYLOCK_BH=y
+CONFIG_INLINE_SPIN_LOCK=y
+CONFIG_INLINE_SPIN_LOCK_BH=y
+CONFIG_INLINE_SPIN_LOCK_IRQ=y
+CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y
+CONFIG_INLINE_SPIN_UNLOCK_BH=y
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_READ_TRYLOCK=y
+CONFIG_INLINE_READ_LOCK=y
+CONFIG_INLINE_READ_LOCK_BH=y
+CONFIG_INLINE_READ_LOCK_IRQ=y
+CONFIG_INLINE_READ_LOCK_IRQSAVE=y
+CONFIG_INLINE_READ_UNLOCK=y
+CONFIG_INLINE_READ_UNLOCK_BH=y
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_WRITE_TRYLOCK=y
+CONFIG_INLINE_WRITE_LOCK=y
+CONFIG_INLINE_WRITE_LOCK_BH=y
+CONFIG_INLINE_WRITE_LOCK_IRQ=y
+CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y
+CONFIG_INLINE_WRITE_UNLOCK=y
+CONFIG_INLINE_WRITE_UNLOCK_BH=y
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_MULTIPLATFORM is not set
+CONFIG_ARCH_AMBARELLA=y
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_LPC32XX is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C24XX is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P64X0 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_EXYNOS is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP1 is not set
+CONFIG_PLAT_AMBARELLA=y
+
+#
+# Ambarella Platform
+#
+CONFIG_PLAT_AMBARELLA_SUPPORT_VIC=y
+# CONFIG_PLAT_AMBARELLA_HAVE_ARM11 is not set
+CONFIG_PLAT_AMBARELLA_CORTEX=y
+CONFIG_PLAT_AMBARELLA_CORTEX_SMP=y
+CONFIG_PLAT_AMBARELLA_LOCAL_TIMERS=y
+CONFIG_PLAT_AMBARELLA_SUPPORT_PM=y
+CONFIG_PLAT_AMBARELLA_MEM_START_LOW=y
+CONFIG_PLAT_AMBARELLA_AHB_APB_HIGH=y
+CONFIG_PLAT_AMBARELLA_SUPPORT_HW_CRYPTO=y
+CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI=y
+CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC=y
+# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64 is not set
+CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS=y
+# CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_RPROC is not set
+# CONFIG_PLAT_AMBARELLA_S2 is not set
+# CONFIG_PLAT_AMBARELLA_A8 is not set
+# CONFIG_PLAT_AMBARELLA_A5S is not set
+# CONFIG_PLAT_AMBARELLA_A7L is not set
+# CONFIG_PLAT_AMBARELLA_S2_ARM11 is not set
+# CONFIG_PLAT_AMBARELLA_S2_CORTEX is not set
+# CONFIG_PLAT_AMBARELLA_S2E is not set
+# CONFIG_PLAT_AMBARELLA_A8_ARM11 is not set
+# CONFIG_PLAT_AMBARELLA_A8_CORTEX is not set
+# CONFIG_PLAT_AMBARELLA_S2L is not set
+CONFIG_PLAT_AMBARELLA_S3=y
+
+#
+# Generic Platform Configuration
+#
+# CONFIG_AMBARELLA_RAW_BOOT is not set
+CONFIG_AMBARELLA_SUPPORT_BAPI=y
+# CONFIG_AMBARELLA_PMUSERENR_EN is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_GDMA is not set
+
+#
+# Sys file system support
+#
+CONFIG_AMBARELLA_SYS_CACHE_CALL=y
+# CONFIG_AMBARELLA_SYS_BAPI_CALL is not set
+
+#
+# Proc file system support
+#
+CONFIG_AMBARELLA_PLL_PROC=y
+# CONFIG_AMBARELLA_SUPPORT_AMBENCH is not set
+
+#
+# Memory Configuration
+#
+CONFIG_AMBARELLA_PPM_SIZE=0x00200000
+CONFIG_AMBARELLA_ZRELADDR=0x00208000
+CONFIG_AMBARELLA_TEXTOFS=0x00008000
+CONFIG_AMBARELLA_PARAMS_PHYS=0x00200100
+CONFIG_AMBARELLA_INITRD_PHYS=0x00A00000
+# CONFIG_AMBARELLA_IO_MAP is not set
+# CONFIG_AMBARELLA_PPM_UNCACHED is not set
+CONFIG_AMBARELLA_TIMER_HZ=100
+CONFIG_AMBARELLA_TIMER_HIGHRES=y
+CONFIG_AMBARELLA_EXT_IRQ_NUM=16
+CONFIG_AMBARELLA_EXT_GPIO_NUM=16
+CONFIG_GPIO_PCA953X=y
+# CONFIG_KEYBOARD_GPIO_POLLED is not set
+# CONFIG_PLAT_SPEAR is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_LPAE is not set
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_ARM_VIRT_EXT=y
+# CONFIG_SWP_EMULATE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_CACHE_L2X0=y
+CONFIG_CACHE_PL310=y
+# CONFIG_CACHE_PL310_EARLY_BRESP is not set
+CONFIG_CACHE_PL310_PREFETCH_OFFSET=0
+# CONFIG_CACHE_PL310_FULL_LINE_OF_ZERO is not set
+# CONFIG_CACHE_PL310_DOUBLE_LINEFILL is not set
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_NR_BANKS=8
+CONFIG_MULTI_IRQ_HANDLER=y
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+# CONFIG_ARM_ERRATA_742230 is not set
+# CONFIG_ARM_ERRATA_742231 is not set
+CONFIG_PL310_ERRATA_588369=y
+# CONFIG_ARM_ERRATA_643719 is not set
+# CONFIG_ARM_ERRATA_720789 is not set
+CONFIG_PL310_ERRATA_727915=y
+# CONFIG_ARM_ERRATA_743622 is not set
+# CONFIG_ARM_ERRATA_751472 is not set
+# CONFIG_PL310_ERRATA_753970 is not set
+# CONFIG_ARM_ERRATA_754322 is not set
+# CONFIG_ARM_ERRATA_754327 is not set
+CONFIG_ARM_ERRATA_764369=y
+# CONFIG_PL310_ERRATA_769419 is not set
+# CONFIG_ARM_ERRATA_775420 is not set
+# CONFIG_ARM_ERRATA_798181 is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_HAVE_SMP=y
+CONFIG_SMP=y
+CONFIG_SMP_ON_UP=y
+CONFIG_ARM_CPU_TOPOLOGY=y
+# CONFIG_SCHED_MC is not set
+# CONFIG_SCHED_SMT is not set
+CONFIG_HAVE_ARM_SCU=y
+# CONFIG_HAVE_ARM_ARCH_TIMER is not set
+# CONFIG_MCPM is not set
+# CONFIG_VMSPLIT_3G is not set
+CONFIG_VMSPLIT_2G=y
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_NR_CPUS=2
+CONFIG_HOTPLUG_CPU=y
+# CONFIG_ARM_PSCI is not set
+CONFIG_LOCAL_TIMERS=y
+CONFIG_ARCH_NR_GPIO=0
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_COUNT=y
+CONFIG_HZ=100
+CONFIG_SCHED_HRTICK=y
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=y
+# CONFIG_HIGHMEM is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_COMPACTION is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_CROSS_MEMORY_ATTACH is not set
+# CONFIG_CLEANCACHE is not set
+# CONFIG_FRONTSWAP is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+# CONFIG_SECCOMP is not set
+CONFIG_CC_STACKPROTECTOR=y
+# CONFIG_XEN is not set
+
+#
+# Boot options
+#
+CONFIG_USE_OF=y
+CONFIG_ATAGS=y
+# CONFIG_DEPRECATED_PARAM_STRUCT is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_ARM_APPENDED_DTB is not set
+CONFIG_CMDLINE="console=ttyS0"
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
+# CONFIG_CMDLINE_EXTEND is not set
+# CONFIG_CMDLINE_FORCE is not set
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_AUTO_ZRELADDR is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_SCRIPT=y
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_COREDUMP=y
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
+CONFIG_PM_SLEEP=y
+CONFIG_PM_SLEEP_SMP=y
+# CONFIG_PM_AUTOSLEEP is not set
+# CONFIG_PM_WAKELOCKS is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_CLK=y
+CONFIG_CPU_PM=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_DIAG is not set
+CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=y
+CONFIG_XFRM=y
+CONFIG_XFRM_ALGO=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+# CONFIG_IP_FIB_TRIE_STATS is not set
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
+# CONFIG_NET_IP_TUNNEL is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+# CONFIG_BRIDGE is not set
+CONFIG_HAVE_NET_DSA=y
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_OPENVSWITCH is not set
+# CONFIG_VSOCKETS is not set
+# CONFIG_NETLINK_MMAP is not set
+# CONFIG_NETLINK_DIAG is not set
+CONFIG_RPS=y
+CONFIG_RFS_ACCEL=y
+CONFIG_XPS=y
+# CONFIG_NETPRIO_CGROUP is not set
+CONFIG_BQL=y
+# CONFIG_BPF_JIT is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+# CONFIG_BT_HIDP is not set
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIBTUSB=m
+CONFIG_BT_HCIBTSDIO=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+# CONFIG_BT_HCIUART_ATH3K is not set
+CONFIG_BT_HCIUART_LL=y
+# CONFIG_BT_HCIUART_3WIRE is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_BT_MRVL is not set
+# CONFIG_BT_ATH3K is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_CFG80211=m
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+CONFIG_CFG80211_DEBUGFS=y
+# CONFIG_CFG80211_INTERNAL_REGDB is not set
+CONFIG_CFG80211_WEXT=y
+# CONFIG_LIB80211 is not set
+CONFIG_MAC80211=m
+CONFIG_MAC80211_HAS_RC=y
+CONFIG_MAC80211_RC_MINSTREL=y
+CONFIG_MAC80211_RC_MINSTREL_HT=y
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
+# CONFIG_MAC80211_MESH is not set
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_MESSAGE_TRACING is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
+CONFIG_RFKILL=m
+CONFIG_RFKILL_INPUT=y
+# CONFIG_RFKILL_GPIO is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+# CONFIG_NFC is not set
+CONFIG_HAVE_BPF_JIT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH=""
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+CONFIG_FW_LOADER_USER_HELPER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_GENERIC_CPU_DEVICES is not set
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=m
+CONFIG_REGMAP_SPI=m
+# CONFIG_DMA_SHARED_BUFFER is not set
+# CONFIG_CMA is not set
+
+#
+# Bus devices
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_BLKDEVS=y
+# CONFIG_MTD_BLOCK is not set
+# CONFIG_MTD_BLOCK_RO is not set
+CONFIG_MTD_BLOCK_AMBRO=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+# CONFIG_MTD_SWAP is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_AMBARELLA_SPI_NOR is not set
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOCG3 is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_BCH=y
+CONFIG_MTD_NAND_ECC_BCH=y
+# CONFIG_MTD_SM_COMMON is not set
+CONFIG_MTD_NAND_AMBARELLA=y
+# CONFIG_MTD_NAND_DENALI is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_DOCG4 is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_LIMIT=20
+# CONFIG_MTD_UBI_FASTMAP is not set
+# CONFIG_MTD_UBI_GLUEBI is not set
+CONFIG_DTC=y
+CONFIG_OF=y
+
+#
+# Device Tree and Open Firmware support
+#
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_OF_SELFTEST is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_DEVICE=y
+CONFIG_OF_I2C=y
+CONFIG_OF_NET=y
+CONFIG_OF_MDIO=m
+CONFIG_OF_MTD=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_BLK_DEV_XIP=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_BLK_DEV_RBD is not set
+
+#
+# Misc devices
+#
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ATMEL_PWM is not set
+# CONFIG_DUMMY_IRQ is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ATMEL_SSC is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_APDS9802ALS is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_ISL29020 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_BH1780 is not set
+# CONFIG_SENSORS_BH1770 is not set
+# CONFIG_SENSORS_APDS990X is not set
+# CONFIG_HMC6352 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_BMP085_I2C is not set
+# CONFIG_BMP085_SPI is not set
+# CONFIG_USB_SWITCH_FSA9480 is not set
+# CONFIG_LATTICE_ECP3_CONFIG is not set
+# CONFIG_SRAM is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_EEPROM_93XX46 is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_TI_ST is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+
+#
+# Altera FPGA firmware download module
+#
+# CONFIG_ALTERA_STAPL is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=m
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_ISCSI_BOOT_SYSFS is not set
+# CONFIG_SCSI_UFSHCD is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_TARGET_CORE is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_CORE=y
+# CONFIG_BONDING is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_MII=y
+# CONFIG_NET_TEAM is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_VXLAN is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+
+#
+# CAIF transport drivers
+#
+
+#
+# Distributed Switch Architecture drivers
+#
+# CONFIG_NET_DSA_MV88E6XXX is not set
+# CONFIG_NET_DSA_MV88E6060 is not set
+# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
+# CONFIG_NET_DSA_MV88E6131 is not set
+# CONFIG_NET_DSA_MV88E6123_61_65 is not set
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_AMBARELLA=m
+CONFIG_NET_VENDOR_AMBARELLA_INTEN_TUE=y
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_CALXEDA_XGMAC is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_DM9000 is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_ETHOC is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+# CONFIG_AT803X_PHY is not set
+# CONFIG_AMD_PHY is not set
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_BCM87XX_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
+CONFIG_MICREL_PHY_KSZ80X1R=m
+# CONFIG_MDIO_BITBANG is not set
+# CONFIG_MDIO_BUS_MUX_GPIO is not set
+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
+# CONFIG_MICREL_KS8995MA is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_RTL8152 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_HSO is not set
+# CONFIG_USB_IPHETH is not set
+CONFIG_WLAN=y
+# CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_AT76C50X_USB is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_RTL8187 is not set
+# CONFIG_MAC80211_HWSIM is not set
+CONFIG_ATH_CARDS=m
+# CONFIG_ATH_DEBUG is not set
+# CONFIG_ATH9K is not set
+# CONFIG_ATH9K_HTC is not set
+# CONFIG_CARL9170 is not set
+CONFIG_ATH6KL=m
+CONFIG_ATH6KL_SDIO=m
+# CONFIG_ATH6KL_USB is not set
+# CONFIG_ATH6KL_DEBUG is not set
+# CONFIG_AR5523 is not set
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_BRCMFMAC is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_P54_COMMON is not set
+# CONFIG_RT2X00 is not set
+# CONFIG_RTLWIFI is not set
+# CONFIG_WL_TI is not set
+# CONFIG_ZD1211RW is not set
+CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
+# CONFIG_MWIFIEX_USB is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+# CONFIG_INPUT_MATRIXKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ADP5589 is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_QT1070 is not set
+# CONFIG_KEYBOARD_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_GPIO=m
+# CONFIG_KEYBOARD_TCA6416 is not set
+# CONFIG_KEYBOARD_TCA8418 is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8333 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_MCS is not set
+# CONFIG_KEYBOARD_MPR121 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_SAMSUNG is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_BMA150 is not set
+CONFIG_INPUT_AMBARELLA_IR=m
+CONFIG_INPUT_AMBARELLA_ADC=m
+# CONFIG_INPUT_MMA8450 is not set
+# CONFIG_INPUT_MPU3050 is not set
+# CONFIG_INPUT_GP2A is not set
+# CONFIG_INPUT_GPIO_TILT_POLLED is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_KXTJ9 is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+CONFIG_INPUT_UINPUT=m
+# CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_PWM_BEEPER is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_CMA3000 is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_TTY=y
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_CONSOLE_SLEEP=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+# CONFIG_DEVKMEM is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AMBARELLA=y
+CONFIG_SERIAL_AMBARELLA_CONSOLE=y
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX310X is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_SCCNXP is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_IFX6X60 is not set
+# CONFIG_SERIAL_XILINX_PS_UART is not set
+# CONFIG_SERIAL_ARC is not set
+# CONFIG_HVC_DCC is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=m
+# CONFIG_I2C_MUX is not set
+# CONFIG_I2C_HELPER_AUTO is not set
+# CONFIG_I2C_SMBUS is not set
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_AMBARELLA=y
+# CONFIG_I2C_CBUS_GPIO is not set
+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_DIOLAN_U2C is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_SLAVE=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+CONFIG_SPI_AMBARELLA=m
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_FSL_SPI is not set
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_SC18IS602 is not set
+# CONFIG_SPI_XCOMM is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=m
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# SPI Slave Controller Drivers
+#
+CONFIG_SPI_SLAVE_AMBARELLA=m
+
+#
+# Qualcomm MSM SSBI bus support
+#
+# CONFIG_SSBI is not set
+# CONFIG_HSI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+# CONFIG_PTP_1588_CLOCK is not set
+
+#
+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
+#
+# CONFIG_PTP_1588_CLOCK_PCH is not set
+CONFIG_PINCTRL=y
+
+#
+# Pin controllers
+#
+CONFIG_PINMUX=y
+CONFIG_PINCONF=y
+# CONFIG_DEBUG_PINCTRL is not set
+# CONFIG_PINCTRL_SINGLE is not set
+# CONFIG_PINCTRL_EXYNOS is not set
+# CONFIG_PINCTRL_EXYNOS5440 is not set
+CONFIG_PINCTRL_AMB=y
+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIO_DEVRES=y
+CONFIG_GPIOLIB=y
+CONFIG_OF_GPIO=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_GENERIC_PLATFORM is not set
+# CONFIG_GPIO_EM is not set
+# CONFIG_GPIO_RCAR is not set
+# CONFIG_GPIO_TS5500 is not set
+# CONFIG_GPIO_GRGPIO is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_GPIO_PCF857X=y
+# CONFIG_GPIO_SX150X is not set
+# CONFIG_GPIO_ADP5588 is not set
+# CONFIG_GPIO_ADNP is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+# CONFIG_GPIO_74X164 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+
+#
+# USB GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_POWER_AVS is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AMBARELLA_WATCHDOG=y
+# CONFIG_DW_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_AS3711 is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_AAT2870_CORE is not set
+# CONFIG_MFD_CROS_EC is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_DA9052_SPI is not set
+# CONFIG_MFD_DA9052_I2C is not set
+# CONFIG_MFD_DA9055 is not set
+# CONFIG_MFD_MC13XXX_SPI is not set
+# CONFIG_MFD_MC13XXX_I2C is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_MFD_88PM800 is not set
+# CONFIG_MFD_88PM805 is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_MAX77686 is not set
+# CONFIG_MFD_MAX77693 is not set
+# CONFIG_MFD_MAX8907 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_MAX8997 is not set
+# CONFIG_MFD_MAX8998 is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_VIPERBOARD is not set
+# CONFIG_MFD_RETU is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_RC5T583 is not set
+# CONFIG_MFD_SEC_CORE is not set
+# CONFIG_MFD_SI476X_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SMSC is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_MFD_STMPE is not set
+# CONFIG_MFD_SYSCON is not set
+# CONFIG_MFD_TI_AM335X_TSCADC is not set
+# CONFIG_MFD_LP8788 is not set
+# CONFIG_MFD_PALMAS is not set
+# CONFIG_TPS6105X is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_MFD_TPS65090 is not set
+# CONFIG_MFD_TPS65217 is not set
+# CONFIG_MFD_TPS6586X is not set
+# CONFIG_MFD_TPS65910 is not set
+# CONFIG_MFD_TPS65912 is not set
+# CONFIG_MFD_TPS65912_I2C is not set
+# CONFIG_MFD_TPS65912_SPI is not set
+# CONFIG_MFD_TPS80031 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_TWL6040_CORE is not set
+# CONFIG_MFD_WL1273_CORE is not set
+# CONFIG_MFD_LM3533 is not set
+# CONFIG_MFD_TC3589X is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_MFD_ARIZONA_I2C is not set
+# CONFIG_MFD_ARIZONA_SPI is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X_I2C is not set
+# CONFIG_MFD_WM831X_SPI is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+CONFIG_FB_SYS_FILLRECT=m
+CONFIG_FB_SYS_COPYAREA=m
+CONFIG_FB_SYS_IMAGEBLIT=m
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+CONFIG_FB_SYS_FOPS=m
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_SMSCUFX is not set
+# CONFIG_FB_UDL is not set
+# CONFIG_FB_GOLDFISH is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+CONFIG_FB_AMBARELLA=m
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_FB_AUO_K190X is not set
+# CONFIG_FB_SIMPLE is not set
+# CONFIG_EXYNOS_VIDEO is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=m
+# CONFIG_BACKLIGHT_ADP8860 is not set
+# CONFIG_BACKLIGHT_ADP8870 is not set
+# CONFIG_BACKLIGHT_LM3630 is not set
+# CONFIG_BACKLIGHT_LM3639 is not set
+# CONFIG_BACKLIGHT_LP855X is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=m
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_FONT_AUTOSELECT=y
+# CONFIG_LOGO is not set
+# CONFIG_FB_SSD1307 is not set
+CONFIG_SOUND=m
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_COMPRESS_OFFLOAD=m
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
+# CONFIG_SND_USB_CAIAQ is not set
+# CONFIG_SND_USB_6FIRE is not set
+CONFIG_SND_SOC=m
+CONFIG_SND_SOC_DMAENGINE_PCM=y
+CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
+CONFIG_SND_AMBARELLA_SOC=m
+CONFIG_SND_AMBARELLA_SOC_I2S=m
+CONFIG_SND_AMBARELLA_BOARD=m
+CONFIG_AMBA_BOARD=m
+# CONFIG_SND_ATMEL_SOC is not set
+CONFIG_SND_SOC_I2C_AND_SPI=m
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_AMBARELLA_DUMMY=m
+CONFIG_SND_AMBARELLA_CODEC=m
+CONFIG_SND_SOC_AK4951_AMB=m
+# CONFIG_SND_SIMPLE_CARD is not set
+# CONFIG_SOUND_PRIME is not set
+
+#
+# HID support
+#
+CONFIG_HID=m
+# CONFIG_HIDRAW is not set
+# CONFIG_UHID is not set
+CONFIG_HID_GENERIC=m
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=m
+# CONFIG_HID_ACRUX is not set
+CONFIG_HID_APPLE=m
+# CONFIG_HID_APPLEIR is not set
+# CONFIG_HID_AUREAL is not set
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+# CONFIG_HID_PRODIKEYS is not set
+CONFIG_HID_CYPRESS=m
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_ELECOM is not set
+CONFIG_HID_EZKEY=m
+# CONFIG_HID_HOLTEK is not set
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_ICADE is not set
+# CONFIG_HID_TWINHAN is not set
+CONFIG_HID_KENSINGTON=m
+# CONFIG_HID_LCPOWER is not set
+# CONFIG_HID_LENOVO_TPKBD is not set
+CONFIG_HID_LOGITECH=m
+# CONFIG_HID_LOGITECH_DJ is not set
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
+# CONFIG_LOGIWHEELS_FF is not set
+# CONFIG_HID_MAGICMOUSE is not set
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_PRIMAX is not set
+# CONFIG_HID_PS3REMOTE is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_SAITEK is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SPEEDLINK is not set
+# CONFIG_HID_STEELSERIES is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TIVO is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+# CONFIG_HID_SENSOR_HUB is not set
+
+#
+# USB HID support
+#
+CONFIG_USB_HID=m
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# I2C HID support
+#
+# CONFIG_I2C_HID is not set
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB_ARCH_HAS_XHCI is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEFAULT_PERSIST is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_EHCI_AMBARELLA=y
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_OHCI_AMBARELLA=y
+# CONFIG_USB_OHCI_HCD_PLATFORM is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_RENESAS_USBHS is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_REALTEK is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_STORAGE_ENE_UB6250 is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_DWC3 is not set
+# CONFIG_USB_CHIPIDEA is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_U1960 is not set
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP210X is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_F81232 is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_METRO is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QCAUX is not set
+# CONFIG_USB_SERIAL_QUALCOMM is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_SYMBOL is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
+# CONFIG_USB_SERIAL_XSENS_MT is not set
+# CONFIG_USB_SERIAL_ZIO is not set
+# CONFIG_USB_SERIAL_WISHBONE is not set
+# CONFIG_USB_SERIAL_ZTE is not set
+# CONFIG_USB_SERIAL_SSU100 is not set
+# CONFIG_USB_SERIAL_QT2 is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_YUREX is not set
+# CONFIG_USB_EZUSB_FX2 is not set
+# CONFIG_USB_HSIC_USB3503 is not set
+CONFIG_USB_PHY=y
+CONFIG_USB_AMBARELLA_PHY=y
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_OMAP_CONTROL_USB is not set
+# CONFIG_OMAP_USB3 is not set
+# CONFIG_SAMSUNG_USBPHY is not set
+# CONFIG_SAMSUNG_USB2PHY is not set
+# CONFIG_SAMSUNG_USB3PHY is not set
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ISP1301 is not set
+# CONFIG_USB_RCAR_PHY is not set
+# CONFIG_USB_ULPI is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
+
+#
+# USB Peripheral Controller
+#
+# CONFIG_USB_FUSB300 is not set
+# CONFIG_USB_R8A66597 is not set
+# CONFIG_USB_PXA27X is not set
+# CONFIG_USB_MV_UDC is not set
+# CONFIG_USB_MV_U3D is not set
+# CONFIG_USB_M66592 is not set
+# CONFIG_USB_NET2272 is not set
+CONFIG_USB_AMBARELLA=m
+CONFIG_USB_LIBCOMPOSITE=m
+CONFIG_USB_F_ACM=m
+CONFIG_USB_U_SERIAL=m
+CONFIG_USB_F_SERIAL=m
+CONFIG_USB_F_OBEX=m
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
+# CONFIG_USB_G_NCM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FUNCTIONFS is not set
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_ACM_MS is not set
+CONFIG_USB_G_MULTI=m
+CONFIG_USB_G_MULTI_RNDIS=y
+# CONFIG_USB_G_MULTI_CDC is not set
+# CONFIG_USB_G_HID is not set
+# CONFIG_USB_G_DBGP is not set
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+# CONFIG_MMC_CLKGATE is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_BLOCK_MINORS=32
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_AMBARELLA=m
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MMC_DW is not set
+# CONFIG_MMC_VUB300 is not set
+# CONFIG_MMC_USHC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_EDAC is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_SYSTOHC=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS3232 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+CONFIG_RTC_DRV_ISL12022=y
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8523 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+# CONFIG_RTC_DRV_EM3027 is not set
+# CONFIG_RTC_DRV_RV3029C2 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T93 is not set
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+# CONFIG_RTC_DRV_RX4581 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+# CONFIG_RTC_DRV_DS2404 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_AMBARELLA=y
+# CONFIG_RTC_DRV_SNVS is not set
+
+#
+# HID Sensor RTC drivers
+#
+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
+CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+# CONFIG_DW_DMAC is not set
+# CONFIG_TIMB_DMA is not set
+CONFIG_AMBARELLA_DMA=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_VIRT_DRIVERS is not set
+
+#
+# Virtio drivers
+#
+# CONFIG_VIRTIO_MMIO is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+# CONFIG_STAGING is not set
+
+#
+# Hardware Spinlock drivers
+#
+# CONFIG_MAILBOX is not set
+# CONFIG_IOMMU_SUPPORT is not set
+
+#
+# Remoteproc drivers
+#
+# CONFIG_STE_MODEM_RPROC is not set
+# CONFIG_RPROC_SUPPORT is not set
+# CONFIG_RPCLNT_SUPPORT is not set
+
+#
+# Rpmsg drivers
+#
+# CONFIG_PM_DEVFREQ is not set
+# CONFIG_EXTCON is not set
+# CONFIG_MEMORY is not set
+# CONFIG_IIO is not set
+CONFIG_PWM=y
+CONFIG_PWM_AMBARELLA=m
+CONFIG_IRQCHIP=y
+CONFIG_AMBARELLA_VIC=y
+# CONFIG_IPACK_BUS is not set
+# CONFIG_RESET_CONTROLLER is not set
+
+#
+# File systems
+#
+CONFIG_DCACHE_WORD_ACCESS=y
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+CONFIG_EXT4_FS=m
+CONFIG_EXT4_USE_FOR_EXT23=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD2=m
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=m
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_EXPORTFS=y
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_TMPFS_XATTR=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+CONFIG_SQUASHFS=y
+# CONFIG_SQUASHFS_XATTR is not set
+CONFIG_SQUASHFS_ZLIB=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX6FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_PSTORE is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_F2FS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V2=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_SWAP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_DEBUG is not set
+# CONFIG_CEPH_FS is not set
+CONFIG_CIFS=y
+CONFIG_CIFS_STATS=y
+# CONFIG_CIFS_STATS2 is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+CONFIG_CIFS_DEBUG=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_SMB2 is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_MAC_ROMAN is not set
+# CONFIG_NLS_MAC_CELTIC is not set
+# CONFIG_NLS_MAC_CENTEURO is not set
+# CONFIG_NLS_MAC_CROATIAN is not set
+# CONFIG_NLS_MAC_CYRILLIC is not set
+# CONFIG_NLS_MAC_GAELIC is not set
+# CONFIG_NLS_MAC_GREEK is not set
+# CONFIG_NLS_MAC_ICELAND is not set
+# CONFIG_NLS_MAC_INUIT is not set
+# CONFIG_NLS_MAC_ROMANIAN is not set
+# CONFIG_NLS_MAC_TURKISH is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_READABLE_ASM is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+# CONFIG_LOCKUP_DETECTOR is not set
+# CONFIG_PANIC_ON_OOPS is not set
+CONFIG_PANIC_ON_OOPS_VALUE=0
+# CONFIG_DETECT_HUNG_TASK is not set
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+# CONFIG_DEBUG_KMEMLEAK is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_ATOMIC_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_TEST_LIST_SORT is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+
+#
+# RCU Debugging
+#
+# CONFIG_PROVE_RCU_DELAY is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=21
+CONFIG_RCU_CPU_STALL_VERBOSE=y
+# CONFIG_RCU_CPU_STALL_INFO is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_DEBUG_PER_CPU_MAPS is not set
+# CONFIG_LKDTM is not set
+# CONFIG_NOTIFIER_ERROR_INJECTION is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_RBTREE_TEST is not set
+# CONFIG_INTERVAL_TREE_TEST is not set
+CONFIG_DYNAMIC_DEBUG=y
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_TEST_STRING_HELPERS is not set
+# CONFIG_TEST_KSTRTOX is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_LL is not set
+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
+CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"
+# CONFIG_PID_IN_CONTEXTIDR is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_USER is not set
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_CMAC is not set
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_CRC32 is not set
+# CONFIG_CRYPTO_GHASH is not set
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA1_ARM is not set
+CONFIG_CRYPTO_SHA256=y
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_AES_ARM is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_USER_API=y
+CONFIG_CRYPTO_USER_API_HASH=y
+CONFIG_CRYPTO_USER_API_SKCIPHER=y
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_DEV_AMBARELLA=m
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_IO=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC32_SELFTEST is not set
+CONFIG_CRC32_SLICEBY8=y
+# CONFIG_CRC32_SLICEBY4 is not set
+# CONFIG_CRC32_SARWATE is not set
+# CONFIG_CRC32_BIT is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+# CONFIG_CRC8 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_XZ_DEC=y
+# CONFIG_XZ_DEC_X86 is not set
+# CONFIG_XZ_DEC_POWERPC is not set
+# CONFIG_XZ_DEC_IA64 is not set
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+# CONFIG_XZ_DEC_SPARC is not set
+CONFIG_XZ_DEC_BCJ=y
+# CONFIG_XZ_DEC_TEST is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_XZ=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_BCH=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_CPU_RMAP=y
+CONFIG_DQL=y
+CONFIG_NLATTR=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+CONFIG_AVERAGE=y
+# CONFIG_CORDIC is not set
+# CONFIG_DDR is not set
+# CONFIG_VIRTUALIZATION is not set
diff --git a/arch/arm/configs/ambarella_s3l_defconfig b/arch/arm/configs/ambarella_s3l_defconfig
new file mode 100644
index 00000000..4bc220eb
--- /dev/null
+++ b/arch/arm/configs/ambarella_s3l_defconfig
@@ -0,0 +1,2763 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/arm 3.10.73 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_NEED_MACH_GPIO_H=y
+CONFIG_NEED_MACH_IO_H=y
+CONFIG_NEED_MACH_MEMORY_H=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_IRQ_WORK=y
+CONFIG_BUILDTIME_EXTABLE_SORT=y
+
+#
+# General setup
+#
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_XZ is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_DEFAULT_HOSTNAME="Ambarella"
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_FHANDLE=y
+# CONFIG_AUDIT is not set
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# Timers subsystem
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ_COMMON=y
+# CONFIG_HZ_PERIODIC is not set
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+
+#
+# CPU/Task time and stats accounting
+#
+CONFIG_TICK_CPU_ACCOUNTING=y
+# CONFIG_IRQ_TIME_ACCOUNTING is not set
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_TREE_PREEMPT_RCU is not set
+CONFIG_TINY_PREEMPT_RCU=y
+CONFIG_PREEMPT_RCU=y
+# CONFIG_RCU_STALL_COMMON is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_RCU_BOOST is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+# CONFIG_CGROUP_FREEZER is not set
+# CONFIG_CGROUP_DEVICE is not set
+# CONFIG_CPUSETS is not set
+# CONFIG_CGROUP_CPUACCT is not set
+# CONFIG_RESOURCE_COUNTERS is not set
+CONFIG_CGROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_CFS_BANDWIDTH is not set
+# CONFIG_RT_GROUP_SCHED is not set
+# CONFIG_BLK_CGROUP is not set
+# CONFIG_CHECKPOINT_RESTORE is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_NET_NS=y
+CONFIG_UIDGID_CONVERTED=y
+# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_XZ=y
+CONFIG_RD_LZO=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_HAVE_UID16=y
+CONFIG_HOTPLUG=y
+# CONFIG_EXPERT is not set
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+# CONFIG_EMBEDDED is not set
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_JUMP_LABEL is not set
+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_OLD_SIGACTION=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_MODULE_SIG is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_BSGLIB is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_AMBPTB_PARTITION=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y
+CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_LOCK=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y
+CONFIG_ARCH_INLINE_READ_TRYLOCK=y
+CONFIG_ARCH_INLINE_READ_LOCK=y
+CONFIG_ARCH_INLINE_READ_LOCK_BH=y
+CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_READ_UNLOCK=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y
+CONFIG_ARCH_INLINE_WRITE_TRYLOCK=y
+CONFIG_ARCH_INLINE_WRITE_LOCK=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_SPIN_TRYLOCK=y
+CONFIG_INLINE_SPIN_TRYLOCK_BH=y
+CONFIG_INLINE_SPIN_LOCK=y
+CONFIG_INLINE_SPIN_LOCK_BH=y
+CONFIG_INLINE_SPIN_LOCK_IRQ=y
+CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y
+CONFIG_INLINE_SPIN_UNLOCK_BH=y
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_READ_TRYLOCK=y
+CONFIG_INLINE_READ_LOCK=y
+CONFIG_INLINE_READ_LOCK_BH=y
+CONFIG_INLINE_READ_LOCK_IRQ=y
+CONFIG_INLINE_READ_LOCK_IRQSAVE=y
+CONFIG_INLINE_READ_UNLOCK=y
+CONFIG_INLINE_READ_UNLOCK_BH=y
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y
+CONFIG_INLINE_WRITE_TRYLOCK=y
+CONFIG_INLINE_WRITE_LOCK=y
+CONFIG_INLINE_WRITE_LOCK_BH=y
+CONFIG_INLINE_WRITE_LOCK_IRQ=y
+CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y
+CONFIG_INLINE_WRITE_UNLOCK=y
+CONFIG_INLINE_WRITE_UNLOCK_BH=y
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y
+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_MULTIPLATFORM is not set
+CONFIG_ARCH_AMBARELLA=y
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_LPC32XX is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C24XX is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P64X0 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_EXYNOS is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP1 is not set
+CONFIG_PLAT_AMBARELLA=y
+
+#
+# Ambarella Platform
+#
+CONFIG_PLAT_AMBARELLA_SUPPORT_VIC=y
+# CONFIG_PLAT_AMBARELLA_HAVE_ARM11 is not set
+CONFIG_PLAT_AMBARELLA_CORTEX=y
+# CONFIG_PLAT_AMBARELLA_CORTEX_SMP is not set
+CONFIG_PLAT_AMBARELLA_SUPPORT_PM=y
+CONFIG_PLAT_AMBARELLA_MEM_START_LOW=y
+CONFIG_PLAT_AMBARELLA_AHB_APB_HIGH=y
+CONFIG_PLAT_AMBARELLA_SUPPORT_HW_CRYPTO=y
+CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI=y
+CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC=y
+# CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64 is not set
+CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS=y
+# CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK is not set
+# CONFIG_PLAT_AMBARELLA_SUPPORT_RPROC is not set
+# CONFIG_PLAT_AMBARELLA_S2 is not set
+# CONFIG_PLAT_AMBARELLA_A8 is not set
+# CONFIG_PLAT_AMBARELLA_A5S is not set
+# CONFIG_PLAT_AMBARELLA_A7L is not set
+# CONFIG_PLAT_AMBARELLA_S2_ARM11 is not set
+# CONFIG_PLAT_AMBARELLA_S2_CORTEX is not set
+# CONFIG_PLAT_AMBARELLA_S2E is not set
+# CONFIG_PLAT_AMBARELLA_A8_ARM11 is not set
+# CONFIG_PLAT_AMBARELLA_A8_CORTEX is not set
+# CONFIG_PLAT_AMBARELLA_S2L is not set
+# CONFIG_PLAT_AMBARELLA_S3 is not set
+CONFIG_PLAT_AMBARELLA_S3L=y
+
+#
+# Generic Platform Configuration
+#
+CONFIG_AMBARELLA_CALC_PLL=y
+# CONFIG_AMBARELLA_RAW_BOOT is not set
+# CONFIG_AMBARELLA_PMUSERENR_EN is not set
+CONFIG_PLAT_AMBARELLA_SUPPORT_GDMA=y
+
+#
+# Sys file system support
+#
+# CONFIG_AMBARELLA_SYS_CACHE_CALL is not set
+
+#
+# Proc file system support
+#
+CONFIG_AMBARELLA_PLL_PROC=y
+# CONFIG_AMBARELLA_SUPPORT_AMBENCH is not set
+
+#
+# Memory Configuration
+#
+CONFIG_AMBARELLA_PPM_SIZE=0x00200000
+CONFIG_AMBARELLA_ZRELADDR=0x00208000
+CONFIG_AMBARELLA_TEXTOFS=0x00008000
+CONFIG_AMBARELLA_PARAMS_PHYS=0x00200100
+CONFIG_AMBARELLA_INITRD_PHYS=0x00A00000
+# CONFIG_AMBARELLA_IO_MAP is not set
+# CONFIG_AMBARELLA_PPM_UNCACHED is not set
+CONFIG_AMBARELLA_TIMER_HZ=100
+CONFIG_AMBARELLA_TIMER_HIGHRES=y
+CONFIG_AMBARELLA_EXT_IRQ_NUM=16
+CONFIG_AMBARELLA_EXT_GPIO_NUM=16
+CONFIG_AMBARELLA_SREF_FIFO_EXEC=y
+CONFIG_GPIO_PCA953X=y
+# CONFIG_KEYBOARD_GPIO_POLLED is not set
+# CONFIG_PLAT_SPEAR is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_LPAE is not set
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_ARM_VIRT_EXT=y
+# CONFIG_SWP_EMULATE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_KUSER_HELPERS=y
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_CACHE_L2X0=y
+CONFIG_CACHE_PL310=y
+# CONFIG_CACHE_PL310_EARLY_BRESP is not set
+CONFIG_CACHE_PL310_PREFETCH_OFFSET=0
+# CONFIG_CACHE_PL310_FULL_LINE_OF_ZERO is not set
+# CONFIG_CACHE_PL310_DOUBLE_LINEFILL is not set
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_NR_BANKS=8
+CONFIG_MULTI_IRQ_HANDLER=y
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_PL310_ERRATA_588369=y
+# CONFIG_ARM_ERRATA_720789 is not set
+CONFIG_PL310_ERRATA_727915=y
+# CONFIG_ARM_ERRATA_743622 is not set
+# CONFIG_ARM_ERRATA_751472 is not set
+# CONFIG_PL310_ERRATA_753970 is not set
+# CONFIG_ARM_ERRATA_754322 is not set
+# CONFIG_PL310_ERRATA_769419 is not set
+# CONFIG_ARM_ERRATA_775420 is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_HAVE_ARM_ARCH_TIMER is not set
+# CONFIG_VMSPLIT_3G is not set
+CONFIG_VMSPLIT_2G=y
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0x80000000
+# CONFIG_ARM_PSCI is not set
+CONFIG_ARCH_NR_GPIO=0
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_COUNT=y
+CONFIG_HZ=100
+CONFIG_SCHED_HRTICK=y
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=y
+# CONFIG_HIGHMEM is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_COMPACTION is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_CROSS_MEMORY_ATTACH is not set
+CONFIG_NEED_PER_CPU_KM=y
+# CONFIG_CLEANCACHE is not set
+# CONFIG_FRONTSWAP is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+# CONFIG_SECCOMP is not set
+CONFIG_CC_STACKPROTECTOR=y
+# CONFIG_XEN is not set
+
+#
+# Boot options
+#
+CONFIG_USE_OF=y
+CONFIG_ATAGS=y
+# CONFIG_DEPRECATED_PARAM_STRUCT is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_ARM_APPENDED_DTB is not set
+CONFIG_CMDLINE="console=ttyS0"
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
+# CONFIG_CMDLINE_EXTEND is not set
+# CONFIG_CMDLINE_FORCE is not set
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_AUTO_ZRELADDR is not set
+
+#
+# CPU Power Management
+#
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+
+#
+# ARM CPU frequency scaling drivers
+#
+# CONFIG_ARM_EXYNOS4210_CPUFREQ is not set
+# CONFIG_ARM_EXYNOS4X12_CPUFREQ is not set
+# CONFIG_ARM_EXYNOS5250_CPUFREQ is not set
+# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set
+CONFIG_ARM_AMBARALLA_CPUFREQ=y
+# CONFIG_CPU_IDLE is not set
+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_SCRIPT=y
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_COREDUMP=y
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_HIBERNATE_CALLBACKS=y
+CONFIG_HIBERNATION=y
+CONFIG_PM_STD_PARTITION=""
+CONFIG_PM_SLEEP=y
+# CONFIG_PM_AUTOSLEEP is not set
+CONFIG_PM_WAKELOCKS=y
+CONFIG_PM_WAKELOCKS_LIMIT=100
+CONFIG_PM_WAKELOCKS_GC=y
+# CONFIG_PM_RUNTIME is not set
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+CONFIG_PM_ADVANCED_DEBUG=y
+# CONFIG_PM_TEST_SUSPEND is not set
+CONFIG_PM_SLEEP_DEBUG=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_CLK=y
+CONFIG_CPU_PM=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_DIAG is not set
+CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=y
+CONFIG_XFRM=y
+CONFIG_XFRM_ALGO=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+# CONFIG_IP_FIB_TRIE_STATS is not set
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
+# CONFIG_NET_IP_TUNNEL is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+# CONFIG_BRIDGE is not set
+CONFIG_HAVE_NET_DSA=y
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_OPENVSWITCH is not set
+# CONFIG_VSOCKETS is not set
+# CONFIG_NETLINK_MMAP is not set
+# CONFIG_NETLINK_DIAG is not set
+# CONFIG_NETPRIO_CGROUP is not set
+CONFIG_BQL=y
+# CONFIG_BPF_JIT is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+# CONFIG_BT_HIDP is not set
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIBTUSB=m
+CONFIG_BT_HCIBTSDIO=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+# CONFIG_BT_HCIUART_ATH3K is not set
+CONFIG_BT_HCIUART_LL=y
+# CONFIG_BT_HCIUART_3WIRE is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_BT_MRVL is not set
+# CONFIG_BT_ATH3K is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_CFG80211=m
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+CONFIG_CFG80211_DEBUGFS=y
+# CONFIG_CFG80211_INTERNAL_REGDB is not set
+CONFIG_CFG80211_WEXT=y
+# CONFIG_LIB80211 is not set
+CONFIG_MAC80211=m
+CONFIG_MAC80211_HAS_RC=y
+CONFIG_MAC80211_RC_MINSTREL=y
+CONFIG_MAC80211_RC_MINSTREL_HT=y
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
+# CONFIG_MAC80211_MESH is not set
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_MESSAGE_TRACING is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
+CONFIG_RFKILL=m
+CONFIG_RFKILL_INPUT=y
+# CONFIG_RFKILL_GPIO is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+# CONFIG_NFC is not set
+CONFIG_HAVE_BPF_JIT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH=""
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+CONFIG_FW_LOADER_USER_HELPER=y
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_GENERIC_CPU_DEVICES is not set
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=m
+CONFIG_REGMAP_SPI=m
+CONFIG_DMA_SHARED_BUFFER=y
+# CONFIG_CMA is not set
+
+#
+# Bus devices
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_BLKDEVS=y
+# CONFIG_MTD_BLOCK is not set
+# CONFIG_MTD_BLOCK_RO is not set
+CONFIG_MTD_BLOCK_AMBRO=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+# CONFIG_MTD_SWAP is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_AMBARELLA_SPI_NOR is not set
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOCG3 is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_BCH=y
+CONFIG_MTD_NAND_ECC_BCH=y
+# CONFIG_MTD_SM_COMMON is not set
+CONFIG_MTD_NAND_AMBARELLA=y
+# CONFIG_MTD_SPINAND_AMBARELLA is not set
+# CONFIG_MTD_SPINAND_ONDIEECC is not set
+# CONFIG_MTD_NAND_DENALI is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_DOCG4 is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_LIMIT=20
+# CONFIG_MTD_UBI_FASTMAP is not set
+# CONFIG_MTD_UBI_GLUEBI is not set
+CONFIG_DTC=y
+CONFIG_OF=y
+
+#
+# Device Tree and Open Firmware support
+#
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_OF_SELFTEST is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_DEVICE=y
+CONFIG_OF_I2C=y
+CONFIG_OF_NET=y
+CONFIG_OF_MDIO=m
+CONFIG_OF_MTD=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_BLK_DEV_XIP=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_BLK_DEV_RBD is not set
+
+#
+# Misc devices
+#
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ATMEL_PWM is not set
+# CONFIG_DUMMY_IRQ is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ATMEL_SSC is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_APDS9802ALS is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_ISL29020 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_BH1780 is not set
+# CONFIG_SENSORS_BH1770 is not set
+# CONFIG_SENSORS_APDS990X is not set
+# CONFIG_HMC6352 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_BMP085_I2C is not set
+# CONFIG_BMP085_SPI is not set
+# CONFIG_USB_SWITCH_FSA9480 is not set
+# CONFIG_LATTICE_ECP3_CONFIG is not set
+# CONFIG_SRAM is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_EEPROM_93XX46 is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_TI_ST is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+
+#
+# Altera FPGA firmware download module
+#
+# CONFIG_ALTERA_STAPL is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=m
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_ISCSI_BOOT_SYSFS is not set
+# CONFIG_SCSI_UFSHCD is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_TARGET_CORE is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_CORE=y
+# CONFIG_BONDING is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_MII=y
+# CONFIG_NET_TEAM is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_VXLAN is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+
+#
+# CAIF transport drivers
+#
+
+#
+# Distributed Switch Architecture drivers
+#
+# CONFIG_NET_DSA_MV88E6XXX is not set
+# CONFIG_NET_DSA_MV88E6060 is not set
+# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
+# CONFIG_NET_DSA_MV88E6131 is not set
+# CONFIG_NET_DSA_MV88E6123_61_65 is not set
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_AMBARELLA=m
+CONFIG_NET_VENDOR_AMBARELLA_INTEN_TUE=y
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_CALXEDA_XGMAC is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_DM9000 is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_ETHOC is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+# CONFIG_AT803X_PHY is not set
+# CONFIG_AMD_PHY is not set
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_BCM87XX_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
+CONFIG_MICREL_PHY_KSZ80X1R=m
+# CONFIG_MDIO_BITBANG is not set
+# CONFIG_MDIO_BUS_MUX_GPIO is not set
+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
+# CONFIG_MICREL_KS8995MA is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_RTL8152 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_HSO is not set
+# CONFIG_USB_IPHETH is not set
+CONFIG_WLAN=y
+# CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_AT76C50X_USB is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_RTL8187 is not set
+# CONFIG_MAC80211_HWSIM is not set
+CONFIG_ATH_CARDS=m
+# CONFIG_ATH_DEBUG is not set
+# CONFIG_ATH9K is not set
+# CONFIG_ATH9K_HTC is not set
+# CONFIG_CARL9170 is not set
+CONFIG_ATH6KL=m
+CONFIG_ATH6KL_SDIO=m
+# CONFIG_ATH6KL_USB is not set
+# CONFIG_ATH6KL_DEBUG is not set
+# CONFIG_AR5523 is not set
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_BRCMFMAC is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_P54_COMMON is not set
+# CONFIG_RT2X00 is not set
+# CONFIG_RTLWIFI is not set
+# CONFIG_WL_TI is not set
+# CONFIG_ZD1211RW is not set
+CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
+# CONFIG_MWIFIEX_USB is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+# CONFIG_INPUT_MATRIXKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ADP5589 is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_QT1070 is not set
+# CONFIG_KEYBOARD_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_GPIO=m
+# CONFIG_KEYBOARD_TCA6416 is not set
+# CONFIG_KEYBOARD_TCA8418 is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8333 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_MCS is not set
+# CONFIG_KEYBOARD_MPR121 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_SAMSUNG is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_BMA150 is not set
+CONFIG_INPUT_AMBARELLA_IR=m
+CONFIG_INPUT_AMBARELLA_ADC=m
+# CONFIG_INPUT_MMA8450 is not set
+# CONFIG_INPUT_MPU3050 is not set
+# CONFIG_INPUT_GP2A is not set
+# CONFIG_INPUT_GPIO_TILT_POLLED is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_KXTJ9 is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+CONFIG_INPUT_UINPUT=m
+# CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_PWM_BEEPER is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_CMA3000 is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_TTY=y
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_CONSOLE_SLEEP=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+# CONFIG_DEVKMEM is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AMBARELLA=y
+CONFIG_SERIAL_AMBARELLA_CONSOLE=y
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX310X is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_SCCNXP is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_IFX6X60 is not set
+# CONFIG_SERIAL_XILINX_PS_UART is not set
+# CONFIG_SERIAL_ARC is not set
+# CONFIG_HVC_DCC is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=m
+# CONFIG_I2C_MUX is not set
+# CONFIG_I2C_HELPER_AUTO is not set
+# CONFIG_I2C_SMBUS is not set
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_AMBARELLA=y
+# CONFIG_I2C_CBUS_GPIO is not set
+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_DIOLAN_U2C is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_SLAVE=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+CONFIG_SPI_AMBARELLA=m
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_FSL_SPI is not set
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_SC18IS602 is not set
+# CONFIG_SPI_XCOMM is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=m
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# SPI Slave Controller Drivers
+#
+CONFIG_SPI_SLAVE_AMBARELLA=m
+
+#
+# Qualcomm MSM SSBI bus support
+#
+# CONFIG_SSBI is not set
+# CONFIG_HSI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+# CONFIG_PTP_1588_CLOCK is not set
+
+#
+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
+#
+# CONFIG_PTP_1588_CLOCK_PCH is not set
+CONFIG_PINCTRL=y
+
+#
+# Pin controllers
+#
+CONFIG_PINMUX=y
+CONFIG_PINCONF=y
+# CONFIG_PINCTRL_SINGLE is not set
+# CONFIG_PINCTRL_EXYNOS is not set
+# CONFIG_PINCTRL_EXYNOS5440 is not set
+CONFIG_PINCTRL_AMB=y
+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIO_DEVRES=y
+CONFIG_GPIOLIB=y
+CONFIG_OF_GPIO=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_GENERIC_PLATFORM is not set
+# CONFIG_GPIO_EM is not set
+# CONFIG_GPIO_RCAR is not set
+# CONFIG_GPIO_TS5500 is not set
+# CONFIG_GPIO_GRGPIO is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+CONFIG_GPIO_PCA953X_IRQ=y
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_SX150X is not set
+# CONFIG_GPIO_ADP5588 is not set
+# CONFIG_GPIO_ADNP is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+# CONFIG_GPIO_74X164 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+
+#
+# USB GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_POWER_AVS is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AMBARELLA_WATCHDOG=y
+# CONFIG_DW_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_AS3711 is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_AAT2870_CORE is not set
+# CONFIG_MFD_CROS_EC is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_DA9052_SPI is not set
+# CONFIG_MFD_DA9052_I2C is not set
+# CONFIG_MFD_DA9055 is not set
+# CONFIG_MFD_MC13XXX_SPI is not set
+# CONFIG_MFD_MC13XXX_I2C is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_MFD_88PM800 is not set
+# CONFIG_MFD_88PM805 is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_MAX77686 is not set
+# CONFIG_MFD_MAX77693 is not set
+# CONFIG_MFD_MAX8907 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_MAX8997 is not set
+# CONFIG_MFD_MAX8998 is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_VIPERBOARD is not set
+# CONFIG_MFD_RETU is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_RC5T583 is not set
+# CONFIG_MFD_SEC_CORE is not set
+# CONFIG_MFD_SI476X_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SMSC is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_MFD_STMPE is not set
+# CONFIG_MFD_SYSCON is not set
+# CONFIG_MFD_TI_AM335X_TSCADC is not set
+# CONFIG_MFD_LP8788 is not set
+# CONFIG_MFD_PALMAS is not set
+# CONFIG_TPS6105X is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_MFD_TPS65090 is not set
+# CONFIG_MFD_TPS65217 is not set
+# CONFIG_MFD_TPS6586X is not set
+# CONFIG_MFD_TPS65910 is not set
+# CONFIG_MFD_TPS65912 is not set
+# CONFIG_MFD_TPS65912_I2C is not set
+# CONFIG_MFD_TPS65912_SPI is not set
+# CONFIG_MFD_TPS80031 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_TWL6040_CORE is not set
+# CONFIG_MFD_WL1273_CORE is not set
+# CONFIG_MFD_LM3533 is not set
+# CONFIG_MFD_TC3589X is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_MFD_ARIZONA_I2C is not set
+# CONFIG_MFD_ARIZONA_SPI is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X_I2C is not set
+# CONFIG_MFD_WM831X_SPI is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_REGULATOR is not set
+CONFIG_MEDIA_SUPPORT=m
+
+#
+# Multimedia core support
+#
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set
+# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set
+# CONFIG_MEDIA_RADIO_SUPPORT is not set
+# CONFIG_MEDIA_RC_SUPPORT is not set
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_DEV=m
+# CONFIG_VIDEO_V4L2_SUBDEV_API is not set
+CONFIG_VIDEO_V4L2=m
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+CONFIG_VIDEOBUF2_CORE=m
+CONFIG_VIDEOBUF2_MEMOPS=m
+CONFIG_VIDEOBUF2_VMALLOC=m
+# CONFIG_VIDEO_V4L2_INT_DEVICE is not set
+# CONFIG_TTPCI_EEPROM is not set
+
+#
+# Media drivers
+#
+CONFIG_MEDIA_USB_SUPPORT=y
+
+#
+# Webcam devices
+#
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
+CONFIG_USB_GSPCA=m
+# CONFIG_USB_M5602 is not set
+# CONFIG_USB_STV06XX is not set
+# CONFIG_USB_GL860 is not set
+# CONFIG_USB_GSPCA_BENQ is not set
+# CONFIG_USB_GSPCA_CONEX is not set
+# CONFIG_USB_GSPCA_CPIA1 is not set
+# CONFIG_USB_GSPCA_ETOMS is not set
+# CONFIG_USB_GSPCA_FINEPIX is not set
+# CONFIG_USB_GSPCA_JEILINJ is not set
+# CONFIG_USB_GSPCA_JL2005BCD is not set
+# CONFIG_USB_GSPCA_KINECT is not set
+# CONFIG_USB_GSPCA_KONICA is not set
+# CONFIG_USB_GSPCA_MARS is not set
+# CONFIG_USB_GSPCA_MR97310A is not set
+# CONFIG_USB_GSPCA_NW80X is not set
+# CONFIG_USB_GSPCA_OV519 is not set
+# CONFIG_USB_GSPCA_OV534 is not set
+# CONFIG_USB_GSPCA_OV534_9 is not set
+# CONFIG_USB_GSPCA_PAC207 is not set
+# CONFIG_USB_GSPCA_PAC7302 is not set
+# CONFIG_USB_GSPCA_PAC7311 is not set
+# CONFIG_USB_GSPCA_SE401 is not set
+# CONFIG_USB_GSPCA_SN9C2028 is not set
+# CONFIG_USB_GSPCA_SN9C20X is not set
+# CONFIG_USB_GSPCA_SONIXB is not set
+# CONFIG_USB_GSPCA_SONIXJ is not set
+# CONFIG_USB_GSPCA_SPCA500 is not set
+# CONFIG_USB_GSPCA_SPCA501 is not set
+# CONFIG_USB_GSPCA_SPCA505 is not set
+# CONFIG_USB_GSPCA_SPCA506 is not set
+# CONFIG_USB_GSPCA_SPCA508 is not set
+# CONFIG_USB_GSPCA_SPCA561 is not set
+# CONFIG_USB_GSPCA_SPCA1528 is not set
+# CONFIG_USB_GSPCA_SQ905 is not set
+# CONFIG_USB_GSPCA_SQ905C is not set
+# CONFIG_USB_GSPCA_SQ930X is not set
+# CONFIG_USB_GSPCA_STK014 is not set
+# CONFIG_USB_GSPCA_STV0680 is not set
+# CONFIG_USB_GSPCA_SUNPLUS is not set
+# CONFIG_USB_GSPCA_T613 is not set
+# CONFIG_USB_GSPCA_TOPRO is not set
+# CONFIG_USB_GSPCA_TV8532 is not set
+# CONFIG_USB_GSPCA_VC032X is not set
+# CONFIG_USB_GSPCA_VICAM is not set
+# CONFIG_USB_GSPCA_XIRLINK_CIT is not set
+# CONFIG_USB_GSPCA_ZC3XX is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_USB_ZR364XX is not set
+# CONFIG_USB_STKWEBCAM is not set
+# CONFIG_USB_S2255 is not set
+# CONFIG_USB_SN9C102 is not set
+
+#
+# Webcam, TV (analog/digital) USB devices
+#
+# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_V4L_PLATFORM_DRIVERS is not set
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set
+# CONFIG_VIDEO_SH_VEU is not set
+# CONFIG_V4L_TEST_DRIVERS is not set
+
+#
+# Supported MMC/SDIO adapters
+#
+# CONFIG_CYPRESS_FIRMWARE is not set
+
+#
+# Media ancillary drivers (tuners, sensors, i2c, frontends)
+#
+CONFIG_MEDIA_SUBDRV_AUTOSELECT=y
+
+#
+# Audio decoders, processors and mixers
+#
+
+#
+# RDS decoders
+#
+
+#
+# Video decoders
+#
+
+#
+# Video and audio decoders
+#
+
+#
+# Video encoders
+#
+
+#
+# Camera sensor devices
+#
+
+#
+# Flash devices
+#
+
+#
+# Video improvement chips
+#
+
+#
+# Miscelaneous helper chips
+#
+
+#
+# Sensors used on soc_camera driver
+#
+
+#
+# Tools to develop new frontends
+#
+# CONFIG_DVB_DUMMY_FE is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+CONFIG_FB_SYS_FILLRECT=m
+CONFIG_FB_SYS_COPYAREA=m
+CONFIG_FB_SYS_IMAGEBLIT=m
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+CONFIG_FB_SYS_FOPS=m
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_SMSCUFX is not set
+# CONFIG_FB_UDL is not set
+# CONFIG_FB_GOLDFISH is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+CONFIG_FB_AMBARELLA=m
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_FB_AUO_K190X is not set
+# CONFIG_FB_SIMPLE is not set
+# CONFIG_EXYNOS_VIDEO is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=m
+# CONFIG_BACKLIGHT_ADP8860 is not set
+# CONFIG_BACKLIGHT_ADP8870 is not set
+# CONFIG_BACKLIGHT_LM3630 is not set
+# CONFIG_BACKLIGHT_LM3639 is not set
+# CONFIG_BACKLIGHT_LP855X is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=m
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_FONT_AUTOSELECT=y
+# CONFIG_LOGO is not set
+# CONFIG_FB_SSD1307 is not set
+CONFIG_SOUND=m
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_COMPRESS_OFFLOAD=m
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
+# CONFIG_SND_USB_CAIAQ is not set
+# CONFIG_SND_USB_6FIRE is not set
+CONFIG_SND_SOC=m
+CONFIG_SND_SOC_DMAENGINE_PCM=y
+CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
+CONFIG_SND_AMBARELLA_SOC=m
+CONFIG_SND_AMBARELLA_SOC_I2S=m
+CONFIG_SND_AMBARELLA_BOARD=m
+CONFIG_AMBA_BOARD=m
+CONFIG_SND_AMBARELLA_CODEC=m
+# CONFIG_SND_SOC_AK4642_AMB is not set
+CONFIG_SND_SOC_AK4951_AMB=m
+# CONFIG_SND_SOC_AK4954_AMB is not set
+CONFIG_SND_SOC_AK7719_DSP=m
+CONFIG_SND_SOC_AK7755=m
+# CONFIG_SND_SOC_TLV320ADC3xxx is not set
+# CONFIG_SND_SOC_ES8388 is not set
+# CONFIG_SND_SOC_WM8974_AMB is not set
+# CONFIG_SND_SOC_WM8940_AMB is not set
+CONFIG_SND_SOC_AMBARELLA_DUMMY=m
+# CONFIG_SND_ATMEL_SOC is not set
+CONFIG_SND_SOC_I2C_AND_SPI=m
+# CONFIG_SND_SOC_ALL_CODECS is not set
+# CONFIG_SND_SIMPLE_CARD is not set
+# CONFIG_SOUND_PRIME is not set
+
+#
+# HID support
+#
+CONFIG_HID=m
+# CONFIG_HIDRAW is not set
+# CONFIG_UHID is not set
+CONFIG_HID_GENERIC=m
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=m
+# CONFIG_HID_ACRUX is not set
+CONFIG_HID_APPLE=m
+# CONFIG_HID_APPLEIR is not set
+# CONFIG_HID_AUREAL is not set
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+# CONFIG_HID_PRODIKEYS is not set
+CONFIG_HID_CYPRESS=m
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_ELECOM is not set
+CONFIG_HID_EZKEY=m
+# CONFIG_HID_HOLTEK is not set
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_ICADE is not set
+# CONFIG_HID_TWINHAN is not set
+CONFIG_HID_KENSINGTON=m
+# CONFIG_HID_LCPOWER is not set
+# CONFIG_HID_LENOVO_TPKBD is not set
+CONFIG_HID_LOGITECH=m
+# CONFIG_HID_LOGITECH_DJ is not set
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
+# CONFIG_LOGIWHEELS_FF is not set
+# CONFIG_HID_MAGICMOUSE is not set
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_PRIMAX is not set
+# CONFIG_HID_PS3REMOTE is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_SAITEK is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SPEEDLINK is not set
+# CONFIG_HID_STEELSERIES is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TIVO is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+# CONFIG_HID_SENSOR_HUB is not set
+
+#
+# USB HID support
+#
+CONFIG_USB_HID=m
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# I2C HID support
+#
+# CONFIG_I2C_HID is not set
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB_ARCH_HAS_XHCI is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEFAULT_PERSIST is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_EHCI_AMBARELLA=m
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_OHCI_AMBARELLA=y
+# CONFIG_USB_OHCI_HCD_PLATFORM is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_RENESAS_USBHS is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_REALTEK is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_STORAGE_ENE_UB6250 is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_DWC3 is not set
+# CONFIG_USB_CHIPIDEA is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_U1960 is not set
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP210X is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_F81232 is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_METRO is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QCAUX is not set
+# CONFIG_USB_SERIAL_QUALCOMM is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_SYMBOL is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
+# CONFIG_USB_SERIAL_XSENS_MT is not set
+# CONFIG_USB_SERIAL_ZIO is not set
+# CONFIG_USB_SERIAL_WISHBONE is not set
+# CONFIG_USB_SERIAL_ZTE is not set
+# CONFIG_USB_SERIAL_SSU100 is not set
+# CONFIG_USB_SERIAL_QT2 is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_EHSET_TEST_FIXTURE is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_YUREX is not set
+# CONFIG_USB_EZUSB_FX2 is not set
+# CONFIG_USB_HSIC_USB3503 is not set
+CONFIG_USB_PHY=y
+CONFIG_USB_AMBARELLA_PHY=y
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_OMAP_CONTROL_USB is not set
+# CONFIG_OMAP_USB3 is not set
+# CONFIG_SAMSUNG_USBPHY is not set
+# CONFIG_SAMSUNG_USB2PHY is not set
+# CONFIG_SAMSUNG_USB3PHY is not set
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ISP1301 is not set
+# CONFIG_USB_RCAR_PHY is not set
+# CONFIG_USB_ULPI is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
+
+#
+# USB Peripheral Controller
+#
+# CONFIG_USB_FUSB300 is not set
+# CONFIG_USB_R8A66597 is not set
+# CONFIG_USB_PXA27X is not set
+# CONFIG_USB_MV_UDC is not set
+# CONFIG_USB_MV_U3D is not set
+# CONFIG_USB_M66592 is not set
+# CONFIG_USB_NET2272 is not set
+CONFIG_USB_AMBARELLA=m
+CONFIG_USB_LIBCOMPOSITE=m
+CONFIG_USB_F_ACM=m
+CONFIG_USB_U_SERIAL=m
+CONFIG_USB_F_SERIAL=m
+CONFIG_USB_F_OBEX=m
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
+# CONFIG_USB_G_NCM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FUNCTIONFS is not set
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_ACM_MS is not set
+CONFIG_USB_G_MULTI=m
+CONFIG_USB_G_MULTI_RNDIS=y
+# CONFIG_USB_G_MULTI_CDC is not set
+# CONFIG_USB_G_HID is not set
+# CONFIG_USB_G_DBGP is not set
+# CONFIG_USB_G_WEBCAM is not set
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+# CONFIG_MMC_CLKGATE is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_BLOCK_MINORS=32
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_AMBARELLA=m
+# CONFIG_AMBARELLA_EMMC_BOOT is not set
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MMC_DW is not set
+# CONFIG_MMC_VUB300 is not set
+# CONFIG_MMC_USHC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_EDAC is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_SYSTOHC=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS3232 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+CONFIG_RTC_DRV_ISL12022=y
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8523 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+# CONFIG_RTC_DRV_EM3027 is not set
+# CONFIG_RTC_DRV_RV3029C2 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T93 is not set
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+# CONFIG_RTC_DRV_RX4581 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+# CONFIG_RTC_DRV_DS2404 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_AMBARELLA=y
+# CONFIG_RTC_DRV_SNVS is not set
+
+#
+# HID Sensor RTC drivers
+#
+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
+CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+# CONFIG_DW_DMAC is not set
+# CONFIG_TIMB_DMA is not set
+CONFIG_AMBARELLA_DMA=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+
+#
+# DMA Clients
+#
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_VIRT_DRIVERS is not set
+
+#
+# Virtio drivers
+#
+# CONFIG_VIRTIO_MMIO is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+# CONFIG_STAGING is not set
+
+#
+# Hardware Spinlock drivers
+#
+# CONFIG_MAILBOX is not set
+# CONFIG_IOMMU_SUPPORT is not set
+
+#
+# Remoteproc drivers
+#
+# CONFIG_STE_MODEM_RPROC is not set
+# CONFIG_RPROC_SUPPORT is not set
+# CONFIG_RPCLNT_SUPPORT is not set
+
+#
+# Rpmsg drivers
+#
+# CONFIG_PM_DEVFREQ is not set
+# CONFIG_EXTCON is not set
+# CONFIG_MEMORY is not set
+CONFIG_IIO=m
+CONFIG_IIO_BUFFER=y
+# CONFIG_IIO_BUFFER_CB is not set
+CONFIG_IIO_KFIFO_BUF=m
+CONFIG_IIO_TRIGGERED_BUFFER=m
+CONFIG_IIO_TRIGGER=y
+CONFIG_IIO_CONSUMERS_PER_TRIGGER=2
+
+#
+# Accelerometers
+#
+# CONFIG_KXSD9 is not set
+# CONFIG_IIO_ST_ACCEL_3AXIS is not set
+
+#
+# Analog to digital converters
+#
+# CONFIG_AD7266 is not set
+# CONFIG_AD7298 is not set
+# CONFIG_AD7923 is not set
+# CONFIG_AD7791 is not set
+# CONFIG_AD7793 is not set
+# CONFIG_AD7476 is not set
+# CONFIG_AD7887 is not set
+# CONFIG_EXYNOS_ADC is not set
+# CONFIG_MAX1363 is not set
+# CONFIG_TI_ADC081C is not set
+
+#
+# Amplifiers
+#
+# CONFIG_AD8366 is not set
+
+#
+# Hid Sensor IIO Common
+#
+
+#
+# Digital to analog converters
+#
+# CONFIG_AD5064 is not set
+# CONFIG_AD5360 is not set
+# CONFIG_AD5380 is not set
+# CONFIG_AD5421 is not set
+# CONFIG_AD5624R_SPI is not set
+# CONFIG_AD5446 is not set
+# CONFIG_AD5449 is not set
+# CONFIG_AD5504 is not set
+# CONFIG_AD5755 is not set
+# CONFIG_AD5764 is not set
+# CONFIG_AD5791 is not set
+# CONFIG_AD5686 is not set
+# CONFIG_MAX517 is not set
+# CONFIG_MCP4725 is not set
+
+#
+# Frequency Synthesizers DDS/PLL
+#
+
+#
+# Clock Generator/Distribution
+#
+# CONFIG_AD9523 is not set
+
+#
+# Phase-Locked Loop (PLL) frequency synthesizers
+#
+# CONFIG_ADF4350 is not set
+
+#
+# Digital gyroscope sensors
+#
+# CONFIG_ADIS16080 is not set
+# CONFIG_ADIS16136 is not set
+# CONFIG_ADXRS450 is not set
+# CONFIG_IIO_ST_GYRO_3AXIS is not set
+# CONFIG_ITG3200 is not set
+
+#
+# Inertial measurement units
+#
+# CONFIG_ADIS16400 is not set
+# CONFIG_ADIS16480 is not set
+# CONFIG_INV_MPU6050_IIO is not set
+CONFIG_INV_MPU9250_IIO=m
+
+#
+# Light sensors
+#
+# CONFIG_ADJD_S311 is not set
+# CONFIG_SENSORS_TSL2563 is not set
+# CONFIG_VCNL4000 is not set
+
+#
+# Magnetometer sensors
+#
+# CONFIG_AK8975 is not set
+# CONFIG_IIO_ST_MAGN_3AXIS is not set
+CONFIG_PWM=y
+CONFIG_PWM_AMBARELLA=m
+CONFIG_IRQCHIP=y
+CONFIG_AMBARELLA_VIC=y
+# CONFIG_IPACK_BUS is not set
+# CONFIG_RESET_CONTROLLER is not set
+
+#
+# File systems
+#
+CONFIG_DCACHE_WORD_ACCESS=y
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+CONFIG_EXT4_FS=m
+CONFIG_EXT4_USE_FOR_EXT23=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD2=m
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=m
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_EXPORTFS=y
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_TMPFS_XATTR=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+CONFIG_SQUASHFS=y
+# CONFIG_SQUASHFS_XATTR is not set
+CONFIG_SQUASHFS_ZLIB=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX6FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_PSTORE is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_F2FS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V2=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_SWAP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_DEBUG is not set
+# CONFIG_CEPH_FS is not set
+CONFIG_CIFS=y
+CONFIG_CIFS_STATS=y
+# CONFIG_CIFS_STATS2 is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+CONFIG_CIFS_DEBUG=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_SMB2 is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_MAC_ROMAN is not set
+# CONFIG_NLS_MAC_CELTIC is not set
+# CONFIG_NLS_MAC_CENTEURO is not set
+# CONFIG_NLS_MAC_CROATIAN is not set
+# CONFIG_NLS_MAC_CYRILLIC is not set
+# CONFIG_NLS_MAC_GAELIC is not set
+# CONFIG_NLS_MAC_GREEK is not set
+# CONFIG_NLS_MAC_ICELAND is not set
+# CONFIG_NLS_MAC_INUIT is not set
+# CONFIG_NLS_MAC_ROMANIAN is not set
+# CONFIG_NLS_MAC_TURKISH is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_PANIC_ON_OOPS is not set
+CONFIG_PANIC_ON_OOPS_VALUE=0
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+
+#
+# RCU Debugging
+#
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_LKDTM is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+CONFIG_DYNAMIC_DEBUG=y
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_TEST_STRING_HELPERS is not set
+# CONFIG_TEST_KSTRTOX is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
+CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"
+# CONFIG_PID_IN_CONTEXTIDR is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_USER is not set
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_CMAC is not set
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_CRC32 is not set
+# CONFIG_CRYPTO_GHASH is not set
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA1_ARM is not set
+CONFIG_CRYPTO_SHA256=y
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_AES_ARM is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_USER_API=y
+CONFIG_CRYPTO_USER_API_HASH=y
+CONFIG_CRYPTO_USER_API_SKCIPHER=y
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_DEV_AMBARELLA=m
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_RATIONAL=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_IO=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC32_SELFTEST is not set
+CONFIG_CRC32_SLICEBY8=y
+# CONFIG_CRC32_SLICEBY4 is not set
+# CONFIG_CRC32_SARWATE is not set
+# CONFIG_CRC32_BIT is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+# CONFIG_CRC8 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_XZ_DEC=y
+# CONFIG_XZ_DEC_X86 is not set
+# CONFIG_XZ_DEC_POWERPC is not set
+# CONFIG_XZ_DEC_IA64 is not set
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+# CONFIG_XZ_DEC_SPARC is not set
+CONFIG_XZ_DEC_BCJ=y
+# CONFIG_XZ_DEC_TEST is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_XZ=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_BCH=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_DQL=y
+CONFIG_NLATTR=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+CONFIG_AVERAGE=y
+# CONFIG_CORDIC is not set
+# CONFIG_DDR is not set
+# CONFIG_VIRTUALIZATION is not set
diff --git a/arch/arm/include/asm/ftrace.h b/arch/arm/include/asm/ftrace.h
index f89515ad..bfe2a2f5 100644
--- a/arch/arm/include/asm/ftrace.h
+++ b/arch/arm/include/asm/ftrace.h
@@ -45,22 +45,14 @@ void *return_address(unsigned int);
#else
-extern inline void *return_address(unsigned int level)
+static inline void *return_address(unsigned int level)
{
return NULL;
}
#endif
-#define HAVE_ARCH_CALLER_ADDR
-
-#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
-#define CALLER_ADDR1 ((unsigned long)return_address(1))
-#define CALLER_ADDR2 ((unsigned long)return_address(2))
-#define CALLER_ADDR3 ((unsigned long)return_address(3))
-#define CALLER_ADDR4 ((unsigned long)return_address(4))
-#define CALLER_ADDR5 ((unsigned long)return_address(5))
-#define CALLER_ADDR6 ((unsigned long)return_address(6))
+#define ftrace_return_address(n) return_address(n)
#endif /* ifndef __ASSEMBLY__ */
diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
index 3b2c40b5..b1379075 100644
--- a/arch/arm/include/asm/hardware/cache-l2x0.h
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h
@@ -78,6 +78,8 @@
#define L2X0_CACHE_ID_RTL_R3P2 0x8
#define L2X0_AUX_CTRL_MASK 0xc0000fff
+#define L2X0_AUX_CTRL_FULL_LINE_OF_ZERO_SHIFT 0
+#define L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT 0
#define L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT 0
#define L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK 0x7
#define L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT 3
@@ -90,12 +92,21 @@
#define L2X0_AUX_CTRL_WAY_SIZE_SHIFT 17
#define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x7 << 17)
#define L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT 22
+#define L2X0_AUX_CTRL_CR_POLICY_SHIFT 25
#define L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT 26
#define L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT 27
#define L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT 28
#define L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT 29
#define L2X0_AUX_CTRL_EARLY_BRESP_SHIFT 30
+#define L2X0_PREFETCH_CTRL_PREFETCH_OFFSET_SHIFT 0
+#define L2X0_PREFETCH_CTRL_PREFETCH_OFFSET_MASK 0x1f
+#define L2X0_PREFETCH_CTRL_PREFETCH_DROP_SHIFT 24
+#define L2X0_PREFETCH_CTRL_DOUBLE_LINEFILL_INCR_SHIFT 23
+#define L2X0_PREFETCH_CTRL_DATA_PREFETCH_SHIFT 28
+#define L2X0_PREFETCH_CTRL_INST_PREFETCH_SHIFT 29
+#define L2X0_PREFETCH_CTRL_DOUBLE_LINEFILL_SHIFT 30
+
#define L2X0_LATENCY_CTRL_SETUP_SHIFT 0
#define L2X0_LATENCY_CTRL_RD_SHIFT 4
#define L2X0_LATENCY_CTRL_WR_SHIFT 8
@@ -107,7 +118,7 @@
#define L2X0_WAY_SIZE_SHIFT 3
#ifndef __ASSEMBLY__
-extern void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask);
+extern void l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask);
#if defined(CONFIG_CACHE_L2X0) && defined(CONFIG_OF)
extern int l2x0_of_init(u32 aux_val, u32 aux_mask);
#else
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index d847cbbc..c27f1070 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -80,7 +80,7 @@
*/
#define IOREMAP_MAX_ORDER 24
-#define CONSISTENT_END (0xffe00000UL)
+#define CONSISTENT_END (0xfee00000UL)
#else /* CONFIG_MMU */
diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h
index f94784f0..dfedbfc1 100644
--- a/arch/arm/include/asm/outercache.h
+++ b/arch/arm/include/asm/outercache.h
@@ -33,6 +33,9 @@ struct outer_cache_fns {
#ifdef CONFIG_OUTER_CACHE_SYNC
void (*sync)(void);
#endif
+ void (*clean_all)(void);
+ void (*enable)(void);
+ int (*is_enabled)(void);
void (*set_debug)(unsigned long);
void (*resume)(void);
};
@@ -81,6 +84,25 @@ static inline void outer_resume(void)
outer_cache.resume();
}
+static inline void outer_clean_all(void)
+{
+ if (outer_cache.clean_all)
+ outer_cache.clean_all();
+}
+
+static inline void outer_enable(void)
+{
+ if (outer_cache.enable)
+ outer_cache.enable();
+}
+
+static inline int outer_is_enabled(void)
+{
+ if (outer_cache.is_enabled)
+ return outer_cache.is_enabled();
+ return 0;
+}
+
#else
static inline void outer_inv_range(phys_addr_t start, phys_addr_t end)
@@ -93,6 +115,9 @@ static inline void outer_flush_all(void) { }
static inline void outer_inv_all(void) { }
static inline void outer_disable(void) { }
static inline void outer_resume(void) { }
+static inline void outer_clean_all(void) { }
+static inline void outer_enable(void) { }
+static inline int outer_is_enabled(void) { return 0; }
#endif
diff --git a/arch/arm/kernel/atags_parse.c b/arch/arm/kernel/atags_parse.c
index 14512e69..762fc66f 100644
--- a/arch/arm/kernel/atags_parse.c
+++ b/arch/arm/kernel/atags_parse.c
@@ -46,7 +46,11 @@ static struct {
{ tag_size(tag_core), ATAG_CORE },
{ 1, PAGE_SIZE, 0xff },
{ tag_size(tag_mem32), ATAG_MEM },
+#if defined(CONFIG_AMBARELLA_RAW_BOOT)
+ { CONFIG_AMBARELLA_MEMORY_SIZE, (DEFAULT_MEM_START + CONFIG_AMBARELLA_PPM_SIZE) },
+#else
{ MEM_SIZE },
+#endif
{ 0, ATAG_NONE }
};
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index f935b5f6..fe5223e1 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -75,6 +75,47 @@
*/
.arm
+ .macro invall_tlb_control, tmp0
+ mov \tmp0, #0x00
+ mcr p15, 0, \tmp0, c8, c7, 0 /* Invalidate entire unified TLB */
+ mcr p15, 0, \tmp0, c8, c6, 0 /* Invalidate entire data TLB */
+ mcr p15, 0, \tmp0, c8, c5, 0 /* Invalidate entire instruction TLB */
+ .endm
+
+ .macro invall_cache, name, tmp0, tmp1, tmp2, tmp3, tmp4
+ mov \tmp0, #0
+ mcr p15, 0, \tmp0, c7, c5, 6 /* Invalidate entire branch prediction array */
+ mcr p15, 0, \tmp0, c7, c5, 0 /* Invalidate entire icache */
+ mcr p15, 2, \tmp0, c0, c0, 0 /* cache size selection register, select dcache */
+ mrc p15, 1, \tmp0, c0, c0, 0 /* cache size id register */
+ mov \tmp0, \tmp0, asr #13
+ movw \tmp2, #0x0fff
+ and \tmp0, \tmp0, \tmp2
+ cmp \tmp0, #0x7f
+ moveq \tmp0, #0x1000
+ beq size_done_\name
+ cmp \tmp0, #0xff
+ moveq \tmp0, #0x2000
+ movne \tmp0, #0x4000
+size_done_\name:
+ mov \tmp1, #0
+ mov \tmp2, #0x40000000
+ mov \tmp3, #0x80000000
+ mov \tmp4, #0xc0000000
+inv_dloop_\name:
+ mcr p15, 0, \tmp1, c7, c6, 2 /* invalidate dcache by set / way */
+ mcr p15, 0, \tmp2, c7, c6, 2 /* invalidate dcache by set / way */
+ mcr p15, 0, \tmp3, c7, c6, 2 /* invalidate dcache by set / way */
+ mcr p15, 0, \tmp4, c7, c6, 2 /* invalidate dcache by set / way */
+ add \tmp1, \tmp1, #0x20
+ add \tmp2, \tmp2, #0x20
+ add \tmp3, \tmp3, #0x20
+ add \tmp4, \tmp4, #0x20
+ cmp \tmp1, \tmp0
+ bne inv_dloop_\name
+ .endm
+
+
__HEAD
ENTRY(stext)
@@ -83,6 +124,11 @@ ENTRY(stext)
THUMB( .thumb ) @ switch to Thumb now.
THUMB(1: )
+#if defined(CONFIG_AMBARELLA_RAW_BOOT)
+ invall_tlb_control r3
+ invall_cache bootstrap, r3, r4, r5, r6, r7
+#endif
+
#ifdef CONFIG_ARM_VIRT_EXT
bl __hyp_stub_install
#endif
@@ -455,14 +501,12 @@ ENDPROC(__enable_mmu)
*
* other registers depend on the function called upon completion
*/
- .align 5
.pushsection .idmap.text, "ax"
+ .align 5
ENTRY(__turn_mmu_on)
mov r0, r0
- instr_sync
mcr p15, 0, r0, c1, c0, 0 @ write control reg
mrc p15, 0, r3, c0, c0, 0 @ read id reg
- instr_sync
mov r3, r3
mov r3, r13
mov pc, r3
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index ac4c2e5e..943660cf 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -223,6 +223,14 @@ void machine_power_off(void)
if (pm_power_off)
pm_power_off();
+
+ /* Give a grace period for failure to restart of 1s */
+ mdelay(1000);
+
+ /* A workaround for power off failed */
+ printk("Power off -- System halted\n");
+ local_irq_disable();
+ while (1);
}
/*
diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c
index fafedd86..3a861fc4 100644
--- a/arch/arm/kernel/return_address.c
+++ b/arch/arm/kernel/return_address.c
@@ -60,14 +60,10 @@ void *return_address(unsigned int level)
#else /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) */
#if defined(CONFIG_ARM_UNWIND)
-#warning "TODO: return_address should use unwind tables"
+//To ceaes compile warning
+/* #warning "TODO: return_address should use unwind tables" */
#endif
-void *return_address(unsigned int level)
-{
- return NULL;
-}
-
#endif /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) / else */
EXPORT_SYMBOL_GPL(return_address);
diff --git a/arch/arm/mach-ambarella/Kconfig b/arch/arm/mach-ambarella/Kconfig
new file mode 100644
index 00000000..6a7911a0
--- /dev/null
+++ b/arch/arm/mach-ambarella/Kconfig
@@ -0,0 +1,481 @@
+#
+# arch/arm/mach-ambarella/Kconfig
+#
+# History:
+# 2006/12/18 - [Charles Chiou] created file
+#
+# Copyright (C) 2004-2009, Ambarella, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+config PLAT_AMBARELLA
+ bool
+ depends on ARCH_AMBARELLA
+ default y
+ select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
+ select GENERIC_CLOCKEVENTS
+ select ARCH_INLINE_SPIN_TRYLOCK
+ select ARCH_INLINE_SPIN_TRYLOCK_BH
+ select ARCH_INLINE_SPIN_LOCK
+ select ARCH_INLINE_SPIN_LOCK_BH
+ select ARCH_INLINE_SPIN_LOCK_IRQ
+ select ARCH_INLINE_SPIN_LOCK_IRQSAVE
+ select ARCH_INLINE_SPIN_UNLOCK
+ select ARCH_INLINE_SPIN_UNLOCK_BH
+ select ARCH_INLINE_SPIN_UNLOCK_IRQ
+ select ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE
+ select ARCH_INLINE_READ_TRYLOCK
+ select ARCH_INLINE_READ_LOCK
+ select ARCH_INLINE_READ_LOCK_BH
+ select ARCH_INLINE_READ_LOCK_IRQ
+ select ARCH_INLINE_READ_LOCK_IRQSAVE
+ select ARCH_INLINE_READ_UNLOCK
+ select ARCH_INLINE_READ_UNLOCK_BH
+ select ARCH_INLINE_READ_UNLOCK_IRQ
+ select ARCH_INLINE_READ_UNLOCK_IRQRESTORE
+ select ARCH_INLINE_WRITE_TRYLOCK
+ select ARCH_INLINE_WRITE_LOCK
+ select ARCH_INLINE_WRITE_LOCK_BH
+ select ARCH_INLINE_WRITE_LOCK_IRQ
+ select ARCH_INLINE_WRITE_LOCK_IRQSAVE
+ select ARCH_INLINE_WRITE_UNLOCK
+ select ARCH_INLINE_WRITE_UNLOCK_BH
+ select ARCH_INLINE_WRITE_UNLOCK_IRQ
+ select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
+ select HAVE_CLK
+ help
+ Base platform code for any Ambarella device
+
+if PLAT_AMBARELLA
+comment "Ambarella Platform"
+
+config PLAT_AMBARELLA_SUPPORT_VIC
+ bool
+ default n
+ select AMBARELLA_VIC
+
+config PLAT_AMBARELLA_HAVE_ARM11
+ bool
+ default n
+
+config PLAT_AMBARELLA_CORTEX
+ bool
+ default n
+ select CPU_V7
+ select MIGHT_HAVE_CACHE_L2X0
+
+config PLAT_AMBARELLA_CORTEX_SMP
+ bool
+ depends on PLAT_AMBARELLA_CORTEX
+ default n
+ select HAVE_SMP
+ select HAVE_ARM_SCU if SMP
+
+config PLAT_AMBARELLA_LOCAL_TIMERS
+ bool
+ depends on PLAT_AMBARELLA_CORTEX_SMP
+ default n
+
+config PLAT_AMBARELLA_SUPPORT_PM
+ bool
+ default n
+
+config PLAT_AMBARELLA_MEM_START_LOW
+ bool
+ default n
+
+config PLAT_AMBARELLA_AHB_APB_HIGH
+ bool
+ default n
+
+config PLAT_AMBARELLA_SUPPORT_HW_CRYPTO
+ bool
+ default n
+
+config PLAT_AMBARELLA_SUPPORT_MMAP_AXI
+ bool
+ default n
+
+config PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC
+ bool
+ default n
+
+config PLAT_AMBARELLA_SUPPORT_MMAP_AHB64
+ bool
+ default n
+
+config PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS
+ bool
+ default n
+
+config PLAT_AMBARELLA_ADD_REGISTER_LOCK
+ bool
+ default n
+
+config PLAT_AMBARELLA_SUPPORT_RPROC
+ bool
+ default n
+
+config PLAT_AMBARELLA_S2
+ bool
+ select USB_ARCH_HAS_EHCI if USB_SUPPORT
+ select USB_ARCH_HAS_OHCI if USB_SUPPORT
+ default n
+
+config PLAT_AMBARELLA_A8
+ bool
+ select PLAT_AMBARELLA_MEM_START_LOW
+ select PLAT_AMBARELLA_AHB_APB_HIGH
+ select PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS
+ default n
+
+choice
+ prompt "Chip REV"
+
+config PLAT_AMBARELLA_A5S
+ bool "A5S"
+ select CPU_V6
+ select CPU_32v6K
+ select PLAT_AMBARELLA_HAVE_ARM11
+ select PLAT_AMBARELLA_SUPPORT_VIC
+ select PLAT_AMBARELLA_SUPPORT_HW_CRYPTO
+ help
+ Say Y here if you are using Ambarella A5S.
+
+config PLAT_AMBARELLA_A7L
+ bool "A7L"
+ select CPU_V6
+ select CPU_32v6K
+ select PLAT_AMBARELLA_HAVE_ARM11
+ select PLAT_AMBARELLA_SUPPORT_VIC
+ select PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC
+ help
+ Say Y here if you are using Ambarella A7l.
+
+config PLAT_AMBARELLA_S2_ARM11
+ bool "S2 ARM11"
+ select CPU_V6
+ select CPU_32v6K
+ select PLAT_AMBARELLA_HAVE_ARM11
+ select PLAT_AMBARELLA_S2
+ select PLAT_AMBARELLA_SUPPORT_VIC
+ select PLAT_AMBARELLA_SUPPORT_HW_CRYPTO
+ select PLAT_AMBARELLA_SUPPORT_MMAP_AHB64
+ help
+ Say Y here if you are using Ambarella S2 ARM11.
+
+config PLAT_AMBARELLA_S2_CORTEX
+ bool "S2 Cortex"
+ select ARM_GIC
+ select PLAT_AMBARELLA_HAVE_ARM11
+ select PLAT_AMBARELLA_S2
+ select PLAT_AMBARELLA_CORTEX
+ select PLAT_AMBARELLA_CORTEX_SMP
+ select HAVE_ARM_TWD if LOCAL_TIMERS
+ select PLAT_AMBARELLA_MEM_START_LOW
+ select PLAT_AMBARELLA_SUPPORT_HW_CRYPTO
+ select PLAT_AMBARELLA_SUPPORT_MMAP_AXI
+ select ARM_ERRATA_754322
+ select ARM_ERRATA_764369 if SMP
+ select ARM_ERRATA_775420
+ select PL310_ERRATA_588369 if CACHE_PL310
+ select PL310_ERRATA_727915 if CACHE_PL310
+ select PL310_ERRATA_753970 if CACHE_PL310
+ select PL310_ERRATA_769419 if CACHE_PL310
+
+ help
+ Say Y here if you are using Ambarella S2 Cortex.
+
+config PLAT_AMBARELLA_S2E
+ bool "S2E"
+ select PLAT_AMBARELLA_CORTEX
+ select PLAT_AMBARELLA_CORTEX_SMP
+ select PLAT_AMBARELLA_LOCAL_TIMERS if LOCAL_TIMERS
+ select PLAT_AMBARELLA_SUPPORT_PM if PM
+ select AMBARELLA_SREF_FIFO_EXEC if PM
+ select PLAT_AMBARELLA_MEM_START_LOW
+ select PLAT_AMBARELLA_SUPPORT_MMAP_AXI
+ select PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC
+ select PLAT_AMBARELLA_SUPPORT_VIC
+ select PLAT_AMBARELLA_SUPPORT_HW_CRYPTO
+ select USB_ARCH_HAS_EHCI if USB_SUPPORT
+ select USB_ARCH_HAS_OHCI if USB_SUPPORT
+ select ARM_ERRATA_754322
+ select ARM_ERRATA_764369 if SMP
+ select ARM_ERRATA_775420
+ select PL310_ERRATA_588369 if CACHE_PL310
+ select PL310_ERRATA_727915 if CACHE_PL310
+ help
+ Say Y here if you are using Ambarella S2E.
+
+config PLAT_AMBARELLA_A8_ARM11
+ bool "A8 ARM11"
+ select CPU_V6
+ select CPU_32v6K
+ select PLAT_AMBARELLA_HAVE_ARM11
+ select PLAT_AMBARELLA_SUPPORT_VIC
+ select PLAT_AMBARELLA_A8
+ select PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC
+ select PLAT_AMBARELLA_SUPPORT_HW_CRYPTO
+ help
+ Say Y here if you are using Ambarella A8 ARM11.
+
+config PLAT_AMBARELLA_A8_CORTEX
+ bool "A8 Cortex"
+ select ARM_GIC
+ select PLAT_AMBARELLA_HAVE_ARM11
+ select PLAT_AMBARELLA_A8
+ select PLAT_AMBARELLA_CORTEX
+ select PLAT_AMBARELLA_CORTEX_SMP
+ select HAVE_ARM_TWD if LOCAL_TIMERS
+ select PLAT_AMBARELLA_SUPPORT_MMAP_AXI
+ select PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC
+ select PLAT_AMBARELLA_SUPPORT_RPROC
+ select AMBARELLA_IO_MAP
+ select AMBARELLA_PPM_UNCACHED
+ select ARM_ERRATA_754322
+ select ARM_ERRATA_764369 if SMP
+ select ARM_ERRATA_775420
+ select PL310_ERRATA_588369 if CACHE_PL310
+ select PL310_ERRATA_727915 if CACHE_PL310
+ select PL310_ERRATA_753970 if CACHE_PL310
+ select PL310_ERRATA_769419 if CACHE_PL310
+ help
+ Say Y here if you are using Ambarella A8 Cortex.
+
+config PLAT_AMBARELLA_S2L
+ bool "S2L"
+ select PLAT_AMBARELLA_CORTEX
+ select PLAT_AMBARELLA_SUPPORT_PM if PM
+ select PLAT_AMBARELLA_MEM_START_LOW
+ select PLAT_AMBARELLA_AHB_APB_HIGH
+ select AMBARELLA_SREF_FIFO_EXEC if PM
+ select PLAT_AMBARELLA_SUPPORT_MMAP_AXI
+ select PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC
+ select PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS
+ select PLAT_AMBARELLA_SUPPORT_VIC
+ select PLAT_AMBARELLA_SUPPORT_HW_CRYPTO
+ select USB_ARCH_HAS_EHCI if USB_SUPPORT
+ select USB_ARCH_HAS_OHCI if USB_SUPPORT
+ select PL310_ERRATA_588369 if CACHE_PL310
+ select PL310_ERRATA_727915 if CACHE_PL310
+ help
+ Say Y here if you are using Ambarella S2L.
+
+config PLAT_AMBARELLA_S3
+ bool "S3"
+ select PLAT_AMBARELLA_CORTEX
+ select PLAT_AMBARELLA_CORTEX_SMP
+ select PLAT_AMBARELLA_LOCAL_TIMERS if LOCAL_TIMERS
+ select PLAT_AMBARELLA_SUPPORT_PM if PM
+ select PLAT_AMBARELLA_MEM_START_LOW
+ select PLAT_AMBARELLA_AHB_APB_HIGH
+ select PLAT_AMBARELLA_SUPPORT_MMAP_AXI
+ select PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC
+ select PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS
+ select PLAT_AMBARELLA_SUPPORT_VIC
+ select PLAT_AMBARELLA_SUPPORT_HW_CRYPTO
+ select USB_ARCH_HAS_EHCI if USB_SUPPORT
+ select USB_ARCH_HAS_OHCI if USB_SUPPORT
+ select ARM_ERRATA_764369 if SMP
+ select PL310_ERRATA_588369 if CACHE_PL310
+ select PL310_ERRATA_727915 if CACHE_PL310
+ help
+ Say Y here if you are using Ambarella S3.
+
+config PLAT_AMBARELLA_S3L
+ bool "S3L"
+ select PLAT_AMBARELLA_CORTEX
+ select PLAT_AMBARELLA_SUPPORT_PM if PM
+ select AMBARELLA_SREF_FIFO_EXEC if PM
+ select PLAT_AMBARELLA_MEM_START_LOW
+ select PLAT_AMBARELLA_AHB_APB_HIGH
+ select PLAT_AMBARELLA_SUPPORT_MMAP_AXI
+ select PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC
+ select PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS
+ select PLAT_AMBARELLA_SUPPORT_VIC
+ select PLAT_AMBARELLA_SUPPORT_HW_CRYPTO
+ select USB_ARCH_HAS_EHCI if USB_SUPPORT
+ select USB_ARCH_HAS_OHCI if USB_SUPPORT
+ select PL310_ERRATA_588369 if CACHE_PL310
+ select PL310_ERRATA_727915 if CACHE_PL310
+ help
+ Say Y here if you are using Ambarella S3L.
+
+endchoice
+
+menu "Generic Platform Configuration"
+
+config AMBARELLA_CALC_PLL
+ bool "Setup PLL by Calculation"
+ select RATIONAL
+ default n
+ help
+ If you are not sure, say N here.
+
+config AMBARELLA_RAW_BOOT
+ bool "Raw boot mode"
+ default n
+ help
+ If you are not sure, say N here.
+
+config PLAT_AMBARELLA_LOWER_ARM_PLL
+ bool "Lower ARM11 PLL when use Cortex only"
+ default n
+ depends on PLAT_AMBARELLA_S2_CORTEX
+ help
+ If you are not sure, say N here.
+
+config AMBARELLA_PMUSERENR_EN
+ bool "Enable userspcae access to PMU"
+ default n
+ help
+ Enable userspcae access to PMU
+
+config PLAT_AMBARELLA_SUPPORT_GDMA
+ bool "Enable gdma"
+ default n
+ help
+ Enable gdma
+
+menu "Sys file system support"
+depends on SYSFS
+
+config AMBARELLA_SYS_CACHE_CALL
+ bool "Support Cache Configuration"
+ default n
+ help
+ If you are not sure, say N here.
+
+endmenu
+
+menu "Proc file system support"
+depends on PROC_FS
+
+config AMBARELLA_PLL_PROC
+ bool "Suport Ambarella PLL proc"
+ default n
+ ---help---
+ /proc/ambarella/clock
+
+ If you are not sure, say N here.
+
+config AMBARELLA_SUPPORT_AMBENCH
+ bool "Suport Ambarella Test (ambench)"
+ default n
+ help
+ /proc/ambarella/ambench
+
+ If you are not sure, say N here.
+
+endmenu
+
+menu "Memory Configuration"
+
+config AMBARELLA_PPM_SIZE
+ hex "PPM SIZE"
+ default 0x00000000
+ range 0x00000000 0x10000000 if VMSPLIT_3G
+ range 0x00000000 0x20000000 if VMSPLIT_2G
+ range 0x00000000 0x60000000 if VMSPLIT_1G
+ help
+ Specify the size from the start of physical DRAM address to reserve.
+
+config AMBARELLA_MEMORY_SIZE
+ hex "Default MEMORY SIZE"
+ depends on AMBARELLA_RAW_BOOT
+ default 0x08000000
+ range 0x04000000 0x40000000
+ help
+ Specify the size of physical DRAM for debug.
+
+config AMBARELLA_ZRELADDR
+ hex "ZRELADDR"
+ default 0x00108000
+ help
+ Specify the kernel entry point start physical address.
+
+config AMBARELLA_TEXTOFS
+ hex "TEXTOFS"
+ default 0x00108000
+ help
+ Speicify the relative text offset.
+
+config AMBARELLA_PARAMS_PHYS
+ hex "PARAMS PHYS"
+ default 0x000c0000
+ help
+ Specify the physical address for kernel parameters.
+
+config AMBARELLA_INITRD_PHYS
+ hex "INITRD PHYS"
+ default 0x00a00000
+ help
+ Specify the physical address for initrd.
+
+config AMBARELLA_IO_MAP
+ bool "Use Ambarella IO Map"
+ default n
+ help
+ __virt_to_phys & __phys_to_virt will use lookup table.
+
+config AMBARELLA_PPM_UNCACHED
+ bool "Map PPM as MT_DEVICE"
+ default n
+ help
+ Default MT_MEMORY.
+
+endmenu
+
+config AMBARELLA_TIMER_HZ
+ int "Kernel HZ (jiffies per second)"
+ range 100 1000
+ default 100
+ help
+ Please test and figure out what you need.
+
+config AMBARELLA_TIMER_HIGHRES
+ bool "High resolution timer wrapper Support"
+ default n
+ depends on HIGH_RES_TIMERS
+ help
+ Add high resolution timer wrapper for non-GPL
+
+config AMBARELLA_EXT_IRQ_NUM
+ int "External IRQ Num"
+ range 0 256
+ default 64
+ help
+ Depends on your HW design.
+
+config AMBARELLA_EXT_GPIO_NUM
+ int "External GPIO Num"
+ range 0 256
+ default 64
+ help
+ Depends on your HW design.
+
+config AMBARELLA_SREF_FIFO_EXEC
+ bool "Self refresh code executed in FIO fifo"
+ default n
+ depends on PLAT_AMBARELLA_SUPPORT_PM
+ help
+ Self refresh 2nd solution.
+endmenu
+
+endif
+
diff --git a/arch/arm/mach-ambarella/Makefile b/arch/arm/mach-ambarella/Makefile
new file mode 100644
index 00000000..b8238cba
--- /dev/null
+++ b/arch/arm/mach-ambarella/Makefile
@@ -0,0 +1,39 @@
+#
+# arch/arm/mach-ambarella/Makefile
+#
+# Author: Anthony Ginger <hfjiang@ambarella.com>
+#
+# Copyright (C) 2004-2011, Ambarella, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+obj-y += fio.o
+obj-y += init.o
+obj-y += clk.o
+ifeq ($(CONFIG_AMBARELLA_CALC_PLL),y)
+obj-y += clk_calc.o
+else
+obj-y += clk_table.o
+endif
+obj-$(CONFIG_PLAT_AMBARELLA_SUPPORT_PM) += pm.o
+obj-$(CONFIG_PLAT_AMBARELLA_SUPPORT_PM) += sleep.o
+obj-y += timer.o
+obj-y += adc.o
+
+obj-y += soc/
+obj-y += smp/
+obj-y += misc/
+
diff --git a/arch/arm/mach-ambarella/Makefile.boot b/arch/arm/mach-ambarella/Makefile.boot
new file mode 100644
index 00000000..e31691e9
--- /dev/null
+++ b/arch/arm/mach-ambarella/Makefile.boot
@@ -0,0 +1,27 @@
+#
+# arch/arm/mach-ambarella/Makefile.boot
+#
+# History:
+# 2006/12/18 - [Charles Chiou] created file
+#
+# Copyright (C) 2004-2009, Ambarella, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+zreladdr-y := $(CONFIG_AMBARELLA_ZRELADDR)
+params_phys-y := $(CONFIG_AMBARELLA_PARAMS_PHYS)
+initrd_phys-y := $(CONFIG_AMBARELLA_INITRD_PHYS)
+
diff --git a/arch/arm/mach-ambarella/adc.c b/arch/arm/mach-ambarella/adc.c
new file mode 100644
index 00000000..b579e901
--- /dev/null
+++ b/arch/arm/mach-ambarella/adc.c
@@ -0,0 +1,510 @@
+/*
+ * arch/arm/plat-ambarella/generic/ambarella_adc_drv.c
+ *
+ * Author: Bing-Liang Hu <blhu@ambarella.com>
+ *
+ * History:
+ * 2014/07/21 - [Cao Rongrong] Re-design the mechanism with client
+ *
+ * Copyright (C) 2014-2019, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <mach/hardware.h>
+#include <plat/adc.h>
+#include <plat/rct.h>
+
+static DEFINE_MUTEX(client_mutex);
+static LIST_HEAD(client_list);
+static struct ambadc_host *ambarella_adc;
+
+static ssize_t ambarella_adc_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ ssize_t ret = 0;
+ u32 i, data;
+
+ for (i = 0; i < ADC_NUM_CHANNELS; i++) {
+ data = ambarella_adc_read_level(i);
+ ret += sprintf(&buf[ret], "adc%d=0x%x\n", i, data);
+ }
+
+ return ret;
+}
+static DEVICE_ATTR(adcsys, 0444, ambarella_adc_show, NULL);
+
+static int ambarella_adc_fifo_ctrl(u32 fid, u16 fcid)
+{
+ u32 reg=0;
+ u32 reg_val=0;
+
+ switch(fid) {
+ case 0:
+ reg = ADC_FIFO_CTRL_0_REG;
+ reg_val = ADC_FIFO_OVER_INT_EN
+ | ADC_FIFO_UNDR_INT_EN
+ | ADC_FIFO_TH
+ | (fcid << ADC_FIFO_ID_SHIFT)
+ | ADC_FIFO_DEPTH;
+ break;
+ case 1:
+ reg = ADC_FIFO_CTRL_1_REG;
+ reg_val = ADC_FIFO_OVER_INT_EN
+ | ADC_FIFO_UNDR_INT_EN
+ | ADC_FIFO_TH
+ | (fcid << ADC_FIFO_ID_SHIFT)
+ | ADC_FIFO_DEPTH;
+ break;
+ case 2:
+ reg = ADC_FIFO_CTRL_2_REG;
+ reg_val = ADC_FIFO_OVER_INT_EN
+ | ADC_FIFO_UNDR_INT_EN
+ | ADC_FIFO_TH
+ | (fcid << ADC_FIFO_ID_SHIFT)
+ | ADC_FIFO_DEPTH;
+ break;
+ break;
+ case 3:
+ reg = ADC_FIFO_CTRL_3_REG;
+ reg_val = ADC_FIFO_OVER_INT_EN
+ | ADC_FIFO_UNDR_INT_EN
+ | ADC_FIFO_TH
+ | (fcid << ADC_FIFO_ID_SHIFT)
+ | ADC_FIFO_DEPTH;
+ break;
+ break;
+ default:
+ pr_err("%s: invalid fifo NO = %d.\n",
+ __func__, fid);
+ return -1;
+ }
+
+ amba_writel(reg, reg_val);
+
+ amba_writel(ADC_FIFO_CTRL_REG, ADC_FIFO_CONTROL_CLEAR);
+ return 0;
+}
+
+static void ambarella_adc_enable(void)
+{
+ /* select adc scaler as clk_adc and power up adc */
+ amba_writel(ADC16_CTRL_REG, 0);
+
+#if (ADC_SUPPORT_SLOT == 1)
+ /* soft reset adc controller, set slot, and then enable it */
+ amba_writel(ADC_CONTROL_REG, ADC_CONTROL_RESET);
+ amba_writel(ADC_SLOT_NUM_REG, 0x0);
+ amba_writel(ADC_SLOT_PERIOD_REG, 0xffff);
+ amba_writel(ADC_SLOT_CTRL_0_REG, 0x0fff);
+#endif
+ //test fifo read in fifo_0
+ if(ambarella_adc->fifo_mode){
+ ambarella_adc_fifo_ctrl(0,1);
+ }
+ amba_setbitsl(ADC_ENABLE_REG, ADC_CONTROL_ENABLE);
+}
+
+static void ambarella_adc_disable(void)
+{
+ amba_clrbitsl(ADC_ENABLE_REG, ADC_CONTROL_ENABLE);
+ amba_writel(ADC16_CTRL_REG, ADC_CTRL_SCALER_POWERDOWN | ADC_CTRL_POWERDOWN);
+}
+
+static void ambarella_adc_start(void)
+{
+ amba_setbitsl(ADC_CONTROL_REG, ADC_CONTROL_MODE | ADC_CONTROL_START);
+}
+
+static void ambarella_adc_stop(void)
+{
+ amba_clrbitsl(ADC_CONTROL_REG, ADC_CONTROL_MODE | ADC_CONTROL_START);
+}
+
+static void ambarella_adc_reset(void)
+{
+ ambarella_adc_disable();
+ ambarella_adc_enable();
+ ambarella_adc_start();
+}
+
+struct ambadc_client *ambarella_adc_register_client(struct device *dev,
+ u32 mode, ambadc_client_callback callback)
+{
+ struct ambadc_host *amb_adc = ambarella_adc;
+ struct ambadc_client *client;
+
+ if (!dev || (mode == AMBADC_CONTINUOUS && !callback)) {
+ dev_err(dev, "dev or callback missing\n");
+ return NULL;
+ }
+
+ client = kzalloc(sizeof(struct ambadc_client), GFP_KERNEL);
+ if (!client) {
+ dev_err(dev, "no memory for adc client\n");
+ return NULL;
+ }
+
+ client->dev = dev;
+ client->dev->parent = amb_adc->dev;
+ client->mode = mode;
+ client->callback = callback;
+ client->host = amb_adc;
+
+ mutex_lock(&client_mutex);
+ list_add_tail(&client->node, &client_list);
+ mutex_unlock(&client_mutex);
+
+ if (mode == AMBADC_CONTINUOUS) {
+ amb_adc->keep_start = true;
+ ambarella_adc_start();
+
+ if (amb_adc->polling_mode) {
+ queue_delayed_work(system_wq,
+ &amb_adc->work, msecs_to_jiffies(20));
+ }
+ }
+
+ return client;
+}
+EXPORT_SYMBOL(ambarella_adc_register_client);
+
+void ambarella_adc_unregister_client(struct ambadc_client *client)
+{
+ struct ambadc_host *amb_adc = client->host;
+ struct ambadc_client *_client;
+ u32 keep_start = 0;
+
+ mutex_lock(&client_mutex);
+
+ list_del(&client->node);
+ kfree(client);
+
+ list_for_each_entry(_client, &client_list, node) {
+ if (_client->mode == AMBADC_CONTINUOUS) {
+ keep_start = 1;
+ break;
+ }
+ }
+
+ mutex_unlock(&client_mutex);
+
+ if (keep_start == 0) {
+ amb_adc->keep_start = false;
+ ambarella_adc_stop();
+ }
+}
+EXPORT_SYMBOL(ambarella_adc_unregister_client);
+
+int ambarella_adc_read_level(u32 ch)
+{
+ struct ambadc_host *amb_adc = ambarella_adc;
+ int data=0;
+ u32 i,count;
+
+ if (ch >= ADC_NUM_CHANNELS)
+ return -EINVAL;
+
+ if (amb_adc == NULL)
+ return -ENODEV;
+
+ if (!amb_adc->keep_start)
+ ambarella_adc_start();
+
+ if(!ambarella_adc->fifo_mode){
+ data = amba_readl(ADC_DATA_REG(ch));
+ } else {
+ count = 0x7ff & amba_readl(ADC_FIFO_STATUS_0_REG);
+ if(count > 4)
+ count -= 4;
+
+ for(i=0;i<count;i++){
+ data = amba_readl(ADC_FIFO_DATA0_REG + i*4);
+ // printk("call back [0x%x]=0x%x,count=0x%x,0x%x\n",
+ // (ADC_FIFO_DATA0_REG + i*4),data,count,ch);
+ }
+ //data = data/count;
+ }
+
+ if (!amb_adc->keep_start)
+ ambarella_adc_stop();
+
+ return data;
+}
+EXPORT_SYMBOL(ambarella_adc_read_level);
+
+int ambarella_adc_set_threshold(struct ambadc_client *client,
+ u32 ch, u32 low, u32 high)
+{
+ struct ambadc_client *_client;
+ int value, rval = 0;
+
+ if (ch >= ADC_NUM_CHANNELS)
+ return -EINVAL;
+
+ if (client->mode != AMBADC_CONTINUOUS) {
+ dev_err(client->dev, "Invalid adc mode: %d\n", client->mode);
+ return -EINVAL;
+ }
+
+ /* interrupt will be happened when level < low OR level > high */
+ value = ADC_EN_HI(!!high) | ADC_EN_LO(!!low) |
+ ADC_VAL_HI(high) | ADC_VAL_LO(low);
+
+ mutex_lock(&client_mutex);
+
+ /* it's not allowed that more than one clients want to set different
+ * threshold for the same adc channel. */
+ list_for_each_entry(_client, &client_list, node) {
+ if (_client == client)
+ continue;
+ /* check if other clients set the threshold for this channel */
+ if (_client->threshold[ch] && (_client->threshold[ch] != value)) {
+ if (value == 0) {
+ rval = 0;
+ goto exit;
+ } else {
+ rval = -EBUSY;
+ goto exit;
+ }
+ }
+ }
+
+ if(!ambarella_adc->fifo_mode)
+ amba_writel(ADC_CHAN_INTR_REG(ch), value);
+
+exit:
+ if (rval == 0)
+ client->threshold[ch] = value;
+
+ mutex_unlock(&client_mutex);
+
+ return rval;
+}
+EXPORT_SYMBOL(ambarella_adc_set_threshold);
+
+static void ambarella_adc_client_callback(u32 ch)
+{
+ struct ambadc_client *client;
+ u32 data;
+
+ data = ambarella_adc_read_level(ch);
+
+ list_for_each_entry(client, &client_list, node) {
+ if (client->callback && client->threshold[ch])
+ client->callback(client, ch, data);
+ }
+}
+
+static void ambarella_adc_polling_work(struct work_struct *work)
+{
+ struct ambadc_host *amb_adc;
+ u32 i;
+
+ amb_adc = container_of(work, struct ambadc_host, work.work);
+
+ for (i = 0; i < ADC_NUM_CHANNELS; i++)
+ ambarella_adc_client_callback(i);
+
+ if (amb_adc->keep_start) {
+ queue_delayed_work(system_wq,
+ &amb_adc->work, msecs_to_jiffies(20));
+ }
+}
+
+static irqreturn_t ambarella_adc_irq(int irq, void *dev_id)
+{
+ u32 i, int_src,rval,chanNo;
+ struct ambadc_host *amb_adc = dev_id;
+
+ chanNo = 0;
+ if(!amb_adc->fifo_mode){
+ int_src = amba_readl(ADC_DATA_INTR_TABLE_REG);
+ amba_writel(ADC_DATA_INTR_TABLE_REG, int_src);
+ chanNo = int_src;
+ }else{
+ rval = amba_readl(ADC_CTRL_INTR_TABLE_REG);
+ if(rval){
+ ambarella_adc_reset();
+ return IRQ_HANDLED;
+ }
+ rval = amba_readl(ADC_FIFO_INTR_TABLE_REG);
+ amba_writel(ADC_FIFO_INTR_TABLE_REG, rval);
+
+ for(i=0;i<ADC_FIFO_NUMBER;i++){
+ if((rval & (1 << i)) == 0)
+ continue;
+ rval = amba_readl(ADC_FIFO_CTRL_X_REG(i));
+ rval = (rval & (0x0000f000)) >> 12;
+ chanNo = 1 << rval;
+ }
+ }
+
+ for (i = 0; i < ADC_NUM_CHANNELS; i++) {
+ if ((chanNo & (1 << i)) == 0)
+ continue;
+
+ ambarella_adc_client_callback(i);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int ambarella_adc_probe(struct platform_device *pdev)
+{
+ struct ambadc_host *amb_adc;
+ struct device_node *np = pdev->dev.of_node;
+ int ret = 0;
+
+ amb_adc = devm_kzalloc(&pdev->dev,
+ sizeof(struct ambadc_host), GFP_KERNEL);
+ if (!amb_adc) {
+ dev_err(&pdev->dev, "Failed to allocate memory!\n");
+ return -ENOMEM;
+ }
+
+ ret = of_property_read_u32(np, "clock-frequency", &amb_adc->clk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Get clock-frequency failed!\n");
+ return -ENODEV;
+ }
+
+ //amb_adc->fifo_mode=1;//test fifo mode
+
+ amb_adc->polling_mode = !!of_find_property(np, "amb,polling-mode", NULL);
+ if (amb_adc->polling_mode) {
+ INIT_DELAYED_WORK(&amb_adc->work, ambarella_adc_polling_work);
+ } else {
+ amb_adc->irq = platform_get_irq(pdev, 0);
+ if (amb_adc->irq < 0) {
+ dev_err(&pdev->dev, "Can not get irq !\n");
+ return -ENXIO;
+ }
+
+ ret = devm_request_irq(&pdev->dev, amb_adc->irq,
+ ambarella_adc_irq, IRQF_TRIGGER_HIGH,
+ dev_name(&pdev->dev), amb_adc);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Can not request irq %d!\n", amb_adc->irq);
+ return -ENXIO;
+ }
+ }
+
+
+ ret = clk_set_rate(clk_get(NULL, "gclk_adc"), amb_adc->clk);
+ if (ret < 0)
+ return ret;
+
+ amb_adc->dev = &pdev->dev;
+
+ ambarella_adc = amb_adc;
+
+ ambarella_adc_enable();
+ if(amb_adc->fifo_mode == 1){
+ amb_adc->keep_start = true;
+ ambarella_adc_start();
+ }
+
+ ret = device_create_file(&pdev->dev, &dev_attr_adcsys);
+ if (ret != 0) {
+ dev_err(&pdev->dev, "can not create file : %d\n", ret);
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, amb_adc);
+
+ dev_info(&pdev->dev, "Ambarella ADC driver init\n");
+
+ return 0;
+}
+
+static int ambarella_adc_remove(struct platform_device *pdev)
+{
+ device_remove_file(&pdev->dev, &dev_attr_adcsys);
+ ambarella_adc_disable();
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int ambarella_adc_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ ambarella_adc_disable();
+ return 0;
+}
+
+static int ambarella_adc_resume(struct platform_device *pdev)
+{
+ struct ambadc_host *amb_adc = platform_get_drvdata(pdev);
+ struct ambadc_client *client;
+ u32 ch;
+
+ clk_set_rate(clk_get(NULL, "gclk_adc"), amb_adc->clk);
+ ambarella_adc_enable();
+
+ if (amb_adc->keep_start)
+ ambarella_adc_start();
+
+ if(ambarella_adc->fifo_mode)
+ goto exit;
+
+ for (ch = 0; ch < ADC_NUM_CHANNELS; ch++) {
+ list_for_each_entry(client, &client_list, node) {
+ if (client->threshold[ch] == 0)
+ continue;
+ amba_writel(ADC_CHAN_INTR_REG(ch), client->threshold[ch]);
+ }
+ }
+
+exit:
+ return 0;
+}
+#endif
+
+static const struct of_device_id ambarella_adc_dt_ids[] = {
+ {.compatible = "ambarella,adc", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ambarella_adc_dt_ids);
+
+static struct platform_driver ambarella_adc_driver = {
+ .driver = {
+ .name = "ambarella-adc",
+ .owner = THIS_MODULE,
+ .of_match_table = ambarella_adc_dt_ids,
+ },
+ .probe = ambarella_adc_probe,
+ .remove = ambarella_adc_remove,
+#ifdef CONFIG_PM
+ .suspend = ambarella_adc_suspend,
+ .resume = ambarella_adc_resume,
+#endif
+};
+
+module_platform_driver(ambarella_adc_driver);
+MODULE_AUTHOR("BingLiang Hu <blhu@ambarella.com>");
+MODULE_DESCRIPTION("Ambarella ADC Driver");
+MODULE_LICENSE("GPL");
+
diff --git a/arch/arm/mach-ambarella/clk.c b/arch/arm/mach-ambarella/clk.c
new file mode 100644
index 00000000..d06365f0
--- /dev/null
+++ b/arch/arm/mach-ambarella/clk.c
@@ -0,0 +1,1232 @@
+/*
+ * arch/arm/mach-ambarella/clk.c
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/clk.h>
+#include <asm/uaccess.h>
+#include <mach/hardware.h>
+#include <plat/iav_helper.h>
+#include <plat/sd.h>
+#include <plat/clk.h>
+
+/* ==========================================================================*/
+static LIST_HEAD(ambarella_all_clocks);
+DEFINE_SPINLOCK(ambarella_clock_lock);
+struct ambarella_service pll_service;
+
+/* ==========================================================================*/
+static unsigned int ambarella_clk_ref_freq = REF_CLK_FREQ;
+
+unsigned int ambarella_clk_get_ref_freq(void)
+{
+ return ambarella_clk_ref_freq;
+}
+EXPORT_SYMBOL(ambarella_clk_get_ref_freq);
+
+/* ==========================================================================*/
+
+struct clk_ops ambarella_rct_scaler_ops = {
+ .enable = NULL,
+ .disable = NULL,
+ .get_rate = ambarella_rct_scaler_get_rate,
+ .round_rate = NULL,
+ .set_rate = ambarella_rct_scaler_set_rate,
+ .set_parent = NULL,
+};
+EXPORT_SYMBOL(ambarella_rct_scaler_ops);
+
+struct clk_ops ambarella_rct_pll_ops = {
+ .enable = ambarella_rct_clk_enable,
+ .disable = ambarella_rct_clk_disable,
+ .get_rate = ambarella_rct_clk_get_rate,
+ .round_rate = NULL,
+ .set_rate = ambarella_rct_clk_set_rate,
+ .set_parent = NULL,
+};
+EXPORT_SYMBOL(ambarella_rct_pll_ops);
+
+struct clk_ops ambarella_rct_adj_ops = {
+ .enable = ambarella_rct_clk_enable,
+ .disable = ambarella_rct_clk_disable,
+ .get_rate = ambarella_rct_clk_get_rate,
+ .round_rate = NULL,
+ .set_rate = ambarella_rct_clk_adj_rate,
+ .set_parent = NULL,
+};
+EXPORT_SYMBOL(ambarella_rct_adj_ops);
+
+/* ==========================================================================*/
+
+int ambarella_rct_clk_enable(struct clk *c)
+{
+ union ctrl_reg_u ctrl_reg;
+
+ if (c->ctrl_reg == -1) {
+ return -1;
+ }
+
+ ctrl_reg.w = amba_rct_readl(c->ctrl_reg);
+ ctrl_reg.s.power_down = 0;
+ ctrl_reg.s.halt_vco = 0;
+ ctrl_reg.s.write_enable = 1;
+ amba_rct_writel(c->ctrl_reg, ctrl_reg.w);
+
+ ctrl_reg.s.write_enable = 0;
+ amba_rct_writel(c->ctrl_reg, ctrl_reg.w);
+
+ c->rate = ambarella_rct_clk_get_rate(c);
+
+ return 0;
+}
+EXPORT_SYMBOL(ambarella_rct_clk_enable);
+
+int ambarella_rct_clk_disable(struct clk *c)
+{
+ union ctrl_reg_u ctrl_reg;
+
+ if (c->ctrl_reg == -1) {
+ return -1;
+ }
+
+ ctrl_reg.w = amba_rct_readl(c->ctrl_reg);
+ ctrl_reg.s.power_down = 1;
+ ctrl_reg.s.halt_vco = 1;
+ ctrl_reg.s.write_enable = 1;
+ amba_rct_writel(c->ctrl_reg, ctrl_reg.w);
+
+ ctrl_reg.s.write_enable = 0;
+ amba_rct_writel(c->ctrl_reg, ctrl_reg.w);
+
+ c->rate = ambarella_rct_clk_get_rate(c);
+
+ return 0;
+}
+EXPORT_SYMBOL(ambarella_rct_clk_disable);
+
+
+/* ==========================================================================*/
+unsigned long ambarella_rct_scaler_get_rate(struct clk *c)
+{
+ u32 parent_rate, divider;
+
+ if (!c->parent || !c->parent->ops || !c->parent->ops->get_rate)
+ parent_rate = ambarella_clk_get_ref_freq();
+ else
+ parent_rate = c->parent->ops->get_rate(c->parent);
+
+ if (c->divider) {
+ c->rate = parent_rate / c->divider;
+ return c->rate;
+ } else if (c->post_reg != -1) {
+ divider = amba_rct_readl(c->post_reg);
+ if (c->extra_scaler == 1) {
+ divider >>= 4;
+ divider++;
+ }
+ if (divider) {
+ c->rate = parent_rate / divider;
+ return c->rate;
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(ambarella_rct_scaler_get_rate);
+
+int ambarella_rct_scaler_set_rate(struct clk *c, unsigned long rate)
+{
+ u32 parent_rate, divider, post_scaler;
+
+ if (!rate)
+ return -1;
+
+ BUG_ON(c->post_reg == -1 || !c->max_divider);
+
+ if (!c->parent || !c->parent->ops || !c->parent->ops->get_rate)
+ parent_rate = ambarella_clk_get_ref_freq();
+ else
+ parent_rate = c->parent->ops->get_rate(c->parent);
+
+ if (c->divider)
+ rate *= c->divider;
+
+ divider = (parent_rate + rate - 1) / rate;
+ if (!divider)
+ return -1;
+
+ post_scaler = min(divider, c->max_divider);
+ if (c->extra_scaler == 1) {
+ post_scaler--;
+ post_scaler <<= 4;
+ amba_rct_writel_en(c->post_reg, post_scaler);
+ } else {
+ amba_rct_writel(c->post_reg, post_scaler);
+ }
+
+ c->rate = ambarella_rct_scaler_get_rate(c);
+
+ return 0;
+}
+EXPORT_SYMBOL(ambarella_rct_scaler_set_rate);
+
+unsigned long ambarella_rct_clk_get_rate(struct clk *c)
+{
+ u32 pre_scaler, post_scaler, intp, sdiv, sout;
+ u64 dividend, divider, frac;
+ union ctrl_reg_u ctrl_reg;
+ union frac_reg_u frac_reg;
+
+ BUG_ON(c->ctrl_reg == -1 || c->frac_reg == -1);
+
+ ctrl_reg.w = amba_rct_readl(c->ctrl_reg);
+ if ((ctrl_reg.s.power_down == 1) || (ctrl_reg.s.halt_vco == 1)) {
+ c->rate = 0;
+ return c->rate;
+ }
+
+ frac_reg.w = amba_rct_readl(c->frac_reg);
+
+ if (c->pres_reg != -1) {
+ pre_scaler = amba_rct_readl(c->pres_reg);
+ if (c->extra_scaler == 1) {
+ pre_scaler >>= 4;
+ pre_scaler++;
+ }
+ } else {
+ pre_scaler = 1;
+ }
+
+ if (c->post_reg != -1) {
+ post_scaler = amba_rct_readl(c->post_reg);
+ if (c->extra_scaler == 1) {
+ post_scaler >>= 4;
+ post_scaler++;
+ }
+ } else {
+ post_scaler = 1;
+ }
+
+ if (ctrl_reg.s.bypass || ctrl_reg.s.force_bypass) {
+ c->rate = ambarella_clk_get_ref_freq() / pre_scaler / post_scaler;
+ return c->rate;
+ }
+
+ intp = ctrl_reg.s.intp + 1;
+ sdiv = ctrl_reg.s.sdiv + 1;
+ sout = ctrl_reg.s.sout + 1;
+
+ dividend = (u64)ambarella_clk_get_ref_freq();
+ dividend *= (u64)intp;
+ dividend *= (u64)sdiv;
+ if (ctrl_reg.s.frac_mode) {
+ if (frac_reg.s.nega) {
+ /* Negative */
+ frac = (0x80000000 - frac_reg.s.frac);
+ frac = (ambarella_clk_get_ref_freq() * frac * sdiv);
+ frac >>= 32;
+ dividend = dividend - frac;
+ } else {
+ /* Positive */
+ frac = frac_reg.s.frac;
+ frac = (ambarella_clk_get_ref_freq() * frac * sdiv);
+ frac >>= 32;
+ dividend = dividend + frac;
+ }
+ }
+
+ divider = pre_scaler * sout * post_scaler;
+ if (c->divider)
+ divider *= c->divider;
+
+ if (divider == 0) {
+ c->rate = 0;
+ return c->rate;
+ }
+
+ AMBCLK_DO_DIV(dividend, divider);
+ c->rate = dividend;
+
+ return c->rate;
+}
+EXPORT_SYMBOL(ambarella_rct_clk_get_rate);
+
+
+int ambarella_rct_clk_adj_rate(struct clk *c, unsigned long rate)
+{
+ union ctrl_reg_u ctrl_reg;
+ u32 curr_rate;
+ u32 IntStepPllOut24MHz;
+ u32 TargetIntp;
+
+ /* get current PLL control registers' values */
+ ctrl_reg.w = amba_rct_readl(c->ctrl_reg);
+
+ if (ctrl_reg.s.sdiv >= ctrl_reg.s.sout) {
+ while (ctrl_reg.s.sdiv > ctrl_reg.s.sout) {
+ ctrl_reg.s.sdiv--;
+ amba_rct_writel(c->ctrl_reg, ctrl_reg.w);
+ }
+ IntStepPllOut24MHz = 1;
+ } else {
+ IntStepPllOut24MHz = (ctrl_reg.s.sout + 1) / (ctrl_reg.s.sdiv + 1);
+ }
+
+ curr_rate = ambarella_rct_clk_get_rate(c);
+ TargetIntp = rate * (ctrl_reg.s.sout + 1) / ((ctrl_reg.s.sdiv + 1) * REF_CLK_FREQ) - 1;
+
+ if (curr_rate > rate) {
+ /* decrease the frequency */
+ while (curr_rate > rate && ctrl_reg.s.intp > 0) {
+ if (ctrl_reg.s.intp - TargetIntp >= IntStepPllOut24MHz)
+ ctrl_reg.s.intp -= IntStepPllOut24MHz;
+ else
+ ctrl_reg.s.intp--;
+
+ amba_rct_writel_en(c->ctrl_reg, ctrl_reg.w);
+ curr_rate = ambarella_rct_clk_get_rate(c);
+ }
+ } else {
+ /* increase the frequency */
+ if (TargetIntp > 123)
+ TargetIntp = 123;
+
+ while (curr_rate < rate && ctrl_reg.s.intp < 123) {
+ if (TargetIntp - ctrl_reg.s.intp >= IntStepPllOut24MHz)
+ ctrl_reg.s.intp += IntStepPllOut24MHz;
+ else
+ ctrl_reg.s.intp++;
+
+ amba_rct_writel_en(c->ctrl_reg, ctrl_reg.w);
+ curr_rate = ambarella_rct_clk_get_rate(c);
+ }
+
+ if (curr_rate > rate && ctrl_reg.s.intp > 6) {
+ /* decrease the frequency so that is it is just below expected */
+ ctrl_reg.s.intp--;
+ amba_rct_writel_en(c->ctrl_reg, ctrl_reg.w);
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(ambarella_rct_clk_adj_rate);
+
+/* ==========================================================================*/
+struct clk *clk_get_sys(const char *dev_id, const char *con_id)
+{
+ struct clk *p;
+ struct clk *clk = ERR_PTR(-ENOENT);
+
+ spin_lock(&ambarella_clock_lock);
+ list_for_each_entry(p, &ambarella_all_clocks, list) {
+ if (dev_id && (strcmp(p->name, dev_id) == 0)) {
+ clk = p;
+ break;
+ }
+ if (con_id && (strcmp(p->name, con_id) == 0)) {
+ clk = p;
+ break;
+ }
+ }
+ spin_unlock(&ambarella_clock_lock);
+
+ return clk;
+}
+EXPORT_SYMBOL(clk_get_sys);
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+ struct clk *p;
+ struct clk *clk = ERR_PTR(-ENOENT);
+
+ if (id == NULL) {
+ return clk;
+ }
+
+ spin_lock(&ambarella_clock_lock);
+ list_for_each_entry(p, &ambarella_all_clocks, list) {
+ if (strcmp(p->name, id) == 0) {
+ clk = p;
+ break;
+ }
+ }
+ spin_unlock(&ambarella_clock_lock);
+
+ return clk;
+}
+EXPORT_SYMBOL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_put);
+
+int clk_enable(struct clk *clk)
+{
+ if (IS_ERR(clk) || (clk == NULL)) {
+ return -EINVAL;
+ }
+
+ clk_enable(clk->parent);
+
+ spin_lock(&ambarella_clock_lock);
+ if (clk->ops && clk->ops->enable) {
+ (clk->ops->enable)(clk);
+ }
+ spin_unlock(&ambarella_clock_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+ if (IS_ERR(clk) || (clk == NULL)) {
+ return;
+ }
+
+ spin_lock(&ambarella_clock_lock);
+ if (clk->ops && clk->ops->disable) {
+ (clk->ops->disable)(clk);
+ }
+ spin_unlock(&ambarella_clock_lock);
+
+ clk_disable(clk->parent);
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (IS_ERR(clk) || (clk == NULL)) {
+ return 0;
+ }
+
+ if (clk->ops != NULL && clk->ops->get_rate != NULL) {
+ return (clk->ops->get_rate)(clk);
+ }
+
+ if (clk->parent != NULL) {
+ return clk_get_rate(clk->parent);
+ }
+
+ return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (IS_ERR(clk) || (clk == NULL)) {
+ return rate;
+ }
+
+ if (clk->ops && clk->ops->round_rate) {
+ return (clk->ops->round_rate)(clk, rate);
+ }
+
+ return rate;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret;
+
+ if (IS_ERR(clk) || (clk == NULL)) {
+ return -EINVAL;
+ }
+
+ if ((clk->ops == NULL) || (clk->ops->set_rate == NULL)) {
+ return -EINVAL;
+ }
+
+ spin_lock(&ambarella_clock_lock);
+ ret = (clk->ops->set_rate)(clk, rate);
+ spin_unlock(&ambarella_clock_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+ if (IS_ERR(clk) || (clk == NULL)) {
+ return ERR_PTR(-EINVAL);
+ }
+
+ return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ int ret = 0;
+
+ if (IS_ERR(clk) || (clk == NULL)) {
+ return -EINVAL;
+ }
+
+ spin_lock(&ambarella_clock_lock);
+ if (clk->ops && clk->ops->set_parent) {
+ ret = (clk->ops->set_parent)(clk, parent);
+ }
+ spin_unlock(&ambarella_clock_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+int ambarella_clk_add(struct clk *clk)
+{
+ struct clk *p;
+
+ if (IS_ERR(clk) || (clk == NULL))
+ return -EINVAL;
+
+ spin_lock(&ambarella_clock_lock);
+ list_for_each_entry(p, &ambarella_all_clocks, list) {
+ if (clk == p) {
+ pr_err("clk %s is existed\n", clk->name);
+ spin_unlock(&ambarella_clock_lock);
+ return -EEXIST;
+ }
+ }
+ list_add(&clk->list, &ambarella_all_clocks);
+ spin_unlock(&ambarella_clock_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(ambarella_clk_add);
+
+/* ==========================================================================*/
+#if defined(CONFIG_AMBARELLA_PLL_PROC)
+static int ambarella_clock_proc_show(struct seq_file *m, void *v)
+{
+ int retlen = 0;
+ struct clk *p;
+
+ retlen += seq_printf(m, "\nClock Information:\n");
+ spin_lock(&ambarella_clock_lock);
+ list_for_each_entry_reverse(p, &ambarella_all_clocks, list) {
+ retlen += seq_printf(m, "\t%s:\t%lu Hz\n",
+ p->name, p->ops->get_rate(p));
+ }
+ spin_unlock(&ambarella_clock_lock);
+
+ return retlen;
+}
+
+static int ambarella_clock_proc_write(struct file *file,
+ const char __user *buffer, size_t count, loff_t *ppos)
+{
+ struct clk *gclk;
+ char *buf, clk_name[32];
+ int freq, rval = count;
+
+ pr_warn("!!!DANGEROUS!!! You must know what you are doning!\n");
+
+ buf = kmalloc(count, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ if (copy_from_user(buf, buffer, count)) {
+ rval = -EFAULT;
+ goto exit;
+ }
+
+ sscanf(buf, "%s %d", clk_name, &freq);
+
+ gclk = clk_get(NULL, clk_name);
+ if (IS_ERR(gclk)) {
+ pr_err("Invalid clk name\n");
+ rval = -EINVAL;
+ goto exit;
+ }
+
+ clk_set_rate(gclk, freq);
+
+exit:
+ kfree(buf);
+ return rval;
+}
+
+static int ambarella_clock_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ambarella_clock_proc_show, PDE_DATA(inode));
+}
+
+static const struct file_operations proc_clock_fops = {
+ .open = ambarella_clock_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .write = ambarella_clock_proc_write,
+};
+#endif
+
+/* ==========================================================================*/
+int __init ambarella_clk_init(void)
+{
+ int ret_val = 0;
+
+#if defined(CONFIG_AMBARELLA_PLL_PROC)
+ proc_create_data("clock", S_IRUGO, get_ambarella_proc_dir(),
+ &proc_clock_fops, NULL);
+#endif
+
+ return ret_val;
+}
+
+/* ==========================================================================*/
+
+static struct clk pll_out_core = {
+ .parent = NULL,
+ .name = "pll_out_core",
+ .rate = 0,
+ .frac_mode = 0,
+ .ctrl_reg = PLL_CORE_CTRL_REG,
+ .pres_reg = -1,
+ .post_reg = -1,
+ .frac_reg = PLL_CORE_FRAC_REG,
+ .ctrl2_reg = PLL_CORE_CTRL2_REG,
+ .ctrl3_reg = PLL_CORE_CTRL3_REG,
+ .lock_reg = PLL_LOCK_REG,
+ .lock_bit = 6,
+ .divider = 0,
+ .max_divider = 0,
+ .extra_scaler = 0,
+ .table = ambarella_pll_int_table,
+ .table_size = ARRAY_SIZE(ambarella_pll_int_table),
+ .ops = &ambarella_rct_adj_ops,
+};
+
+static struct clk gclk_core = {
+ .parent = &pll_out_core,
+ .name = "gclk_core",
+ .rate = 0,
+ .frac_mode = 0,
+ .ctrl_reg = -1,
+ .pres_reg = -1,
+#if ((CHIP_REV == A5S) || (CHIP_REV == S2) || (CHIP_REV == S2E))
+ .post_reg = SCALER_CORE_POST_REG,
+#else
+ .post_reg = -1,
+#endif
+ .frac_reg = -1,
+ .ctrl2_reg = -1,
+ .ctrl3_reg = -1,
+ .lock_reg = -1,
+ .lock_bit = 0,
+#if ((CHIP_REV == A5S) || (CHIP_REV == S2) || (CHIP_REV == S2E))
+ .divider = 0,
+ .max_divider = (1 << 4) - 1,
+#else
+ .divider = 2,
+ .max_divider = 0,
+#endif
+ .extra_scaler = 0,
+ .ops = &ambarella_rct_scaler_ops,
+};
+
+static struct clk gclk_ahb = {
+ .parent = &gclk_core,
+ .name = "gclk_ahb",
+ .rate = 0,
+ .frac_mode = 0,
+ .ctrl_reg = -1,
+ .pres_reg = -1,
+ .post_reg = -1,
+ .frac_reg = -1,
+ .ctrl2_reg = -1,
+ .ctrl3_reg = -1,
+ .lock_reg = -1,
+ .lock_bit = 0,
+#if (CHIP_REV == A5S)
+ .divider = 1,
+#else
+ .divider = 2,
+#endif
+ .max_divider = 0,
+ .extra_scaler = 0,
+ .ops = &ambarella_rct_scaler_ops,
+};
+
+static struct clk gclk_apb = {
+ .parent = &gclk_ahb,
+ .name = "gclk_apb",
+ .rate = 0,
+ .frac_mode = 0,
+ .ctrl_reg = -1,
+ .pres_reg = -1,
+ .post_reg = -1,
+ .frac_reg = -1,
+ .ctrl2_reg = -1,
+ .ctrl3_reg = -1,
+ .lock_reg = -1,
+ .lock_bit = 0,
+ .divider = 2,
+ .max_divider = 0,
+ .extra_scaler = 0,
+ .ops = &ambarella_rct_scaler_ops,
+};
+
+static struct clk gclk_ddr = {
+ .parent = NULL,
+ .name = "gclk_ddr",
+ .rate = 0,
+ .frac_mode = 0,
+ .ctrl_reg = PLL_DDR_CTRL_REG,
+ .pres_reg = -1,
+ .post_reg = -1,
+ .frac_reg = PLL_DDR_FRAC_REG,
+ .ctrl2_reg = PLL_DDR_CTRL2_REG,
+ .ctrl3_reg = PLL_DDR_CTRL3_REG,
+ .lock_reg = PLL_LOCK_REG,
+ .lock_bit = 5,
+ .divider = 2,
+ .max_divider = 0,
+ .extra_scaler = 0,
+ .table = ambarella_pll_int_table,
+ .table_size = ARRAY_SIZE(ambarella_pll_int_table),
+ .ops = &ambarella_rct_adj_ops,
+};
+
+/* ==========================================================================*/
+#if defined(CONFIG_PLAT_AMBARELLA_CORTEX)
+static struct clk gclk_cortex = {
+ .parent = NULL,
+ .name = "gclk_cortex",
+ .rate = 0,
+ .frac_mode = 0,
+ .ctrl_reg = PLL_CORTEX_CTRL_REG,
+ .pres_reg = -1,
+ .post_reg = -1,
+ .frac_reg = PLL_CORTEX_FRAC_REG,
+ .ctrl2_reg = PLL_CORTEX_CTRL2_REG,
+ .ctrl3_reg = PLL_CORTEX_CTRL3_REG,
+ .lock_reg = PLL_LOCK_REG,
+ .lock_bit = 2,
+ .divider = 0,
+ .max_divider = 0,
+ .extra_scaler = 0,
+ .table = ambarella_pll_int_table,
+ .table_size = ARRAY_SIZE(ambarella_pll_int_table),
+ .ops = &ambarella_rct_adj_ops,
+};
+static struct clk gclk_axi = {
+ .parent = &gclk_cortex,
+ .name = "gclk_axi",
+ .rate = 0,
+ .frac_mode = 0,
+ .ctrl_reg = -1,
+ .pres_reg = -1,
+ .post_reg = -1,
+ .frac_reg = -1,
+ .ctrl2_reg = -1,
+ .ctrl3_reg = -1,
+ .lock_reg = -1,
+ .lock_bit = 0,
+ .divider = 3,
+ .max_divider = 0,
+ .extra_scaler = 0,
+ .ops = &ambarella_rct_scaler_ops,
+};
+#if defined(CONFIG_HAVE_ARM_TWD)
+static struct clk clk_smp_twd = {
+ .parent = &gclk_axi,
+ .name = "smp_twd",
+ .rate = 0,
+ .frac_mode = 0,
+ .ctrl_reg = -1,
+ .pres_reg = -1,
+ .post_reg = -1,
+ .frac_reg = -1,
+ .ctrl2_reg = -1,
+ .ctrl3_reg = -1,
+ .lock_reg = -1,
+ .lock_bit = 0,
+ .divider = 1,
+ .max_divider = 0,
+ .extra_scaler = 0,
+ .ops = &ambarella_rct_scaler_ops,
+};
+#endif
+#endif
+
+static struct clk gclk_idsp = {
+ .parent = NULL,
+ .name = "gclk_idsp",
+ .rate = 0,
+ .frac_mode = 0,
+ .ctrl_reg = PLL_IDSP_CTRL_REG,
+ .pres_reg = -1,
+ .post_reg = SCALER_IDSP_POST_REG,
+ .frac_reg = PLL_IDSP_FRAC_REG,
+ .ctrl2_reg = PLL_IDSP_CTRL2_REG,
+ .ctrl3_reg = PLL_IDSP_CTRL3_REG,
+ .lock_reg = PLL_LOCK_REG,
+ .lock_bit = 4,
+ .divider = 0,
+ .max_divider = (1 << 4) - 1,
+#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+ .extra_scaler = 1,
+#else
+ .extra_scaler = 0,
+#endif
+ .table = ambarella_pll_int_table,
+ .table_size = ARRAY_SIZE(ambarella_pll_int_table),
+ .ops = &ambarella_rct_pll_ops,
+};
+
+#ifdef CONFIG_AMBARELLA_CALC_PLL
+static struct clk gclk_so = {
+ .parent = NULL,
+ .name = "gclk_so",
+ .rate = 0,
+ .frac_mode = 1,
+ .ctrl_reg = PLL_SENSOR_CTRL_REG,
+ .pres_reg = SCALER_SENSOR_PRE_REG,
+ .post_reg = SCALER_SENSOR_POST_REG,
+ .frac_reg = PLL_SENSOR_FRAC_REG,
+ .ctrl2_reg = PLL_SENSOR_CTRL2_REG,
+ .ctrl3_reg = PLL_SENSOR_CTRL3_REG,
+ .lock_reg = PLL_LOCK_REG,
+ .lock_bit = 3,
+ .divider = 0,
+ .max_divider = (1 << 4) - 1,
+#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+ .max_divider = (1 << 4) - 1,
+ .extra_scaler = 1,
+#else
+ .max_divider = (1 << 16) - 1,
+ .extra_scaler = 0,
+#endif
+ .ops = &ambarella_rct_pll_ops,
+};
+
+static struct clk gclk_vo = {
+ .parent = NULL,
+ .name = "gclk_vo",
+ .rate = 0,
+ .frac_mode = 1,
+ .ctrl_reg = PLL_HDMI_CTRL_REG,
+ .pres_reg = SCALER_HDMI_PRE_REG,
+ .post_reg = -1,
+ .frac_reg = PLL_HDMI_FRAC_REG,
+ .ctrl2_reg = PLL_HDMI_CTRL2_REG,
+#if (CHIP_REV == S2E) || (CHIP_REV == S3L)
+ .ctrl2_val = 0x3f770b00,
+#endif
+ .ctrl3_reg = PLL_HDMI_CTRL3_REG,
+ .lock_reg = PLL_LOCK_REG,
+ .lock_bit = 8,
+ .divider = 10,
+#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+ .max_divider = (1 << 4) - 1,
+ .extra_scaler = 1,
+#else
+ .max_divider = (1 << 16) - 1,
+ .extra_scaler = 0,
+#endif
+ .ops = &ambarella_rct_pll_ops,
+};
+
+static struct clk gclk_vo2 = {
+ .parent = NULL,
+ .name = "gclk_vo2",
+ .rate = 0,
+ .frac_mode = 1,
+ .ctrl_reg = PLL_VIDEO2_CTRL_REG,
+ .pres_reg = SCALER_VIDEO2_PRE_REG,
+ .post_reg = SCALER_VIDEO2_POST_REG,
+ .frac_reg = PLL_VIDEO2_FRAC_REG,
+ .ctrl2_reg = PLL_VIDEO2_CTRL2_REG,
+ .ctrl3_reg = PLL_VIDEO2_CTRL3_REG,
+ .lock_reg = PLL_LOCK_REG,
+ .lock_bit = 0,
+ .divider = 0,
+#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+ .max_divider = (1 << 4) - 1,
+ .extra_scaler = 1,
+#else
+ .max_divider = (1 << 16) - 1,
+ .extra_scaler = 0,
+#endif
+ .ops = &ambarella_rct_pll_ops,
+};
+#endif
+
+static struct clk gclk_uart = {
+#if (CHIP_REV == S2E)
+ .parent = &gclk_idsp,
+#else
+ .parent = NULL,
+#endif
+ .name = "gclk_uart",
+ .rate = 0,
+ .frac_mode = 0,
+ .ctrl_reg = -1,
+ .pres_reg = -1,
+ .post_reg = CG_UART_REG,
+ .frac_reg = -1,
+ .ctrl2_reg = -1,
+ .ctrl3_reg = -1,
+ .lock_reg = -1,
+ .lock_bit = 0,
+ .divider = 0,
+ .max_divider = (1 << 24) - 1,
+ .extra_scaler = 0,
+ .ops = &ambarella_rct_scaler_ops,
+};
+
+static struct clk gclk_audio = {
+ .parent = NULL,
+ .name = "gclk_audio",
+ .rate = 0,
+ .frac_mode = 1,
+ .ctrl_reg = PLL_AUDIO_CTRL_REG,
+ .pres_reg = SCALER_AUDIO_PRE_REG,
+ .post_reg = SCALER_AUDIO_POST_REG,
+ .frac_reg = PLL_AUDIO_FRAC_REG,
+ .ctrl2_reg = PLL_AUDIO_CTRL2_REG,
+ .ctrl3_reg = PLL_AUDIO_CTRL3_REG,
+ .lock_reg = PLL_LOCK_REG,
+ .lock_bit = 7,
+ .divider = 0,
+#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+ .max_divider = (1 << 4) - 1,
+ .extra_scaler = 1,
+#else
+ .max_divider = (1 << 16) - 1,
+ .extra_scaler = 0,
+#endif
+ .table = ambarella_pll_frac_table,
+ .table_size = ARRAY_SIZE(ambarella_pll_frac_table),
+ .ops = &ambarella_rct_pll_ops,
+};
+
+#if (CHIP_REV == S2E) || (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+static struct clk pll_out_sd = {
+ .parent = NULL,
+ .name = "pll_out_sd",
+ .rate = 0,
+ .frac_mode = 1,
+ .ctrl_reg = PLL_SD_CTRL_REG,
+ .pres_reg = -1,
+ .post_reg = -1,
+ .frac_reg = PLL_SD_FRAC_REG,
+ .ctrl2_reg = PLL_SD_CTRL2_REG,
+ .ctrl3_reg = PLL_SD_CTRL3_REG,
+ .lock_reg = PLL_LOCK_REG,
+ .lock_bit = 12,
+ .divider = 0,
+ .max_divider = 0,
+ .extra_scaler = 0,
+ .table = ambarella_pll_int_table,
+ .table_size = ARRAY_SIZE(ambarella_pll_int_table),
+ .ops = &ambarella_rct_pll_ops,
+};
+#endif
+
+#if (SD_SUPPORT_SDXC == 1)
+static struct clk gclk_sdxc = {
+ .parent = &pll_out_sd,
+ .name = "gclk_sdxc",
+ .rate = 0,
+ .frac_mode = 0,
+ .ctrl_reg = -1,
+ .pres_reg = -1,
+ .post_reg = SCALER_SDXC_REG,
+ .frac_reg = -1,
+ .ctrl2_reg = -1,
+ .ctrl3_reg = -1,
+ .lock_reg = -1,
+ .lock_bit = 0,
+ .divider = 0,
+ .max_divider = (1 << 16) - 1,
+ .extra_scaler = 0,
+ .ops = &ambarella_rct_scaler_ops,
+};
+#endif
+
+#if (SD_SUPPORT_SDIO == 1)
+static struct clk gclk_sdio = {
+#if (CHIP_REV == S2E) || (CHIP_REV == S2L) || (CHIP_REV == S3)
+ .parent = &pll_out_sd,
+#else
+ .parent = &pll_out_core,
+#endif
+ .name = "gclk_sdio",
+ .rate = 0,
+ .frac_mode = 0,
+ .ctrl_reg = -1,
+ .pres_reg = -1,
+ .post_reg = SCALER_SDIO_REG,
+ .frac_reg = -1,
+ .ctrl2_reg = -1,
+ .ctrl3_reg = -1,
+ .lock_reg = -1,
+ .lock_bit = 0,
+ .divider = 0,
+ .max_divider = (1 << 16) - 1,
+ .extra_scaler = 0,
+ .ops = &ambarella_rct_scaler_ops,
+};
+#endif
+
+static struct clk gclk_sd = {
+#if (CHIP_REV == S2E) || (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+ .parent = &pll_out_sd,
+#else
+ .parent = &pll_out_core,
+#endif
+ .name = "gclk_sd",
+ .rate = 0,
+ .frac_mode = 0,
+ .ctrl_reg = -1,
+ .pres_reg = -1,
+ .post_reg = SCALER_SD48_REG,
+ .frac_reg = -1,
+ .ctrl2_reg = -1,
+ .ctrl3_reg = -1,
+ .lock_reg = -1,
+ .lock_bit = 0,
+ .divider = 0,
+ .max_divider = (1 << 16) - 1,
+ .extra_scaler = 0,
+ .ops = &ambarella_rct_scaler_ops,
+};
+
+static struct clk gclk_ir = {
+ .parent = NULL,
+ .name = "gclk_ir",
+ .rate = 0,
+ .frac_mode = 0,
+ .ctrl_reg = -1,
+ .pres_reg = -1,
+ .post_reg = CG_IR_REG,
+ .frac_reg = -1,
+ .ctrl2_reg = -1,
+ .ctrl3_reg = -1,
+ .lock_reg = -1,
+ .lock_bit = 0,
+ .divider = 0,
+ .max_divider = (1 << 24) - 1,
+ .extra_scaler = 0,
+ .ops = &ambarella_rct_scaler_ops,
+};
+
+static struct clk gclk_adc = {
+ .parent = NULL,
+ .name = "gclk_adc",
+ .rate = 0,
+ .frac_mode = 0,
+ .ctrl_reg = -1,
+ .pres_reg = -1,
+ .post_reg = SCALER_ADC_REG,
+ .frac_reg = -1,
+ .ctrl2_reg = -1,
+ .ctrl3_reg = -1,
+ .lock_reg = -1,
+ .lock_bit = 0,
+ .divider = 2,
+ .max_divider = (1 << 16) - 1,
+ .extra_scaler = 0,
+ .ops = &ambarella_rct_scaler_ops,
+};
+
+static struct clk gclk_ssi = { /* for SSI master */
+#if (CHIP_REV == A5S) || (CHIP_REV == S2) || (CHIP_REV == S2E)
+ .parent = &gclk_apb,
+#else
+ .parent = &pll_out_core,
+#endif
+ .name = "gclk_ssi",
+ .rate = 0,
+ .frac_mode = 0,
+ .ctrl_reg = -1,
+ .pres_reg = -1,
+ .post_reg = CG_SSI_REG,
+ .frac_reg = -1,
+ .ctrl2_reg = -1,
+ .ctrl3_reg = -1,
+ .lock_reg = -1,
+ .lock_bit = 0,
+ .divider = 0,
+ .max_divider = (1 << 24) - 1,
+ .extra_scaler = 0,
+ .ops = &ambarella_rct_scaler_ops,
+};
+
+static struct clk gclk_ssi2 = { /* for SSI slave */
+#if (CHIP_REV == A5S) || (CHIP_REV == S2) || (CHIP_REV == S2E)
+ .parent = &gclk_apb,
+#else
+ .parent = &pll_out_core,
+#endif
+ .name = "gclk_ssi2",
+ .rate = 0,
+ .frac_mode = 0,
+ .ctrl_reg = -1,
+ .pres_reg = -1,
+ .post_reg = CG_SSI2_REG,
+ .frac_reg = -1,
+ .ctrl2_reg = -1,
+ .ctrl3_reg = -1,
+ .lock_reg = -1,
+ .lock_bit = 0,
+ .divider = 0,
+ .max_divider = (1 << 24) - 1,
+ .extra_scaler = 0,
+ .ops = &ambarella_rct_scaler_ops,
+};
+
+#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+static struct clk gclk_ssi3 = { /* for SPINOR */
+ /* TODO: parent is determined by CLK_REF_SSI3_REG */
+ .parent = &pll_out_core,
+ .name = "gclk_ssi3",
+ .rate = 0,
+ .frac_mode = 0,
+ .ctrl_reg = -1,
+ .pres_reg = -1,
+ .post_reg = CG_SSI3_REG,
+ .frac_reg = -1,
+ .ctrl2_reg = -1,
+ .ctrl3_reg = -1,
+ .lock_reg = -1,
+ .lock_bit = 0,
+ .divider = 0,
+ .max_divider = (1 << 24) - 1,
+ .extra_scaler = 0,
+ .ops = &ambarella_rct_scaler_ops,
+};
+#endif
+
+static struct clk gclk_pwm = {
+ .parent = &gclk_apb,
+ .name = "gclk_pwm",
+ .rate = 0,
+ .frac_mode = 0,
+ .ctrl_reg = -1,
+ .pres_reg = -1,
+ .post_reg = CG_PWM_REG,
+ .frac_reg = -1,
+ .ctrl2_reg = -1,
+ .ctrl3_reg = -1,
+ .lock_reg = -1,
+ .lock_bit = 0,
+ .divider = 0,
+ .max_divider = (1 << 24) - 1,
+ .extra_scaler = 0,
+ .ops = &ambarella_rct_scaler_ops,
+};
+
+static int ambarella_pll_service(void *arg, void *result)
+{
+ struct ambsvc_pll *pll_svc = arg;
+ struct clk *clk;
+ int rval = 0;
+
+ BUG_ON(!pll_svc || !pll_svc->name);
+
+ clk = clk_get(NULL, pll_svc->name);
+ if (IS_ERR(clk)) {
+ pr_err("%s: ERR get %s\n", __func__, pll_svc->name);
+ return -EINVAL;
+ }
+
+ switch (pll_svc->svc_id) {
+ case AMBSVC_PLL_GET_RATE:
+ pll_svc->rate = clk_get_rate(clk);
+ break;
+ case AMBSVC_PLL_SET_RATE:
+ clk_set_rate(clk, pll_svc->rate);
+ break;
+
+ default:
+ pr_err("%s: Invalid pll service (%d)\n", __func__, pll_svc->svc_id);
+ rval = -EINVAL;
+ break;
+ }
+
+ return rval;
+}
+
+void ambarella_init_early(void)
+{
+ ambarella_clk_add(&pll_out_core);
+#if (CHIP_REV == S2E) || (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+ ambarella_clk_add(&pll_out_sd);
+#endif
+#if defined(CONFIG_PLAT_AMBARELLA_CORTEX)
+ ambarella_clk_add(&gclk_cortex);
+ ambarella_clk_add(&gclk_axi);
+#if defined(CONFIG_HAVE_ARM_TWD)
+ ambarella_clk_add(&clk_smp_twd);
+#endif
+#endif
+ ambarella_clk_add(&gclk_ddr);
+ ambarella_clk_add(&gclk_core);
+ ambarella_clk_add(&gclk_ahb);
+ ambarella_clk_add(&gclk_apb);
+ ambarella_clk_add(&gclk_idsp);
+#ifdef CONFIG_AMBARELLA_CALC_PLL
+ amba_rct_writel(CLK_SI_INPUT_MODE_REG, 0x0);
+#if (CHIP_REV == S2E)
+ amba_rct_setbitsl(HDMI_CLOCK_CTRL_REG, 0x1);
+#endif
+ ambarella_clk_add(&gclk_so);
+ ambarella_clk_add(&gclk_vo2); /* for lcd */
+ ambarella_clk_add(&gclk_vo); /* for tv */
+#endif
+#if (CHIP_REV == S2E)
+ amba_rct_writel(UART_CLK_SRC_SEL_REG, UART_CLK_SRC_IDSP);
+#endif
+ ambarella_clk_add(&gclk_uart);
+ ambarella_clk_add(&gclk_audio);
+#if (SD_SUPPORT_SDXC == 1)
+ ambarella_clk_add(&gclk_sdxc);
+#endif
+#if (SD_SUPPORT_SDIO == 1)
+ ambarella_clk_add(&gclk_sdio);
+#endif
+ ambarella_clk_add(&gclk_sd);
+ ambarella_clk_add(&gclk_ir);
+ ambarella_clk_add(&gclk_adc);
+ ambarella_clk_add(&gclk_ssi);
+ ambarella_clk_add(&gclk_ssi2);
+#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+ ambarella_clk_add(&gclk_ssi3);
+#endif
+ ambarella_clk_add(&gclk_pwm);
+
+ /* register ambarella clk service for private operation */
+ pll_service.service = AMBARELLA_SERVICE_PLL;
+ pll_service.func = ambarella_pll_service;
+ ambarella_register_service(&pll_service);
+}
+
diff --git a/arch/arm/mach-ambarella/clk_calc.c b/arch/arm/mach-ambarella/clk_calc.c
new file mode 100644
index 00000000..790e4453
--- /dev/null
+++ b/arch/arm/mach-ambarella/clk_calc.c
@@ -0,0 +1,162 @@
+/*
+ * arch/arm/mach-ambarella/pll_calc.c
+ *
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * Copyright (C) 2012-2016, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/rational.h>
+#include <mach/init.h>
+#include <plat/clk.h>
+#include <plat/fio.h>
+#include <plat/sd.h>
+#include <plat/spi.h>
+
+/* these two tables are actually not used */
+struct pll_table ambarella_pll_frac_table[AMBARELLA_PLL_FRAC_TABLE_SIZE];
+struct pll_table ambarella_pll_int_table[AMBARELLA_PLL_INT_TABLE_SIZE];
+
+int ambarella_rct_clk_set_rate(struct clk *c, unsigned long rate)
+{
+ unsigned long rate_int, pre_scaler = 1, post_scaler = 1;
+ unsigned long intp, sdiv = 1, sout = 1;
+ u32 ctrl2, ctrl3, fix_divider = c->divider ? c->divider : 1;
+ u64 dividend, divider, diff;
+ union ctrl_reg_u ctrl_reg;
+ union frac_reg_u frac_reg;
+
+ BUG_ON(c->ctrl_reg == -1 || c->ctrl2_reg == -1 || c->ctrl3_reg == -1);
+
+ rate *= fix_divider;
+
+ if (rate < REF_CLK_FREQ && c->post_reg != -1) {
+ rate *= 16;
+ post_scaler = 16;
+ }
+
+ if (rate < REF_CLK_FREQ) {
+ pr_err("Error: target rate is too slow: %ld!\n", rate);
+ return -1;
+ }
+
+ //TODO: temporary solution for s3l 4Kp30 hdmi vout
+ if(rate == (PLL_CLK_296_703MHZ * fix_divider)){
+ pre_scaler = 4;
+ intp = 0x63;
+ sdiv = 5;
+ sout = 1;
+ c->frac_mode = 0;
+ }else{
+ /* fvco should be less than 1.5GHz, so we use 64 as max_numerator,
+ * although the actual bit width of pll_intp is 7 */
+ rational_best_approximation(rate, REF_CLK_FREQ, 64, 16, &intp, &sout);
+
+ /* fvco should be faster than 700MHz, otherwise pll out is not stable */
+ while (REF_CLK_FREQ / 1000000 * intp * sdiv / pre_scaler < 700) {
+ if (sout > 8 || intp > 64)
+ break;
+ intp *= 2;
+ sout *= 2;
+ }
+
+ BUG_ON(pre_scaler > 16 || post_scaler > 16);
+ BUG_ON(intp > 64 || sdiv > 16 || sout > 16 || sdiv > 16);
+ }
+
+ if (c->pres_reg != -1) {
+ if (c->extra_scaler == 1)
+ amba_rct_writel_en(c->pres_reg, (pre_scaler - 1) << 4);
+ else
+ amba_rct_writel(c->pres_reg, pre_scaler);
+ }
+
+ if (c->post_reg != -1) {
+ if (c->extra_scaler == 1)
+ amba_rct_writel_en(c->post_reg, (post_scaler - 1) << 4);
+ else
+ amba_rct_writel(c->post_reg, post_scaler);
+ }
+
+ ctrl_reg.w = amba_rct_readl(c->ctrl_reg);
+ ctrl_reg.s.intp = intp - 1;
+ ctrl_reg.s.sdiv = sdiv - 1;
+ ctrl_reg.s.sout = sout - 1;
+ ctrl_reg.s.bypass = 0;
+ ctrl_reg.s.frac_mode = 0;
+ ctrl_reg.s.force_reset = 0;
+ ctrl_reg.s.power_down = 0;
+ ctrl_reg.s.halt_vco = 0;
+ ctrl_reg.s.tristate = 0;
+ ctrl_reg.s.force_lock = 1;
+ ctrl_reg.s.force_bypass = 0;
+ ctrl_reg.s.write_enable = 0;
+ amba_rct_writel_en(c->ctrl_reg, ctrl_reg.w);
+
+ if (c->frac_mode) {
+ rate_int = ambarella_rct_clk_get_rate(c) * fix_divider * post_scaler;
+ if (rate_int <= rate)
+ diff = rate - rate_int;
+ else
+ diff = rate_int - rate;
+
+ if (diff) {
+ dividend = diff * pre_scaler * sout;
+ dividend = dividend << 32;
+ divider = (u64)sdiv * REF_CLK_FREQ;
+ dividend = DIV_ROUND_CLOSEST_ULL(dividend, divider);
+ if (rate_int <= rate) {
+ frac_reg.s.nega = 0;
+ frac_reg.s.frac = dividend;
+ } else {
+ frac_reg.s.nega = 1;
+ frac_reg.s.frac = 0x80000000 - dividend;
+ }
+ amba_rct_writel(c->frac_reg, frac_reg.w);
+
+ ctrl_reg.s.frac_mode = 1;
+ }
+
+ amba_rct_writel_en(c->ctrl_reg, ctrl_reg.w);
+ }
+
+ ctrl2 = c->ctrl2_val ? c->ctrl2_val : 0x3f770000;
+ ctrl3 = c->ctrl3_val ? c->ctrl3_val : ctrl_reg.s.frac_mode ? 0x00069300 : 0x00068300;
+ if(rate == (PLL_CLK_296_703MHZ * fix_divider)){
+ ctrl2 = 0x3f700e00;
+ ctrl3 = 0x00068306;
+ }
+ amba_rct_writel(c->ctrl2_reg, ctrl2);
+ amba_rct_writel(c->ctrl3_reg, ctrl3);
+
+ c->rate = ambarella_rct_clk_get_rate(c);
+
+ /* check if result rate is precise or not */
+ if (abs(c->rate - rate / fix_divider / post_scaler) > 10) {
+ pr_warn("%s: rate is not very precise: %lld, %ld\n",
+ c->name, c->rate, rate / fix_divider / post_scaler);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(ambarella_rct_clk_set_rate);
+
diff --git a/arch/arm/mach-ambarella/clk_table.c b/arch/arm/mach-ambarella/clk_table.c
new file mode 100644
index 00000000..9d7e325f
--- /dev/null
+++ b/arch/arm/mach-ambarella/clk_table.c
@@ -0,0 +1,2543 @@
+/*
+ * arch/arm/mach-ambarella/clk_table.c
+ *
+ * Author: Anthony Ginger <rrcao@ambarella.com>
+ *
+ * Copyright (C) 2012-2016, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <linux/module.h>
+#include <linux/io.h>
+#include <plat/clk.h>
+
+int ambarella_rct_clk_set_rate(struct clk *c, unsigned long rate)
+{
+ u32 pre_scaler, post_scaler, middle;
+ u32 intp, sdiv, sout, post, ctrl2, ctrl3;
+ u64 dividend, divider, diff;
+ union ctrl_reg_u ctrl_reg;
+ union frac_reg_u frac_reg;
+
+ if (!rate)
+ return -1;
+
+ BUG_ON(c->ctrl_reg == -1 || c->ctrl2_reg == -1 || c->ctrl3_reg == -1);
+ BUG_ON(c->post_reg != -1 && !c->max_divider);
+ BUG_ON(!c->table || c->table_size == 0);
+#if 0
+ if (c->divider)
+ rate *= c->divider;
+#endif
+ if (c->pres_reg != -1) {
+ if (c->pres_val) {
+ pre_scaler = c->pres_val;
+ if (c->extra_scaler == 1)
+ amba_rct_writel_en(c->pres_reg, (pre_scaler - 1) << 4);
+ else
+ amba_rct_writel(c->pres_reg, pre_scaler);
+ } else {
+ pre_scaler = amba_rct_readl(c->pres_reg);
+ if (c->extra_scaler == 1) {
+ pre_scaler >>= 4;
+ pre_scaler++;
+ }
+ }
+ } else {
+ pre_scaler = 1;
+ }
+
+ middle = ambarella_rct_find_pll_table_index(rate,
+ pre_scaler, c->table, c->table_size);
+ intp = c->table[middle].intp;
+ sdiv = c->table[middle].sdiv;
+ sout = c->table[middle].sout;
+ post = c->post_val ? c->post_val : c->table[middle].post;
+
+ ctrl_reg.w = amba_rct_readl(c->ctrl_reg);
+ ctrl_reg.s.intp = intp;
+ ctrl_reg.s.sdiv = sdiv;
+ ctrl_reg.s.sout = sout;
+ ctrl_reg.s.bypass = 0;
+ ctrl_reg.s.frac_mode = 0;
+ ctrl_reg.s.force_reset = 0;
+ ctrl_reg.s.power_down = 0;
+ ctrl_reg.s.halt_vco = 0;
+ ctrl_reg.s.tristate = 0;
+ ctrl_reg.s.force_lock = 1;
+ ctrl_reg.s.force_bypass = 0;
+ ctrl_reg.s.write_enable = 0;
+ amba_rct_writel_en(c->ctrl_reg, ctrl_reg.w);
+
+ if (c->post_reg != -1) {
+ post_scaler = min(post, c->max_divider);
+ if (c->extra_scaler == 1)
+ amba_rct_writel_en(c->post_reg, (post_scaler - 1) << 4);
+ else
+ amba_rct_writel(c->post_reg, post_scaler);
+ }
+
+ if (c->frac_mode) {
+ c->rate = ambarella_rct_clk_get_rate(c);
+ if (c->rate < rate)
+ diff = rate - c->rate;
+ else
+ diff = c->rate - rate;
+
+ dividend = diff * pre_scaler * (sout + 1) * post;
+ if (c->divider)
+ dividend *= c->divider;
+ dividend = dividend << 32;
+ divider = (u64)ambarella_clk_get_ref_freq() * (sdiv + 1);
+ AMBCLK_DO_DIV_ROUND(dividend, divider);
+ if (c->rate <= rate) {
+ frac_reg.s.nega = 0;
+ frac_reg.s.frac = dividend;
+ } else {
+ frac_reg.s.nega = 1;
+ frac_reg.s.frac = 0x80000000 - dividend;
+ }
+ amba_rct_writel(c->frac_reg, frac_reg.w);
+
+ ctrl_reg.w = amba_rct_readl(c->ctrl_reg);
+ if (diff)
+ ctrl_reg.s.frac_mode = 1;
+ else
+ ctrl_reg.s.frac_mode = 0;
+
+ ctrl_reg.s.force_lock = 1;
+ ctrl_reg.s.write_enable = 1;
+ amba_rct_writel(c->ctrl_reg, ctrl_reg.w);
+
+ ctrl_reg.s.write_enable = 0;
+ amba_rct_writel(c->ctrl_reg, ctrl_reg.w);
+ }
+
+ ctrl2 = c->ctrl2_val ? c->ctrl2_val : 0x3f770000;
+ ctrl3 = c->ctrl3_val ? c->ctrl3_val : ctrl_reg.s.frac_mode ? 0x00069300 : 0x00068300;
+ amba_rct_writel(c->ctrl2_reg, ctrl2);
+ amba_rct_writel(c->ctrl3_reg, ctrl3);
+
+ c->rate = ambarella_rct_clk_get_rate(c);
+
+ return 0;
+}
+EXPORT_SYMBOL(ambarella_rct_clk_set_rate);
+
+u32 ambarella_rct_find_pll_table_index(unsigned long rate, u32 pre_scaler,
+ const struct pll_table *table, u32 table_size)
+{
+ u64 dividend;
+ u64 divider;
+ u32 start;
+ u32 middle;
+ u32 end;
+ u32 index_limit;
+ u64 diff = 0;
+ u64 diff_low = 0xFFFFFFFFFFFFFFFF;
+ u64 diff_high = 0xFFFFFFFFFFFFFFFF;
+
+ pr_debug("pre_scaler = [0x%08X]\n", pre_scaler);
+
+ dividend = rate;
+ dividend *= pre_scaler;
+ dividend *= (1000 * 1000 * 1000);
+ divider = ambarella_clk_get_ref_freq() / (1000 * 1000);
+ AMBCLK_DO_DIV(dividend, divider);
+
+ index_limit = (table_size - 1);
+ start = 0;
+ end = index_limit;
+ middle = table_size / 2;
+ while (table[middle].multiplier != dividend) {
+ if (table[middle].multiplier < dividend) {
+ start = middle;
+ } else {
+ end = middle;
+ }
+ middle = (start + end) / 2;
+ if (middle == start || middle == end) {
+ break;
+ }
+ }
+ if ((middle > 0) && ((middle + 1) <= index_limit)) {
+ if (table[middle - 1].multiplier < dividend) {
+ diff_low = dividend - table[middle - 1].multiplier;
+ } else {
+ diff_low = table[middle - 1].multiplier - dividend;
+ }
+ if (table[middle].multiplier < dividend) {
+ diff = dividend - table[middle].multiplier;
+ } else {
+ diff = table[middle].multiplier - dividend;
+ }
+ if (table[middle + 1].multiplier < dividend) {
+ diff_high = dividend - table[middle + 1].multiplier;
+ } else {
+ diff_high = table[middle + 1].multiplier - dividend;
+ }
+ pr_debug("multiplier[%u] = [%llu]\n", (middle - 1),
+ table[middle - 1].multiplier);
+ pr_debug("multiplier[%u] = [%llu]\n", (middle),
+ table[middle].multiplier);
+ pr_debug("multiplier[%u] = [%llu]\n", (middle + 1),
+ table[middle + 1].multiplier);
+ } else if ((middle == 0) && ((middle + 1) <= index_limit)) {
+ if (table[middle].multiplier < dividend) {
+ diff = dividend - table[middle].multiplier;
+ } else {
+ diff = table[middle].multiplier - dividend;
+ }
+ if (table[middle + 1].multiplier < dividend) {
+ diff_high = dividend - table[middle + 1].multiplier;
+ } else {
+ diff_high = table[middle + 1].multiplier - dividend;
+ }
+ pr_debug("multiplier[%u] = [%llu]\n", (middle),
+ table[middle].multiplier);
+ pr_debug("multiplier[%u] = [%llu]\n", (middle + 1),
+ table[middle + 1].multiplier);
+ } else if ((middle > 0) && ((middle + 1) > index_limit)) {
+ if (table[middle - 1].multiplier < dividend) {
+ diff_low = dividend - table[middle - 1].multiplier;
+ } else {
+ diff_low = table[middle - 1].multiplier - dividend;
+ }
+ if (table[middle].multiplier < dividend) {
+ diff = dividend - table[middle].multiplier;
+ } else {
+ diff = table[middle].multiplier - dividend;
+ }
+ pr_debug("multiplier[%u] = [%llu]\n", (middle - 1),
+ table[middle - 1].multiplier);
+ pr_debug("multiplier[%u] = [%llu]\n", (middle),
+ table[middle].multiplier);
+ }
+ pr_debug("diff_low = [%llu]\n", diff_low);
+ pr_debug("diff = [%llu]\n", diff);
+ pr_debug("diff_high = [%llu]\n", diff_high);
+ if (diff_low < diff) {
+ if (middle) {
+ middle--;
+ }
+ }
+ if (diff_high < diff) {
+ middle++;
+ if (middle > index_limit) {
+ middle = index_limit;
+ }
+ }
+ pr_debug("middle = [%u]\n", middle);
+
+ return middle;
+}
+EXPORT_SYMBOL(ambarella_rct_find_pll_table_index);
+
+/* ==========================================================================*/
+
+struct pll_table ambarella_pll_int_table[AMBARELLA_PLL_INT_TABLE_SIZE] =
+{
+ { 1000000000000000, 13, 0, 13, 1},
+ { 1500000000000000, 13, 2, 27, 1},
+ { 2000000000000000, 13, 0, 6, 1},
+ { 2500000000000000, 14, 0, 5, 1},
+ { 3000000000000000, 13, 2, 13, 1},
+ { 3500000000000000, 13, 0, 3, 1},
+ { 4000000000000000, 13, 1, 6, 1},
+ { 4500000000000000, 14, 2, 9, 1},
+ { 5000000000000000, 14, 0, 2, 1},
+ { 5500000000000000, 21, 0, 3, 1},
+ { 6000000000000000, 13, 2, 6, 1},
+ { 6500000000000000, 25, 0, 3, 1},
+ { 7000000000000000, 13, 0, 1, 1},
+ { 7500000000000000, 14, 0, 1, 1},
+ { 8000000000000000, 15, 0, 1, 1},
+ { 8500000000000000, 16, 0, 1, 1},
+ { 9000000000000000, 14, 2, 4, 1},
+ { 9500000000000000, 18, 0, 1, 1},
+ { 10000000000000000, 14, 1, 2, 1},
+ { 10500000000000000, 13, 2, 3, 1},
+ { 11000000000000000, 21, 0, 1, 1},
+ { 11500000000000000, 22, 0, 1, 1},
+ { 12000000000000000, 15, 2, 3, 1},
+ { 12500000000000000, 24, 0, 1, 1},
+ { 13000000000000000, 25, 0, 1, 1},
+ { 13500000000000000, 17, 2, 3, 1},
+ { 14000000000000000, 13, 0, 0, 1},
+ { 14500000000000000, 28, 0, 1, 1},
+ { 15000000000000000, 14, 0, 0, 1},
+ { 15500000000000000, 30, 0, 1, 1},
+ { 16000000000000000, 15, 0, 0, 1},
+ { 16500000000000000, 21, 2, 3, 1},
+ { 17000000000000000, 16, 0, 0, 1},
+ { 17500000000000000, 34, 0, 1, 1},
+ { 18000000000000000, 17, 0, 0, 1},
+ { 18500000000000000, 36, 0, 1, 1},
+ { 19000000000000000, 18, 0, 0, 1},
+ { 19500000000000000, 25, 2, 3, 1},
+ { 20000000000000000, 19, 0, 0, 1},
+ { 20500000000000000, 40, 0, 1, 1},
+ { 21000000000000000, 13, 2, 1, 1},
+ { 21500000000000000, 42, 0, 1, 1},
+ { 22000000000000000, 21, 0, 0, 1},
+ { 22500000000000000, 14, 2, 1, 1},
+ { 23000000000000000, 22, 0, 0, 1},
+ { 23500000000000000, 46, 0, 1, 1},
+ { 24000000000000000, 15, 2, 1, 1},
+ { 24500000000000000, 48, 0, 1, 1},
+ { 25000000000000000, 24, 0, 0, 1},
+ { 25500000000000000, 16, 2, 1, 1},
+ { 26000000000000000, 25, 0, 0, 1},
+ { 27000000000000000, 17, 2, 1, 1},
+ { 28000000000000000, 13, 1, 0, 1},
+ { 28500000000000000, 18, 2, 1, 1},
+ { 29000000000000000, 28, 0, 0, 1},
+ { 30000000000000000, 14, 1, 0, 1},
+ { 31000000000000000, 30, 0, 0, 1},
+ { 31500000000000000, 20, 2, 1, 1},
+ { 32000000000000000, 15, 1, 0, 1},
+ { 33000000000000000, 21, 2, 1, 1},
+ { 34000000000000000, 16, 1, 0, 1},
+ { 34500000000000000, 22, 2, 1, 1},
+ { 35000000000000000, 34, 0, 0, 1},
+ { 36000000000000000, 17, 1, 0, 1},
+ { 37000000000000000, 36, 0, 0, 1},
+ { 37500000000000000, 24, 2, 1, 1},
+ { 38000000000000000, 18, 1, 0, 1},
+ { 39000000000000000, 25, 2, 1, 1},
+ { 40000000000000000, 19, 1, 0, 1},
+ { 40500000000000000, 26, 2, 1, 1},
+ { 41000000000000000, 40, 0, 0, 1},
+ { 42000000000000000, 13, 2, 0, 1},
+ { 43000000000000000, 42, 0, 0, 1},
+ { 43500000000000000, 28, 2, 1, 1},
+ { 44000000000000000, 21, 1, 0, 1},
+ { 45000000000000000, 14, 2, 0, 1},
+ { 46000000000000000, 22, 1, 0, 1},
+ { 46500000000000000, 30, 2, 1, 1},
+ { 47000000000000000, 46, 0, 0, 1},
+ { 48000000000000000, 15, 2, 0, 1},
+ { 49000000000000000, 48, 0, 0, 1},
+ { 49500000000000000, 32, 2, 1, 1},
+ { 50000000000000000, 24, 1, 0, 1},
+ { 51000000000000000, 16, 2, 0, 1},
+ { 52000000000000000, 25, 1, 0, 1},
+ { 52500000000000000, 34, 2, 1, 1},
+ { 54000000000000000, 17, 2, 0, 1},
+ { 55500000000000000, 36, 2, 1, 1},
+ { 56000000000000000, 27, 1, 0, 1},
+ { 57000000000000000, 18, 2, 0, 1},
+ { 58000000000000000, 28, 1, 0, 1},
+ { 58500000000000000, 38, 2, 1, 1},
+ { 60000000000000000, 19, 2, 0, 1},
+};
+EXPORT_SYMBOL(ambarella_pll_int_table);
+
+
+struct pll_table ambarella_pll_frac_table[AMBARELLA_PLL_FRAC_TABLE_SIZE] =
+{
+ { 16601562500000, 0, 0, 3, 15 },
+ { 16732282936573, 0, 0, 3, 15 },
+ { 16865080222486, 0, 2, 15, 11 },
+ { 17000000923872, 0, 2, 15, 11 },
+ { 17137097194791, 0, 1, 8, 13 },
+ { 17276423051953, 0, 1, 8, 13 },
+ { 17418032512068, 0, 1, 8, 13 },
+ { 17561983317137, 0, 2, 12, 13 },
+ { 17708333209157, 0, 2, 12, 13 },
+ { 17847768962383, 0, 0, 3, 14 },
+ { 17989417538047, 0, 0, 3, 14 },
+ { 18133332952857, 0, 0, 4, 11 },
+ { 18279569223523, 0, 0, 4, 11 },
+ { 18428184092045, 0, 0, 5, 9 },
+ { 18579235300422, 0, 0, 5, 9 },
+ { 18732782453299, 0, 2, 15, 10 },
+ { 18973214551806, 0, 1, 6, 15 },
+ { 19122609868646, 0, 1, 6, 15 },
+ { 19274376332760, 0, 0, 3, 13 },
+ { 19428571686149, 0, 2, 10, 14 },
+ { 19585253670812, 0, 2, 10, 14 },
+ { 19744483754039, 0, 0, 4, 10 },
+ { 19906323403120, 0, 0, 4, 10 },
+ { 20070837810636, 0, 0, 4, 10 },
+ { 20238095894456, 0, 1, 8, 11 },
+ { 20432692021132, 0, 0, 6, 7 },
+ { 20593579858541, 0, 3, 12, 15 },
+ { 20757021382451, 0, 0, 3, 12 },
+ { 20923076197505, 0, 2, 10, 13 },
+ { 21091811358929, 0, 2, 10, 13 },
+ { 21263290196657, 0, 2, 9, 14 },
+ { 21437577903271, 0, 2, 9, 14 },
+ { 21614748984575, 0, 2, 9, 14 },
+ { 21794872358441, 0, 1, 6, 13 },
+ { 22135416045785, 0, 0, 2, 15 },
+ { 22309711202979, 0, 4, 15, 14 },
+ { 22486772388220, 0, 4, 15, 14 },
+ { 22666666656733, 0, 0, 3, 11 },
+ { 22849462926388, 0, 0, 3, 11 },
+ { 23035230115056, 0, 2, 9, 13 },
+ { 23224044591188, 0, 2, 9, 13 },
+ { 23415977135301, 0, 2, 15, 8 },
+ { 23611111566424, 0, 3, 12, 13 },
+ { 23809524253011, 0, 0, 2, 14 },
+ { 24147726595402, 0, 3, 10, 15 },
+ { 24337867274880, 0, 3, 10, 15 },
+ { 24531025439501, 0, 1, 8, 9 },
+ { 24727271869779, 0, 1, 8, 9 },
+ { 24926686659455, 0, 0, 3, 10 },
+ { 25129342451692, 0, 0, 3, 10 },
+ { 25335321202874, 0, 4, 13, 14 },
+ { 25544703006744, 0, 4, 13, 14 },
+ { 25757575407624, 0, 0, 2, 13 },
+ { 25974025949836, 0, 1, 6, 11 },
+ { 26194144040346, 0, 4, 15, 12 },
+ { 26562500745058, 0, 1, 4, 15 },
+ { 26771653443575, 0, 2, 7, 14 },
+ { 26984127238393, 0, 2, 7, 14 },
+ { 27200000360608, 0, 2, 9, 11 },
+ { 27419354766607, 0, 4, 12, 14 },
+ { 27642276138067, 0, 0, 2, 12 },
+ { 27868852019310, 0, 0, 2, 12 },
+ { 28099173679948, 0, 3, 10, 13 },
+ { 28333334252238, 0, 4, 15, 11 },
+ { 28571428731084, 0, 0, 4, 7 },
+ { 28813559561968, 0, 2, 7, 13 },
+ { 29059829190373, 0, 6, 15, 15 },
+ { 29513888061047, 0, 4, 12, 13 },
+ { 29746280983090, 0, 4, 11, 14 },
+ { 29982363805175, 0, 2, 9, 10 },
+ { 30222222208977, 0, 0, 2, 11 },
+ { 30465949326754, 0, 2, 6, 14 },
+ { 30713640153408, 0, 1, 4, 13 },
+ { 30965391546488, 0, 6, 14, 15 },
+ { 31221304088831, 0, 0, 3, 8 },
+ { 31481482088566, 0, 0, 3, 8 },
+ { 31746033579111, 0, 1, 6, 9 },
+ { 32015066593885, 0, 4, 11, 13 },
+ { 32288700342177, 0, 4, 10, 14 },
+ { 32567050307989, 0, 4, 10, 14 },
+ { 32850243151188, 0, 2, 6, 13 },
+ { 33203125000000, 0, 0, 1, 15 },
+ { 33464565873146, 0, 0, 1, 15 },
+ { 33730160444975, 0, 6, 15, 13 },
+ { 34000001847744, 0, 2, 7, 11 },
+ { 34274194389582, 0, 3, 8, 13 },
+ { 34552846103907, 0, 4, 11, 12 },
+ { 34836065024136, 0, 4, 11, 12 },
+ { 35123966634274, 0, 4, 10, 13 },
+ { 35416666418314, 0, 5, 12, 13 },
+ { 35714287310839, 0, 0, 1, 14 },
+ { 36016948521137, 0, 6, 12, 15 },
+ { 36324787884951, 0, 1, 4, 11 },
+ { 36637932062149, 0, 6, 15, 12 },
+ { 36956522613764, 0, 0, 2, 9 },
+ { 37280701100826, 0, 2, 7, 10 },
+ { 37610620260239, 0, 2, 7, 10 },
+ { 37946429103613, 0, 4, 10, 12 },
+ { 38245219737291, 0, 3, 6, 15 },
+ { 38548752665520, 0, 0, 1, 13 },
+ { 38857143372297, 0, 6, 11, 15 },
+ { 39170507341623, 0, 4, 15, 8 },
+ { 39488967508078, 0, 4, 8, 14 },
+ { 39812646806240, 0, 6, 15, 11 },
+ { 40141675621271, 0, 8, 15, 14 },
+ { 40476191788912, 0, 3, 8, 11 },
+ { 40816325694323, 0, 1, 6, 7 },
+ { 41162226349115, 0, 7, 12, 15 },
+ { 41514042764902, 0, 6, 12, 13 },
+ { 41871920228004, 0, 5, 10, 13 },
+ { 42236026376486, 0, 6, 10, 15 },
+ { 42606517672539, 0, 4, 8, 13 },
+ { 42983565479517, 0, 2, 4, 14 },
+ { 43367348611355, 0, 8, 15, 13 },
+ { 43758042156696, 0, 6, 15, 10 },
+ { 44270832091570, 0, 1, 2, 15 },
+ { 44619422405958, 0, 4, 7, 14 },
+ { 44973544776440, 0, 6, 11, 13 },
+ { 45333333313465, 0, 0, 1, 11 },
+ { 45698925852776, 0, 10, 15, 15 },
+ { 46070460230112, 0, 2, 4, 13 },
+ { 46448089182377, 0, 4, 8, 12 },
+ { 46831954270601, 0, 2, 7, 8 },
+ { 47222223132849, 0, 7, 12, 13 },
+ { 47619048506021, 0, 0, 2, 7 },
+ { 48022598028183, 0, 4, 7, 13 },
+ { 48433046787977, 0, 7, 10, 15 },
+ { 48850573599339, 0, 10, 14, 15 },
+ { 49275361001492, 0, 3, 8, 9 },
+ { 49707602709532, 0, 5, 10, 11 },
+ { 50147492438555, 0, 0, 1, 10 },
+ { 50595238804817, 0, 4, 8, 11 },
+ { 51051050424576, 0, 4, 6, 14 },
+ { 51515150815248, 0, 1, 2, 13 },
+ { 51987767219543, 0, 3, 6, 11 },
+ { 52469134330750, 0, 10, 13, 15 },
+ { 53125001490116, 0, 6, 10, 12 },
+ { 53543306887150, 0, 2, 3, 14 },
+ { 53968254476786, 0, 6, 9, 13 },
+ { 54400000721216, 0, 2, 4, 11 },
+ { 54838709533215, 0, 4, 6, 13 },
+ { 55284552276134, 0, 0, 1, 9 },
+ { 55737704038620, 0, 0, 1, 9 },
+ { 56198347359896, 0, 8, 15, 10 },
+ { 56666668504477, 0, 4, 7, 11 },
+ { 57142857462168, 0, 1, 4, 7 },
+ { 57627119123936, 0, 2, 3, 13 },
+ { 58119658380747, 0, 12, 15, 14 },
+ { 58620691299438, 0, 8, 10, 14 },
+ { 59130433946848, 0, 9, 12, 13 },
+ { 59649121016264, 0, 4, 5, 14 },
+ { 60176990926266, 0, 2, 4, 10 },
+ { 60714285820723, 0, 1, 2, 11 },
+ { 61261262744665, 0, 2, 6, 7 },
+ { 61818182468414, 0, 12, 13, 15 },
+ { 62385320663452, 0, 0, 1, 8 },
+ { 62962964177132, 0, 8, 10, 13 },
+ { 63551403582096, 0, 3, 6, 9 },
+ { 64150944352150, 0, 4, 5, 13 },
+ { 64761906862258, 0, 6, 8, 12 },
+ { 65384618937969, 0, 10, 11, 14 },
+ { 65891474485397, 0, 5, 6, 13 },
+ { 66406250000000, 0, 12, 13, 14 },
+ { 66929131746292, 0, 14, 15, 14 },
+ { 67460320889950, 0, 6, 7, 13 },
+ { 68000003695488, 0, 2, 3, 11 },
+ { 68548388779163, 0, 7, 8, 13 },
+ { 69105692207813, 0, 8, 9, 13 },
+ { 69672130048274, 0, 4, 5, 12 },
+ { 70247933268547, 0, 8, 15, 8 },
+ { 70833332836628, 16, 0, 15, 15 },
+ { 71428574621677, 0, 0, 0, 14 },
+ { 72033897042274, 0, 14, 15, 13 },
+ { 72649575769901, 0, 3, 4, 11 },
+ { 73275864124298, 0, 10, 9, 15 },
+ { 73913045227528, 0, 12, 15, 11 },
+ { 74561402201653, 0, 8, 10, 11 },
+ { 75221240520477, 0, 2, 3, 10 },
+ { 75892858207226, 16, 0, 15, 14 },
+ { 76576575636864, 0, 14, 13, 14 },
+ { 77272728085518, 0, 12, 11, 14 },
+ { 77981650829315, 0, 5, 6, 11 },
+ { 78703701496124, 0, 12, 10, 15 },
+ { 79439252614975, 0, 4, 6, 9 },
+ { 80188676714897, 0, 8, 7, 14 },
+ { 80952383577824, 16, 0, 13, 15 },
+ { 81730768084526, 16, 0, 15, 13 },
+ { 82524269819260, 0, 14, 12, 14 },
+ { 83333335816860, 0, 0, 0, 12 },
+ { 84158413112164, 0, 11, 10, 13 },
+ { 85000000894070, 16, 0, 13, 14 },
+ { 85858583450317, 0, 10, 15, 8 },
+ { 86734697222710, 16, 0, 13, 14 },
+ { 87628863751888, 0, 6, 7, 10 },
+ { 88541664183140, 16, 0, 15, 12 },
+ { 89238844811916, 0, 4, 3, 14 },
+ { 89947089552879, 0, 8, 9, 10 },
+ { 90666666626930, 18, 0, 13, 15 },
+ { 91397851705551, 18, 0, 15, 13 },
+ { 92140920460224, 0, 5, 4, 13 },
+ { 92896178364754, 0, 12, 9, 14 },
+ { 93663908541203, 0, 2, 3, 8 },
+ { 94444446265697, 16, 0, 11, 15 },
+ { 95238097012043, 0, 1, 2, 7 },
+ { 96045196056366, 0, 4, 3, 13 },
+ { 96866093575954, 18, 0, 13, 14 },
+ { 97701147198677, 1, 10, 14, 15 },
+ { 98550722002983, 0, 12, 10, 12 },
+ { 99415205419064, 0, 11, 10, 11 },
+ { 100294984877110, 0, 0, 0, 10 },
+ { 101190477609634, 16, 0, 11, 14 },
+ { 102102100849152, 0, 4, 6, 7 },
+ { 103030301630497, 16, 0, 10, 15 },
+ { 103975534439087, 0, 7, 6, 11 },
+ { 104938268661499, 0, 14, 10, 13 },
+ { 105919003486633, 0, 6, 5, 11 },
+ { 106918238103390, 0, 2, 1, 14 },
+ { 107936508953571, 18, 0, 15, 11 },
+ { 108974359929562, 16, 0, 11, 13 },
+ { 110032364726067, 0, 10, 9, 10 },
+ { 111111111938953, 0, 0, 0, 9 },
+ { 112211219966412, 0, 10, 6, 14 },
+ { 113333337008953, 16, 0, 9, 15 },
+ { 114478111267090, 0, 10, 7, 12 },
+ { 115646257996559, 0, 13, 10, 11 },
+ { 116838485002518, 0, 8, 6, 11 },
+ { 118055552244186, 16, 0, 11, 12 },
+ { 119298242032528, 2, 6, 15, 11 },
+ { 120567373931408, 2, 8, 15, 14 },
+ { 121863797307014, 18, 0, 11, 13 },
+ { 123188406229019, 0, 7, 4, 13 },
+ { 124542124569416, 1, 13, 14, 15 },
+ { 125925928354263, 16, 0, 8, 15 },
+ { 127340823411942, 0, 6, 4, 11 },
+ { 128787875175475, 16, 0, 10, 12 },
+ { 130268201231956, 4, 4, 15, 12 },
+ { 131782948970795, 0, 11, 6, 13 },
+ { 132812500000000, 16, 1, 15, 16 },
+ { 133858263492584, 0, 14, 7, 14 },
+ { 134920641779900, 16, 0, 8, 14 },
+ { 136000007390976, 22, 0, 12, 13 },
+ { 137096777558327, 22, 0, 11, 14 },
+ { 138211384415627, 28, 0, 13, 15 },
+ { 139344260096549, 22, 0, 10, 15 },
+ { 140495866537094, 17, 1, 15, 16 },
+ { 141666665673256, 16, 1, 15, 15 },
+ { 142857149243355, 0, 0, 0, 7 },
+ { 144067794084549, 18, 0, 10, 12 },
+ { 145299151539803, 16, 0, 8, 13 },
+ { 146551728248596, 0, 10, 4, 15 },
+ { 147826090455055, 18, 1, 15, 16 },
+ { 149122804403305, 17, 1, 15, 15 },
+ { 150442481040955, 16, 1, 14, 15 },
+ { 151785716414452, 16, 1, 15, 14 },
+ { 153153151273727, 0, 14, 6, 14 },
+ { 154545456171036, 16, 0, 9, 11 },
+ { 155963301658630, 19, 1, 15, 16},
+ { 157407402992249, 18, 1, 15, 15},
+ { 158878505229950, 17, 1, 14, 15},
+ { 160377353429794, 17, 1, 15, 14},
+ { 161904767155647, 16, 1, 14, 14},
+ { 163461536169052, 16, 1, 15, 13},
+ { 165048539638519, 36, 0, 15, 14 },
+ { 166666671633720, 19, 1, 15, 15},
+ { 168316826224327, 18, 1, 14, 15},
+ { 170000001788139, 18, 1, 15, 14},
+ { 171717166900635, 17, 1, 14, 14},
+ { 173469394445419, 16, 1, 14, 13},
+ { 175257727503777, 20, 1, 15, 15},
+ { 177083328366280, 16, 1, 15, 12},
+ { 178947374224663, 19, 1, 15, 14},
+ { 180851057171822, 18, 1, 14, 14},
+ { 182795703411102, 18, 1, 15, 13},
+ { 184782609343529, 17, 1, 14, 13},
+ { 186813190579414, 17, 1, 15, 12},
+ { 188888892531395, 16, 1, 14, 12},
+ { 191011235117912, 19, 1, 15, 13},
+ { 193181812763214, 16, 1, 15, 11},
+ { 195402294397354, 18, 1, 14, 13},
+ { 197674423456192, 18, 1, 15, 12},
+ { 200000002980232, 17, 1, 14, 12},
+ { 202380955219269, 16, 1, 13, 12},
+ { 204819276928902, 16, 1, 14, 11},
+ { 207317069172859, 19, 1, 15, 12},
+ { 209876537322998, 18, 1, 14, 12},
+ { 212500005960464, 16, 1, 15, 10},
+ { 215189874172211, 18, 1, 15, 11},
+ { 217948719859123, 17, 1, 14, 11},
+ { 220779225230217, 16, 1, 13, 11},
+ { 223684206604958, 17, 1, 15, 10},
+ { 226666674017906, 16, 1, 14, 10},
+ { 229729726910591, 18, 1, 14, 11},
+ { 232876718044281, 17, 1, 13, 11},
+ { 236111104488373, 16, 1, 15, 9},
+ { 239436626434326, 17, 1, 14, 10},
+ { 242857143282890, 16, 1, 13, 10},
+ { 246376812458038, 18, 1, 13, 11},
+ { 250000000000000, 16, 1, 14, 9},
+ { 253731340169907, 18, 1, 14, 10},
+ { 255639106035233, 17, 1, 13, 10},
+ { 257575750350951, 16, 1, 11, 11},
+ { 261538475751877, 16, 1, 12, 10},
+ { 263565897941589, 18, 1, 15, 9},
+ { 265625000000000, 16, 1, 15, 8},
+ { 267716526985168, 20, 1, 12, 12},
+ { 269841283559798, 16, 1, 13, 9},
+ { 272000014781952, 17, 1, 11, 11},
+ { 274193555116653, 21, 1, 15, 10},
+ { 276422768831253, 19, 1, 15, 9},
+ { 278688520193099, 20, 1, 14, 10},
+ { 280991733074188, 17, 1, 15, 8},
+ { 283333331346512, 16, 1, 14, 8},
+ { 285714298486710, 17, 1, 13, 9},
+ { 288135588169098, 18, 1, 11, 11},
+ { 290598303079605, 16, 1, 12, 9},
+ { 293103456497192, 21, 1, 14, 10},
+ { 295652180910110, 18, 1, 15, 8},
+ { 298245608806610, 17, 1, 14, 8},
+ { 300884962081909, 18, 1, 13, 9},
+ { 303571432828903, 16, 1, 15, 7},
+ { 306306302547455, 17, 1, 12, 9},
+ { 309090912342072, 20, 1, 14, 9},
+ { 311926603317261, 19, 1, 15, 8},
+ { 314814805984497, 18, 1, 14, 8},
+ { 317757010459900, 19, 1, 13, 9},
+ { 320754706859589, 17, 1, 15, 7},
+ { 323809534311295, 16, 1, 14, 7},
+ { 326923072338104, 16, 1, 12, 8},
+ { 330097079277039, 19, 1, 10, 11},
+ { 333333343267441, 19, 1, 14, 8},
+ { 336633652448654, 21, 1, 12, 10},
+ { 340000003576279, 18, 1, 15, 7},
+ { 343434333801270, 17, 1, 14, 7},
+ { 346938788890839, 16, 1, 13, 7},
+ { 350515455007553, 20, 1, 14, 8},
+ { 354166656732559, 16, 1, 15, 6},
+ { 357894748449326, 19, 1, 15, 7},
+ { 361702114343643, 18, 1, 14, 7},
+ { 365591406822205, 17, 1, 13, 7},
+ { 369565218687057, 19, 1, 11, 9},
+ { 373626381158829, 17, 1, 15, 6},
+ { 377777785062790, 16, 1, 14, 6},
+ { 382022470235825, 19, 1, 14, 7},
+ { 386363625526428, 18, 1, 13, 7},
+ { 390804588794708, 21, 1, 15, 7},
+ { 395348846912384, 18, 1, 15, 6},
+ { 400000005960464, 17, 1, 14, 6},
+ { 404761910438538, 16, 1, 13, 6},
+ { 409638553857803, 19, 1, 13, 7},
+ { 414634138345718, 19, 1, 15, 6},
+ { 419753074645996, 18, 1, 14, 6},
+ { 425000011920929, 16, 1, 15, 5},
+ { 430379748344421, 17, 1, 13, 6},
+ { 435897439718246, 16, 1, 12, 6},
+ { 441558450460434, 19, 1, 14, 6},
+ { 447368413209915, 17, 1, 15, 5},
+ { 453333348035812, 16, 1, 14, 5},
+ { 459459453821182, 17, 1, 12, 6},
+ { 465753436088562, 20, 1, 14, 6},
+ { 472222208976746, 18, 1, 15, 5},
+ { 478873252868652, 17, 1, 14, 5},
+ { 485714286565781, 16, 1, 13, 5},
+ { 492753624916077, 18, 1, 10, 7},
+ { 500000000000000, 19, 1, 15, 5},
+ { 507462680339813, 18, 1, 14, 5},
+ { 515151500701903, 17, 1, 13, 5},
+ { 523076951503754, 16, 1, 12, 5},
+ { 531250000000000, 16, 1, 15, 4},
+ { 539682567119597, 18, 1, 13, 5},
+ { 548387110233307, 21, 1, 15, 5},
+ { 552631556987762, 78, 0, 10, 13},
+ { 557377040386199, 17, 1, 12, 5},
+ { 566666662693024, 16, 1, 14, 4},
+ { 571428596973419, 19, 1, 13, 5},
+ { 576271176338196, 18, 1, 10, 6},
+ { 580645143985748, 18, 1, 12, 5},
+ { 586206912994385, 21, 1, 14, 5},
+ { 591549277305603, 23, 1, 8, 9},
+ { 596491217613220, 17, 1, 14, 4},
+ { 607142865657806, 16, 1, 13, 4},
+ { 612903237342834, 19, 1, 12, 5},
+ { 618181824684143, 16, 1, 10, 5},
+ { 622950792312622, 19, 1, 15, 4},
+ { 629629611968994, 18, 1, 14, 4},
+ { 634920656681061, 20, 1, 10, 6},
+ { 641509413719177, 17, 1, 13, 4},
+ { 647058844566345, 28, 4, 15, 14},
+ { 653846144676208, 16, 1, 12, 4},
+ { 666666686534882, 19, 1, 14, 4},
+ { 680000007152557, 18, 1, 13, 4},
+ { 688524603843689, 21, 1, 15, 4},
+ { 693877577781677, 17, 1, 12, 4},
+ { 701754391193390, 20, 1, 14, 4},
+ { 708333313465118, 16, 1, 15, 3},
+ { 716981112957001, 19, 1, 13, 4},
+ { 723404228687286, 17, 1, 9, 5},
+ { 730769217014313, 18, 1, 12, 4},
+ { 739130437374115, 23, 1, 12, 5},
+ { 745098054409027, 20, 1, 13, 4},
+ { 755555570125580, 16, 1, 14, 3},
+ { 765957474708557, 19, 1, 12, 4},
+ { 772727251052856, 16, 1, 10, 4},
+ { 782608687877655, 21, 1, 13, 4},
+ { 790697693824768, 18, 1, 15, 3},
+ { 800000011920929, 17, 1, 14, 3},
+ { 809523820877075, 16, 1, 13, 3},
+ { 818181812763214, 17, 1, 10, 4},
+ { 829268276691437, 19, 1, 15, 3},
+ { 837209284305573, 20, 1, 9, 5},
+ { 850000023841858, 18, 1, 14, 3},
+ { 857142865657806, 17, 1, 13, 3},
+ { 863636374473572, 18, 1, 10, 4},
+ { 871794879436493, 16, 1, 12, 3},
+ { 883720934391022, 19, 1, 14, 3},
+ { 894736826419830, 17, 1, 9, 4},
+ { 904761910438538, 18, 1, 13, 3},
+ { 918918907642365, 17, 1, 12, 3},
+ { 926829278469086, 20, 1, 14, 3},
+ { 936170220375061, 22, 1, 6, 7},
+ { 944444417953491, 16, 1, 11, 3},
+ { 952380955219269, 19, 1, 13, 3},
+ { 959999978542328, 23, 1, 9, 5},
+ { 971428573131561, 18, 1, 12, 3},
+ { 978723406791687, 23, 1, 6, 7},
+ { 1000000000000000, 17, 1, 11, 3},
+ { 1022222280502318, 22, 1, 14, 3},
+ { 1030303001403809, 16, 1, 10, 3},
+ { 1043478250503540, 30, 6, 15, 13 },
+ { 1052631616592407, 21, 1, 13, 3},
+ { 1062500000000000, 16, 1, 15, 2},
+ { 1076923131942749, 20, 1, 12, 3},
+ { 1085714340209961, 23, 1, 10, 4},
+ { 1096774220466614, 17, 1, 10, 3},
+ { 1105263113975524, 78, 1, 10, 13 },
+ { 1117647051811218, 19, 1, 11, 3},
+ { 1133333325386047, 16, 1, 14, 2},
+ { 1142857193946838, 23, 1, 13, 3},
+ { 1151515126228333, 18, 1, 10, 3},
+ { 1161290287971497, 20, 1, 11, 3},
+ { 1172413825988770, 22, 1, 12, 3},
+ { 1187500000000000, 18, 1, 15, 2},
+ { 1200000047683716, 17, 1, 14, 2},
+ { 1214285731315613, 16, 1, 13, 2},
+ { 1225806474685669, 23, 1, 12, 3},
+ { 1241379261016846, 19, 1, 15, 2},
+ { 1259259223937988, 18, 1, 14, 2},
+ { 1272727251052856, 20, 1, 10, 3},
+ { 1285714268684387, 17, 1, 13, 2},
+ { 1297297239303588, 22, 10, 12, 15 },
+ { 1307692289352417, 16, 1, 12, 2},
+ { 1333333373069763, 19, 1, 14, 2},
+ { 1360000014305115, 18, 1, 13, 2},
+ { 1371428608894348, 23, 1, 6, 5},
+ { 1384615421295166, 17, 1, 12, 2},
+ { 1399999976158142, 20, 1, 14, 2},
+ { 1416666626930237, 16, 1, 11, 2},
+ { 1428571462631226, 19, 1, 13, 2},
+ { 1440000057220459, 17, 1, 4, 5},
+ { 1461538434028625, 18, 1, 12, 2},
+ { 1478260874748230, 19, 1, 8, 3},
+ { 1500000000000000, 17, 1, 11, 2},
+ { 1519999980926514, 18, 1, 4, 5},
+ { 1533333301544189, 22, 1, 14, 2},
+ { 1545454502105713, 16, 1, 10, 2},
+ { 1565217375755310, 21, 1, 13, 2},
+ { 1583333373069763, 18, 1, 11, 2},
+ { 1600000023841858, 23, 1, 14, 2},
+ { 1619047641754150, 20, 1, 12, 2},
+ { 1636363625526428, 17, 1, 10, 2},
+ { 1652173876762390, 36, 4, 7, 14 },
+ { 1666666626930237, 19, 1, 11, 2},
+ { 1679999947547913, 21, 1, 12, 2},
+ { 1700000047683716, 16, 1, 9, 2},
+ { 1714285731315613, 23, 1, 13, 2},
+ { 1727272748947144, 18, 1, 10, 2},
+ { 1750000000000000, 20, 1, 11, 2},
+ { 1769230723381042, 22, 1, 12, 2},
+ { 1789473652839661, 17, 1, 9, 2},
+ { 1809523820877075, 19, 1, 10, 2},
+ { 1826086997985839, 21, 1, 11, 2},
+ { 1840000033378601, 23, 1, 12, 2},
+ { 1888888835906982, 16, 1, 8, 2},
+ { 1904761910438538, 20, 1, 10, 2},
+ { 1919999957084656, 23, 1, 4, 5},
+ { 2000000000000000, 17, 1, 8, 2},
+ { 2086956501007080, 36, 10, 12, 15 },
+ { 2105263233184814, 20, 1, 9, 2},
+ { 2125000000000000, 16, 1, 15, 1},
+ { 2190476179122924, 23, 1, 10, 2},
+ { 2210526227951049, 21, 1, 9, 2},
+ { 2235294103622437, 19, 1, 8, 2},
+ { 2266666650772095, 16, 1, 14, 1},
+ { 2285714387893677, 23, 1, 6, 3},
+ { 2315789461135864, 22, 1, 9, 2},
+ { 2333333253860474, 20, 1, 8, 2},
+ { 2352941274642944, 18, 12, 6, 15 },
+ { 2375000000000000, 18, 1, 15, 1},
+ { 2400000095367432, 17, 1, 14, 1},
+ { 2428571462631226, 16, 1, 13, 1},
+ { 2470588207244873, 82, 4, 11, 14 },
+ { 2500000000000000, 19, 1, 15, 1},
+ { 2533333301544189, 18, 1, 14, 1},
+ { 2571428537368774, 17, 1, 13, 1},
+ { 2615384578704834, 16, 1, 12, 1},
+ { 2666666746139526, 19, 1, 14, 1},
+ { 2714285612106323, 18, 1, 13, 1},
+ { 2769230842590332, 17, 1, 12, 1},
+ { 2799999952316284, 20, 1, 14, 1},
+ { 2833333253860474, 16, 1, 11, 1},
+ { 2857142925262451, 19, 1, 13, 1},
+ { 2923076868057251, 18, 1, 12, 1},
+ { 3000000000000000, 17, 1, 11, 1},
+ { 3066666603088379, 22, 1, 14, 1},
+ { 3090909004211426, 16, 1, 10, 1},
+ { 3142857074737549, 21, 1, 13, 1},
+ { 3166666746139526, 18, 1, 11, 1},
+ { 3200000047683716, 23, 1, 14, 1},
+ { 3230769157409668, 20, 1, 12, 1},
+ { 3272727251052856, 17, 1, 10, 1},
+ { 3333333253860474, 19, 1, 11, 1},
+ { 3400000095367432, 16, 1, 9, 1},
+ { 3428571462631226, 23, 1, 13, 1},
+ { 3454545497894287, 18, 1, 10, 1},
+ { 3500000000000000, 20, 1, 11, 1},
+ { 3538461446762085, 22, 1, 12, 1},
+ { 3599999904632568, 17, 1, 9, 1},
+ { 3636363744735718, 19, 1, 10, 1},
+ { 3666666746139526, 21, 1, 11, 1},
+ { 3777777671813965, 16, 1, 8, 1},
+ { 3818181753158569, 20, 1, 10, 1},
+ { 4000000000000000, 17, 1, 8, 1},
+ { 4199999809265136, 20, 1, 9, 1},
+ { 4250000000000000, 16, 1, 7, 1},
+ { 4363636493682861, 23, 1, 10, 1},
+ { 4400000095367431, 21, 1, 9, 1},
+ { 4444444656372070, 19, 1, 8, 1},
+ { 4500000000000000, 17, 1, 7, 1},
+ { 4599999904632568, 22, 1, 9, 1},
+ { 4666666507720947, 20, 1, 8, 1},
+ { 4750000000000000, 18, 1, 7, 1},
+ { 4800000190734863, 23, 1, 9, 1},
+ { 4857142925262451, 16, 1, 6, 1},
+ { 5000000000000000, 19, 1, 7, 1},
+ { 5142857074737549, 17, 1, 6, 1},
+ { 5250000000000000, 20, 1, 7, 1},
+ { 5333333492279053, 23, 1, 8, 1},
+ { 5428571224212646, 18, 1, 6, 1},
+ { 5500000000000000, 21, 1, 7, 1},
+ { 5666666507720947, 16, 1, 5, 1},
+ { 5714285850524902, 19, 1, 6, 1},
+ { 6000000000000000, 17, 1, 5, 1},
+ { 6285714149475098, 21, 1, 6, 1},
+ { 6333333492279053, 18, 1, 5, 1},
+ { 6571428775787354, 22, 1, 6, 1},
+ { 6666666507720947, 19, 1, 5, 1},
+ { 6800000190734863, 16, 1, 4, 1},
+ { 6857142925262451, 23, 1, 6, 1},
+ { 7000000000000000, 20, 1, 5, 1},
+ { 7199999809265137, 17, 1, 4, 1},
+ { 7333333492279053, 21, 1, 5, 1},
+ { 7599999904632568, 18, 1, 4, 1},
+ { 7666666507720947, 22, 1, 5, 1},
+ { 8000000000000000, 19, 1, 4, 1},
+ { 8399999618530273, 20, 1, 4, 1},
+ { 8500000000000000, 16, 1, 3, 1},
+ { 8800000190734863, 21, 1, 4, 1},
+ { 9000000000000000, 17, 1, 3, 1},
+ { 9199999809265136, 22, 1, 4, 1},
+ { 9500000000000000, 18, 1, 3, 1},
+ { 9600000381469726, 23, 1, 4, 1},
+ { 10000000000000000, 19, 1, 3, 1},
+ { 10500000000000000, 20, 1, 3, 1},
+ { 11000000000000000, 21, 1, 3, 1},
+ { 11333333015441894, 16, 1, 2, 1},
+ { 11500000000000000, 22, 1, 3, 1},
+ { 12000000000000000, 17, 1, 2, 1},
+ { 12666666984558106, 18, 1, 2, 1},
+ { 13333333015441894, 19, 1, 2, 1},
+ { 14000000000000000, 20, 1, 2, 1},
+ { 14666666984558106, 21, 1, 2, 1},
+ { 15333333015441894, 22, 1, 2, 1},
+ { 16000000000000000, 23, 1, 2, 1},
+ { 17000000000000000, 16, 1, 1, 1},
+ { 18000000000000000, 17, 1, 1, 1},
+ { 19000000000000000, 18, 1, 1, 1},
+ { 20000000000000000, 19, 1, 1, 1},
+ { 21000000000000000, 20, 1, 1, 1},
+ { 22000000000000000, 21, 1, 1, 1},
+ { 23000000000000000, 22, 1, 1, 1},
+ { 24000000000000000, 23, 1, 1, 1},
+};
+EXPORT_SYMBOL(ambarella_pll_frac_table);
+
+struct pll_table ambarella_pll_vout_table[AMBARELLA_PLL_VOUT_TABLE_SIZE] = {
+ { 1000000000000000, 9, 0, 0, 1},// 0.000000
+ { 1007407426834106, 46, 2, 13, 1},// 0.026262
+ { 1014925360679626, 65, 1, 12, 1},// 0.045250
+ { 1019999980926514, 50, 0, 4, 1},// 0.000002
+ { 1022556424140930, 91, 0, 8, 1},// 0.032683
+ { 1027027010917664, 112, 0, 10, 1},// 0.023925
+ { 1030303001403809, 102, 0, 9, 1},// 0.029409
+ { 1033783793449402, 30, 0, 2, 1},// 0.043574
+ { 1037037014961243, 82, 0, 7, 1},// 0.044645
+ { 1040816307067871, 51, 0, 4, 1},// 0.078430
+ { 1043478250503540, 72, 0, 6, 1},// 0.059523
+ { 1046153903007507, 67, 1, 12, 1},// 0.000005
+ { 1049999952316284, 20, 0, 1, 1},// 0.000005
+ { 1054263591766357, 115, 0, 10, 1},// 0.026736
+ { 1058823585510254, 126, 0, 11, 1},// 0.046302
+ { 1062500000000000, 84, 0, 7, 1},// 0.000000
+ { 1066666722297668, 31, 0, 2, 1},// 0.000005
+ { 1070866107940674, 74, 0, 6, 1},// 0.052524
+ { 1074626922607422, 42, 0, 3, 1},// 0.034717
+ { 1079365134239197, 53, 0, 4, 1},// 0.058818
+ { 1082089543342590, 118, 0, 10, 1},// 0.025078
+ { 1085106372833252, 46, 2, 12, 1},// 0.045248
+ { 1088000059127808, 86, 0, 7, 1},// 0.045961
+ { 1092857122421265, 50, 2, 13, 1},// 0.000002
+ { 1096774220466614, 34, 4, 15, 1},// 0.275738
+ { 1101449251174927, 10, 0, 0, 1},// 0.131577
+ { 1105691075325012, 58, 2, 15, 1},// 0.050550
+ { 1108695626258850, 18, 6, 11, 1},// 0.032677
+ { 1111888170242310, 88, 0, 7, 1},// 0.055026
+ { 1114754080772400, 77, 0, 6, 1},// 0.042015
+ { 1117647051811218, 122, 0, 10, 1},// 0.047848
+ { 1120567321777344, 55, 0, 4, 1},// 0.050628
+ { 1123966932296753, 72, 1, 12, 1},// 0.079185
+ { 1127118587493896, 123, 0, 10, 1},// 0.013676
+ { 1130434751510620, 48, 2, 12, 1},// 0.029589
+ { 1133333325386047, 33, 0, 2, 1},// 0.000001
+ { 1136752128601074, 124, 0, 10, 1},// 0.034176
+ { 1139705896377563, 56, 0, 4, 1},// 0.025805
+ { 1142857193946838, 79, 0, 6, 1},// 0.000004
+ { 1146551728248596, 85, 1, 14, 1},// 0.010025
+ { 1149606347084045, 22, 0, 1, 1},// 0.034242
+ { 1152542352676392, 74, 1, 12, 1},// 0.113124
+ { 1155555605888367, 103, 0, 8, 1},// 0.000004
+ { 1159090876579285, 57, 0, 4, 1},// 0.078434
+ { 1162393212318420, 92, 0, 7, 1},// 0.009187
+ { 1166666626930237, 34, 0, 2, 1},// 0.000003
+ { 1172413825988770, 42, 2, 10, 1},// 0.026735
+ { 1176923036575317, 50, 2, 12, 1},// 0.000003
+ { 1182608723640442, 70, 0, 5, 1},// 0.061272
+ { 1186046481132507, 82, 0, 6, 1},// 0.028009
+ { 1189189195632935, 106, 0, 8, 1},// 0.025253
+ { 1192982435226440, 30, 4, 12, 1},// 0.056559
+ { 1196850419044495, 11, 0, 0, 1},// 0.263156
+ { 1200000047683716, 11, 0, 0, 1},// 0.000004
+ { 1203539848327637, 11, 0, 0, 1},// 0.294120
+ { 1206896543502808, 12, 12, 13, 1},// 0.020409
+ { 1210084080696106, 120, 0, 9, 1},// 0.006948
+ { 1214285731315613, 84, 0, 6, 1},// 0.000001
+ { 1220338940620422, 60, 0, 4, 1},// 0.027774
+ { 1225225210189819, 48, 0, 3, 1},// 0.018381
+ { 1230769276618958, 79, 1, 12, 1},// 0.000004
+ { 1236363649368286, 67, 1, 10, 1},// 0.000001
+ { 1239669442176819, 61, 0, 4, 1},// 0.026665
+ { 1243902444839478, 111, 0, 8, 1},// 0.043573
+ { 1247706413269043, 16, 10, 14, 1},// 0.083333
+ { 1254098415374756, 68, 1, 10, 1},// 0.035646
+ { 1259259223937988, 62, 0, 4, 1},// 0.058826
+ { 1264462828636169, 58, 2, 13, 1},// 0.014007
+ { 1267857193946838, 28, 6, 15, 1},// 0.070419
+ { 1271028041839600, 88, 0, 6, 1},// 0.031512
+ { 1274999976158142, 50, 0, 3, 1},// 0.000002
+ { 1278846144676208, 114, 0, 8, 1},// 0.083541
+ { 1283018827438354, 76, 0, 5, 1},// 0.024513
+ { 1286956548690796, 102, 0, 7, 1},// 0.042228
+ { 1291262149810791, 70, 1, 10, 1},// 0.027342
+ { 1295238137245178, 68, 2, 15, 1},// 0.114893
+ { 1299145340919495, 12, 0, 0, 1},// 0.065786
+ { 1303921580314636, 18, 10, 15, 1},// 0.178571
+ { 1307692289352417, 84, 1, 12, 1},// 0.000001
+ { 1312500000000000, 104, 0, 7, 1},// 0.000000
+ { 1316831707954407, 78, 0, 5, 1},// 0.012533
+ { 1320388317108154, 65, 0, 4, 1},// 0.029409
+ { 1324324369430542, 52, 0, 3, 1},// 0.051017
+ { 1330000042915344, 18, 6, 9, 1},// 0.000003
+ { 1333333373069763, 39, 0, 2, 1},// 0.000003
+ { 1342105269432068, 22, 6, 11, 1},// 0.032680
+ { 1346534609794617, 100, 1, 14, 1},// 0.009807
+ { 1350000023841858, 26, 0, 1, 1},// 0.000002
+ { 1353982329368591, 87, 1, 12, 1},// 0.010057
+ { 1360000014305115, 67, 0, 4, 1},// 0.000001
+ { 1366071462631226, 40, 0, 2, 1},// 0.043570
+ { 1373737335205078, 102, 1, 14, 1},// 0.029409
+ { 1378378391265869, 123, 0, 8, 1},// 0.043574
+ { 1383928537368774, 82, 0, 5, 1},// 0.043008
+ { 1387755155563354, 110, 0, 7, 1},// 0.018386
+ { 1394495368003845, 18, 10, 14, 1},// 0.083330
+ { 1398058295249939, 13, 0, 0, 1},// 0.138886
+ { 1402061820030212, 13, 0, 0, 1},// 0.147056
+ { 1407407402992249, 60, 2, 12, 1},// 0.020243
+ { 1411764740943909, 126, 0, 8, 1},// 0.046299
+ { 1416666626930237, 84, 0, 5, 1},// 0.000003
+ { 1420560717582703, 70, 0, 4, 1},// 0.039472
+ { 1425742626190186, 56, 0, 3, 1},// 0.052087
+ { 1431578993797302, 92, 1, 12, 1},// 0.056564
+ { 1436170220375061, 78, 1, 10, 1},// 0.013467
+ { 1440000057220459, 71, 0, 4, 1},// 0.000004
+ { 1446808457374573, 30, 6, 14, 1},// 0.009800
+ { 1450549483299255, 28, 0, 1, 1},// 0.037881
+ { 1457142829895020, 101, 0, 6, 1},// 0.000002
+ { 1462365627288818, 116, 0, 7, 1},// 0.009189
+ { 1466666698455811, 43, 0, 2, 1},// 0.000002
+ { 1471153855323792, 102, 0, 6, 1},// 0.018674
+ { 1478260874748230, 68, 2, 13, 1},// 0.021008
+ { 1485436916351318, 103, 0, 6, 1},// 0.018673
+ { 1490196108818054, 81, 1, 10, 1},// 0.047845
+ { 1494505524635315, 111, 1, 14, 1},// 0.078433
+ { 1500000000000000, 14, 0, 0, 1},// 0.000000
+ { 1504950523376465, 112, 1, 14, 1},// 0.114033
+ { 1511111140251160, 67, 1, 8, 1},// 0.000002
+ { 1515789508819580, 90, 0, 5, 1},// 0.057868
+ { 1519999980926514, 75, 0, 4, 1},// 0.000001
+ { 1528089880943298, 106, 0, 6, 1},// 0.031513
+ { 1531914949417114, 48, 4, 15, 1},// 0.043406
+ { 1538461565971375, 99, 1, 12, 1},// 0.000002
+ { 1545454502105713, 84, 1, 10, 1},// 0.000003
+ { 1551020383834839, 30, 0, 1, 1},// 0.065788
+ { 1555555582046509, 69, 1, 8, 1},// 0.000002
+ { 1563218355178833, 85, 1, 10, 1},// 0.026740
+ { 1568181872367859, 101, 1, 12, 1},// 0.066886
+ { 1573033690452576, 117, 1, 14, 1},// 0.019049
+ { 1577319622039795, 40, 4, 12, 1},// 0.025140
+ { 1581395387649536, 22, 10, 15, 1},// 0.009194
+ { 1587628841400146, 126, 0, 7, 1},// 0.008115
+ { 1593750000000000, 84, 2, 15, 1},// 0.000000
+ { 1600000023841858, 15, 0, 0, 1},// 0.000001
+ { 1604166626930237, 74, 2, 13, 1},// 0.185531
+ { 1610526323318481, 22, 6, 9, 1},// 0.032680
+ { 1614583373069763, 112, 0, 6, 1},// 0.018436
+ { 1619047641754150, 36, 6, 15, 1},// 0.018384
+ { 1623529434204102, 72, 1, 8, 1},// 0.080517
+ { 1627659559249878, 113, 0, 6, 1},// 0.056023
+ { 1634408593177795, 48, 0, 2, 1},// 0.065789
+ { 1638554215431213, 70, 2, 12, 1},// 0.005656
+ { 1645161271095276, 73, 1, 8, 1},// 0.043572
+ { 1652173876762390, 123, 1, 14, 1},// 0.070178
+ { 1658536553382874, 115, 0, 6, 1},// 0.084032
+ { 1663043498992920, 18, 6, 7, 1},// 0.032681
+ { 1674418568611145, 66, 0, 3, 1},// 0.034724
+ { 1679012298583984, 46, 4, 13, 1},// 0.026258
+ { 1683544278144836, 100, 0, 5, 1},// 0.012530
+ { 1688888907432556, 75, 1, 8, 1},// 0.000001
+ { 1694117665290833, 126, 1, 14, 1},// 0.046297
+ { 1700000047683716, 16, 0, 0, 1},// 0.000003
+ { 1705128192901611, 90, 2, 15, 1},// 0.065790
+ { 1709677457809448, 56, 2, 9, 1},// 0.018866
+ { 1714285731315613, 119, 0, 6, 1},// 0.000001
+ { 1721518993377686, 30, 4, 8, 1},// 0.040849
+ { 1727272748947144, 94, 1, 10, 1},// 0.000001
+ { 1733333349227905, 51, 0, 2, 1},// 0.000001
+ { 1738636374473572, 112, 1, 12, 1},// 0.010056
+ { 1743589758872986, 92, 2, 15, 1},// 0.009190
+ { 1750000000000000, 34, 0, 1, 1},// 0.000000
+ { 1758620738983154, 87, 0, 4, 1},// 0.078429
+ { 1766233801841736, 52, 0, 2, 1},// 0.024508
+ { 1773333311080933, 37, 6, 14, 1},// 0.000001
+ { 1779069781303406, 82, 2, 13, 1},// 0.028012
+ { 1783783793449402, 106, 0, 5, 1},// 0.025253
+ { 1789473652839661, 22, 6, 8, 1},// 0.032678
+ { 1794871807098389, 40, 6, 15, 1},// 0.062501
+ { 1799999952316284, 17, 0, 0, 1},// 0.000003
+ { 1808219194412231, 30, 6, 11, 1},// 0.006312
+ { 1813333392143250, 67, 3, 14, 1},// 0.000003
+ { 1821428537368774, 84, 2, 13, 1},// 0.000002
+ { 1831325292587280, 118, 1, 12, 1},// 0.030364
+ { 1837837815284729, 48, 2, 7, 1},// 0.018381
+ { 1843373537063599, 58, 4, 15, 1},// 0.020422
+ { 1848837256431580, 36, 0, 1, 1},// 0.062891
+ { 1853658556938171, 101, 1, 10, 1},// 0.047846
+ { 1863013744354248, 40, 4, 10, 1},// 0.033420
+ { 1870129823684692, 16, 10, 9, 1},// 0.006942
+ { 1876543164253235, 121, 1, 12, 1},// 0.020245
+ { 1883116841316223, 112, 0, 5, 1},// 0.011496
+ { 1888888835906982, 84, 1, 8, 1},// 0.000003
+ { 1894736886024475, 100, 2, 15, 1},// 0.052086
+ { 1899999976158142, 18, 0, 0, 1},// 0.000001
+ { 1909090876579285, 104, 1, 10, 1},// 0.000002
+ { 1915493011474609, 82, 2, 12, 1},// 0.005659
+ { 1922077894210815, 124, 1, 12, 1},// 0.051977
+ { 1927536249160767, 105, 1, 10, 1},// 0.013671
+ { 1936708807945251, 70, 2, 10, 1},// 0.017823
+ { 1942857146263123, 67, 1, 6, 1},// 0.000000
+ { 1948717951774597, 38, 0, 1, 1},// 0.065789
+ { 1955882310867310, 87, 1, 8, 1},// 0.016706
+ { 1961538434028625, 84, 2, 12, 1},// 0.000001
+ { 1971014499664307, 68, 1, 6, 1},// 0.021008
+ { 1987012982368469, 52, 2, 7, 1},// 0.024510
+ { 2000000000000000, 19, 0, 0, 1},// 0.000000
+ { 2013157844543457, 22, 6, 7, 1},// 0.032677
+ { 2029850721359253, 28, 6, 9, 1},// 0.007354
+ { 2039999961853027, 101, 0, 4, 1},// 0.000002
+ { 2046153783798218, 37, 6, 12, 1},// 0.000003
+ { 2054054021835327, 88, 2, 12, 1},// 0.010120
+ { 2060606002807617, 102, 0, 4, 1},// 0.029409
+ { 2067567586898804, 61, 0, 2, 1},// 0.043574
+ { 2078125000000000, 16, 10, 8, 1},// 0.016708
+ { 2086956501007080, 72, 1, 6, 1},// 0.059523
+ { 2092307806015015, 67, 3, 12, 1},// 0.000005
+ { 2099999904632568, 20, 0, 0, 1},// 0.000005
+ { 2111111164093018, 94, 1, 8, 1},// 0.000003
+ { 2117647171020508, 126, 0, 5, 1},// 0.046302
+ { 2125000000000000, 84, 0, 3, 1},// 0.000000
+ { 2130434751510620, 70, 2, 9, 1},// 0.020407
+ { 2140845060348511, 106, 0, 4, 1},// 0.039473
+ { 2149253845214844, 42, 0, 1, 1},// 0.034717
+ { 2158730268478394, 36, 6, 11, 1},// 0.018387
+ { 2164179086685181, 100, 2, 13, 1},// 0.004927
+ { 2171428680419922, 75, 1, 6, 1},// 0.000005
+ { 2177419424057007, 97, 1, 8, 1},// 0.016458
+ { 2185714244842529, 50, 2, 6, 1},// 0.000002
+ { 2193548440933228, 116, 2, 15, 1},// 0.009189
+ { 2202898502349854, 21, 0, 0, 1},// 0.131577
+ { 2208955287933350, 80, 2, 10, 1},// 0.006140
+ { 2217391252517700, 18, 6, 5, 1},// 0.032677
+ { 2229508161544800, 77, 1, 6, 1},// 0.042015
+ { 2235294103622437, 122, 1, 10, 1},// 0.047848
+ { 2242424249649048, 100, 1, 8, 1},// 0.090090
+ { 2250000000000000, 44, 0, 1, 1},// 0.000000
+ { 2258064508438110, 78, 1, 6, 1},// 0.040816
+ { 2266666650772095, 67, 0, 2, 1},// 0.000001
+ { 2275861978530884, 90, 0, 3, 1},// 0.037875
+ { 2283581972122192, 98, 2, 12, 1},// 0.045254
+ { 2293103456497192, 85, 3, 14, 1},// 0.010025
+ { 2305084705352783, 122, 2, 15, 1},// 0.050553
+ { 2311475515365601, 103, 1, 8, 1},// 0.015765
+ { 2318181753158569, 84, 2, 10, 1},// 0.000003
+ { 2333333253860474, 69, 0, 2, 1},// 0.000003
+ { 2344827651977539, 85, 2, 10, 1},// 0.026735
+ { 2353846073150635, 101, 2, 12, 1},// 0.000003
+ { 2360655784606934, 117, 0, 4, 1},// 0.027780
+ { 2368421077728271, 76, 3, 12, 1},// 0.034187
+ { 2375000000000000, 94, 0, 3, 1},// 0.000000
+ { 2385964870452881, 61, 4, 12, 1},// 0.056559
+ { 2392857074737549, 66, 4, 13, 1},// 0.000003
+ { 2400000095367432, 23, 0, 0, 1},// 0.000004
+ { 2409836053848267, 52, 4, 10, 1},// 0.030921
+ { 2418181896209717, 37, 6, 10, 1},// 0.000003
+ { 2428571462631226, 84, 1, 6, 1},// 0.000001
+ { 2440677881240845, 121, 0, 4, 1},// 0.027774
+ { 2451612949371338, 48, 0, 1, 1},// 0.065791
+ { 2462962865829468, 114, 2, 13, 1},// 0.053710
+ { 2472727298736572, 67, 3, 10, 1},// 0.000001
+ { 2482758522033691, 90, 2, 10, 1},// 0.037875
+ { 2491803169250488, 22, 12, 11, 1},// 0.005478
+ { 2500000000000000, 24, 0, 0, 1},// 0.000000
+ { 2508196830749512, 42, 6, 11, 1},// 0.005442
+ { 2518518447875977, 30, 12, 15, 1},// 0.009194
+ { 2526315689086914, 100, 0, 3, 1},// 0.052079
+ { 2533333301544189, 75, 0, 2, 1},// 0.000001
+ { 2542372941970825, 88, 1, 6, 1},// 0.019045
+ { 2549999952316284, 50, 0, 1, 1},// 0.000002
+ { 2557692289352417, 114, 1, 8, 1},// 0.083541
+ { 2566037654876709, 76, 0, 2, 1},// 0.024513
+ { 2576271295547485, 66, 4, 12, 1},// 0.025299
+ { 2586206912994385, 96, 3, 14, 1},// 0.017777
+ { 2593220233917236, 120, 2, 13, 1},// 0.014002
+ { 2599999904632568, 25, 0, 0, 1},// 0.000004
+ { 2607843160629272, 112, 2, 12, 1},// 0.005785
+ { 2615384578704834, 84, 3, 12, 1},// 0.000001
+ { 2625000000000000, 104, 0, 3, 1},// 0.000000
+ { 2637931108474731, 48, 6, 12, 1},// 0.020108
+ { 2647058725357056, 85, 3, 12, 1},// 0.034184
+ { 2660000085830688, 18, 6, 4, 1},// 0.000003
+ { 2666666746139526, 79, 0, 2, 1},// 0.000003
+ { 2684210538864136, 22, 6, 5, 1},// 0.032680
+ { 2692307710647583, 69, 4, 12, 1},// 0.000001
+ { 2701754331588745, 26, 0, 0, 1},// 0.064933
+ { 2711538553237915, 121, 1, 8, 1},// 0.015764
+ { 2720000028610229, 67, 1, 4, 1},// 0.000001
+ { 2732142925262451, 81, 0, 2, 1},// 0.043570
+ { 2745098114013672, 18, 12, 8, 1},// 0.023812
+ { 2755102157592773, 123, 1, 8, 1},// 0.016457
+ { 2763636350631714, 75, 3, 10, 1},// 0.000000
+ { 2775510311126709, 110, 0, 3, 1},// 0.018386
+ { 2785714387893677, 64, 2, 6, 1},// 0.000004
+ { 2799999952316284, 27, 0, 0, 1},// 0.000002
+ { 2807692289352417, 72, 4, 12, 1},// 0.000001
+ { 2814814805984497, 121, 2, 12, 1},// 0.020243
+ { 2823529481887817, 126, 1, 8, 1},// 0.046299
+ { 2833333253860474, 84, 0, 2, 1},// 0.000003
+ { 2843137264251709, 90, 4, 15, 1},// 0.021551
+ { 2857142925262451, 99, 1, 6, 1},// 0.000002
+ { 2867924451828003, 50, 8, 15, 1},// 0.028786
+ { 2880000114440918, 71, 1, 4, 1},// 0.000004
+ { 2893616914749146, 61, 6, 14, 1},// 0.009800
+ { 2905660390853882, 92, 4, 15, 1},// 0.020292
+ { 2913043498992920, 101, 1, 6, 1},// 0.042643
+ { 2923076868057251, 94, 3, 12, 1},// 0.000002
+ { 2933333396911621, 87, 0, 2, 1},// 0.000002
+ { 2942307710647583, 102, 1, 6, 1},// 0.018674
+ { 2956521749496460, 42, 10, 15, 1},// 0.009192
+ { 2980392217636108, 52, 8, 15, 1},// 0.028781
+ { 3000000000000000, 29, 0, 0, 1},// 0.000000
+ { 3022222280502319, 67, 3, 8, 1},// 0.000002
+ { 3039999961853027, 75, 1, 4, 1},// 0.000001
+ { 3059999942779541, 50, 2, 4, 1},// 0.000002
+ { 3069767475128174, 56, 6, 12, 1},// 0.017484
+ { 3079999923706055, 76, 1, 4, 1},// 0.000002
+ { 3090909004211426, 84, 3, 10, 1},// 0.000003
+ { 3102040767669678, 30, 0, 0, 1},// 0.065788
+ { 3111111164093018, 69, 3, 8, 1},// 0.000002
+ { 3122448921203613, 57, 6, 12, 1},// 0.020112
+ { 3130434751510620, 36, 10, 12, 1},// 0.010685
+ { 3142857074737549, 109, 1, 6, 1},// 0.000002
+ { 3152173995971680, 42, 10, 14, 1},// 0.036779
+ { 3162790775299072, 22, 10, 7, 1},// 0.009194
+ { 3173913002014160, 118, 3, 14, 1},// 0.018264
+ { 3187500000000000, 84, 2, 7, 1},// 0.000000
+ { 3200000047683716, 31, 0, 0, 1},// 0.000001
+ { 3208333253860474, 76, 4, 11, 1},// 0.000002
+ { 3219512224197388, 22, 6, 4, 1},// 0.015151
+ { 3229166746139526, 112, 1, 6, 1},// 0.018436
+ { 3238095283508301, 36, 6, 7, 1},// 0.018384
+ { 3255319118499756, 46, 8, 12, 1},// 0.045248
+ { 3272727251052856, 119, 2, 10, 1},// 0.000001
+ { 3285714387893677, 114, 1, 6, 1},// 0.000003
+ { 3295454502105713, 37, 12, 14, 1},// 0.064367
+ { 3304347753524780, 123, 3, 14, 1},// 0.070178
+ { 3317073106765747, 72, 4, 10, 1},// 0.033424
+ { 3326086997985840, 18, 6, 3, 1},// 0.032681
+ { 3348837137222290, 66, 0, 1, 1},// 0.034724
+ { 3365853548049927, 100, 0, 2, 1},// 0.024158
+ { 3377777814865112, 75, 3, 8, 1},// 0.000001
+ { 3391304254531860, 36, 10, 11, 1},// 0.010687
+ { 3400000095367432, 33, 0, 0, 1},// 0.000003
+ { 3410256385803223, 30, 10, 9, 1},// 0.007518
+ { 3428571462631226, 119, 1, 6, 1},// 0.000001
+ { 3444444417953491, 61, 4, 8, 1},// 0.000001
+ { 3454545497894287, 94, 3, 10, 1},// 0.000001
+ { 3466666698455811, 103, 0, 2, 1},// 0.000001
+ { 3477272748947144, 112, 3, 12, 1},// 0.010056
+ { 3487179517745972, 92, 2, 7, 1},// 0.009190
+ { 3500000000000000, 34, 0, 0, 1},// 0.000000
+ { 3512195110321045, 78, 3, 8, 1},// 0.030864
+ { 3522727251052856, 46, 2, 3, 1},// 0.064517
+ { 3534883737564087, 98, 4, 13, 1},// 0.023496
+ { 3545454502105713, 77, 4, 10, 1},// 0.000001
+ { 3558139562606812, 60, 6, 11, 1},// 0.005446
+ { 3567567586898804, 106, 0, 2, 1},// 0.025253
+ { 3578947305679321, 45, 6, 8, 1},// 0.032678
+ { 3589743614196777, 78, 4, 10, 1},// 0.032467
+ { 3599999904632568, 35, 0, 0, 1},// 0.000003
+ { 3609755992889404, 64, 4, 8, 1},// 0.037540
+ { 3619047641754150, 30, 6, 5, 1},// 0.065790
+ { 3631578922271729, 117, 3, 12, 1},// 0.022296
+ { 3642857074737549, 84, 2, 6, 1},// 0.000002
+ { 3658536672592163, 127, 1, 6, 1},// 0.038098
+ { 3675675630569458, 48, 2, 3, 1},// 0.018381
+ { 3692307710647583, 119, 3, 12, 1},// 0.000000
+ { 3707317113876343, 88, 4, 11, 1},// 0.027411
+ { 3717948675155640, 92, 1, 4, 1},// 0.055174
+ { 3731707334518433, 96, 4, 12, 1},// 0.025139
+ { 3743589639663696, 102, 3, 10, 1},// 0.049816
+ { 3756097555160522, 25, 12, 8, 1},// 0.014430
+ { 3777777671813965, 84, 3, 8, 1},// 0.000003
+ { 3789473772048950, 30, 10, 8, 1},// 0.015434
+ { 3799999952316284, 37, 0, 0, 1},// 0.000001
+ { 3810810804367065, 48, 6, 8, 1},// 0.007880
+ { 3825000047683716, 50, 2, 3, 1},// 0.000001
+ { 3837837934494019, 95, 1, 4, 1},// 0.056336
+ { 3849999904632568, 76, 0, 1, 1},// 0.000002
+ { 3868421077728271, 42, 8, 9, 1},// 0.040816
+ { 3885714292526245, 67, 3, 6, 1},// 0.000000
+ { 3897435903549194, 38, 0, 0, 1},// 0.065789
+ { 3911764621734619, 87, 3, 8, 1},// 0.016706
+ { 3923076868057251, 97, 1, 4, 1},// 0.078430
+ { 3948717832565308, 78, 0, 1, 1},// 0.032470
+ { 3972972869873047, 52, 2, 3, 1},// 0.051023
+ { 4000000000000000, 39, 0, 0, 1},// 0.000000
+ { 4026315689086914, 22, 6, 3, 1},// 0.032677
+ { 4052631378173828, 80, 0, 1, 1},// 0.064930
+ { 4083333492279053, 48, 4, 5, 1},// 0.000004
+ { 4108108043670654, 112, 3, 10, 1},// 0.023925
+ { 4121212005615234, 52, 6, 8, 1},// 0.024513
+ { 4135135173797607, 90, 4, 10, 1},// 0.029708
+ { 4156250000000000, 33, 10, 8, 1},// 0.016708
+ { 4166666507720947, 124, 0, 2, 1},// 0.000004
+ { 4181818008422852, 114, 3, 10, 1},// 0.000004
+ { 4199999809265137, 41, 0, 0, 1},// 0.000005
+ { 4222222328186035, 94, 3, 8, 1},// 0.000003
+ { 4235294342041016, 126, 0, 2, 1},// 0.046302
+ { 4250000000000000, 84, 0, 1, 1},// 0.000000
+ { 4264705657958984, 66, 6, 10, 1},// 0.025073
+ { 4277777671813965, 76, 4, 8, 1},// 0.000002
+ { 4290322780609131, 38, 10, 9, 1},// 0.007523
+ { 4312500000000000, 114, 2, 7, 1},// 0.000000
+ { 4323529243469238, 107, 1, 4, 1},// 0.081629
+ { 4342857360839844, 75, 3, 6, 1},// 0.000005
+ { 4354838848114014, 97, 3, 8, 1},// 0.016458
+ { 4371428489685059, 101, 2, 6, 1},// 0.000002
+ { 4387096881866455, 116, 2, 7, 1},// 0.009189
+ { 4400000095367432, 43, 0, 0, 1},// 0.000002
+ { 4411764621734619, 62, 6, 9, 1},// 0.039998
+ { 4433333396911621, 18, 6, 2, 1},// 0.000001
+ { 4454545497894287, 97, 4, 10, 1},// 0.000001
+ { 4470588207244873, 122, 3, 10, 1},// 0.047848
+ { 4484848499298096, 100, 3, 8, 1},// 0.090090
+ { 4500000000000000, 44, 0, 0, 1},// 0.000000
+ { 4516129016876221, 78, 3, 6, 1},// 0.040816
+ { 4533333301544189, 67, 1, 2, 1},// 0.000001
+ { 4551723957061768, 90, 0, 1, 1},// 0.037875
+ { 4586206912994385, 106, 2, 6, 1},// 0.010741
+ { 4606060504913330, 82, 4, 8, 1},// 0.109651
+ { 4620689868927002, 76, 2, 4, 1},// 0.014930
+ { 4636363506317139, 52, 6, 7, 1},// 0.024513
+ { 4666666507720947, 69, 1, 2, 1},// 0.000003
+ { 4689655303955078, 66, 6, 9, 1},// 0.007350
+ { 4714285850524902, 109, 2, 6, 1},// 0.000003
+ { 4727272510528564, 62, 2, 3, 1},// 0.048072
+ { 4750000000000000, 94, 0, 1, 1},// 0.000000
+ { 4781250000000000, 40, 6, 5, 1},// 0.043573
+ { 4800000190734863, 47, 0, 0, 1},// 0.000004
+ { 4812500000000000, 76, 4, 7, 1},// 0.000000
+ { 4827586174011230, 25, 12, 6, 1},// 0.020409
+ { 4843750000000000, 108, 3, 8, 1},// 0.014337
+ { 4857142925262451, 84, 3, 6, 1},// 0.000001
+ { 4875000000000000, 64, 2, 3, 1},// 0.000000
+ { 4888888835906982, 109, 3, 8, 1},// 0.000001
+ { 4903225898742676, 48, 0, 0, 1},// 0.065791
+ { 4935483932495117, 78, 4, 7, 1},// 0.040848
+ { 4965517044067383, 70, 6, 9, 1},// 0.090282
+ { 5000000000000000, 49, 0, 0, 1},// 0.000000
+ { 5037036895751953, 30, 12, 7, 1},// 0.009194
+ { 5066666603088379, 75, 1, 2, 1},// 0.000001
+ { 5099999904632568, 50, 0, 0, 1},// 0.000002
+ { 5115384578704834, 114, 3, 8, 1},// 0.083541
+ { 5129032135009766, 40, 4, 3, 1},// 0.078614
+ { 5142857074737549, 119, 2, 6, 1},// 0.000001
+ { 5166666507720947, 30, 4, 2, 1},// 0.000003
+ { 5185184955596924, 120, 2, 6, 1},// 0.010209
+ { 5199999809265137, 51, 0, 0, 1},// 0.000004
+ { 5214285850524902, 72, 4, 6, 1},// 0.000003
+ { 5230769157409668, 121, 2, 6, 1},// 0.042015
+ { 5250000000000000, 104, 0, 1, 1},// 0.000000
+ { 5275862216949463, 94, 4, 8, 1},// 0.036308
+ { 5300000190734863, 52, 0, 0, 1},// 0.000004
+ { 5320000171661377, 37, 6, 4, 1},// 0.000003
+ { 5333333492279053, 79, 1, 2, 1},// 0.000003
+ { 5357142925262451, 124, 2, 6, 1},// 0.000001
+ { 5384615421295166, 28, 12, 6, 1},// 0.020407
+ { 5400000095367432, 53, 0, 0, 1},// 0.000002
+ { 5423077106475830, 121, 3, 8, 1},// 0.015764
+ { 5440000057220459, 67, 3, 4, 1},// 0.000001
+ { 5464285850524902, 81, 1, 2, 1},// 0.043570
+ { 5481481552124023, 46, 6, 5, 1},// 0.033782
+ { 5500000000000000, 54, 0, 0, 1},// 0.000000
+ { 5519999980926514, 91, 2, 4, 1},// 0.000000
+ { 5538461685180664, 96, 3, 6, 1},// 0.079362
+ { 5555555343627930, 124, 3, 8, 1},// 0.000004
+ { 5571428775787354, 77, 4, 6, 1},// 0.000004
+ { 5599999904632568, 55, 0, 0, 1},// 0.000002
+ { 5615384578704834, 74, 2, 3, 1},// 0.171234
+ { 5629629611968994, 12, 12, 2, 1},// 0.065790
+ { 5666666507720947, 84, 1, 2, 1},// 0.000003
+ { 5703703880310059, 56, 0, 0, 1},// 0.064938
+ { 5739130496978760, 40, 6, 4, 1},// 0.015150
+ { 5760000228881836, 95, 2, 4, 1},// 0.000004
+ { 5782608509063721, 80, 4, 6, 1},// 0.053709
+ { 5800000190734863, 57, 0, 0, 1},// 0.000003
+ { 5826086997985840, 101, 3, 6, 1},// 0.042643
+ { 5846153736114502, 116, 0, 1, 1},// 0.065791
+ { 5869565010070801, 87, 1, 2, 1},// 0.049379
+ { 5884615421295166, 102, 3, 6, 1},// 0.018674
+ { 5913043498992920, 42, 10, 7, 1},// 0.009192
+ { 5961538314819336, 52, 8, 7, 1},// 0.016131
+ { 6000000000000000, 59, 0, 0, 1},// 0.000000
+ { 6045454502105713, 46, 8, 6, 1},// 0.042964
+ { 6079999923706055, 75, 3, 4, 1},// 0.000001
+ { 6119999885559082, 101, 2, 4, 1},// 0.000002
+ { 6136363506317139, 91, 1, 2, 1},// 0.049381
+ { 6159999847412109, 76, 3, 4, 1},// 0.000002
+ { 6181818008422852, 52, 6, 5, 1},// 0.024513
+ { 6199999809265137, 61, 0, 0, 1},// 0.000003
+ { 6239999771118164, 103, 2, 4, 1},// 0.000004
+ { 6260869503021240, 72, 5, 6, 1},// 0.059523
+ { 6285714149475098, 109, 3, 6, 1},// 0.000002
+ { 6304347991943359, 62, 0, 0, 1},// 0.068968
+ { 6333333492279053, 94, 1, 2, 1},// 0.000003
+ { 6375000000000000, 84, 2, 3, 1},// 0.000000
+ { 6391304492950439, 63, 0, 0, 1},// 0.136052
+ { 6416666507720947, 76, 4, 5, 1},// 0.000002
+ { 6434782505035400, 45, 6, 4, 1},// 0.081083
+ { 6458333492279053, 112, 3, 6, 1},// 0.018436
+ { 6476190567016602, 36, 6, 3, 1},// 0.018384
+ { 6500000000000000, 64, 0, 0, 1},// 0.000000
+ { 6521739006042480, 86, 2, 3, 1},// 0.050002
+ { 6545454502105713, 108, 2, 4, 1},// 0.083333
+ { 6571428775787354, 114, 3, 6, 1},// 0.000003
+ { 6590909004211426, 78, 4, 5, 1},// 0.114941
+ { 6608695507049561, 65, 0, 0, 1},// 0.131577
+ { 6652173995971680, 18, 6, 1, 1},// 0.032681
+ { 6681818008422852, 116, 3, 6, 1},// 0.058312
+ { 6699999809265137, 66, 0, 0, 1},// 0.000003
+ { 6727272510528564, 100, 1, 2, 1},// 0.090093
+ { 6750000000000000, 44, 2, 1, 1},// 0.000000
+ { 6782608509063721, 36, 10, 5, 1},// 0.010687
+ { 6800000190734863, 67, 0, 0, 1},// 0.000003
+ { 6818181991577148, 30, 10, 4, 1},// 0.026664
+ { 6857142925262451, 119, 3, 6, 1},// 0.000001
+ { 6909090995788574, 120, 3, 6, 1},// 0.075187
+ { 6954545497894287, 115, 2, 4, 1},// 0.078431
+ { 7000000000000000, 69, 0, 0, 1},// 0.000000
+ { 7045454502105713, 46, 2, 1, 1},// 0.064517
+ { 7090909004211426, 123, 3, 6, 1},// 0.073259
+ { 7157894611358643, 12, 10, 1, 1},// 0.110292
+ { 7181818008422852, 40, 6, 3, 1},// 0.094934
+ { 7199999809265137, 71, 0, 0, 1},// 0.000003
+ { 7238095283508301, 30, 6, 2, 1},// 0.065790
+ { 7263157844543457, 120, 2, 4, 1},// 0.043478
+ { 7285714149475098, 90, 3, 4, 1},// 0.078430
+ { 7349999904632568, 48, 2, 1, 1},// 0.000001
+ { 7368421077728271, 16, 12, 2, 1},// 0.023810
+ { 7388888835906982, 122, 2, 4, 1},// 0.120300
+ { 7428571224212646, 98, 2, 3, 1},// 0.048074
+ { 7473684310913086, 22, 12, 3, 1},// 0.017604
+ { 7500000000000000, 74, 0, 0, 1},// 0.000000
+ { 7523809432983398, 42, 6, 3, 1},// 0.015824
+ { 7555555343627930, 125, 2, 4, 1},// 0.058826
+ { 7578947544097900, 100, 2, 3, 1},// 0.052086
+ { 7599999904632568, 75, 0, 0, 1},// 0.000001
+ { 7650000095367432, 50, 2, 1, 1},// 0.000001
+ { 7699999809265137, 76, 0, 0, 1},// 0.000002
+ { 7736842155456543, 42, 8, 4, 1},// 0.040816
+ { 7777777671813965, 96, 3, 4, 1},// 0.228570
+ { 7800000190734863, 77, 0, 0, 1},// 0.000002
+ { 7823529243469238, 66, 6, 5, 1},// 0.087717
+ { 7894736766815186, 78, 0, 0, 1},// 0.066668
+ { 7941176414489746, 118, 1, 2, 1},// 0.098765
+ { 8000000000000000, 79, 0, 0, 1},// 0.000000
+ { 8052631378173828, 22, 6, 1, 1},// 0.032677
+ { 8105262756347656, 80, 0, 0, 1},// 0.064930
+ { 8166666984558105, 48, 4, 2, 1},// 0.000004
+ { 8210526466369629, 81, 0, 0, 1},// 0.128207
+ { 8235294342041016, 18, 12, 2, 1},// 0.023812
+ { 8312500000000000, 103, 3, 4, 1},// 0.090226
+ { 8333333015441895, 124, 1, 2, 1},// 0.000004
+ { 8368420600891113, 66, 4, 3, 1},// 0.078622
+ { 8444444656372070, 12, 12, 1, 1},// 0.065787
+ { 8470588684082031, 126, 1, 2, 1},// 0.046302
+ { 8500000000000000, 84, 0, 0, 1},// 0.000000
+ { 8529411315917969, 127, 1, 2, 1},// 0.045982
+ { 8555555343627930, 106, 3, 4, 1},// 0.051951
+ { 8588234901428223, 38, 10, 4, 1},// 0.095886
+ { 8625000000000000, 114, 2, 3, 1},// 0.000000
+ { 8647058486938477, 107, 3, 4, 1},// 0.081629
+ { 8705882072448730, 86, 0, 0, 1},// 0.067564
+ { 8750000000000000, 34, 4, 1, 1},// 0.000000
+ { 8777777671813965, 116, 2, 3, 1},// 0.031644
+ { 8800000190734863, 87, 0, 0, 1},// 0.000002
+ { 8823529243469238, 62, 6, 4, 1},// 0.039998
+ { 8866666793823242, 37, 6, 2, 1},// 0.000001
+ { 8941176414489746, 66, 3, 2, 1},// 0.087719
+ { 9000000000000000, 89, 0, 0, 1},// 0.000000
+ { 9066666603088379, 67, 3, 2, 1},// 0.000001
+ { 9117647171020508, 113, 3, 4, 1},// 0.025805
+ { 9187500000000000, 50, 8, 4, 1},// 0.081633
+ { 9250000000000000, 36, 4, 1, 1},// 0.000000
+ { 9294117927551270, 92, 0, 0, 1},// 0.063288
+ { 9333333015441895, 69, 3, 2, 1},// 0.000003
+ { 9375000000000000, 124, 2, 3, 1},// 0.000000
+ { 9399999618530273, 93, 0, 0, 1},// 0.000004
+ { 9428571701049805, 28, 12, 3, 1},// 0.037882
+ { 9466666221618652, 70, 3, 2, 1},// 0.000005
+ { 9500000000000000, 94, 0, 0, 1},// 0.000000
+ { 9562500000000000, 40, 6, 2, 1},// 0.043573
+ { 9600000381469727, 95, 0, 0, 1},// 0.000004
+ { 9625000000000000, 76, 4, 3, 1},// 0.000000
+ { 9666666984558105, 57, 4, 2, 1},// 0.000003
+ { 9714285850524902, 80, 5, 4, 1},// 0.058822
+ { 9750000000000000, 64, 2, 1, 1},// 0.000000
+ { 9800000190734863, 97, 0, 0, 1},// 0.000002
+ { 9857142448425293, 73, 3, 2, 1},// 0.096623
+ { 9937500000000000, 70, 6, 4, 1},// 0.025157
+ { 10000000000000000, 99, 0, 0, 1},// 0.000000
+ { 10071428298950195, 30, 12, 3, 1},// 0.035464
+ { 10133333206176758, 75, 3, 2, 1},// 0.000001
+ { 10199999809265137, 101, 0, 0, 1},// 0.000002
+ { 10230769157409668, 40, 4, 1, 1},// 0.187971
+ { 10285714149475098, 102, 0, 0, 1},// 0.138890
+ { 10357142448425293, 68, 2, 1, 1},// 0.068962
+ { 10399999618530273, 103, 0, 0, 1},// 0.000004
+ { 10428571701049805, 18, 10, 1, 1},// 0.205477
+ { 10461538314819336, 18, 10, 1, 1},// 0.110293
+ { 10500000000000000, 104, 0, 0, 1},// 0.000000
+ { 10533333778381348, 78, 3, 2, 1},// 0.000004
+ { 10571428298950195, 46, 8, 3, 1},// 0.033786
+ { 10615385055541992, 84, 4, 3, 1},// 0.090576
+ { 10714285850524902, 38, 10, 3, 1},// 0.099999
+ { 10769230842590332, 42, 4, 1, 1},// 0.178572
+ { 10857142448425293, 30, 6, 1, 1},// 0.065786
+ { 10928571701049805, 81, 3, 2, 1},// 0.043570
+ { 11000000000000000, 109, 0, 0, 1},// 0.000000
+ { 11076923370361328, 82, 3, 2, 1},// 0.092595
+ { 11142857551574707, 88, 4, 3, 1},// 0.160260
+ { 11250000000000000, 74, 2, 1, 1},// 0.000000
+ { 11285714149475098, 40, 10, 3, 1},// 0.094936
+ { 11333333015441895, 84, 3, 2, 1},// 0.000003
+ { 11384614944458008, 90, 4, 3, 1},// 0.084456
+ { 11500000000000000, 114, 0, 0, 1},// 0.000000
+ { 11538461685180664, 76, 2, 1, 1},// 0.099999
+ { 11692307472229004, 116, 0, 0, 1},// 0.065791
+ { 11769230842590332, 46, 4, 1, 1},// 0.163399
+ { 11846154212951660, 78, 2, 1, 1},// 0.032464
+ { 11923076629638672, 52, 8, 3, 1},// 0.016131
+ { 12000000000000000, 119, 0, 0, 1},// 0.000000
+ { 12090909004211426, 120, 0, 0, 1},// 0.075189
+ { 12181818008422852, 72, 4, 2, 1},// 0.124377
+ { 12250000000000000, 48, 4, 1, 1},// 0.000000
+ { 12362637333333333, 52, 6, 2, 1},// 0.032593 vout
+ { 12363636016845703, 52, 6, 2, 1},// 0.024513
+ { 12375000000000000, 98, 4, 3, 1},// 0.000000 vout
+ { 12500000000000000, 124, 0, 0, 1},// 0.000000
+ { 12545454978942871, 93, 3, 2, 1},// 0.096622
+ { 12666666984558105, 94, 3, 2, 1},// 0.000003
+ { 12750000000000000, 84, 2, 1, 1},// 0.000000
+ { 12833333015441895, 76, 4, 2, 1},// 0.000002
+ { 12916666984558105, 96, 3, 2, 1},// 0.129030
+ { 13000000000000000, 64, 1, 0, 1},// 0.000000
+ { 13090909004211426, 97, 3, 2, 1},// 0.185185
+ { 13166666984558105, 78, 4, 2, 1},// 0.000002
+ { 13199999809265137, 65, 1, 0, 1},// 0.000001
+ { 13250000000000000, 52, 4, 1, 1},// 0.000000
+ { 13300000190734863, 18, 6, 0, 1},// 0.000001
+ { 13363636016845703, 88, 2, 1, 1},// 0.102038
+ { 13399999618530273, 66, 1, 0, 1},// 0.000003
+ { 13454545021057129, 100, 3, 2, 1},// 0.090093
+ { 13500000000000000, 44, 2, 0, 1},// 0.000000
+ { 13600000381469727, 67, 1, 0, 1},// 0.000003
+ { 13636363983154297, 90, 2, 1, 1},// 0.099997
+ { 13818181991577148, 82, 4, 2, 1},// 0.109648
+ { 13909090995788574, 37, 10, 2, 1},// 0.174291
+ { 14000000000000000, 69, 1, 0, 1},// 0.000000
+ { 14090909004211426, 46, 2, 0, 1},// 0.064517
+ { 14181818008422852, 84, 4, 2, 1},// 0.106836
+ { 14363636016845703, 40, 6, 1, 1},// 0.094934
+ { 14399999618530273, 71, 1, 0, 1},// 0.000003
+ { 14454545021057129, 61, 6, 2, 1},// 0.083860
+ { 14500000000000000, 28, 4, 0, 1},// 0.000000
+ { 14600000381469727, 72, 1, 0, 1},// 0.000003
+ { 14699999809265137, 48, 2, 0, 1},// 0.000001
+ { 14777777671813965, 73, 1, 0, 1},// 0.150377
+ { 14888889312744141, 98, 2, 1, 1},// 0.261197
+ { 15000000000000000, 74, 1, 0, 1},// 0.000000
+ { 15111110687255859, 100, 2, 1, 1},// 0.257356
+ { 15199999809265137, 75, 1, 0, 1},// 0.000001
+ { 15300000190734863, 50, 2, 0, 1},// 0.000001
+ { 15399999618530273, 76, 1, 0, 1},// 0.000002
+ { 15500000000000000, 30, 4, 0, 1},// 0.000000
+ { 15555555343627930, 77, 1, 0, 1},// 0.285716
+ { 15600000381469727, 77, 1, 0, 1},// 0.000002
+ { 15666666984558105, 93, 4, 2, 1},// 0.000002
+ { 15777777671813965, 42, 10, 2, 1},// 0.070422
+ { 15899999618530273, 52, 2, 0, 1},// 0.000002
+ { 16000000000000000, 79, 1, 0, 1},// 0.000000
+ { 16111110687255859, 22, 6, 0, 1},// 0.068963
+ { 16222221374511719, 80, 1, 0, 1},// 0.136981
+ { 16333333969116211, 97, 4, 2, 1},// 0.000004
+ { 16444444656372070, 46, 6, 1, 1},// 0.033782
+ { 16500000000000000, 54, 2, 0, 1},// 0.000000
+ { 16625000000000000, 82, 1, 0, 1},// 0.150376
+ { 16666666030883789, 124, 3, 2, 1},// 0.000004
+ { 16750000000000000, 66, 4, 1, 1},// 0.000000
+ { 16888889312744141, 12, 12, 0, 1},// 0.065787
+ { 17000000000000000, 84, 1, 0, 1},// 0.000000
+ { 17111110687255859, 56, 2, 0, 1},// 0.064933
+ { 17250000000000000, 114, 2, 1, 1},// 0.000000
+ { 17333333969116211, 86, 1, 0, 1},// 0.384612
+ { 17500000000000000, 34, 4, 0, 1},// 0.000000
+ { 17555555343627930, 116, 2, 1, 1},// 0.031644
+ { 17625000000000000, 87, 1, 0, 1},// 0.141844
+ { 17750000000000000, 70, 4, 1, 1},// 0.000000
+ { 18000000000000000, 89, 1, 0, 1},// 0.000000
+ { 18125000000000000, 120, 2, 1, 1},// 0.137931
+ { 18250000000000000, 72, 4, 1, 1},// 0.000000
+ { 18375000000000000, 91, 1, 0, 1},// 0.136054
+ { 18500000000000000, 36, 4, 0, 1},// 0.000000
+ { 18750000000000000, 124, 2, 1, 1},// 0.000000
+ { 18857143402099609, 28, 12, 1, 1},// 0.037882
+ { 19000000000000000, 94, 1, 0, 1},// 0.000000
+ { 19125000000000000, 95, 1, 0, 1},// 0.392157
+ { 19250000000000000, 76, 4, 1, 1},// 0.000000
+ { 19375000000000000, 96, 1, 0, 1},// 0.129032
+ { 19428571701049805, 96, 1, 0, 1},// 0.147060
+ { 19500000000000000, 64, 2, 0, 1},// 0.000000
+ { 19714284896850586, 78, 4, 1, 1},// 0.181164
+ { 19875000000000000, 98, 1, 0, 1},// 0.377358
+ { 20000000000000000, 99, 1, 0, 1},// 0.000000
+ { 20142856597900391, 30, 12, 1, 1},// 0.035464
+ { 20285715103149414, 28, 6, 0, 1},// 0.070419
+ { 20571428298950195, 102, 1, 0, 1},// 0.138890
+ { 20714284896850586, 68, 2, 0, 1},// 0.068962
+ { 20857143402099609, 18, 10, 0, 1},// 0.205477
+ { 21000000000000000, 104, 1, 0, 1},// 0.000000
+ { 21142856597900391, 46, 8, 1, 1},// 0.033786
+ { 21428571701049805, 38, 10, 1, 1},// 0.099999
+ { 21714284896850586, 30, 6, 0, 1},// 0.065786
+ { 21857143402099609, 72, 2, 0, 1},// 0.196076
+ { 22000000000000000, 109, 1, 0, 1},// 0.000000
+ { 22166666030883789, 110, 1, 0, 1},// 0.150379
+ { 22285715103149414, 88, 4, 1, 1},// 0.160260
+ { 22500000000000000, 74, 2, 0, 1},// 0.000000
+ { 22571428298950195, 40, 10, 1, 1},// 0.094936
+ { 22666666030883789, 112, 1, 0, 1},// 0.294115
+ { 23000000000000000, 114, 1, 0, 1},// 0.000000
+ { 23333333969116211, 116, 1, 0, 1},// 0.285712
+ { 23500000000000000, 46, 4, 0, 1},// 0.000000
+ { 23666666030883789, 42, 10, 1, 1},// 0.070420
+ { 24000000000000000, 119, 1, 0, 1},// 0.000000
+ { 24166666030883789, 68, 6, 1, 1},// 0.068963
+ { 24333333969116211, 80, 2, 0, 1},// 0.136989
+ { 24500000000000000, 48, 4, 0, 1},// 0.000000
+ { 24666666030883789, 18, 12, 0, 1},// 0.135138
+ { 24725274666666666, 98, 4, 1, 1},// 0.100000 vout
+ { 24750000000000000, 98, 4, 1, 1},// 0.000000 vout
+ { 25000000000000000, 124, 1, 0, 1},// 0.000000
+ { 25333333969116211, 22, 10, 0, 1},// 0.131581
+ { 25500000000000000, 84, 2, 0, 1},// 0.000000
+ { 25666666030883789, 127, 1, 0, 1},// 0.259738
+ { 25833333969116211, 85, 2, 0, 1},// 0.129035
+ { 26000000000000000, 64, 3, 0, 1},// 0.000000
+ { 26333333969116211, 87, 2, 0, 1},// 0.253162
+ { 26399999618530273, 87, 2, 0, 1},// 0.000001
+ { 26500000000000000, 52, 4, 0, 1},// 0.000000
+ { 26600000381469727, 37, 6, 0, 1},// 0.000001
+ { 26799999237060547, 66, 3, 0, 1},// 0.000003
+ { 27000000000000000, 89, 2, 0, 1},// 0.000000
+ { 27200000762939453, 67, 3, 0, 1},// 0.000003
+ { 27600000381469727, 91, 2, 0, 1},// 0.000001
+ { 28000000000000000, 69, 3, 0, 1},// 0.000000
+ { 28200000762939453, 93, 2, 0, 1},// 0.000003
+ { 28399999618530273, 70, 3, 0, 1},// 0.000001
+ { 28799999237060547, 95, 2, 0, 1},// 0.000003
+ { 29000000000000000, 57, 4, 0, 1},// 0.000000
+ { 29200000762939453, 72, 3, 0, 1},// 0.000003
+ { 29399999618530273, 97, 2, 0, 1},// 0.000001
+ { 29600000381469727, 73, 3, 0, 1},// 0.000001
+ { 30000000000000000, 99, 2, 0, 1},// 0.000000
+ { 30399999618530273, 75, 3, 0, 1},// 0.000001
+ { 30600000381469727, 101, 2, 0, 1},// 0.000001
+ { 30799999237060547, 76, 3, 0, 1},// 0.000002
+ { 31000000000000000, 61, 4, 0, 1},// 0.000000
+ { 31200000762939453, 103, 2, 0, 1},// 0.000002
+ { 31600000381469727, 78, 3, 0, 1},// 0.000001
+ { 31799999237060547, 105, 2, 0, 1},// 0.000002
+ { 33000000000000000, 109, 2, 0, 1},// 0.000000
+ { 33250000000000000, 110, 2, 0, 1},// 0.150376
+ { 33500000000000000, 66, 4, 0, 1},// 0.000000
+ { 33750000000000000, 25, 12, 0, 1},// 0.148148
+ { 34000000000000000, 84, 3, 0, 1},// 0.000000
+ { 34500000000000000, 114, 2, 0, 1},// 0.000000
+ { 35000000000000000, 69, 4, 0, 1},// 0.000000
+ { 35250000000000000, 87, 3, 0, 1},// 0.141844
+ { 35500000000000000, 70, 4, 0, 1},// 0.000000
+ { 36000000000000000, 119, 2, 0, 1},// 0.000000
+ { 36250000000000000, 120, 2, 0, 1},// 0.137931
+ { 36500000000000000, 72, 4, 0, 1},// 0.000000
+ { 36750000000000000, 91, 3, 0, 1},// 0.136054
+ { 37000000000000000, 73, 4, 0, 1},// 0.000000
+ { 37500000000000000, 124, 2, 0, 1},// 0.000000
+ { 38000000000000000, 94, 3, 0, 1},// 0.000000
+ { 38250000000000000, 126, 2, 0, 1},// 0.392157
+ { 38500000000000000, 76, 4, 0, 1},// 0.000000
+ { 38750000000000000, 96, 3, 0, 1},// 0.129032
+ { 39000000000000000, 77, 4, 0, 1},// 0.000000
+ { 39500000000000000, 78, 4, 0, 1},// 0.000000
+ { 39750000000000000, 98, 3, 0, 1},// 0.377358
+ { 44000000000000000, 109, 3, 0, 1},// 0.000000
+ { 44333332061767578, 110, 3, 0, 1},// 0.150379
+ { 44666667938232422, 111, 3, 0, 1},// 0.298505
+ { 45000000000000000, 89, 4, 0, 1},// 0.000000
+ { 45333332061767578, 112, 3, 0, 1},// 0.294115
+ { 46000000000000000, 114, 3, 0, 1},// 0.000000
+ { 46666667938232422, 116, 3, 0, 1},// 0.285712
+ { 47000000000000000, 93, 4, 0, 1},// 0.000000
+ { 47333332061767578, 42, 10, 0, 1},// 0.070420
+ { 48000000000000000, 119, 3, 0, 1},// 0.000000
+ { 48333332061767578, 68, 6, 0, 1},// 0.068963
+ { 48666667938232422, 80, 5, 0, 1},// 0.136989
+ { 49000000000000000, 97, 4, 0, 1},// 0.000000
+ { 49333332061767578, 37, 12, 0, 1},// 0.135138
+ { 50000000000000000, 124, 3, 0, 1},// 0.000000
+ { 50666667938232422, 124, 3, 0, 1},// 1.315792
+ { 51000000000000000, 124, 3, 0, 1},// 1.960784
+ { 51333332061767578, 124, 3, 0, 1},// 2.597400
+ { 51666667938232422, 124, 3, 0, 1},// 3.225809
+ { 52000000000000000, 124, 3, 0, 1},// 3.846154
+ { 52666667938232422, 124, 3, 0, 1},// 5.063293
+ { 53000000000000000, 124, 3, 0, 1},// 5.660377
+} ;
+EXPORT_SYMBOL(ambarella_pll_vout_table);
+
+struct pll_table ambarella_pll_vout2_table[AMBARELLA_PLL_VOUT2_TABLE_SIZE] = {
+ {1000000000000000, 78, 1, 1, 79},
+ {1007407426834106, 77, 1, 4, 31},
+ {1014925360679626, 78, 1, 12, 12},
+ {1019999980926514, 78, 1, 4, 31},
+ {1022556424140930, 67, 1, 6, 19},
+ {1027027010917664, 78, 1, 13, 11},
+ {1030303001403809, 78, 1, 8, 17},
+ {1033783793449402, 75, 1, 6, 21},
+ {1037037014961243, 78, 1, 7, 19},
+ {1040816307067871, 77, 1, 14, 10},
+ {1043478250503540, 71, 1, 5, 23},
+ {1046153903007507, 76, 1, 6, 21},
+ {1049999952316284, 74, 1, 12, 11},
+ {1054263591766357, 78, 1, 14, 10},
+ {1058823585510254, 77, 1, 6, 21},
+ {1062500000000000, 76, 1, 4, 29},
+ {1066666722297668, 78, 1, 3, 37},
+ {1070866107940674, 76, 1, 15, 9},
+ {1074626922607422, 78, 1, 6, 21},
+ {1079365134239197, 75, 1, 2, 47},
+ {1082089543342590, 78, 1, 1, 73},
+ {1085106372833252, 75, 1, 13, 10},
+ {1088000059127808, 78, 1, 4, 29},
+ {1092857122421265, 77, 1, 12, 11},
+ {1096774220466614, 78, 1, 15, 9},
+ {1101449251174927, 76, 1, 13, 10},
+ {1105691075325012, 78, 1, 12, 11},
+ {1108695626258850, 74, 1, 14, 9},
+ {1111888170242310, 78, 1, 1, 71},
+ {1114754080772400, 76, 1, 5, 23},
+ {1117647051811218, 75, 1, 7, 17},
+ {1120567321777344, 78, 1, 2, 47},
+ {1123966932296753, 75, 1, 14, 9},
+ {1127118587493896, 78, 1, 13, 10},
+ {1130434751510620, 77, 1, 5, 23},
+ {1133333325386047, 75, 1, 1, 67},
+ {1136752128601074, 74, 1, 11, 11},
+ {1139705896377563, 76, 1, 14, 9},
+ {1142857193946838, 78, 1, 5, 23},
+ {1146551728248596, 77, 1, 7, 17},
+ {1149606347084045, 75, 1, 11, 11},
+ {1152542352676392, 74, 1, 12, 10},
+ {1155555605888367, 77, 1, 14, 9},
+ {1159090876579285, 78, 1, 7, 17},
+ {1162393212318420, 77, 1, 1, 67},
+ {1166666626930237, 76, 1, 11, 11},
+ {1172413825988770, 78, 1, 14, 9},
+ {1176923036575317, 78, 1, 1, 67},
+ {1182608723640442, 77, 1, 11, 11},
+ {1186046481132507, 78, 1, 6, 19},
+ {1189189195632935, 74, 1, 13, 9},
+ {1192982435226440, 76, 1, 2, 43},
+ {1196850419044495, 78, 1, 11, 11},
+ {1200000047683716, 77, 1, 12, 10},
+ {1203539848327637, 76, 1, 15, 8},
+ {1206896543502808, 77, 1, 2, 43},
+ {1210084080696106, 76, 1, 0, 127},
+ {1214285731315613, 78, 1, 12, 10},
+ {1220338940620422, 77, 1, 15, 8},
+ {1225225210189819, 78, 1, 2, 43},
+ {1230769276618958, 77, 1, 0, 127},
+ {1236363649368286, 78, 1, 15, 8},
+ {1239669442176819, 76, 1, 3, 31},
+ {1243902444839478, 78, 1, 0, 127},
+ {1247706413269043, 77, 1, 4, 25},
+ {1254098415374756, 78, 1, 13, 9},
+ {1259259223937988, 77, 1, 3, 31},
+ {1264462828636169, 78, 1, 4, 25},
+ {1267857193946838, 77, 1, 2, 41},
+ {1271028041839600, 78, 1, 3, 31},
+ {1274999976158142, 75, 1, 6, 17},
+ {1278846144676208, 77, 1, 1, 61},
+ {1283018827438354, 78, 1, 2, 41},
+ {1286956548690796, 77, 1, 10, 11},
+ {1291262149810791, 76, 1, 6, 17},
+ {1295238137245178, 78, 1, 1, 61},
+ {1299145340919495, 77, 1, 14, 8},
+ {1303921580314636, 78, 1, 10, 11},
+ {1307692289352417, 77, 1, 6, 17},
+ {1312500000000000, 72, 1, 2, 37},
+ {1316831707954407, 78, 1, 14, 8},
+ {1320388317108154, 77, 1, 1, 59},
+ {1324324369430542, 76, 1, 3, 29},
+ {1330000042915344, 78, 1, 6, 17},
+ {1333333373069763, 77, 1, 12, 9},
+ {1342105269432068, 78, 1, 1, 59},
+ {1346534609794617, 71, 1, 0, 107},
+ {1350000023841858, 78, 1, 12, 9},
+ {1353982329368591, 77, 1, 4, 23},
+ {1360000014305115, 78, 1, 3, 29},
+ {1366071462631226, 77, 1, 5, 19},
+ {1373737335205078, 78, 1, 4, 23},
+ {1378378391265869, 77, 1, 0, 113},
+ {1383928537368774, 78, 1, 5, 19},
+ {1387755155563354, 74, 1, 11, 9},
+ {1394495368003845, 77, 1, 15, 7},
+ {1398058295249939, 78, 1, 0, 113},
+ {1402061820030212, 77, 1, 2, 37},
+ {1407407402992249, 78, 1, 15, 7},
+ {1411764740943909, 76, 1, 0, 109},
+ {1416666626930237, 77, 1, 10, 10},
+ {1420560717582703, 78, 1, 2, 37},
+ {1425742626190186, 76, 1, 11, 9},
+ {1431578993797302, 77, 1, 0, 109},
+ {1436170220375061, 78, 1, 10, 10},
+ {1440000057220459, 74, 1, 12, 8},
+ {1446808457374573, 78, 1, 0, 109},
+ {1450549483299255, 76, 1, 1, 53},
+ {1457142829895020, 77, 1, 0, 107},
+ {1462365627288818, 78, 1, 11, 9},
+ {1466666698455811, 76, 1, 14, 7},
+ {1471153855323792, 77, 1, 1, 53},
+ {1478260874748230, 78, 1, 0, 107},
+ {1485436916351318, 77, 1, 14, 7},
+ {1490196108818054, 78, 1, 1, 53},
+ {1494505524635315, 76, 1, 0, 103},
+ {1500000000000000, 77, 1, 12, 8},
+ {1504950523376465, 78, 1, 14, 7},
+ {1511111140251160, 77, 1, 0, 103},
+ {1515789508819580, 78, 1, 12, 8},
+ {1519999980926514, 75, 1, 9, 10},
+ {1528089880943298, 77, 1, 5, 17},
+ {1531914949417114, 78, 1, 0, 103},
+ {1538461565971375, 76, 1, 9, 10},
+ {1545454502105713, 78, 1, 5, 17},
+ {1551020383834839, 75, 1, 13, 7},
+ {1555555582046509, 76, 1, 10, 9},
+ {1563218355178833, 78, 1, 0, 101},
+ {1568181872367859, 76, 1, 13, 7},
+ {1573033690452576, 77, 1, 10, 9},
+ {1577319622039795, 78, 1, 9, 10},
+ {1581395387649536, 75, 1, 15, 6},
+ {1587628841400146, 76, 1, 0, 97},
+ {1593750000000000, 78, 1, 10, 9},
+ {1600000023841858, 75, 1, 4, 19},
+ {1604166626930237, 76, 1, 15, 6},
+ {1610526323318481, 78, 1, 13, 7},
+ {1614583373069763, 75, 1, 1, 47},
+ {1619047641754150, 76, 1, 4, 19},
+ {1623529434204102, 77, 1, 15, 6},
+ {1627659559249878, 78, 1, 0, 97},
+ {1634408593177795, 76, 1, 1, 47},
+ {1638554215431213, 77, 1, 4, 19},
+ {1645161271095276, 78, 1, 15, 6},
+ {1652173876762390, 76, 1, 2, 31},
+ {1658536553382874, 77, 1, 1, 47},
+ {1663043498992920, 78, 1, 4, 19},
+ {1674418568611145, 77, 1, 2, 31},
+ {1679012298583984, 78, 1, 1, 47},
+ {1683544278144836, 74, 1, 0, 89},
+ {1688888907432556, 76, 1, 12, 7},
+ {1694117665290833, 77, 1, 3, 23},
+ {1700000047683716, 78, 1, 2, 31},
+ {1705128192901611, 75, 1, 0, 89},
+ {1709677457809448, 76, 1, 14, 6},
+ {1714285731315613, 78, 1, 3, 23},
+ {1721518993377686, 74, 1, 2, 29},
+ {1727272748947144, 76, 1, 0, 89},
+ {1733333349227905, 78, 1, 12, 7},
+ {1738636374473572, 73, 1, 4, 17},
+ {1743589758872986, 75, 1, 2, 29},
+ {1750000000000000, 77, 1, 0, 89},
+ {1758620738983154, 78, 1, 14, 6},
+ {1766233801841736, 76, 1, 2, 29},
+ {1773333311080933, 78, 1, 0, 89},
+ {1779069781303406, 73, 1, 0, 83},
+ {1783783793449402, 75, 1, 4, 17},
+ {1789473652839661, 77, 1, 2, 29},
+ {1794871807098389, 78, 1, 10, 8},
+ {1799999952316284, 72, 1, 8, 9},
+ {1808219194412231, 76, 1, 4, 17},
+ {1813333392143250, 78, 1, 2, 29},
+ {1821428537368774, 72, 1, 15, 5},
+ {1831325292587280, 77, 1, 4, 17},
+ {1837837815284729, 78, 1, 1, 43},
+ {1843373537063599, 71, 1, 12, 6},
+ {1848837256431580, 74, 1, 8, 9},
+ {1853658556938171, 77, 1, 13, 6},
+ {1863013744354248, 78, 1, 4, 17},
+ {1870129823684692, 73, 1, 0, 79},
+ {1876543164253235, 78, 1, 13, 6},
+ {1883116841316223, 66, 1, 0, 71},
+ {1888888835906982, 70, 1, 14, 5},
+ {1894736886024475, 74, 1, 0, 79},
+ {1899999976158142, 78, 1, 0, 83},
+ {1909090876579285, 65, 1, 2, 23},
+ {1915493011474609, 71, 1, 14, 5},
+ {1922077894210815, 78, 1, 1, 41},
+ {1927536249160767, 46, 2, 0, 73},
+ {1936708807945251, 65, 1, 3, 17},
+ {1942857146263123, 73, 1, 3, 19},
+ {1948717951774597, 78, 1, 8, 9},
+ {1955882310867310, 48, 2, 14, 5},
+ {1961538434028625, 52, 2, 8, 9},
+ {1971014499664307, 78, 1, 15, 5},
+ {1987012982368469, 52, 2, 15, 5},
+ {2000000000000000, 78, 1, 0, 79},
+ {2013157844543457, 52, 2, 0, 79},
+ {2029850721359253, 78, 1, 12, 6},
+ {2039999961853027, 52, 2, 12, 6},
+ {2046153783798218, 44, 2, 10, 6},
+ {2054054021835327, 78, 1, 10, 7},
+ {2060606002807617, 68, 1, 0, 67},
+ {2067567586898804, 50, 2, 1, 37},
+ {2078125000000000, 78, 1, 3, 19},
+ {2086956501007080, 74, 1, 11, 6},
+ {2092307806015015, 67, 1, 12, 5},
+ {2099999904632568, 48, 2, 13, 5},
+ {2111111164093018, 78, 1, 14, 5},
+ {2117647171020508, 71, 1, 3, 17},
+ {2125000000000000, 68, 1, 12, 5},
+ {2130434751510620, 78, 1, 1, 37},
+ {2140845060348511, 77, 1, 0, 73},
+ {2149253845214844, 72, 1, 3, 17},
+ {2158730268478394, 68, 1, 15, 4},
+ {2164179086685181, 78, 1, 0, 73},
+ {2171428680419922, 75, 1, 13, 5},
+ {2177419424057007, 72, 1, 0, 67},
+ {2185714244842529, 70, 1, 12, 5},
+ {2193548440933228, 78, 1, 11, 6},
+ {2202898502349854, 76, 1, 13, 5},
+ {2208955287933350, 73, 1, 0, 67},
+ {2217391252517700, 71, 1, 12, 5},
+ {2229508161544800, 78, 1, 0, 71},
+ {2235294103622437, 75, 1, 3, 17},
+ {2242424249649048, 73, 1, 10, 6},
+ {2250000000000000, 71, 1, 15, 4},
+ {2258064508438110, 78, 1, 13, 5},
+ {2266666650772095, 76, 1, 3, 17},
+ {2275861978530884, 74, 1, 10, 6},
+ {2283581972122192, 71, 1, 8, 7},
+ {2293103456497192, 78, 1, 2, 23},
+ {2305084705352783, 75, 1, 10, 6},
+ {2311475515365601, 73, 1, 15, 4},
+ {2318181753158569, 78, 1, 3, 17},
+ {2333333253860474, 77, 1, 0, 67},
+ {2344827651977539, 74, 1, 15, 4},
+ {2353846073150635, 78, 1, 0, 67},
+ {2360655784606934, 77, 1, 10, 6},
+ {2368421077728271, 76, 1, 12, 5},
+ {2375000000000000, 75, 1, 15, 4},
+ {2385964870452881, 74, 1, 8, 7},
+ {2392857074737549, 78, 1, 10, 6},
+ {2400000095367432, 77, 1, 12, 5},
+ {2409836053848267, 76, 1, 15, 4},
+ {2418181896209717, 74, 1, 1, 31},
+ {2428571462631226, 78, 1, 12, 5},
+ {2440677881240845, 77, 1, 15, 4},
+ {2451612949371338, 75, 1, 1, 31},
+ {2462962865829468, 78, 1, 15, 4},
+ {2472727298736572, 77, 1, 8, 7},
+ {2482758522033691, 76, 1, 1, 31},
+ {2491803169250488, 75, 1, 0, 61},
+ {2500000000000000, 74, 1, 14, 4},
+ {2508196830749512, 78, 1, 8, 7},
+ {2518518447875977, 77, 1, 1, 31},
+ {2526315689086914, 71, 1, 2, 19},
+ {2533333301544189, 75, 1, 14, 4},
+ {2542372941970825, 78, 1, 1, 31},
+ {2549999952316284, 73, 1, 1, 29},
+ {2557692289352417, 77, 1, 0, 61},
+ {2566037654876709, 76, 1, 14, 4},
+ {2576271295547485, 75, 1, 0, 59},
+ {2586206912994385, 78, 1, 0, 61},
+ {2593220233917236, 73, 1, 2, 19},
+ {2599999904632568, 77, 1, 14, 4},
+ {2607843160629272, 76, 1, 0, 59},
+ {2615384578704834, 75, 1, 1, 29},
+ {2625000000000000, 70, 1, 8, 6},
+ {2637931108474731, 78, 1, 14, 4},
+ {2647058725357056, 52, 2, 14, 4},
+ {2660000085830688, 76, 1, 1, 29},
+ {2666666746139526, 75, 1, 2, 19},
+ {2684210538864136, 78, 1, 0, 59},
+ {2692307710647583, 69, 1, 12, 4},
+ {2701754331588745, 76, 1, 2, 19},
+ {2711538553237915, 75, 1, 13, 4},
+ {2720000028610229, 78, 1, 1, 29},
+ {2732142925262451, 77, 1, 2, 19},
+ {2745098114013672, 76, 1, 13, 4},
+ {2755102157592773, 72, 1, 0, 53},
+ {2763636350631714, 75, 1, 10, 5},
+ {2775510311126709, 78, 1, 2, 19},
+ {2785714387893677, 77, 1, 13, 4},
+ {2799999952316284, 76, 1, 10, 5},
+ {2807692289352417, 72, 1, 12, 4},
+ {2814814805984497, 78, 1, 13, 4},
+ {2823529481887817, 74, 1, 0, 53},
+ {2833333253860474, 77, 1, 10, 5},
+ {2843137264251709, 73, 1, 12, 4},
+ {2857142925262451, 76, 1, 8, 6},
+ {2867924451828003, 78, 1, 10, 5},
+ {2880000114440918, 74, 1, 12, 4},
+ {2893616914749146, 77, 1, 8, 6},
+ {2905660390853882, 76, 1, 0, 53},
+ {2913043498992920, 72, 1, 9, 5},
+ {2923076868057251, 78, 1, 8, 6},
+ {2933333396911621, 71, 1, 6, 7},
+ {2942307710647583, 77, 1, 0, 53},
+ {2956521749496460, 76, 1, 12, 4},
+ {2980392217636108, 78, 1, 0, 53},
+ {3000000000000000, 77, 1, 12, 4},
+ {3022222280502319, 76, 1, 2, 17},
+ {3039999961853027, 78, 1, 12, 4},
+ {3059999942779541, 77, 1, 2, 17},
+ {3069767475128174, 65, 1, 0, 43},
+ {3079999923706055, 76, 1, 9, 5},
+ {3090909004211426, 78, 1, 2, 17},
+ {3102040767669678, 75, 1, 6, 7},
+ {3111111164093018, 69, 1, 14, 3},
+ {3122448921203613, 77, 1, 9, 5},
+ {3130434751510620, 71, 1, 1, 23},
+ {3142857074737549, 76, 1, 6, 7},
+ {3152173995971680, 78, 1, 9, 5},
+ {3162790775299072, 75, 1, 15, 3},
+ {3173913002014160, 72, 1, 1, 23},
+ {3187500000000000, 77, 1, 6, 7},
+ {3200000047683716, 71, 1, 14, 3},
+ {3208333253860474, 76, 1, 15, 3},
+ {3219512224197388, 78, 1, 6, 7},
+ {3229166746139526, 75, 1, 0, 47},
+ {3238095283508301, 72, 1, 14, 3},
+ {3255319118499756, 77, 1, 15, 3},
+ {3272727251052856, 76, 1, 0, 47},
+ {3285714387893677, 78, 1, 15, 3},
+ {3295454502105713, 70, 1, 0, 43},
+ {3304347753524780, 75, 1, 1, 23},
+ {3317073106765747, 77, 1, 0, 47},
+ {3326086997985840, 74, 1, 14, 3},
+ {3348837137222290, 76, 1, 1, 23},
+ {3365853548049927, 78, 1, 0, 47},
+ {3377777814865112, 75, 1, 14, 3},
+ {3391304254531860, 77, 1, 1, 23},
+ {3400000095367432, 67, 1, 9, 4},
+ {3410256385803223, 74, 1, 10, 4},
+ {3428571462631226, 78, 1, 1, 23},
+ {3444444417953491, 73, 1, 0, 43},
+ {3454545497894287, 75, 1, 10, 4},
+ {3466666698455811, 77, 1, 14, 3},
+ {3477272748947144, 72, 1, 13, 3},
+ {3487179517745972, 74, 1, 0, 43},
+ {3500000000000000, 76, 1, 10, 4},
+ {3512195110321045, 78, 1, 14, 3},
+ {3522727251052856, 73, 1, 13, 3},
+ {3534883737564087, 75, 1, 0, 43},
+ {3545454502105713, 77, 1, 10, 4},
+ {3558139562606812, 72, 1, 0, 41},
+ {3567567586898804, 74, 1, 13, 3},
+ {3578947305679321, 76, 1, 0, 43},
+ {3589743614196777, 78, 1, 10, 4},
+ {3599999904632568, 71, 1, 9, 4},
+ {3609755992889404, 73, 1, 0, 41},
+ {3619047641754150, 77, 1, 0, 43},
+ {3631578922271729, 68, 1, 1, 19},
+ {3642857074737549, 72, 1, 9, 4},
+ {3658536672592163, 76, 1, 13, 3},
+ {3675675630569458, 78, 1, 0, 43},
+ {3692307710647583, 73, 1, 9, 4},
+ {3707317113876343, 77, 1, 13, 3},
+ {3717948675155640, 66, 1, 11, 3},
+ {3731707334518433, 70, 1, 1, 19},
+ {3743589639663696, 74, 1, 9, 4},
+ {3756097555160522, 78, 1, 13, 3},
+ {3777777671813965, 69, 1, 0, 37},
+ {3789473772048950, 73, 1, 12, 3},
+ {3799999952316284, 77, 1, 0, 41},
+ {3810810804367065, 46, 2, 0, 37},
+ {3825000047683716, 68, 1, 11, 3},
+ {3837837934494019, 74, 1, 12, 3},
+ {3849999904632568, 78, 1, 0, 41},
+ {3868421077728271, 52, 2, 0, 41},
+ {3885714292526245, 73, 1, 1, 19},
+ {3897435903549194, 77, 1, 9, 4},
+ {3911764621734619, 46, 2, 11, 3},
+ {3923076868057251, 50, 2, 12, 3},
+ {3948717832565308, 78, 1, 9, 4},
+ {3972972869873047, 52, 2, 9, 4},
+ {4000000000000000, 77, 1, 12, 3},
+ {4026315689086914, 50, 2, 1, 19},
+ {4052631378173828, 78, 1, 12, 3},
+ {4083333492279053, 52, 2, 12, 3},
+ {4108108043670654, 77, 1, 1, 19},
+ {4121212005615234, 67, 1, 10, 3},
+ {4135135173797607, 50, 2, 0, 37},
+ {4156250000000000, 78, 1, 1, 19},
+ {4166666507720947, 74, 1, 11, 3},
+ {4181818008422852, 68, 1, 10, 3},
+ {4199999809265137, 48, 2, 6, 5},
+ {4222222328186035, 77, 1, 0, 37},
+ {4235294342041016, 71, 1, 1, 17},
+ {4250000000000000, 67, 1, 15, 2},
+ {4264705657958984, 78, 1, 0, 37},
+ {4277777671813965, 76, 1, 11, 3},
+ {4290322780609131, 72, 1, 1, 17},
+ {4312500000000000, 70, 1, 10, 3},
+ {4323529243469238, 77, 1, 11, 3},
+ {4342857360839844, 75, 1, 6, 5},
+ {4354838848114014, 71, 1, 10, 3},
+ {4371428489685059, 69, 1, 15, 2},
+ {4387096881866455, 78, 1, 11, 3},
+ {4400000095367432, 76, 1, 6, 5},
+ {4411764621734619, 74, 1, 1, 17},
+ {4433333396911621, 72, 1, 10, 3},
+ {4454545497894287, 77, 1, 6, 5},
+ {4470588207244873, 75, 1, 1, 17},
+ {4484848499298096, 73, 1, 10, 3},
+ {4500000000000000, 71, 1, 15, 2},
+ {4516129016876221, 78, 1, 6, 5},
+ {4533333301544189, 76, 1, 1, 17},
+ {4551723957061768, 74, 1, 10, 3},
+ {4586206912994385, 77, 1, 1, 17},
+ {4606060504913330, 75, 1, 10, 3},
+ {4620689868927002, 73, 1, 15, 2},
+ {4636363506317139, 78, 1, 1, 17},
+ {4666666507720947, 76, 1, 10, 3},
+ {4689655303955078, 74, 1, 15, 2},
+ {4714285850524902, 72, 1, 0, 31},
+ {4727272510528564, 77, 1, 10, 3},
+ {4750000000000000, 75, 1, 15, 2},
+ {4781250000000000, 78, 1, 10, 3},
+ {4800000190734863, 71, 1, 14, 2},
+ {4812500000000000, 76, 1, 15, 2},
+ {4827586174011230, 74, 1, 0, 31},
+ {4843750000000000, 30, 4, 15, 2},
+ {4857142925262451, 72, 1, 14, 2},
+ {4875000000000000, 77, 1, 15, 2},
+ {4888888835906982, 70, 1, 0, 29},
+ {4903225898742676, 75, 1, 0, 31},
+ {4935483932495117, 78, 1, 15, 2},
+ {4965517044067383, 76, 1, 0, 31},
+ {5000000000000000, 74, 1, 14, 2},
+ {5037036895751953, 77, 1, 0, 31},
+ {5066666603088379, 75, 1, 14, 2},
+ {5099999904632568, 78, 1, 0, 31},
+ {5115384578704834, 18, 6, 12, 2},
+ {5129032135009766, 76, 1, 14, 2},
+ {5142857074737549, 71, 1, 13, 2},
+ {5166666507720947, 74, 1, 0, 29},
+ {5185184955596924, 69, 1, 8, 3},
+ {5199999809265137, 77, 1, 14, 2},
+ {5214285850524902, 72, 1, 13, 2},
+ {5230769157409668, 75, 1, 0, 29},
+ {5250000000000000, 70, 1, 8, 3},
+ {5275862216949463, 78, 1, 14, 2},
+ {5300000190734863, 76, 1, 0, 29},
+ {5320000171661377, 45, 2, 12, 2},
+ {5333333492279053, 71, 1, 8, 3},
+ {5357142925262451, 74, 1, 13, 2},
+ {5384615421295166, 77, 1, 0, 29},
+ {5400000095367432, 72, 1, 8, 3},
+ {5423077106475830, 75, 1, 13, 2},
+ {5440000057220459, 78, 1, 0, 29},
+ {5464285850524902, 70, 1, 12, 2},
+ {5481481552124023, 73, 1, 8, 3},
+ {5500000000000000, 76, 1, 13, 2},
+ {5519999980926514, 68, 1, 4, 5},
+ {5538461685180664, 71, 1, 12, 2},
+ {5555555343627930, 74, 1, 8, 3},
+ {5571428775787354, 77, 1, 13, 2},
+ {5599999904632568, 69, 1, 4, 5},
+ {5615384578704834, 72, 1, 12, 2},
+ {5629629611968994, 78, 1, 13, 2},
+ {5666666507720947, 70, 1, 4, 5},
+ {5703703880310059, 76, 1, 8, 3},
+ {5739130496978760, 68, 1, 11, 2},
+ {5760000228881836, 74, 1, 12, 2},
+ {5782608509063721, 77, 1, 8, 3},
+ {5800000190734863, 28, 4, 4, 5},
+ {5826086997985840, 72, 1, 4, 5},
+ {5846153736114502, 78, 1, 8, 3},
+ {5869565010070801, 48, 2, 4, 5},
+ {5884615421295166, 52, 2, 8, 3},
+ {5913043498992920, 76, 1, 12, 2},
+ {5961538314819336, 30, 4, 12, 2},
+ {6000000000000000, 77, 1, 12, 2},
+ {6045454502105713, 28, 4, 11, 2},
+ {6079999923706055, 78, 1, 12, 2},
+ {6119999885559082, 52, 2, 12, 2},
+ {6136363506317139, 44, 2, 10, 2},
+ {6159999847412109, 76, 1, 4, 5},
+ {6181818008422852, 67, 1, 10, 2},
+ {6199999809265137, 30, 4, 4, 5},
+ {6239999771118164, 77, 1, 4, 5},
+ {6260869503021240, 71, 1, 0, 23},
+ {6285714149475098, 65, 1, 6, 3},
+ {6304347991943359, 78, 1, 4, 5},
+ {6333333492279053, 75, 1, 11, 2},
+ {6375000000000000, 69, 1, 10, 2},
+ {6391304492950439, 48, 2, 0, 23},
+ {6416666507720947, 76, 1, 11, 2},
+ {6434782505035400, 73, 1, 0, 23},
+ {6458333492279053, 70, 1, 10, 2},
+ {6476190567016602, 67, 1, 6, 3},
+ {6500000000000000, 77, 1, 11, 2},
+ {6521739006042480, 74, 1, 0, 23},
+ {6545454502105713, 71, 1, 10, 2},
+ {6571428775787354, 78, 1, 11, 2},
+ {6590909004211426, 65, 1, 9, 2},
+ {6608695507049561, 75, 1, 0, 23},
+ {6652173995971680, 72, 1, 10, 2},
+ {6681818008422852, 76, 1, 0, 23},
+ {6699999809265137, 66, 1, 9, 2},
+ {6727272510528564, 73, 1, 10, 2},
+ {6750000000000000, 70, 1, 6, 3},
+ {6782608509063721, 77, 1, 0, 23},
+ {6800000190734863, 67, 1, 9, 2},
+ {6818181991577148, 74, 1, 10, 2},
+ {6857142925262451, 78, 1, 0, 23},
+ {6909090995788574, 75, 1, 10, 2},
+ {6954545497894287, 72, 1, 6, 3},
+ {7000000000000000, 76, 1, 10, 2},
+ {7045454502105713, 73, 1, 6, 3},
+ {7090909004211426, 77, 1, 10, 2},
+ {7157894611358643, 74, 1, 6, 3},
+ {7181818008422852, 78, 1, 10, 2},
+ {7199999809265137, 71, 1, 9, 2},
+ {7238095283508301, 75, 1, 6, 3},
+ {7263157844543457, 68, 1, 0, 19},
+ {7285714149475098, 72, 1, 9, 2},
+ {7349999904632568, 76, 1, 6, 3},
+ {7368421077728271, 69, 1, 0, 19},
+ {7388888835906982, 73, 1, 9, 2},
+ {7428571224212646, 77, 1, 6, 3},
+ {7473684310913086, 70, 1, 0, 19},
+ {7500000000000000, 74, 1, 9, 2},
+ {7523809432983398, 78, 1, 6, 3},
+ {7555555343627930, 67, 1, 8, 2},
+ {7578947544097900, 71, 1, 0, 19},
+ {7599999904632568, 75, 1, 9, 2},
+ {7650000095367432, 68, 1, 8, 2},
+ {7699999809265137, 76, 1, 9, 2},
+ {7736842155456543, 48, 2, 0, 19},
+ {7777777671813965, 73, 1, 0, 19},
+ {7800000190734863, 77, 1, 9, 2},
+ {7823529243469238, 46, 2, 8, 2},
+ {7894736766815186, 78, 1, 9, 2},
+ {7941176414489746, 52, 2, 9, 2},
+ {8000000000000000, 75, 1, 0, 19},
+ {8052631378173828, 50, 2, 0, 19},
+ {8105262756347656, 76, 1, 0, 19},
+ {8166666984558105, 48, 2, 8, 2},
+ {8210526466369629, 77, 1, 0, 19},
+ {8235294342041016, 69, 1, 0, 17},
+ {8312500000000000, 78, 1, 0, 19},
+ {8333333015441895, 74, 1, 8, 2},
+ {8368420600891113, 66, 1, 15, 1},
+ {8444444656372070, 75, 1, 8, 2},
+ {8470588684082031, 71, 1, 0, 17},
+ {8500000000000000, 67, 1, 15, 1},
+ {8529411315917969, 28, 4, 0, 17},
+ {8555555343627930, 76, 1, 8, 2},
+ {8588234901428223, 72, 1, 0, 17},
+ {8625000000000000, 68, 1, 15, 1},
+ {8647058486938477, 77, 1, 8, 2},
+ {8705882072448730, 73, 1, 0, 17},
+ {8750000000000000, 69, 1, 15, 1},
+ {8777777671813965, 78, 1, 8, 2},
+ {8800000190734863, 65, 1, 14, 1},
+ {8823529243469238, 74, 1, 0, 17},
+ {8866666793823242, 70, 1, 15, 1},
+ {8941176414489746, 75, 1, 0, 17},
+ {9000000000000000, 71, 1, 15, 1},
+ {9066666603088379, 76, 1, 0, 17},
+ {9117647171020508, 72, 1, 15, 1},
+ {9187500000000000, 77, 1, 0, 17},
+ {9250000000000000, 73, 1, 15, 1},
+ {9294117927551270, 78, 1, 0, 17},
+ {9333333015441895, 69, 1, 14, 1},
+ {9375000000000000, 74, 1, 15, 1},
+ {9399999618530273, 46, 2, 14, 1},
+ {9428571701049805, 65, 1, 13, 1},
+ {9466666221618652, 70, 1, 14, 1},
+ {9500000000000000, 75, 1, 15, 1},
+ {9562500000000000, 66, 1, 13, 1},
+ {9600000381469727, 71, 1, 14, 1},
+ {9625000000000000, 76, 1, 15, 1},
+ {9666666984558105, 30, 4, 15, 1},
+ {9714285850524902, 72, 1, 14, 1},
+ {9750000000000000, 77, 1, 15, 1},
+ {9800000190734863, 48, 2, 14, 1},
+ {9857142448425293, 78, 1, 15, 1},
+ {9937500000000000, 52, 2, 15, 1},
+ {10000000000000000, 74, 1, 14, 1},
+ {10071428298950195, 46, 2, 13, 1},
+ {10133333206176758, 75, 1, 14, 1},
+ {10199999809265137, 50, 2, 14, 1},
+ {10230769157409668, 18, 6, 12, 1},
+ {10285714149475098, 76, 1, 14, 1},
+ {10357142448425293, 30, 4, 14, 1},
+ {10399999618530273, 77, 1, 14, 1},
+ {10428571701049805, 72, 1, 13, 1},
+ {10461538314819336, 67, 1, 12, 1},
+ {10500000000000000, 48, 2, 13, 1},
+ {10533333778381348, 78, 1, 14, 1},
+ {10571428298950195, 73, 1, 13, 1},
+ {10615385055541992, 68, 1, 12, 1},
+ {10714285850524902, 74, 1, 13, 1},
+ {10769230842590332, 69, 1, 12, 1},
+ {10857142448425293, 75, 1, 13, 1},
+ {10928571701049805, 70, 1, 12, 1},
+ {11000000000000000, 76, 1, 13, 1},
+ {11076923370361328, 71, 1, 12, 1},
+ {11142857551574707, 77, 1, 13, 1},
+ {11250000000000000, 72, 1, 12, 1},
+ {11285714149475098, 78, 1, 13, 1},
+ {11333333015441895, 67, 1, 11, 1},
+ {11384614944458008, 73, 1, 12, 1},
+ {11500000000000000, 68, 1, 11, 1},
+ {11538461685180664, 74, 1, 12, 1},
+ {11692307472229004, 75, 1, 12, 1},
+ {11769230842590332, 50, 2, 12, 1},
+ {11846154212951660, 76, 1, 12, 1},
+ {11923076629638672, 30, 4, 12, 1},
+ {12000000000000000, 77, 1, 12, 1},
+ {12090909004211426, 28, 4, 11, 1},
+ {12181818008422852, 78, 1, 12, 1},
+ {12250000000000000, 52, 2, 12, 1},
+ {12363636016845703, 73, 1, 11, 1},
+ {12500000000000000, 74, 1, 11, 1},
+ {12545454978942871, 68, 1, 10, 1},
+ {12666666984558105, 75, 1, 11, 1},
+ {12750000000000000, 69, 1, 10, 1},
+ {12833333015441895, 76, 1, 11, 1},
+ {12916666984558105, 70, 1, 10, 1},
+ {13000000000000000, 77, 1, 11, 1},
+ {13090909004211426, 71, 1, 10, 1},
+ {13166666984558105, 78, 1, 11, 1},
+ {13199999809265137, 65, 1, 9, 1},
+ {13250000000000000, 72, 1, 10, 1},
+ {13300000190734863, 18, 6, 9, 1},
+ {13363636016845703, 48, 2, 10, 1},
+ {13399999618530273, 66, 1, 9, 1},
+ {13454545021057129, 73, 1, 10, 1},
+ {13500000000000000, 44, 2, 9, 1},
+ {13600000381469727, 67, 1, 9, 1},
+ {13636363983154297, 74, 1, 10, 1},
+ {13818181991577148, 75, 1, 10, 1},
+ {13909090995788574, 50, 2, 10, 1},
+ {14000000000000000, 76, 1, 10, 1},
+ {14090909004211426, 46, 2, 9, 1},
+ {14181818008422852, 77, 1, 10, 1},
+ {14363636016845703, 78, 1, 10, 1},
+ {14399999618530273, 71, 1, 9, 1},
+ {14454545021057129, 52, 2, 10, 1},
+ {14500000000000000, 28, 4, 9, 1},
+ {14600000381469727, 72, 1, 9, 1},
+ {14699999809265137, 65, 1, 8, 1},
+ {14777777671813965, 73, 1, 9, 1},
+ {14888889312744141, 66, 1, 8, 1},
+ {15000000000000000, 74, 1, 9, 1},
+ {15111110687255859, 67, 1, 8, 1},
+ {15199999809265137, 75, 1, 9, 1},
+ {15300000190734863, 68, 1, 8, 1},
+ {15399999618530273, 76, 1, 9, 1},
+ {15500000000000000, 30, 4, 9, 1},
+ {15555555343627930, 69, 1, 8, 1},
+ {15600000381469727, 77, 1, 9, 1},
+ {15666666984558105, 46, 2, 8, 1},
+ {15777777671813965, 78, 1, 9, 1},
+ {15899999618530273, 52, 2, 9, 1},
+ {16000000000000000, 71, 1, 8, 1},
+ {16111110687255859, 28, 4, 8, 1},
+ {16222221374511719, 72, 1, 8, 1},
+ {16333333969116211, 48, 2, 8, 1},
+ {16444444656372070, 73, 1, 8, 1},
+ {16500000000000000, 65, 1, 7, 1},
+ {16625000000000000, 18, 6, 7, 1},
+ {16666666030883789, 74, 1, 8, 1},
+ {16750000000000000, 66, 1, 7, 1},
+ {16888889312744141, 75, 1, 8, 1},
+ {17000000000000000, 67, 1, 7, 1},
+ {17111110687255859, 76, 1, 8, 1},
+ {17250000000000000, 68, 1, 7, 1},
+ {17333333969116211, 77, 1, 8, 1},
+ {17500000000000000, 69, 1, 7, 1},
+ {17555555343627930, 78, 1, 8, 1},
+ {17625000000000000, 52, 2, 8, 1},
+ {17750000000000000, 70, 1, 7, 1},
+ {18000000000000000, 71, 1, 7, 1},
+ {18125000000000000, 28, 4, 7, 1},
+ {18250000000000000, 72, 1, 7, 1},
+ {18375000000000000, 48, 2, 7, 1},
+ {18500000000000000, 73, 1, 7, 1},
+ {18750000000000000, 74, 1, 7, 1},
+ {18857143402099609, 65, 1, 6, 1},
+ {19000000000000000, 75, 1, 7, 1},
+ {19125000000000000, 66, 1, 6, 1},
+ {19250000000000000, 76, 1, 7, 1},
+ {19375000000000000, 30, 4, 7, 1},
+ {19428571701049805, 67, 1, 6, 1},
+ {19500000000000000, 77, 1, 7, 1},
+ {19714284896850586, 78, 1, 7, 1},
+ {19875000000000000, 52, 2, 7, 1},
+ {20000000000000000, 69, 1, 6, 1},
+ {20142856597900391, 46, 2, 6, 1},
+ {20285715103149414, 70, 1, 6, 1},
+ {20571428298950195, 71, 1, 6, 1},
+ {20714284896850586, 28, 4, 6, 1},
+ {20857143402099609, 72, 1, 6, 1},
+ {21000000000000000, 48, 2, 6, 1},
+ {21142856597900391, 73, 1, 6, 1},
+ {21428571701049805, 74, 1, 6, 1},
+ {21714284896850586, 75, 1, 6, 1},
+ {21857143402099609, 50, 2, 6, 1},
+ {22000000000000000, 76, 1, 6, 1},
+ {22166666030883789, 30, 4, 6, 1},
+ {22285715103149414, 77, 1, 6, 1},
+ {22500000000000000, 44, 2, 5, 1},
+ {22571428298950195, 78, 1, 6, 1},
+ {22666666030883789, 67, 1, 5, 1},
+ {23000000000000000, 68, 1, 5, 1},
+ {23333333969116211, 69, 1, 5, 1},
+ {23500000000000000, 46, 2, 5, 1},
+ {23666666030883789, 70, 1, 5, 1},
+ {24000000000000000, 71, 1, 5, 1},
+ {24166666030883789, 28, 4, 5, 1},
+ {24333333969116211, 72, 1, 5, 1},
+ {24500000000000000, 48, 2, 5, 1},
+ {24666666030883789, 73, 1, 5, 1},
+ {25000000000000000, 74, 1, 5, 1},
+ {25333333969116211, 75, 1, 5, 1},
+ {25500000000000000, 50, 2, 5, 1},
+ {25666666030883789, 76, 1, 5, 1},
+ {25833333969116211, 30, 4, 5, 1},
+ {26000000000000000, 77, 1, 5, 1},
+ {26333333969116211, 78, 1, 5, 1},
+ {26399999618530273, 65, 1, 4, 1},
+ {26500000000000000, 52, 2, 5, 1},
+ {26600000381469727, 18, 6, 4, 1},
+ {26799999237060547, 66, 1, 4, 1},
+ {27000000000000000, 44, 2, 4, 1},
+ {27200000762939453, 67, 1, 4, 1},
+ {27600000381469727, 68, 1, 4, 1},
+ {28000000000000000, 69, 1, 4, 1},
+ {28200000762939453, 46, 2, 4, 1},
+ {28399999618530273, 70, 1, 4, 1},
+ {28799999237060547, 71, 1, 4, 1},
+ {29000000000000000, 28, 4, 4, 1},
+ {29200000762939453, 72, 1, 4, 1},
+ {29399999618530273, 48, 2, 4, 1},
+ {29600000381469727, 73, 1, 4, 1},
+ {30000000000000000, 74, 1, 4, 1},
+ {30399999618530273, 75, 1, 4, 1},
+ {30600000381469727, 50, 2, 4, 1},
+ {30799999237060547, 76, 1, 4, 1},
+ {31000000000000000, 30, 4, 4, 1},
+ {31200000762939453, 77, 1, 4, 1},
+ {31600000381469727, 78, 1, 4, 1},
+ {31799999237060547, 52, 2, 4, 1},
+ {33000000000000000, 65, 1, 3, 1},
+ {33250000000000000, 18, 6, 3, 1},
+ {33500000000000000, 66, 1, 3, 1},
+ {33750000000000000, 44, 2, 3, 1},
+ {34000000000000000, 67, 1, 3, 1},
+ {34500000000000000, 68, 1, 3, 1},
+ {35000000000000000, 69, 1, 3, 1},
+ {35250000000000000, 46, 2, 3, 1},
+ {35500000000000000, 70, 1, 3, 1},
+ {36000000000000000, 71, 1, 3, 1},
+ {36250000000000000, 28, 4, 3, 1},
+ {36500000000000000, 72, 1, 3, 1},
+ {36750000000000000, 48, 2, 3, 1},
+ {37000000000000000, 73, 1, 3, 1},
+ {37500000000000000, 74, 1, 3, 1},
+ {38000000000000000, 75, 1, 3, 1},
+ {38250000000000000, 50, 2, 3, 1},
+ {38500000000000000, 76, 1, 3, 1},
+ {38750000000000000, 30, 4, 3, 1},
+ {39000000000000000, 77, 1, 3, 1},
+ {39500000000000000, 78, 1, 3, 1},
+ {39750000000000000, 52, 2, 3, 1},
+ {44000000000000000, 65, 1, 2, 1},
+ {44333332061767578, 18, 6, 2, 1},
+ {44666667938232422, 66, 1, 2, 1},
+ {45000000000000000, 44, 2, 2, 1},
+ {45333332061767578, 67, 1, 2, 1},
+ {46000000000000000, 68, 1, 2, 1},
+ {46666667938232422, 69, 1, 2, 1},
+ {47000000000000000, 46, 2, 2, 1},
+ {47333332061767578, 70, 1, 2, 1},
+ {48000000000000000, 71, 1, 2, 1},
+ {48333332061767578, 28, 4, 2, 1},
+ {48666667938232422, 72, 1, 2, 1},
+ {49000000000000000, 48, 2, 2, 1},
+ {49333332061767578, 73, 1, 2, 1},
+ {50000000000000000, 74, 1, 2, 1},
+ {50666667938232422, 75, 1, 2, 1},
+ {51000000000000000, 50, 2, 2, 1},
+ {51333332061767578, 76, 1, 2, 1},
+ {51666667938232422, 30, 4, 2, 1},
+ {52000000000000000, 77, 1, 2, 1},
+ {52666667938232422, 78, 1, 2, 1},
+ {53000000000000000, 52, 2, 2, 1},
+};
+EXPORT_SYMBOL(ambarella_pll_vout2_table);
+
+
diff --git a/arch/arm/mach-ambarella/fio.c b/arch/arm/mach-ambarella/fio.c
new file mode 100644
index 00000000..aa1071df
--- /dev/null
+++ b/arch/arm/mach-ambarella/fio.c
@@ -0,0 +1,303 @@
+/*
+ * arch/arm/plat-ambarella/generic/fio.c
+ *
+ * History:
+ * 2008/03/05 - [Chien-Yang Chen] created file
+ * 2008/01/09 - [Anthony Ginger] Port to 2.6.28.
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/setup.h>
+#include <mach/hardware.h>
+#include <asm/cacheflush.h>
+#include <plat/fio.h>
+#include <plat/sd.h>
+#include <plat/nand.h>
+#include <plat/rct.h>
+
+static void *fio_4k_vaddr = NULL;
+
+#if (FIO_INDEPENDENT_SD == 0)
+
+static DECLARE_WAIT_QUEUE_HEAD(fio_wait);
+static DEFINE_SPINLOCK(fio_lock);
+static DEFINE_SPINLOCK(fio_sd0_int_lock);
+
+static u32 fio_owner = SELECT_FIO_FREE;
+static u32 fio_sd_owner_cnt = 0;
+#if (CHIP_REV == A5S)
+static u32 fio_default_owner = SELECT_FIO_SDIO;
+#else
+static u32 fio_default_owner = SELECT_FIO_SD;
+#endif
+static u32 fio_sd_int = 0;
+static u32 fio_sdio_int = 0;
+
+
+static int __init fio_default_owner_init(char *p)
+{
+ fio_default_owner = simple_strtoul(p, NULL, 0);
+ return 0;
+}
+early_param("fio_default_owner", fio_default_owner_init);
+
+void __fio_select_lock(int module)
+{
+ u32 fio_ctr;
+ u32 fio_dmactr;
+#if (CHIP_REV == A5S)
+ unsigned long flags;
+#endif
+
+ if (module == SELECT_FIO_FREE)
+ return;
+
+ fio_ctr = amba_readl(FIO_CTR_REG);
+ fio_dmactr = amba_readl(FIO_DMACTR_REG);
+
+ switch (module) {
+ case SELECT_FIO_FL:
+ fio_ctr &= ~FIO_CTR_XD;
+ fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_FL;
+ break;
+
+ case SELECT_FIO_XD:
+ fio_ctr |= FIO_CTR_XD;
+ fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_XD;
+ break;
+
+ case SELECT_FIO_CF:
+ fio_ctr &= ~FIO_CTR_XD;
+ fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_CF;
+ break;
+
+ case SELECT_FIO_SD:
+ fio_ctr &= ~FIO_CTR_XD;
+ fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_SD;
+ break;
+
+ case SELECT_FIO_SDIO:
+ fio_ctr |= FIO_CTR_XD;
+ fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_SD;
+ break;
+
+ default:
+ break;
+ }
+
+#if (CHIP_REV == A5S)
+ spin_lock_irqsave(&fio_sd0_int_lock, flags);
+ amba_clrbitsl(SD0_REG(SD_NISEN_OFFSET), SD_NISEN_CARD);
+ spin_unlock_irqrestore(&fio_sd0_int_lock, flags);
+#endif
+ amba_writel(FIO_CTR_REG, fio_ctr);
+ amba_writel(FIO_DMACTR_REG, fio_dmactr);
+#if (CHIP_REV == A5S)
+ if (module == SELECT_FIO_SD) {
+ spin_lock_irqsave(&fio_sd0_int_lock, flags);
+ amba_writel(SD0_REG(SD_NISEN_OFFSET), fio_sd_int);
+ amba_writel(SD0_REG(SD_NIXEN_OFFSET), fio_sd_int);
+ spin_unlock_irqrestore(&fio_sd0_int_lock, flags);
+ } else if (module == SELECT_FIO_SDIO) {
+ spin_lock_irqsave(&fio_sd0_int_lock, flags);
+ amba_writel(SD0_REG(SD_NISEN_OFFSET), fio_sdio_int);
+ amba_writel(SD0_REG(SD_NIXEN_OFFSET), fio_sdio_int);
+ spin_unlock_irqrestore(&fio_sd0_int_lock, flags);
+ }
+#endif
+}
+
+static bool fio_check_free(u32 module)
+{
+ unsigned long flags;
+ bool is_free = false;
+
+ spin_lock_irqsave(&fio_lock, flags);
+
+ if (fio_owner == SELECT_FIO_FREE) {
+ is_free = true;
+ fio_owner = module;
+ } else if (fio_owner == module) {
+ is_free = true;
+ if (fio_owner != SELECT_FIO_SD)
+ pr_warning("%s: module[%d] reentry!\n", __func__, module);
+ }
+
+ if (is_free && module == SELECT_FIO_SD)
+ fio_sd_owner_cnt++;
+
+ spin_unlock_irqrestore(&fio_lock, flags);
+
+ return is_free;
+}
+
+
+void fio_select_lock(int module)
+{
+ wait_event(fio_wait, fio_check_free(module));
+ __fio_select_lock(module);
+}
+EXPORT_SYMBOL(fio_select_lock);
+
+void fio_unlock(int module)
+{
+ unsigned long flags;
+
+ BUG_ON(fio_owner != module);
+
+ spin_lock_irqsave(&fio_lock, flags);
+
+ if (module != SELECT_FIO_SD || --fio_sd_owner_cnt == 0)
+ fio_owner = SELECT_FIO_FREE;
+
+ if (fio_owner == SELECT_FIO_FREE) {
+ if (fio_default_owner != module)
+ __fio_select_lock(fio_default_owner);
+ wake_up(&fio_wait);
+ }
+
+ spin_unlock_irqrestore(&fio_lock, flags);
+}
+EXPORT_SYMBOL(fio_unlock);
+
+static int fio_amb_sd0_is_enable(void)
+{
+ u32 fio_ctr;
+ u32 fio_dmactr;
+
+ fio_ctr = amba_readl(FIO_CTR_REG);
+ fio_dmactr = amba_readl(FIO_DMACTR_REG);
+
+ return (((fio_ctr & FIO_CTR_XD) == 0) &&
+ ((fio_dmactr & FIO_DMACTR_SD) == FIO_DMACTR_SD));
+}
+
+void fio_amb_sd0_set_int(u32 mask, u32 on)
+{
+ unsigned long flags;
+ u32 int_flag;
+
+ spin_lock_irqsave(&fio_sd0_int_lock, flags);
+ int_flag = amba_readl(SD0_REG(SD_NISEN_OFFSET));
+ if (on)
+ int_flag |= mask;
+ else
+ int_flag &= ~mask;
+ fio_sd_int = int_flag;
+ if (fio_amb_sd0_is_enable()) {
+ amba_writel(SD0_REG(SD_NISEN_OFFSET), int_flag);
+ amba_writel(SD0_REG(SD_NIXEN_OFFSET), int_flag);
+ }
+ spin_unlock_irqrestore(&fio_sd0_int_lock, flags);
+}
+EXPORT_SYMBOL(fio_amb_sd0_set_int);
+
+static int fio_amb_sdio0_is_enable(void)
+{
+ u32 fio_ctr;
+ u32 fio_dmactr;
+
+ fio_ctr = amba_readl(FIO_CTR_REG);
+ fio_dmactr = amba_readl(FIO_DMACTR_REG);
+
+ return (((fio_ctr & FIO_CTR_XD) == FIO_CTR_XD) &&
+ ((fio_dmactr & FIO_DMACTR_SD) == FIO_DMACTR_SD));
+}
+
+void fio_amb_sdio0_set_int(u32 mask, u32 on)
+{
+ unsigned long flags;
+ u32 int_flag;
+
+ spin_lock_irqsave(&fio_sd0_int_lock, flags);
+ int_flag = amba_readl(SD0_REG(SD_NISEN_OFFSET));
+ if (on)
+ int_flag |= mask;
+ else
+ int_flag &= ~mask;
+ fio_sdio_int = int_flag;
+ if (fio_amb_sdio0_is_enable()) {
+ amba_writel(SD0_REG(SD_NISEN_OFFSET), int_flag);
+ amba_writel(SD0_REG(SD_NIXEN_OFFSET), int_flag);
+ }
+ spin_unlock_irqrestore(&fio_sd0_int_lock, flags);
+}
+EXPORT_SYMBOL(fio_amb_sdio0_set_int);
+#endif
+
+void ambarella_fio_prepare(void)
+{
+ fio_4k_vaddr = __arm_ioremap_exec(FIO_4K_PHYS_BASE, 0x1000, false);
+ if (!fio_4k_vaddr)
+ pr_warning("__arm_ioremap_exec for FIFO failed!\n");
+}
+
+void *ambarella_fio_push(void *func, u32 size)
+{
+ BUG_ON(!fio_4k_vaddr || (size > 0x1000));
+
+ amba_writel(FIO_CTR_REG, (amba_readl(FIO_CTR_REG) | FIO_CTR_RR));
+ memcpy(fio_4k_vaddr, func, size);
+
+ flush_icache_range((unsigned long)(fio_4k_vaddr),
+ (unsigned long)(fio_4k_vaddr) + (size));
+
+ return fio_4k_vaddr;
+}
+EXPORT_SYMBOL(ambarella_fio_push);
+
+void ambarella_fio_rct_reset(void)
+{
+ amba_rct_writel(FIO_RESET_REG, FIO_RESET_FIO_RST);
+ mdelay(1);
+ amba_rct_writel(FIO_RESET_REG, 0x0);
+ mdelay(1);
+}
+EXPORT_SYMBOL(ambarella_fio_rct_reset);
+
+/* ==========================================================================*/
+int __init ambarella_init_fio(void)
+{
+ /* ioremap for self refresh */
+ ambarella_fio_prepare();
+#if defined(CONFIG_AMBARELLA_RAW_BOOT)
+ amba_rct_writel(FIO_RESET_REG, (FIO_RESET_FIO_RST | FIO_RESET_CF_RST |
+ FIO_RESET_XD_RST | FIO_RESET_FLASH_RST));
+ mdelay(100);
+ amba_rct_writel(FIO_RESET_REG, 0);
+ mdelay(100);
+ amba_clrbitsl(FIO_CTR_REG, FIO_CTR_RR);
+
+ amba_setbitsl(NAND_CTR_REG, 0);
+ amba_writel(NAND_CMD_REG, 0xff);
+ mdelay(100);
+ amba_writel(NAND_INT_REG, 0x0);
+ amba_writel(NAND_CMD_REG, 0x90);
+ mdelay(100);
+ amba_writel(NAND_INT_REG, 0x0);
+#endif
+ return 0;
+}
+
diff --git a/arch/arm/mach-ambarella/hibernate.c b/arch/arm/mach-ambarella/hibernate.c
new file mode 100644
index 00000000..94b0a9c5
--- /dev/null
+++ b/arch/arm/mach-ambarella/hibernate.c
@@ -0,0 +1,357 @@
+
+/*
+ * Hibernation support specific for ARM
+ *
+ * Derived from work on ARM hibernation support by:
+ *
+ * Ubuntu project, hibernation support for mach-dove
+ * Copyright (C) 2010 Nokia Corporation (Hiroshi Doyu)
+ * Copyright (C) 2010 Texas Instruments, Inc. (Teerth Reddy et al.)
+ * https://lkml.org/lkml/2010/6/18/4
+ * https://lists.linux-foundation.org/pipermail/linux-pm/2010-June/027422.html
+ * https://patchwork.kernel.org/patch/96442/
+ *
+ * Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl>
+ *
+ * Copyright (C) 2015 Ambarella, Shanghai(Jorney Tu)
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/mm.h>
+#include <linux/suspend.h>
+#include <asm/system_misc.h>
+#include <asm/idmap.h>
+#include <asm/suspend.h>
+#include <asm/memory.h>
+#include <asm/sections.h>
+#include <linux/mtd/mtd.h>
+#include <linux/vmalloc.h>
+
+#define HIBERNATE_MTD_NAME "swp"
+
+static int mtd_page_offset = 0;
+
+extern const void __nosave_begin, __nosave_end;
+
+static const unsigned int crc32_tab[] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
+ 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
+ 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
+ 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
+ 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
+ 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
+ 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
+ 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
+ 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
+ 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
+ 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
+ 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
+ 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
+ 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
+ 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
+ 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
+ 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
+ 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+static unsigned int __crc32(unsigned int crc, const void *buf, unsigned int size)
+{
+ const unsigned char *p;
+ unsigned int __crc = crc;
+
+ p = buf;
+
+ while (size > 0) {
+ __crc = crc32_tab[(__crc ^ *p++) & 0xff] ^ (__crc >> 8);
+ size--;
+ }
+
+ return __crc ^ ~0U;
+}
+
+
+int pfn_is_nosave(unsigned long pfn)
+{
+ return 0;
+}
+
+void notrace save_processor_state(void)
+{
+ WARN_ON(num_online_cpus() != 1);
+ local_fiq_disable();
+}
+
+void notrace restore_processor_state(void)
+{
+ local_fiq_enable();
+}
+
+/*
+ * Snapshot kernel memory and reset the system.
+ *
+ * swsusp_save() is executed in the suspend finisher so that the CPU
+ * context pointer and memory are part of the saved image, which is
+ * required by the resume kernel image to restart execution from
+ * swsusp_arch_suspend().
+ *
+ * soft_restart is not technically needed, but is used to get success
+ * returned from cpu_suspend.
+ *
+ * When soft reboot completes, the hibernation snapshot is written out.
+ */
+static int notrace arch_save_image(unsigned long unused)
+{
+ int ret;
+
+ ret = swsusp_save();
+ if (ret == 0)
+ soft_restart(virt_to_phys(cpu_resume));
+ return ret;
+}
+
+/*
+ * Save the current CPU state before suspend / poweroff.
+ */
+int notrace swsusp_arch_suspend(void)
+{
+ return cpu_suspend(0, arch_save_image);
+}
+
+/*
+ * Restore page contents for physical pages that were in use during loading
+ * hibernation image. Switch to idmap_pgd so the physical page tables
+ * are overwritten with the same contents.
+ */
+static void notrace arch_restore_image(void *unused)
+{
+ struct pbe *pbe;
+
+ cpu_switch_mm(idmap_pgd, &init_mm);
+ for (pbe = restore_pblist; pbe; pbe = pbe->next)
+ copy_page(pbe->orig_address, pbe->address);
+
+ soft_restart(virt_to_phys(cpu_resume));
+}
+
+static u64 resume_stack[PAGE_SIZE / 2 / sizeof(u64)] __nosavedata;
+
+/*
+ * Resume from the hibernation image.
+ * Due to the kernel heap / data restore, stack contents change underneath
+ * and that would make function calls impossible; switch to a temporary
+ * stack within the nosave region to avoid that problem.
+ */
+int swsusp_arch_resume(void)
+{
+ extern void call_with_stack(void (*fn)(void *), void *arg, void *sp);
+ call_with_stack(arch_restore_image, 0,
+ resume_stack + ARRAY_SIZE(resume_stack));
+ return 0;
+}
+
+struct mtd_info *mtd_probe_dev(void)
+{
+ struct mtd_info *info = NULL;
+ info = get_mtd_device_nm(HIBERNATE_MTD_NAME);
+
+ if(IS_ERR(info)){
+ printk("SWP: mtd dev no found!\n");
+ return NULL;
+ }else{
+ /* Makesure the swp partition has 32M at least */
+ if(info->size < 0x2000000){
+ printk("ERR: swp partition size is less than 32M\n");
+ return NULL;
+ }
+
+ printk("MTD name: %s\n", info->name);
+ printk("MTD size: 0x%llx\n", info->size);
+ printk("MTD blocksize: 0x%x\n", info->erasesize);
+ printk("MTD pagesize: 0x%x\n", info->writesize);
+ }
+ return info;
+}
+
+
+int hibernate_mtd_check(struct mtd_info *mtd, int ofs)
+{
+
+ int loff = ofs;
+ int block = 0;
+
+ while (mtd_block_isbad(mtd, loff) > 0){
+
+ if(loff > mtd->size){
+ printk("SWP: overflow mtd device ...\n");
+ loff = 0;
+ break;
+ }
+
+ printk("SWP: offset %d is a bad block\n" ,loff);
+
+ block = loff / mtd->erasesize;
+ loff = (block + 1) * mtd->erasesize;
+ }
+ return loff / PAGE_SIZE;
+}
+
+
+int hibernate_write_page(struct mtd_info *mtd, void *buf)
+{
+
+ int ret, retlen;
+ int offset = 0;
+
+ /* Default: The 1st 4k(one PAGE_SIZE) is empty in "swp" mtd partition */
+ mtd_page_offset++;
+
+#if 1 /* bad block checking is needed ? */
+ offset = hibernate_mtd_check(mtd, mtd_page_offset * PAGE_SIZE);
+#else
+ offset = mtd_page_offset;
+#endif
+
+ if(offset == 0)
+ return -EINVAL;
+
+ ret = mtd_write(mtd, PAGE_SIZE * offset, PAGE_SIZE, &retlen, buf);
+ if(ret < 0){
+ printk("SWP: MTD write failed!\n");
+ return -EFAULT;
+ }
+
+ mtd_page_offset = offset;
+ return 0;
+}
+
+int hibernate_save_image(struct mtd_info *mtd, struct snapshot_handle *snapshot,
+ struct swsusp_info *header)
+{
+
+ int ret;
+ int nr_pages = 0;
+ unsigned int crc = 0;
+
+ while (1) {
+ ret = snapshot_read_next(snapshot);
+ if (ret <= 0)
+ break;
+
+ ret = hibernate_write_page(mtd, data_of(*snapshot));
+ if (ret) {
+ printk("hibernate_write_page error.\n");
+ return ret;
+ }
+
+ nr_pages++;
+
+ if (nr_pages > nr_meta_pages)
+ crc = __crc32(crc, data_of(*snapshot), PAGE_SIZE);
+ }
+
+ if(!ret)
+ printk("LINUX: %d pages, crc = %08x.\n", nr_pages - nr_meta_pages, crc);
+
+ if(!nr_pages)
+ ret = -EINVAL;
+
+ header->crc32 = crc;
+ header->lzo_enable = 0;
+
+ /* save the header */
+ mtd_page_offset = 0;
+ hibernate_write_page(mtd, header);
+
+ return ret;
+}
+
+int hibernate_mtd_write(struct mtd_info *mtd)
+{
+
+ int error = 0;
+ struct swsusp_info *header, *copy;
+ struct snapshot_handle snapshot;
+
+ copy = vmalloc(sizeof(struct swsusp_info));
+ if (!copy)
+ return -ENOMEM;
+
+ memset(&snapshot, 0, sizeof(struct snapshot_handle));
+
+ if(nr_meta_pages <= 0)
+ return -EFAULT;
+
+ error = snapshot_read_next(&snapshot);
+ if (error < PAGE_SIZE) {
+ if (error >= 0)
+ error = -EFAULT;
+ goto out_finish;
+ }
+
+ header = (struct swsusp_info *)data_of(snapshot);
+ memcpy(copy, header, sizeof(struct swsusp_info));
+
+ /*
+ * Skip saving the header. the header is copied and
+ * will be save after the CRC of the kernel snapshot
+ * has been generated. The mtd_page_offset should be
+ * set at meta data offset.
+ *
+ * */
+ mtd_page_offset ++;
+
+ /* TODO: SWP partition space size check */
+ if (header->pages * 0x1000 > mtd->size){
+ printk("ERR: swp partition[0x%llx] has not enough space for the \
+ kernel snapshot[0x%lx]\n", mtd->size, header->pages * 0x1000);
+ return -ENOMEM;
+ }
+
+ error = hibernate_save_image(mtd, &snapshot, copy);
+
+out_finish:
+ vfree(copy);
+ return error;
+
+}
+
+int swsusp_write_mtd(int flags)
+{
+
+ struct mtd_info *info = NULL;
+
+ mtd_page_offset = 0;
+
+ info = mtd_probe_dev();
+ if(!info)
+ return -EFAULT;
+
+ return hibernate_mtd_write(info);
+}
+
diff --git a/arch/arm/mach-ambarella/include/mach/common.h b/arch/arm/mach-ambarella/include/mach/common.h
new file mode 100644
index 00000000..c0cb7343
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/mach/common.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/plat-ambarella/include/mach/common.h
+ *
+ * History:
+ * 2012/11/12 - Ken He <jianhe@ambarella.com> created file
+ *
+ * Coryright (c) 2012, Ambarella, Inc.
+ * http://www.ambarella.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+#ifndef __MACH_COMMON_H
+#define __MACH_COMMON_H
+
+extern struct smp_operations ambarella_smp_ops;
+
+#endif
diff --git a/arch/arm/mach-ambarella/include/mach/debug-macro.S b/arch/arm/mach-ambarella/include/mach/debug-macro.S
new file mode 100644
index 00000000..672ed554
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/mach/debug-macro.S
@@ -0,0 +1,71 @@
+/*
+ * arch/arm/plat-ambarella/include/mach/debug-macro.S
+ *
+ * History:
+ * 2006/12/27 - [Charles Chiou] created file
+ * 2010/03/29 - [Cao Rongrong] port to BOSS
+ * 2010/11/04 - [Cao Rongrong] port to Linux-2.6.36+
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <mach/hardware.h>
+#include <plat/uart.h>
+
+#define AMBA_UART_BASE_P (APB_PHYS_BASE + UART_OFFSET)
+#define AMBA_UART_BASE_V (APB_BASE + UART_OFFSET)
+
+#if defined(CONFIG_AMBARELLA_DEBUG_LL_UART0)
+ .macro addruart, rp, rv, tmp
+ ldr \rp, =AMBA_UART_BASE_P
+ ldr \rv, =AMBA_UART_BASE_V
+ .endm
+
+ .macro senduart, rd, rx
+ str \rd, [\rx, #UART_TH_OFFSET]
+ .endm
+
+ .macro waituart, rd, rx
+1001:
+ ldr \rd, [\rx, #UART_LS_OFFSET]
+ tst \rd, #UART_LS_TEMT
+ beq 1001b
+ .endm
+
+ .macro busyuart, rd, rx
+1002:
+ ldr \rd, [\rx, #UART_LS_OFFSET]
+ tst \rd, #UART_LS_TEMT
+ beq 1002b
+ .endm
+#elif defined(CONFIG_DEBUG_LL_UART_NONE)
+ .macro addruart, rp, rv, tmp
+ ldr \rp, =AMBA_UART_BASE_P
+ ldr \rv, =AMBA_UART_BASE_V
+ .endm
+
+ .macro senduart,rd,rx
+ .endm
+
+ .macro waituart,rd,rx
+ .endm
+
+ .macro busyuart,rd,rx
+ .endm
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/mach/gpio.h b/arch/arm/mach-ambarella/include/mach/gpio.h
new file mode 100644
index 00000000..5764299a
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/mach/gpio.h
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/plat-ambarella/include/mach/gpio.h
+ *
+ * History:
+ * 2006/12/27 - [Charles Chiou] created file
+ * 2009/01/12 - [Anthony Ginger] Port to 2.6.28
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H
+
+/* ==========================================================================*/
+#include <mach/hardware.h>
+#include <plat/gpio.h>
+
+/* ==========================================================================*/
+#ifndef __ASSEMBLER__
+
+/* ==========================================================================*/
+
+#endif /* __ASSEMBLER__ */
+/* ==========================================================================*/
+
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/mach/hardware.h b/arch/arm/mach-ambarella/include/mach/hardware.h
new file mode 100644
index 00000000..595bb79a
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/mach/hardware.h
@@ -0,0 +1,54 @@
+/*
+ * arch/arm/plat-ambarella/include/mach/hardware.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+/* ==========================================================================*/
+#include <plat/chip.h>
+#include <mach/memory.h>
+
+#include <plat/gpio.h>
+#include <plat/irq.h>
+#include <plat/pm.h>
+#include <plat/hwlock.h>
+#if defined(CONFIG_PLAT_AMBARELLA_CORTEX)
+#include <plat/cortex.h>
+#endif
+/* ==========================================================================*/
+#ifndef __ASSEMBLER__
+
+/* ==========================================================================*/
+extern u64 ambarella_dmamask;
+
+/* ==========================================================================*/
+extern int ambarella_create_proc_dir(void);
+extern struct proc_dir_entry *get_ambarella_proc_dir(void);
+
+extern u32 ambarella_get_poc(void);
+
+#endif
+/* ==========================================================================*/
+
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/mach/init.h b/arch/arm/mach-ambarella/include/mach/init.h
new file mode 100644
index 00000000..500714ef
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/mach/init.h
@@ -0,0 +1,103 @@
+/*
+ * arch/arm/plat-ambarella/include/mach/init.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ASM_ARCH_INIT_H
+#define __ASM_ARCH_INIT_H
+
+/* ==========================================================================*/
+#include <plat/gpio.h>
+#include <plat/adc.h>
+#include <plat/audio.h>
+#include <plat/crypto.h>
+#include <plat/dma.h>
+#include <plat/eth.h>
+#include <plat/event.h>
+#include <plat/fio.h>
+#include <plat/idc.h>
+#include <plat/ir.h>
+#include <plat/irq.h>
+#include <plat/nand.h>
+#include <plat/clk.h>
+#include <plat/pm.h>
+#include <plat/pwm.h>
+#include <plat/rtc.h>
+#include <plat/sd.h>
+#include <plat/spi.h>
+#include <plat/timer.h>
+#include <plat/uart.h>
+#include <plat/udc.h>
+#include <plat/ahci.h>
+#include <plat/wdt.h>
+#include <plat/pinctrl.h>
+
+/* ==========================================================================*/
+#ifndef __ASSEMBLER__
+
+#define AMBARELLA_BOARD_TYPE_AUTO (0)
+#define AMBARELLA_BOARD_TYPE_BUB (1)
+#define AMBARELLA_BOARD_TYPE_EVK (2)
+#define AMBARELLA_BOARD_TYPE_IPCAM (3)
+#define AMBARELLA_BOARD_TYPE_VENDOR (4)
+#define AMBARELLA_BOARD_TYPE_ATB (5)
+
+#define AMBARELLA_BOARD_VERSION(c,t,r) (((c) << 16) + ((t) << 12) + (r))
+#define AMBARELLA_BOARD_CHIP(v) (((v) >> 16) & 0xFFFF)
+#define AMBARELLA_BOARD_TYPE(v) (((v) >> 12) & 0xF)
+#define AMBARELLA_BOARD_REV(v) (((v) >> 0) & 0xFFF)
+
+/* ==========================================================================*/
+extern void ambarella_init_early(void);
+extern void ambarella_init_machine(void);
+extern void ambarella_map_io(void);
+extern void ambarella_restart_machine(char mode, const char *cmd);
+
+/* ==========================================================================*/
+extern int ambarella_init_fb(void);
+
+/* ==========================================================================*/
+extern u32 ambarella_phys_to_virt(u32 paddr);
+extern u32 ambarella_virt_to_phys(u32 vaddr);
+
+extern u32 get_ambarella_iavmem_phys(void);
+extern u32 get_ambarella_iavmem_size(void);
+
+extern u32 get_ambarella_fbmem_phys(void);
+extern u32 get_ambarella_fbmem_size(void);
+
+extern u32 get_ambarella_ppm_phys(void);
+extern u32 get_ambarella_ppm_virt(void);
+extern u32 get_ambarella_ppm_size(void);
+
+extern u32 get_ambarella_ahb_phys(void);
+extern u32 get_ambarella_ahb_virt(void);
+extern u32 get_ambarella_ahb_size(void);
+
+extern u32 get_ambarella_apb_phys(void);
+extern u32 get_ambarella_apb_virt(void);
+extern u32 get_ambarella_apb_size(void);
+
+#endif /* __ASSEMBLER__ */
+/* ==========================================================================*/
+
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/mach/io.h b/arch/arm/mach-ambarella/include/mach/io.h
new file mode 100644
index 00000000..1cf73546
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/mach/io.h
@@ -0,0 +1,231 @@
+/*
+ * arch/arm/plat-ambarella/include/mach/io.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ASM_ARCH_IO_H
+#define __ASM_ARCH_IO_H
+
+/* ==========================================================================*/
+#include <mach/hardware.h>
+
+/* ==========================================================================*/
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a) ((void __iomem *)(a))
+#define __mem_pci(a) (a)
+
+/* ==========================================================================*/
+#ifndef __ASSEMBLER__
+
+#if defined(CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK)
+#define AMBARELLA_REG_LOCK() AMBARELLA_GLOBAL_HW_LOCK()
+#define AMBARELLA_REG_UNLOCK() AMBARELLA_GLOBAL_HW_UNLOCK()
+#else
+#define AMBARELLA_REG_LOCK()
+#define AMBARELLA_REG_UNLOCK()
+#endif
+
+#define amba_readb(v) __raw_readb(v)
+#define amba_readw(v) __raw_readw(v)
+#define amba_writeb(v,d) __raw_writeb(d,v)
+#define amba_writew(v,d) __raw_writew(d,v)
+
+static inline u32 __amba_readl(volatile void __iomem *address)
+{
+ u32 tmpval;
+
+ AMBARELLA_REG_LOCK();
+ tmpval = __raw_readl(address);
+ AMBARELLA_REG_UNLOCK();
+
+ return tmpval;
+}
+
+static inline void __amba_writel(volatile void __iomem *address, u32 value)
+{
+ AMBARELLA_REG_LOCK();
+ __raw_writel(value, address);
+ AMBARELLA_REG_UNLOCK();
+}
+
+static inline void __amba_writel_en(volatile void __iomem *address, u32 value)
+{
+ AMBARELLA_REG_LOCK();
+ __raw_writel(value, address);
+ __raw_writel((value | 0x1), address);
+ __raw_writel(value, address);
+ AMBARELLA_REG_UNLOCK();
+}
+
+#define amba_readl(v) __amba_readl((volatile void __iomem *)v)
+#define amba_writel(v,d) __amba_writel((volatile void __iomem *)v, d)
+
+static inline void __amba_read2w(volatile void __iomem *address,
+ u16 *value1, u16 *value2)
+{
+ volatile void __iomem *base;
+ u32 tmpreg;
+
+ BUG_ON((u32)address & 0x03);
+
+ base = (volatile void __iomem *)((u32)address & 0xFFFFFFFC);
+ tmpreg = amba_readl(base);
+ *value1 = (u16)tmpreg;
+ *value2 = (u16)(tmpreg >> 16);
+}
+
+static inline void __amba_write2w(volatile void __iomem *address,
+ u16 value1, u16 value2)
+{
+ volatile void __iomem *base;
+ u32 tmpreg;
+
+ BUG_ON((u32)address & 0x03);
+
+ base = (volatile void __iomem *)((u32)address & 0xFFFFFFFC);
+ tmpreg = value2;
+ tmpreg <<= 16;
+ tmpreg |= value1;
+ amba_writel(base, tmpreg);
+}
+
+#define amba_read2w(v,pd1,pd2) __amba_read2w(v,pd1,pd2)
+#define amba_write2w(v,d1,d2) __amba_write2w(v,d1,d2)
+
+#define amba_setbitsb(v, mask) amba_writeb((v),(amba_readb(v) | (mask)))
+#define amba_setbitsw(v, mask) amba_writew((v),(amba_readw(v) | (mask)))
+#define amba_setbitsl(v, mask) amba_writel((v),(amba_readl(v) | (mask)))
+
+#define amba_clrbitsb(v, mask) amba_writeb((v),(amba_readb(v) & ~(mask)))
+#define amba_clrbitsw(v, mask) amba_writew((v),(amba_readw(v) & ~(mask)))
+#define amba_clrbitsl(v, mask) amba_writel((v),(amba_readl(v) & ~(mask)))
+
+#define amba_tstbitsb(v, mask) (amba_readb(v) & (mask))
+#define amba_tstbitsw(v, mask) (amba_readw(v) & (mask))
+#define amba_tstbitsl(v, mask) (amba_readl(v) & (mask))
+
+static inline void amba_change_bit(
+ volatile void __iomem *vaddress,
+ unsigned int bit)
+{
+ u32 mask = 1UL << (bit & 31);
+ u32 data;
+
+ data = amba_readl(vaddress);
+ data ^= mask;
+ amba_writel(vaddress, data);
+}
+static inline int amba_test_and_set_bit(
+ volatile void __iomem *vaddress,
+ unsigned int bit)
+{
+ u32 mask = 1UL << (bit & 31);
+ u32 data;
+ u32 tmp;
+
+ data = amba_readl(vaddress);
+ tmp = data | mask;
+ amba_writel(vaddress, tmp);
+
+ return data & mask;
+}
+static inline int amba_test_and_clear_bit(
+ volatile void __iomem *vaddress,
+ unsigned int bit)
+{
+ u32 mask = 1UL << (bit & 31);
+ u32 data;
+ u32 tmp;
+
+ data = amba_readl(vaddress);
+ tmp = data & ~mask;
+ amba_writel(vaddress, tmp);
+
+ return data & mask;
+}
+static inline int amba_test_and_change_bit(
+ volatile void __iomem *vaddress,
+ unsigned int bit)
+{
+ u32 mask = 1UL << (bit & 31);
+ u32 data;
+ u32 tmp;
+
+ data = amba_readl(vaddress);
+ tmp = data ^ mask;
+ amba_writel(vaddress, tmp);
+
+ return data & mask;
+}
+static inline int amba_test_and_set_mask(
+ volatile void __iomem *vaddress,
+ unsigned int mask)
+{
+ u32 data;
+ u32 tmp;
+
+ data = amba_readl(vaddress);
+ tmp = data | mask;
+ amba_writel(vaddress, tmp);
+
+ return data & mask;
+}
+static inline int amba_test_and_clear_mask(
+ volatile void __iomem *vaddress,
+ unsigned int mask)
+{
+ u32 data;
+ u32 tmp;
+
+ data = amba_readl(vaddress);
+ tmp = data & ~mask;
+ amba_writel(vaddress, tmp);
+
+ return data & mask;
+}
+
+/* ==========================================================================*/
+static inline u32 __amba_rct_readl(volatile void __iomem *address)
+{
+ volatile u32 tmpval;
+
+ AMBARELLA_REG_LOCK();
+ tmpval = __raw_readl(address);
+#if (CHIP_REV == A8)
+ tmpval = __raw_readl(address);
+#endif /* CHIP_REV */
+ AMBARELLA_REG_UNLOCK();
+
+ return tmpval;
+}
+
+#define amba_rct_readl(v) __amba_rct_readl((volatile void __iomem *)v)
+#define amba_rct_writel(v,d) __amba_writel((volatile void __iomem *)v, d)
+#define amba_rct_writel_en(v,d) __amba_writel_en((volatile void __iomem *)v, d)
+#define amba_rct_setbitsl(v, mask) amba_rct_writel((v),(amba_rct_readl(v) | (mask)))
+#define amba_rct_clrbitsl(v, mask) amba_rct_writel((v),(amba_rct_readl(v) & ~(mask)))
+
+#endif /* __ASSEMBLER__ */
+/* ==========================================================================*/
+
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/mach/irqs.h b/arch/arm/mach-ambarella/include/mach/irqs.h
new file mode 100644
index 00000000..f233b117
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/mach/irqs.h
@@ -0,0 +1,44 @@
+/*
+ * arch/arm/plat-ambarella/include/mach/irqs.h
+ *
+ * History:
+ * 2007/01/27 - [Charles Chiou] created file
+ * 2008/02/19 - [Allen Wang] changed to use capabilities and chip ID
+ * 2008/05/13 - [Allen Wang] added capabilities of A2S and A2M silicons
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+/* ==========================================================================*/
+#include <mach/hardware.h>
+#include <plat/irq.h>
+
+/* ==========================================================================*/
+#ifndef __ASSEMBLER__
+
+#define IRQ_LOCALTIMER 29
+/* ==========================================================================*/
+
+#endif /* __ASSEMBLER__ */
+/* ==========================================================================*/
+
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/mach/memory.h b/arch/arm/mach-ambarella/include/mach/memory.h
new file mode 100644
index 00000000..9b7246da
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/mach/memory.h
@@ -0,0 +1,206 @@
+/*
+ * arch/arm/plat-ambarella/include/mach/memory.h
+ *
+ * History:
+ * 2006/12/27 - [Charles Chiou] created file
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * MAP Sample Phisical Virtual Size
+ * --------------------------------------------------------------------------
+ * AHB(IO) AHB_PHYS_BASE AHB_BASE AHB_SIZE
+ * APB(IO) APB_PHYS_BASE APB_BASE APB_BASE
+ * MISC(IO) MISC_PHYS_BASE MISC_BASE MISC_SIZE
+ * PPM DEFAULT_MEM_START AHB_BASE - Size CONFIG_AMBARELLA_PPM_SIZE
+ * Linux MEM PHYS_OFFSET CONFIG_VMSPLIT_xG Linux MEM Size
+ */
+
+/* ==========================================================================*/
+#if defined(CONFIG_PLAT_AMBARELLA_MEM_START_LOW)
+#define DEFAULT_MEM_START (0x00000000)
+#else
+#define DEFAULT_MEM_START (0xc0000000)
+#endif
+#ifndef CONFIG_ARM_PATCH_PHYS_VIRT
+#define PHYS_OFFSET (DEFAULT_MEM_START + CONFIG_AMBARELLA_PPM_SIZE)
+#endif
+
+/* ==========================================================================*/
+/* Physical Address and Size */
+#if defined(CONFIG_PLAT_AMBARELLA_AHB_APB_HIGH)
+#define AHB_PHYS_BASE (0xe0000000)
+#define APB_PHYS_BASE (0xe8000000)
+#else
+#define AHB_PHYS_BASE (0x60000000)
+#define APB_PHYS_BASE (0x70000000)
+#endif
+#define AHB_SIZE (0x01000000)
+#define APB_SIZE (0x01000000)
+
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI)
+#define AXI_PHYS_BASE (0xf0000000)
+#define AXI_SIZE (0x00030000)
+#endif
+
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC)
+#define DRAMC_PHYS_BASE (0xdffe0000)
+#define DRAMC_SIZE (0x00020000)
+#endif
+
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64)
+#define AHB64_PHYS_BASE (0x80000000)
+#define AHB64_SIZE (0x00020000)
+#endif
+
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS)
+#define DBGBUS_PHYS_BASE (0xec000000)
+#define DBGBUS_SIZE (0x00200000)
+#define DBGFMEM_PHYS_BASE (0xee000000)
+#define DBGFMEM_SIZE (0x01000000)
+#endif
+
+/* Virtual Address */
+#if defined(CONFIG_VMSPLIT_3G)
+#define AHB_BASE (0xf0000000)
+#define APB_BASE (0xf1000000)
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI)
+#define AXI_BASE (0xf2000000)
+#endif
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC)
+#define DRAMC_BASE (0xf2040000)
+#endif
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64)
+#define AHB64_BASE (0xf20c0000)
+#endif
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS)
+#define DBGBUS_BASE (0xf2200000)
+#define DBGFMEM_BASE (0xf3000000)
+#endif
+
+#elif defined(CONFIG_VMSPLIT_2G)
+#define AHB_BASE (0xe0000000)
+#define APB_BASE (0xe8000000)
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI)
+#define AXI_BASE (0xf0000000)
+#endif
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC)
+#define DRAMC_BASE (0xef000000)
+#endif
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64)
+#define AHB64_BASE (0xed000000)
+#endif
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS)
+#define DBGBUS_BASE (0xec000000)
+#define DBGFMEM_BASE (0xee000000)
+#endif
+
+#else /* CONFIG_VMSPLIT_1G */
+#define AHB_BASE (0xe0000000)
+#define APB_BASE (0xe8000000)
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI)
+#define AXI_BASE (0xf0000000)
+#endif
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC)
+#define DRAMC_BASE (0xef000000)
+#endif
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64)
+#define AHB64_BASE (0xed000000)
+#endif
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS)
+#define DBGBUS_BASE (0xec000000)
+#define DBGFMEM_BASE (0xee000000)
+#endif
+#endif /* CONFIG_VMSPLIT_3G */
+
+/* ==========================================================================*/
+#define DEFAULT_BST_START (DEFAULT_MEM_START + 0x00000000)
+#define DEFAULT_BST_SIZE (0x00000000)
+#define AMB_BST_MAGIC (0xffaa5500)
+#define AMB_BST_INVALID (0xdeadbeaf)
+#define AMB_BST_START_COUNTER (0xffffffff)
+
+#define DEFAULT_DEBUG_START (DEFAULT_MEM_START + 0x000f8000)
+#define DEFAULT_DEBUG_SIZE (0x00008000)
+
+/* ==========================================================================*/
+/*
+ * Constants used to force the right instruction encodings and shifts
+ * so that all we need to do is modify the 8-bit constant field.
+ */
+#define __PV_BITS_31_24 0x81000000
+
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
+#ifndef __ASSEMBLY__
+extern u32 ambarella_phys_to_virt(u32 paddr);
+extern u32 ambarella_virt_to_phys(u32 vaddr);
+extern unsigned long __pv_phys_offset;
+#define PHYS_OFFSET __pv_phys_offset
+
+#define __pv_stub(from,to,instr,type) \
+ __asm__("@ __pv_stub\n" \
+ "1: " instr " %0, %1, %2\n" \
+ " .pushsection .pv_table,\"a\"\n" \
+ " .long 1b\n" \
+ " .popsection\n" \
+ : "=r" (to) \
+ : "r" (from), "I" (type))
+
+static inline unsigned long __amb_raw_virt_to_phys(unsigned long x)
+{
+ unsigned long t;
+ __pv_stub(x, t, "add", __PV_BITS_31_24);
+ return t;
+}
+
+static inline unsigned long __amb_raw_phys_to_virt(unsigned long x)
+{
+ unsigned long t;
+ __pv_stub(x, t, "sub", __PV_BITS_31_24);
+ return t;
+}
+#endif /* __ASSEMBLY__ */
+#else /* CONFIG_ARM_PATCH_PHYS_VIRT */
+#define __amb_raw_virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET)
+#define __amb_raw_phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET)
+#endif /* CONFIG_ARM_PATCH_PHYS_VIRT */
+
+#if defined(CONFIG_AMBARELLA_IO_MAP)
+#define __virt_to_phys(x) (ambarella_virt_to_phys(x))
+#define __phys_to_virt(x) (ambarella_phys_to_virt(x))
+#else
+#define __virt_to_phys(x) (__amb_raw_virt_to_phys(x))
+#define __phys_to_virt(x) (__amb_raw_phys_to_virt(x))
+#endif
+#define __virt_to_bus(x) __virt_to_phys(x)
+#define __bus_to_virt(x) __phys_to_virt(x)
+#define __pfn_to_bus(x) __pfn_to_phys(x)
+#define __bus_to_pfn(x) __phys_to_pfn(x)
+
+
+/* ==========================================================================*/
+#define MAX_PHYSMEM_BITS 32
+#define SECTION_SIZE_BITS 24
+/* ==========================================================================*/
+
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/mach/timex.h b/arch/arm/mach-ambarella/include/mach/timex.h
new file mode 100644
index 00000000..5efe4351
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/mach/timex.h
@@ -0,0 +1,33 @@
+/*
+ * arch/arm/plat-ambarella/include/mach/timex.h
+ *
+ * History:
+ * 2006/12/27 - [Charles Chiou] created file
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+#include <plat/chip.h>
+
+#define CLOCK_TICK_RATE REF_CLK_FREQ
+
+#endif /* __ASM_ARCH_TIMEX_H */
+
diff --git a/arch/arm/mach-ambarella/include/mach/uncompress.h b/arch/arm/mach-ambarella/include/mach/uncompress.h
new file mode 100644
index 00000000..35f8d46b
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/mach/uncompress.h
@@ -0,0 +1,54 @@
+/*
+ * arch/arm/plat-ambarella/include/mach/uart.h
+ *
+ * History:
+ * 2006/12/27 - [Charles Chiou] created file
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+/* ==========================================================================*/
+
+/* ==========================================================================*/
+#ifndef __ASSEMBLER__
+
+/* ==========================================================================*/
+static inline void putc(int c)
+{
+
+}
+
+static inline void flush(void)
+{
+}
+
+static __inline__ void arch_decomp_setup(void)
+{
+
+}
+
+#define arch_decomp_wdog()
+
+#endif /* __ASSEMBLER__ */
+/* ==========================================================================*/
+
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/plat/adc.h b/arch/arm/mach-ambarella/include/plat/adc.h
new file mode 100644
index 00000000..a9d450a9
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/adc.h
@@ -0,0 +1,375 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/adc.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_ADC_H__
+#define __PLAT_AMBARELLA_ADC_H__
+
+#include <linux/workqueue.h>
+
+/* ==========================================================================*/
+#if (CHIP_REV == A7L)
+#define ADC_NUM_CHANNELS 8
+#elif (CHIP_REV == S2) || (CHIP_REV == S2E)
+#define ADC_NUM_CHANNELS 12
+#elif (CHIP_REV == S3)
+#define ADC_NUM_CHANNELS 5
+#else
+#define ADC_NUM_CHANNELS 4
+#endif
+
+#if (CHIP_REV == A5S)
+#define ADC_SUPPORT_THRESHOLD_INT 0
+#define ADC_SUPPORT_SLOT 0
+#else
+#define ADC_SUPPORT_THRESHOLD_INT 1
+#define ADC_SUPPORT_SLOT 1
+#endif
+
+/* ==========================================================================*/
+#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+#define ADC_OFFSET 0x1D000
+#else
+#define ADC_OFFSET 0xD000
+#endif
+#define ADC_BASE (APB_BASE + ADC_OFFSET)
+#define ADC_REG(x) (ADC_BASE + (x))
+
+/* ==========================================================================*/
+#if (CHIP_REV == A5S)
+#define ADC_CONTROL_TYPE 0
+#define ADC_CONTROL_OFFSET 0x00
+#define ADC_ENABLE_OFFSET 0x18
+#else
+#define ADC_CONTROL_TYPE 1
+#define ADC_CONTROL_OFFSET 0x04
+#define ADC_ENABLE_OFFSET ADC_CONTROL_OFFSET
+#endif
+
+#if (CHIP_REV == A5S)
+/* NOTE: ADC channel is re-order for A5S to make life easier */
+#define ADC_DATA0_OFFSET 0x04
+#define ADC_DATA1_OFFSET 0x08
+#define ADC_DATA2_OFFSET 0x0c
+#define ADC_DATA3_OFFSET 0x10
+#else
+#define ADC_DATA0_OFFSET 0x150
+#define ADC_DATA1_OFFSET 0x154
+#define ADC_DATA2_OFFSET 0x158
+#define ADC_DATA3_OFFSET 0x15c
+#endif
+
+#define ADC_COUNTER_OFFSET 0x008
+
+#if (CHIP_REV == A5S)
+#define ADC_CHAN0_INTR_OFFSET 0x44
+#define ADC_CHAN1_INTR_OFFSET 0x48
+#define ADC_CHAN2_INTR_OFFSET 0x4c
+#define ADC_CHAN3_INTR_OFFSET 0x50
+#else
+#define ADC_CHAN0_INTR_OFFSET 0x120
+#define ADC_CHAN1_INTR_OFFSET 0x124
+#define ADC_CHAN2_INTR_OFFSET 0x128
+#define ADC_CHAN3_INTR_OFFSET 0x12c
+#endif
+
+#if (CHIP_REV == A7L)
+#define ADC_DATA4_OFFSET 0x100
+#define ADC_DATA5_OFFSET 0x104
+#define ADC_DATA6_OFFSET 0x108
+#define ADC_DATA7_OFFSET 0x10c
+#define ADC_CHAN4_INTR_OFFSET 0x110
+#define ADC_CHAN5_INTR_OFFSET 0x114
+#define ADC_CHAN6_INTR_OFFSET 0x118
+#define ADC_CHAN7_INTR_OFFSET 0x11c
+#elif (CHIP_REV == S2) || (CHIP_REV == S2E) || (CHIP_REV == S3)
+#define ADC_DATA4_OFFSET 0x160
+#define ADC_DATA5_OFFSET 0x164
+#define ADC_DATA6_OFFSET 0x168
+#define ADC_DATA7_OFFSET 0x16c
+#define ADC_CHAN4_INTR_OFFSET 0x130
+#define ADC_CHAN5_INTR_OFFSET 0x134
+#define ADC_CHAN6_INTR_OFFSET 0x138
+#define ADC_CHAN7_INTR_OFFSET 0x13c
+#else
+#define ADC_DATA4_OFFSET 0x54
+#define ADC_DATA5_OFFSET 0x58
+#define ADC_DATA6_OFFSET 0x5c
+#define ADC_DATA7_OFFSET 0x60
+#define ADC_CHAN4_INTR_OFFSET 0x64
+#define ADC_CHAN5_INTR_OFFSET 0x68
+#define ADC_CHAN6_INTR_OFFSET 0x6c
+#define ADC_CHAN7_INTR_OFFSET 0x70
+#endif
+
+#if (CHIP_REV == S2) || (CHIP_REV == S2E)
+#define ADC_DATA8_OFFSET 0x170
+#define ADC_DATA9_OFFSET 0x174
+#define ADC_DATA10_OFFSET 0x178
+#define ADC_DATA11_OFFSET 0x17c
+#define ADC_CHAN8_INTR_OFFSET 0x140
+#define ADC_CHAN9_INTR_OFFSET 0x144
+#define ADC_CHAN10_INTR_OFFSET 0x148
+#define ADC_CHAN11_INTR_OFFSET 0x14c
+#else
+#define ADC_DATA8_OFFSET 0x60
+#define ADC_DATA9_OFFSET 0x70
+#define ADC_CHAN8_INTR_OFFSET 0x120
+#define ADC_CHAN9_INTR_OFFSET 0x124
+#endif
+
+/* S2, S2L and S3 */
+#define ADC_STATUS_OFFSET 0x000
+#define ADC_SLOT_NUM_OFFSET 0x00c
+#define ADC_SLOT_PERIOD_OFFSET 0x010
+#define ADC_CTRL_INTR_TABLE_OFFSET 0x044
+#define ADC_DATA_INTR_TABLE_OFFSET 0x048
+#define ADC_FIFO_INTR_TABLE_OFFSET 0x04c
+#define ADC_ERR_STATUS_OFFSET 0x050
+
+#define ADC_SLOT_CTRL_0_OFFSET 0x100
+#define ADC_SLOT_CTRL_1_OFFSET 0x104
+#define ADC_SLOT_CTRL_2_OFFSET 0x108
+#define ADC_SLOT_CTRL_3_OFFSET 0x10c
+#define ADC_SLOT_CTRL_4_OFFSET 0x110
+#define ADC_SLOT_CTRL_5_OFFSET 0x114
+#define ADC_SLOT_CTRL_6_OFFSET 0x118
+#define ADC_SLOT_CTRL_7_OFFSET 0x11c
+
+#define ADC_FIFO_CTRL_0_OFFSET 0x180
+#define ADC_FIFO_CTRL_1_OFFSET 0x184
+#define ADC_FIFO_CTRL_2_OFFSET 0x188
+#define ADC_FIFO_CTRL_3_OFFSET 0x18C
+#define ADC_FIFO_CTRL_OFFSET 0x190
+
+#define ADC_FIFO_STATUS_0_OFFSET 0x1a0
+#define ADC_FIFO_STATUS_1_OFFSET 0x1a4
+#define ADC_FIFO_STATUS_2_OFFSET 0x1a8
+#define ADC_FIFO_STATUS_3_OFFSET 0x1ac
+
+#define ADC_EC_ADC_OFFSET 0x1C0
+#define ADC_EC_REFVAL_OFFSET 0x1C4
+#define ADC_EC_RESHAPE_OFFSET 0x1C8
+
+#define ADC_FIFO_DATA0_OFFSET 0x200
+#define ADC_FIFO_DATA1_OFFSET 0x280
+#define ADC_FIFO_DATA2_OFFSET 0x300
+#define ADC_FIFO_DATA3_OFFSET 0x380
+
+/* A7 */
+#define ADC_DATA4_SAMPLE0_OFFSET 0x60
+#define ADC_DATA4_SAMPLE1_OFFSET 0x64
+#define ADC_DATA4_SAMPLE2_OFFSET 0x68
+#define ADC_DATA4_SAMPLE3_OFFSET 0x6c
+#define ADC_DATA5_SAMPLE0_OFFSET 0x70
+#define ADC_DATA5_SAMPLE1_OFFSET 0x74
+#define ADC_DATA5_SAMPLE2_OFFSET 0x78
+#define ADC_DATA5_SAMPLE3_OFFSET 0x5c
+
+#define ADC_CONTROL_REG ADC_REG(ADC_CONTROL_OFFSET)
+#define ADC_COUNTER_REG ADC_REG(ADC_COUNTER_OFFSET)
+#define ADC_ENABLE_REG ADC_REG(ADC_ENABLE_OFFSET)
+
+#define ADC_DATA0_REG ADC_REG(ADC_DATA0_OFFSET)
+#define ADC_DATA1_REG ADC_REG(ADC_DATA1_OFFSET)
+#define ADC_DATA2_REG ADC_REG(ADC_DATA2_OFFSET)
+#define ADC_DATA3_REG ADC_REG(ADC_DATA3_OFFSET)
+#define ADC_DATA4_REG ADC_REG(ADC_DATA4_OFFSET)
+#define ADC_DATA5_REG ADC_REG(ADC_DATA5_OFFSET)
+#define ADC_DATA6_REG ADC_REG(ADC_DATA6_OFFSET)
+#define ADC_DATA7_REG ADC_REG(ADC_DATA7_OFFSET)
+#define ADC_DATA8_REG ADC_REG(ADC_DATA8_OFFSET)
+#define ADC_DATA9_REG ADC_REG(ADC_DATA9_OFFSET)
+
+#define ADC_CHAN0_INTR_REG ADC_REG(ADC_CHAN0_INTR_OFFSET)
+#define ADC_CHAN1_INTR_REG ADC_REG(ADC_CHAN1_INTR_OFFSET)
+#define ADC_CHAN2_INTR_REG ADC_REG(ADC_CHAN2_INTR_OFFSET)
+#define ADC_CHAN3_INTR_REG ADC_REG(ADC_CHAN3_INTR_OFFSET)
+#define ADC_CHAN4_INTR_REG ADC_REG(ADC_CHAN4_INTR_OFFSET)
+#define ADC_CHAN5_INTR_REG ADC_REG(ADC_CHAN5_INTR_OFFSET)
+#define ADC_CHAN6_INTR_REG ADC_REG(ADC_CHAN6_INTR_OFFSET)
+#define ADC_CHAN7_INTR_REG ADC_REG(ADC_CHAN7_INTR_OFFSET)
+#define ADC_CHAN8_INTR_REG ADC_REG(ADC_CHAN8_INTR_OFFSET)
+#define ADC_CHAN9_INTR_REG ADC_REG(ADC_CHAN9_INTR_OFFSET)
+
+#define ADC_DATA4_SAMPLE0_REG ADC_REG(ADC_DATA4_SAMPLE0_OFFSET)
+#define ADC_DATA4_SAMPLE1_REG ADC_REG(ADC_DATA4_SAMPLE1_OFFSET)
+#define ADC_DATA4_SAMPLE2_REG ADC_REG(ADC_DATA4_SAMPLE2_OFFSET)
+#define ADC_DATA4_SAMPLE3_REG ADC_REG(ADC_DATA4_SAMPLE3_OFFSET)
+#define ADC_DATA5_SAMPLE0_REG ADC_REG(ADC_DATA5_SAMPLE0_OFFSET)
+#define ADC_DATA5_SAMPLE1_REG ADC_REG(ADC_DATA5_SAMPLE1_OFFSET)
+#define ADC_DATA5_SAMPLE2_REG ADC_REG(ADC_DATA5_SAMPLE2_OFFSET)
+#define ADC_DATA5_SAMPLE3_REG ADC_REG(ADC_DATA5_SAMPLE3_OFFSET)
+
+/* valid only for S2/S2E/S2L/S3/S3L */
+#define ADC_STATUS_REG ADC_REG(ADC_STATUS_OFFSET)
+#define ADC_SLOT_NUM_REG ADC_REG(ADC_SLOT_NUM_OFFSET)
+#define ADC_SLOT_PERIOD_REG ADC_REG(ADC_SLOT_PERIOD_OFFSET)
+#define ADC_CTRL_INTR_TABLE_REG ADC_REG(ADC_CTRL_INTR_TABLE_OFFSET)
+#define ADC_DATA_INTR_TABLE_REG ADC_REG(ADC_DATA_INTR_TABLE_OFFSET)
+#define ADC_FIFO_INTR_TABLE_REG ADC_REG(ADC_FIFO_INTR_TABLE_OFFSET)
+#define ADC_ERR_STATUS_REG ADC_REG(ADC_ERR_STATUS_OFFSET)
+
+#define ADC_SLOT_CTRL_0_REG ADC_REG(ADC_SLOT_CTRL_0_OFFSET)
+#define ADC_SLOT_CTRL_1_REG ADC_REG(ADC_SLOT_CTRL_1_OFFSET)
+#define ADC_SLOT_CTRL_2_REG ADC_REG(ADC_SLOT_CTRL_2_OFFSET)
+#define ADC_SLOT_CTRL_3_REG ADC_REG(ADC_SLOT_CTRL_3_OFFSET)
+#define ADC_SLOT_CTRL_4_REG ADC_REG(ADC_SLOT_CTRL_4_OFFSET)
+#define ADC_SLOT_CTRL_5_REG ADC_REG(ADC_SLOT_CTRL_5_OFFSET)
+#define ADC_SLOT_CTRL_6_REG ADC_REG(ADC_SLOT_CTRL_6_OFFSET)
+#define ADC_SLOT_CTRL_7_REG ADC_REG(ADC_SLOT_CTRL_7_OFFSET)
+
+#define ADC_FIFO_CTRL_0_REG ADC_REG(ADC_FIFO_CTRL_0_OFFSET)
+#define ADC_FIFO_CTRL_1_REG ADC_REG(ADC_FIFO_CTRL_1_OFFSET)
+#define ADC_FIFO_CTRL_2_REG ADC_REG(ADC_FIFO_CTRL_2_OFFSET)
+#define ADC_FIFO_CTRL_3_REG ADC_REG(ADC_FIFO_CTRL_3_OFFSET)
+#define ADC_FIFO_CTRL_REG ADC_REG(ADC_FIFO_CTRL_OFFSET)
+
+#define ADC_FIFO_STATUS_0_REG ADC_REG(ADC_FIFO_STATUS_0_OFFSET)
+#define ADC_FIFO_STATUS_1_REG ADC_REG(ADC_FIFO_STATUS_1_OFFSET)
+#define ADC_FIFO_STATUS_2_REG ADC_REG(ADC_FIFO_STATUS_2_OFFSET)
+#define ADC_FIFO_STATUS_3_REG ADC_REG(ADC_FIFO_STATUS_3_OFFSET)
+
+#define ADC_EC_ADC_REG ADC_REG(ADC_EC_ADC_OFFSET)
+#define ADC_EC_REFVAL_REG ADC_REG(ADC_EC_REFVAL_OFFSET)
+#define ADC_EC_RESHAPE_REG ADC_REG(ADC_EC_RESHAPE_OFFSET)
+
+#define ADC_FIFO_DATA0_REG ADC_REG(ADC_FIFO_DATA0_OFFSET)
+#define ADC_FIFO_DATA1_REG ADC_REG(ADC_FIFO_DATA1_OFFSET)
+#define ADC_FIFO_DATA2_REG ADC_REG(ADC_FIFO_DATA2_OFFSET)
+#define ADC_FIFO_DATA3_REG ADC_REG(ADC_FIFO_DATA3_OFFSET)
+
+#define ADC_DATA10_REG ADC_REG(ADC_DATA10_OFFSET)
+#define ADC_DATA11_REG ADC_REG(ADC_DATA11_OFFSET)
+#define ADC_CHAN10_INTR_REG ADC_REG(ADC_CHAN10_INTR_OFFSET)
+#define ADC_CHAN11_INTR_REG ADC_REG(ADC_CHAN11_INTR_OFFSET)
+
+#if (CHIP_REV == A7L)
+#error "ADC_DATA_REG/ADC_CHAN_INTR_REG(ch) Not Implemented"
+#else
+#define ADC_DATA_OFFSET(ch) (ADC_DATA0_OFFSET + (ch) * 4)
+#define ADC_DATA_REG(ch) ADC_REG(ADC_DATA_OFFSET(ch))
+#define ADC_FIFO_CTRL_X_OFFSET(fifoNo) (ADC_FIFO_CTRL_0_OFFSET + (fifoNo) * 4)
+#define ADC_FIFO_CTRL_X_REG(fifoNo) ADC_REG(ADC_FIFO_CTRL_X_OFFSET(fifoNo))
+#define ADC_CHAN_INTR_OFFSET(ch) (ADC_CHAN0_INTR_OFFSET + (ch) * 4)
+#define ADC_CHAN_INTR_REG(ch) ADC_REG(ADC_CHAN_INTR_OFFSET(ch))
+#endif
+
+#define ADC16_CTRL_OFFSET 0x198
+#define ADC16_CTRL_REG RCT_REG(ADC16_CTRL_OFFSET)
+
+/* ADC_CONTROL_REG */
+#define ADC_CONTROL_GYRO_SAMPLE_MODE 0x08
+
+/* valid only for S2/S2E/S2L/S3/S3L */
+#define ADC_CONTROL_RESET 0x01
+#define ADC_FIFO_OVER_INT_EN (0x1 << 31)
+#define ADC_FIFO_UNDR_INT_EN (0x1 << 30)
+#define ADC_FIFO_DEPTH 0x80
+#define ADC_FIFO_TH (((ADC_FIFO_DEPTH >> 2)-1) << 16)
+#define ADC_FIFO_CLEAR 0x1
+#define ADC_FIFO_ID_SHIFT 12
+#define ADC_FIFO_CONTROL_CLEAR 0x01
+#define ADC_FIFO_NUMBER 0x04
+
+#define ADC_CTRL_SCALER_POWERDOWN 0x100
+#define ADC_CTRL_POWERDOWN 0x2
+#define ADC_CTRL_CLK_SOURCE_SCALER 0x0
+#define ADC_CTRL_CLK_SOURCE_AUDIO 0x1
+
+#if (CHIP_REV == A5S)
+#define ADC_CONTROL_MODE 0x04
+#define ADC_CONTROL_ENABLE 0x01
+#define ADC_CONTROL_START 0x02
+#else
+#define ADC_CONTROL_MODE 0x02
+#define ADC_CONTROL_ENABLE 0x04
+#define ADC_CONTROL_START 0x08
+#endif
+#define ADC_CONTROL_STATUS 0x01
+
+#if (CHIP_REV == A5S)
+#define ADC_EN_HI(x) ((x) << 31)
+#define ADC_EN_LO(x) ((x) << 30)
+#else
+#define ADC_EN_HI(x) ((x) << 31)
+#define ADC_EN_LO(x) ((x) << 31)
+#endif
+
+#define ADC_VAL_HI(x) (((x) & 0xfff) << 16)
+#define ADC_VAL_LO(x) ((x) & 0xfff)
+/* ==========================================================================*/
+
+#define ADC_MAX_SLOT_NUMBER 8
+
+#define ADC_CH0 (1 << 0)
+#define ADC_CH1 (1 << 1)
+#define ADC_CH2 (1 << 2)
+#define ADC_CH3 (1 << 3)
+#define ADC_CH4 (1 << 4)
+#define ADC_CH5 (1 << 5)
+#define ADC_CH6 (1 << 6)
+#define ADC_CH7 (1 << 7)
+#define ADC_CH8 (1 << 8)
+#define ADC_CH9 (1 << 9)
+#define ADC_CH10 (1 << 10)
+#define ADC_CH11 (1 << 11)
+
+enum {
+ AMBADC_ONESHOT = 0,
+ AMBADC_CONTINUOUS,
+};
+
+struct ambadc_host {
+ struct device *dev;
+ u32 irq;
+ u32 clk;
+ bool polling_mode;
+ bool keep_start;
+ bool fifo_mode;
+ struct delayed_work work;
+};
+
+struct ambadc_client;
+typedef int (*ambadc_client_callback)(struct ambadc_client *client,
+ u32 ch, u32 level);
+typedef int (*ambadc_read_level)(u32 ch);
+
+struct ambadc_client {
+ struct device *dev;
+ struct ambadc_host *host;
+ struct list_head node;
+ u32 threshold[ADC_NUM_CHANNELS];
+ u32 mode;
+ ambadc_client_callback callback;
+};
+
+extern struct ambadc_client *ambarella_adc_register_client(struct device *dev,
+ u32 mode, ambadc_client_callback callback);
+extern void ambarella_adc_unregister_client(struct ambadc_client *client);
+
+extern int ambarella_adc_set_threshold(struct ambadc_client *client,
+ u32 ch, u32 low, u32 high);
+extern int ambarella_adc_read_level(u32 ch);
+
+#endif /* __PLAT_AMBARELLA_ADC_H__ */
+
diff --git a/arch/arm/mach-ambarella/include/plat/ahci.h b/arch/arm/mach-ambarella/include/plat/ahci.h
new file mode 100644
index 00000000..081a2574
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/ahci.h
@@ -0,0 +1,34 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/ahci.h
+ *
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_AHCI_H__
+#define __PLAT_AMBARELLA_AHCI_H__
+
+/* ==========================================================================*/
+
+#define SATA_OFFSET 0x1A000
+
+/* ==========================================================================*/
+
+#endif /* __PLAT_AMBARELLA_AHCI_H__ */
+
diff --git a/arch/arm/mach-ambarella/include/plat/ambasyncproc.h b/arch/arm/mach-ambarella/include/plat/ambasyncproc.h
new file mode 100644
index 00000000..375273b4
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/ambasyncproc.h
@@ -0,0 +1,46 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/ambasyncproc.h
+ *
+ * Author: Zhenwu Xue <zwxue@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_ASYNC_PROC_H
+#define __PLAT_AMBARELLA_ASYNC_PROC_H
+
+/* ==========================================================================*/
+#ifndef __ASSEMBLER__
+
+struct amb_async_proc_info {
+ char proc_name[256];
+ struct file_operations fops;
+ void *private_data;
+ struct fasync_struct *fasync_queue;
+ struct mutex op_mutex;
+ int use_count;
+};
+
+extern int amb_async_proc_create(struct amb_async_proc_info *pinfo);
+extern int amb_async_proc_remove(struct amb_async_proc_info *pinfo);
+
+#endif /* __ASSEMBLER__ */
+/* ==========================================================================*/
+
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/plat/ambcache.h b/arch/arm/mach-ambarella/include/plat/ambcache.h
new file mode 100644
index 00000000..5520f67f
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/ambcache.h
@@ -0,0 +1,31 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/ambcache.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_CACHE_H
+#define __PLAT_AMBARELLA_CACHE_H
+
+#ifndef __ASSEMBLER__
+
+#endif /* __ASSEMBLER__ */
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/plat/ambevent.h b/arch/arm/mach-ambarella/include/plat/ambevent.h
new file mode 100644
index 00000000..4f29e95f
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/ambevent.h
@@ -0,0 +1,86 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/ambevent.h
+ *
+ * History:
+ * 2010/07/23 - [Zhenwu Xue] Create
+ *
+ * Copyright 2008-2015 Ambarella Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __AMB_EVENT_H
+#define __AMB_EVENT_H
+
+/* ==========================================================================*/
+#ifndef __ASSEMBLER__
+#include <linux/kobject.h>
+
+/* Copy from build/include/ambas_event.h */
+enum amb_event_type {
+ /* No Event */
+ AMB_EV_NONE = 0x00000000,
+
+ /* VIN Event */
+ AMB_EV_VIN_DECODER_SOURCE_PLUG = 0x00010000,
+ AMB_EV_VIN_DECODER_SOURCE_REMOVE,
+
+ /* VOUT Event */
+ AMB_EV_VOUT_CVBS_PLUG = 0x00020000,
+ AMB_EV_VOUT_CVBS_REMOVE,
+ AMB_EV_VOUT_YPBPR_PLUG,
+ AMB_EV_VOUT_YPBPR_REMOVE,
+ AMB_EV_VOUT_HDMI_PLUG,
+ AMB_EV_VOUT_HDMI_REMOVE,
+
+ /* SENSOR Event*/
+ AMB_EV_ACCELEROMETER_REPORT = 0x00030000,
+ AMB_EV_MAGNETIC_FIELD_REPORT,
+ AMB_EV_LIGHT_REPORT,
+ AMB_EV_PROXIMITY_REPORT,
+ AMB_EV_GYROSCOPE_REPORT,
+ AMB_EV_TEMPERATURE_REPORT,
+
+ /* FB2 Event */
+ AMB_EV_FB2_PAN_DISPLAY = 0x00040000,
+
+ /* FDET_EVENT */
+ AMB_EV_FDET_FACE_DETECTED = 0x00050000,
+};
+
+struct amb_event {
+ u32 sno; //sequential number
+ u64 time_code;
+ enum amb_event_type type;
+ u8 data[32];
+};
+
+struct amb_event_pool {
+ struct mutex op_mutex;
+ struct amb_event events[256];
+ unsigned int ev_sno;
+ unsigned char ev_index;
+};
+
+extern int amb_event_pool_init(struct amb_event_pool *pool);
+extern int amb_event_pool_affuse(struct amb_event_pool *pool,
+ struct amb_event event);
+extern int amb_event_pool_query_index(struct amb_event_pool *pool);
+extern int amb_event_pool_query_event(struct amb_event_pool *pool,
+ struct amb_event *event, unsigned char index);
+extern int amb_event_report_uevent(struct kobject *kobj,
+ enum kobject_action action, char *envp_ext[]);
+
+#endif /* __ASSEMBLER__ */
+/* ==========================================================================*/
+
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/plat/ambsyncproc.h b/arch/arm/mach-ambarella/include/plat/ambsyncproc.h
new file mode 100644
index 00000000..2632949e
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/ambsyncproc.h
@@ -0,0 +1,68 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/ambync_proc.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_SYNC_PROC_H
+#define __PLAT_AMBARELLA_SYNC_PROC_H
+
+#include <linux/fs.h>
+
+/* ==========================================================================*/
+#define AMBA_SYNC_PROC_MAX_ID (31)
+#define AMBA_SYNC_PROC_PAGE_SIZE (PAGE_SIZE - 16)
+
+/* ==========================================================================*/
+#ifndef __ASSEMBLER__
+
+typedef int(ambsync_read_proc_t)(char *start, void *data);
+
+struct ambsync_proc_pinfo {
+ u32 id;
+ u32 mask;
+ char *page;
+};
+
+struct ambsync_proc_hinfo {
+ u32 maxid;
+ u32 tmo;
+ wait_queue_head_t sync_proc_head;
+ atomic_t sync_proc_flag;
+ struct idr sync_proc_idr;
+ struct mutex sync_proc_lock;
+ ambsync_read_proc_t *sync_read_proc;
+ void *sync_read_data;
+};
+
+/* ==========================================================================*/
+
+/* ==========================================================================*/
+extern int ambsync_proc_hinit(struct ambsync_proc_hinfo *hinfo);
+extern int ambsync_proc_open(struct inode *inode, struct file *file);
+extern int ambsync_proc_release(struct inode *inode, struct file *file);
+extern ssize_t ambsync_proc_read(struct file *file, char __user *buf, size_t size, loff_t *ppos);
+extern ssize_t ambsync_proc_write(struct file *file, const char __user *buf, size_t size, loff_t *ppos);
+
+#endif /* __ASSEMBLER__ */
+/* ==========================================================================*/
+
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/plat/audio.h b/arch/arm/mach-ambarella/include/plat/audio.h
new file mode 100644
index 00000000..6ddcd327
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/audio.h
@@ -0,0 +1,203 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/audio.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_AUDIO_H__
+#define __PLAT_AMBARELLA_AUDIO_H__
+
+/* ==========================================================================*/
+#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+#define I2S_OFFSET 0x1A000
+#else
+#define I2S_OFFSET 0xA000
+#endif
+#define I2S_BASE (AHB_BASE + I2S_OFFSET)
+#define I2S_BASE_PHYS (AHB_PHYS_BASE + I2S_OFFSET)
+#define I2S_REG(x) (I2S_BASE + (x))
+#define I2S_REG_PHYS(x) (I2S_BASE_PHYS + (x))
+
+/* ==========================================================================*/
+#define I2S_MODE_OFFSET 0x00
+#define I2S_RX_CTRL_OFFSET 0x04
+#define I2S_TX_CTRL_OFFSET 0x08
+#define I2S_WLEN_OFFSET 0x0c
+#define I2S_WPOS_OFFSET 0x10
+#define I2S_SLOT_OFFSET 0x14
+#define I2S_TX_FIFO_LTH_OFFSET 0x18
+#define I2S_RX_FIFO_GTH_OFFSET 0x1c
+#define I2S_CLOCK_OFFSET 0x20
+#define I2S_INIT_OFFSET 0x24
+#define I2S_TX_STATUS_OFFSET 0x28
+#define I2S_TX_LEFT_DATA_OFFSET 0x2c
+#define I2S_TX_RIGHT_DATA_OFFSET 0x30
+#define I2S_RX_STATUS_OFFSET 0x34
+#define I2S_RX_DATA_OFFSET 0x38
+#define I2S_TX_FIFO_CNTR_OFFSET 0x3c
+#define I2S_RX_FIFO_CNTR_OFFSET 0x40
+#define I2S_TX_INT_ENABLE_OFFSET 0x44
+#define I2S_RX_INT_ENABLE_OFFSET 0x48
+#define I2S_RX_ECHO_OFFSET 0x4c
+#define I2S_24BITMUX_MODE_OFFSET 0x50
+#define I2S_GATEOFF_OFFSET 0x54
+#define I2S_CHANNEL_SELECT_OFFSET 0x58
+#define I2S_RX_DATA_DMA_OFFSET 0x80
+#define I2S_TX_LEFT_DATA_DMA_OFFSET 0xc0
+
+#define I2S_MODE_REG I2S_REG(0x00)
+#define I2S_RX_CTRL_REG I2S_REG(0x04)
+#define I2S_TX_CTRL_REG I2S_REG(0x08)
+#define I2S_WLEN_REG I2S_REG(0x0c)
+#define I2S_WPOS_REG I2S_REG(0x10)
+#define I2S_SLOT_REG I2S_REG(0x14)
+#define I2S_TX_FIFO_LTH_REG I2S_REG(0x18)
+#define I2S_RX_FIFO_GTH_REG I2S_REG(0x1c)
+#define I2S_CLOCK_REG I2S_REG(0x20)
+#define I2S_INIT_REG I2S_REG(0x24)
+#define I2S_TX_STATUS_REG I2S_REG(0x28)
+#define I2S_TX_LEFT_DATA_REG I2S_REG(0x2c)
+#define I2S_TX_RIGHT_DATA_REG I2S_REG(0x30)
+#define I2S_RX_STATUS_REG I2S_REG(0x34)
+#define I2S_RX_DATA_REG I2S_REG(0x38)
+#define I2S_TX_FIFO_CNTR_REG I2S_REG(0x3c)
+#define I2S_RX_FIFO_CNTR_REG I2S_REG(0x40)
+#define I2S_TX_INT_ENABLE_REG I2S_REG(0x44)
+#define I2S_RX_INT_ENABLE_REG I2S_REG(0x48)
+#define I2S_RX_ECHO_REG I2S_REG(0x4c)
+#define I2S_24BITMUX_MODE_REG I2S_REG(0x50)
+#define I2S_GATEOFF_REG I2S_REG(0x54)
+#define I2S_CHANNEL_SELECT_REG I2S_REG(0x58)
+#define I2S_RX_DATA_DMA_REG I2S_REG_PHYS(0x80)
+#define I2S_TX_LEFT_DATA_DMA_REG I2S_REG_PHYS(0xc0)
+
+#define I2S_LEFT_JUSTIFIED_MODE 0x0
+#define I2S_RIGHT_JUSTIFIED_MODE 0x1
+#define I2S_MSB_EXTEND_MODE 0x2
+#define I2S_I2S_MODE 0x4
+#define I2S_DSP_MODE 0x6
+
+#define I2S_TX_FIFO_RESET_BIT (1 << 4)
+#define I2S_RX_FIFO_RESET_BIT (1 << 3)
+#define I2S_TX_ENABLE_BIT (1 << 2)
+#define I2S_RX_ENABLE_BIT (1 << 1)
+#define I2S_FIFO_RESET_BIT (1 << 0)
+
+#define I2S_RX_LOOPBACK_BIT (1 << 3)
+#define I2S_RX_ORDER_BIT (1 << 2)
+#define I2S_RX_WS_MST_BIT (1 << 1)
+#define I2S_RX_WS_INV_BIT (1 << 0)
+
+#define I2S_TX_LOOPBACK_BIT (1 << 7)
+#define I2S_TX_ORDER_BIT (1 << 6)
+#define I2S_TX_WS_MST_BIT (1 << 5)
+#define I2S_TX_WS_INV_BIT (1 << 4)
+#define I2S_TX_UNISON_BIT (1 << 3)
+#define I2S_TX_MUTE_BIT (1 << 2)
+#define I2S_TX_MONO_MASK 0xfffffffc
+#define I2S_TX_MONO_RIGHT (1 << 1)
+#define I2S_TX_MONO_LEFT (1 << 0)
+
+#define I2S_CLK_WS_OUT_EN (1 << 9)
+#define I2S_CLK_BCLK_OUT_EN (1 << 8)
+#define I2S_CLK_BCLK_OUTPUT (1 << 7)
+#define I2S_CLK_MASTER_MODE (I2S_CLK_WS_OUT_EN | \
+ I2S_CLK_BCLK_OUT_EN | \
+ I2S_CLK_BCLK_OUTPUT)
+#define I2S_CLK_TX_PO_FALL (1 << 6)
+#define I2S_CLK_RX_PO_FALL (1 << 5)
+#define I2S_CLK_DIV_MASK 0xffffffe0
+
+#define I2S_RX_SHIFT_ENB (1 << 1)
+#define I2S_TX_SHIFT_ENB (1 << 0)
+
+#define I2S_2CHANNELS_ENB 0x00
+#define I2S_4CHANNELS_ENB 0x01
+#define I2S_6CHANNELS_ENB 0x02
+
+#define I2S_FIFO_THRESHOLD_INTRPT 0x08
+#define I2S_FIFO_FULL_INTRPT 0x02
+#define I2S_FIFO_EMPTY_INTRPT 0x01
+
+/* I2S_24BITMUX_MODE_REG */
+#define I2S_24BITMUX_MODE_ENABLE 0x1
+#define I2S_24BITMUX_MODE_FDMA_BURST_DIS 0x2
+#define I2S_24BITMUX_MODE_RST_CHAN0 0x4
+#define I2S_24BITMUX_MODE_DMA_BOOTSEL 0x8
+
+/* ==========================================================================*/
+#define DAI_CLOCK_MASK 0x0000001f
+
+#define MAX_MCLK_IDX_NUM 15
+
+/* ==========================================================================*/
+#ifndef __ASSEMBLER__
+
+struct notifier_block;
+
+struct ambarella_i2s_interface {
+ u32 state;
+ u32 mode;
+ u32 clksrc;
+ u32 mclk;
+ u32 div;
+ u32 sfreq;
+ u32 channels;
+ u32 word_len;
+ u32 word_pos;
+ u32 slots;
+ u32 rx_ctrl;
+ u32 tx_ctrl;
+ u32 rx_fifo_len;
+ u32 tx_fifo_len;
+ u32 multi24;
+};
+
+enum Audio_Notify_Type
+{
+ AUDIO_NOTIFY_UNKNOWN,
+ AUDIO_NOTIFY_INIT,
+ AUDIO_NOTIFY_SETHWPARAMS,
+ AUDIO_NOTIFY_REMOVE
+};
+
+#define AMBARELLA_CLKSRC_ONCHIP 0x0
+#define AMBARELLA_CLKSRC_SP_CLK 0x1
+#define AMBARELLA_CLKSRC_CLK_SI 0x2
+#define AMBARELLA_CLKSRC_EXTERNAL 0x3
+#define AMBARELLA_CLKSRC_LVDS_IDSP_SCLK 0x4
+
+#define AMBARELLA_CLKDIV_LRCLK 0
+
+/* ==========================================================================*/
+extern int ambarella_init_audio(void);
+
+extern void ambarella_audio_notify_transition(
+ struct ambarella_i2s_interface *data, unsigned int type);
+extern int ambarella_audio_register_notifier(struct notifier_block *nb);
+extern int ambarella_audio_unregister_notifier(struct notifier_block *nb);
+
+extern struct ambarella_i2s_interface get_audio_i2s_interface(void);
+
+#endif /* __ASSEMBLER__ */
+/* ==========================================================================*/
+
+#endif /* __PLAT_AMBARELLA_AUDIO_H__ */
+
diff --git a/arch/arm/mach-ambarella/include/plat/chip.h b/arch/arm/mach-ambarella/include/plat/chip.h
new file mode 100644
index 00000000..64683e0c
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/chip.h
@@ -0,0 +1,83 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/chip.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2013, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_CHIP_H__
+#define __PLAT_AMBARELLA_CHIP_H__
+
+/* ==========================================================================*/
+#define A5S (5100)
+#define A7L (7500)
+#define A8 (8000)
+#define S2 (9000)
+#define S2E (9100)
+#define S2L (12000)
+#define S3 (11000)
+#define S3L (13000)
+#define S5 (15000)
+
+#define CHIP_ID(x) ((x / 1000))
+#define CHIP_MAJOR(x) ((x / 100) % 10)
+#define CHIP_MINOR(x) ((x / 10) % 10)
+
+#if defined(CONFIG_PLAT_AMBARELLA_A5S)
+#define CHIP_REV A5S
+#elif defined(CONFIG_PLAT_AMBARELLA_A7L)
+#define CHIP_REV A7L
+#elif defined(CONFIG_PLAT_AMBARELLA_S2)
+#define CHIP_REV S2
+#elif defined(CONFIG_PLAT_AMBARELLA_S2E)
+#define CHIP_REV S2E
+#elif defined(CONFIG_PLAT_AMBARELLA_A8)
+#define CHIP_REV A8
+#elif defined(CONFIG_PLAT_AMBARELLA_S2L)
+#define CHIP_REV S2L
+#elif defined(CONFIG_PLAT_AMBARELLA_S3)
+#define CHIP_REV S3
+#elif defined(CONFIG_PLAT_AMBARELLA_S3L)
+#define CHIP_REV S3L
+#elif defined(CONFIG_ARCH_AMBARELLA_S5)
+#define CHIP_REV S5
+#else
+#error "Undefined CHIP_REV"
+#endif
+
+/* ==========================================================================*/
+#if (CHIP_REV == A8)
+#define REF_CLK_FREQ 27000000
+#else
+#define REF_CLK_FREQ 24000000
+#endif
+
+/* ==========================================================================*/
+#if (CHIP_REV == A5S) || (CHIP_REV == A7L)
+#define CHIP_BROKEN_UNALIGNED_ACCESS 1
+#endif
+
+#if (CHIP_REV == S3)
+#define CHIP_FIX_2NDCORTEX_BOOT 1
+#endif
+
+/* ==========================================================================*/
+
+#endif /* __PLAT_AMBARELLA_CHIP_H__ */
+
diff --git a/arch/arm/mach-ambarella/include/plat/clk.h b/arch/arm/mach-ambarella/include/plat/clk.h
new file mode 100644
index 00000000..e4fcc820
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/clk.h
@@ -0,0 +1,261 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/clk.c
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_CLK_H__
+#define __PLAT_AMBARELLA_CLK_H__
+
+#include <plat/rct.h>
+
+/* ==========================================================================*/
+enum PLL_CLK_HZ {
+ PLL_CLK_10D1001MHZ = 9990010,
+ PLL_CLK_10MHZ = 10000000,
+ PLL_CLK_13D1001MHZ = 12987012,
+ PLL_CLK_13MHZ = 13000000,
+ PLL_CLK_13_5D1001MHZ = 13486513,
+ PLL_CLK_13_5MHZ = 13500000,
+ PLL_CLK_17_97515MHZ = 17975154,
+ PLL_CLK_17_97554MHZ = 17975544,
+ PLL_CLK_17_98201MHZ = 17982018,
+ PLL_CLK_18_44MHz = 18440000,
+ PLL_CLK_22_5MHZ = 22500000,
+ PLL_CLK_23_9772MHZ = 23977223,
+ PLL_CLK_23_9784MHZ = 23978422,
+ PLL_CLK_23_99MHZ = 23998277,
+ PLL_CLK_23_967MHZ = 23967392,
+ PLL_CLK_23_971MHZ = 23971444,
+ PLL_CLK_24D1001MHZ = 23976024,
+ PLL_CLK_23_996MHZ = 23996483,
+ PLL_CLK_24MHZ = 24000000,
+ PLL_CLK_24M1001MHZ = 24024000,
+ PLL_CLK_24_072MHZ = 24072001,
+ PLL_CLK_24_3MHZ = 24300000,
+ PLL_CLK_24_54MHZ = 24545430,
+ PLL_CLK_25MHZ = 25000000,
+ PLL_CLK_27D1001MHZ = 26973027,
+ PLL_CLK_26_9823MHZ = 26982318,
+ PLL_CLK_26_9485MHZ = 26948544,
+ PLL_CLK_26_9568MHZ = 26956800,
+ PLL_CLK_27MHZ = 27000000,
+ PLL_CLK_27_0432MHZ = 27043200,
+ PLL_CLK_27_0514MHZ = 27051402,
+ PLL_CLK_27M1001MHZ = 27027000,
+ PLL_CLK_30MHZ = 30000000,
+ PLL_CLK_27_1792MHZ = 27179210,
+ PLL_CLK_32_5D1001MHZ = 32467532,
+ PLL_CLK_36D1001MHZ = 35964036,
+ PLL_CLK_36MHZ = 36000000,
+ PLL_CLK_36_20MHZ = 36197802,
+ PLL_CLK_36_23MHZ = 36234000,
+ PLL_CLK_37_125D1001MHZ = 37087912,
+ PLL_CLK_37_125MHZ = 37125000,
+ PLL_CLK_42D1001MHZ = 41958042,
+ PLL_CLK_42MHZ = 42000000,
+ PLL_CLK_45MHZ = 45000000,
+ PLL_CLK_48D1001MHZ = 47952048,
+ PLL_CLK_48MHZ = 48000000,
+ PLL_CLK_48_6MHZ = 48600000,
+ PLL_CLK_49_5D1001MHZ = 49450549,
+ PLL_CLK_49_5MHZ = 49500000,
+ PLL_CLK_54MHZ = 54000000,
+ PLL_CLK_54M1001MHZ = 54054000,
+ PLL_CLK_59_4MHZ = 59400000,
+ PLL_CLK_60MHZ = 60000000,
+ PLL_CLK_60M1001MHZ = 60060000,
+ PLL_CLK_60_05MHz = 60054545,
+ PLL_CLK_60_16MHZ = 60164835,
+ PLL_CLK_60_18MHZ = 60183566,
+ PLL_CLK_60_29MHZ = 60285794,
+ PLL_CLK_60_33MHZ = 60329670,
+ PLL_CLK_60_35MHZ = 60346080,
+ PLL_CLK_60_39MHZ = 60390000,
+ PLL_CLK_60_48MHz = 60480000,
+ PLL_CLK_64D1001MHZ = 63936064,
+ PLL_CLK_64MHZ = 64000000,
+ PLL_CLK_65D1001MHZ = 64935064,
+ PLL_CLK_72D1001MHZ = 71928072,
+ PLL_CLK_72MHZ = 72000000,
+ PLL_CLK_74_25D1001MHZ = 74175824,
+ PLL_CLK_74_25MHZ = 74250000,
+ PLL_CLK_80MHZ = 80000000,
+ PLL_CLK_90D1001MHZ = 89910090,
+ PLL_CLK_90MHZ = 90000000,
+ PLL_CLK_90_62D1001MHZ = 90525314,
+ PLL_CLK_90_62MHZ = 90615840,
+ PLL_CLK_90_69D1001MHZ = 90596763,
+ PLL_CLK_90_69MHZ = 90687360,
+ PLL_CLK_95_993D1001MHZ = 95896903,
+ PLL_CLK_96D1001MHZ = 95904096,
+ PLL_CLK_96MHZ = 96000000,
+ PLL_CLK_99D1001MHZ = 98901099,
+ PLL_CLK_99MHZ = 99000000,
+ PLL_CLK_99_18D1001MHZ = 99081439,
+ PLL_CLK_99_18MHZ = 99180720,
+ PLL_CLK_108MHZ = 108000000,
+ PLL_CLK_148_5D1001MHZ = 148351648,
+ PLL_CLK_148_5MHZ = 148500000,
+ PLL_CLK_120MHZ = 120000000,
+ PLL_CLK_144MHZ = 144000000,
+ PLL_CLK_150MHZ = 150000000,
+ PLL_CLK_156MHZ = 156000000,
+ PLL_CLK_160MHZ = 160000000,
+ PLL_CLK_192MHZ = 192000000,
+ PLL_CLK_216MHZ = 216000000,
+ PLL_CLK_230_4MHZ = 230400000,
+ PLL_CLK_240MHZ = 240000000,
+ PLL_CLK_288MHZ = 288000000,
+ PLL_CLK_296_703MHZ = 296703000,
+ PLL_CLK_297MHZ = 297000000,
+ PLL_CLK_320MHZ = 320000000,
+ PLL_CLK_384MHZ = 384000000,
+ PLL_CLK_495MHZ = 495000000,
+ PLL_CLK_594MHZ = 594000000,
+};
+
+struct clk;
+struct clk_ops {
+ int (*enable)(struct clk *c);
+ int (*disable)(struct clk *c);
+ unsigned long (*get_rate)(struct clk *c);
+ unsigned long (*round_rate)(struct clk *c, unsigned long rate);
+ int (*set_rate)(struct clk *c, unsigned long rate);
+ int (*set_parent)(struct clk *c, struct clk *parent);
+};
+
+struct clk {
+ struct list_head list;
+ struct clk *parent;
+ const char *name;
+ u64 rate;
+ u32 frac_mode;
+ u32 ctrl_reg;
+ u32 pres_reg;
+ u32 pres_val;
+ u32 post_reg;
+ u32 post_val;
+ u32 frac_reg;
+ u32 ctrl2_reg;
+ u32 ctrl2_val;
+ u32 ctrl3_reg;
+ u32 ctrl3_val;
+ u32 lock_reg;
+ u32 lock_bit;
+ u32 divider;
+ u32 max_divider;
+ u32 extra_scaler;
+ struct pll_table *table;
+ u32 table_size;
+ struct clk_ops *ops;
+};
+
+struct pll_table {
+ u64 multiplier; /* pll_out / (ref_clk / pre_scaler) */
+
+ u32 intp;
+ u32 sdiv;
+ u32 sout;
+ u32 post;
+};
+
+union ctrl_reg_u {
+ struct {
+ u32 write_enable : 1; /* [0] */
+ u32 reserved1 : 1; /* [1] */
+ u32 bypass : 1; /* [2] */
+ u32 frac_mode : 1; /* [3] */
+ u32 force_reset : 1; /* [4] */
+ u32 power_down : 1; /* [5] */
+ u32 halt_vco : 1; /* [6] */
+ u32 tristate : 1; /* [7] */
+ u32 tout_async : 4; /* [11:8] */
+ u32 sdiv : 4; /* [15:12] */
+ u32 sout : 4; /* [19:16] */
+ u32 force_lock : 1; /* [20] */
+ u32 force_bypass : 1; /* [21] */
+ u32 reserved2 : 2; /* [23:22] */
+ u32 intp : 7; /* [30:24] */
+ u32 reserved3 : 1; /* [31] */
+ } s;
+ u32 w;
+};
+
+union frac_reg_u {
+ struct {
+ u32 frac : 31; /* [30:0] */
+ u32 nega : 1; /* [31] */
+ } s;
+ u32 w;
+};
+
+/* ==========================================================================*/
+#ifndef __ASSEMBLER__
+
+#define AMBCLK_DO_DIV(divident, divider) do { \
+ do_div((divident), (divider)); \
+ } while (0)
+
+#define AMBCLK_DO_DIV_ROUND(divident, divider) do { \
+ (divident) += ((divider) >> 1); \
+ do_div((divident), (divider)); \
+ } while (0)
+
+extern struct clk_ops ambarella_rct_pll_ops;
+extern struct clk_ops ambarella_rct_scaler_ops;
+
+#ifdef CONFIG_AMBARELLA_CALC_PLL
+#define AMBARELLA_PLL_FRAC_TABLE_SIZE (0)
+extern struct pll_table ambarella_pll_frac_table[AMBARELLA_PLL_FRAC_TABLE_SIZE];
+#define AMBARELLA_PLL_INT_TABLE_SIZE (0)
+extern struct pll_table ambarella_pll_int_table[AMBARELLA_PLL_INT_TABLE_SIZE];
+#else
+#define AMBARELLA_PLL_FRAC_TABLE_SIZE (590)
+extern struct pll_table ambarella_pll_frac_table[AMBARELLA_PLL_FRAC_TABLE_SIZE];
+#define AMBARELLA_PLL_INT_TABLE_SIZE (93)
+extern struct pll_table ambarella_pll_int_table[AMBARELLA_PLL_INT_TABLE_SIZE];
+#define AMBARELLA_PLL_VOUT_TABLE_SIZE (797)
+extern struct pll_table ambarella_pll_vout_table[AMBARELLA_PLL_VOUT_TABLE_SIZE];
+#define AMBARELLA_PLL_VOUT2_TABLE_SIZE (793)
+extern struct pll_table ambarella_pll_vout2_table[AMBARELLA_PLL_VOUT2_TABLE_SIZE];
+#endif
+
+extern u32 ambarella_rct_find_pll_table_index(unsigned long rate,
+ u32 pre_scaler, const struct pll_table *table, u32 table_size);
+
+extern unsigned long ambarella_rct_clk_get_rate(struct clk *c);
+extern int ambarella_rct_clk_set_rate(struct clk *c, unsigned long rate);
+extern int ambarella_rct_clk_adj_rate(struct clk *c, unsigned long rate);
+extern int ambarella_rct_clk_enable(struct clk *c);
+extern int ambarella_rct_clk_disable(struct clk *c);
+
+extern unsigned long ambarella_rct_scaler_get_rate(struct clk *c);
+extern int ambarella_rct_scaler_set_rate(struct clk *c, unsigned long rate);
+
+extern int ambarella_clk_init(void);
+extern int ambarella_clk_add(struct clk *clk);
+extern unsigned int ambarella_clk_get_ref_freq(void);
+
+#endif /* __ASSEMBLER__ */
+/* ==========================================================================*/
+
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/plat/cortex.h b/arch/arm/mach-ambarella/include/plat/cortex.h
new file mode 100644
index 00000000..4e84793d
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/cortex.h
@@ -0,0 +1,71 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/cortex.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_CORTEX_H
+#define __PLAT_AMBARELLA_CORTEX_H
+
+/* ==========================================================================*/
+#define AMBARELLA_VA_SCU_BASE (AXI_BASE + 0x00000000)
+#define AMBARELLA_VA_GIC_CPU_BASE (AXI_BASE + 0x00000100)
+#define AMBARELLA_VA_GT_BASE (AXI_BASE + 0x00000200)
+#define AMBARELLA_VA_PT_WD_BASE (AXI_BASE + 0x00000600)
+#define AMBARELLA_VA_GIC_DIST_BASE (AXI_BASE + 0x00001000)
+#define AMBARELLA_VA_L2CC_BASE (AXI_BASE + 0x00002000)
+
+#define AMBARELLA_PA_SCU_BASE (AXI_PHYS_BASE + 0x00000000)
+#define AMBARELLA_PA_GIC_CPU_BASE (AXI_PHYS_BASE + 0x00000100)
+#define AMBARELLA_PA_GT_BASE (AXI_PHYS_BASE + 0x00000200)
+#define AMBARELLA_PA_PT_WD_BASE (AXI_PHYS_BASE + 0x00000600)
+#define AMBARELLA_PA_GIC_DIST_BASE (AXI_PHYS_BASE + 0x00001000)
+#define AMBARELLA_PA_L2CC_BASE (AXI_PHYS_BASE + 0x00002000)
+
+/* ==========================================================================*/
+#define PROCESSOR_START_0 (0)
+#define PROCESSOR_START_1 (1)
+#define PROCESSOR_START_2 (2)
+#define PROCESSOR_START_3 (3)
+
+#define PROCESSOR_STATUS_0 (4)
+#define PROCESSOR_STATUS_1 (5)
+#define PROCESSOR_STATUS_2 (6)
+#define PROCESSOR_STATUS_3 (7)
+
+#define ICDISER0_MASK (8)
+#define INTDIS_LOCKER (9)
+#define INTDIS_STATUS (10)
+
+#define MACHINE_ID (11)
+#define ATAG_DATA (12)
+
+#define AMBARELLA_BST_HEAD_CACHE_SIZE (32)
+
+/* ==========================================================================*/
+#ifndef __ASSEMBLER__
+
+/* ==========================================================================*/
+
+#endif /* __ASSEMBLER__ */
+/* ==========================================================================*/
+
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/plat/cpufreq.h b/arch/arm/mach-ambarella/include/plat/cpufreq.h
new file mode 100644
index 00000000..998a3519
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/cpufreq.h
@@ -0,0 +1,36 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/cpufreq.h
+ *
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_CPUFREQ_H
+#define __PLAT_AMBARELLA_CPUFREQ_H
+
+#include <linux/cpufreq.h>
+
+struct ambarella_cpufreq_config {
+ struct cpufreq_frequency_table *freq_table;
+ int (*set_voltage) (unsigned int index);
+ int (*init) (void);
+ int (*exit) (void);
+};
+
+#endif
diff --git a/arch/arm/mach-ambarella/include/plat/crypto.h b/arch/arm/mach-ambarella/include/plat/crypto.h
new file mode 100644
index 00000000..002469d7
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/crypto.h
@@ -0,0 +1,342 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/crypto.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_CRYPTO_H__
+#define __PLAT_AMBARELLA_CRYPTO_H__
+
+/* ==========================================================================*/
+#if (CHIP_REV == A5S)
+#define CRYPT_UNIT_OFFSET 0x14000
+#define CRYPT_UNIT_BASE (AHB_BASE + CRYPT_UNIT_OFFSET)
+#else
+#define CRYPT_UNIT_OFFSET 0x20000
+#define CRYPT_UNIT_BASE (AXI_BASE + CRYPT_UNIT_OFFSET)
+#endif
+
+#define CRYPT_UNIT_REG(x) (CRYPT_UNIT_BASE + (x))
+
+#define DES_OFFSET(x) (x)
+#define AES_OFFSET(x) ((1 << 9) | (x))
+#define SHA1_MD5_OFFSET(x) ((2 << 9) | (x))
+
+#define DES_REG(x) CRYPT_UNIT_REG(DES_OFFSET(x))
+#define AES_REG(x) CRYPT_UNIT_REG(AES_OFFSET(x))
+#define SHA1_MD5_REG(x) CRYPT_UNIT_REG(SHA1_MD5_OFFSET(x))
+
+/* ==========================================================================*/
+
+/* AES/DES */
+
+
+#define CRYPT_D_HI_OFFSET 0x00
+#define CRYPT_D_LO_OFFSET 0x04
+#define CRYPT_D_INPUT_ENC_HI_OFFSET 0x08
+#define CRYPT_D_INPUT_ENC_LO_OFFSET 0x0c
+#define CRYPT_D_INPUT_DEC_HI_OFFSET 0x10
+#define CRYPT_D_INPUT_DEC_LO_OFFSET 0x14
+#define CRYPT_D_OUTPUT_HI_OFFSET 0x18
+#define CRYPT_D_OUTPUT_LO_OFFSET 0x1c
+#define CRYPT_D_OUTPUT_READY_OFFSET 0x20
+#define CRYPT_D_INT_EN_OFFSET 0x28
+
+#define CRYPT_A_256_224_OFFSET 0x00
+#define CRYPT_A_256_192_OFFSET 0x04
+#define CRYPT_A_256_160_OFFSET 0x08
+#define CRYPT_A_256_128_OFFSET 0x0c
+#define CRYPT_A_256_96_OFFSET 0x10
+#define CRYPT_A_256_64_OFFSET 0x14
+#define CRYPT_A_256_32_OFFSET 0x18
+#define CRYPT_A_256_0_OFFSET 0x1c
+#define CRYPT_A_192_160_OFFSET 0x20
+#define CRYPT_A_192_128_OFFSET 0x24
+#define CRYPT_A_192_96_OFFSET 0x28
+#define CRYPT_A_192_64_OFFSET 0x2c
+#define CRYPT_A_192_32_OFFSET 0x30
+#define CRYPT_A_192_0_OFFSET 0x34
+#define CRYPT_A_128_96_OFFSET 0x38
+#define CRYPT_A_128_64_OFFSET 0x3c
+#define CRYPT_A_128_32_OFFSET 0x40
+#define CRYPT_A_128_0_OFFSET 0x44
+
+#define CRYPT_A_INPUT_ENC_96_OFFSET 0x48
+#define CRYPT_A_INPUT_ENC_64_OFFSET 0x4c
+#define CRYPT_A_INPUT_ENC_32_OFFSET 0x50
+#define CRYPT_A_INPUT_ENC_0_OFFSET 0x54
+#define CRYPT_A_INPUT_DEC_96_OFFSET 0x58
+#define CRYPT_A_INPUT_DEC_64_OFFSET 0x5c
+#define CRYPT_A_INPUT_DEC_32_OFFSET 0x60
+#define CRYPT_A_INPUT_DEC_0_OFFSET 0x64
+#define CRYPT_A_OUTPUT_96_OFFSET 0x68
+#define CRYPT_A_OUTPUT_64_OFFSET 0x6c
+#define CRYPT_A_OUTPUT_32_OFFSET 0x70
+#define CRYPT_A_OUTPUT_0_OFFSET 0x74
+#define CRYPT_A_OUTPUT_READY_OFFSET 0x78
+#define CRYPT_A_INT_EN_OFFSET 0x80
+
+#define CRYPT_D_HI_REG DES_REG(0x00)
+#define CRYPT_D_LO_REG DES_REG(0x04)
+#define CRYPT_D_INPUT_ENC_HI_REG DES_REG(0x08)
+#define CRYPT_D_INPUT_ENC_LO_REG DES_REG(0x0c)
+#define CRYPT_D_INPUT_DEC_HI_REG DES_REG(0x10)
+#define CRYPT_D_INPUT_DEC_LO_REG DES_REG(0x14)
+#define CRYPT_D_OUTPUT_HI_REG DES_REG(0x18)
+#define CRYPT_D_OUTPUT_LO_REG DES_REG(0x1c)
+#define CRYPT_D_OUTPUT_READY_REG DES_REG(0x20)
+#define CRYPT_D_INT_EN_REG DES_REG(0x28)
+
+#define CRYPT_A_256_224_REG AES_REG(0x00)
+#define CRYPT_A_256_192_REG AES_REG(0x04)
+#define CRYPT_A_256_160_REG AES_REG(0x08)
+#define CRYPT_A_256_128_REG AES_REG(0x0c)
+#define CRYPT_A_256_96_REG AES_REG(0x10)
+#define CRYPT_A_256_64_REG AES_REG(0x14)
+#define CRYPT_A_256_32_REG AES_REG(0x18)
+#define CRYPT_A_256_0_REG AES_REG(0x1c)
+#define CRYPT_A_192_160_REG AES_REG(0x20)
+#define CRYPT_A_192_128_REG AES_REG(0x24)
+#define CRYPT_A_192_96_REG AES_REG(0x28)
+#define CRYPT_A_192_64_REG AES_REG(0x2c)
+#define CRYPT_A_192_32_REG AES_REG(0x30)
+#define CRYPT_A_192_0_REG AES_REG(0x34)
+#define CRYPT_A_128_96_REG AES_REG(0x38)
+#define CRYPT_A_128_64_REG AES_REG(0x3c)
+#define CRYPT_A_128_32_REG AES_REG(0x40)
+#define CRYPT_A_128_0_REG AES_REG(0x44)
+
+#define CRYPT_A_INPUT_ENC_96_REG AES_REG(0x48)
+#define CRYPT_A_INPUT_ENC_64_REG AES_REG(0x4c)
+#define CRYPT_A_INPUT_ENC_32_REG AES_REG(0x50)
+#define CRYPT_A_INPUT_ENC_0_REG AES_REG(0x54)
+#define CRYPT_A_INPUT_DEC_96_REG AES_REG(0x58)
+#define CRYPT_A_INPUT_DEC_64_REG AES_REG(0x5c)
+#define CRYPT_A_INPUT_DEC_32_REG AES_REG(0x60)
+#define CRYPT_A_INPUT_DEC_0_REG AES_REG(0x64)
+#define CRYPT_A_OUTPUT_96_REG AES_REG(0x68)
+#define CRYPT_A_OUTPUT_64_REG AES_REG(0x6c)
+#define CRYPT_A_OUTPUT_32_REG AES_REG(0x70)
+#define CRYPT_A_OUTPUT_0_REG AES_REG(0x74)
+#define CRYPT_A_OUTPUT_READY_REG AES_REG(0x78)
+#define CRYPT_A_INT_EN_REG AES_REG(0x80)
+
+
+/* ==========================================================================*/
+
+/* SHA1/MD5 */
+
+#define CRYPT_SHA1_INIT_31_0_OFFSET SHA1_MD5_OFFSET(0x0)
+#define CRYPT_SHA1_INIT_63_32_OFFSET SHA1_MD5_OFFSET(0x4)
+#define CRYPT_SHA1_INIT_95_64_OFFSET SHA1_MD5_OFFSET(0x8)
+#define CRYPT_SHA1_INIT_127_96_OFFSET SHA1_MD5_OFFSET(0xc)
+#define CRYPT_SHA1_INIT_159_128_OFFSET SHA1_MD5_OFFSET(0x10)
+#define CRYPT_SHA1_INPUT_31_0_OFFSET SHA1_MD5_OFFSET(0x18)
+#define CRYPT_SHA1_INPUT_63_32_OFFSET SHA1_MD5_OFFSET(0x1c)
+#define CRYPT_SHA1_INPUT_95_64_OFFSET SHA1_MD5_OFFSET(0x20)
+#define CRYPT_SHA1_INPUT_127_96_OFFSET SHA1_MD5_OFFSET(0x24)
+#define CRYPT_SHA1_INPUT_159_128_OFFSET SHA1_MD5_OFFSET(0x28)
+#define CRYPT_SHA1_INPUT_191_160_OFFSET SHA1_MD5_OFFSET(0x2c)
+#define CRYPT_SHA1_INPUT_223_192_OFFSET SHA1_MD5_OFFSET(0x30)
+#define CRYPT_SHA1_INPUT_255_224_OFFSET SHA1_MD5_OFFSET(0x34)
+#define CRYPT_SHA1_INPUT_287_256_OFFSET SHA1_MD5_OFFSET(0x38)
+#define CRYPT_SHA1_INPUT_319_288_OFFSET SHA1_MD5_OFFSET(0x3c)
+#define CRYPT_SHA1_INPUT_351_320_OFFSET SHA1_MD5_OFFSET(0x40)
+#define CRYPT_SHA1_INPUT_383_352_OFFSET SHA1_MD5_OFFSET(0x44)
+#define CRYPT_SHA1_INPUT_415_384_OFFSET SHA1_MD5_OFFSET(0x48)
+#define CRYPT_SHA1_INPUT_447_416_OFFSET SHA1_MD5_OFFSET(0x4c)
+#define CRYPT_SHA1_INPUT_479_448_OFFSET SHA1_MD5_OFFSET(0x50)
+#define CRYPT_SHA1_INPUT_511_480_OFFSET SHA1_MD5_OFFSET(0x54)
+#define CRYPT_SHA1_OUTPUT_31_0_OFFSET SHA1_MD5_OFFSET(0x58)
+#define CRYPT_SHA1_OUTPUT_63_32_OFFSET SHA1_MD5_OFFSET(0x5c)
+#define CRYPT_SHA1_OUTPUT_95_64_OFFSET SHA1_MD5_OFFSET(0x60)
+#define CRYPT_SHA1_OUTPUT_127_96_OFFSET SHA1_MD5_OFFSET(0x64)
+#define CRYPT_SHA1_OUTPUT_159_128_OFFSET SHA1_MD5_OFFSET(0x68)
+#define CRYPT_SHA1_OUTPUT_READY_OFFSET SHA1_MD5_OFFSET(0x70)
+#define CRYPT_SHA1_INT_EN_OFFSET SHA1_MD5_OFFSET(0x78)
+#define CRYPT_MD5_INIT_31_0_OFFSET SHA1_MD5_OFFSET(0x80)
+#define CRYPT_MD5_INIT_63_32_OFFSET SHA1_MD5_OFFSET(0x84)
+#define CRYPT_MD5_INIT_95_64_OFFSET SHA1_MD5_OFFSET(0x88)
+#define CRYPT_MD5_INIT_127_96_OFFSET SHA1_MD5_OFFSET(0x8c)
+#define CRYPT_MD5_INPUT_31_0_OFFSET SHA1_MD5_OFFSET(0x90)
+#define CRYPT_MD5_INPUT_63_32_OFFSET SHA1_MD5_OFFSET(0x94)
+#define CRYPT_MD5_INPUT_95_64_OFFSET SHA1_MD5_OFFSET(0x98)
+#define CRYPT_MD5_INPUT_127_96_OFFSET SHA1_MD5_OFFSET(0x9c)
+#define CRYPT_MD5_INPUT_159_128_OFFSET SHA1_MD5_OFFSET(0xa0)
+#define CRYPT_MD5_INPUT_191_160_OFFSET SHA1_MD5_OFFSET(0xa4)
+#define CRYPT_MD5_INPUT_223_192_OFFSET SHA1_MD5_OFFSET(0xa8)
+#define CRYPT_MD5_INPUT_255_224_OFFSET SHA1_MD5_OFFSET(0xac)
+#define CRYPT_MD5_INPUT_287_256_OFFSET SHA1_MD5_OFFSET(0xb0)
+#define CRYPT_MD5_INPUT_319_288_OFFSET SHA1_MD5_OFFSET(0xb4)
+#define CRYPT_MD5_INPUT_351_320_OFFSET SHA1_MD5_OFFSET(0xb8)
+#define CRYPT_MD5_INPUT_383_352_OFFSET SHA1_MD5_OFFSET(0xbc)
+#define CRYPT_MD5_INPUT_415_384_OFFSET SHA1_MD5_OFFSET(0xc0)
+#define CRYPT_MD5_INPUT_447_416_OFFSET SHA1_MD5_OFFSET(0xc4)
+#define CRYPT_MD5_INPUT_479_448_OFFSET SHA1_MD5_OFFSET(0xc8)
+#define CRYPT_MD5_INPUT_511_480_OFFSET SHA1_MD5_OFFSET(0xcc)
+#define CRYPT_MD5_OUTPUT_31_0_OFFSET SHA1_MD5_OFFSET(0xd0)
+#define CRYPT_MD5_OUTPUT_63_32_OFFSET SHA1_MD5_OFFSET(0xd4)
+#define CRYPT_MD5_OUTPUT_95_64_OFFSET SHA1_MD5_OFFSET(0xd8)
+#define CRYPT_MD5_OUTPUT_127_96_OFFSET SHA1_MD5_OFFSET(0xdc)
+#define CRYPT_MD5_OUTPUT_READY_OFFSET SHA1_MD5_OFFSET(0xe0)
+#define CRYPT_MD5_INT_EN_OFFSET SHA1_MD5_OFFSET(0xe8)
+#define CRYPT_MD5_SHA1_READY_INPUT_OFFSET SHA1_MD5_OFFSET(0xf0)
+
+#define CRYPT_SHA1_INIT_31_0_REG SHA1_MD5_REG(0x0)
+#define CRYPT_SHA1_INIT_63_32_REG SHA1_MD5_REG(0x4)
+#define CRYPT_SHA1_INIT_95_64_REG SHA1_MD5_REG(0x8)
+#define CRYPT_SHA1_INIT_127_96_REG SHA1_MD5_REG(0xc)
+#define CRYPT_SHA1_INIT_159_128_REG SHA1_MD5_REG(0x10)
+#define CRYPT_SHA1_INPUT_31_0_REG SHA1_MD5_REG(0x18)
+#define CRYPT_SHA1_INPUT_63_32_REG SHA1_MD5_REG(0x1c)
+#define CRYPT_SHA1_INPUT_95_64_REG SHA1_MD5_REG(0x20)
+#define CRYPT_SHA1_INPUT_127_96_REG SHA1_MD5_REG(0x24)
+#define CRYPT_SHA1_INPUT_159_128_REG SHA1_MD5_REG(0x28)
+#define CRYPT_SHA1_INPUT_191_160_REG SHA1_MD5_REG(0x2c)
+#define CRYPT_SHA1_INPUT_223_192_REG SHA1_MD5_REG(0x30)
+#define CRYPT_SHA1_INPUT_255_224_REG SHA1_MD5_REG(0x34)
+#define CRYPT_SHA1_INPUT_287_256_REG SHA1_MD5_REG(0x38)
+#define CRYPT_SHA1_INPUT_319_288_REG SHA1_MD5_REG(0x3c)
+#define CRYPT_SHA1_INPUT_351_320_REG SHA1_MD5_REG(0x40)
+#define CRYPT_SHA1_INPUT_383_352_REG SHA1_MD5_REG(0x44)
+#define CRYPT_SHA1_INPUT_415_384_REG SHA1_MD5_REG(0x48)
+#define CRYPT_SHA1_INPUT_447_416_REG SHA1_MD5_REG(0x4c)
+#define CRYPT_SHA1_INPUT_479_448_REG SHA1_MD5_REG(0x50)
+#define CRYPT_SHA1_INPUT_511_480_REG SHA1_MD5_REG(0x54)
+#define CRYPT_SHA1_OUTPUT_31_0_REG SHA1_MD5_REG(0x58)
+#define CRYPT_SHA1_OUTPUT_63_32_REG SHA1_MD5_REG(0x5c)
+#define CRYPT_SHA1_OUTPUT_95_64_REG SHA1_MD5_REG(0x60)
+#define CRYPT_SHA1_OUTPUT_127_96_REG SHA1_MD5_REG(0x64)
+#define CRYPT_SHA1_OUTPUT_159_128_REG SHA1_MD5_REG(0x68)
+#define CRYPT_SHA1_OUTPUT_READY_REG SHA1_MD5_REG(0x70)
+#define CRYPT_SHA1_INT_EN_REG SHA1_MD5_REG(0x78)
+#define CRYPT_MD5_INIT_31_0_REG SHA1_MD5_REG(0x80)
+#define CRYPT_MD5_INIT_63_32_REG SHA1_MD5_REG(0x84)
+#define CRYPT_MD5_INIT_95_64_REG SHA1_MD5_REG(0x88)
+#define CRYPT_MD5_INIT_127_96_REG SHA1_MD5_REG(0x8c)
+#define CRYPT_MD5_INPUT_31_0_REG SHA1_MD5_REG(0x90)
+#define CRYPT_MD5_INPUT_63_32_REG SHA1_MD5_REG(0x94)
+#define CRYPT_MD5_INPUT_95_64_REG SHA1_MD5_REG(0x98)
+#define CRYPT_MD5_INPUT_127_96_REG SHA1_MD5_REG(0x9c)
+#define CRYPT_MD5_INPUT_159_128_REG SHA1_MD5_REG(0xa0)
+#define CRYPT_MD5_INPUT_191_160_REG SHA1_MD5_REG(0xa4)
+#define CRYPT_MD5_INPUT_223_192_REG SHA1_MD5_REG(0xa8)
+#define CRYPT_MD5_INPUT_255_224_REG SHA1_MD5_REG(0xac)
+#define CRYPT_MD5_INPUT_287_256_REG SHA1_MD5_REG(0xb0)
+#define CRYPT_MD5_INPUT_319_288_REG SHA1_MD5_REG(0xb4)
+#define CRYPT_MD5_INPUT_351_320_REG SHA1_MD5_REG(0xb8)
+#define CRYPT_MD5_INPUT_383_352_REG SHA1_MD5_REG(0xbc)
+#define CRYPT_MD5_INPUT_415_384_REG SHA1_MD5_REG(0xc0)
+#define CRYPT_MD5_INPUT_447_416_REG SHA1_MD5_REG(0xc4)
+#define CRYPT_MD5_INPUT_479_448_REG SHA1_MD5_REG(0xc8)
+#define CRYPT_MD5_INPUT_511_480_REG SHA1_MD5_REG(0xcc)
+#define CRYPT_MD5_OUTPUT_31_0_REG SHA1_MD5_REG(0xd0)
+#define CRYPT_MD5_OUTPUT_63_32_REG SHA1_MD5_REG(0xd4)
+#define CRYPT_MD5_OUTPUT_95_64_REG SHA1_MD5_REG(0xd8)
+#define CRYPT_MD5_OUTPUT_127_96_REG SHA1_MD5_REG(0xdc)
+#define CRYPT_MD5_OUTPUT_READY_REG SHA1_MD5_REG(0xe0)
+#define CRYPT_MD5_INT_EN_REG SHA1_MD5_REG(0xe8)
+#define CRYPT_MD5_SHA1_READY_INPUT_REG SHA1_MD5_REG(0xf0)
+
+/* ==========================================================================*/
+#define AMBARELLA_CRYPTO_ALIGNMENT (16)
+#define AMBARELLA_CRA_PRIORITY (300)
+#define AMBARELLA_COMPOSITE_PRIORITY (400)
+
+#define AMBA_HW_ENCRYPT_CMD (0)
+#define AMBA_HW_DECRYPT_CMD (1)
+
+/* ==========================================================================*/
+#ifndef __ASSEMBLER__
+
+#define CRYPT_A_INPUT1 CRYPT_A_INPUT_ENC_96_REG
+#define CRYPT_A_INPUT2 CRYPT_A_INPUT_DEC_96_REG
+#define CRYPT_A_OPCODE NULL
+#define CRYPT_D_INPUT1 CRYPT_D_INPUT_ENC_HI_REG
+#define CRYPT_D_INPUT2 CRYPT_D_INPUT_DEC_HI_REG
+#define CRYPT_D_OPCODE NULL
+
+#define CRYPT_MD5_SHA1_READY_INPUT CRYPT_MD5_SHA1_READY_INPUT_REG
+#define CRYPT_MD5_INIT_31_0 CRYPT_MD5_INIT_31_0_REG
+#define CRYPT_MD5_INPUT_31_0 CRYPT_MD5_INPUT_31_0_REG
+#define CRYPT_MD5_OUTPUT_READY CRYPT_MD5_OUTPUT_READY_REG
+#define CRYPT_MD5_OUTPUT_31_0 CRYPT_MD5_OUTPUT_31_0_REG
+#define CRYPT_SHA1_INIT_31_0 CRYPT_SHA1_INIT_31_0_REG
+#define CRYPT_SHA1_INPUT_31_0 CRYPT_SHA1_INPUT_31_0_REG
+#define CRYPT_SHA1_OUTPUT_READY CRYPT_SHA1_OUTPUT_READY_REG
+#define CRYPT_SHA1_OUTPUT_31_0 CRYPT_SHA1_OUTPUT_31_0_REG
+#define CRYPT_MD5_INT_EN CRYPT_MD5_INT_EN_REG
+#define CRYPT_SHA1_INT_EN CRYPT_SHA1_INT_EN_REG
+
+#define INDEPENDENT_MD5 1
+
+typedef struct md5_digest_s
+{
+ u32 digest_0;
+ u32 digest_32;
+
+ u32 digest_64;
+ u32 digest_96;
+
+ u32 digest_128;
+ u32 digest_160;
+
+ u32 digest_192;
+ u32 digest_224;
+
+ u32 digest_256;
+ u32 digest_288;
+
+ u32 digest_320;
+ u32 digest_352;
+
+ u32 digest_384;
+ u32 digest_416;
+
+ u32 digest_448;
+ u32 digest_480;
+} md5_digest_t;
+
+typedef struct md5_data_s
+{
+ u32 data[16];
+} md5_data_t;
+
+typedef struct sha1_digest_s
+{
+ u32 digest_0;
+ u32 digest_32;
+ u32 digest_64;
+ u32 digest_96;
+ u32 digest_128;
+ u32 digest_padding;
+
+} sha1_digest_t;
+
+typedef struct sha1_data_s
+{
+ u32 data[16];
+} sha1_data_t;
+
+#endif /* __ASSEMBLER__ */
+/* ==========================================================================*/
+
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/plat/dma.h b/arch/arm/mach-ambarella/include/plat/dma.h
new file mode 100644
index 00000000..0833aa6e
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/dma.h
@@ -0,0 +1,231 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/dma.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_DMA_H__
+#define __PLAT_AMBARELLA_DMA_H__
+
+/* ==========================================================================*/
+#if (CHIP_REV == A5S) || (CHIP_REV == A7L)
+#define NUM_DMA_CHANNELS 4
+#elif (CHIP_REV == S2)
+#define NUM_DMA_CHANNELS 5
+#else
+#define NUM_DMA_CHANNELS 8
+#endif
+
+#define DMA_OFFSET 0x5000
+#define DMA_BASE (AHB_BASE + DMA_OFFSET)
+#define DMA_REG(x) (DMA_BASE + (x))
+
+#define FDMA_OFFSET 0x12000
+#define FDMA_BASE (AHB_BASE + FDMA_OFFSET)
+#define FDMA_REG(x) (FDMA_BASE + (x))
+
+/* ==========================================================================*/
+
+#define INVALID_DMA_CHAN 0xFF
+
+#if (CHIP_REV == S2L)
+#define NOR_SPI_TX_DMA_CHAN 0 /* share with SSI0 */
+#define NOR_SPI_RX_DMA_CHAN 1 /* share with SSI0 */
+#define SSI1_TX_DMA_CHAN 2
+#define SSI1_RX_DMA_CHAN 3
+#define UART_TX_DMA_CHAN 4 /* share with SSIS0 */
+#define UART_RX_DMA_CHAN 5 /* share with SSIS0 */
+#define I2S_RX_DMA_CHAN 6
+#define I2S_TX_DMA_CHAN 7
+/* non-existed dma channel */
+#define MS_AHB_SSI_TX_DMA_CHAN INVALID_DMA_CHAN
+#define SPDIF_AHB_SSI_DMA_CHAN INVALID_DMA_CHAN
+#define SLIM_TX_DMA_CHAN INVALID_DMA_CHAN
+#define SLIM_RX_DMA_CHAN INVALID_DMA_CHAN
+
+#elif (CHIP_REV == S3) || (CHIP_REV == S3L)
+#define NOR_SPI_TX_DMA_CHAN 0
+#define NOR_SPI_RX_DMA_CHAN 1
+#define SSI1_TX_DMA_CHAN 2
+#define SSI1_RX_DMA_CHAN 3
+#define UART_TX_DMA_CHAN 4
+#define UART_RX_DMA_CHAN 5
+#define I2S_RX_DMA_CHAN 6
+#define I2S_TX_DMA_CHAN 7
+
+#elif (CHIP_REV == S2E)
+#define NOR_SPI_TX_DMA_CHAN 0
+#define I2S_RX_DMA_CHAN 1
+#define I2S_TX_DMA_CHAN 2
+#define I2S1_RX_DMA_CHAN 3
+#define I2S1_TX_DMA_CHAN 4
+#define UART_RX_DMA_CHAN 5
+#define UART_TX_DMA_CHAN 6
+#define NOR_SPI_RX_DMA_CHAN 7
+/* non-existed dma channel */
+#define SSI1_TX_DMA_CHAN INVALID_DMA_CHAN
+#define SSI1_RX_DMA_CHAN INVALID_DMA_CHAN
+
+#else
+#define I2S_RX_DMA_CHAN 1
+#define I2S_TX_DMA_CHAN 2
+#define MS_AHB_SSI_TX_DMA_CHAN 3
+#define SPDIF_AHB_SSI_DMA_CHAN 4
+/* non-existed dma channel */
+#define NOR_SPI_TX_DMA_CHAN INVALID_DMA_CHAN
+#define NOR_SPI_RX_DMA_CHAN INVALID_DMA_CHAN
+#define SSI1_TX_DMA_CHAN INVALID_DMA_CHAN
+#define SSI1_RX_DMA_CHAN INVALID_DMA_CHAN
+#define UART_TX_DMA_CHAN INVALID_DMA_CHAN
+#define UART_RX_DMA_CHAN INVALID_DMA_CHAN
+#define SLIM_TX_DMA_CHAN INVALID_DMA_CHAN
+#define SLIM_RX_DMA_CHAN INVALID_DMA_CHAN
+
+#endif
+
+/* ==========================================================================*/
+#define DMA_CHAN_CTR_REG(x) DMA_REG((0x300 + ((x) << 4)))
+#define DMA_CHAN_SRC_REG(x) DMA_REG((0x304 + ((x) << 4)))
+#define DMA_CHAN_DST_REG(x) DMA_REG((0x308 + ((x) << 4)))
+#define DMA_CHAN_STA_REG(x) DMA_REG((0x30c + ((x) << 4)))
+#define DMA_CHAN_DA_REG(x) DMA_REG((0x380 + ((x) << 2)))
+
+/* ==========================================================================*/
+
+#define FDMA_CHAN_CTR_REG(x) FDMA_REG((0x300 + ((x) << 4)))
+#define FDMA_CHAN_SRC_REG(x) FDMA_REG((0x304 + ((x) << 4)))
+#define FDMA_CHAN_DST_REG(x) FDMA_REG((0x308 + ((x) << 4)))
+#define FDMA_CHAN_STA_REG(x) FDMA_REG((0x30c + ((x) << 4)))
+#define FDMA_CHAN_DA_REG(x) FDMA_REG((0x380 + ((x) << 2)))
+#define FDMA_CHAN_DSM_CTR_REG(x) FDMA_REG((0x3a0 + ((x) << 4)))
+
+#define FDMA_CHAN_SPR_CNT_REG(x) FDMA_REG((0x200 + ((x) << 4)))
+#define FDMA_CHAN_SPR_SRC_REG(x) FDMA_REG((0x204 + ((x) << 4)))
+#define FDMA_CHAN_SPR_DST_REG(x) FDMA_REG((0x208 + ((x) << 4)))
+#define FDMA_CHAN_SPR_STA_REG(x) FDMA_REG((0x20c + ((x) << 4)))
+#define FDMA_CHAN_SPR_DA_REG(x) FDMA_REG((0x280 + ((x) << 2)))
+
+/* ==========================================================================*/
+
+#define DMA_INT_OFFSET 0x3f0
+#define DMA_PAUSE_SET_OFFSET 0x3f4
+#define DMA_PAUSE_CLR_OFFSET 0x3f8
+#define DMA_EARLY_END_OFFSET 0x3fc
+
+/* ==========================================================================*/
+
+/* DMA_CHANX_CTR_REG */
+#define DMA_CHANX_CTR_EN 0x80000000
+#define DMA_CHANX_CTR_D 0x40000000
+#define DMA_CHANX_CTR_WM 0x20000000
+#define DMA_CHANX_CTR_RM 0x10000000
+#define DMA_CHANX_CTR_NI 0x08000000
+#define DMA_CHANX_CTR_BLK_1024B 0x07000000
+#define DMA_CHANX_CTR_BLK_512B 0x06000000
+#define DMA_CHANX_CTR_BLK_256B 0x05000000
+#define DMA_CHANX_CTR_BLK_128B 0x04000000
+#define DMA_CHANX_CTR_BLK_64B 0x03000000
+#define DMA_CHANX_CTR_BLK_32B 0x02000000
+#define DMA_CHANX_CTR_BLK_16B 0x01000000
+#define DMA_CHANX_CTR_BLK_8B 0x00000000
+#define DMA_CHANX_CTR_TS_8B 0x00C00000
+#define DMA_CHANX_CTR_TS_4B 0x00800000
+#define DMA_CHANX_CTR_TS_2B 0x00400000
+#define DMA_CHANX_CTR_TS_1B 0x00000000
+
+/* DMA descriptor bit fields */
+#define DMA_DESC_EOC 0x01000000
+#define DMA_DESC_WM 0x00800000
+#define DMA_DESC_RM 0x00400000
+#define DMA_DESC_NI 0x00200000
+#define DMA_DESC_TS_8B 0x00180000
+#define DMA_DESC_TS_4B 0x00100000
+#define DMA_DESC_TS_2B 0x00080000
+#define DMA_DESC_TS_1B 0x00000000
+#define DMA_DESC_BLK_1024B 0x00070000
+#define DMA_DESC_BLK_512B 0x00060000
+#define DMA_DESC_BLK_256B 0x00050000
+#define DMA_DESC_BLK_128B 0x00040000
+#define DMA_DESC_BLK_64B 0x00030000
+#define DMA_DESC_BLK_32B 0x00020000
+#define DMA_DESC_BLK_16B 0x00010000
+#define DMA_DESC_BLK_8B 0x00000000
+#define DMA_DESC_ID 0x00000004
+#define DMA_DESC_IE 0x00000002
+#define DMA_DESC_ST 0x00000001
+
+/* DMA_CHANX_STA_REG */
+#define DMA_CHANX_STA_DM 0x80000000
+#define DMA_CHANX_STA_OE 0x40000000
+#define DMA_CHANX_STA_DA 0x20000000
+#define DMA_CHANX_STA_DD 0x10000000
+#define DMA_CHANX_STA_OD 0x08000000
+#define DMA_CHANX_STA_ME 0x04000000
+#define DMA_CHANX_STA_BE 0x02000000
+#define DMA_CHANX_STA_RWE 0x01000000
+#define DMA_CHANX_STA_AE 0x00800000
+#define DMA_CHANX_STA_DN 0x00400000
+
+/* DMA_INT_REG */
+#define DMA_INT_CHAN(x) (0x1 << (x))
+
+#define DMA_INT_CHAN4 0x00000010
+#define DMA_INT_CHAN3 0x00000008
+#define DMA_INT_CHAN2 0x00000004
+#define DMA_INT_CHAN1 0x00000002
+#define DMA_INT_CHAN0 0x00000001
+
+/* DMA_DUAL_SPACE_MODE_REG */
+#define DMA_DSM_EN 0x80000000
+#define DMA_DSM_MAJP_2KB 0x00000090
+#define DMA_DSM_SPJP_64B 0x00000004
+#define DMA_DSM_SPJP_128B 0x00000005
+
+#if (CHIP_REV == S3) || (CHIP_REV == S2E) || (CHIP_REV == S3L)
+#define DMA_NODC_MN_BURST_SIZE (DMA_CHANX_CTR_BLK_512B | DMA_CHANX_CTR_TS_8B)
+#define DMA_NODC_SP_BURST_SIZE (DMA_CHANX_CTR_BLK_16B | DMA_CHANX_CTR_TS_8B)
+#define DMA_DESC_MN_BURST_SIZE (DMA_DESC_BLK_512B | DMA_DESC_TS_8B)
+#define DMA_DESC_SP_BURST_SIZE (DMA_DESC_BLK_16B | DMA_DESC_TS_8B)
+#define DMA_NODC_MN_BURST_SIZE8 (DMA_CHANX_CTR_BLK_512B | DMA_CHANX_CTR_TS_8B)
+#define FIO_MN_BURST_SIZE (FIO_DMACTR_BLK_512B | FIO_DMACTR_TS8B)
+#define FIO_SP_BURST_SIZE (FIO_DMACTR_BLK_16B | FIO_DMACTR_TS8B)
+#define FIO_MN_BURST_SIZE8 (FIO_DMACTR_BLK_512B | FIO_DMACTR_TS8B)
+#else
+#define DMA_NODC_MN_BURST_SIZE (DMA_CHANX_CTR_BLK_512B | DMA_CHANX_CTR_TS_4B)
+#define DMA_NODC_SP_BURST_SIZE (DMA_CHANX_CTR_BLK_16B | DMA_CHANX_CTR_TS_4B)
+#define DMA_DESC_MN_BURST_SIZE (DMA_DESC_BLK_512B | DMA_DESC_TS_4B)
+#define DMA_DESC_SP_BURST_SIZE (DMA_DESC_BLK_16B | DMA_DESC_TS_4B)
+#define DMA_NODC_MN_BURST_SIZE8 (DMA_CHANX_CTR_BLK_512B | DMA_CHANX_CTR_TS_8B)
+#define FIO_MN_BURST_SIZE (FIO_DMACTR_BLK_512B | FIO_DMACTR_TS4B)
+#define FIO_SP_BURST_SIZE (FIO_DMACTR_BLK_16B | FIO_DMACTR_TS4B)
+#define FIO_MN_BURST_SIZE8 (FIO_DMACTR_BLK_512B | FIO_DMACTR_TS8B)
+#endif
+
+/* ==========================================================================*/
+#ifndef __ASSEMBLER__
+
+extern int ambarella_dma_channel_id(void *chan);
+
+#endif /* __ASSEMBLER__ */
+
+/* ==========================================================================*/
+
+#endif /* __PLAT_AMBARELLA_DMA_H__ */
+
diff --git a/arch/arm/mach-ambarella/include/plat/drctl.h b/arch/arm/mach-ambarella/include/plat/drctl.h
new file mode 100644
index 00000000..5d088e17
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/drctl.h
@@ -0,0 +1,54 @@
+/*
+ * ambhw/drctl.h
+ *
+ * History:
+ * 2007/01/27 - [Charles Chiou] created file
+ *
+ * Copyright 2008-2015 Ambarella Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __AMBHW__DRCTRL_H__
+#define __AMBHW__DRCTRL_H__
+
+#if (CHIP_REV == A5S) || (CHIP_REV == S2)
+#define DRAM_DRAM_OFFSET 0x4000
+#define DRAM_DDRC_OFFSET DRAM_DRAM_OFFSET
+#else
+#define DRAM_DRAM_OFFSET 0x0000
+#define DRAM_DDRC_OFFSET 0x0800
+#endif
+
+#define DDRC_REG(x) (DRAMC_BASE + DRAM_DDRC_OFFSET + (x))
+#define DRAM_REG(x) (DRAMC_BASE + DRAM_DRAM_OFFSET + (x))
+
+/* ==========================================================================*/
+#define DDRC_CTL_OFFSET (0x00)
+#define DDRC_CFG_OFFSET (0x04)
+#define DDRC_TIMING1_OFFSET (0x08)
+#define DDRC_TIMING2_OFFSET (0x0C)
+#define DDRC_TIMING3_OFFSET (0x10)
+#define DDRC_INIT_CTL_OFFSET (0x14)
+#define DDRC_MODE_OFFSET (0x18)
+#define DDRC_SELF_REF_OFFSET (0x1C)
+#define DDRC_DQS_SYNC_OFFSET (0x20)
+#define DDRC_PAD_ZCTL_OFFSET (0x24)
+#define DDRC_ZQ_CALIB_OFFSET (0x28)
+#define DDRC_RSVD_SPACE_OFFSET (0x2C)
+#define DDRC_BYTE_MAP_OFFSET (0x30)
+#define DDRC_DDR3PLUS_BNKGRP_OFFSET (0x34)
+#define DDRC_POWER_DOWN_OFFSET (0x38)
+#define DDRC_DLL_CALIB_OFFSET (0x3C)
+#define DDRC_DEBUG1_OFFSET (0x40)
+
+/* ==========================================================================*/
+#endif /* __AMBHW__DRCTRL_H__ */
+
diff --git a/arch/arm/mach-ambarella/include/plat/eth.h b/arch/arm/mach-ambarella/include/plat/eth.h
new file mode 100644
index 00000000..7764ca52
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/eth.h
@@ -0,0 +1,440 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/eth.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_ETH_H__
+#define __PLAT_AMBARELLA_ETH_H__
+
+/* ==========================================================================*/
+#if (CHIP_REV == A7L)
+#define ETH_INSTANCES 0
+#else
+#define ETH_INSTANCES 1
+#endif
+
+#if (CHIP_REV == S2) || (CHIP_REV == S2E) || (CHIP_REV == A8)
+#define SUPPORT_GMII 1
+#else
+#define SUPPORT_GMII 0
+#endif
+
+#if (CHIP_REV == S3)
+#define ETH_ENHANCED 1
+struct ambeth_desc {
+ u32 status;
+ u32 length;
+ u32 buffer1;
+ u32 buffer2;
+ u32 des4;
+ u32 des5;
+ u32 des6;
+ u32 des7;
+} __attribute((packed));
+#else
+#define ETH_ENHANCED 0
+struct ambeth_desc {
+ u32 status;
+ u32 length;
+ u32 buffer1;
+ u32 buffer2;
+} __attribute((packed));
+#endif
+/* ==========================================================================*/
+#define ETH_OFFSET 0xE000
+#define ETH_DMA_OFFSET 0xF000
+#define ETH2_OFFSET 0x18000
+#define ETH2_DMA_OFFSET 0x19000
+
+#define ETH_BASE (AHB_BASE + ETH_OFFSET)
+#define ETH_DMA_BASE (AHB_BASE + ETH_DMA_OFFSET)
+#define ETH2_BASE (AHB_BASE + ETH2_OFFSET)
+#define ETH2_DMA_BASE (AHB_BASE + ETH2_DMA_OFFSET)
+
+#define ETH_REG(x) (ETH_BASE + (x))
+#define ETH_DMA_REG(x) (ETH_DMA_BASE + (x))
+#define ETH2_REG(x) (ETH2_BASE + (x))
+#define ETH2_DMA_REG(x) (ETH2_DMA_BASE + (x))
+
+/* ==========================================================================*/
+#define ETH_MAC_CFG_OFFSET 0x0000
+#define ETH_MAC_FRAME_FILTER_OFFSET 0x0004
+#define ETH_MAC_HASH_HI_OFFSET 0x0008
+#define ETH_MAC_HASH_LO_OFFSET 0x000c
+#define ETH_MAC_GMII_ADDR_OFFSET 0x0010
+#define ETH_MAC_GMII_DATA_OFFSET 0x0014
+#define ETH_MAC_FLOW_CTR_OFFSET 0x0018
+#define ETH_MAC_VLAN_TAG_OFFSET 0x001c
+#define ETH_MAC_VERSION_OFFSET 0x0020
+#define ETH_MAC_DEBUG_OFFSET 0x0024
+#define ETH_MAC_WKUPFMFILTER_OFFSET 0x0028
+#define ETH_MAC_PMT_OFFSET 0x002C
+#define ETH_MAC_LPI_CS_OFFSET 0x0030
+#define ETH_MAC_LPI_TIMERS_OFFSET 0x0034
+#define ETH_MAC_INTERRUPT_STATUS_OFFSET 0x0038
+#define ETH_MAC_INTERRUPT_MASK_OFFSET 0x003C
+#define ETH_MAC_MAC0_HI_OFFSET 0x0040
+#define ETH_MAC_MAC0_LO_OFFSET 0x0044
+#define ETH_MAC_MAC1_HI_OFFSET 0x0048
+#define ETH_MAC_MAC1_LO_OFFSET 0x004c
+#define ETH_MAC_MAC2_HI_OFFSET 0x0050
+#define ETH_MAC_MAC2_LO_OFFSET 0x0054
+#define ETH_MAC_AN_STATUS_OFFSET 0x00C4
+#define ETH_MAC_RGMII_CS_OFFSET 0x00D8
+#define ETH_MAC_GPIO_OFFSET 0x00E0
+
+#define ETH_DMA_BUS_MODE_OFFSET 0x1000
+#define ETH_DMA_TX_POLL_DMD_OFFSET 0x1004
+#define ETH_DMA_RX_POLL_DMD_OFFSET 0x1008
+#define ETH_DMA_RX_DESC_LIST_OFFSET 0x100c
+#define ETH_DMA_TX_DESC_LIST_OFFSET 0x1010
+#define ETH_DMA_STATUS_OFFSET 0x1014
+#define ETH_DMA_OPMODE_OFFSET 0x1018
+#define ETH_DMA_INTEN_OFFSET 0x101c
+#define ETH_DMA_MISS_FRAME_BOCNT_OFFSET 0x1020
+#define ETH_DMA_HOST_TX_DESC_OFFSET 0x1048
+#define ETH_DMA_HOST_RX_DESC_OFFSET 0x104c
+#define ETH_DMA_HOST_TX_BUF_OFFSET 0x1050
+#define ETH_DMA_HOST_RX_BUF_OFFSET 0x1054
+
+/* ETH_MAC_CFG_REG */
+#define ETH_MAC_CFG_WD 0x00800000
+#define ETH_MAC_CFG_JD 0x00400000
+#define ETH_MAC_CFG_BE 0x00200000
+#define ETH_MAC_CFG_JE 0x00100000
+#define ETH_MAC_CFG_IFG_96 0x000e0000
+#define ETH_MAC_CFG_IFG_88 0x000c0000
+#define ETH_MAC_CFG_IFG_80 0x000a0000
+#define ETH_MAC_CFG_IFG_72 0x00080000
+#define ETH_MAC_CFG_IFG_64 0x00060000
+#define ETH_MAC_CFG_IFG_56 0x00040000
+#define ETH_MAC_CFG_IFG_48 0x00020000
+#define ETH_MAC_CFG_IFG_40 0x00000000
+#define ETH_MAC_CFG_DCRS 0x00010000
+#define ETH_MAC_CFG_PS 0x00008000
+#define ETH_MAC_CFG_FES 0x00004000
+#define ETH_MAC_CFG_DO 0x00002000
+#define ETH_MAC_CFG_LM 0x00001000
+#define ETH_MAC_CFG_DM 0x00000800
+#define ETH_MAC_CFG_IPC 0x00000400
+#define ETH_MAC_CFG_DR 0x00000200
+#define ETH_MAC_CFG_LUD 0x00000100
+#define ETH_MAC_CFG_ACS 0x00000080
+#define ETH_MAC_CFG_BL_1 0x00000060
+#define ETH_MAC_CFG_BL_4 0x00000040
+#define ETH_MAC_CFG_BL_8 0x00000020
+#define ETH_MAC_CFG_BL_10 0x00000000
+#define ETH_MAC_CFG_DC 0x00000010
+#define ETH_MAC_CFG_TE 0x00000008 /* Transmitter Enable */
+#define ETH_MAC_CFG_RE 0x00000004 /* Receiver Enable */
+
+/* ETH_MAC_FRAME_FILTER_REG */
+#define ETH_MAC_FRAME_FILTER_RA 0x80000000
+#define ETH_MAC_FRAME_FILTER_SAF 0x00000200
+#define ETH_MAC_FRAME_FILTER_SAIF 0x00000100
+#define ETH_MAC_FRAME_FILTER_PCF_PASS 0x000000c0
+#define ETH_MAC_FRAME_FILTER_PCF_FAIL 0x00000040
+#define ETH_MAC_FRAME_FILTER_PCF_ALL 0x00000000
+#define ETH_MAC_FRAME_FILTER_DBF 0x00000020
+#define ETH_MAC_FRAME_FILTER_PM 0x00000010
+#define ETH_MAC_FRAME_FILTER_DAIF 0x00000008
+#define ETH_MAC_FRAME_FILTER_HMC 0x00000004
+#define ETH_MAC_FRAME_FILTER_HUC 0x00000002
+#define ETH_MAC_FRAME_FILTER_PR 0x00000001
+
+/* ETH_MAC_GMII_ADDR_REG */
+#define ETH_MAC_GMII_ADDR_PA(x) (((x) & 0x1f) << 11)
+#define ETH_MAC_GMII_ADDR_GR(x) (((x) & 0x1f) << 6)
+#define ETH_MAC_GMII_ADDR_CR_250_300MHZ 0x00000014
+#define ETH_MAC_GMII_ADDR_CR_150_250MHZ 0x00000010
+#define ETH_MAC_GMII_ADDR_CR_35_60MHZ 0x0000000c
+#define ETH_MAC_GMII_ADDR_CR_20_35MHZ 0x00000008
+#define ETH_MAC_GMII_ADDR_CR_100_150MHZ 0x00000004
+#define ETH_MAC_GMII_ADDR_CR_60_100MHZ 0x00000000
+#define ETH_MAC_GMII_ADDR_GW 0x00000002
+#define ETH_MAC_GMII_ADDR_GB 0x00000001
+
+/* ETH_MAC_FLOW_CTR_REG */
+#define ETH_MAC_FLOW_CTR_PT(x) (((x) & 0xffff) << 16)
+#define ETH_MAC_FLOW_CTR_PLT_256 0x00000030
+#define ETH_MAC_FLOW_CTR_PLT_144 0x00000020
+#define ETH_MAC_FLOW_CTR_PLT_28 0x00000010
+#define ETH_MAC_FLOW_CTR_PLT_4 0x00000000
+#define ETH_MAC_FLOW_CTR_UP 0x00000008
+#define ETH_MAC_FLOW_CTR_RFE 0x00000004
+#define ETH_MAC_FLOW_CTR_TFE 0x00000002
+#define ETH_MAC_FLOW_CTR_FCBBPA 0x00000001
+
+/* ETH_MAC_VERSION_REG */
+#define ETH_MAC_VERSION_USER(v) (((x) & 0x0000ff00) >> 8)
+#define ETH_MAC_VERSION_SYN(v) ((x) & 0x000000ff)
+
+/* ETH_DMA_BUS_MODE_REG */
+#define ETH_DMA_BUS_MODE_FB 0x00010000
+#define ETH_DMA_BUS_MODE_PR4 0x0000c000
+#define ETH_DMA_BUS_MODE_PR3 0x00008000
+#define ETH_DMA_BUS_MODE_PR2 0x00004000
+#define ETH_DMA_BUS_MODE_PR1 0x00000000
+#define ETH_DMA_BUS_MODE_PBL_32 0x00002000
+#define ETH_DMA_BUS_MODE_PBL_16 0x00001000
+#define ETH_DMA_BUS_MODE_PBL_8 0x00000800
+#define ETH_DMA_BUS_MODE_PBL_4 0x00000400
+#define ETH_DMA_BUS_MODE_PBL_2 0x00000200
+#define ETH_DMA_BUS_MODE_PBL_1 0x00000100
+#define ETH_DMA_BUS_MODE_ATDS 0x00000080
+#define ETH_DMA_BUS_MODE_DSL(len) ((len & 0x1f) << 2)
+#define ETH_DMA_BUS_MODE_DA_RX 0x00000002
+#define ETH_DMA_BUS_MODE_DA_TX 0x00000000
+#define ETH_DMA_BUS_MODE_SWR 0x00000001
+
+/* ETH_DMA_STATUS_REG */
+#define ETH_DMA_STATUS_GPI 0x10000000
+#define ETH_DMA_STATUS_GMI 0x08000000
+#define ETH_DMA_STATUS_GLI 0x04000000
+#define ETH_DMA_STATUS_EB_MASK 0x03800000
+#define ETH_DMA_STATUS_EB_TXDMA 0x02000000
+#define ETH_DMA_STATUS_EB_RXDMA 0x00000000
+#define ETH_DMA_STATUS_EB_RXFER 0x01000000
+#define ETH_DMA_STATUS_EB_TXFER 0x00000000
+#define ETH_DMA_STATUS_EB_DESC 0x00800000
+#define ETH_DMA_STATUS_EB_DBUF 0x00000000
+#define ETH_DMA_STATUS_TS_MASK 0x00700000
+#define ETH_DMA_STATUS_TS_CTD 0x00700000
+#define ETH_DMA_STATUS_TS_SUSP 0x00600000
+#define ETH_DMA_STATUS_TS_READ 0x00300000
+#define ETH_DMA_STATUS_TS_WAIT 0x00200000
+#define ETH_DMA_STATUS_TS_FETCH 0x00100000
+#define ETH_DMA_STATUS_TS_STOP 0x00000000
+#define ETH_DMA_STATUS_RS_MASK 0x000e0000
+#define ETH_DMA_STATUS_RS_RCV 0x000e0000
+#define ETH_DMA_STATUS_RS_CRD 0x000a0000
+#define ETH_DMA_STATUS_RS_SUSP 0x00080000
+#define ETH_DMA_STATUS_RS_WAIT 0x00060000
+#define ETH_DMA_STATUS_RS_FETCH 0x00020000
+#define ETH_DMA_STATUS_RS_STOP 0x00000000
+#define ETH_DMA_STATUS_NIS 0x00010000
+#define ETH_DMA_STATUS_AIS 0x00008000
+#define ETH_DMA_STATUS_ERI 0x00004000
+#define ETH_DMA_STATUS_FBI 0x00002000
+#define ETH_DMA_STATUS_ETI 0x00000400
+#define ETH_DMA_STATUS_RWT 0x00000200
+#define ETH_DMA_STATUS_RPS 0x00000100
+#define ETH_DMA_STATUS_RU 0x00000080
+#define ETH_DMA_STATUS_RI 0x00000040
+#define ETH_DMA_STATUS_UNF 0x00000020
+#define ETH_DMA_STATUS_OVF 0x00000010
+#define ETH_DMA_STATUS_TJT 0x00000008
+#define ETH_DMA_STATUS_TU 0x00000004
+#define ETH_DMA_STATUS_TPS 0x00000002
+#define ETH_DMA_STATUS_TI 0x00000001
+
+/* ETH_DMA_OPMODE_REG */
+#define ETH_DMA_OPMODE_DT 0x04000000
+#define ETH_DMA_OPMODE_RSF 0x02000000
+#define ETH_DMA_OPMODE_DFF 0x01000000
+#define ETH_DMA_OPMODE_TSF 0x00200000
+#define ETH_DMA_OPMODE_FTF 0x00100000
+#define ETH_DMA_OPMODE_TTC_16 0x0001c000
+#define ETH_DMA_OPMODE_TTC_24 0x00018000
+#define ETH_DMA_OPMODE_TTC_32 0x00014000
+#define ETH_DMA_OPMODE_TTC_40 0x00010000
+#define ETH_DMA_OPMODE_TTC_256 0x0000c000
+#define ETH_DMA_OPMODE_TTC_192 0x00008000
+#define ETH_DMA_OPMODE_TTC_128 0x00004000
+#define ETH_DMA_OPMODE_TTC_64 0x00000000
+#define ETH_DMA_OPMODE_ST 0x00002000
+#define ETH_DMA_OPMODE_RFD_4K 0x00001800
+#define ETH_DMA_OPMODE_RFD_3K 0x00001000
+#define ETH_DMA_OPMODE_RFD_2K 0x00000800
+#define ETH_DMA_OPMODE_RFD_1K 0x00000000
+#define ETH_DMA_OPMODE_RFA_4K 0x00000600
+#define ETH_DMA_OPMODE_RFA_3K 0x00000400
+#define ETH_DMA_OPMODE_RFA_2K 0x00000200
+#define ETH_DMA_OPMODE_RFA_1K 0x00000000
+#define ETH_DMA_OPMODE_EFC 0x00000100
+#define ETH_DMA_OPMODE_FEF 0x00000080
+#define ETH_DMA_OPMODE_FUF 0x00000040
+#define ETH_DMA_OPMODE_RTC_128 0x00000018
+#define ETH_DMA_OPMODE_RTC_96 0x00000010
+#define ETH_DMA_OPMODE_RTC_32 0x00000008
+#define ETH_DMA_OPMODE_RTC_64 0x00000000
+#define ETH_DMA_OPMODE_OSF 0x00000004
+#define ETH_DMA_OPMODE_SR 0x00000002
+
+/* ETH_DMA_INTEN_REG */
+#define ETH_DMA_INTEN_NIE 0x00010000
+#define ETH_DMA_INTEN_AIE 0x00008000
+#define ETH_DMA_INTEN_ERE 0x00004000
+#define ETH_DMA_INTEN_FBE 0x00002000
+#define ETH_DMA_INTEN_ETE 0x00000400
+#define ETH_DMA_INTEN_RWE 0x00000200
+#define ETH_DMA_INTEN_RSE 0x00000100
+#define ETH_DMA_INTEN_RUE 0x00000080
+#define ETH_DMA_INTEN_RIE 0x00000040
+#define ETH_DMA_INTEN_UNE 0x00000020
+#define ETH_DMA_INTEN_OVE 0x00000010
+#define ETH_DMA_INTEN_TJE 0x00000008
+#define ETH_DMA_INTEN_TUE 0x00000004
+#define ETH_DMA_INTEN_TSE 0x00000002
+#define ETH_DMA_INTEN_TIE 0x00000001
+
+/* ETH_DMA_MISS_FRAME_BOCNT_REG */
+#define ETH_DMA_MISS_FRAME_BOCNT_FIFO 0x10000000
+#define ETH_DMA_MISS_FRAME_BOCNT_APP(v) (((v) & 0x0ffe0000) >> 17)
+#define ETH_DMA_MISS_FRAME_BOCNT_FRAME 0x00001000
+#define ETH_DMA_MISS_FRAME_BOCNT_HOST(v) ((v) & 0x0000ffff)
+
+/* Receive Descriptor 0 (RDES0) */
+#define ETH_RDES0_OWN 0x80000000
+#define ETH_RDES0_AFM 0x40000000
+#define ETH_RDES0_FL(v) (((v) & 0x3fff0000) >> 16)
+#define ETH_RDES0_ES 0x00008000
+#define ETH_RDES0_DE 0x00004000
+#define ETH_RDES0_SAF 0x00002000
+#define ETH_RDES0_LE 0x00001000
+#define ETH_RDES0_OE 0x00000800
+#define ETH_RDES0_VLAN 0x00000400
+#define ETH_RDES0_FS 0x00000200
+#define ETH_RDES0_LS 0x00000100
+#define ETH_RDES0_IPC 0x00000080
+#define ETH_RDES0_LC 0x00000040
+#define ETH_RDES0_FT 0x00000020
+#define ETH_RDES0_RWT 0x00000010
+#define ETH_RDES0_RE 0x00000008
+#define ETH_RDES0_DBE 0x00000004
+#define ETH_RDES0_CE 0x00000002
+#define ETH_RDES0_RX 0x00000001
+
+#define ETH_RDES0_COE_MASK 0x000000a1
+#define ETH_RDES0_COE_LENLT600 0x00000000 /* Bit(5:7:0)=>0 IEEE 802.3 type frame Length field is Lessthan 0x0600 */
+#define ETH_RDES0_COE_UNSUPPORTED 0x00000001 /* Bit(5:7:0)=>1 Payload & Ip header checksum bypassed (unsuppported payload) */
+#define ETH_RDES0_COE_RESERVED 0x00000080 /* Bit(5:7:0)=>2 Reserved */
+#define ETH_RDES0_COE_CHKBYPASS 0x00000081 /* Bit(5:7:0)=>3 Neither IPv4 nor IPV6. So checksum bypassed */
+#define ETH_RDES0_COE_NOCHKERROR 0x00000020 /* Bit(5:7:0)=>4 No IPv4/IPv6 Checksum error detected */
+#define ETH_RDES0_COE_PLCHKERROR 0x00000021 /* Bit(5:7:0)=>5 Payload checksum error detected for Ipv4/Ipv6 frames */
+#define ETH_RDES0_COE_HDRCHKERROR 0x000000a0 /* Bit(5:7:0)=>6 Ip header checksum error detected for Ipv4 frames */
+#define ETH_RDES0_COE_HDRPLCHKERROR 0x000000a1 /* Bit(5:7:0)=>7 Payload & Ip header checksum error detected for Ipv4/Ipv6 frames */
+
+/* Receive Descriptor 1 (RDES1) */
+#define ETH_RDES1_DIC 0x80000000
+#if (CHIP_REV == S3)
+#define ETH_RDES1_RER 0x00008000
+#define ETH_RDES1_RCH 0x00004000
+#define ETH_RDES1_RBS2(v) (((v) & 0x1FFF0000) >> 16)
+#define ETH_RDES1_RBS1(v) ((v) & 0x00001FFF)
+#define ETH_RDES1_RBS2x(x) (((x) << 16) & 0x1FFF0000)
+#define ETH_RDES1_RBS1x(x) ((x) & 0x00001FFF)
+#else
+#define ETH_RDES1_RER 0x02000000
+#define ETH_RDES1_RCH 0x01000000
+#define ETH_RDES1_RBS2(v) (((v) & 0x003ff800) >> 11) /* Receive Buffer 2 Size */
+#define ETH_RDES1_RBS1(v) ((v) & 0x000007ff) /* Receive Buffer 1 Size */
+#define ETH_RDES1_RBS2x(x) (((x) << 11) & 0x003ff800) /* Receive Buffer 2 Size */
+#define ETH_RDES1_RBS1x(x) ((x) & 0x000007ff) /* Receive Buffer 1 Size */
+#endif
+
+/* Transmit Descriptor 0 (TDES0) */
+#define ETH_TDES0_OWN 0x80000000
+#define ETH_TDES0_TTSS 0x00020000
+#define ETH_TDES0_IHE 0x00010000
+#define ETH_TDES0_ES 0x00008000
+#define ETH_TDES0_JT 0x00004000
+#define ETH_TDES0_FF 0x00002000
+#define ETH_TDES0_PCE 0x00001000
+#define ETH_TDES0_LCA 0x00000800
+#define ETH_TDES0_NC 0x00000400
+#define ETH_TDES0_LCO 0x00000200
+#define ETH_TDES0_EC 0x00000100
+#define ETH_TDES0_VF 0x00000080
+#define ETH_TDES0_CC(v) (((v) & 0x00000078) >> 3)
+#define ETH_TDES0_ED 0x00000004
+#define ETH_TDES0_UF 0x00000002
+#define ETH_TDES0_DB 0x00000001
+#define ETH_TDES0_ES_MASK (ETH_TDES0_UF | ETH_TDES0_ED | \
+ ETH_TDES0_EC | ETH_TDES0_LCO | \
+ ETH_TDES0_NC | ETH_TDES0_LCA | \
+ ETH_TDES0_FF | ETH_TDES0_JT | \
+ ETH_TDES0_ES)
+
+/* Transmit Descriptor 1 (TDES1) */
+#define ETH_TDES1_IC 0x80000000
+#define ETH_TDES1_LS 0x40000000
+#define ETH_TDES1_FS 0x20000000
+#define ETH_TDES1_CIC_TUI 0x10000000
+#define ETH_TDES1_CIC_HDR 0x08000000
+#define ETH_TDES1_DC 0x04000000
+#define ETH_TDES1_TER 0x02000000
+#define ETH_TDES1_TCH 0x01000000
+#define ETH_TDES1_DP 0x00800000
+#if (CHIP_REV == S3)
+#define ETH_TDES1_TBS2(v) (((v) & 0x1FFF0000) >> 16)
+#define ETH_TDES1_TBS1(v) ((v) & 0x00001FFF)
+#define ETH_TDES1_TBS2x(x) (((x) << 16) & 0x1FFF0000)
+#define ETH_TDES1_TBS1x(x) ((x) & 0x00001FFF)
+#else
+#define ETH_TDES1_TBS2(v) (((v) & 0x003ff800) >> 11)
+#define ETH_TDES1_TBS1(v) ((v) & 0x000007ff)
+#define ETH_TDES1_TBS2x(x) (((x) << 11) & 0x003ff800)
+#define ETH_TDES1_TBS1x(x) ((x) & 0x000007ff)
+#endif
+/* ==========================================================================*/
+#define ETH_ENHANCED_TDES0_IC 0x40000000
+#define ETH_ENHANCED_TDES0_LS 0x20000000
+#define ETH_ENHANCED_TDES0_FS 0x10000000
+#define ETH_ENHANCED_TDES0_DC 0x08000000
+#define ETH_ENHANCED_TDES0_DP 0x04000000
+#define ETH_ENHANCED_TDES0_CRCR 0x01000000
+#define ETH_ENHANCED_TDES0_CIC_V2 0x00C00000
+#define ETH_ENHANCED_TDES0_CIC_V1 0x00800000
+#define ETH_ENHANCED_TDES0_CIC_HDR 0x00400000
+#define ETH_ENHANCED_TDES0_TER 0x00200000
+#define ETH_ENHANCED_TDES0_TCH 0x00100000
+
+#define ETH_ENHANCED_TDES1_SAIC_MAC1 0x80000000
+#define ETH_ENHANCED_TDES1_SAIC_REPLACE 0x40000000
+#define ETH_ENHANCED_TDES1_SAIC_INCLUDE 0x20000000
+
+/*Different Bit of Descriptor*/
+#define ETH_TDES_IC 0x1
+#define ETH_TDES_LS 0x2
+#define ETH_TDES_FS 0x4
+#define ETH_TDES_DC 0x8
+#define ETH_TDES_TCH 0x10
+#define ETH_TDES_CIC 0x20
+/* ==========================================================================*/
+#define AMBARELLA_ETH_FC_AUTONEG (1 << 0)
+#define AMBARELLA_ETH_FC_RX (1 << 1)
+#define AMBARELLA_ETH_FC_TX (1 << 2)
+
+#if (CHIP_REV == A8)
+#define SYS_CONFIG_ETH_ENABLE 0xffffffff
+#elif (CHIP_REV == S2) || (CHIP_REV == S2E)
+#define SYS_CONFIG_ETH_ENABLE 0x00800000
+#elif (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+#define SYS_CONFIG_ETH_ENABLE 0x00000001
+#else
+#define SYS_CONFIG_ETH_ENABLE 0x00000080
+#endif
+
+/* ==========================================================================*/
+
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/plat/event.h b/arch/arm/mach-ambarella/include/plat/event.h
new file mode 100644
index 00000000..582fb1db
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/event.h
@@ -0,0 +1,75 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/event.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_EVENT_H
+#define __PLAT_AMBARELLA_EVENT_H
+
+/* ==========================================================================*/
+#define AMBA_EVENT_PRE (0x80000000)
+#define AMBA_EVENT_POST (0x40000000)
+#define AMBA_EVENT_CHECK (0x20000000)
+
+#define AMBA_EVENT_ID_CPUFREQ (1)
+#define AMBA_EVENT_ID_PM (2)
+#define AMBA_EVENT_ID_TOSS (3)
+#define AMBA_EVENT_ID_GIVEUP_DSP (4)
+#define AMBA_EVENT_ID_TAKEOVER_DSP (5)
+#define AMBA_EVENT_ID_VIN_LOSS (6)
+
+#define AMBA_EVENT_PRE_CPUFREQ (AMBA_EVENT_ID_CPUFREQ | AMBA_EVENT_PRE)
+#define AMBA_EVENT_POST_CPUFREQ (AMBA_EVENT_ID_CPUFREQ | AMBA_EVENT_POST)
+#define AMBA_EVENT_CHECK_CPUFREQ (AMBA_EVENT_ID_CPUFREQ | AMBA_EVENT_CHECK)
+#define AMBA_EVENT_PRE_PM (AMBA_EVENT_ID_PM | AMBA_EVENT_PRE)
+#define AMBA_EVENT_POST_PM (AMBA_EVENT_ID_PM | AMBA_EVENT_POST)
+#define AMBA_EVENT_CHECK_PM (AMBA_EVENT_ID_PM | AMBA_EVENT_CHECK)
+#define AMBA_EVENT_PRE_TOSS (AMBA_EVENT_ID_TOSS | AMBA_EVENT_PRE)
+#define AMBA_EVENT_POST_TOSS (AMBA_EVENT_ID_TOSS | AMBA_EVENT_POST)
+#define AMBA_EVENT_CHECK_TOSS (AMBA_EVENT_ID_TOSS | AMBA_EVENT_CHECK)
+
+#define AMBA_EVENT_PRE_GIVEUP_DSP (AMBA_EVENT_ID_GIVEUP_DSP | AMBA_EVENT_PRE)
+#define AMBA_EVENT_POST_GIVEUP_DSP (AMBA_EVENT_ID_GIVEUP_DSP | AMBA_EVENT_POST)
+#define AMBA_EVENT_GIVEUP_DSP (AMBA_EVENT_ID_GIVEUP_DSP | AMBA_EVENT_CHECK)
+#define AMBA_EVENT_PRE_TAKEOVER_DSP (AMBA_EVENT_ID_TAKEOVER_DSP | AMBA_EVENT_PRE)
+#define AMBA_EVENT_POST_TAKEOVER_DSP (AMBA_EVENT_ID_TAKEOVER_DSP | AMBA_EVENT_POST)
+#define AMBA_EVENT_TAKEOVER_DSP (AMBA_EVENT_ID_TAKEOVER_DSP | AMBA_EVENT_CHECK)
+
+#define AMBA_EVENT_POST_VIN_LOSS (AMBA_EVENT_ID_VIN_LOSS | AMBA_EVENT_POST)
+
+/* ==========================================================================*/
+#ifndef __ASSEMBLER__
+
+/* ==========================================================================*/
+
+/* ==========================================================================*/
+extern int ambarella_register_event_notifier(void *nb);
+extern int ambarella_unregister_event_notifier(void *nb);
+extern int ambarella_set_event(unsigned long val, void *v);
+extern int ambarella_register_raw_event_notifier(void *nb);
+extern int ambarella_unregister_raw_event_notifier(void *nb);
+extern int ambarella_set_raw_event(unsigned long val, void *v);
+
+#endif /* __ASSEMBLER__ */
+/* ==========================================================================*/
+
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/plat/fb.h b/arch/arm/mach-ambarella/include/plat/fb.h
new file mode 100644
index 00000000..f0f4e9ff
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/fb.h
@@ -0,0 +1,151 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/fb.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_FB_H
+#define __PLAT_AMBARELLA_FB_H
+
+#define AMBARELLA_FB_MAX_NUM 2
+
+/* ==========================================================================*/
+#define AMBARELLA_CLUT_TABLE_SIZE (256 * 3)
+#define AMBARELLA_BLEND_TABLE_SIZE (256)
+
+/* ==========================================================================*/
+#ifndef __ASSEMBLER__
+enum ambarella_fb_color_format {
+ AMBFB_COLOR_AUTO = 0,
+
+ AMBFB_COLOR_CLUT_8BPP,
+ AMBFB_COLOR_RGB565,
+
+ AMBFB_COLOR_BGR565,
+ AMBFB_COLOR_AGBR4444, //AYUV 4:4:4:4
+ AMBFB_COLOR_RGBA4444,
+ AMBFB_COLOR_BGRA4444,
+ AMBFB_COLOR_ABGR4444,
+ AMBFB_COLOR_ARGB4444,
+ AMBFB_COLOR_AGBR1555, //AYUV 1:5:5:5
+ AMBFB_COLOR_GBR1555, //YUV 1(ignored):5:5:5
+ AMBFB_COLOR_RGBA5551,
+ AMBFB_COLOR_BGRA5551,
+ AMBFB_COLOR_ABGR1555,
+ AMBFB_COLOR_ARGB1555,
+ AMBFB_COLOR_AGBR8888, //AYUV 8:8:8:8
+ AMBFB_COLOR_AYUV8888,
+ AMBFB_COLOR_RGBA8888,
+ AMBFB_COLOR_BGRA8888,
+ AMBFB_COLOR_ABGR8888,
+ AMBFB_COLOR_ARGB8888,
+
+ AMBFB_COLOR_VYU565,
+ AMBFB_COLOR_AYUV4444,
+ AMBFB_COLOR_AYUV1555,
+ AMBFB_COLOR_YUV555,
+
+ AMBFB_COLOR_UNSUPPORTED, //Reserved only, not supported
+};
+
+enum ambarella_dsp_status {
+ AMBA_DSP_ENCODE_MODE = 0x00,
+ AMBA_DSP_DECODE_MODE = 0x01,
+ AMBA_DSP_RESET_MODE = 0x02,
+ AMBA_DSP_UNKNOWN_MODE = 0x03,
+ AMBA_DSP_QUICKLOGO_MODE = 0x04,
+};
+
+enum ambarella_fb_status {
+ AMBFB_UNKNOWN_MODE = 0x00,
+ AMBFB_ACTIVE_MODE,
+ AMBFB_STOP_MODE,
+};
+
+typedef int (*ambarella_fb_pan_display_fn)(struct fb_var_screeninfo *var,
+ struct fb_info *info);
+typedef int (*ambarella_fb_setcmap_fn)(struct fb_cmap *cmap,
+ struct fb_info *info);
+typedef int (*ambarella_fb_check_var_fn)(struct fb_var_screeninfo *var,
+ struct fb_info *info);
+typedef int (*ambarella_fb_set_par_fn)(struct fb_info *info);
+typedef int (*ambarella_fb_blank_fn)(int blank_mode, struct fb_info *info);
+
+struct ambarella_fb_cvs_buf { //Conversion Buffer
+ int available;
+ u32 base_buf_phy;
+ u8 *ping_buf;
+ u32 ping_buf_phy;
+ u32 ping_buf_size;
+ u8 *pong_buf;
+ u32 pong_buf_size;
+ u32 pong_buf_phy;
+};
+
+struct ambarella_fb_iav_info {
+ struct fb_var_screeninfo screen_var;
+ struct fb_fix_screeninfo screen_fix;
+ enum ambarella_dsp_status dsp_status;
+
+ ambarella_fb_pan_display_fn pan_display;
+ ambarella_fb_setcmap_fn setcmap;
+ ambarella_fb_check_var_fn check_var;
+ ambarella_fb_set_par_fn set_par;
+ ambarella_fb_blank_fn set_blank;
+};
+
+struct ambarella_platform_fb {
+ struct mutex lock;
+ struct fb_var_screeninfo screen_var;
+ struct fb_fix_screeninfo screen_fix;
+ enum ambarella_dsp_status dsp_status;
+ enum ambarella_fb_status fb_status;
+ u8 clut_table[AMBARELLA_CLUT_TABLE_SIZE];
+ u8 blend_table[AMBARELLA_BLEND_TABLE_SIZE];
+ enum ambarella_fb_color_format color_format;
+ struct ambarella_fb_cvs_buf conversion_buf;
+ u32 use_prealloc;
+ u32 prealloc_line_length;
+
+ ambarella_fb_pan_display_fn pan_display;
+ ambarella_fb_setcmap_fn setcmap;
+ ambarella_fb_check_var_fn check_var;
+ ambarella_fb_set_par_fn set_par;
+ ambarella_fb_blank_fn set_blank;
+
+ struct fb_info *proc_fb_info;
+ struct proc_dir_entry *proc_file;
+ wait_queue_head_t proc_wait;
+ u32 proc_wait_flag;
+};
+
+/* ==========================================================================*/
+
+extern struct ambarella_platform_fb *ambfb_data_ptr[];
+
+/* ==========================================================================*/
+extern int ambarella_fb_get_platform_info(u32, struct ambarella_platform_fb *);
+extern int ambarella_fb_set_iav_info(u32, struct ambarella_fb_iav_info *);
+
+#endif /* __ASSEMBLER__ */
+/* ==========================================================================*/
+
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/plat/fio.h b/arch/arm/mach-ambarella/include/plat/fio.h
new file mode 100644
index 00000000..ee31d429
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/fio.h
@@ -0,0 +1,188 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/fio.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_COMMON_FIO_H__
+#define __PLAT_AMBARELLA_COMMON_FIO_H__
+
+/* ==========================================================================*/
+#if (CHIP_REV == A5S)
+#define FIO_USE_2X_FREQ 1
+#else
+#define FIO_USE_2X_FREQ 0
+#endif
+
+#if (CHIP_REV == A5S)
+#define NAND_READ_ID5 0
+#else
+#define NAND_READ_ID5 1
+#endif
+
+#if (CHIP_REV == A5S) || (CHIP_REV == S2)
+#define FIO_INDEPENDENT_SD 0
+#else
+#define FIO_INDEPENDENT_SD 1
+#endif
+
+/* For BCH mode */
+#if (CHIP_REV == S3L)
+#define FIO_SUPPORT_SKIP_BLANK_ECC 1
+#else
+#define FIO_SUPPORT_SKIP_BLANK_ECC 0
+#endif
+
+/* ==========================================================================*/
+#define FIO_FIFO_OFFSET 0x0000
+#define FIO_OFFSET 0x1000
+#if (CHIP_REV == S2E)
+#define FIO_4K_OFFSET 0x1e000
+#else
+#define FIO_4K_OFFSET 0x30000
+#endif
+
+#define FIO_4K_PHYS_BASE (AHB_PHYS_BASE + FIO_4K_OFFSET)
+
+#define FIO_FIFO_BASE (AHB_BASE + FIO_FIFO_OFFSET)
+#define FIO_BASE (AHB_BASE + FIO_OFFSET)
+#define FIO_4K_BASE (AHB_BASE + FIO_4K_OFFSET)
+#define FIO_REG(x) (FIO_BASE + (x))
+#define FIO_4K_REG(x) (FIO_4K_BASE + (x))
+
+/* ==========================================================================*/
+#define FIO_CTR_OFFSET 0x000
+#define FIO_STA_OFFSET 0x004
+#define FIO_DMACTR_OFFSET 0x080
+#define FIO_DMAADR_OFFSET 0x084
+#define FIO_DMASTA_OFFSET 0x08c
+#define FIO_DSM_CTR_OFFSET 0x0a0
+#define FIO_ECC_RPT_STA_OFFSET 0x0a4
+
+#define FIO_CTR_REG FIO_REG(0x000)
+#define FIO_STA_REG FIO_REG(0x004)
+#define FIO_DMACTR_REG FIO_REG(0x080)
+#define FIO_DMAADR_REG FIO_REG(0x084)
+#define FIO_DMASTA_REG FIO_REG(0x08c)
+#define FIO_DSM_CTR_REG FIO_REG(0x0a0)
+#define FIO_ECC_RPT_STA_REG FIO_REG(0x0a4)
+
+/* FIO_CTR_REG */
+#define FIO_CTR_DA 0x00020000
+#define FIO_CTR_DR 0x00010000
+#define FIO_CTR_SX 0x00000100
+#if (FIO_SUPPORT_SKIP_BLANK_ECC == 1)
+#define FIO_CTR_SKIP_BLANK 0x00000080
+#else
+#define FIO_CTR_SKIP_BLANK 0x00000000
+#endif
+#define FIO_CTR_ECC_8BIT 0x00000060
+#define FIO_CTR_ECC_6BIT 0x00000040
+#define FIO_CTR_RS 0x00000010
+#define FIO_CTR_SE 0x00000008
+#define FIO_CTR_CO 0x00000004
+#define FIO_CTR_RR 0x00000002
+#define FIO_CTR_XD 0x00000001
+
+/* FIO_STA_REG */
+#define FIO_STA_SI 0x00000008
+#define FIO_STA_CI 0x00000004
+#define FIO_STA_XI 0x00000002
+#define FIO_STA_FI 0x00000001
+
+/* FIO_DMACTR_REG */
+#define FIO_DMACTR_EN 0x80000000
+#define FIO_DMACTR_RM 0x40000000
+#define FIO_DMACTR_SD 0x30000000
+#define FIO_DMACTR_CF 0x20000000
+#define FIO_DMACTR_XD 0x10000000
+#define FIO_DMACTR_FL 0x00000000
+#define FIO_DMACTR_BLK_32768B 0x0c000000
+#define FIO_DMACTR_BLK_16384B 0x0b000000
+#define FIO_DMACTR_BLK_8192B 0x0a000000
+#define FIO_DMACTR_BLK_4096B 0x09000000
+#define FIO_DMACTR_BLK_2048B 0x08000000
+#define FIO_DMACTR_BLK_1024B 0x07000000
+#define FIO_DMACTR_BLK_256B 0x05000000
+#define FIO_DMACTR_BLK_512B 0x06000000
+#define FIO_DMACTR_BLK_128B 0x04000000
+#define FIO_DMACTR_BLK_64B 0x03000000
+#define FIO_DMACTR_BLK_32B 0x02000000
+#define FIO_DMACTR_BLK_16B 0x01000000
+#define FIO_DMACTR_BLK_8B 0x00000000
+#define FIO_DMACTR_TS8B 0x00c00000
+#define FIO_DMACTR_TS4B 0x00800000
+#define FIO_DMACTR_TS2B 0x00400000
+#define FIO_DMACTR_TS1B 0x00000000
+
+/* FIO_DMASTA_REG */
+#define FIO_DMASTA_RE 0x04000000
+#define FIO_DMASTA_AE 0x02000000
+#define FIO_DMASTA_DN 0x01000000
+
+/* FIO_DSM_CTR_REG */
+#define FIO_DSM_EN 0x80000000
+#define FIO_DSM_MAJP_2KB 0x00000090
+#define FIO_DSM_SPJP_64B 0x00000004
+#define FIO_DSM_SPJP_128B 0x00000005
+
+/* FIO_ECC_RPT_REG */
+#define FIO_ECC_RPT_ERR 0x80000000
+#define FIO_ECC_RPT_FAIL 0x40000000
+
+/* ==========================================================================*/
+#define SELECT_FIO_FREE (0x00000000)
+#define SELECT_FIO_FL (0x00000001)
+#define SELECT_FIO_XD (0x00000002)
+#define SELECT_FIO_CF (0x00000004)
+#define SELECT_FIO_SD (0x00000008)
+#define SELECT_FIO_SDIO (0x00000010)
+
+#define FIO_OP_NOT_DONE_ER (-1) /* operation(xfer) not done error */
+#define FIO_READ_ER (-2) /* uncorrected ECC error */
+#define FIO_ADDR_ER (-3) /* address unaligned error */
+
+/* ==========================================================================*/
+#ifndef __ASSEMBLER__
+
+/* ==========================================================================*/
+
+#if (FIO_INDEPENDENT_SD == 1)
+static inline void fio_select_lock(int module) { }
+static inline void fio_unlock(int module) { }
+static inline void fio_amb_sd0_set_int(u32 mask, u32 on){ }
+static inline void fio_amb_sdio0_set_int(u32 mask, u32 on){ }
+#else
+extern void fio_select_lock(int module);
+extern void fio_unlock(int module);
+extern void fio_amb_sd0_set_int(u32 mask, u32 on);
+extern void fio_amb_sdio0_set_int(u32 mask, u32 on);
+#endif
+
+extern int ambarella_init_fio(void);
+extern void ambarella_fio_rct_reset(void);
+
+extern void *ambarella_fio_push(void *func, u32 size);
+
+#endif /* __ASSEMBLER__ */
+/* ==========================================================================*/
+
+#endif /* __PLAT_AMBARELLA_COMMON_FIO_H__ */
+
diff --git a/arch/arm/mach-ambarella/include/plat/gdma.h b/arch/arm/mach-ambarella/include/plat/gdma.h
new file mode 100644
index 00000000..21129d47
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/gdma.h
@@ -0,0 +1,100 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/gdma.h
+ *
+ * History:
+ * 2013/11/26 - Ken He <jianhe@ambarella.com> created file
+ *
+ * Copyright (C) 2012-2016, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_GDMA_H__
+#define __PLAT_AMBARELLA_GDMA_H__
+
+/****************************************************/
+/* Capabilities based on chip revision */
+/****************************************************/
+
+#define GDMA_OFFSET 0x15000
+#define GDMA_BASE (AHB_BASE + GDMA_OFFSET)
+#define GDMA_REG(x) (GDMA_BASE + (x))
+
+#if (CHIP_REV == A5S)
+#define GDMA_SUPPORT_ALPHA_BLEND 0
+#else
+#define GDMA_SUPPORT_ALPHA_BLEND 1
+#endif
+
+struct gdma_param {
+ u32 dest_addr;
+ u32 dest_virt_addr;
+ u32 src_addr;
+ u32 src_virt_addr;
+ u8 dest_non_cached;
+ u8 src_non_cached;
+ u8 reserved[2];
+ u16 src_pitch;
+ u16 dest_pitch;
+ u16 width;
+ u16 height;
+};
+
+/****************************************************/
+/* Controller registers definitions */
+/****************************************************/
+#define GDMA_SRC_1_BASE_OFFSET 0x00
+#define GDMA_SRC_1_PITCH_OFFSET 0x04
+#define GDMA_SRC_2_BASE_OFFSET 0x08
+#define GDMA_SRC_2_PITCH_OFFSET 0x0c
+#define GDMA_DST_BASE_OFFSET 0x10
+#define GDMA_DST_PITCH_OFFSET 0x14
+#define GDMA_WIDTH_OFFSET 0x18
+#define GDMA_HIGHT_OFFSET 0x1c
+#define GDMA_TRANSPARENT_OFFSET 0x20
+#define GDMA_OPCODE_OFFSET 0x24
+#define GDMA_PENDING_OPS_OFFSET 0x28
+
+#if (GDMA_SUPPORT_ALPHA_BLEND == 1)
+#define GDMA_PIXELFORMAT_OFFSET 0x2c
+#define GDMA_ALPHA_OFFSET 0x30
+#define GDMA_CLUT_BASE_OFFSET 0x400
+#endif
+
+#define GDMA_SRC_1_BASE_REG GDMA_REG(GDMA_SRC_1_BASE_OFFSET)
+#define GDMA_SRC_1_PITCH_REG GDMA_REG(GDMA_SRC_1_PITCH_OFFSET)
+#define GDMA_SRC_2_BASE_REG GDMA_REG(GDMA_SRC_2_BASE_OFFSET)
+#define GDMA_SRC_2_PITCH_REG GDMA_REG(GDMA_SRC_2_PITCH_OFFSET)
+#define GDMA_DST_BASE_REG GDMA_REG(GDMA_DST_BASE_OFFSET)
+#define GDMA_DST_PITCH_REG GDMA_REG(GDMA_DST_PITCH_OFFSET)
+#define GDMA_WIDTH_REG GDMA_REG(GDMA_WIDTH_OFFSET)
+#define GDMA_HEIGHT_REG GDMA_REG(GDMA_HIGHT_OFFSET)
+#define GDMA_TRANSPARENT_REG GDMA_REG(GDMA_TRANSPARENT_OFFSET)
+#define GDMA_OPCODE_REG GDMA_REG(GDMA_OPCODE_OFFSET)
+#define GDMA_PENDING_OPS_REG GDMA_REG(GDMA_PENDING_OPS_OFFSET)
+
+#if (GDMA_SUPPORT_ALPHA_BLEND == 1)
+#define GDMA_PIXELFORMAT_REG GDMA_REG(GDMA_PIXELFORMAT_OFFSET)
+#define GDMA_ALPHA_REG GDMA_REG(GDMA_ALPHA_OFFSET)
+#define GDMA_CLUT_BASE_REG GDMA_REG(GDMA_CLUT_BASE_OFFSET)
+
+/* GDMA_PIXELFORMAT_REG */
+#define GDMA_PIXELFORMAT_THROTTLE_DRAM (1L << 11)
+
+#endif /* (GDMA_SUPPORT_ALPHA_BLEND == 1)*/
+
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/plat/gpio.h b/arch/arm/mach-ambarella/include/plat/gpio.h
new file mode 100644
index 00000000..ee2b64e8
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/gpio.h
@@ -0,0 +1,201 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/gpio.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_GPIO_H__
+#define __PLAT_AMBARELLA_GPIO_H__
+
+/* ==========================================================================*/
+#if (CHIP_REV == A7L)
+#define GPIO_INSTANCES 4
+#define GPIO_MAX_LINES 128
+#elif (CHIP_REV == A5S)
+#define GPIO_INSTANCES 3
+#define GPIO_MAX_LINES 96
+#elif (CHIP_REV == S2) || (CHIP_REV == S2E)
+#define GPIO_INSTANCES 5
+#define GPIO_MAX_LINES 138
+#elif (CHIP_REV == A8)
+#define GPIO_INSTANCES 1
+#define GPIO_MAX_LINES 16
+#elif (CHIP_REV == S2L) || (CHIP_REV == S3L)
+#define GPIO_INSTANCES 4
+#define GPIO_MAX_LINES 114
+#elif (CHIP_REV == S3)
+#define GPIO_INSTANCES 7
+#define GPIO_MAX_LINES 201
+#else
+#error "Not supported!"
+#endif
+
+/* ==========================================================================*/
+#define GPIO0_OFFSET 0x9000
+#define GPIO1_OFFSET 0xA000
+#define GPIO2_OFFSET 0xE000
+#if (CHIP_REV == A5S)
+#define GPIO3_OFFSET 0x1F000
+#elif (CHIP_REV == A7L)
+#define GPIO3_OFFSET 0x1E000
+#else
+#define GPIO3_OFFSET 0x10000
+#endif
+#define GPIO4_OFFSET 0x11000
+#if (CHIP_REV == S3)
+#define GPIO5_OFFSET 0xD000
+#else
+#define GPIO5_OFFSET 0x12000
+#endif
+#define GPIO6_OFFSET 0x14000
+
+#define GPIO0_BASE (APB_BASE + GPIO0_OFFSET)
+#define GPIO1_BASE (APB_BASE + GPIO1_OFFSET)
+#define GPIO2_BASE (APB_BASE + GPIO2_OFFSET)
+#define GPIO3_BASE (APB_BASE + GPIO3_OFFSET)
+#define GPIO4_BASE (APB_BASE + GPIO4_OFFSET)
+#define GPIO5_BASE (APB_BASE + GPIO5_OFFSET)
+#define GPIO6_BASE (APB_BASE + GPIO6_OFFSET)
+
+#define GPIO0_REG(x) (GPIO0_BASE + (x))
+#define GPIO1_REG(x) (GPIO1_BASE + (x))
+#define GPIO2_REG(x) (GPIO2_BASE + (x))
+#define GPIO3_REG(x) (GPIO3_BASE + (x))
+#define GPIO4_REG(x) (GPIO4_BASE + (x))
+#define GPIO5_REG(x) (GPIO5_BASE + (x))
+#define GPIO6_REG(x) (GPIO6_BASE + (x))
+
+/* ==========================================================================*/
+#if (CHIP_REV == A5S)
+#define GPIO_PAD_PULL_CTRL_SUPPORT 0
+#else
+#define GPIO_PAD_PULL_CTRL_SUPPORT 1
+#endif
+
+#if (CHIP_REV == A7L) || (CHIP_REV == S2) || (CHIP_REV == S2E) || (CHIP_REV == A8)
+#define GPIO_PAD_PULL_OFFSET 0xD000
+#else
+#define GPIO_PAD_PULL_OFFSET 0x15000
+#endif
+
+#define GPIO_PAD_PULL_EN_0_OFFSET 0x80
+#define GPIO_PAD_PULL_EN_1_OFFSET 0x84
+#define GPIO_PAD_PULL_EN_2_OFFSET 0x88
+#define GPIO_PAD_PULL_EN_3_OFFSET 0x8C
+#define GPIO_PAD_PULL_EN_4_OFFSET 0x90
+#define GPIO_PAD_PULL_EN_5_OFFSET 0x100
+#define GPIO_PAD_PULL_EN_6_OFFSET 0x104
+
+#define GPIO_PAD_PULL_DIR_0_OFFSET 0x94
+#define GPIO_PAD_PULL_DIR_1_OFFSET 0x98
+#define GPIO_PAD_PULL_DIR_2_OFFSET 0x9C
+#define GPIO_PAD_PULL_DIR_3_OFFSET 0xA0
+#define GPIO_PAD_PULL_DIR_4_OFFSET 0xA4
+#define GPIO_PAD_PULL_DIR_5_OFFSET 0x10C
+#define GPIO_PAD_PULL_DIR_6_OFFSET 0x110
+
+#define GPIO_PAD_PULL_EN_OFFSET(bank) ((bank) >= 5 ? \
+ (0x100 + (((bank) - 5) * 4)) : \
+ (0x80 + ((bank) * 4)))
+#define GPIO_PAD_PULL_DIR_OFFSET(bank) ((bank) >= 5 ? \
+ (0x10C + (((bank) - 5) * 4)) : \
+ (0x94 + ((bank) * 4)))
+
+#define GPIO_PAD_PULL_BASE (APB_BASE + GPIO_PAD_PULL_OFFSET)
+#define GPIO_PAD_PULL_REG(x) (GPIO_PAD_PULL_BASE + (x))
+
+/* ==========================================================================*/
+#define GPIO_DATA_OFFSET 0x00
+#define GPIO_DIR_OFFSET 0x04
+#define GPIO_IS_OFFSET 0x08
+#define GPIO_IBE_OFFSET 0x0c
+#define GPIO_IEV_OFFSET 0x10
+#define GPIO_IE_OFFSET 0x14
+#define GPIO_AFSEL_OFFSET 0x18
+#define GPIO_RIS_OFFSET 0x1c
+#define GPIO_MIS_OFFSET 0x20
+#define GPIO_IC_OFFSET 0x24
+#define GPIO_MASK_OFFSET 0x28
+#define GPIO_ENABLE_OFFSET 0x2c
+
+/* ==========================================================================*/
+#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+#define IOMUX_SUPPORT 1
+#else
+#define IOMUX_SUPPORT 0
+#endif
+
+#define IOMUX_REG0_0_OFFSET 0x00
+#define IOMUX_REG0_1_OFFSET 0x04
+#define IOMUX_REG0_2_OFFSET 0x08
+#define IOMUX_REG1_0_OFFSET 0x0c
+#define IOMUX_REG1_1_OFFSET 0x10
+#define IOMUX_REG1_2_OFFSET 0x14
+#define IOMUX_REG2_0_OFFSET 0x18
+#define IOMUX_REG2_1_OFFSET 0x1c
+#define IOMUX_REG2_2_OFFSET 0x20
+#define IOMUX_REG3_0_OFFSET 0x24
+#define IOMUX_REG3_1_OFFSET 0x28
+#define IOMUX_REG3_2_OFFSET 0x2c
+#define IOMUX_REG4_0_OFFSET 0x30
+#define IOMUX_REG4_1_OFFSET 0x34
+#define IOMUX_REG4_2_OFFSET 0x38
+#define IOMUX_REG5_0_OFFSET 0x3c
+#define IOMUX_REG5_1_OFFSET 0x40
+#define IOMUX_REG5_2_OFFSET 0x44
+#define IOMUX_REG6_0_OFFSET 0x48
+#define IOMUX_REG6_1_OFFSET 0x4c
+#define IOMUX_REG6_2_OFFSET 0x50
+#define IOMUX_CTRL_SET_OFFSET 0xf0
+#define IOMUX_REG_OFFSET(bank, n) (((bank) * 0xc) + ((n) * 4))
+
+#define IOMUX_OFFSET 0x16000
+#define IOMUX_BASE (APB_BASE + IOMUX_OFFSET)
+#define IOMUX_REG(x) (IOMUX_BASE + (x))
+
+/* ==========================================================================*/
+#define GPIO_BANK_SIZE 32
+#define AMBGPIO_SIZE (GPIO_INSTANCES * GPIO_BANK_SIZE)
+
+#ifndef CONFIG_AMBARELLA_EXT_GPIO_NUM
+#define CONFIG_AMBARELLA_EXT_GPIO_NUM (64)
+#endif
+#define EXT_GPIO(x) (AMBGPIO_SIZE + x)
+
+#define ARCH_NR_GPIOS EXT_GPIO(CONFIG_AMBARELLA_EXT_GPIO_NUM)
+
+/* ==========================================================================*/
+#define GPIO(x) (x)
+
+#define GPIO_HIGH 1
+#define GPIO_LOW 0
+
+#define GPIO_FUNC_SW_INPUT 0
+#define GPIO_FUNC_SW_OUTPUT 1
+#define GPIO_FUNC_HW 2
+
+/* ==========================================================================*/
+#ifndef __ASSEMBLER__
+
+#endif /* __ASSEMBLER__ */
+/* ==========================================================================*/
+
+#endif /* __PLAT_AMBARELLA_GPIO_H__ */
+
diff --git a/arch/arm/mach-ambarella/include/plat/highres_timer.h b/arch/arm/mach-ambarella/include/plat/highres_timer.h
new file mode 100644
index 00000000..2f673268
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/highres_timer.h
@@ -0,0 +1,32 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/highres_timer.h
+ *
+ * Author: Louis Sun <lysun@ambarella.com>
+ *
+ * Copyright (C) 2004-2011, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_HIGHRES_TIMER_H
+#define __PLAT_AMBARELLA_HIGHRES_TIMER_H
+
+extern void highres_timer_init(struct hrtimer *timer, clockid_t clock_id, enum hrtimer_mode mode);
+extern int highres_timer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode);
+extern int highres_timer_cancel(struct hrtimer *timer);
+
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/plat/hwlock.h b/arch/arm/mach-ambarella/include/plat/hwlock.h
new file mode 100644
index 00000000..a3aab6e5
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/hwlock.h
@@ -0,0 +1,43 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/hwlock.h
+ *
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_HWLOCK_H__
+#define __PLAT_AMBARELLA_HWLOCK_H__
+
+/* ==========================================================================*/
+#ifndef __ASSEMBLER__
+
+#include <linux/spinlock.h>
+extern spinlock_t ambarella_global_hw_lock;
+extern unsigned long ambarella_global_hw_flags;
+
+#define AMBARELLA_GLOBAL_HW_LOCK() \
+ spin_lock_irqsave(&ambarella_global_hw_lock, ambarella_global_hw_flags)
+#define AMBARELLA_GLOBAL_HW_UNLOCK() \
+ spin_unlock_irqrestore(&ambarella_global_hw_lock, ambarella_global_hw_flags)
+
+#endif /* __ASSEMBLER__ */
+/* ==========================================================================*/
+
+#endif /* __PLAT_AMBARELLA_HWLOCK_H__ */
+
diff --git a/arch/arm/mach-ambarella/include/plat/iav_helper.h b/arch/arm/mach-ambarella/include/plat/iav_helper.h
new file mode 100644
index 00000000..f74a7936
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/iav_helper.h
@@ -0,0 +1,85 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/service.h
+ *
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * Copyright (C) 2012-2016, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_SERVICE_H
+#define __PLAT_AMBARELLA_SERVICE_H
+
+#ifndef __ASSEMBLER__
+
+/*===========================================================================*/
+
+/* gpio service for private operation */
+enum ambsvc_gpio_service_id {
+ AMBSVC_GPIO_REQUEST = 0,
+ AMBSVC_GPIO_OUTPUT,
+ AMBSVC_GPIO_INPUT,
+ AMBSVC_GPIO_FREE,
+ AMBSVC_GPIO_TO_IRQ,
+};
+
+struct ambsvc_gpio {
+ int svc_id;
+ int gpio;
+ int value;
+};
+
+/* pll service for private operation */
+enum ambsvc_pll_service_id {
+ AMBSVC_PLL_GET_RATE = 0,
+ AMBSVC_PLL_SET_RATE = 1,
+};
+
+struct ambsvc_pll {
+ int svc_id;
+ char *name;
+ int rate;
+};
+
+enum ambarella_service_id {
+ AMBARELLA_SERVICE_GPIO = 1,
+ AMBARELLA_SERVICE_PLL = 2,
+};
+
+typedef int (*ambarella_service_func)(void *arg, void *result);
+
+struct ambarella_service {
+ int service;
+ ambarella_service_func func;
+ struct list_head node;
+};
+
+extern int ambarella_register_service(struct ambarella_service *amb_svc);
+extern int ambarella_unregister_service(struct ambarella_service *amb_svc);
+extern int ambarella_request_service(int service, void *arg, void *result);
+
+/*===========================================================================*/
+extern void ambcache_clean_all(void *addr, unsigned int size);
+extern void ambcache_clean_range(void *addr, unsigned int size);
+extern void ambcache_inv_range(void *addr, unsigned int size);
+
+/*===========================================================================*/
+
+#endif /* __ASSEMBLER__ */
+
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/plat/idc.h b/arch/arm/mach-ambarella/include/plat/idc.h
new file mode 100644
index 00000000..bcf1dc31
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/idc.h
@@ -0,0 +1,93 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/idc.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_IDC_H__
+#define __PLAT_AMBARELLA_IDC_H__
+
+/* ==========================================================================*/
+#if (CHIP_REV == A5S) || (CHIP_REV == A7L)
+#define IDC_INSTANCES 2
+#define IDC_SUPPORT_INTERNAL_MUX 1
+#define IDC3_BUS_MUX GPIO(36)
+#else
+#define IDC_INSTANCES 3
+#define IDC_SUPPORT_INTERNAL_MUX 0
+#endif
+
+/* ==========================================================================*/
+#define IDC_OFFSET 0x3000
+#define IDC_BASE (APB_BASE + IDC_OFFSET)
+#define IDC_REG(x) (IDC_BASE + (x))
+
+#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+#define IDC2_OFFSET 0x1000
+#else
+#define IDC2_OFFSET 0x7000
+#endif
+#define IDC2_BASE (APB_BASE + IDC2_OFFSET)
+#define IDC2_REG(x) (IDC2_BASE + (x))
+
+#if (CHIP_REV == S2) || (CHIP_REV == S2E)
+#define IDC3_OFFSET 0x13000
+#elif (CHIP_REV == A8)
+#define IDC3_OFFSET 0xE000
+#elif (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+#define IDC3_OFFSET 0x7000
+#endif
+#define IDC3_BASE (APB_BASE + IDC3_OFFSET)
+#define IDC3_REG(x) (IDC3_BASE + (x))
+
+/* ==========================================================================*/
+#define IDC_ENR_OFFSET 0x00
+#define IDC_CTRL_OFFSET 0x04
+#define IDC_DATA_OFFSET 0x08
+#define IDC_STS_OFFSET 0x0c
+#define IDC_PSLL_OFFSET 0x10
+#define IDC_PSLH_OFFSET 0x14
+#define IDC_FMCTRL_OFFSET 0x18
+#define IDC_FMDATA_OFFSET 0x1c
+#define IDC_DUTYCYCLE_OFFSET 0x24
+#define IDC_STRETCHSCL_OFFSET 0x28
+
+#define IDC_ENR_REG_ENABLE (0x01)
+#define IDC_ENR_REG_DISABLE (0x00)
+
+#define IDC_CTRL_STOP (0x08)
+#define IDC_CTRL_START (0x04)
+#define IDC_CTRL_IF (0x02)
+#define IDC_CTRL_ACK (0x01)
+#define IDC_CTRL_CLS (0x00)
+
+#define IDC_STS_FIFO_EMP (0x04)
+#define IDC_STS_FIFO_FUL (0x02)
+
+#define IDC_FIFO_BUF_SIZE (63)
+
+#define IDC_FMCTRL_STOP (0x08)
+#define IDC_FMCTRL_START (0x04)
+#define IDC_FMCTRL_IF (0x02)
+
+/* ==========================================================================*/
+
+#endif /* __PLAT_AMBARELLA_IDC_H__ */
+
diff --git a/arch/arm/mach-ambarella/include/plat/ir.h b/arch/arm/mach-ambarella/include/plat/ir.h
new file mode 100644
index 00000000..7babbc74
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/ir.h
@@ -0,0 +1,58 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/ir.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_IR_H__
+#define __PLAT_AMBARELLA_IR_H__
+
+/* ==========================================================================*/
+#define IR_OFFSET 0x6000
+#define IR_BASE (APB_BASE + IR_OFFSET)
+#define IR_REG(x) (IR_BASE + (x))
+
+/* ==========================================================================*/
+#define IR_CONTROL_OFFSET 0x00
+#define IR_STATUS_OFFSET 0x04
+#define IR_DATA_OFFSET 0x08
+
+#define IR_CONTROL_REG IR_REG(0x00)
+#define IR_STATUS_REG IR_REG(0x04)
+#define IR_DATA_REG IR_REG(0x08)
+
+/* IR_CONTROL_REG */
+#define IR_CONTROL_RESET 0x00004000
+#define IR_CONTROL_ENB 0x00002000
+#define IR_CONTROL_LEVINT 0x00001000
+#define IR_CONTROL_INTLEV(x) (((x) & 0x3f) << 4)
+#define IR_CONTROL_FIFO_OV 0x00000008
+#define IR_CONTROL_INTENB 0x00000004
+
+enum ambarella_ir_protocol {
+ AMBA_IR_PROTOCOL_NEC = 0,
+ AMBA_IR_PROTOCOL_PANASONIC = 1,
+ AMBA_IR_PROTOCOL_SONY = 2,
+ AMBA_IR_PROTOCOL_PHILIPS = 3,
+ AMBA_IR_PROTOCOL_END
+};
+
+#endif /* __PLAT_AMBARELLA_IR_H__ */
+
diff --git a/arch/arm/mach-ambarella/include/plat/irq.h b/arch/arm/mach-ambarella/include/plat/irq.h
new file mode 100644
index 00000000..7786c423
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/irq.h
@@ -0,0 +1,946 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/irq.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_IRQ_H__
+#define __PLAT_AMBARELLA_IRQ_H__
+
+/* ==========================================================================*/
+#if (CHIP_REV == A5S)
+#define VIC_INSTANCES (2)
+#define VIC_SUPPORT_CPU_OFFLOAD (0)
+#define VIC_SUPPORT_REPRIORITIZE (0)
+#elif (CHIP_REV == A7L)
+#define VIC_INSTANCES (2)
+#define VIC_SUPPORT_CPU_OFFLOAD (1)
+#define VIC_SUPPORT_REPRIORITIZE (1)
+#elif (CHIP_REV == S2)
+#define VIC_INSTANCES (3)
+#define VIC_SUPPORT_CPU_OFFLOAD (0)
+#define VIC_SUPPORT_REPRIORITIZE (0)
+#elif (CHIP_REV == S2E) || (CHIP_REV == S3L)
+#define VIC_INSTANCES (3)
+#define VIC_SUPPORT_CPU_OFFLOAD (2)
+#define VIC_SUPPORT_REPRIORITIZE (1)
+#elif (CHIP_REV == A8)
+#define VIC_INSTANCES (3)
+#define VIC_SUPPORT_CPU_OFFLOAD (1)
+#define VIC_SUPPORT_REPRIORITIZE (1)
+#elif (CHIP_REV == S2L)
+#define VIC_INSTANCES (3)
+#define VIC_SUPPORT_CPU_OFFLOAD (1)
+#define VIC_SUPPORT_REPRIORITIZE (1)
+#elif (CHIP_REV == S3)
+#define VIC_INSTANCES (4)
+#define VIC_SUPPORT_CPU_OFFLOAD (2)
+#define VIC_SUPPORT_REPRIORITIZE (1)
+#else
+#error "Not supported!"
+#endif
+
+#if (VIC_SUPPORT_CPU_OFFLOAD == 2)
+#if (CHIP_REV == S3)
+#define VIC_NULL_PRI_IRQ_VAL (0x00000060)
+#define VIC_NULL_PRI_IRQ_FIX (0)
+#elif (CHIP_REV == S2E)
+#define VIC_NULL_PRI_IRQ_VAL (0x00000040)
+#define VIC_NULL_PRI_IRQ_FIX (1)
+#else
+#define VIC_NULL_PRI_IRQ_VAL (0xffffffff)
+#define VIC_NULL_PRI_IRQ_FIX (0)
+#endif
+#endif
+
+#if (CHIP_REV == S3) || (CHIP_REV == S3L)
+#define VIC_2NDGEN_BITASSIGNMENT (1)
+#endif
+
+/* ==========================================================================*/
+#define VIC0_OFFSET 0x3000
+#define VIC1_OFFSET 0x10000
+#define VIC2_OFFSET 0x1C000
+#define VIC3_OFFSET 0x11000
+
+#define VIC0_BASE (AHB_BASE + VIC0_OFFSET)
+#define VIC1_BASE (AHB_BASE + VIC1_OFFSET)
+#define VIC2_BASE (AHB_BASE + VIC2_OFFSET)
+#define VIC3_BASE (AHB_BASE + VIC3_OFFSET)
+
+#define VIC0_REG(x) (VIC0_BASE + (x))
+#define VIC1_REG(x) (VIC1_BASE + (x))
+#define VIC2_REG(x) (VIC2_BASE + (x))
+#define VIC3_REG(x) (VIC3_BASE + (x))
+#define VIC_REG(irq, x) ((irq) < VIC0_INT_VEC(NR_VIC_IRQ_SIZE) ? VIC0_REG((x)) : \
+ (irq) < VIC1_INT_VEC(NR_VIC_IRQ_SIZE) ? VIC1_REG((x)) : \
+ (irq) < VIC2_INT_VEC(NR_VIC_IRQ_SIZE) ? VIC2_REG((x)) : \
+ VIC3_REG((x)))
+
+/* ==========================================================================*/
+#define NR_VIC_IRQ_SIZE (32)
+
+#if defined(CONFIG_ARM_GIC)
+#define VIC_IRQ(x) ((x) + 32)
+#define NR_SPI_IRQS (256)
+#define SGI_INT_VEC(x) (x)
+#define PPI_INT_VEC(x) (x)
+#define SPI_INT_VEC(x) (x)
+#else
+#define VIC_IRQ(x) (x)
+#endif
+
+#define VIC0_INT_VEC(x) (VIC_IRQ(x) + NR_VIC_IRQ_SIZE * 0)
+#define VIC1_INT_VEC(x) (VIC_IRQ(x) + NR_VIC_IRQ_SIZE * 1)
+#define VIC2_INT_VEC(x) (VIC_IRQ(x) + NR_VIC_IRQ_SIZE * 2)
+#define VIC3_INT_VEC(x) (VIC_IRQ(x) + NR_VIC_IRQ_SIZE * 3)
+
+#ifndef NR_SPI_IRQS
+#define NR_VIC_IRQS (VIC_INSTANCES * NR_VIC_IRQ_SIZE)
+#define GPIO_INT_VEC(x) (NR_VIC_IRQS + x)
+#else
+#define NR_VIC_IRQS NR_SPI_IRQS
+#define GPIO_INT_VEC(x) (NR_SPI_IRQS + x)
+#endif
+
+#ifndef CONFIG_AMBARELLA_EXT_IRQ_NUM
+#define CONFIG_AMBARELLA_EXT_IRQ_NUM (64)
+#endif
+#define EXT_IRQ(x) GPIO_INT_VEC(AMBGPIO_SIZE + x)
+
+#define NR_IRQS EXT_IRQ(CONFIG_AMBARELLA_EXT_IRQ_NUM)
+
+/* ==========================================================================*/
+#define VIC_IRQ_STA_OFFSET (0x00)
+#define VIC_FIQ_STA_OFFSET (0x04)
+#define VIC_RAW_STA_OFFSET (0x08)
+#define VIC_INT_SEL_OFFSET (0x0c)
+#define VIC_INTEN_OFFSET (0x10)
+#define VIC_INTEN_CLR_OFFSET (0x14)
+#define VIC_SOFTEN_OFFSET (0x18)
+#define VIC_SOFTEN_CLR_OFFSET (0x1c)
+#define VIC_PROTEN_OFFSET (0x20)
+#define VIC_SENSE_OFFSET (0x24)
+#define VIC_BOTHEDGE_OFFSET (0x28)
+#define VIC_EVENT_OFFSET (0x2c)
+#define VIC_INT_PTR0_OFFSET (0x30)
+#define VIC_INT_PTR1_OFFSET (0x34)
+#define VIC_EDGE_CLR_OFFSET (0x38)
+#define VIC_INT_SEL_INT_OFFSET (0x3c)
+#define VIC_INT_SEL_CLR_INT_OFFSET (0x40)
+#define VIC_INT_EN_INT_OFFSET (0x44)
+#define VIC_INT_EN_CLR_INT_OFFSET (0x48)
+#define VIC_SOFT_INT_INT_OFFSET (0x4c)
+#define VIC_SOFT_INT_CLR_INT_OFFSET (0x50)
+#define VIC_INT_SENSE_INT_OFFSET (0x54)
+#define VIC_INT_SENSE_CLR_INT_OFFSET (0x58)
+#define VIC_INT_BOTHEDGE_INT_OFFSET (0x5c)
+#define VIC_INT_BOTHEDGE_CLR_INT_OFFSET (0x60)
+#define VIC_INT_EVT_INT_OFFSET (0x64)
+#define VIC_INT_EVT_CLR_INT_OFFSET (0x68)
+#define VIC_INT_PENDING_OFFSET (0x6c)
+#define VIC_INT_RE_PRIORITIZE_EN_OFFSET (0x70)
+#define VIC_INT_PRIORITY_0_OFFSET (0x74)
+#define VIC_INT_PRIORITY_1_OFFSET (0x78)
+#define VIC_INT_PRIORITY_2_OFFSET (0x7c)
+#define VIC_INT_PRIORITY_3_OFFSET (0x80)
+#define VIC_INT_PRIORITY_4_OFFSET (0x84)
+#define VIC_INT_PRIORITY_5_OFFSET (0x88)
+#define VIC_INT_DELAY_EN_OFFSET (0x8c)
+#define VIC_INT_DELAY_OFFSET (0x90)
+#define VIC_INT_PENDING_C1_REG (0x94)
+#define VIC_INT_EDGE_CLR_OFFSET (0x98)
+
+/* ==========================================================================*/
+#if (CHIP_REV == A5S)
+#define USBVBUS_IRQ VIC0_INT_VEC(0)
+#define VOUT_IRQ VIC0_INT_VEC(1)
+#define VIN_IRQ VIC0_INT_VEC(2)
+#define VDSP_IRQ VIC0_INT_VEC(3)
+#define USBC_IRQ VIC0_INT_VEC(4)
+#define HIF_ARM1_IRQ VIC0_INT_VEC(5)
+#define HIF_ARM2_IRQ VIC0_INT_VEC(6)
+#define I2STX_IRQ VIC0_INT_VEC(7)
+#define I2SRX_IRQ VIC0_INT_VEC(8)
+#define UART0_IRQ VIC0_INT_VEC(9)
+#define GPIO0_IRQ VIC0_INT_VEC(10)
+#define GPIO1_IRQ VIC0_INT_VEC(11)
+#define TIMER1_IRQ VIC0_INT_VEC(12)
+#define TIMER2_IRQ VIC0_INT_VEC(13)
+#define TIMER3_IRQ VIC0_INT_VEC(14)
+#define DMA_IRQ VIC0_INT_VEC(15)
+#define FIOCMD_IRQ VIC0_INT_VEC(16)
+#define FIODMA_IRQ VIC0_INT_VEC(17)
+#define SD_IRQ VIC0_INT_VEC(18)
+#define IDC_IRQ VIC0_INT_VEC(19)
+#define SSI_IRQ VIC0_INT_VEC(20)
+#define WDT_IRQ VIC0_INT_VEC(21)
+#define IRIF_IRQ VIC0_INT_VEC(22)
+#define CFCD1_IRQ VIC0_INT_VEC(23)
+#define SD1CD_IRQ VIC0_INT_VEC(24)
+#define UART1_IRQ VIC0_INT_VEC(25)
+#define SSI_SLAVE_IRQ VIC0_INT_VEC(26)
+#define ETH_IRQ VIC0_INT_VEC(27)
+#define IDSP_ERROR_IRQ VIC0_INT_VEC(28)
+#define VOUT_SYNC_MISSED_IRQ VIC0_INT_VEC(29)
+#define GPIO2_IRQ VIC0_INT_VEC(30)
+#define CFCD2_IRQ VIC0_INT_VEC(31)
+
+#define AUDIO_ORC_IRQ VIC1_INT_VEC(0)
+#define DMA_FIOS_IRQ VIC1_INT_VEC(1)
+#define ADC_LEVEL_IRQ VIC1_INT_VEC(2)
+#define VOUT1_SYNC_MISSED_IRQ VIC1_INT_VEC(3)
+#define IDC2_IRQ VIC1_INT_VEC(4)
+#define IDSP_LAST_PIXEL_IRQ VIC1_INT_VEC(5)
+#define IDSP_VSYNC_IRQ VIC1_INT_VEC(6)
+#define IDSP_SENSOR_VSYNC_IRQ VIC1_INT_VEC(7)
+#define HDMI_IRQ VIC1_INT_VEC(8)
+#define SSI2_IRQ VIC1_INT_VEC(9)
+#define VOUT_TV_SYNC_IRQ VIC1_INT_VEC(10)
+#define VOUT_LCD_SYNC_IRQ VIC1_INT_VEC(11)
+#define ORC_VOUT0_IRQ VIC1_INT_VEC(12)
+#define AES_IRQ VIC1_INT_VEC(13)
+#define DES_IRQ VIC1_INT_VEC(14)
+#define MS_IRQ VIC1_INT_VEC(15)
+#define GDMA_IRQ VIC1_INT_VEC(16)
+#define MOTOR_IRQ VIC1_INT_VEC(17)
+#define PMU_IRQ VIC1_INT_VEC(31)
+
+/* ==========================================================================*/
+#elif (CHIP_REV == A7L)
+#define USBVBUS_IRQ VIC0_INT_VEC(0)
+#define VOUT_IRQ VIC0_INT_VEC(1)
+#define VIN_IRQ VIC0_INT_VEC(2)
+#define GDMA_IRQ VIC0_INT_VEC(3)
+#define USBC_IRQ VIC0_INT_VEC(4)
+#define SD1CD_IRQ VIC0_INT_VEC(5)
+#define VDSP_IRQ VIC0_INT_VEC(6)
+#define I2STX_IRQ VIC0_INT_VEC(7)
+#define I2SRX_IRQ VIC0_INT_VEC(8)
+#define UART0_IRQ VIC0_INT_VEC(9)
+#define GPIO0_IRQ VIC0_INT_VEC(10)
+#define GPIO1_IRQ VIC0_INT_VEC(11)
+#define TIMER1_IRQ VIC0_INT_VEC(12)
+#define TIMER2_IRQ VIC0_INT_VEC(13)
+#define TIMER3_IRQ VIC0_INT_VEC(14)
+#define DMA_IRQ VIC0_INT_VEC(15)
+#define FIOCMD_IRQ VIC0_INT_VEC(16)
+#define FIODMA_IRQ VIC0_INT_VEC(17)
+#define SD_IRQ VIC0_INT_VEC(18)
+#define IDC_IRQ VIC0_INT_VEC(19)
+#define SSI_IRQ VIC0_INT_VEC(20)
+#define WDT_IRQ VIC0_INT_VEC(21)
+#define IRIF_IRQ VIC0_INT_VEC(22)
+#define CFCD2_IRQ VIC0_INT_VEC(24)
+#define UART1_IRQ VIC0_INT_VEC(25)
+#define IDC2_IRQ VIC0_INT_VEC(26)
+#define IDSP_ERROR_IRQ VIC0_INT_VEC(28)
+#define GPIO2_IRQ VIC0_INT_VEC(30)
+
+#define PMU_IRQ VIC1_INT_VEC(0)
+#define DMA_FIOS_IRQ VIC1_INT_VEC(1)
+#define ADC_LEVEL_IRQ VIC1_INT_VEC(2)
+#define IDSP_LAST_PIXEL_IRQ VIC1_INT_VEC(5)
+#define IDSP_VSYNC_IRQ VIC1_INT_VEC(6)
+#define IDSP_SENSOR_VSYNC_IRQ VIC1_INT_VEC(7)
+#define HDMI_IRQ VIC1_INT_VEC(8)
+#define SSI_SLAVE_IRQ VIC1_INT_VEC(9)
+#define VOUT_TV_SYNC_IRQ VIC1_INT_VEC(10)
+#define VOUT_LCD_SYNC_IRQ VIC1_INT_VEC(11)
+#define ORC_VOUT0_IRQ VIC1_INT_VEC(12)
+#define MS_IRQ VIC1_INT_VEC(15)
+#define MOTOR_IRQ VIC1_INT_VEC(17)
+#define GPIO3_IRQ VIC1_INT_VEC(19)
+#define DRAM_ERROR_IRQ VIC1_INT_VEC(23)
+#define SD2_IRQ VIC1_INT_VEC(24)
+#define TIMER4_IRQ VIC1_INT_VEC(27)
+#define TIMER5_IRQ VIC1_INT_VEC(28)
+#define TIMER6_IRQ VIC1_INT_VEC(29)
+#define TIMER7_IRQ VIC1_INT_VEC(30)
+#define TIMER8_IRQ VIC1_INT_VEC(31)
+
+/* ==========================================================================*/
+#elif (CHIP_REV == S2)
+#define USBVBUS_IRQ VIC0_INT_VEC(0)
+#define USBC_IRQ VIC0_INT_VEC(4)
+#define USB_CHARGE_IRQ VIC0_INT_VEC(5)
+#define I2STX_IRQ VIC0_INT_VEC(7)
+#define I2SRX_IRQ VIC0_INT_VEC(8)
+#define UART0_IRQ VIC0_INT_VEC(9)
+#define GPIO0_IRQ VIC0_INT_VEC(10)
+#define GPIO1_IRQ VIC0_INT_VEC(11)
+#define DMA_IRQ VIC0_INT_VEC(15)
+#define FIOCMD_IRQ VIC0_INT_VEC(16)
+#define FIODMA_IRQ VIC0_INT_VEC(17)
+#define SD_IRQ VIC0_INT_VEC(18)
+#define IDC_IRQ VIC0_INT_VEC(19)
+#define SSI_IRQ VIC0_INT_VEC(20)
+#define IRIF_IRQ VIC0_INT_VEC(22)
+#define CFCD1_IRQ VIC0_INT_VEC(23)
+#define SD1CD_IRQ VIC0_INT_VEC(24)
+#define UART1_IRQ VIC0_INT_VEC(25)
+#define SSI_SLAVE_IRQ VIC0_INT_VEC(26)
+#define ETH_IRQ VIC0_INT_VEC(27)
+#define IDSP_SOFT_IRQ VIC0_INT_VEC(28)
+#define GPIO3_IRQ VIC0_INT_VEC(29)
+#define GPIO2_IRQ VIC0_INT_VEC(30)
+
+#define ROLLING_SHUTTER_IRQ VIC1_INT_VEC(0)
+#define DMA_FIOS_IRQ VIC1_INT_VEC(1)
+#define ADC_LEVEL_IRQ VIC1_INT_VEC(2)
+#define IDSP_VIN_SOFT_IRQ VIC1_INT_VEC(3)
+#define IDC2_IRQ VIC1_INT_VEC(4)
+#define IDSP_LAST_PIXEL_IRQ VIC1_INT_VEC(5)
+#define IDSP_VSYNC_IRQ VIC1_INT_VEC(6)
+#define IDSP_SENSOR_VSYNC_IRQ VIC1_INT_VEC(7)
+#define HDMI_IRQ VIC1_INT_VEC(8)
+#define FIOS_ECC_IRQ VIC1_INT_VEC(9)
+
+#define GPIO4_IRQ VIC1_INT_VEC(16)
+#define MOTOR_IRQ VIC1_INT_VEC(17)
+#define GDMA_IRQ VIC1_INT_VEC(18)
+#define FACE_DET_IRQ VIC1_INT_VEC(19)
+#define SD2_IRQ VIC1_INT_VEC(20)
+#define SSI_MASTER_IRQ VIC1_INT_VEC(21)
+#define IDSP_PROG_IRQ VIC1_INT_VEC(26)
+
+#define VDSP_PIP_SVSYNC_IRQ VIC2_INT_VEC(0)
+#define IDSP_PIP_SVSYNC_IRQ VIC2_INT_VEC(1)
+#define IDSP_PIP_PROG_IRQ VIC2_INT_VEC(2)
+#define IDSP_PIP_LAST_PIXEL_IRQ VIC2_INT_VEC(3)
+#define CORTEX_CORE0_IRQ VIC2_INT_VEC(4)
+#define CORTEX_CORE1_IRQ VIC2_INT_VEC(5)
+#define ETH_PMT_INTR_IRQ VIC2_INT_VEC(6)
+#define I2S1_RX_IRQ VIC2_INT_VEC(7)
+#define I2S1_TX_IRQ VIC2_INT_VEC(8)
+#define USB_EHCI_IRQ VIC2_INT_VEC(9)
+#define AXI_SOFT_IRQ(x) VIC2_INT_VEC((x) + 10) /* 0 <= x <= 13 */
+#define CORTEX_WDT_IRQ VIC2_INT_VEC(24)
+#define USB_OHCI_IRQ VIC2_INT_VEC(25)
+#define IDC3_IRQ VIC2_INT_VEC(26)
+#define UART2_IRQ VIC2_INT_VEC(27)
+#define UART3_IRQ VIC2_INT_VEC(28)
+#define PMU_IRQ VIC2_INT_VEC(31)
+
+#if defined(CONFIG_ARM_GIC)
+#define VOUT_IRQ VIC3_INT_VEC(0)
+#define VIN_IRQ VIC3_INT_VEC(1)
+#define TIMER1_IRQ VIC3_INT_VEC(2)
+#define TIMER2_IRQ VIC3_INT_VEC(3)
+#define TIMER3_IRQ VIC3_INT_VEC(4)
+#define WDT_IRQ VIC3_INT_VEC(5)
+#define VOUT_TV_SYNC_IRQ VIC3_INT_VEC(6)
+#define VOUT_LCD_SYNC_IRQ VIC3_INT_VEC(7)
+#define ORC_VOUT0_IRQ VIC3_INT_VEC(8)
+#define TIMER4_IRQ VIC3_INT_VEC(9)
+#define TIMER5_IRQ VIC3_INT_VEC(10)
+#define TIMER6_IRQ VIC3_INT_VEC(11)
+#define TIMER7_IRQ VIC3_INT_VEC(12)
+#define TIMER8_IRQ VIC3_INT_VEC(13)
+#define CODE_VDSP_0_IRQ VIC3_INT_VEC(14)
+#define CODE_VDSP_1_IRQ VIC3_INT_VEC(15)
+#define CODE_VDSP_2_IRQ VIC3_INT_VEC(16)
+#define CODE_VDSP_3_IRQ VIC3_INT_VEC(17)
+#define MD5_IRQ VIC3_INT_VEC(24)
+#define DES_IRQ VIC3_INT_VEC(25)
+#define AES_IRQ VIC3_INT_VEC(26)
+#define SHA1_IRQ VIC3_INT_VEC(27)
+#else
+#define VOUT_IRQ VIC0_INT_VEC(1)
+#define VIN_IRQ VIC0_INT_VEC(2)
+#define TIMER1_IRQ VIC0_INT_VEC(12)
+#define TIMER2_IRQ VIC0_INT_VEC(13)
+#define TIMER3_IRQ VIC0_INT_VEC(14)
+#define WDT_IRQ VIC0_INT_VEC(21)
+#define VOUT_TV_SYNC_IRQ VIC1_INT_VEC(10)
+#define VOUT_LCD_SYNC_IRQ VIC1_INT_VEC(11)
+#define ORC_VOUT0_IRQ VIC1_INT_VEC(14)
+#define TIMER4_IRQ VIC1_INT_VEC(27)
+#define TIMER5_IRQ VIC1_INT_VEC(28)
+#define TIMER6_IRQ VIC1_INT_VEC(29)
+#define TIMER7_IRQ VIC1_INT_VEC(30)
+#define TIMER8_IRQ VIC1_INT_VEC(31)
+#define CODE_VDSP_0_IRQ VIC0_INT_VEC(3)
+#define CODE_VDSP_1_IRQ VIC1_INT_VEC(24)
+#define CODE_VDSP_2_IRQ VIC1_INT_VEC(23)
+#define CODE_VDSP_3_IRQ VIC1_INT_VEC(22)
+#define DES_IRQ VIC1_INT_VEC(12)
+#define AES_IRQ VIC1_INT_VEC(13)
+#define MD5_SHA1_IRQ VIC1_INT_VEC(25)
+#endif
+
+#define GLOBAL_TIMER_IRQ PPI_INT_VEC(27)
+#define LEGACY_FIQ PPI_INT_VEC(28)
+#define LOCAL_TIMER_IRQ PPI_INT_VEC(29)
+#define LOCAL_WDOG_IRQ PPI_INT_VEC(30)
+#define LEGACY_IRQ PPI_INT_VEC(31)
+
+#define DDD_IRQ SPI_INT_VEC(153)
+#define DECODE_ERROR_IRQ SPI_INT_VEC(154)
+#define SLAVE_ERROR_IRQ SPI_INT_VEC(155)
+#define FMEM_READ_ERROR_IRQ SPI_INT_VEC(156)
+#define FMEM_WRITE_ERROR_IRQ SPI_INT_VEC(157)
+#define L2CC_ECNTR_IRQ SPI_INT_VEC(158)
+#define L2CC_COMBINED_IRQ SPI_INT_VEC(159)
+
+/* ==========================================================================*/
+#elif (CHIP_REV == S2E)
+#define USBVBUS_IRQ VIC0_INT_VEC(0)
+#define VOUT_IRQ VIC0_INT_VEC(1)
+#define VIN_IRQ VIC0_INT_VEC(2)
+#define CODE_VDSP_0_IRQ VIC0_INT_VEC(3)
+#define USBC_IRQ VIC0_INT_VEC(4)
+#define USB_CHARGE_IRQ VIC0_INT_VEC(5)
+#define PMU_IRQ VIC0_INT_VEC(6)
+#define I2STX_IRQ VIC0_INT_VEC(7)
+#define I2SRX_IRQ VIC0_INT_VEC(8)
+#define UART0_IRQ VIC0_INT_VEC(9)
+#define GPIO0_IRQ VIC0_INT_VEC(10)
+#define GPIO1_IRQ VIC0_INT_VEC(11)
+#define TIMER1_IRQ VIC0_INT_VEC(12)
+#define TIMER2_IRQ VIC0_INT_VEC(13)
+#define TIMER3_IRQ VIC0_INT_VEC(14)
+#define DMA_IRQ VIC0_INT_VEC(15)
+#define FIOCMD_IRQ VIC0_INT_VEC(16)
+#define FIODMA_IRQ VIC0_INT_VEC(17)
+#define SD_IRQ VIC0_INT_VEC(18)
+#define IDC_IRQ VIC0_INT_VEC(19)
+#define SSI_IRQ VIC0_INT_VEC(20)
+#define WDT_IRQ VIC0_INT_VEC(21)
+#define IRIF_IRQ VIC0_INT_VEC(22)
+#define SD1CD_IRQ VIC0_INT_VEC(23)
+#define SD0CD_IRQ VIC0_INT_VEC(24)
+#define UART1_IRQ VIC0_INT_VEC(25)
+#define SSI_SLAVE_IRQ VIC0_INT_VEC(26)
+#define ETH_IRQ VIC0_INT_VEC(27)
+#define IDSP_SOFT_IRQ VIC0_INT_VEC(28)
+#define GPIO3_IRQ VIC0_INT_VEC(29)
+#define GPIO2_IRQ VIC0_INT_VEC(30)
+#define PMU1_IRQ VIC0_INT_VEC(31)
+
+#define ROLLING_SHUTTER_IRQ VIC1_INT_VEC(0)
+#define DMA_FIOS_IRQ VIC1_INT_VEC(1)
+#define ADC_LEVEL_IRQ VIC1_INT_VEC(2)
+#define IDSP_VIN_SOFT_IRQ VIC1_INT_VEC(3)
+#define IDC2_IRQ VIC1_INT_VEC(4)
+#define IDSP_LAST_PIXEL_IRQ VIC1_INT_VEC(5)
+#define IDSP_VSYNC_IRQ VIC1_INT_VEC(6)
+#define IDSP_SENSOR_VSYNC_IRQ VIC1_INT_VEC(7)
+#define HDMI_IRQ VIC1_INT_VEC(8)
+#define FIOS_ECC_IRQ VIC1_INT_VEC(9)
+#define VOUT_TV_SYNC_IRQ VIC1_INT_VEC(10)
+#define VOUT_LCD_SYNC_IRQ VIC1_INT_VEC(11)
+#define AES_IRQ VIC1_INT_VEC(12)
+#define DES_IRQ VIC1_INT_VEC(13)
+#define ORC_VOUT0_IRQ VIC1_INT_VEC(14)
+#define MD5_IRQ VIC1_INT_VEC(15)
+#define GPIO4_IRQ VIC1_INT_VEC(16)
+#define MOTOR_IRQ VIC1_INT_VEC(17)
+#define GDMA_IRQ VIC1_INT_VEC(18)
+#define L2CC_INTR1_IRQ VIC1_INT_VEC(19)
+#define SD2_IRQ VIC1_INT_VEC(20)
+#define SSI_MASTER_IRQ VIC1_INT_VEC(21)
+#define CODE_VDSP_3_IRQ VIC1_INT_VEC(22)
+#define CODE_VDSP_2_IRQ VIC1_INT_VEC(23)
+#define CODE_VDSP_1_IRQ VIC1_INT_VEC(24)
+#define L2CC_INTR_IRQ VIC1_INT_VEC(25)
+#define IDSP_PROG_IRQ VIC1_INT_VEC(26)
+#define TIMER4_IRQ VIC1_INT_VEC(27)
+#define TIMER5_IRQ VIC1_INT_VEC(28)
+#define TIMER6_IRQ VIC1_INT_VEC(29)
+#define TIMER7_IRQ VIC1_INT_VEC(30)
+#define TIMER8_IRQ VIC1_INT_VEC(31)
+
+#define VDSP_PIP_SVSYNC_IRQ VIC2_INT_VEC(0)
+#define IDSP_PIP_SVSYNC_IRQ VIC2_INT_VEC(1)
+#define IDSP_PIP_PROG_IRQ VIC2_INT_VEC(2)
+#define IDSP_PIP_LAST_PIXEL_IRQ VIC2_INT_VEC(3)
+#define CORTEX_CORE0_IRQ VIC2_INT_VEC(4)
+#define CORTEX_CORE1_IRQ VIC2_INT_VEC(5)
+#define ETH_PMT_INTR_IRQ VIC2_INT_VEC(6)
+#define I2S1_RX_IRQ VIC2_INT_VEC(7)
+#define I2S1_TX_IRQ VIC2_INT_VEC(8)
+#define USB_EHCI_IRQ VIC2_INT_VEC(9)
+#define IPI00_IRQ VIC2_INT_VEC(10)
+#define IPI01_IRQ VIC2_INT_VEC(11)
+#define IPI02_IRQ VIC2_INT_VEC(12)
+#define IPI03_IRQ VIC2_INT_VEC(13)
+#define IPI04_IRQ VIC2_INT_VEC(14)
+#define IPI05_IRQ VIC2_INT_VEC(15)
+#define IPI06_IRQ VIC2_INT_VEC(16)
+#define IPI10_IRQ VIC2_INT_VEC(17)
+#define IPI11_IRQ VIC2_INT_VEC(18)
+#define IPI12_IRQ VIC2_INT_VEC(19)
+#define IPI13_IRQ VIC2_INT_VEC(20)
+#define IPI14_IRQ VIC2_INT_VEC(21)
+#define IPI15_IRQ VIC2_INT_VEC(22)
+#define IPI16_IRQ VIC2_INT_VEC(23)
+#define SHA1_IRQ VIC2_INT_VEC(24)
+#define USB_OHCI_IRQ VIC2_INT_VEC(25)
+#define IDC3_IRQ VIC2_INT_VEC(26)
+#define UART2_IRQ VIC2_INT_VEC(27)
+#define UART3_IRQ VIC2_INT_VEC(28)
+
+/* ==========================================================================*/
+#elif (CHIP_REV == A8)
+#define USBVBUS_IRQ VIC0_INT_VEC(0)
+#define ROLLING_SHUTTER_IRQ VIC0_INT_VEC(3)
+#define USBC_IRQ VIC0_INT_VEC(4)
+#define HIF_ARM1_IRQ VIC0_INT_VEC(5)
+#define HIF_ARM2_IRQ VIC0_INT_VEC(6)
+#define I2STX_IRQ VIC0_INT_VEC(7)
+#define I2SRX_IRQ VIC0_INT_VEC(8)
+#define UART0_IRQ VIC0_INT_VEC(9)
+#define GPIO0_IRQ VIC0_INT_VEC(10)
+#define GPIO1_IRQ VIC0_INT_VEC(11)
+#define DMA_IRQ VIC0_INT_VEC(15)
+#define FIOCMD_IRQ VIC0_INT_VEC(16)
+#define FIODMA_IRQ VIC0_INT_VEC(17)
+#define SD_IRQ VIC0_INT_VEC(18)
+#define IDC_IRQ VIC0_INT_VEC(19)
+#define SSI_IRQ VIC0_INT_VEC(20)
+#define IRIF_IRQ VIC0_INT_VEC(22)
+#define CFCD1_IRQ VIC0_INT_VEC(23)
+#define SD1CD_IRQ VIC0_INT_VEC(24)
+#define UART1_IRQ VIC0_INT_VEC(25)
+#define SSI_SLAVE_IRQ VIC0_INT_VEC(26)
+#define ETH_IRQ VIC0_INT_VEC(27)
+#define IDSP_SOFT_IRQ VIC0_INT_VEC(28)
+#define ETH_POWER_IRQ VIC0_INT_VEC(29)
+#define GPIO2_IRQ VIC0_INT_VEC(30)
+#define CFCD2_IRQ VIC0_INT_VEC(31)
+
+#define DRAM_AXI_ERROR_IRQ VIC1_INT_VEC(0)
+#define DMA_FIOS_IRQ VIC1_INT_VEC(1)
+#define ADC_LEVEL_IRQ VIC1_INT_VEC(2)
+#define SSI3_IRQ VIC1_INT_VEC(3)
+#define IDC2_IRQ VIC1_INT_VEC(4)
+#define IDSP_LAST_PIXEL_IRQ VIC1_INT_VEC(5)
+#define IDSP_VSYNC_IRQ VIC1_INT_VEC(6)
+#define IDSP_SENSOR_VSYNC_IRQ VIC1_INT_VEC(7)
+#define HDMI_IRQ VIC1_INT_VEC(8)
+#define SSI2_IRQ VIC1_INT_VEC(9)
+#define AES_IRQ VIC1_INT_VEC(13)
+#define DES_IRQ VIC1_INT_VEC(14)
+#define MS_IRQ VIC1_INT_VEC(15)
+#define USB_EHCI_IRQ VIC1_INT_VEC(16)
+#define MOTOR_IRQ VIC1_INT_VEC(17)
+#define MD5_SHA1_IRQ VIC1_INT_VEC(18)
+#define GPIO3_IRQ VIC1_INT_VEC(19)
+#define GPIO4_IRQ VIC1_INT_VEC(20)
+#define GPIO5_IRQ VIC1_INT_VEC(21)
+#define SATA_IRQ VIC1_INT_VEC(22)
+#define DRAM_ERROR_IRQ VIC1_INT_VEC(23)
+#define SD2_IRQ VIC1_INT_VEC(24)
+#define UART2_IRQ VIC1_INT_VEC(25)
+#define UART3_IRQ VIC1_INT_VEC(26)
+
+#define GSSI_IRQ VIC2_INT_VEC(0)
+#define SSI4_IRQ VIC2_INT_VEC(1)
+#define PMU_IRQ VIC2_INT_VEC(2)
+#define SD2CD_IRQ VIC2_INT_VEC(3)
+#define CORTEX_CORE0_IRQ VIC2_INT_VEC(4)
+#define CORTEX_CORE1_IRQ VIC2_INT_VEC(5)
+#define TS_CH1_RX_IRQ VIC2_INT_VEC(6)
+#define TS_CH0_RX_IRQ VIC2_INT_VEC(7)
+#define TS_CH1_TX_IRQ VIC2_INT_VEC(8)
+#define TS_CH0_TX_IRQ VIC2_INT_VEC(9)
+#define AXI_SOFT_IRQ(x) VIC2_INT_VEC((x) + 10) /* 0 <= x <= 13 */
+#define CORTEX_WDT_IRQ VIC2_INT_VEC(24)
+#define USB_OHCI_IRQ VIC2_INT_VEC(25)
+#define SPDIF_IRQ VIC2_INT_VEC(26)
+#define SSI_AHB_IRQ VIC2_INT_VEC(27)
+#define IDC3_IRQ VIC2_INT_VEC(28)
+
+#if defined(CONFIG_ARM_GIC)
+#define VOUT_IRQ VIC3_INT_VEC(0)
+#define VIN_IRQ VIC3_INT_VEC(1)
+#define TIMER1_IRQ VIC3_INT_VEC(2)
+#define TIMER2_IRQ VIC3_INT_VEC(3)
+#define TIMER3_IRQ VIC3_INT_VEC(4)
+#define WDT_IRQ VIC3_INT_VEC(5)
+#define VOUT_TV_SYNC_IRQ VIC3_INT_VEC(6)
+#define VOUT_LCD_SYNC_IRQ VIC3_INT_VEC(7)
+#define ORC_VOUT0_IRQ VIC3_INT_VEC(8)
+#define TIMER4_IRQ VIC3_INT_VEC(9)
+#define TIMER5_IRQ VIC3_INT_VEC(10)
+#define TIMER6_IRQ VIC3_INT_VEC(11)
+#define TIMER7_IRQ VIC3_INT_VEC(12)
+#define TIMER8_IRQ VIC3_INT_VEC(13)
+#define CODING_ORC0_IRQ VIC3_INT_VEC(14)
+#define CODING_ORC1_IRQ VIC3_INT_VEC(15)
+#define CODING_ORC2_IRQ VIC3_INT_VEC(16)
+#define CODING_ORC3_IRQ VIC3_INT_VEC(17)
+#else
+#define VOUT_IRQ VIC0_INT_VEC(1)
+#define VIN_IRQ VIC0_INT_VEC(2)
+#define TIMER1_IRQ VIC0_INT_VEC(12)
+#define TIMER2_IRQ VIC0_INT_VEC(13)
+#define TIMER3_IRQ VIC0_INT_VEC(14)
+#define WDT_IRQ VIC0_INT_VEC(21)
+#define VOUT_TV_SYNC_IRQ VIC1_INT_VEC(10)
+#define VOUT_LCD_SYNC_IRQ VIC1_INT_VEC(11)
+#define ORC_VOUT0_IRQ VIC1_INT_VEC(12)
+#define TIMER4_IRQ VIC1_INT_VEC(27)
+#define TIMER5_IRQ VIC1_INT_VEC(28)
+#define TIMER6_IRQ VIC1_INT_VEC(29)
+#define TIMER7_IRQ VIC1_INT_VEC(30)
+#define TIMER8_IRQ VIC1_INT_VEC(31)
+#define CODING_ORC0_IRQ VIC2_INT_VEC(28)
+#define CODING_ORC1_IRQ VIC2_INT_VEC(29)
+#define CODING_ORC2_IRQ VIC2_INT_VEC(30)
+#define CODING_ORC3_IRQ VIC2_INT_VEC(31)
+#endif
+
+#define GLOBAL_TIMER_IRQ PPI_INT_VEC(27)
+#define LEGACY_FIQ PPI_INT_VEC(28)
+#define LOCAL_TIMER_IRQ PPI_INT_VEC(29)
+#define LOCAL_WDOG_IRQ PPI_INT_VEC(30)
+#define LEGACY_IRQ PPI_INT_VEC(31)
+
+#define DDD_IRQ SPI_INT_VEC(153)
+#define DECODE_ERROR_IRQ SPI_INT_VEC(154)
+#define SLAVE_ERROR_IRQ SPI_INT_VEC(155)
+#define FMEM_READ_ERROR_IRQ SPI_INT_VEC(156)
+#define FMEM_WRITE_ERROR_IRQ SPI_INT_VEC(157)
+#define L2CC_ECNTR_IRQ SPI_INT_VEC(158)
+#define L2CC_COMBINED_IRQ SPI_INT_VEC(159)
+
+/* ==========================================================================*/
+#elif (CHIP_REV == S2L)
+#define USBVBUS_IRQ VIC0_INT_VEC(0)
+#define VOUT_IRQ VIC0_INT_VEC(1)
+#define VIN_IRQ VIC0_INT_VEC(2)
+#define CODE_VDSP_0_IRQ VIC0_INT_VEC(3)
+#define USBC_IRQ VIC0_INT_VEC(4)
+#define USB_CHARGE_IRQ VIC0_INT_VEC(5)
+#define SD2CD_IRQ VIC0_INT_VEC(6)
+#define I2STX_IRQ VIC0_INT_VEC(7)
+#define I2SRX_IRQ VIC0_INT_VEC(8)
+#define UART0_IRQ VIC0_INT_VEC(9)
+#define GPIO0_IRQ VIC0_INT_VEC(10)
+#define GPIO1_IRQ VIC0_INT_VEC(11)
+#define TIMER1_IRQ VIC0_INT_VEC(12)
+#define TIMER2_IRQ VIC0_INT_VEC(13)
+#define TIMER3_IRQ VIC0_INT_VEC(14)
+#define DMA_IRQ VIC0_INT_VEC(15)
+#define FIOCMD_IRQ VIC0_INT_VEC(16)
+#define FIODMA_IRQ VIC0_INT_VEC(17)
+#define SD_IRQ VIC0_INT_VEC(18)
+#define IDC_IRQ VIC0_INT_VEC(19)
+#define SD3_IRQ VIC0_INT_VEC(20)
+#define WDT_IRQ VIC0_INT_VEC(21)
+#define IRIF_IRQ VIC0_INT_VEC(22)
+#define SD1CD_IRQ VIC0_INT_VEC(23)
+#define SD0CD_IRQ VIC0_INT_VEC(24)
+#define UART1_IRQ VIC0_INT_VEC(25)
+#define MOTOR_IRQ VIC0_INT_VEC(26)
+#define ETH_IRQ VIC0_INT_VEC(27)
+#define USB_CONNECT_CHANGE_IRQ VIC0_INT_VEC(28)
+#define GPIO3_IRQ VIC0_INT_VEC(29)
+#define GPIO2_IRQ VIC0_INT_VEC(30)
+
+#define ETH_PMT_IRQ VIC1_INT_VEC(0)
+#define DMA_FIOS_IRQ VIC1_INT_VEC(1)
+#define ADC_LEVEL_IRQ VIC1_INT_VEC(2)
+#define SSI_MASTER0_IRQ VIC1_INT_VEC(3)
+#define IDC3_IRQ VIC1_INT_VEC(4)
+#define SSI_MASTER1_IRQ VIC1_INT_VEC(5)
+#define SSI_SLAVE_IRQ VIC1_INT_VEC(6)
+#define USB_EHCI_IRQ VIC1_INT_VEC(7)
+#define HDMI_IRQ VIC1_INT_VEC(8)
+#define FIOS_ECC_IRQ VIC1_INT_VEC(9)
+#define VOUT_TV_SYNC_IRQ VIC1_INT_VEC(10)
+#define VOUT_LCD_SYNC_IRQ VIC1_INT_VEC(11)
+#define USB_OHCI_IRQ VIC1_INT_VEC(12)
+#define NOR_SPI VIC1_INT_VEC(13)
+#define ORC_VOUT0_IRQ VIC1_INT_VEC(14)
+#define GDMA_IRQ VIC1_INT_VEC(18)
+#define IDC2_IRQ VIC1_INT_VEC(19)
+#define SD2_IRQ VIC1_INT_VEC(20)
+#define IDSP_PIP_VSYNC_IRQ VIC1_INT_VEC(21)
+#define IDSP_PIP_SOF_IRQ VIC1_INT_VEC(22)
+#define IDSP_PIP_MVSYNC_IRQ VIC1_INT_VEC(23)
+#define IDSP_PIP_LAST_PIXEL_IRQ VIC1_INT_VEC(24)
+#define IDSP_PIP_DVSYNC_IRQ VIC1_INT_VEC(25)
+#define VDSP_PIP_CODING_IRQ VIC1_INT_VEC(26)
+#define TIMER4_IRQ VIC1_INT_VEC(27)
+#define TIMER5_IRQ VIC1_INT_VEC(28)
+#define TIMER6_IRQ VIC1_INT_VEC(29)
+#define TIMER7_IRQ VIC1_INT_VEC(30)
+#define TIMER8_IRQ VIC1_INT_VEC(31)
+
+#define IDSP_VIN_MVSYNC_IRQ VIC2_INT_VEC(0)
+#define IDSP_VIN_VSYNC_IRQ VIC2_INT_VEC(1)
+#define IDSP_VIN_SOF_IRQ VIC2_INT_VEC(2)
+#define IDSP_VIN_DVSYNC_IRQ VIC2_INT_VEC(3)
+#define IDSP_VIN_LAST_PIXEL_IRQ VIC2_INT_VEC(4)
+#define L2CC_INTR_IRQ VIC2_INT_VEC(21)
+#define MD5_IRQ VIC2_INT_VEC(22)
+#define DES_IRQ VIC2_INT_VEC(23)
+#define AES_IRQ VIC2_INT_VEC(24)
+#define SHA1_IRQ VIC2_INT_VEC(25)
+#define USB_DIGITAL_ID_CHANGE_IRQ VIC2_INT_VEC(27)
+#define PMU_IRQ VIC2_INT_VEC(28)
+#define L2CC_DECERR_IRQ VIC2_INT_VEC(29)
+#define L2CC_SLVERR_IRQ VIC2_INT_VEC(30)
+#define L2CC_ECNTR_IRQ VIC2_INT_VEC(31)
+
+/* ==========================================================================*/
+#elif (CHIP_REV == S3)
+#define IPI00_IRQ VIC0_INT_VEC(0)
+#define IPI01_IRQ VIC0_INT_VEC(1)
+#define IPI02_IRQ VIC0_INT_VEC(2)
+#define IPI03_IRQ VIC0_INT_VEC(3)
+#define IPI04_IRQ VIC0_INT_VEC(4)
+#define IPI05_IRQ VIC0_INT_VEC(5)
+#define IPI06_IRQ VIC0_INT_VEC(6)
+#define TIMER1_IRQ VIC0_INT_VEC(7)
+#define TIMER2_IRQ VIC0_INT_VEC(8)
+#define TIMER3_IRQ VIC0_INT_VEC(9)
+#define TIMER4_IRQ VIC0_INT_VEC(10)
+#define TIMER5_IRQ VIC0_INT_VEC(11)
+#define TIMER6_IRQ VIC0_INT_VEC(12)
+#define TIMER7_IRQ VIC0_INT_VEC(13)
+#define TIMER8_IRQ VIC0_INT_VEC(14)
+#define PMU_IRQ VIC0_INT_VEC(15)
+#define IPI10_IRQ VIC0_INT_VEC(16)
+#define IPI11_IRQ VIC0_INT_VEC(17)
+#define IPI12_IRQ VIC0_INT_VEC(18)
+#define IPI13_IRQ VIC0_INT_VEC(19)
+#define IPI14_IRQ VIC0_INT_VEC(20)
+#define IPI15_IRQ VIC0_INT_VEC(21)
+#define IPI16_IRQ VIC0_INT_VEC(22)
+#define TIMER11_IRQ VIC0_INT_VEC(23)
+#define TIMER12_IRQ VIC0_INT_VEC(24)
+#define TIMER13_IRQ VIC0_INT_VEC(25)
+#define TIMER14_IRQ VIC0_INT_VEC(26)
+#define TIMER15_IRQ VIC0_INT_VEC(27)
+#define TIMER16_IRQ VIC0_INT_VEC(28)
+#define TIMER17_IRQ VIC0_INT_VEC(29)
+#define TIMER18_IRQ VIC0_INT_VEC(30)
+#define PMU1_IRQ VIC0_INT_VEC(31)
+
+#define IDSP_VIN_STAT_IRQ VIC1_INT_VEC(0)
+#define IDSP_VIN_MVSYNC_IRQ VIC1_INT_VEC(1)
+#define IDSP_VIN_VSYNC_IRQ VIC1_INT_VEC(2)
+#define IDSP_VIN_SOF_IRQ VIC1_INT_VEC(3)
+#define IDSP_VIN_DVSYNC_IRQ VIC1_INT_VEC(4)
+#define IDSP_VIN_LAST_PIXEL_IRQ VIC1_INT_VEC(5)
+#define IDSP_PIP_STAT_IRQ VIC1_INT_VEC(6)
+#define IDSP_PIP_MVSYNC_IRQ VIC1_INT_VEC(7)
+#define IDSP_PIP_VSYNC_IRQ VIC1_INT_VEC(8)
+#define IDSP_PIP_SOF_IRQ VIC1_INT_VEC(9)
+#define IDSP_PIP_DVSYNC_IRQ VIC1_INT_VEC(10)
+#define IDSP_PIP_LAST_PIXEL_IRQ VIC1_INT_VEC(11)
+#define VOUT_TV_SYNC_IRQ VIC1_INT_VEC(12)
+#define VOUT_LCD_SYNC_IRQ VIC1_INT_VEC(13)
+#define CODE_VDSP_0_IRQ VIC1_INT_VEC(14)
+#define CODE_VDSP_1_IRQ VIC1_INT_VEC(15)
+#define CODE_VDSP_2_IRQ VIC1_INT_VEC(16)
+#define CODE_VDSP_3_IRQ VIC1_INT_VEC(17)
+#define CODE_VDSP_4_IRQ VIC1_INT_VEC(18)
+#define CODE_VDSP_5_IRQ VIC1_INT_VEC(19)
+#define CODE_VDSP_6_IRQ VIC1_INT_VEC(20)
+#define CODE_VDSP_7_IRQ VIC1_INT_VEC(21)
+#define VIN_IRQ VIC1_INT_VEC(22)
+#define ORC_VOUT0_IRQ VIC1_INT_VEC(23)
+#define VOUT_IRQ VIC1_INT_VEC(24)
+#define VDSP_ORC_BKPT_IRQ VIC1_INT_VEC(25)
+#define VDSP_EORC0_BKPT_IRQ VIC1_INT_VEC(26)
+#define VDSP_DORC_BRPT_IRQ VIC1_INT_VEC(27)
+#define VDSP_PIP_CODING_IRQ VIC1_INT_VEC(28)
+#define FDET_IRQ VIC1_INT_VEC(29)
+#define TIMER10_IRQ VIC1_INT_VEC(30)
+#define TIMER9_IRQ VIC1_INT_VEC(31)
+
+#define CANC_IRQ VIC2_INT_VEC(0)
+#define ETH_IRQ VIC2_INT_VEC(1)
+#define USB_EHCI_IRQ VIC2_INT_VEC(2)
+#define USB_OHCI_IRQ VIC2_INT_VEC(3)
+#define USBC_IRQ VIC2_INT_VEC(4)
+#define DMA_IRQ VIC2_INT_VEC(5)
+#define DMA_FIOS_IRQ VIC2_INT_VEC(6)
+#define FIOS_ECC_IRQ VIC2_INT_VEC(7)
+#define FIOCMD_IRQ VIC2_INT_VEC(8)
+#define FIODMA_IRQ VIC2_INT_VEC(9)
+#define GDMA_IRQ VIC2_INT_VEC(10)
+#define SD3_IRQ VIC2_INT_VEC(11)
+#define SD2_IRQ VIC2_INT_VEC(12)
+#define SD_IRQ VIC2_INT_VEC(13)
+#define NOR_SPI VIC2_INT_VEC(14)
+#define SSI_MASTER1_IRQ VIC2_INT_VEC(15)
+#define SSI_MASTER0_IRQ VIC2_INT_VEC(16)
+#define SSI_SLAVE_IRQ VIC2_INT_VEC(17)
+#define UART1_IRQ VIC2_INT_VEC(18)
+#define IDC3_IRQ VIC2_INT_VEC(19)
+#define IDC2_IRQ VIC2_INT_VEC(20)
+#define IDC_IRQ VIC2_INT_VEC(21)
+#define IRIF_IRQ VIC2_INT_VEC(22)
+#define I2STX_IRQ VIC2_INT_VEC(23)
+#define I2SRX_IRQ VIC2_INT_VEC(24)
+#define IDC_SLAVE_IRQ VIC2_INT_VEC(25)
+#define HIF_ARM2_IRQ VIC2_INT_VEC(26)
+#define HIF_ARM1_IRQ VIC2_INT_VEC(27)
+#define TS_CH1_RX_IRQ VIC2_INT_VEC(28)
+#define TS_CH0_RX_IRQ VIC2_INT_VEC(29)
+#define TS_CH1_TX_IRQ VIC2_INT_VEC(30)
+#define TS_CH0_TX_IRQ VIC2_INT_VEC(31)
+
+#define USBVBUS_IRQ VIC3_INT_VEC(0)
+#define USB_DIGITAL_ID_CHANGE_IRQ VIC3_INT_VEC(1)
+#define USB_CONNECT_CHANGE_IRQ VIC3_INT_VEC(2)
+#define USB_CHARGE_IRQ VIC3_INT_VEC(3)
+#define SD2CD_IRQ VIC3_INT_VEC(4)
+#define SD1CD_IRQ VIC3_INT_VEC(5)
+#define SD0CD_IRQ VIC3_INT_VEC(6)
+#define ADC_LEVEL_IRQ VIC3_INT_VEC(7)
+#define HDMI_IRQ VIC3_INT_VEC(8)
+#define WDT_IRQ VIC3_INT_VEC(9)
+#define SLIM_IRQ VIC3_INT_VEC(10)
+#define ETH_PMT_IRQ VIC3_INT_VEC(11)
+#define UART0_IRQ VIC3_INT_VEC(12)
+#define MOTOR_IRQ VIC3_INT_VEC(13)
+#define SHA1_IRQ VIC3_INT_VEC(14)
+#define AES_IRQ VIC3_INT_VEC(15)
+#define DES_IRQ VIC3_INT_VEC(16)
+#define MD5_IRQ VIC3_INT_VEC(17)
+#define L2CC_INTR_IRQ VIC3_INT_VEC(18)
+#define L2CC_INTR1_IRQ VIC3_INT_VEC(19)
+#define AXI_SWI_IRQ VIC3_INT_VEC(20)
+#define AXI_SWI1_IRQ VIC3_INT_VEC(21)
+#define GPIO6_IRQ VIC3_INT_VEC(22)
+#define GPIO5_IRQ VIC3_INT_VEC(23)
+#define GPIO4_IRQ VIC3_INT_VEC(24)
+#define GPIO3_IRQ VIC3_INT_VEC(25)
+#define GPIO2_IRQ VIC3_INT_VEC(26)
+#define GPIO1_IRQ VIC3_INT_VEC(27)
+#define GPIO0_IRQ VIC3_INT_VEC(28)
+#define DMIC_IRQ VIC3_INT_VEC(29)
+#define TIMER20_IRQ VIC3_INT_VEC(30)
+#define TIMER19_IRQ VIC3_INT_VEC(31)
+
+/* ==========================================================================*/
+#elif (CHIP_REV == S3L)
+#define TIMER1_IRQ VIC0_INT_VEC(0)
+#define TIMER2_IRQ VIC0_INT_VEC(1)
+#define TIMER3_IRQ VIC0_INT_VEC(2)
+#define TIMER4_IRQ VIC0_INT_VEC(3)
+#define TIMER5_IRQ VIC0_INT_VEC(4)
+#define TIMER6_IRQ VIC0_INT_VEC(5)
+#define TIMER7_IRQ VIC0_INT_VEC(6)
+#define AXI_SOFT_IRQ(x) VIC0_INT_VEC((x) + 7) /* 0 <= x <= 13 */
+#define AXI_SW_IRQ0 VIC0_INT_VEC(21)
+#define AXI_SW_IRQ1 VIC0_INT_VEC(22)
+#define PMU_IRQ VIC0_INT_VEC(23)
+#define L2CC_INTR_IRQ VIC0_INT_VEC(24)
+#define L2CC_DECERR_IRQ VIC0_INT_VEC(25)
+#define L2CC_SLVERR_IRQ VIC0_INT_VEC(26)
+#define L2CC_ECNTR_IRQ VIC0_INT_VEC(27)
+#define MD5_IRQ VIC0_INT_VEC(28)
+#define DES_IRQ VIC0_INT_VEC(29)
+#define AES_IRQ VIC0_INT_VEC(30)
+#define SHA1_IRQ VIC0_INT_VEC(31)
+
+#define IDSP_VIN_MVSYNC_IRQ VIC1_INT_VEC(0)
+#define IDSP_VIN_VSYNC_IRQ VIC1_INT_VEC(1)
+#define IDSP_VIN_SOF_IRQ VIC1_INT_VEC(2)
+#define IDSP_VIN_DVSYNC_IRQ VIC1_INT_VEC(3)
+#define IDSP_VIN_LAST_PIXEL_IRQ VIC1_INT_VEC(4)
+#define GDMA_IRQ VIC1_INT_VEC(5)
+#define IDSP_PIP_MVSYNC_IRQ VIC1_INT_VEC(6)
+#define IDSP_PIP_VSYNC_IRQ VIC1_INT_VEC(7)
+#define IDSP_PIP_SOF_IRQ VIC1_INT_VEC(8)
+#define IDSP_PIP_DVSYNC_IRQ VIC1_INT_VEC(9)
+#define IDSP_PIP_LAST_PIXEL_IRQ VIC1_INT_VEC(10)
+#define VOUT_TV_SYNC_IRQ VIC1_INT_VEC(11)
+#define VOUT_LCD_SYNC_IRQ VIC1_INT_VEC(12)
+#define CODE_VDSP_0_IRQ VIC1_INT_VEC(13)
+#define CODE_VDSP_1_IRQ VIC1_INT_VEC(14)
+#define CODE_VDSP_2_IRQ VIC1_INT_VEC(15)
+#define CODE_VDSP_3_IRQ VIC1_INT_VEC(16)
+#define GPIO3_IRQ VIC1_INT_VEC(17)
+#define GPIO2_IRQ VIC1_INT_VEC(18)
+#define GPIO1_IRQ VIC1_INT_VEC(19)
+#define GPIO0_IRQ VIC1_INT_VEC(20)
+#define VIN_IRQ VIC1_INT_VEC(21)
+#define ORC_VOUT0_IRQ VIC1_INT_VEC(22)
+#define VOUT_IRQ VIC1_INT_VEC(23)
+#define VDSP_PIP_CODING_IRQ VIC1_INT_VEC(24)
+#define ADC_LEVEL_IRQ VIC1_INT_VEC(25)
+#define HDMI_IRQ VIC1_INT_VEC(26)
+#define WDT_IRQ VIC1_INT_VEC(27)
+#define ETH_PMT_IRQ VIC1_INT_VEC(28)
+#define UART0_IRQ VIC1_INT_VEC(29)
+#define MOTOR_IRQ VIC1_INT_VEC(30)
+#define TIMER8_IRQ VIC1_INT_VEC(31)
+
+#define PWC_ALRAM VIC2_INT_VEC(0)
+#define ETH_IRQ VIC2_INT_VEC(1)
+#define USB_EHCI_IRQ VIC2_INT_VEC(2)
+#define USB_OHCI_IRQ VIC2_INT_VEC(3)
+#define USBC_IRQ VIC2_INT_VEC(4)
+#define DMA_IRQ VIC2_INT_VEC(5)
+#define DMA_FIOS_IRQ VIC2_INT_VEC(6)
+#define FIOS_ECC_IRQ VIC2_INT_VEC(7)
+#define FIOCMD_IRQ VIC2_INT_VEC(8)
+#define FIODMA_IRQ VIC2_INT_VEC(9)
+#define SD2_IRQ VIC2_INT_VEC(10) /* SDXC rather than SDIO */
+#define SD_IRQ VIC2_INT_VEC(11)
+#define NOR_SPI VIC2_INT_VEC(12)
+#define SSI_MASTER1_IRQ VIC2_INT_VEC(13)
+#define SSI_MASTER0_IRQ VIC2_INT_VEC(14)
+#define SSI_SLAVE_IRQ VIC2_INT_VEC(15)
+#define UART1_IRQ VIC2_INT_VEC(16)
+#define IDC3_IRQ VIC2_INT_VEC(17)
+#define IDC2_IRQ VIC2_INT_VEC(18)
+#define IDC_IRQ VIC2_INT_VEC(19)
+#define IRIF_IRQ VIC2_INT_VEC(20)
+#define I2STX_IRQ VIC2_INT_VEC(21)
+#define I2SRX_IRQ VIC2_INT_VEC(22)
+#define USBVBUS_IRQ VIC2_INT_VEC(23)
+#define USB_DIGITAL_ID_CHANGE_IRQ VIC2_INT_VEC(24)
+#define USB_CONNECT_CHANGE_IRQ VIC2_INT_VEC(25)
+#define USB_CHARGE_IRQ VIC2_INT_VEC(26)
+#define SD2CD_IRQ VIC2_INT_VEC(27) /* SDXC rather than SDIO */
+#define SD0CD_IRQ VIC2_INT_VEC(28)
+
+/* ==========================================================================*/
+#else
+#error "Not supported!"
+#endif
+
+/* ==========================================================================*/
+#define VIRQ_RISING_EDGE 0
+#define VIRQ_FALLING_EDGE 1
+#define VIRQ_BOTH_EDGES 2
+#define VIRQ_LEVEL_LOW 3
+#define VIRQ_LEVEL_HIGH 4
+
+#ifndef __ASSEMBLER__
+
+extern void ambvic_sw_set(void __iomem *vic_base, unsigned int vic_irq);
+extern void ambvic_sw_clr(void __iomem *vic_base, unsigned int vic_irq);
+
+#endif /* __ASSEMBLER__ */
+/* ==========================================================================*/
+
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/plat/nand.h b/arch/arm/mach-ambarella/include/plat/nand.h
new file mode 100644
index 00000000..3cb9e38b
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/nand.h
@@ -0,0 +1,247 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/nand.h
+ *
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_NAND_H__
+#define __PLAT_AMBARELLA_NAND_H__
+
+/* ==========================================================================*/
+
+#if (CHIP_REV == S2E) || (CHIP_REV == S3L)
+#define NAND_ECC_RPT_NUM_SUPPORT 1
+#else
+#define NAND_ECC_RPT_NUM_SUPPORT 0
+#endif
+
+/* ==========================================================================*/
+#define FLASH_CTR_OFFSET 0x120
+#define FLASH_CMD_OFFSET 0x124
+#define FLASH_TIM0_OFFSET 0x128
+#define FLASH_TIM1_OFFSET 0x12c
+#define FLASH_TIM2_OFFSET 0x130
+#define FLASH_TIM3_OFFSET 0x134
+#define FLASH_TIM4_OFFSET 0x138
+#define FLASH_TIM5_OFFSET 0x13c
+#define FLASH_STA_OFFSET 0x140
+#define FLASH_ID_OFFSET 0x144
+#define FLASH_CFI_OFFSET 0x148
+#define FLASH_LEN_OFFSET 0x14c
+#define FLASH_INT_OFFSET 0x150
+#define FLASH_EX_CTR_OFFSET 0x15c
+#define FLASH_EX_ID_OFFSET 0x160
+/* followings are for customer command, start from S3L */
+#define FLASH_TIM6_OFFSET 0x164
+#define FLASH_CC_OFFSET 0x170
+#define FLASH_CC_WORD_OFFSET 0x174
+#define FLASH_CC_DATA0_OFFSET 0x180
+#define FLASH_CC_DATA1_OFFSET 0x184
+#define FLASH_CC_DATA2_OFFSET 0x188
+#define FLASH_CC_DATA3_OFFSET 0x18c
+#define FLASH_CC_DATA4_OFFSET 0x190
+#define FLASH_CC_DATA5_OFFSET 0x194
+#define FLASH_CC_DATA6_OFFSET 0x198
+#define FLASH_CC_DATA7_OFFSET 0x19c
+
+#define NAND_CTR_REG FIO_REG(0x120)
+#define NAND_CMD_REG FIO_REG(0x124)
+#define NAND_TIM0_REG FIO_REG(0x128)
+#define NAND_TIM1_REG FIO_REG(0x12c)
+#define NAND_TIM2_REG FIO_REG(0x130)
+#define NAND_TIM3_REG FIO_REG(0x134)
+#define NAND_TIM4_REG FIO_REG(0x138)
+#define NAND_TIM5_REG FIO_REG(0x13c)
+#define NAND_STA_REG FIO_REG(0x140)
+#define NAND_ID_REG FIO_REG(0x144)
+#define NAND_COPY_ADDR_REG FIO_REG(0x148)
+#define NAND_LEN_REG FIO_REG(0x14c)
+#define NAND_INT_REG FIO_REG(0x150)
+#define NAND_EXT_CTR_REG FIO_REG(0x15c)
+#define NAND_EXT_ID5_REG FIO_REG(0x160)
+/* followings are for customer command, start from S3L */
+#define NAND_TIM6_REG FIO_REG(0x164)
+#define NAND_CC_REG FIO_REG(0x170)
+#define NAND_CC_WORD_REG FIO_REG(0x174)
+#define NAND_CC_DATA0_REG FIO_REG(0x180)
+#define NAND_CC_DATA1_REG FIO_REG(0x184)
+#define NAND_CC_DATA2_REG FIO_REG(0x188)
+#define NAND_CC_DATA3_REG FIO_REG(0x18c)
+#define NAND_CC_DATA4_REG FIO_REG(0x190)
+#define NAND_CC_DATA5_REG FIO_REG(0x194)
+#define NAND_CC_DATA6_REG FIO_REG(0x198)
+#define NAND_CC_DATA7_REG FIO_REG(0x19c)
+
+#define NAND_READ_CMDWORD_REG FIO_REG(0x154)
+#define NAND_PROG_CMDWORD_REG FIO_REG(0x158)
+#define NAND_CMDWORD1(x) ((x) << 16)
+#define NAND_CMDWORD2(x) ((x) & 0xff)
+
+#define NAND_CPS1_ADDR_REG FIO_REG(0x154)
+#define NAND_CPD1_ADDR_REG FIO_REG(0x158)
+#define NAND_CPS2_ADDR_REG FIO_REG(0x15c)
+#define NAND_CPD2_ADDR_REG FIO_REG(0x160)
+#define NAND_CPS3_ADDR_REG FIO_REG(0x164)
+#define NAND_CPD3_ADDR_REG FIO_REG(0x168)
+#define NAND_NBR_SPA_REG FIO_REG(0x16c)
+
+#define NAND_CTR_A(x) ((x) << 28)
+#define NAND_CTR_SA 0x08000000
+#define NAND_CTR_SE 0x04000000
+#define NAND_CTR_C2 0x02000000
+#define NAND_CTR_P3 0x01000000
+#define NAND_CTR_I4 0x00800000
+#define NAND_CTR_RC 0x00400000
+#define NAND_CTR_CC 0x00200000
+#define NAND_CTR_CE 0x00100000
+#define NAND_CTR_EC_MAIN 0x00080000
+#define NAND_CTR_EC_SPARE 0x00040000
+#define NAND_CTR_EG_MAIN 0x00020000
+#define NAND_CTR_EG_SPARE 0x00010000
+#define NAND_CTR_WP 0x00000200
+#define NAND_CTR_IE 0x00000100
+#define NAND_CTR_XS 0x00000080
+#define NAND_CTR_SZ_8G 0x00000070
+#define NAND_CTR_SZ_4G 0x00000060
+#define NAND_CTR_SZ_2G 0x00000050
+#define NAND_CTR_SZ_1G 0x00000040
+#define NAND_CTR_SZ_512M 0x00000030
+#define NAND_CTR_SZ_256M 0x00000020
+#define NAND_CTR_SZ_128M 0x00000010
+#define NAND_CTR_SZ_64M 0x00000000
+#define NAND_CTR_4BANK 0x00000008
+#define NAND_CTR_2BANK 0x00000004
+#define NAND_CTR_1BANK 0x00000000
+#define NAND_CTR_WD_64BIT 0x00000003
+#define NAND_CTR_WD_32BIT 0x00000002
+#define NAND_CTR_WD_16BIT 0x00000001
+#define NAND_CTR_WD_8BIT 0x00000000
+
+#define NAND_CTR_INTLVE 0x80000000
+#define NAND_CTR_SPRBURST 0x40000000
+#define NAND_CFG_STAT_ENB 0x00002000
+#define NAND_CTR_2INTL 0x00001000
+#define NAND_CTR_K9 0x00000800
+
+#define NAND_CTR_WAS 0x00000400
+
+#define NAND_AMB_CMD_ADDR(x) ((x) << 4)
+#define NAND_AMB_CMD_NOP 0x0
+#define NAND_AMB_CMD_DMA 0x1
+#define NAND_AMB_CMD_RESET 0x2
+#define NAND_AMB_CMD_NOP2 0x3
+#define NAND_AMB_CMD_NOP3 0x4
+#define NAND_AMB_CMD_NOP4 0x5
+#define NAND_AMB_CMD_NOP5 0x6
+#define NAND_AMB_CMD_COPYBACK 0x7
+#define NAND_AMB_CMD_NOP6 0x8
+#define NAND_AMB_CMD_ERASE 0x9
+#define NAND_AMB_CMD_READID 0xa
+#define NAND_AMB_CMD_NOP7 0xb
+#define NAND_AMB_CMD_READSTATUS 0xc
+#define NAND_AMB_CMD_NOP8 0xd
+#define NAND_AMB_CMD_READ 0xe
+#define NAND_AMB_CMD_PROGRAM 0xf
+
+/* NAND_TIM0_REG (NAND mode) */
+#define NAND_TIM0_TCLS(x) ((x) << 24)
+#define NAND_TIM0_TALS(x) ((x) << 16)
+#define NAND_TIM0_TCS(x) ((x) << 8)
+#define NAND_TIM0_TDS(x) (x)
+
+/* NAND_TIM1_REG (NAND mode) */
+#define NAND_TIM1_TCLH(x) ((x) << 24)
+#define NAND_TIM1_TALH(x) ((x) << 16)
+#define NAND_TIM1_TCH(x) ((x) << 8)
+#define NAND_TIM1_TDH(x) (x)
+
+/* NAND_TIM2_REG (NAND mode) */
+#define NAND_TIM2_TWP(x) ((x) << 24)
+#define NAND_TIM2_TWH(x) ((x) << 16)
+#define NAND_TIM2_TWB(x) ((x) << 8)
+#define NAND_TIM2_TRR(x) (x)
+
+/* NAND_TIM3_REG (NAND mode) */
+#define NAND_TIM3_TRP(x) ((x) << 24)
+#define NAND_TIM3_TREH(x) ((x) << 16)
+#define NAND_TIM3_TRB(x) ((x) << 8)
+#define NAND_TIM3_TCEH(x) (x)
+
+/* NAND_TIM4_REG (NAND mode) */
+#define NAND_TIM4_TRDELAY(x) ((x) << 24)
+#define NAND_TIM4_TCLR(x) ((x) << 16)
+#define NAND_TIM4_TWHR(x) ((x) << 8)
+#define NAND_TIM4_TIR(x) (x)
+
+/* NAND_TIM5_REG (NAND mode) */
+#define NAND_TIM5_TWW(x) ((x) << 16)
+#define NAND_TIM5_TRHZ(x) ((x) << 8)
+#define NAND_TIM5_TAR(x) (x)
+
+/* NAND_INT_REG (NAND mode) */
+#define NAND_INT_DI 0x1
+
+/* NAND_EXT_CTR_REG */
+#define NAND_EXT_CTR_I5 0x00800000
+#define NAND_EXT_CTR_SP_2X 0x00000001
+
+/* ==========================================================================*/
+#define EC_MDSD 0 /* check main disable and spare disable */
+#define EC_MDSE 1 /* check main disable and spare enable */
+#define EC_MESD 2 /* check main enable and spare disable */
+#define EC_MESE 3 /* check main enable and spare enable */
+
+#define EG_MDSD 0 /* generate main disable and spare disable */
+#define EG_MDSE 1 /* generate main disable and spare enable */
+#define EG_MESD 2 /* generate main enable and spare disable */
+#define EG_MESE 3 /* generate main enable and spare enable */
+
+/**
+ * Define for xdhost and nand_host
+ */
+#define MAIN_ONLY 0
+#define SPARE_ONLY 1
+#define MAIN_ECC 2
+#define SPARE_ECC 3
+#define SPARE_ONLY_BURST 4
+#define SPARE_ECC_BURST 5
+
+/* ECC use bch-x bytes */
+#define NAND_ECC_BCH6_BYTES 40 /* 10Bytes/512Bytes, so 40B/2048B */
+#define NAND_ECC_BCH8_BYTES 52 /* 13Bytes/512Bytes, so 52B/2048B */
+
+
+#define FIO_DMA_CHAN 0
+#define FDMA_CTR_OFFSET (0x300 + ((FIO_DMA_CHAN) << 4))
+#define FDMA_SRC_OFFSET (0x304 + ((FIO_DMA_CHAN) << 4))
+#define FDMA_DST_OFFSET (0x308 + ((FIO_DMA_CHAN) << 4))
+#define FDMA_STA_OFFSET (0x30c + ((FIO_DMA_CHAN) << 4))
+#define FDMA_DA_OFFSET (0x380 + ((FIO_DMA_CHAN) << 2))
+#define FDMA_INT_OFFSET (0x3f0)
+
+#define FDMA_SPR_CNT_OFFSET (0x200 + ((FIO_DMA_CHAN) << 4))
+#define FDMA_SPR_SRC_OFFSET (0x204 + ((FIO_DMA_CHAN) << 4))
+#define FDMA_SPR_DST_OFFSET (0x208 + ((FIO_DMA_CHAN) << 4))
+#define FDMA_SPR_STA_OFFSET (0x20c + ((FIO_DMA_CHAN) << 4))
+#define FDMA_SPR_DA_OFFSET (0x280 + ((FIO_DMA_CHAN) << 2))
+#define FDMA_DSM_CTR_OFFSET (0x3a0 + ((FIO_DMA_CHAN) << 2))
+
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/plat/pinctrl.h b/arch/arm/mach-ambarella/include/plat/pinctrl.h
new file mode 100644
index 00000000..3b2b24eb
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/pinctrl.h
@@ -0,0 +1,45 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/pinctrl.h
+ *
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * Copyright (C) 2012-2016, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_PINCTRL_H__
+#define __PLAT_AMBARELLA_PINCTRL_H__
+
+#ifndef __ASSEMBLER__
+
+#define PINID_TO_BANK(p) ((p) >> 5)
+#define PINID_TO_OFFSET(p) ((p) & 0x1f)
+
+/* pins alternate function */
+enum amb_pin_altfunc {
+ AMB_ALTFUNC_GPIO = 0,
+ AMB_ALTFUNC_HW_1,
+ AMB_ALTFUNC_HW_2,
+ AMB_ALTFUNC_HW_3,
+ AMB_ALTFUNC_HW_4,
+ AMB_ALTFUNC_HW_5,
+};
+
+#endif /* __ASSEMBLER__ */
+
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/plat/pm.h b/arch/arm/mach-ambarella/include/plat/pm.h
new file mode 100644
index 00000000..110b488e
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/pm.h
@@ -0,0 +1,53 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/pm.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_PM_H
+#define __PLAT_AMBARELLA_PM_H
+
+/* ==========================================================================*/
+
+/* ==========================================================================*/
+#ifndef __ASSEMBLER__
+
+/* ==========================================================================*/
+
+/* ==========================================================================*/
+#ifdef CONFIG_PLAT_AMBARELLA_SUPPORT_PM
+extern int ambarella_init_pm(void);
+extern int ambarella_finish_suspend(unsigned long);
+extern void ambarella_cpu_resume(void);
+
+#ifdef CONFIG_AMBARELLA_SREF_FIFO_EXEC
+extern int ambarella_optimize_suspend(unsigned long);
+extern int ambarella_optimize_suspend_sz;
+#endif /* CONFIG_AMBARELLA_SREF_FIFO_EXEC */
+
+#else
+static inline int ambarella_init_pm(void){return 0;}
+#endif
+
+#endif /* __ASSEMBLER__ */
+/* ==========================================================================*/
+
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/plat/ptb.h b/arch/arm/mach-ambarella/include/plat/ptb.h
new file mode 100644
index 00000000..99c4f259
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/ptb.h
@@ -0,0 +1,166 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/ptb.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_PTB_H
+#define __PLAT_AMBARELLA_PTB_H
+
+/* ==========================================================================*/
+#define BOOT_DEV_NAND 0x1
+#define BOOT_DEV_NOR 0x2
+#define BOOT_DEV_SM 0x3
+#define BOOT_DEV_ONENAND 0x4
+#define BOOT_DEV_SNOR 0x5
+
+#define PART_DEV_AUTO (0x00)
+#define PART_DEV_NAND (0x01)
+#define PART_DEV_EMMC (0x02)
+#define PART_DEV_SNOR (0x04)
+
+#define FW_MODEL_NAME_SIZE 128
+
+#define PART_MAX_WITH_RSV 32
+
+#define PART_MAX 20
+#define CMDLINE_PART_MAX 8
+
+#define HAS_IMG_PARTS 15
+#define HAS_NO_IMG_PARTS 1
+#define TOTAL_FW_PARTS (HAS_IMG_PARTS + HAS_NO_IMG_PARTS)
+
+/* ==========================================================================*/
+#ifndef __ASSEMBLER__
+
+typedef struct flpart_s
+{
+ u32 crc32; /**< CRC32 checksum of image */
+ u32 ver_num; /**< Version number */
+ u32 ver_date; /**< Version date */
+ u32 img_len; /**< Lengh of image in the partition */
+ u32 mem_addr; /**< Starting address to copy to RAM */
+ u32 flag; /**< Special properties of this partition */
+ u32 magic; /**< Magic number */
+} __attribute__((packed)) flpart_t;
+
+#define FLDEV_CMD_LINE_SIZE 1024
+
+typedef struct netdev_s
+{
+ /* This section contains networking related settings */
+ u8 mac[6]; /**< MAC address*/
+ u32 ip; /**< Boot loader's LAN IP */
+ u32 mask; /**< Boot loader's LAN mask */
+ u32 gw; /**< Boot loader's LAN gateway */
+} __attribute__((packed)) netdev_t;
+
+typedef struct fldev_s
+{
+ char sn[32]; /**< Serial number */
+ u8 usbdl_mode; /**< USB download mode */
+ u8 auto_boot; /**< Automatic boot */
+ u8 rsv[2];
+ u32 splash_id;
+ char cmdline[FLDEV_CMD_LINE_SIZE];
+
+ /* This section contains networking related settings */
+ netdev_t eth[2];
+ netdev_t wifi[2];
+ netdev_t usb_eth[2];
+
+ /* This section contains update by network related settings */
+ u32 auto_dl; /**< Automatic download? */
+ u32 tftpd; /**< Boot loader's TFTP server */
+ u32 pri_addr; /**< RTOS download address */
+ char pri_file[32]; /**< RTOS file name */
+ u32 pri_comp; /**< RTOS compressed? */
+ u32 dtb_addr; /**< DTB download address */
+ char dtb_file[32]; /**< DTB file name */
+ u32 rmd_addr; /**< Ramdisk download address */
+ char rmd_file[32]; /**< Ramdisk file name */
+ u32 rmd_comp; /**< Ramdisk compressed? */
+ u32 dsp_addr; /**< DSP download address */
+ char dsp_file[32]; /**< DSP file name */
+ u32 dsp_comp; /**< DSP compressed? */
+
+ u32 magic; /**< Magic number */
+} __attribute__((packed)) fldev_t;
+
+/*The header of PTB*/
+#define PTB_HEADER_SIZE 64
+#define PTB_HEADER_PAD_SIZE (PTB_HEADER_SIZE - sizeof(u32) * 4)
+typedef struct ptb_header_s
+{
+ u32 magic;
+ u32 crc32;
+ u32 version;
+ u32 dev;
+ u8 rsv[PTB_HEADER_PAD_SIZE];
+} __attribute__((packed)) ptb_header_t;
+
+#define PTB_SIZE 4096
+#define PTB_PAD_SIZE \
+ (PTB_SIZE - PART_MAX_WITH_RSV * sizeof(flpart_t) - sizeof(fldev_t))
+
+typedef struct flpart_table_s
+{
+ flpart_t part[PART_MAX_WITH_RSV];/** Partitions */
+ /* ------------------------------------------ */
+ fldev_t dev; /**< Device properties */
+ u8 rsv[PTB_PAD_SIZE]; /**< Padding to 2048 bytes */
+} __attribute__((packed)) flpart_table_t;
+
+/**
+ * The meta data table is a region in flash after partition table.
+ * The data need by dual boot are stored.
+ */
+/* For first version of flpart_meta_t */
+#define PTB_META_MAGIC 0x33219fbd
+/* For second version of flpart_meta_t */
+#define PTB_META_MAGIC2 0x4432a0ce
+#define PTB_META_MAGIC3 0x42405891
+#define PART_NAME_LEN 8
+#define PTB_META_ACTURAL_LEN (sizeof(u32) + (sizeof(u32) * 3 + PART_NAME_LEN) * PART_MAX + \
+ FW_MODEL_NAME_SIZE)
+#define PTB_META_SIZE 2048
+#define PTB_META_PAD_SIZE (PTB_META_SIZE - PTB_META_ACTURAL_LEN)
+typedef struct flpart_meta_s
+{
+ u32 magic;
+ struct {
+ u32 sblk;
+ u32 nblk;
+ u32 dev;
+ char name[PART_NAME_LEN];
+ } part_info[PART_MAX];
+ u8 model_name[FW_MODEL_NAME_SIZE];
+ u8 rsv[PTB_META_PAD_SIZE];
+ /* This meta crc32 doesn't include itself. */
+ /* It's only calc data before this field. */
+ u32 crc32;
+} __attribute__((packed)) flpart_meta_t;
+
+#endif /* __ASSEMBLER__ */
+
+/* ==========================================================================*/
+
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/plat/pwm.h b/arch/arm/mach-ambarella/include/plat/pwm.h
new file mode 100644
index 00000000..a27c6b45
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/pwm.h
@@ -0,0 +1,83 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/pwm.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_PWM_H__
+#define __PLAT_AMBARELLA_PWM_H__
+
+#if (CHIP_REV == A8)
+#define PWM_INSTANCES 0
+#elif (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+#define PWM_INSTANCES 4
+#else
+#define PWM_INSTANCES 5
+#endif
+
+/* ==========================================================================*/
+#define PWM_OFFSET 0x8000
+#define PWM_BASE (APB_BASE + PWM_OFFSET)
+#define PWM_REG(x) (PWM_BASE + (x))
+
+#define STEPPER_OFFSET 0x4000
+#define STEPPER_BASE (APB_BASE + STEPPER_OFFSET)
+#define PWM_ST_REG(x) (STEPPER_BASE + (x))
+
+/* ==========================================================================*/
+#define PWM_CONTROL_OFFSET 0x00
+#define PWM_ENABLE_OFFSET 0x04
+#define PWM_MODE_OFFSET 0x08
+#define PWM_CONTROL1_OFFSET 0x0c
+
+#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+#define PWM_B0_ENABLE_OFFSET 0x04
+#define PWM_B1_ENABLE_OFFSET 0x0c
+#define PWM_C0_ENABLE_OFFSET 0x14
+#define PWM_C1_ENABLE_OFFSET 0x1c
+#define PWM_B0_DATA1_OFFSET 0x20
+#define PWM_B1_DATA1_OFFSET 0x24
+#define PWM_C0_DATA1_OFFSET 0x28
+#define PWM_C1_DATA1_OFFSET 0x2c
+#else
+#define PWM_B0_ENABLE_OFFSET 0x304
+#define PWM_B1_ENABLE_OFFSET 0x30c
+#define PWM_C0_ENABLE_OFFSET 0x314
+#define PWM_C1_ENABLE_OFFSET 0x31c
+#define PWM_B0_DATA1_OFFSET 0x320
+#define PWM_B1_DATA1_OFFSET 0x324
+#define PWM_C0_DATA1_OFFSET 0x328
+#define PWM_C1_DATA1_OFFSET 0x32c
+#endif
+
+#define PWM_CLK_SRC_BIT (0x1 << 31)
+#define PWM_INV_EN_BIT (0x1 << 31)
+#define PWM_DIVIDER_MASK (0x7ffffffe)
+#define PWM_PWM_EN_BIT (0x1)
+
+#define PWM_PWM_TICKS_MAX_BITS 16
+#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+#define PWM_ST_TICKS_MAX_BITS 16
+#else
+#define PWM_ST_TICKS_MAX_BITS 10
+#endif
+
+#endif /* __PLAT_AMBARELLA_PWM_H__ */
+
diff --git a/arch/arm/mach-ambarella/include/plat/rct.h b/arch/arm/mach-ambarella/include/plat/rct.h
new file mode 100644
index 00000000..9d3f5be7
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/rct.h
@@ -0,0 +1,691 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/rct.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2013, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_RCT_H__
+#define __PLAT_AMBARELLA_RCT_H__
+
+/* ==========================================================================*/
+#define RCT_OFFSET 0x170000
+#if (CHIP_REV == A8) || (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+#define RCT_BASE (DBGBUS_BASE + RCT_OFFSET)
+#define RCT_PHYS_BASE (DBGBUS_PHYS_BASE + RCT_OFFSET)
+#define RCT_BUS_BASE DBGBUS_BASE
+#else
+#define RCT_BASE (APB_BASE + RCT_OFFSET)
+#define RCT_PHYS_BASE (APB_PHYS_BASE + RCT_OFFSET)
+#define RCT_BUS_BASE APB_BASE
+#endif
+#define RCT_REG(x) (RCT_BASE + (x))
+
+/* ==========================================================================*/
+#define PLL_LOCK_OFFSET 0x2C
+#define SOFT_OR_DLL_RESET_OFFSET 0x68
+
+#define PLL_LOCK_REG RCT_REG(PLL_LOCK_OFFSET)
+#define SOFT_OR_DLL_RESET_REG RCT_REG(SOFT_OR_DLL_RESET_OFFSET)
+
+/* ==========================================================================*/
+#define FIO_RESET_OFFSET 0x74
+#define FIO_RESET_REG RCT_REG(FIO_RESET_OFFSET)
+#define FIO_RESET_FIO_RST 0x00000008
+#define FIO_RESET_CF_RST 0x00000004
+#define FIO_RESET_XD_RST 0x00000002
+#define FIO_RESET_FLASH_RST 0x00000001
+
+/* ==========================================================================*/
+#if (CHIP_REV == A5S) || (CHIP_REV == S2) || (CHIP_REV == S2E)
+#define USBP1_CTRL_OFFSET 0x88
+#define UDC_SOFT_RESET_OFFSET USBP1_CTRL_OFFSET
+#define UDC_SOFT_RESET_MASK 0x20000000
+#else
+#define USBC_CTRL_OFFSET 0x2cc
+#define UDC_SOFT_RESET_OFFSET USBC_CTRL_OFFSET
+#define UDC_SOFT_RESET_MASK 0x2
+#endif
+#define UDC_SOFT_RESET_REG RCT_REG(UDC_SOFT_RESET_OFFSET)
+
+#if (CHIP_REV == S2) || (CHIP_REV == S2E)
+#define USB0_IS_HOST_MASK 0x00000020
+#else
+#define USBP0_SEL_OFFSET 0x2c0
+#define USBP0_SEL_REG RCT_REG(USBP0_SEL_OFFSET)
+#define USB0_IS_HOST_MASK 0x00000002
+#endif
+
+/* ==========================================================================*/
+#define PLL_AUDIO_CTRL_OFFSET 0x54
+#define PLL_AUDIO_FRAC_OFFSET 0x58
+#define SCALER_AUDIO_POST_OFFSET 0x5C
+#define SCALER_AUDIO_PRE_OFFSET 0x60
+#define PLL_AUDIO_CTRL2_OFFSET 0x124
+#define PLL_AUDIO_CTRL3_OFFSET 0x12c
+
+#define PLL_AUDIO_CTRL_REG RCT_REG(PLL_AUDIO_CTRL_OFFSET)
+#define PLL_AUDIO_FRAC_REG RCT_REG(PLL_AUDIO_FRAC_OFFSET)
+#define SCALER_AUDIO_POST_REG RCT_REG(SCALER_AUDIO_POST_OFFSET)
+#define SCALER_AUDIO_PRE_REG RCT_REG(SCALER_AUDIO_PRE_OFFSET)
+#define PLL_AUDIO_CTRL2_REG RCT_REG(PLL_AUDIO_CTRL2_OFFSET)
+#define PLL_AUDIO_CTRL3_REG RCT_REG(PLL_AUDIO_CTRL3_OFFSET)
+
+/* ==========================================================================*/
+#define ANA_PWR_OFFSET 0x50
+#define ANA_PWR_REG RCT_REG(ANA_PWR_OFFSET)
+#define ANA_PWR_POWER_DOWN 0x0020
+
+#define SYS_CONFIG_OFFSET 0x34
+#define SYS_CONFIG_REG RCT_REG(SYS_CONFIG_OFFSET)
+
+#define WDT_RST_L_OFFSET 0x78
+#if (CHIP_REV == S2) || (CHIP_REV == S2E)
+#define UNLOCK_WDT_RST_L_OFFSET 0x50
+#define UNLOCK_WDT_RST_L_VAL 0x80
+#else
+#define UNLOCK_WDT_RST_L_OFFSET 0x260
+#define UNLOCK_WDT_RST_L_VAL 0x01
+#endif
+#define WDT_RST_L_REG RCT_REG(WDT_RST_L_OFFSET)
+#define UNLOCK_WDT_RST_L_REG RCT_REG(UNLOCK_WDT_RST_L_OFFSET)
+
+/* ==========================================================================*/
+#define CG_UART_OFFSET 0x38
+#define CG_SSI_OFFSET 0x3C
+#define CG_MOTOR_OFFSET 0x40
+#define CG_IR_OFFSET 0x44
+#define CG_HOST_OFFSET 0x48
+#define CG_PWM_OFFSET 0x84
+#define CG_SSI2_OFFSET 0xEC
+#define CLK_REF_SSI_OFFSET 0x19c
+#define CG_SSI3_OFFSET 0x518
+#define CLK_REF_SSI3_OFFSET 0x51c
+
+#define CG_UART_REG RCT_REG(CG_UART_OFFSET)
+#define CG_SSI_REG RCT_REG(CG_SSI_OFFSET)
+#define CG_MOTOR_REG RCT_REG(CG_MOTOR_OFFSET)
+#define CG_IR_REG RCT_REG(CG_IR_OFFSET)
+#define CG_HOST_REG RCT_REG(CG_HOST_OFFSET)
+#define CG_PWM_REG RCT_REG(CG_PWM_OFFSET)
+#define CG_SSI2_REG RCT_REG(CG_SSI2_OFFSET)
+#define CG_SSI3_REG RCT_REG(CG_SSI3_OFFSET)
+#define CLK_REF_SSI_REG RCT_REG(CLK_REF_SSI_OFFSET)
+#define CLK_REF_SSI3_REG RCT_REG(CLK_REF_SSI3_OFFSET)
+
+#define UART_CLK_SRC_CLK_REF 0x00
+#define UART_CLK_SRC_CORE 0x01
+#define UART_CLK_SRC_IDSP 0x03
+#if (CHIP_REV == S2) || (CHIP_REV == S2E)
+#define UART_CLK_SRC_SEL_OFFSET 0x320
+#else
+#define UART_CLK_SRC_SEL_OFFSET 0x1C8
+#endif
+#define UART_CLK_SRC_SEL_REG RCT_REG(UART_CLK_SRC_SEL_OFFSET)
+
+/* ==========================================================================*/
+#define PLL_CORE_CTRL_OFFSET 0x00
+#define PLL_CORE_FRAC_OFFSET 0x04
+#define PLL_CORE_CTRL2_OFFSET 0x100
+#define PLL_CORE_CTRL3_OFFSET 0x104
+#define PLL_CORE_CTRL_REG RCT_REG(PLL_CORE_CTRL_OFFSET)
+#define PLL_CORE_FRAC_REG RCT_REG(PLL_CORE_FRAC_OFFSET)
+#define PLL_CORE_CTRL2_REG RCT_REG(PLL_CORE_CTRL2_OFFSET)
+#define PLL_CORE_CTRL3_REG RCT_REG(PLL_CORE_CTRL3_OFFSET)
+
+#if ((CHIP_REV == A5S) || (CHIP_REV == S2) || (CHIP_REV == S2E))
+#define SCALER_CORE_POST_OFFSET 0x118
+#define CORE_CLK_RATIO_1X_OFFSET 0x24C
+#define SCALER_CORE_POST_REG RCT_REG(SCALER_CORE_POST_OFFSET)
+#define CORE_CLK_RATIO_1X_REG RCT_REG(CORE_CLK_RATIO_1X_OFFSET)
+#endif
+
+/* ==========================================================================*/
+
+#define PLL_HDMILC_CTRL_OFFSET 0x404
+#define PLL_HDMILC_FRAC_OFFSET 0x408
+#define PLL_HDMILC_CTRL2_OFFSET 0x40c
+#define PLL_HDMILC_CTRL3_OFFSET 0x410
+#define PLL_HDMILC_CTRL4_OFFSET 0x418
+#define PLL_HDMILC_CTRL_REG RCT_REG(PLL_HDMILC_CTRL_OFFSET)
+#define PLL_HDMILC_FRAC_REG RCT_REG(PLL_HDMILC_FRAC_OFFSET)
+#define PLL_HDMILC_CTRL2_REG RCT_REG(PLL_HDMILC_CTRL2_OFFSET)
+#define PLL_HDMILC_CTRL3_REG RCT_REG(PLL_HDMILC_CTRL3_OFFSET)
+#define PLL_HDMILC_CTRL4_REG RCT_REG(PLL_HDMILC_CTRL4_OFFSET)
+
+/* ==========================================================================*/
+#define CKEN_CLUSTER_REG_OFFSET 0x8C
+#define PLL_IDSP_CTRL_OFFSET 0xE4
+#define PLL_IDSP_FRAC_OFFSET 0xE8
+#define PLL_IDSP_CTRL2_OFFSET 0x108
+#define PLL_IDSP_CTRL3_OFFSET 0x10C
+#define SCALER_IDSP_POST_OFFSET 0x1F4
+
+#define CKEN_CLUSTER_REG RCT_REG(CKEN_CLUSTER_REG_OFFSET)
+#define PLL_IDSP_CTRL_REG RCT_REG(PLL_IDSP_CTRL_OFFSET)
+#define PLL_IDSP_FRAC_REG RCT_REG(PLL_IDSP_FRAC_OFFSET)
+#define PLL_IDSP_CTRL2_REG RCT_REG(PLL_IDSP_CTRL2_OFFSET)
+#define PLL_IDSP_CTRL3_REG RCT_REG(PLL_IDSP_CTRL3_OFFSET)
+#define SCALER_IDSP_POST_REG RCT_REG(SCALER_IDSP_POST_OFFSET)
+
+/* ==========================================================================*/
+#define PLL_DDR_CTRL_OFFSET 0xDC
+#define PLL_DDR_FRAC_OFFSET 0xE0
+#define PLL_DDR_CTRL2_OFFSET 0x110
+#define PLL_DDR_CTRL3_OFFSET 0x114
+
+#define PLL_DDR_CTRL_REG RCT_REG(PLL_DDR_CTRL_OFFSET)
+#define PLL_DDR_FRAC_REG RCT_REG(PLL_DDR_FRAC_OFFSET)
+#define PLL_DDR_CTRL2_REG RCT_REG(PLL_DDR_CTRL2_OFFSET)
+#define PLL_DDR_CTRL3_REG RCT_REG(PLL_DDR_CTRL3_OFFSET)
+
+/* ==========================================================================*/
+#define PLL_SENSOR_CTRL_OFFSET 0x24
+#define PLL_SENSOR_FRAC_OFFSET 0x28
+#define PLL_SENSOR_CTRL2_OFFSET 0x11C
+#define PLL_SENSOR_CTRL3_OFFSET 0x120
+#define SCALER_SENSOR_PRE_OFFSET 0x4C
+#define SCALER_SENSOR_POST_OFFSET 0x30
+#define CLK_SI_INPUT_MODE_OFFSET 0xBC
+#define SCALER_SENSOR_VIN_OFFSET 0x230
+
+#define PLL_SENSOR_CTRL_REG RCT_REG(PLL_SENSOR_CTRL_OFFSET)
+#define PLL_SENSOR_FRAC_REG RCT_REG(PLL_SENSOR_FRAC_OFFSET)
+#define PLL_SENSOR_CTRL2_REG RCT_REG(PLL_SENSOR_CTRL2_OFFSET)
+#define PLL_SENSOR_CTRL3_REG RCT_REG(PLL_SENSOR_CTRL3_OFFSET)
+#define SCALER_SENSOR_PRE_REG RCT_REG(SCALER_SENSOR_PRE_OFFSET)
+#define SCALER_SENSOR_POST_REG RCT_REG(SCALER_SENSOR_POST_OFFSET)
+#define CLK_SI_INPUT_MODE_REG RCT_REG(CLK_SI_INPUT_MODE_OFFSET)
+#define SCALER_SENSOR_VIN_REG RCT_REG(SCALER_SENSOR_VIN_OFFSET)
+
+/* ==========================================================================*/
+
+#define HDMI_CLOCK_CTRL_OFFSET 0x008
+#define PLL_HDMI_CTRL_OFFSET 0x164
+#define PLL_HDMI_CTRL2_OFFSET 0x150
+#define PLL_HDMI_CTRL3_OFFSET 0x154
+#define PLL_HDMI_FRAC_OFFSET 0x168
+#define SCALER_HDMI_PRE_OFFSET 0x170
+#define SCALER_HDMI_POST_OFFSET 0x16C
+
+#define HDMI_CLOCK_CTRL_REG RCT_REG(HDMI_CLOCK_CTRL_OFFSET)
+#define PLL_HDMI_CTRL_REG RCT_REG(PLL_HDMI_CTRL_OFFSET)
+#define PLL_HDMI_CTRL2_REG RCT_REG(PLL_HDMI_CTRL2_OFFSET)
+#define PLL_HDMI_CTRL3_REG RCT_REG(PLL_HDMI_CTRL3_OFFSET)
+#define PLL_HDMI_FRAC_REG RCT_REG(PLL_HDMI_FRAC_OFFSET)
+#define SCALER_HDMI_PRE_REG RCT_REG(SCALER_HDMI_PRE_OFFSET)
+#define SCALER_HDMI_POST_REG RCT_REG(SCALER_HDMI_POST_OFFSET)
+
+#define USE_CLK_SI_4_CLK_VO_OFFSET 0xB8
+#define CLK_REF_VIDEO_EXTERNAL_OFFSET 0xAC
+
+#define USE_CLK_SI_4_CLK_VO_REG RCT_REG(USE_CLK_SI_4_CLK_VO_OFFSET)
+#define CLK_REF_VIDEO_EXTERNAL_REG RCT_REG(CLK_REF_VIDEO_EXTERNAL_OFFSET)
+
+/* ==========================================================================*/
+#define PLL_VIDEO_CTRL_OFFSET 0x14
+#define PLL_VIDEO_FRAC_OFFSET 0x18
+#define SCALER_VIDEO_PRE_OFFSET 0x1C
+#define SCALER_VIDEO_POST_OFFSET 0xA0
+#define PLL_VIDEO_CTRL2_OFFSET 0x130
+#define PLL_VIDEO_CTRL3_OFFSET 0x134
+#define PLL_VIDEO_CTRL_REG RCT_REG(PLL_VIDEO_CTRL_OFFSET)
+#define PLL_VIDEO_FRAC_REG RCT_REG(PLL_VIDEO_FRAC_OFFSET)
+#define SCALER_VIDEO_PRE_REG RCT_REG(SCALER_VIDEO_PRE_OFFSET)
+#define SCALER_VIDEO_POST_REG RCT_REG(SCALER_VIDEO_POST_OFFSET)
+#define PLL_VIDEO_CTRL2_REG RCT_REG(PLL_VIDEO_CTRL2_OFFSET)
+#define PLL_VIDEO_CTRL3_REG RCT_REG(PLL_VIDEO_CTRL3_OFFSET)
+
+#define PLL_VIDEO2_CTRL_OFFSET 0xC0
+#define PLL_VIDEO2_FRAC_OFFSET 0xC4
+#define SCALER_VIDEO2_PRE_OFFSET 0xC8
+#define SCALER_VIDEO2_POST_OFFSET 0xCC
+#define PLL_VIDEO2_CTRL2_OFFSET 0x13C
+#define PLL_VIDEO2_CTRL3_OFFSET 0x140
+#define USE_CLK_SI_4_VO2_OFFSET 0xD0
+#define USE_EXTERNAL_VD2_CLK_OFFSET 0xD4
+#define CLK_REF_VIDEO2_EXTERNAL_OFFSET 0xD8
+
+#define PLL_VIDEO2_CTRL_REG RCT_REG(PLL_VIDEO2_CTRL_OFFSET)
+#define PLL_VIDEO2_FRAC_REG RCT_REG(PLL_VIDEO2_FRAC_OFFSET)
+#define SCALER_VIDEO2_PRE_REG RCT_REG(SCALER_VIDEO2_PRE_OFFSET)
+#define SCALER_VIDEO2_POST_REG RCT_REG(SCALER_VIDEO2_POST_OFFSET)
+#define PLL_VIDEO2_CTRL2_REG RCT_REG(PLL_VIDEO2_CTRL2_OFFSET)
+#define PLL_VIDEO2_CTRL3_REG RCT_REG(PLL_VIDEO2_CTRL3_OFFSET)
+#define USE_CLK_SI_4_VO2_REG RCT_REG(USE_CLK_SI_4_VO2_OFFSET)
+#define USE_EXTERNAL_VD2_CLK_REG RCT_REG(USE_EXTERNAL_VD2_CLK_OFFSET)
+#define CLK_REF_VIDEO2_EXTERNAL_REG RCT_REG(CLK_REF_VIDEO2_EXTERNAL_OFFSET)
+
+/* ==========================================================================*/
+#define SCALER_ARM_ASYNC_OFFSET 0x1F0
+
+#define SCALER_ARM_ASYNC_REG RCT_REG(SCALER_ARM_ASYNC_OFFSET)
+
+/* ==========================================================================*/
+#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+#define PLL_CORTEX_CTRL_OFFSET 0x264
+#define PLL_CORTEX_FRAC_OFFSET 0x268
+#define PLL_CORTEX_CTRL2_OFFSET 0x26C
+#define PLL_CORTEX_CTRL3_OFFSET 0x270
+#else
+#define PLL_CORTEX_CTRL_OFFSET 0x2B0
+#define PLL_CORTEX_FRAC_OFFSET 0x2B4
+#define PLL_CORTEX_CTRL2_OFFSET 0x2B8
+#define PLL_CORTEX_CTRL3_OFFSET 0x2BC
+#endif
+
+#define PLL_CORTEX_CTRL_REG RCT_REG(PLL_CORTEX_CTRL_OFFSET)
+#define PLL_CORTEX_FRAC_REG RCT_REG(PLL_CORTEX_FRAC_OFFSET)
+#define PLL_CORTEX_CTRL2_REG RCT_REG(PLL_CORTEX_CTRL2_OFFSET)
+#define PLL_CORTEX_CTRL3_REG RCT_REG(PLL_CORTEX_CTRL3_OFFSET)
+
+/* ==========================================================================*/
+
+#if (CHIP_REV == S3L)
+#define ENET_CLK_SRC_SEL_OFFSET 0x544
+#define ENET_CLK_SRC_SEL_REG RCT_REG(ENET_CLK_SRC_SEL_OFFSET)
+#elif (CHIP_REV == S2E || CHIP_REV == S2)
+#define ENET_CLK_SRC_SEL_OFFSET 0x2CC
+#define ENET_CLK_SRC_SEL_REG RCT_REG(ENET_CLK_SRC_SEL_OFFSET)
+#else
+#define ENET_CLK_SRC_SEL_REG 0
+#endif
+
+#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+#define PLL_ENET_CTRL_OFFSET 0x520
+#define PLL_ENET_FRAC_OFFSET 0x524
+#define PLL_ENET_CTRL2_OFFSET 0x528
+#define PLL_ENET_CTRL3_OFFSET 0x52C
+#define SCALER_ENET_POST_OFFSET 0x534
+#endif
+#define PLL_ENET_CTRL_REG RCT_REG(PLL_ENET_CTRL_OFFSET)
+#define PLL_ENET_FRAC_REG RCT_REG(PLL_ENET_FRAC_OFFSET)
+#define PLL_ENET_CTRL2_REG RCT_REG(PLL_ENET_CTRL2_OFFSET)
+#define PLL_ENET_CTRL3_REG RCT_REG(PLL_ENET_CTRL3_OFFSET)
+#define SCALER_ENET_POST_REG RCT_REG(SCALER_ENET_POST_OFFSET)
+
+/* ==========================================================================*/
+#define SCALER_SD48_OFFSET 0x0C
+#define SCALER_SD48_REG RCT_REG(SCALER_SD48_OFFSET)
+
+#if (CHIP_REV == S2) || (CHIP_REV == S2E)
+#define SCALER_SDIO_OFFSET 0x10
+#else
+#define SCALER_SDIO_OFFSET 0x430
+#endif
+#define SCALER_SDIO_REG RCT_REG(SCALER_SDIO_OFFSET)
+
+#define SCALER_SDXC_OFFSET 0x434
+#define SCALER_SDXC_REG RCT_REG(SCALER_SDXC_OFFSET)
+
+#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+#define PLL_SD_CTRL_OFFSET 0x4AC
+#define PLL_SD_FRAC_OFFSET 0x4B0
+#define PLL_SD_CTRL2_OFFSET 0x4B4
+#define PLL_SD_CTRL3_OFFSET 0x4B8
+#elif (CHIP_REV == S2E)
+#define SDVCO_FOR_GTX_SOURCE 0x00000010
+#define FUNC_MISC_CTRL_OFFSET 0x328
+#define PLL_SD_CTRL_OFFSET 0x354
+#define PLL_SD_FRAC_OFFSET 0x360
+#define PLL_SD_CTRL2_OFFSET 0x358
+#define PLL_SD_CTRL3_OFFSET 0x35C
+#define FUNC_MISC_CTRL_REG RCT_REG(FUNC_MISC_CTRL_OFFSET)
+#endif
+#define PLL_SD_CTRL_REG RCT_REG(PLL_SD_CTRL_OFFSET)
+#define PLL_SD_FRAC_REG RCT_REG(PLL_SD_FRAC_OFFSET)
+#define PLL_SD_CTRL2_REG RCT_REG(PLL_SD_CTRL2_OFFSET)
+#define PLL_SD_CTRL3_REG RCT_REG(PLL_SD_CTRL3_OFFSET)
+
+#if (CHIP_REV == A5S) || (CHIP_REV == S2)
+#define SD_SOFT_PHY_SUPPORT 0
+#else
+#define SD_SOFT_PHY_SUPPORT 1
+#endif
+
+#if (SD_SOFT_PHY_SUPPORT == 1)
+#define SD_PHY_CLKOUT_BYPASS 1 << 26
+#define SD_PHY_RESET 1 << 25
+#define SD_PHY_RX_CLK_POL 1 << 19
+#define SD_PHY_DATA_CMD_BYPASS 1 << 18
+#define SD_PHY_DLL_BYPASS 1 << 17
+
+#if (CHIP_REV == S2E)
+#define SD_PHY_CTRL_0_OFFSET 0x340
+#define SD_PHY_CTRL_1_OFFSET 0x344
+#define SD_PHY_OBSV_OFFSET 0x348
+#else
+#define SD_PHY_CTRL_0_OFFSET 0x4C0
+#define SD_PHY_CTRL_1_OFFSET 0x4C4
+#define SD_PHY_OBSV_OFFSET 0x4F0
+#endif
+#define SD_PHY_CTRL_0_REG RCT_REG(SD_PHY_CTRL_0_OFFSET)
+#define SD_PHY_CTRL_1_REG RCT_REG(SD_PHY_CTRL_1_OFFSET)
+#define SD_PHY_OBSV_REG RCT_REG(SD_PHY_OBSV_OFFSET)
+
+#if (CHIP_REV == S3L)
+#define SDXC_PHY_CTRL_0_OFFSET 0x4C8
+#define SDXC_PHY_CTRL_1_OFFSET 0x4CC
+#define SDXC_PHY_OBSV_OFFSET 0x4F0
+#define SDXC_PHY_CTRL_0_REG RCT_REG(SDXC_PHY_CTRL_0_OFFSET)
+#define SDXC_PHY_CTRL_1_REG RCT_REG(SDXC_PHY_CTRL_1_OFFSET)
+#define SDXC_PHY_OBSV_REG RCT_REG(SDXC_PHY_OBSV_OFFSET)
+#endif
+
+#else
+#define MS_DELAY_CTRL_OFFSET 0x1D0
+#define MS_DELAY_CTRL_REG RCT_REG(MS_DELAY_CTRL_OFFSET)
+#endif
+
+
+/* ==========================================================================*/
+#if (CHIP_REV == A5S) || (CHIP_REV == A7L) || (CHIP_REV == S2) || (CHIP_REV == S2E)
+#define ADC_SOFT_RESET 0x0
+#else
+#define ADC_SOFT_RESET 0x10000
+#endif
+#define SCALER_ADC_OFFSET 0x09C
+#define SCALER_ADC_REG RCT_REG(SCALER_ADC_OFFSET)
+
+#define ADC16_CTRL_OFFSET 0x198
+#define ADC16_CTRL_REG RCT_REG(ADC16_CTRL_OFFSET)
+
+/* ==========================================================================*/
+#define AHB_MISC_EN_OFFSET 0x21C
+#define AHB_MISC_EN_REG RCT_REG(AHB_MISC_EN_OFFSET)
+
+/* ==========================================================================*/
+#define IOCTRL_GPIO_OFFSET 0x1F8
+#define IOCTRL_GPIO_REG RCT_REG(IOCTRL_GPIO_OFFSET)
+
+#define IOCTRL_MISC1_OFFSET 0x1FC
+#define IOCTRL_MISC1_REG RCT_REG(IOCTRL_MISC1_OFFSET)
+
+#define IOCTRL_MISC2_OFFSET 0x200
+#define IOCTRL_MISC2_REG RCT_REG(IOCTRL_MISC2_OFFSET)
+
+#define IOCTRL_SMIOA_OFFSET 0x204
+#define IOCTRL_SMIOA_REG RCT_REG(IOCTRL_SMIOA_OFFSET)
+
+#define IOCTRL_SMIOB_OFFSET 0x208
+#define IOCTRL_SMIOB_REG RCT_REG(IOCTRL_SMIOB_OFFSET)
+
+#define IOCTRL_SMIOC_OFFSET 0x20C
+#define IOCTRL_SMIOC_REG RCT_REG(IOCTRL_SMIOC_OFFSET)
+
+#define IOCTRL_SMIOD_OFFSET 0x210
+#define IOCTRL_SMIOD_REG RCT_REG(IOCTRL_SMIOD_OFFSET)
+
+#define IOCTRL_VD1_OFFSET 0x214
+#define IOCTRL_VD1_REG RCT_REG(IOCTRL_VD1_OFFSET)
+
+#define IOCTRL_SENSOR_OFFSET 0x218
+#define IOCTRL_SENSOR_REG RCT_REG(IOCTRL_SENSOR_OFFSET)
+
+#define IOCTRL_STRIG_OFFSET 0x250
+#define IOCTRL_STRIG_REG RCT_REG(IOCTRL_STRIG_OFFSET)
+
+#define IOCTRL_SDXC_OFFSET 0x2F4
+#define IOCTRL_SDXC_REG RCT_REG(IOCTRL_SDXC_OFFSET)
+
+#define SDXC_PULL_CTRL_OFFSET 0x2F8
+#define SDXC_PULL_CTRL_REG RCT_REG(SDXC_PULL_CTRL_OFFSET)
+
+#if (CHIP_REV == S2) || (CHIP_REV == S2E)
+#define IOCTRL_DRIVE_STRENGTH_3MA 0x0
+#define IOCTRL_DRIVE_STRENGTH_12MA 0x1
+#define IOCTRL_DRIVE_STRENGTH_6MA 0x2
+#define IOCTRL_DRIVE_STRENGTH_18MA 0x3
+#else
+#define IOCTRL_DRIVE_STRENGTH_2MA 0x0
+#define IOCTRL_DRIVE_STRENGTH_8MA 0x1
+#define IOCTRL_DRIVE_STRENGTH_4MA 0x2
+#define IOCTRL_DRIVE_STRENGTH_12MA 0x3
+#endif
+
+#if (CHIP_REV == A5S)
+#define GPIO_PAD_DS_SUPPORT 0
+#else
+#define GPIO_PAD_DS_SUPPORT 1
+#endif
+
+#if (CHIP_REV == S2) || (CHIP_REV == S2E)
+#define GPIO_DS0_0_OFFSET 0x270
+#define GPIO_DS0_1_OFFSET 0x274
+#define GPIO_DS0_2_OFFSET 0x278
+#define GPIO_DS0_3_OFFSET 0x27C
+#define GPIO_DS0_4_OFFSET 0x280
+#define GPIO_DS1_0_OFFSET 0x284
+#define GPIO_DS1_1_OFFSET 0x288
+#define GPIO_DS1_2_OFFSET 0x28C
+#define GPIO_DS1_3_OFFSET 0x290
+#define GPIO_DS1_4_OFFSET 0x294
+#define GPIO_DS0_OFFSET(bank) (0x270 + ((bank) * 4))
+#define GPIO_DS1_OFFSET(bank) (0x284 + ((bank) * 4))
+
+#else
+#define GPIO_DS0_0_OFFSET 0x314
+#define GPIO_DS1_0_OFFSET 0x318
+#define GPIO_DS0_1_OFFSET 0x31C
+#define GPIO_DS1_1_OFFSET 0x320
+#define GPIO_DS0_2_OFFSET 0x324
+#define GPIO_DS1_2_OFFSET 0x328
+#define GPIO_DS0_3_OFFSET 0x32C
+#define GPIO_DS1_3_OFFSET 0x330
+#define GPIO_DS0_4_OFFSET 0x438
+#define GPIO_DS1_4_OFFSET 0x43C
+#define GPIO_DS0_5_OFFSET 0x440
+#define GPIO_DS1_5_OFFSET 0x444
+#define GPIO_DS0_6_OFFSET 0x448
+#define GPIO_DS1_6_OFFSET 0x44C
+#define GPIO_DS0_OFFSET(bank) ((bank) >= 4 ? \
+ (0x438 + (((bank) - 4) * 8)) : \
+ (0x314 + ((bank) * 8)))
+#define GPIO_DS1_OFFSET(bank) ((bank) >= 4 ? \
+ (0x438 + (((bank) - 4) * 8) + 4) : \
+ (0x314 + ((bank) * 8) + 4))
+#endif
+
+#define GPIO_DS0_0_REG RCT_REG(GPIO_DS0_0_OFFSET)
+#define GPIO_DS1_0_REG RCT_REG(GPIO_DS1_0_OFFSET)
+#define GPIO_DS0_1_REG RCT_REG(GPIO_DS0_1_OFFSET)
+#define GPIO_DS1_1_REG RCT_REG(GPIO_DS1_1_OFFSET)
+#define GPIO_DS0_2_REG RCT_REG(GPIO_DS0_2_OFFSET)
+#define GPIO_DS1_2_REG RCT_REG(GPIO_DS1_2_OFFSET)
+#define GPIO_DS0_3_REG RCT_REG(GPIO_DS0_3_OFFSET)
+#define GPIO_DS1_3_REG RCT_REG(GPIO_DS1_3_OFFSET)
+#define GPIO_DS0_4_REG RCT_REG(GPIO_DS0_4_OFFSET)
+#define GPIO_DS1_4_REG RCT_REG(GPIO_DS1_4_OFFSET)
+#define GPIO_DS0_5_REG RCT_REG(GPIO_DS0_5_OFFSET)
+#define GPIO_DS1_5_REG RCT_REG(GPIO_DS1_5_OFFSET)
+#define GPIO_DS0_6_REG RCT_REG(GPIO_DS0_6_OFFSET)
+#define GPIO_DS1_6_REG RCT_REG(GPIO_DS1_6_OFFSET)
+
+/* ==========================================================================*/
+#define RCT_TIMER_OFFSET 0x254
+#define RCT_TIMER_CTRL_OFFSET 0x258
+
+#define RCT_TIMER_REG RCT_REG(RCT_TIMER_OFFSET)
+#define RCT_TIMER_CTRL_REG RCT_REG(RCT_TIMER_CTRL_OFFSET)
+
+/* ==========================================================================*/
+
+#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+#define AHB_MISC_OFFSET 0x21c
+#endif
+#define AHB_MISC_REG RCT_REG(AHB_MISC_OFFSET)
+
+/* ==========================================================================*/
+
+/* Secure and Scratchpad */
+#define AHB_SCRATCHPAD_OFFSET 0x1B000
+#define AHB_SECURE_OFFSET 0x1D000
+#define AHB_SCRATCHPAD_BASE (AHB_BASE + AHB_SCRATCHPAD_OFFSET)
+#define AHB_SECURE_BASE (AHB_BASE + AHB_SECURE_OFFSET)
+#define AHB_SCRATCHPAD_REG(x) (AHB_SCRATCHPAD_BASE + (x))
+#define AHB_SECURE_REG(x) (AHB_SECURE_BASE + (x))
+
+#if (CHIP_REV == S3L)
+#define AHBSP_PRI_IRQ_C0_OFFSET 0x38
+#define AHBSP_PRI_IRQ_C1_OFFSET -1 /* not supported */
+#else
+#define AHBSP_PRI_IRQ_C0_OFFSET 0x3C
+#define AHBSP_PRI_IRQ_C1_OFFSET 0x40
+#endif
+#define AHBSP_PRI_IRQ_C0_REG AHB_SCRATCHPAD_REG(AHBSP_PRI_IRQ_C0_OFFSET)
+#define AHBSP_PRI_IRQ_C1_REG AHB_SCRATCHPAD_REG(AHBSP_PRI_IRQ_C1_OFFSET)
+
+/* ==========================================================================*/
+
+#if (CHIP_REV == S3) || (CHIP_REV == S3L)
+#define DMA_SUPPORT_SELECT_CHANNEL 1
+#else
+#define DMA_SUPPORT_SELECT_CHANNEL 0
+#endif
+
+#if (CHIP_REV == S3)
+#define AHBSP_DMA_CHANNEL_SEL_OFFSET 0x30
+#elif (CHIP_REV == S3L)
+#define AHBSP_DMA_CHANNEL_SEL_OFFSET 0x2C
+#endif
+#define AHBSP_DMA_CHANNEL_SEL_REG AHB_SCRATCHPAD_REG(AHBSP_DMA_CHANNEL_SEL_OFFSET)
+
+#define SSI0_TX_DMA_REQ_IDX 0
+#define SSI0_RX_DMA_REQ_IDX 1
+#define SSI1_TX_DMA_REQ_IDX 2
+#define SSI1_RX_DMA_REQ_IDX 3
+#define NOR_SPI_TX_DMA_REQ_IDX 4
+#define NOR_SPI_RX_DMA_REQ_IDX 5
+#define SSIS0_TX_DMA_REQ_IDX 6
+#define SSIS0_RX_DMA_REQ_IDX 7
+#define UART_TX_DMA_REQ_IDX 8
+#define UART_RX_DMA_REQ_IDX 9
+#define I2S_TX_DMA_REQ_IDX 10
+#define I2S_RX_DMA_REQ_IDX 11
+#define SLIM_TX_DMA_REQ_IDX 12
+#define SLIM_RX_DMA_REQ_IDX 13
+
+/* ==========================================================================*/
+#if (CHIP_REV == A5S) || (CHIP_REV == A7L)
+#define POC_BOOT_MAP_TYPE 0
+#define POC_BOOT_FROM_MASK 0x00010500
+#define POC_BOOT_FROM_USB 0x00000000
+#define POC_BOOT_FROM_BYPASS 0x00000100
+#define POC_BOOT_FROM_NAND 0x00000400
+#define POC_BOOT_FROM_EMMC 0xFFFFFFFF /* not supported */
+#define POC_BOOT_FROM_SPINOR 0xFFFFFFFF /* not supported */
+#define POC_BOOT_FROM_HIF 0xFFFFFFFF /* not supported */
+#elif (CHIP_REV == S2) || (CHIP_REV == S2E)
+#define POC_BOOT_MAP_TYPE 0
+#define POC_BOOT_FROM_MASK 0x00003140
+#define POC_BOOT_FROM_BYPASS 0x00000040
+#define POC_BOOT_FROM_USB 0x00000000
+#define POC_BOOT_FROM_NAND 0x00000100
+#define POC_BOOT_FROM_SPINOR 0x00001000 /* not supported on S2 */
+#define POC_BOOT_FROM_EMMC 0x00002000
+#define POC_BOOT_FROM_HIF 0xFFFFFFFF /* not supported */
+#elif (CHIP_REV == S3)
+#define POC_BOOT_MAP_TYPE 1
+#define POC_BOOT_FROM_MASK 0x00000570
+#define POC_BOOT_FROM_BYPASS 0x00000100
+#define POC_BOOT_FROM_USB 0x00000400
+#define POC_BOOT_FROM_SPINOR 0x00000000
+#define POC_BOOT_FROM_NAND 0x00000010
+#define POC_BOOT_FROM_EMMC 0x00000020
+#define POC_BOOT_FROM_HIF 0x00000040
+#elif (CHIP_REV == S2L) || (CHIP_REV == S3L)
+#define POC_BOOT_MAP_TYPE 1
+#define POC_BOOT_FROM_MASK 0x00000530
+#define POC_BOOT_FROM_BYPASS 0x00000100
+#define POC_BOOT_FROM_USB 0x00000400
+#define POC_BOOT_FROM_SPINOR 0x00000000
+#define POC_BOOT_FROM_NAND 0x00000010
+#define POC_BOOT_FROM_EMMC 0x00000020
+#define POC_BOOT_FROM_HIF 0xFFFFFFFF /* not supported */
+#endif
+
+#define RCT_BOOT_FROM_BYPASS 0x80000000
+#define RCT_BOOT_FROM_NAND 0x00000001
+#define RCT_BOOT_FROM_USB 0x00000002
+#define RCT_BOOT_FROM_EMMC 0x00000004
+#define RCT_BOOT_FROM_SPINOR 0x00000008
+#define RCT_BOOT_FROM_HIF 0x00000010
+
+/* ==========================================================================*/
+#if (CHIP_REV == A5S)
+#define SYS_CONFIG_NAND_PAGE_SIZE 0x00000020
+#define SYS_CONFIG_NAND_READ_CONFIRM 0x00000040
+#define SYS_CONFIG_NAND_ECC_BCH_EN 0x00000000
+#define SYS_CONFIG_NAND_ECC_SPARE_2X 0x00000000
+#elif (CHIP_REV == S2) || (CHIP_REV == S2E)
+#define SYS_CONFIG_NAND_PAGE_SIZE 0x00000010
+#define SYS_CONFIG_NAND_READ_CONFIRM 0x00000020
+#define SYS_CONFIG_NAND_ECC_BCH_EN 0x00000400
+#define SYS_CONFIG_NAND_ECC_SPARE_2X 0x00000800
+#else
+#define SYS_CONFIG_NAND_PAGE_SIZE 0x00040000
+#define SYS_CONFIG_NAND_READ_CONFIRM 0x00020000
+#define SYS_CONFIG_NAND_ECC_BCH_EN 0x00010000
+#define SYS_CONFIG_NAND_ECC_SPARE_2X 0x00008000
+#endif
+
+/* these definition are used by software */
+#define RCT_BOOT_NAND_AUTO 0x00000000
+#define RCT_BOOT_NAND_PAGE_SIZE 0x00000001
+#define RCT_BOOT_NAND_READ_CONFIRM 0x00000002
+#define RCT_BOOT_NAND_ECC_BCH_EN 0x00000004
+#define RCT_BOOT_NAND_ECC_SPARE_2X 0x00000008
+
+/* ==========================================================================*/
+#if (CHIP_REV == S2)
+#define SYS_CONFIG_MMC_HS 0x00010000
+#define SYS_CONFIG_MMC_DDR 0x00020000
+#define SYS_CONFIG_MMC_4BIT 0x00040000
+#define SYS_CONFIG_MMC_8BIT 0x00080000
+#elif (CHIP_REV == S2E)
+#define SYS_CONFIG_MMC_HS 0x00010000
+#define SYS_CONFIG_MMC_DDR 0x00000000 /* not supported */
+#define SYS_CONFIG_MMC_4BIT 0x00040000
+#define SYS_CONFIG_MMC_8BIT 0x00080000
+#elif (CHIP_REV == S2L) || (CHIP_REV == S3)
+#define SYS_CONFIG_MMC_HS 0x00008000
+#define SYS_CONFIG_MMC_DDR 0x00004000
+#define SYS_CONFIG_MMC_4BIT 0x00020000
+#define SYS_CONFIG_MMC_8BIT 0x00010000
+#elif (CHIP_REV == S3L)
+#define SYS_CONFIG_MMC_HS 0x00000000
+#define SYS_CONFIG_MMC_DDR 0x00000000
+#define SYS_CONFIG_MMC_4BIT 0x00010000
+#define SYS_CONFIG_MMC_8BIT 0x00008000
+#else
+#define SYS_CONFIG_MMC_HS 0x00000000
+#define SYS_CONFIG_MMC_DDR 0x00000000
+#define SYS_CONFIG_MMC_4BIT 0x00000000
+#define SYS_CONFIG_MMC_8BIT 0x00000000
+#endif
+
+/* these definition are used by software */
+#define RCT_BOOT_EMMC_AUTO 0x00000000
+#define RCT_BOOT_EMMC_HS 0x00000001
+#define RCT_BOOT_EMMC_DDR 0x00000002
+#define RCT_BOOT_EMMC_4BIT 0x00000004
+#define RCT_BOOT_EMMC_8BIT 0x00000008
+
+#endif /* __PLAT_AMBARELLA_RCT_H__ */
+
diff --git a/arch/arm/mach-ambarella/include/plat/remoteproc.h b/arch/arm/mach-ambarella/include/plat/remoteproc.h
new file mode 100644
index 00000000..a59d09b5
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/remoteproc.h
@@ -0,0 +1,44 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/remoteproc.h
+ *
+ * Author: Tzu-Jung Lee <tjlee@ambarella.com>
+ *
+ * Copyright (C) 2012-2012, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_REMOTEPROC_H
+#define __PLAT_AMBARELLA_REMOTEPROC_H
+
+#include <linux/remoteproc.h>
+
+struct ambarella_rproc_pdata {
+ const char *name;
+ struct rproc *rproc;
+ const char *firmware;
+ int svq_tx_irq;
+ int svq_rx_irq;
+ int rvq_tx_irq;
+ int rvq_rx_irq;
+ const struct rproc_ops *ops;
+ unsigned long buf_addr_pa;
+ struct work_struct svq_work;
+ struct work_struct rvq_work;
+ struct resource_table *(*gen_rsc_table)(int *tablesz);
+};
+
+#endif /* __PLAT_AMBARELLA_REMOTEPROC_H */
diff --git a/arch/arm/mach-ambarella/include/plat/remoteproc_cfg.h b/arch/arm/mach-ambarella/include/plat/remoteproc_cfg.h
new file mode 100644
index 00000000..873ef038
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/remoteproc_cfg.h
@@ -0,0 +1,125 @@
+/**
+ * History:
+ * 2012/09/17 - [Tzu-Jung Lee] created file
+ *
+ * Copyright 2008-2015 Ambarella Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __PLAT_AMBARELLA_REMOTEPROC_CFG_H
+#define __PLAT_AMBARELLA_REMOTEPROC_CFG_H
+
+
+/*
+ * [Copy from the virtio_ring.h]
+ *
+ * The standard layout for the ring is a continuous chunk of memory which looks
+ * like this. We assume num is a power of 2.
+ *
+ * struct vring
+ * {
+ * // The actual descriptors (16 bytes each)
+ * struct vring_desc desc[num];
+ *
+ * // A ring of available descriptor heads with free-running index.
+ * __u16 avail_flags;
+ * __u16 avail_idx;
+ * __u16 available[num];
+ * __u16 used_event_idx;
+ *
+ * // Padding to the next align boundary.
+ * char pad[];
+ *
+ * // A ring of used descriptor heads with free-running index.
+ * __u16 used_flags;
+ * __u16 used_idx;
+ * struct vring_used_elem used[num];
+ * __u16 avail_event_idx;
+ * };
+ */
+
+/*
+ * Calculation of memory usage for a descriptior rings with n buffers:
+ *
+ * (16 * n) + 2 + 2 + (2 * n) + PAD + 2 + 2 + (8 * n) + 2
+ *
+ * = (26 * n) + 10 + PAD( < 4K)
+ *
+ * EX:
+ * A RPMSG bus with 4096 buffers has two descriptor rings with 2048
+ * descriptors each. And each of the them needs:
+ *
+ * 26 * 2K + 10 + 4K = 56 K + 10 bytes
+ */
+
+#define RPMSG_VRING_BASE (CONFIG_RPMSG_VRING_BASE)
+#define RPMSG_NUM_BUFS (CONFIG_RPMSG_NUM_BUFS)
+#define RPMSG_BUF_SIZE (CONFIG_RPMSG_BUF_SIZE)
+
+#define RPMSG_TOTAL_BUF_SPACE (RPMSG_NUM_BUFS * RPMSG_BUF_SIZE)
+
+#ifdef CONFIG_MACH_GINKGO
+
+#define VRING_C0_TO_C1 (0x21000000)
+#define VRING_C1_TO_C0 (0x21020000)
+#define VRING_C0_AND_C1_BUF (0x20000000)
+#define VRING_IRQ_C0_TO_C1_KICK (106)
+#define VRING_IRQ_C0_TO_C1_ACK (107)
+#define VRING_IRQ_C1_TO_C0_KICK (108)
+#define VRING_IRQ_C1_TO_C0_ACK (109)
+
+#elif defined(CONFIG_MACH_HYACINTH_0) || defined(CONFIG_MACH_HYACINTH_1)
+/*
+ * On A8, we allocate 4096 4K-byte buffers for each RPMSG bus.
+ * The buffers are partitioned into two dedicated halves for TX and RX.
+ * Besides the 16 MB buffer space, each RPMSG bus also requires two
+ * descriptor rings with 56 KB each.
+ *
+ * Two make it simple for the configuration and debugging,
+ * we allocate 64 MB in total for the 3 RPMSG buses.
+ * The first 16 MB are used for the 3 * 2 descrpitor rings.
+ * And the reset of 48 MB are partitioned for the 3 buses.
+ */
+#define VRING_CA9_B_TO_A (RPMSG_VRING_BASE + 0x00000000)
+#define VRING_CA9_A_TO_B (RPMSG_VRING_BASE + 0x00010000)
+
+#define VRING_ARM11_TO_CA9_A (RPMSG_VRING_BASE + 0x00020000)
+#define VRING_CA9_A_TO_ARM11 (RPMSG_VRING_BASE + 0x00030000)
+
+#define VRING_ARM11_TO_CA9_B (RPMSG_VRING_BASE + 0x00040000)
+#define VRING_CA9_B_TO_ARM11 (RPMSG_VRING_BASE + 0x00050000)
+
+#define VRING_BUF_CA9_A_AND_B (RPMSG_VRING_BASE + RPMSG_TOTAL_BUF_SPACE * 1)
+
+#define VRING_BUF_CA9_A_AND_ARM11 (RPMSG_VRING_BASE + RPMSG_TOTAL_BUF_SPACE * 2)
+
+#define VRING_BUF_CA9_B_AND_ARM11 (RPMSG_VRING_BASE + RPMSG_TOTAL_BUF_SPACE * 3)
+
+#define VRING_CA9_A_TO_B_CLNT_IRQ (106)
+#define VRING_CA9_A_TO_B_HOST_IRQ (107)
+
+#define VRING_CA9_B_TO_A_CLNT_IRQ (108)
+#define VRING_CA9_B_TO_A_HOST_IRQ (109)
+
+#define VRING_CA9_A_TO_ARM11_CLNT_IRQ (110)
+#define VRING_CA9_A_TO_ARM11_HOST_IRQ (111)
+
+#define VRING_ARM11_TO_CA9_A_CLNT_IRQ (112)
+#define VRING_ARM11_TO_CA9_A_HOST_IRQ (113)
+
+#define VRING_CA9_B_TO_ARM11_CLNT_IRQ (114)
+#define VRING_CA9_B_TO_ARM11_HOST_IRQ (115)
+
+#define VRING_ARM11_TO_CA9_B_CLNT_IRQ (116)
+#define VRING_ARM11_TO_CA9_B_HOST_IRQ (117)
+#endif /* CONFIG_MACH_XXX */
+
+#endif /* __PLAT_AMBARELLA_REMOTEPROC_CFG_H */
diff --git a/arch/arm/mach-ambarella/include/plat/rpdev.h b/arch/arm/mach-ambarella/include/plat/rpdev.h
new file mode 100644
index 00000000..d8a4ce12
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/rpdev.h
@@ -0,0 +1,68 @@
+/**
+ * system/src/rpclnt/rpdev.h
+ *
+ * History:
+ * 2012/08/15 - [Tzu-Jung Lee] created file
+ *
+ * Copyright 2008-2015 Ambarella Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __RPDEV_H__
+#define __RPDEV_H__
+
+#define RPMSG_VRING_ALIGN (4096)
+#define RPMSG_RESERVED_ADDRESSES (1024)
+#define RPMSG_ADDRESS_ANY (0xffffffff)
+#define RPMSG_NS_ADDR (53)
+#define RPMSG_NAME_LEN (32)
+
+#if defined (__KERNEL__)
+#include <plat/remoteproc_cfg.h>
+#include <linux/sched.h>
+#include <linux/rpmsg.h>
+#else
+#include "rpmsg.h"
+#endif
+
+struct rpdev;
+typedef void (*rpdev_cb)(struct rpdev* rpdev, void *data, int len,
+ void *priv, u32 src);
+struct rpdev {
+
+#if defined(__KERNEL__)
+ struct completion comp;
+#else
+ ID flgid;
+#endif
+
+ struct rpclnt *rpclnt;
+ char name[RPMSG_NAME_LEN];
+ u32 src;
+ u32 dst;
+ u32 flags;
+
+ rpdev_cb cb;
+ void *priv;
+};
+
+extern int rpdev_register(struct rpdev *rpdev, const char *bus_name);
+
+extern struct rpdev *rpdev_alloc(const char *name, int flags,
+ rpdev_cb cb, void *priv);
+
+extern int rpdev_send_offchannel(struct rpdev *rpdev, u32 src, u32 dst,
+ void *data, int len);
+
+extern int rpdev_send(struct rpdev *rpdev, void *data, int len);
+extern int rpdev_trysend(struct rpdev *rpdev, void *data, int len);
+
+#endif /* __RPDEV_H__ */
diff --git a/arch/arm/mach-ambarella/include/plat/rtc.h b/arch/arm/mach-ambarella/include/plat/rtc.h
new file mode 100644
index 00000000..6d7c638f
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/rtc.h
@@ -0,0 +1,98 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/rtc.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_RTC_H__
+#define __PLAT_AMBARELLA_RTC_H__
+
+/* ==========================================================================*/
+#if (CHIP_REV == A5S)
+#define RTC_SUPPORT_30BITS_PASSED_SECONDS 1
+#else
+#define RTC_SUPPORT_30BITS_PASSED_SECONDS 0
+#endif
+
+#if (CHIP_REV == A5S)
+#define RTC_POWER_LOST_DETECT 0
+#else
+#define RTC_POWER_LOST_DETECT 1
+#endif
+
+/* ==========================================================================*/
+#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+#define RTC_OFFSET 0x15000
+#else
+#define RTC_OFFSET 0xD000
+#endif
+#define RTC_BASE (APB_BASE + RTC_OFFSET)
+#define RTC_REG(x) (RTC_BASE + (x))
+
+/* ==========================================================================*/
+#define RTC_POS0_OFFSET 0x20
+#define RTC_POS1_OFFSET 0x24
+#define RTC_POS2_OFFSET 0x28
+#define RTC_PWC_ALAT_OFFSET 0x2C
+#define RTC_PWC_CURT_OFFSET 0x30
+#define RTC_CURT_OFFSET 0x34
+#define RTC_ALAT_OFFSET 0x38
+#define RTC_STATUS_OFFSET 0x3C
+#define RTC_RESET_OFFSET 0x40
+#define RTC_WO_OFFSET 0x7C
+
+#define RTC_PWC_DNALERT_OFFSET 0xA8
+#define RTC_PWC_LBAT_OFFSET 0xAC
+#define RTC_PWC_REG_WKUPC_OFFSET 0xB0
+#define RTC_PWC_REG_STA_OFFSET 0xB4
+#define RTC_PWC_SET_STATUS_OFFSET 0xC0
+#define RTC_PWC_CLR_REG_WKUPC_OFFSET 0xC4
+#define RTC_PWC_WKENC_OFFSET 0xC8
+#define RTC_POS3_OFFSET 0xD0
+
+#define RTC_PWC_ENP1C_OFFSET 0xD4
+#define RTC_PWC_ENP2C_OFFSET 0xD8
+#define RTC_PWC_ENP3C_OFFSET 0xDC
+#define RTC_PWC_ENP1_OFFSET 0xE0
+#define RTC_PWC_ENP2_OFFSET 0xE4
+#define RTC_PWC_ENP3_OFFSET 0xE8
+#define RTC_PWC_DISP1C_OFFSET 0xEC
+#define RTC_PWC_DISP2C_OFFSET 0xF0
+#define RTC_PWC_DISP3C_OFFSET 0xF4
+#define RTC_PWC_DISP1_OFFSET 0xF8
+#define RTC_PWC_DISP2_OFFSET 0xB8
+#define RTC_PWC_DISP3_OFFSET 0xBC
+
+/* ==========================================================================*/
+/* RTC_STATUS_OFFSET */
+#define RTC_STATUS_WKUP 0x8
+#define RTC_STATUS_ALA_WK 0x4
+#define RTC_STATUS_PC_RST 0x2
+#define RTC_STATUS_RTC_CLK 0x1
+
+/* RTC_PWC_REG_STA_OFFSET */
+#define RTC_PWC_LOSS_MASK 0x20
+#define RTC_PWC_ALARM_MASK 0x8
+#define RTC_PWC_SR_MASK 0x4
+
+/* ==========================================================================*/
+
+#endif /* __PLAT_AMBARELLA_RTC_H__ */
+
diff --git a/arch/arm/mach-ambarella/include/plat/sd.h b/arch/arm/mach-ambarella/include/plat/sd.h
new file mode 100644
index 00000000..f6561d10
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/sd.h
@@ -0,0 +1,384 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/sd.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_SD_H__
+#define __PLAT_AMBARELLA_SD_H__
+
+/* ==========================================================================*/
+#if (CHIP_REV == A7L) || (CHIP_REV == S2) || (CHIP_REV == S2E) || (CHIP_REV == S3L)
+#define SD_INSTANCES 2
+#elif (CHIP_REV == S2L) || (CHIP_REV == S3)
+#define SD_INSTANCES 3
+#else
+#define SD_INSTANCES 1
+#endif
+
+#if (CHIP_REV == S2) || (CHIP_REV == S2E) || (CHIP_REV == S2L) || (CHIP_REV == S3)
+#define SD_SUPPORT_SDIO 1
+#else
+#define SD_SUPPORT_SDIO 0
+#endif
+
+#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+#define SD_SUPPORT_SDXC 1
+#else
+#define SD_SUPPORT_SDXC 0
+#endif
+
+/* ==========================================================================*/
+#define SD0_OFFSET 0x2000
+#define SD1_OFFSET 0xC000
+#define SD2_OFFSET 0x1F000
+
+#define SD0_BASE (AHB_BASE + SD0_OFFSET)
+#define SD1_BASE (AHB_BASE + SD1_OFFSET)
+#define SD2_BASE (AHB_BASE + SD2_OFFSET)
+#define SD_BASE(id) ((id == 0) ? SD0_BASE : \
+ (id == 1) ? SD1_BASE : SD2_BASE)
+
+#define SD0_REG(x) (SD0_BASE + (x))
+#define SD2_REG(x) (SD1_BASE + (x))
+#define SD3_REG(x) (SD2_BASE + (x))
+
+/* ==========================================================================*/
+#define SD_DMA_ADDR_OFFSET 0x000
+#define SD_BLK_SZ_OFFSET 0x004 /* Half word */
+#define SD_BLK_CNT_OFFSET 0x006 /* Half word */
+#define SD_ARG_OFFSET 0x008
+#define SD_XFR_OFFSET 0x00C /* Half word */
+#define SD_CMD_OFFSET 0x00E /* Half word */
+#define SD_RSP0_OFFSET 0x010
+#define SD_RSP1_OFFSET 0x014
+#define SD_RSP2_OFFSET 0x018
+#define SD_RSP3_OFFSET 0x01C
+#define SD_DATA_OFFSET 0x020
+#define SD_STA_OFFSET 0x024
+#define SD_HOST_OFFSET 0x028 /* Byte */
+#define SD_PWR_OFFSET 0x029 /* Byte */
+#define SD_GAP_OFFSET 0x02A /* Byte */
+#define SD_WAK_OFFSET 0x02B /* Byte */
+#define SD_CLK_OFFSET 0x02C /* Half word */
+#define SD_TMO_OFFSET 0x02E /* Byte */
+#define SD_RESET_OFFSET 0x02F /* Byte */
+#define SD_NIS_OFFSET 0x030 /* Half word */
+#define SD_EIS_OFFSET 0x032 /* Half word */
+#define SD_NISEN_OFFSET 0x034 /* Half word */
+#define SD_EISEN_OFFSET 0x036 /* Half word */
+#define SD_NIXEN_OFFSET 0x038 /* Half word */
+#define SD_EIXEN_OFFSET 0x03A /* Half word */
+#define SD_AC12ES_OFFSET 0x03C /* Half word */
+#define SD_HOST2_OFFSET 0x03E /* Half word */
+#define SD_CAP_OFFSET 0x040
+#define SD_CUR_OFFSET 0x048
+#define SD_ADMA_STA_OFFSET 0x054
+#define SD_ADMA_ADDR_OFFSET 0x058
+#define SD_XC_CTR_OFFSET 0x060
+#define SD_BOOT_CTR_OFFSET 0x070
+#define SD_BOOT_STA_OFFSET 0x074
+#define SD_VOL_SW_OFFSET 0x07C
+#define SD_DELAY_SEL_L 0x0D8
+#define SD_DELAY_SEL_H 0x0DC
+#define SD_LAT_CTRL_OFFSET 0x0F8
+#define SD_SIST_OFFSET 0x0FC /* Half word */
+#define SD_VER_OFFSET 0x0FE /* Half word */
+
+/* SD_BLK_SZ_REG */
+#define SD_BLK_SZ_4KB 0x0000
+#define SD_BLK_SZ_8KB 0x1000
+#define SD_BLK_SZ_16KB 0x2000
+#define SD_BLK_SZ_32KB 0x3000
+#define SD_BLK_SZ_64KB 0x4000
+#define SD_BLK_SZ_128KB 0x5000
+#define SD_BLK_SZ_256KB 0x6000
+#define SD_BLK_SZ_512KB 0x7000
+
+/* SD_XFR_REG */
+#define SD_XFR_MUL_SEL 0x0020
+#define SD_XFR_SGL_SEL 0x0000
+#define SD_XFR_CTH_SEL 0x0010
+#define SD_XFR_HTC_SEL 0x0000
+#define SD_XFR_AC12_EN 0x0004
+#define SD_XFR_BLKCNT_EN 0x0002
+#define SD_XFR_DMA_EN 0x0001
+
+/* SD_CMD_REG */
+#define SD_CMD_IDX(x) ((x) << 8)
+#define SD_CMD_NORMAL 0x00000000
+#define SD_CMD_SUSPEND 0x00000040
+#define SD_CMD_RESUME 0x00000080
+#define SD_CMD_ABORT 0x000000C0
+#define SD_CMD_DATA 0x00000020
+#define SD_CMD_CHKIDX 0x00000010
+#define SD_CMD_CHKCRC 0x00000008
+#define SD_CMD_RSP_NONE 0x00000000
+#define SD_CMD_RSP_136 0x00000001
+#define SD_CMD_RSP_48 0x00000002
+#define SD_CMD_RSP_48BUSY 0x00000003
+
+/* SD_STA_REG */
+#define SD_STA_DAT_LSL(x) ((((x) & 0x1e000000) >> 25) | \
+ (((x) & 0x00f00000) >> 20))
+#define SD_STA_CMD_LSL(x) (((x) & 0x01000000) >> 24)
+#define SD_STA_WPS_PL 0x00080000
+#define SD_STA_CDP_L 0x00040000
+#define SD_STA_CSS 0x00020000
+#define SD_STA_CARD_INSERTED 0x00010000
+#define SD_STA_BUFFER_READ_EN 0x00000800
+#define SD_STA_BUFFER_WRITE_EN 0x00000400
+#define SD_STA_READ_XFR_ACTIVE 0x00000200
+#define SD_STA_WRITE_XFR_ACTIVE 0x00000100
+#define SD_STA_DAT_ACTIVE 0x00000004
+#define SD_STA_CMD_INHIBIT_DAT 0x00000002
+#define SD_STA_CMD_INHIBIT_CMD 0x00000001
+
+/* SD_HOST_REG */
+#define SD_HOST_ADMA 0x10
+#define SD_HOST_8BIT 0x08
+#define SD_HOST_HIGH_SPEED 0x04
+#define SD_HOST_4BIT 0x02
+#define SD_HOST_LED_ON 0x01
+
+/* SD_PWR_REG */
+#if (CHIP_REV == A5S)
+#define SD_PWR_3_3V 0x0e
+#define SD_PWR_3_0V 0x0c
+#define SD_PWR_1_8V 0x0a
+#else
+/* SD_PWR_REG only care about bit[3] */
+#define SD_PWR_3_3V 0x08
+#define SD_PWR_3_0V 0x08
+#define SD_PWR_1_8V 0x00
+#endif
+
+#define SD_PWR_ON 0x01
+#define SD_PWR_OFF 0x00
+
+/* SD_GAP_REG */
+#define SD_GAP_INT_AT_GAP 0x08
+#define SD_GAP_READ_WAIT 0x04
+#define SD_GAP_CONT_REQ 0x02
+#define SD_GAP_STOP_AT_GAP 0x01
+
+/* SD_WAK_REG */
+#define SD_WAK_ON_CARD_RMV 0x04
+#define SD_WAK_ON_CARD_IST 0x02
+#define SD_WAK_ON_CARD_INT 0x01
+
+/* SD_CLK_REG */
+#define SD_CLK_DIV_256 0x8000
+#define SD_CLK_DIV_128 0x4000
+#define SD_CLK_DIV_64 0x2000
+#define SD_CLK_DIV_32 0x1000
+#define SD_CLK_DIV_16 0x0800
+#define SD_CLK_DIV_8 0x0400
+#define SD_CLK_DIV_4 0x0200
+#define SD_CLK_DIV_2 0x0100
+#define SD_CLK_DIV_1 0x0000
+#define SD_CLK_EN 0x0004
+#define SD_CLK_ICLK_STABLE 0x0002
+#define SD_CLK_ICLK_EN 0x0001
+
+/* SD_TMO_REG */
+
+/* SD_RESET_REG */
+#define SD_RESET_DAT 0x04
+#define SD_RESET_CMD 0x02
+#define SD_RESET_ALL 0x01
+
+/* SD_NIS_REG */
+#define SD_NIS_ERROR 0x8000
+#define SD_NIS_CARD 0x0100
+#define SD_NIS_REMOVAL 0x0080
+#define SD_NIS_INSERT 0x0040
+#define SD_NIS_READ_READY 0x0020
+#define SD_NIS_WRITE_READY 0x0010
+#define SD_NIS_DMA 0x0008
+#define SD_NIS_BLOCK_GAP 0x0004
+#define SD_NIS_XFR_DONE 0x0002
+#define SD_NIS_CMD_DONE 0x0001
+
+/* SD_EIS_REG */
+#define SD_EIS_ADMA_ERR 0x0200
+#define SD_EIS_ACMD12_ERR 0x0100
+#define SD_EIS_CURRENT_ERR 0x0080
+#define SD_EIS_DATA_BIT_ERR 0x0040
+#define SD_EIS_DATA_CRC_ERR 0x0020
+#define SD_EIS_DATA_TMOUT_ERR 0x0010
+#define SD_EIS_CMD_IDX_ERR 0x0008
+#define SD_EIS_CMD_BIT_ERR 0x0004
+#define SD_EIS_CMD_CRC_ERR 0x0002
+#define SD_EIS_CMD_TMOUT_ERR 0x0001
+
+/* SD_NISEN_REG */
+#define SD_NISEN_CARD 0x0100
+#define SD_NISEN_REMOVAL 0x0080
+#define SD_NISEN_INSERT 0x0040
+#define SD_NISEN_READ_READY 0x0020
+#define SD_NISEN_WRITE_READY 0x0010
+#define SD_NISEN_DMA 0x0008
+#define SD_NISEN_BLOCK_GAP 0x0004
+#define SD_NISEN_XFR_DONE 0x0002
+#define SD_NISEN_CMD_DONE 0x0001
+
+/* SD_EISEN_REG */
+#define SD_EISEN_ADMA_ERR 0x0200
+#define SD_EISEN_ACMD12_ERR 0x0100
+#define SD_EISEN_CURRENT_ERR 0x0080
+#define SD_EISEN_DATA_BIT_ERR 0x0040
+#define SD_EISEN_DATA_CRC_ERR 0x0020
+#define SD_EISEN_DATA_TMOUT_ERR 0x0010
+#define SD_EISEN_CMD_IDX_ERR 0x0008
+#define SD_EISEN_CMD_BIT_ERR 0x0004
+#define SD_EISEN_CMD_CRC_ERR 0x0002
+#define SD_EISEN_CMD_TMOUT_ERR 0x0001
+
+/* SD_NIXEN_REG */
+#define SD_NIXEN_CARD 0x0100
+#define SD_NIXEN_REMOVAL 0x0080
+#define SD_NIXEN_INSERT 0x0040
+#define SD_NIXEN_READ_READY 0x0020
+#define SD_NIXEN_WRITE_READY 0x0010
+#define SD_NIXEN_DMA 0x0008
+#define SD_NIXEN_BLOCK_GAP 0x0004
+#define SD_NIXEN_XFR_DONE 0x0002
+#define SD_NIXEN_CMD_DONE 0x0001
+
+/* SD_EIXEN_REG */
+#define SD_EIXEN_ADMA_ERR 0x0200
+#define SD_EIXEN_ACMD12_ERR 0x0100
+#define SD_EIXEN_CURRENT_ERR 0x0080
+#define SD_EIXEN_DATA_BIT_ERR 0x0040
+#define SD_EIXEN_DATA_CRC_ERR 0x0020
+#define SD_EIXEN_DATA_TMOUT_ERR 0x0010
+#define SD_EIXEN_CMD_IDX_ERR 0x0008
+#define SD_EIXEN_CMD_BIT_ERR 0x0004
+#define SD_EIXEN_CMD_CRC_ERR 0x0002
+#define SD_EIXEN_CMD_TMOUT_ERR 0x0001
+
+/* SD_AC12ES_REG */
+#if (CHIP_REV == A5S)
+#define SD_AC12ES_NOT_ISSUED 0x0040
+#define SD_AC12ES_INDEX 0x0020
+#define SD_AC12ES_END_BIT 0x0010
+#else
+#define SD_AC12ES_NOT_ISSUED 0x0080
+#define SD_AC12ES_INDEX 0x0010
+#define SD_AC12ES_END_BIT 0x0008
+#endif
+#define SD_AC12ES_CRC_ERROR 0x0004
+#define SD_AC12ES_TMOUT_ERROR 0x0002
+#define SD_AC12ES_NOT_EXECED 0x0001
+
+/* SD_ADMA_STA_REG */
+#define SD_ADMA_STA_ST_STOP 0x00000000
+#define SD_ADMA_STA_ST_FDS 0x00000001
+#define SD_ADMA_STA_ST_TFR 0x00000003
+#define SD_ADMA_STA_LEN_ERR 0x00000004
+
+/* SD_CAP_REG */
+#define SD_CAP_INTMODE 0x08000000
+#define SD_CAP_VOL_1_8V 0x04000000
+#define SD_CAP_VOL_3_0V 0x02000000
+#define SD_CAP_VOL_3_3V 0x01000000
+#define SD_CAP_SUS_RES 0x00800000
+#define SD_CAP_DMA 0x00400000
+#define SD_CAP_HIGH_SPEED 0x00200000
+#define SD_CAP_ADMA_SUPPORT 0x00080000
+#define SD_CAP_MAX_512B_BLK 0x00000000
+#define SD_CAP_MAX_1KB_BLK 0x00010000
+#define SD_CAP_MAX_2KB_BLK 0x00020000
+#define SD_CAP_BASE_FREQ(x) (((x) & 0x3f00) >> 8)
+#define SD_CAP_TOCLK_KHZ 0x00000000
+#define SD_CAP_TOCLK_MHZ 0x00000080
+#define SD_CAP_TOCLK_FREQ(x) (((x) & 0x3f))
+
+/* SD_XC_CTR_REG */
+#define SD_XC_CTR_DDR_EN 0x00008000
+#define SD_XC_CTR_VOL_1_8V 0x00000001
+#define SD_XC_CTR_VOL_3_3V 0x00000000
+
+/* SD_BOOT_CTR_REG */
+#define SD_BOOT_CTR_RST_EN 0x00010000
+
+/* SD_BOOT_STA_REG */
+#define SD_BOOT_STA_END_ALT 0x01010000
+#define SD_BOOT_STA_BOOT_RDY 0x00000001
+
+/* SD_VOL_SW_REG */
+#define SD_VOL_SW_CMD_STAT_H 0x00010000
+#define SD_VOL_SW_DAT_STAT_H 0x00000007
+
+/* SD_VER_REG */
+#define SD_VER_VENDOR(x) ((x) >> 8)
+#define SD_VER_SPEC(x) ((x) & 0xf)
+
+#define SD_ADMA_TBL_LINE_SIZE (8)
+#define SD_ADMA_TBL_LINE_MAX_LEN (0x40000)
+#define SD_ADMA_TBL_ATTR_NOP (0x0000)
+#define SD_ADMA_TBL_ATTR_RSV (0x0010)
+#define SD_ADMA_TBL_ATTR_TRAN (0x0020)
+#define SD_ADMA_TBL_ATTR_LINK (0x0030)
+#define SD_ADMA_TBL_ATTR_WORD (0x0008)
+#define SD_ADMA_TBL_ATTR_INT (0x0004)
+#define SD_ADMA_TBL_ATTR_END (0x0002)
+#define SD_ADMA_TBL_ATTR_VALID (0x0001)
+
+/* ==========================================================================*/
+#define SMIO_2 GPIO(64)
+#define SMIO_3 GPIO(65)
+#define SMIO_4 GPIO(66)
+#define SMIO_5 GPIO(67)
+#define SD1_CD GPIO(67)
+#define SMIO_6 GPIO(68)
+#define SMIO_38 GPIO(69)
+#define SMIO_39 GPIO(70)
+#define SMIO_40 GPIO(71)
+#define SMIO_41 GPIO(72)
+#define SMIO_42 GPIO(73)
+#define SMIO_43 GPIO(74)
+#define SMIO_44 GPIO(75)
+#define SMIO_45 GPIO(76)
+
+/* ==========================================================================*/
+#if (CHIP_REV == A5S)
+#define AMBA_SD_MAX_SLOT_NUM (2)
+#else
+#define AMBA_SD_MAX_SLOT_NUM (1)
+#endif
+
+#if (CHIP_REV == S3L)
+#define sd_slot_is_valid(slot) ((slot) == 0 || (slot) == 2)
+#else
+#define sd_slot_is_valid(slot) ((slot) < SD_INSTANCES)
+#endif
+
+#if (CHIP_REV == A5S) || (CHIP_REV == A7L) || (CHIP_REV == S2)
+#define sd_addr_is_unlign(addr) ((addr) & 0x3)
+#else
+#define sd_addr_is_unlign(addr) 0
+#endif
+
+#endif
+
+extern void ambarella_detect_sd_slot(int slotid, int fixed_cd);
+
diff --git a/arch/arm/mach-ambarella/include/plat/spi.h b/arch/arm/mach-ambarella/include/plat/spi.h
new file mode 100644
index 00000000..e04a18fc
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/spi.h
@@ -0,0 +1,319 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/spi.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_SPI_H__
+#define __PLAT_AMBARELLA_SPI_H__
+
+#include <linux/spi/spi.h>
+
+/* ==========================================================================*/
+#if (CHIP_REV == A5S)
+#define SPI_INSTANCES 2
+#define SPI_AHB_INSTANCES 0
+#define SPI_SLAVE_INSTANCES 1
+#define SPI_AHB_SLAVE_INSTANCES 0
+#elif (CHIP_REV == S2)
+#ifdef CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64
+#define SPI_INSTANCES 2
+#else
+#define SPI_INSTANCES 1
+#endif
+#define SPI_AHB_INSTANCES 0
+#define SPI_SLAVE_INSTANCES 1
+#define SPI_AHB_SLAVE_INSTANCES 0
+#elif (CHIP_REV == S2E)
+#define SPI_INSTANCES 1
+#define SPI_AHB_INSTANCES 1
+#define SPI_SLAVE_INSTANCES 1
+#define SPI_AHB_SLAVE_INSTANCES 0
+#elif (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+#define SPI_INSTANCES 0
+#define SPI_AHB_INSTANCES 2
+#define SPI_SLAVE_INSTANCES 0
+#define SPI_AHB_SLAVE_INSTANCES 1
+#elif (CHIP_REV == A7L)
+#define SPI_INSTANCES 1
+#define SPI_AHB_INSTANCES 0
+#define SPI_SLAVE_INSTANCES 1
+#define SPI_AHB_SLAVE_INSTANCES 0
+#else
+#define SPI_INSTANCES 1
+#define SPI_AHB_INSTANCES 0
+#define SPI_SLAVE_INSTANCES 0
+#define SPI_AHB_SLAVE_INSTANCES 0
+#endif
+
+#if (CHIP_REV == A5S)
+#define SPI_SUPPORT_MASTER_CHANGE_ENA_POLARITY 0
+#define SPI_SUPPORT_MASTER_DELAY_START_TIME 0
+#define SPI_SUPPORT_NSM_SHAKE_START_BIT_CHSANGE 0
+#else
+#define SPI_SUPPORT_MASTER_CHANGE_ENA_POLARITY 1
+#define SPI_SUPPORT_MASTER_DELAY_START_TIME 1 // S2L only support ssi0, remember to fix it
+#define SPI_SUPPORT_NSM_SHAKE_START_BIT_CHSANGE 1 // S2 and S2L is not explain this in PRM
+#endif
+
+#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+#define SPI_TARGET_FRAME 1
+#else
+#define SPI_TARGET_FRAME 0
+#endif
+
+/* ==========================================================================*/
+#if (SPI_INSTANCES >= 1)
+#define SPI_OFFSET 0x2000
+#define SPI_BASE (APB_BASE + SPI_OFFSET)
+#define SPI_REG(x) (SPI_BASE + (x))
+#endif
+
+#if (SPI_SLAVE_INSTANCES >= 1)
+#if (CHIP_REV == A7L)
+#define SPI_SLAVE_OFFSET 0x1000
+#else
+#define SPI_SLAVE_OFFSET 0x1E000
+#endif
+#define SPI_SLAVE_BASE (APB_BASE + SPI_SLAVE_OFFSET)
+#define SPI_SLAVE_REG(x) (SPI_SLAVE_BASE + (x))
+#endif
+
+#if (SPI_INSTANCES >= 2)
+#define SPI2_OFFSET 0xF000
+#define SPI2_BASE (APB_BASE + SPI2_OFFSET)
+#define SPI2_REG(x) (SPI2_BASE + (x))
+#endif
+
+#if (SPI_INSTANCES >= 3)
+#define SPI3_OFFSET 0x15000
+#define SPI3_BASE (APB_BASE + SPI3_OFFSET)
+#define SPI3_REG(x) (SPI3_BASE + (x))
+#endif
+
+#if (SPI_INSTANCES >= 4)
+#define SPI4_OFFSET 0x16000
+#define SPI4_BASE (APB_BASE + SPI4_OFFSET)
+#define SPI4_REG(x) (SPI4_BASE + (x))
+#endif
+
+#if (SPI_AHB_INSTANCES == 1)
+#define SSI_DMA_OFFSET 0xD000
+#define SSI_DMA_BASE (AHB_BASE + SSI_DMA_OFFSET)
+#define SSI_DMA_REG(x) (SSI_DMA_BASE + (x))
+
+#if (SPI_INSTANCES == 1)
+#define SPI2_OFFSET 0x1F000
+#define SPI2_BASE (AHB_BASE + SPI2_OFFSET)
+#define SPI2_REG(x) (SPI2_BASE + (x))
+#endif
+#endif
+
+#if (SPI_AHB_INSTANCES == 2)
+#define SPI_OFFSET 0x20000
+#define SPI_BASE (AHB_BASE + SPI_OFFSET)
+#define SPI_REG(x) (SPI_BASE + (x))
+
+#define SPI2_OFFSET 0x21000
+#define SPI2_BASE (AHB_BASE + SPI2_OFFSET)
+#define SPI2_REG(x) (SPI2_BASE + (x))
+#endif
+
+#if (SPI_AHB_SLAVE_INSTANCES >= 1)
+#define SPI_AHB_SLAVE_OFFSET 0x26000
+#define SPI_AHB_SLAVE_BASE (AHB_BASE + SPI_AHB_SLAVE_OFFSET)
+#define SPI_AHB_SLAVE_REG(x) (SPI_AHB_SLAVE_BASE + (x))
+#endif
+
+#define SPI_MASTER_INSTANCES (SPI_INSTANCES + SPI_AHB_INSTANCES)
+
+
+/* ==========================================================================*/
+/* SPI_FIFO_SIZE */
+#define SPI_DATA_FIFO_SIZE_16 0x10
+#define SPI_DATA_FIFO_SIZE_32 0x20
+#define SPI_DATA_FIFO_SIZE_64 0x40
+#define SPI_DATA_FIFO_SIZE_128 0x80
+
+/****************************************************/
+/* Controller registers definitions */
+/****************************************************/
+
+#define SPI_CTRLR0_OFFSET 0x00
+#define SPI_CTRLR1_OFFSET 0x04
+#define SPI_SSIENR_OFFSET 0x08
+#define SPI_MWCR_OFFSET 0x0c // no PRM explain it and no code use it. should be commented after check
+#define SPI_SER_OFFSET 0x10
+#define SPI_BAUDR_OFFSET 0x14
+#define SPI_TXFTLR_OFFSET 0x18
+#define SPI_RXFTLR_OFFSET 0x1c
+#define SPI_TXFLR_OFFSET 0x20
+#define SPI_RXFLR_OFFSET 0x24
+#define SPI_SR_OFFSET 0x28
+#define SPI_IMR_OFFSET 0x2c
+#define SPI_ISR_OFFSET 0x30
+#define SPI_RISR_OFFSET 0x34
+#define SPI_TXOICR_OFFSET 0x38
+#define SPI_RXOICR_OFFSET 0x3c
+#define SPI_RXUICR_OFFSET 0x40
+#define SPI_MSTICR_OFFSET 0x44
+#define SPI_ICR_OFFSET 0x48
+#define SPI_DMAC_OFFSET 0x4c
+#define SPI_IDR_OFFSET 0x58
+#define SPI_VERSION_ID_OFFSET 0x5c
+#define SPI_DR_OFFSET 0x60
+
+#if (SPI_SUPPORT_MASTER_CHANGE_ENA_POLARITY == 1)
+#define SPI_SSIENPOLR_OFFSET 0x260
+#endif
+#if (SPI_SUPPORT_MASTER_DELAY_START_TIME == 1)
+#define SPI_SCLK_OUT_DLY_OFFSET 0x264
+#endif
+#if (SPI_SUPPORT_NSM_SHAKE_START_BIT_CHSANGE == 1)
+#define SPI_START_BIT_OFFSET 0x268
+#endif
+
+#if (SPI_TARGET_FRAME == 1)
+#define SPI_TARGET_FRAME_COUNT 0x27c
+#define SPI_FRAME_COUNT 0x280
+#define SPI_FCRICR 0x284
+#define SPI_TX_FRAME_COUNT 0x288
+#endif
+/* ==========================================================================*/
+/* SPI rw mode */
+#define SPI_WRITE_READ 0
+#define SPI_WRITE_ONLY 1
+#define SPI_READ_ONLY 2
+
+/* Tx FIFO empty interrupt mask */
+#define SPI_TXEIS_MASK 0x00000001
+#define SPI_TXOIS_MASK 0x00000002
+#define SPI_RXFIS_MASK 0x00000010
+#define SPI_FCRIS_MASK 0x00000100
+
+/* SPI Parameters */
+#define SPI_DUMMY_DATA 0xffff
+#define MAX_QUERY_TIMES 10
+
+/* Default SPI settings */
+#define SPI_MODE SPI_MODE_0
+#define SPI_SCPOL 0
+#define SPI_SCPH 0
+#define SPI_FRF 0
+#define SPI_CFS 0x0
+#define SPI_DFS 0xf
+#define SPI_BAUD_RATE 200000
+
+/* ==========================================================================*/
+typedef union {
+ struct {
+ u32 dfs : 4; /* [3:0] */
+ u32 frf : 2; /* [5:4] */
+ u32 scph : 1; /* [6] */
+ u32 scpol : 1; /* [7] */
+ u32 tmod : 2; /* [9:8] */
+ u32 slv_oe : 1; /* [10] */
+ u32 srl : 1; /* [11] */
+ u32 reserv1 : 5; /* [16:12] */
+ u32 residue : 1; /* [17] */
+ u32 tx_lsb : 1; /* [18] */
+ u32 rx_lsb : 1; /* [19] */
+ u32 reserv2 : 1; /* [20] */
+ u32 fc_en : 1; /* [21] */
+ u32 rxd_mg : 4; /* [25:22] */
+ u32 byte_ws : 1; /* [26] */
+ u32 hold : 1; /* [27] */
+ u32 reserv3 : 4; /* [31:28] */
+ } s;
+ u32 w;
+} spi_ctrl0_reg_t;
+
+typedef union {
+ struct {
+ u32 busy : 1; /* [0] */
+ u32 tfnf : 1; /* [1] */
+ u32 tfe : 1; /* [2] */
+ u32 rfne : 1; /* [3] */
+ u32 rff : 1; /* [4] */
+ u32 txe : 1; /* [5] */
+ u32 dcol : 1; /* [6] */
+ u32 reserve : 25; /* [31:7] */
+ } s;
+ u32 w;
+} spi_status_reg_t;
+
+/* ==========================================================================*/
+
+#ifndef __ASSEMBLER__
+
+struct ambarella_spi_cfg_info {
+ u8 spi_mode;
+ u8 cfs_dfs;
+ u8 cs_change;
+ u32 baud_rate;
+};
+typedef struct ambarella_spi_cfg_info amba_spi_cfg_t;
+
+typedef struct {
+ u8 bus_id;
+ u8 cs_id;
+ u8 *buffer;
+ u32 n_size; // u16 n_size;
+} amba_spi_write_t;
+
+typedef struct {
+ u8 bus_id;
+ u8 cs_id;
+ u8 *buffer;
+ u16 n_size;
+} amba_spi_read_t;
+
+typedef struct {
+ u8 bus_id;
+ u8 cs_id;
+ u8 *w_buffer;
+ u8 *r_buffer;
+ u16 w_size;
+ u16 r_size;
+} amba_spi_write_then_read_t;
+
+typedef struct {
+ u8 bus_id;
+ u8 cs_id;
+ u8 *w_buffer;
+ u8 *r_buffer;
+ u16 n_size;
+} amba_spi_write_and_read_t;
+
+/* ==========================================================================*/
+extern int ambarella_spi_write(amba_spi_cfg_t *spi_cfg,
+ amba_spi_write_t *spi_write);
+extern int ambarella_spi_read(amba_spi_cfg_t *spi_cfg,
+ amba_spi_read_t *spi_read);
+extern int ambarella_spi_write_then_read(amba_spi_cfg_t *spi_cfg,
+ amba_spi_write_then_read_t *spi_write_then_read);
+extern int ambarella_spi_write_and_read(amba_spi_cfg_t *spi_cfg,
+ amba_spi_write_and_read_t *spi_write_and_read);
+
+#endif /* __ASSEMBLER__ */
+/* ==========================================================================*/
+
+#endif /* __PLAT_AMBARELLA_SPI_H__ */
+
diff --git a/arch/arm/mach-ambarella/include/plat/timer.h b/arch/arm/mach-ambarella/include/plat/timer.h
new file mode 100644
index 00000000..8da17104
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/timer.h
@@ -0,0 +1,285 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/timer.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_TIMER_H__
+#define __PLAT_AMBARELLA_TIMER_H__
+
+/* ==========================================================================*/
+#define TIMER_OFFSET 0xB000
+#define TIMER_BASE (APB_BASE + TIMER_OFFSET)
+#define TIMER_REG(x) (TIMER_BASE + (x))
+
+#define TIMER1_OFFSET 0xF000
+#define TIMER1_BASE (APB_BASE + TIMER1_OFFSET)
+#define TIMER1_REG(x) (TIMER1_BASE + (x))
+
+/* ==========================================================================*/
+#if (CHIP_REV == A5S)
+#define INTERVAL_TIMER_INSTANCES 3
+#elif (CHIP_REV == S3)
+#define INTERVAL_TIMER_INSTANCES 20
+#else
+#define INTERVAL_TIMER_INSTANCES 8
+#endif
+
+/* ==========================================================================*/
+#define TIMER1_STATUS_OFFSET 0x00
+#define TIMER1_RELOAD_OFFSET 0x04
+#define TIMER1_MATCH1_OFFSET 0x08
+#define TIMER1_MATCH2_OFFSET 0x0c
+#define TIMER2_STATUS_OFFSET 0x10
+#define TIMER2_RELOAD_OFFSET 0x14
+#define TIMER2_MATCH1_OFFSET 0x18
+#define TIMER2_MATCH2_OFFSET 0x1c
+#define TIMER3_STATUS_OFFSET 0x20
+#define TIMER3_RELOAD_OFFSET 0x24
+#define TIMER3_MATCH1_OFFSET 0x28
+#define TIMER3_MATCH2_OFFSET 0x2c
+
+#if (INTERVAL_TIMER_INSTANCES > 3)
+#define TIMER4_STATUS_OFFSET 0x34
+#define TIMER4_RELOAD_OFFSET 0x38
+#define TIMER4_MATCH1_OFFSET 0x3c
+#define TIMER4_MATCH2_OFFSET 0x40
+#define TIMER5_STATUS_OFFSET 0x44
+#define TIMER5_RELOAD_OFFSET 0x48
+#define TIMER5_MATCH1_OFFSET 0x4c
+#define TIMER5_MATCH2_OFFSET 0x50
+#define TIMER6_STATUS_OFFSET 0x54
+#define TIMER6_RELOAD_OFFSET 0x58
+#define TIMER6_MATCH1_OFFSET 0x5c
+#define TIMER6_MATCH2_OFFSET 0x60
+#define TIMER7_STATUS_OFFSET 0x64
+#define TIMER7_RELOAD_OFFSET 0x68
+#define TIMER7_MATCH1_OFFSET 0x6c
+#define TIMER7_MATCH2_OFFSET 0x70
+#define TIMER8_STATUS_OFFSET 0x74
+#define TIMER8_RELOAD_OFFSET 0x78
+#define TIMER8_MATCH1_OFFSET 0x7c
+#define TIMER8_MATCH2_OFFSET 0x80
+#endif
+
+#if (INTERVAL_TIMER_INSTANCES > 8)
+#define TIMER9_STATUS_OFFSET 0x88
+#define TIMER9_RELOAD_OFFSET 0x8c
+#define TIMER9_MATCH1_OFFSET 0x90
+#define TIMER9_MATCH2_OFFSET 0x94
+#define TIMER10_STATUS_OFFSET 0x98
+#define TIMER10_RELOAD_OFFSET 0x9c
+#define TIMER10_MATCH1_OFFSET 0xa0
+#define TIMER10_MATCH2_OFFSET 0xa4
+
+/* belong to the 2nd timer instance */
+#define TIMER11_STATUS_OFFSET 0x00
+#define TIMER11_RELOAD_OFFSET 0x04
+#define TIMER11_MATCH1_OFFSET 0x08
+#define TIMER11_MATCH2_OFFSET 0x0c
+#define TIMER12_STATUS_OFFSET 0x10
+#define TIMER12_RELOAD_OFFSET 0x14
+#define TIMER12_MATCH1_OFFSET 0x18
+#define TIMER12_MATCH2_OFFSET 0x1c
+#define TIMER13_STATUS_OFFSET 0x20
+#define TIMER13_RELOAD_OFFSET 0x24
+#define TIMER13_MATCH1_OFFSET 0x28
+#define TIMER13_MATCH2_OFFSET 0x2c
+#define TIMER14_STATUS_OFFSET 0x34
+#define TIMER14_RELOAD_OFFSET 0x38
+#define TIMER14_MATCH1_OFFSET 0x3c
+#define TIMER14_MATCH2_OFFSET 0x40
+#define TIMER15_STATUS_OFFSET 0x44
+#define TIMER15_RELOAD_OFFSET 0x48
+#define TIMER15_MATCH1_OFFSET 0x4c
+#define TIMER15_MATCH2_OFFSET 0x50
+#define TIMER16_STATUS_OFFSET 0x54
+#define TIMER16_RELOAD_OFFSET 0x58
+#define TIMER16_MATCH1_OFFSET 0x5c
+#define TIMER16_MATCH2_OFFSET 0x60
+#define TIMER17_STATUS_OFFSET 0x64
+#define TIMER17_RELOAD_OFFSET 0x68
+#define TIMER17_MATCH1_OFFSET 0x6c
+#define TIMER17_MATCH2_OFFSET 0x70
+#define TIMER18_STATUS_OFFSET 0x74
+#define TIMER18_RELOAD_OFFSET 0x78
+#define TIMER18_MATCH1_OFFSET 0x7c
+#define TIMER18_MATCH2_OFFSET 0x80
+#define TIMER19_STATUS_OFFSET 0x88
+#define TIMER19_RELOAD_OFFSET 0x8c
+#define TIMER19_MATCH1_OFFSET 0x90
+#define TIMER19_MATCH2_OFFSET 0x94
+#define TIMER20_STATUS_OFFSET 0x98
+#define TIMER20_RELOAD_OFFSET 0x9c
+#define TIMER20_MATCH1_OFFSET 0xa0
+#define TIMER20_MATCH2_OFFSET 0xa4
+#endif
+
+#define TIMER_CTR_OFFSET 0x30
+#define TIMER_CTR1_OFFSET 0x84
+
+#define TIMER1_STATUS_REG TIMER_REG(TIMER1_STATUS_OFFSET)
+#define TIMER1_RELOAD_REG TIMER_REG(TIMER1_RELOAD_OFFSET)
+#define TIMER1_MATCH1_REG TIMER_REG(TIMER1_MATCH1_OFFSET)
+#define TIMER1_MATCH2_REG TIMER_REG(TIMER1_MATCH2_OFFSET)
+#define TIMER2_STATUS_REG TIMER_REG(TIMER2_STATUS_OFFSET)
+#define TIMER2_RELOAD_REG TIMER_REG(TIMER2_RELOAD_OFFSET)
+#define TIMER2_MATCH1_REG TIMER_REG(TIMER2_MATCH1_OFFSET)
+#define TIMER2_MATCH2_REG TIMER_REG(TIMER2_MATCH2_OFFSET)
+#define TIMER3_STATUS_REG TIMER_REG(TIMER3_STATUS_OFFSET)
+#define TIMER3_RELOAD_REG TIMER_REG(TIMER3_RELOAD_OFFSET)
+#define TIMER3_MATCH1_REG TIMER_REG(TIMER3_MATCH1_OFFSET)
+#define TIMER3_MATCH2_REG TIMER_REG(TIMER3_MATCH2_OFFSET)
+#if (INTERVAL_TIMER_INSTANCES > 3)
+#define TIMER4_STATUS_REG TIMER_REG(TIMER4_STATUS_OFFSET)
+#define TIMER4_RELOAD_REG TIMER_REG(TIMER4_RELOAD_OFFSET)
+#define TIMER4_MATCH1_REG TIMER_REG(TIMER4_MATCH1_OFFSET)
+#define TIMER4_MATCH2_REG TIMER_REG(TIMER4_MATCH2_OFFSET)
+#define TIMER5_STATUS_REG TIMER_REG(TIMER5_STATUS_OFFSET)
+#define TIMER5_RELOAD_REG TIMER_REG(TIMER5_RELOAD_OFFSET)
+#define TIMER5_MATCH1_REG TIMER_REG(TIMER5_MATCH1_OFFSET)
+#define TIMER5_MATCH2_REG TIMER_REG(TIMER5_MATCH2_OFFSET)
+#define TIMER6_STATUS_REG TIMER_REG(TIMER6_STATUS_OFFSET)
+#define TIMER6_RELOAD_REG TIMER_REG(TIMER6_RELOAD_OFFSET)
+#define TIMER6_MATCH1_REG TIMER_REG(TIMER6_MATCH1_OFFSET)
+#define TIMER6_MATCH2_REG TIMER_REG(TIMER6_MATCH2_OFFSET)
+#define TIMER7_STATUS_REG TIMER_REG(TIMER7_STATUS_OFFSET)
+#define TIMER7_RELOAD_REG TIMER_REG(TIMER7_RELOAD_OFFSET)
+#define TIMER7_MATCH1_REG TIMER_REG(TIMER7_MATCH1_OFFSET)
+#define TIMER7_MATCH2_REG TIMER_REG(TIMER7_MATCH2_OFFSET)
+#define TIMER8_STATUS_REG TIMER_REG(TIMER8_STATUS_OFFSET)
+#define TIMER8_RELOAD_REG TIMER_REG(TIMER8_RELOAD_OFFSET)
+#define TIMER8_MATCH1_REG TIMER_REG(TIMER8_MATCH1_OFFSET)
+#define TIMER8_MATCH2_REG TIMER_REG(TIMER8_MATCH2_OFFSET)
+#endif
+#if (INTERVAL_TIMER_INSTANCES > 8)
+#define TIMER9_STATUS_REG TIMER_REG(TIMER9_STATUS_OFFSET)
+#define TIMER9_RELOAD_REG TIMER_REG(TIMER9_RELOAD_OFFSET)
+#define TIMER9_MATCH1_REG TIMER_REG(TIMER9_MATCH1_OFFSET)
+#define TIMER9_MATCH2_REG TIMER_REG(TIMER9_MATCH2_OFFSET)
+#define TIMER10_STATUS_REG TIMER_REG(TIMER10_STATUS_OFFSET)
+#define TIMER10_RELOAD_REG TIMER_REG(TIMER10_RELOAD_OFFSET)
+#define TIMER10_MATCH1_REG TIMER_REG(TIMER10_MATCH1_OFFSET)
+#define TIMER10_MATCH2_REG TIMER_REG(TIMER10_MATCH2_OFFSET)
+
+/* belong to the 2nd timer instance */
+#define TIMER11_STATUS_REG TIMER1_REG(TIMER11_STATUS_OFFSET)
+#define TIMER11_RELOAD_REG TIMER1_REG(TIMER11_RELOAD_OFFSET)
+#define TIMER11_MATCH1_REG TIMER1_REG(TIMER11_MATCH1_OFFSET)
+#define TIMER11_MATCH2_REG TIMER1_REG(TIMER11_MATCH2_OFFSET)
+#define TIMER12_STATUS_REG TIMER1_REG(TIMER12_STATUS_OFFSET)
+#define TIMER12_RELOAD_REG TIMER1_REG(TIMER12_RELOAD_OFFSET)
+#define TIMER12_MATCH1_REG TIMER1_REG(TIMER12_MATCH1_OFFSET)
+#define TIMER12_MATCH2_REG TIMER1_REG(TIMER12_MATCH2_OFFSET)
+#define TIMER13_STATUS_REG TIMER1_REG(TIMER13_STATUS_OFFSET)
+#define TIMER13_RELOAD_REG TIMER1_REG(TIMER13_RELOAD_OFFSET)
+#define TIMER13_MATCH1_REG TIMER1_REG(TIMER13_MATCH1_OFFSET)
+#define TIMER13_MATCH2_REG TIMER1_REG(TIMER13_MATCH2_OFFSET)
+#define TIMER14_STATUS_REG TIMER1_REG(TIMER14_STATUS_OFFSET)
+#define TIMER14_RELOAD_REG TIMER1_REG(TIMER14_RELOAD_OFFSET)
+#define TIMER14_MATCH1_REG TIMER1_REG(TIMER14_MATCH1_OFFSET)
+#define TIMER14_MATCH2_REG TIMER1_REG(TIMER14_MATCH2_OFFSET)
+#define TIMER15_STATUS_REG TIMER1_REG(TIMER15_STATUS_OFFSET)
+#define TIMER15_RELOAD_REG TIMER1_REG(TIMER15_RELOAD_OFFSET)
+#define TIMER15_MATCH1_REG TIMER1_REG(TIMER15_MATCH1_OFFSET)
+#define TIMER15_MATCH2_REG TIMER1_REG(TIMER15_MATCH2_OFFSET)
+#define TIMER16_STATUS_REG TIMER1_REG(TIMER16_STATUS_OFFSET)
+#define TIMER16_RELOAD_REG TIMER1_REG(TIMER16_RELOAD_OFFSET)
+#define TIMER16_MATCH1_REG TIMER1_REG(TIMER16_MATCH1_OFFSET)
+#define TIMER16_MATCH2_REG TIMER1_REG(TIMER16_MATCH2_OFFSET)
+#define TIMER17_STATUS_REG TIMER1_REG(TIMER17_STATUS_OFFSET)
+#define TIMER17_RELOAD_REG TIMER1_REG(TIMER17_RELOAD_OFFSET)
+#define TIMER17_MATCH1_REG TIMER1_REG(TIMER17_MATCH1_OFFSET)
+#define TIMER17_MATCH2_REG TIMER1_REG(TIMER17_MATCH2_OFFSET)
+#define TIMER18_STATUS_REG TIMER1_REG(TIMER18_STATUS_OFFSET)
+#define TIMER18_RELOAD_REG TIMER1_REG(TIMER18_RELOAD_OFFSET)
+#define TIMER18_MATCH1_REG TIMER1_REG(TIMER18_MATCH1_OFFSET)
+#define TIMER18_MATCH2_REG TIMER1_REG(TIMER18_MATCH2_OFFSET)
+#define TIMER19_STATUS_REG TIMER1_REG(TIMER19_STATUS_OFFSET)
+#define TIMER19_RELOAD_REG TIMER1_REG(TIMER19_RELOAD_OFFSET)
+#define TIMER19_MATCH1_REG TIMER1_REG(TIMER19_MATCH1_OFFSET)
+#define TIMER19_MATCH2_REG TIMER1_REG(TIMER19_MATCH2_OFFSET)
+#define TIMER20_STATUS_REG TIMER1_REG(TIMER20_STATUS_OFFSET)
+#define TIMER20_RELOAD_REG TIMER1_REG(TIMER20_RELOAD_OFFSET)
+#define TIMER20_MATCH1_REG TIMER1_REG(TIMER20_MATCH1_OFFSET)
+#define TIMER20_MATCH2_REG TIMER1_REG(TIMER20_MATCH2_OFFSET)
+#endif
+
+#define TIMER_CTR_REG TIMER_REG(TIMER_CTR_OFFSET)
+#define TIMER_CTR1_REG TIMER_REG(TIMER_CTR1_OFFSET)
+#define TIMER1_CTR_REG TIMER1_REG(TIMER_CTR_OFFSET)
+#define TIMER1_CTR1_REG TIMER1_REG(TIMER_CTR1_OFFSET)
+
+#define TIMER_CTR_EN1 0x00000001
+#define TIMER_CTR_CSL1 0x00000002
+#define TIMER_CTR_OF1 0x00000004
+#define TIMER_CTR_EN2 0x00000010
+#define TIMER_CTR_CSL2 0x00000020
+#define TIMER_CTR_OF2 0x00000040
+#define TIMER_CTR_EN3 0x00000100
+#define TIMER_CTR_CSL3 0x00000200
+#define TIMER_CTR_OF3 0x00000400
+#if (INTERVAL_TIMER_INSTANCES > 3)
+#define TIMER_CTR_EN4 0x00001000
+#define TIMER_CTR_CSL4 0x00002000
+#define TIMER_CTR_OF4 0x00004000
+#define TIMER_CTR_EN5 0x00010000
+#define TIMER_CTR_CSL5 0x00020000
+#define TIMER_CTR_OF5 0x00040000
+#define TIMER_CTR_EN6 0x00100000
+#define TIMER_CTR_CSL6 0x00200000
+#define TIMER_CTR_OF6 0x00400000
+#define TIMER_CTR_EN7 0x01000000
+#define TIMER_CTR_CSL7 0x02000000
+#define TIMER_CTR_OF7 0x04000000
+#define TIMER_CTR_EN8 0x10000000
+#define TIMER_CTR_CSL8 0x20000000
+#define TIMER_CTR_OF8 0x40000000
+#endif
+#if (INTERVAL_TIMER_INSTANCES > 8)
+#define TIMER_CTR_EN9 0x00000001
+#define TIMER_CTR_OF9 0x00000004
+#define TIMER_CTR_EN10 0x00000010
+#define TIMER_CTR_OF10 0x00000040
+#endif
+
+#define TIMER_STATUS_OFFSET 0x00
+#define TIMER_RELOAD_OFFSET 0x04
+#define TIMER_MATCH1_OFFSET 0x08
+#define TIMER_MATCH2_OFFSET 0x0c
+
+#define TIMER_CTRL_OF 0x4
+#define TIMER_CTRL_CSL 0x2
+#define TIMER_CTRL_EN 0x1
+
+/* ==========================================================================*/
+#ifndef __ASSEMBLER__
+
+/* ==========================================================================*/
+extern struct sys_timer ambarella_timer;
+
+/* ==========================================================================*/
+extern void ambarella_timer_init(void);
+
+#endif /* __ASSEMBLER__ */
+/* ==========================================================================*/
+
+#endif /* __PLAT_AMBARELLA_TIMER_H__ */
+
diff --git a/arch/arm/mach-ambarella/include/plat/uart.h b/arch/arm/mach-ambarella/include/plat/uart.h
new file mode 100644
index 00000000..7c497549
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/uart.h
@@ -0,0 +1,179 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/uart.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_UART_H__
+#define __PLAT_AMBARELLA_UART_H__
+
+/* ==========================================================================*/
+#if (CHIP_REV == A8) || (CHIP_REV == S2) || (CHIP_REV == S2E)
+#define UART_INSTANCES 4
+#else
+#define UART_INSTANCES 2
+#endif
+
+/* ==========================================================================*/
+#define UART_OFFSET 0x5000
+#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+#define UART1_OFFSET 0x32000
+#else
+#define UART1_OFFSET 0x1F000
+#endif
+#if (CHIP_REV == S2) || (CHIP_REV == S2E)
+#define UART2_OFFSET 0x14000
+#define UART3_OFFSET 0x15000
+#elif (CHIP_REV == A8)
+#define UART2_OFFSET 0x13000
+#define UART3_OFFSET 0x14000
+#endif
+
+#define UART0_BASE (APB_BASE + UART_OFFSET)
+#if (CHIP_REV == S2L) || (CHIP_REV == S3) || (CHIP_REV == S3L)
+#define UART1_BASE (AHB_BASE + UART1_OFFSET)
+#else
+#define UART1_BASE (APB_BASE + UART1_OFFSET)
+#endif
+#if (CHIP_REV == A8) || (CHIP_REV == S2) || (CHIP_REV == S2E)
+#define UART2_BASE (APB_BASE + UART2_OFFSET)
+#define UART3_BASE (APB_BASE + UART3_OFFSET)
+#endif
+
+#define UART0_REG(x) (UART0_BASE + (x))
+#define UART1_REG(x) (UART1_BASE + (x))
+#if (CHIP_REV == A8) || (CHIP_REV == S2) || (CHIP_REV == S2E)
+#define UART2_REG(x) (UART2_BASE + (x))
+#define UART3_REG(x) (UART3_BASE + (x))
+#endif
+/* ==========================================================================*/
+#define UART_RB_OFFSET 0x00
+#define UART_TH_OFFSET 0x00
+#define UART_DLL_OFFSET 0x00
+#define UART_IE_OFFSET 0x04
+#define UART_DLH_OFFSET 0x04
+#define UART_II_OFFSET 0x08
+#define UART_FC_OFFSET 0x08
+#define UART_LC_OFFSET 0x0c
+#define UART_MC_OFFSET 0x10
+#define UART_LS_OFFSET 0x14
+#define UART_MS_OFFSET 0x18
+#define UART_SC_OFFSET 0x1c /* Byte */
+#define UART_DMAE_OFFSET 0x28
+#define UART_DMAF_OFFSET 0x40 /* DMA fifo */
+#define UART_US_OFFSET 0x7c
+#define UART_TFL_OFFSET 0x80
+#define UART_RFL_OFFSET 0x84
+#define UART_SRR_OFFSET 0x88
+
+/* UART[x]_IE_REG */
+#define UART_IE_PTIME 0x80
+#define UART_IE_ETOI 0x20
+#define UART_IE_EBDI 0x10
+#define UART_IE_EDSSI 0x08
+#define UART_IE_ELSI 0x04
+#define UART_IE_ETBEI 0x02
+#define UART_IE_ERBFI 0x01
+
+/* UART[x]_II_REG */
+#define UART_II_MODEM_STATUS_CHANGED 0x00
+#define UART_II_NO_INT_PENDING 0x01
+#define UART_II_THR_EMPTY 0x02
+#define UART_II_RCV_DATA_AVAIL 0x04
+#define UART_II_RCV_STATUS 0x06
+#define UART_II_CHAR_TIMEOUT 0x0c
+
+/* UART[x]_FC_REG */
+#define UART_FC_RX_ONECHAR 0x00
+#define UART_FC_RX_QUARTER_FULL 0x40
+#define UART_FC_RX_HALF_FULL 0x80
+#define UART_FC_RX_2_TO_FULL 0xc0
+#define UART_FC_TX_EMPTY 0x00
+#define UART_FC_TX_2_IN_FIFO 0x10
+#define UART_FC_TX_QUATER_IN_FIFO 0x20
+#define UART_FC_TX_HALF_IN_FIFO 0x30
+#define UART_FC_XMITR 0x04
+#define UART_FC_RCVRR 0x02
+#define UART_FC_FIFOE 0x01
+
+/* UART[x]_LC_REG */
+#define UART_LC_DLAB 0x80
+#define UART_LC_BRK 0x40
+#define UART_LC_EVEN_PARITY 0x10
+#define UART_LC_ODD_PARITY 0x00
+#define UART_LC_PEN 0x08
+#define UART_LC_STOP_2BIT 0x04
+#define UART_LC_STOP_1BIT 0x00
+#define UART_LC_CLS_8_BITS 0x03
+#define UART_LC_CLS_7_BITS 0x02
+#define UART_LC_CLS_6_BITS 0x01
+#define UART_LC_CLS_5_BITS 0x00
+/* quick defs */
+#define UART_LC_8N1 0x03
+#define UART_LC_7E1 0x0a
+
+/* UART[x]_MC_REG */
+#define UART_MC_SIRE 0x40
+#define UART_MC_AFCE 0x20
+#define UART_MC_LB 0x10
+#define UART_MC_OUT2 0x08
+#define UART_MC_OUT1 0x04
+#define UART_MC_RTS 0x02
+#define UART_MC_DTR 0x01
+
+/* UART[x]_LS_REG */
+#define UART_LS_FERR 0x80
+#define UART_LS_TEMT 0x40
+#define UART_LS_THRE 0x20
+#define UART_LS_BI 0x10
+#define UART_LS_FE 0x08
+#define UART_LS_PE 0x04
+#define UART_LS_OE 0x02
+#define UART_LS_DR 0x01
+
+/* UART[x]_MS_REG */
+#define UART_MS_DCD 0x80
+#define UART_MS_RI 0x40
+#define UART_MS_DSR 0x20
+#define UART_MS_CTS 0x10
+#define UART_MS_DDCD 0x08
+#define UART_MS_TERI 0x04
+#define UART_MS_DDSR 0x02
+#define UART_MS_DCTS 0x01
+
+/* UART[x]_US_REG */
+#define UART_US_RFF 0x10
+#define UART_US_RFNE 0x08
+#define UART_US_TFE 0x04
+#define UART_US_TFNF 0x02
+#define UART_US_BUSY 0x01
+
+/* ==========================================================================*/
+#define UART_FIFO_SIZE (16)
+
+#define DEFAULT_AMBARELLA_UART_MCR (0)
+#if (CHIP_REV == A5S)
+#define DEFAULT_AMBARELLA_UART_IER (UART_IE_ELSI | UART_IE_ERBFI)
+#else
+#define DEFAULT_AMBARELLA_UART_IER (UART_IE_ELSI | UART_IE_ERBFI | UART_IE_ETOI)
+#endif
+
+#endif /* __PLAT_AMBARELLA_UART_H__ */
+
diff --git a/arch/arm/mach-ambarella/include/plat/udc.h b/arch/arm/mach-ambarella/include/plat/udc.h
new file mode 100644
index 00000000..b28e63ad
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/udc.h
@@ -0,0 +1,403 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/udc.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_UDC_H__
+#define __PLAT_AMBARELLA_UDC_H__
+
+/* ==========================================================================*/
+#define USBDC_OFFSET 0x6000
+#define USBDC_BASE (AHB_BASE + USBDC_OFFSET)
+#define USBDC_REG(x) (USBDC_BASE + (x))
+
+/* ==========================================================================*/
+
+/*----------------------------------------------
+ macros
+----------------------------------------------*/
+#define USB_READ_REG(adr) (*(volatile unsigned long *)(adr))
+#define USB_WRITE_REG(adr, val) (*(volatile unsigned long *)(adr)=(val))
+#define USB_SET_REG(adr, val) (USB_WRITE_REG((adr), (USB_READ_REG(adr) | (val))))
+#define USB_CLR_REG(adr, val) (USB_WRITE_REG((adr), (USB_READ_REG(adr) & ~(val))))
+
+//-------------------------------------
+// USB RxFIFO and TxFIFO depth (single or multiple)
+//-------------------------------------
+#define USB_RXFIFO_DEPTH_CTRLOUT (256 << 16) // shared
+#define USB_RXFIFO_DEPTH_BULKOUT (256 << 16) // shared
+#define USB_RXFIFO_DEPTH_INTROUT (256 << 16) // shared
+#define USB_TXFIFO_DEPTH_CTRLIN (64 / 4) // 16 32-bit
+#define USB_TXFIFO_DEPTH_BULKIN (1024 / 4) // 256 32-bit
+#define USB_TXFIFO_DEPTH_INTRIN (512 / 4) // 128 32-bit
+#define USB_TXFIFO_DEPTH_ISOIN ((512 * 2) / 4) // 128 32-bit
+
+#define USB_TXFIFO_DEPTH (64 / 4 + 4 * 512 / 4) // 528 32-bit
+#define USB_RXFIFO_DEPTH (256) // 256 32-bit
+
+//-------------------------------------
+// USB memory map
+//-------------------------------------
+#define USB_EP_IN_BASE USBDC_BASE // IN endpoint specific registers
+#define USB_EP_OUT_BASE (USBDC_BASE + 0x0200) // OUT endpoint specific registers
+#define USB_DEV_BASE (USBDC_BASE + 0x0400) // device specific registers
+#define USB_UDC_BASE (USBDC_BASE + 0x0504) // UDC specific registers, 0x0500 is reserved for control endpoint (RO)
+#define USB_RXFIFO_BASE (USBDC_BASE + 0x0800) // RxFIFO
+#define USB_TXFIFO_BASE (USB_RXFIFO_BASE + USB_RXFIFO_DEPTH) // TxFIFO
+
+//-------------------------------------
+// USB register address
+//-------------------------------------
+#define USB_EP_IN_CTRL_REG(n) (USB_EP_IN_BASE + 0x0000 + 0x0020 * (n))
+#define USB_EP_IN_STS_REG(n) (USB_EP_IN_BASE + 0x0004 + 0x0020 * (n))
+#define USB_EP_IN_BUF_SZ_REG(n) (USB_EP_IN_BASE + 0x0008 + 0x0020 * (n))
+#define USB_EP_IN_MAX_PKT_SZ_REG(n) (USB_EP_IN_BASE + 0x000c + 0x0020 * (n))
+#define USB_EP_IN_DAT_DESC_PTR_REG(n) (USB_EP_IN_BASE + 0x0014 + 0x0020 * (n))
+#define USB_EP_IN_WR_CFM_REG (USB_EP_IN_BASE + 0x001c + 0x0020 * (n)) // for slave-only mode
+
+#define USB_EP_OUT_CTRL_REG(n) (USB_EP_OUT_BASE + 0x0000 + 0x0020 * (n))
+#define USB_EP_OUT_STS_REG(n) (USB_EP_OUT_BASE + 0x0004 + 0x0020 * (n))
+#define USB_EP_OUT_PKT_FRM_NUM_REG(n) (USB_EP_OUT_BASE + 0x0008 + 0x0020 * (n))
+#define USB_EP_OUT_MAX_PKT_SZ_REG(n) (USB_EP_OUT_BASE + 0x000c + 0x0020 * (n))
+#define USB_EP_OUT_SETUP_BUF_PTR_REG(n) (USB_EP_OUT_BASE + 0x0010 + 0x0020 * (n))
+#define USB_EP_OUT_DAT_DESC_PTR_REG(n) (USB_EP_OUT_BASE + 0x0014 + 0x0020 * (n))
+#define USB_EP_OUT_RD_CFM_ZO_REG (USB_EP_OUT_BASE + 0x001c + 0x0020 * (n)) // for slave-only mode
+
+#define USB_DEV_CFG_REG (USB_DEV_BASE + 0x0000)
+#define USB_DEV_CTRL_REG (USB_DEV_BASE + 0x0004)
+#define USB_DEV_STS_REG (USB_DEV_BASE + 0x0008)
+#define USB_DEV_INTR_REG (USB_DEV_BASE + 0x000c)
+#define USB_DEV_INTR_MSK_REG (USB_DEV_BASE + 0x0010)
+#define USB_DEV_EP_INTR_REG (USB_DEV_BASE + 0x0014)
+#define USB_DEV_EP_INTR_MSK_REG (USB_DEV_BASE + 0x0018)
+#define USB_DEV_TEST_MODE_REG (USB_DEV_BASE + 0x001c)
+
+#define USB_UDC_REG(n) (USB_UDC_BASE + 0x0004 * (n)) // EP0 is reserved for control endpoint
+
+//-------------------------------------
+// USB register fields
+//-------------------------------------
+//-----------------
+// for endpoint specific registers
+//-----------------
+// for USB_EP_IN_CTRL_REG(n) and USB_EP_OUT_CTRL_REG(n) // default
+#define USB_EP_STALL 0x00000001 // 0 (RW)
+#define USB_EP_FLUSH 0x00000002 // 0 (RW)
+#define USB_EP_SNOOP 0x00000004 // 0 (RW) - for OUT EP only
+#define USB_EP_POLL_DEMAND 0x00000008 // 0 (RW) - for IN EP only
+#define USB_EP_TYPE_CTRL 0x00000000 // 00 (RW)
+#define USB_EP_TYPE_ISO 0x00000010 // 00 (RW)
+#define USB_EP_TYPE_BULK 0x00000020 // 00 (RW)
+#define USB_EP_TYPE_INTR 0x00000030 // 00 (RW)
+#define USB_EP_NAK_STS 0x00000040 // 0 (RO) - set by UDC after SETUP and STALL
+#define USB_EP_SET_NAK 0x00000080 // 0 (WO)
+#define USB_EP_CLR_NAK 0x00000100 // 0 (WO)
+#define USB_EP_RCV_RDY 0x00000200 // 0 (RW)(D) - set by APP when APP is ready for DMA
+ // clear by UDC when end of each packet if USB_DEV_DESC_UPD is set
+ // clear by UDC when end of payload if USB_DEV_DESC_UPD is clear
+
+// for USB_EP_IN_STS_REG(n) and USB_EP_OUT_STS_REG(n)
+#define USB_EP_OUT_PKT_MSK 0x00000030 // 00 (R/WC) - 01 for OUT and 10 for SETUP - for OUT EP only
+#define USB_EP_OUT_PKT 0x00000010
+#define USB_EP_SETUP_PKT 0x00000020
+#define USB_EP_IN_PKT 0x00000040 // 0 (R/WC) - for IN EP only
+#define USB_EP_BUF_NOT_AVAIL 0x00000080 // 0 (R/WC)(D) - set by UDC when descriptor is not available
+ // clear by APP when interrupt is serviced
+#define USB_EP_HOST_ERR 0x00000200 // 0 (R/WC) - set by DMA when DMA is error
+#define USB_EP_TRN_DMA_CMPL 0x00000400 // 0 (R/WC)(D) - set by DMA when DMA is completed
+#define USB_EP_RCV_CLR_STALL 0x02000000 // 0 (R/WC) - Received Clear Stall indication
+ // clear by APP when interrupt is serviced
+#define USB_EP_RCV_SET_STALL 0x04000000 // 0 (R/WC) - Received Set Stall indication
+#define USB_EP_RX_PKT_SZ 0x007ff800 // bit mask (RW) - receive packet size in RxFIFO (e.g. SETUP=64, BULK=512)
+
+#define USB_EP_TXFIFO_EMPTY 0x08000000 // 0 (R/WC) - TxFIFO is empty after DMA transfer done
+
+// for USB_EP_IN_BUF_SZ_REG(n) and USB_EP_OUT_PKT_FRM_NUM_REG(n)
+#define USB_EP_TXFIFO_DEPTH 0x0000ffff // bit mask (RW) - for IN EP only
+#define USB_EP_FRM_NUM 0x0000ffff // bit mask (RW) - for OUT EP only
+
+// for USB_EP_IN_MAX_PKT_SZ_REG(n) and USB_EP_OUT_MAX_PKT_SZ_REG(n)
+#define USB_EP_RXFIFO_DEPTH 0xffff0000 // bit mask (RW) - for OUT EP only
+#define USB_EP_MAX_PKT_SZ 0x0000ffff // bit mask (RW)
+
+//-----------------
+// for device specific registers
+//-----------------
+// for USB_DEV_CFG_REG
+#define USB_DEV_SPD_HI 0x00000000 // 00 (RW) - PHY CLK = 30 or 60 MHz
+#define USB_DEV_SPD_FU 0x00000001 // 00 (RW) - PHY CLK = 30 or 60 MHz
+#define USB_DEV_SPD_LO 0x00000002 // 00 (RW) - PHY CLK = 6 MHz
+#define USB_DEV_SPD_FU48 0x00000003 // 00 (RW) - PHY CLK = 48 MHz
+
+#define USB_DEV_REMOTE_WAKEUP_EN 0x00000004 // 0 (RW)
+
+#define USB_DEV_BUS_POWER 0x00000000 // 0 (RW)
+#define USB_DEV_SELF_POWER 0x00000008 // 0 (RW)
+
+#define USB_DEV_SYNC_FRM_EN 0x00000010 // 0 (RW)
+
+#define USB_DEV_PHY_16BIT 0x00000000 // 0 (RW)
+#define USB_DEV_PHY_8BIT 0x00000020 // 0 (RW)
+
+#define USB_DEV_UTMI_DIR_UNI 0x00000000 // 0 (RW) - UDC20 reserved to 0
+#define USB_DEV_UTMI_DIR_BI 0x00000040 // 0 (RW)
+
+#define USB_DEV_STS_OUT_NONZERO 0x00000180 // bit mask (RW)
+
+#define USB_DEV_PHY_ERR 0x00000200 // 0 (RW)
+
+#define USB_DEV_SPD_FU_TIMEOUT 0x00001c00 // bit mask (RW)
+#define USB_DEV_SPD_HI_TIMEOUT 0x0000e000 // bit mask (RW)
+
+#define USB_DEV_HALT_ACK 0x00000000 // 0 (RW) - ACK Clear_Feature (ENDPOINT_HALT) of EP0
+#define USB_DEV_HALT_STALL 0x00010000 // 1 (RW) - STALL Clear_Feature (ENDPOINT_HALT) of EP0
+
+#define USB_DEV_CSR_PRG_EN 0x00020000 // 1 (RW) - enable CSR_DONE of USB_DEV_CFG_REG
+
+#define USB_DEV_SET_DESC_STALL 0x00000000 // 0 (RW) - STALL Set_Descriptor
+#define USB_DEV_SET_DESC_ACK 0x00040000 // 1 (RW) - ACK Set_Descriptor
+
+#define USB_DEV_SDR 0x00000000 // 0 (RW)
+#define USB_DEV_DDR 0x00080000 // 1 (RW)
+
+// for USB_DEV_CTRL_REG
+#define USB_DEV_REMOTE_WAKEUP 0x00000001 // 0 (RW)
+#define USB_DEV_RCV_DMA_EN 0x00000004 // 0 (RW)(D)
+#define USB_DEV_TRN_DMA_EN 0x00000008 // 0 (RW)(D)
+
+#define USB_DEV_DESC_UPD_PYL 0x00000000 // 0 (RW)(D)
+#define USB_DEV_DESC_UPD_PKT 0x00000010 // 0 (RW)(D)
+
+#define USB_DEV_LITTLE_ENDN 0x00000000 // 0 (RW)(D)
+#define USB_DEV_BIG_ENDN 0x00000020 // 0 (RW)(D)
+
+#define USB_DEV_PKT_PER_BUF_MD 0x00000000 // 0 (RW)(D) - packet-per-buffer mode
+#define USB_DEV_BUF_FIL_MD 0x00000040 // 0 (RW)(D) - buffer fill mode
+
+#define USB_DEV_THRESH_EN 0x00000080 // 0 (RW)(D) - for OUT EP only
+
+#define USB_DEV_BURST_EN 0x00000100 // 0 (RW)(D)
+
+#define USB_DEV_SLAVE_ONLY_MD 0x00000000 // 0 (RW)(D)
+#define USB_DEV_DMA_MD 0x00000200 // 0 (RW)(D)
+
+#define USB_DEV_SOFT_DISCON 0x00000400 // 0 (RW) - signal UDC20 to disconnect
+#define USB_DEV_TIMER_SCALE_DOWN 0x00000800 // 0 (RW) - for gate-level simulation only
+#define USB_DEV_NAK 0x00001000 // 0 (RW) - device NAK (applied to all EPs)
+#define USB_DEV_CSR_DONE 0x00002000 // 0 (RW) - set to ACK Set_Configuration or Set_Interface if USB_DEV_CSR_PRG_EN
+#define USB_DEV_FLUSH_RXFIFO 0x00004000
+ // clear to NAK
+#define USB_DEV_BURST_LEN 0x00070000 // bit mask (RW)
+#define USB_DEV_THRESH_LEN 0x0f000000 // bit mask (RW)
+
+// for USB_DEV_STS_REG
+#define USB_DEV_CFG_NUM 0x0000000f // bit mask (RO)
+#define USB_DEV_INTF_NUM 0x000000f0 // bit mask (RO)
+#define USB_DEV_ALT_SET 0x00000f00 // bit mask (RO)
+#define USB_DEV_SUSP_STS 0x00001000 // bit mask (RO)
+
+#define USB_DEV_ENUM_SPD 0x00006000 // bit mask (RO)
+#define USB_DEV_ENUM_SPD_HI 0x00000000 // 00 (RO)
+#define USB_DEV_ENUM_SPD_FU 0x00002000 // 00 (RO)
+#define USB_DEV_ENUM_SPD_LO 0x00004000 // 00 (RO)
+#define USB_DEV_ENUM_SPD_FU48 0x00006000 // 00 (RO)
+
+#define USB_DEV_RXFIFO_EMPTY_STS 0x00008000 // bit mask (RO)
+#define USB_DEV_PHY_ERR_STS 0x00010000 // bit mask (RO)
+#define USB_DEV_FRM_NUM 0xfffc0000 // bit mask (RO)
+
+// for USB_DEV_INTR_REG
+#define USB_DEV_SET_CFG 0x00000001 // 0 (R/WC)
+#define USB_DEV_SET_INTF 0x00000002 // 0 (R/WC)
+#define USB_DEV_IDLE_3MS 0x00000004 // 0 (R/WC)
+#define USB_DEV_RESET 0x00000008 // 0 (R/WC)
+#define USB_DEV_SUSP 0x00000010 // 0 (R/WC)
+#define USB_DEV_SOF 0x00000020 // 0 (R/WC)
+#define USB_DEV_ENUM_CMPL 0x00000040 // 0 (R/WC)
+
+// for USB_DEV_INTR_MSK_REG
+#define USB_DEV_MSK_SET_CFG 0x00000001 // 0 (R/WC)
+#define USB_DEV_MSK_SET_INTF 0x00000002 // 0 (R/WC)
+#define USB_DEV_MSK_IDLE_3MS 0x00000004 // 0 (R/WC)
+#define USB_DEV_MSK_RESET 0x00000008 // 0 (R/WC)
+#define USB_DEV_MSK_SUSP 0x00000010 // 0 (R/WC)
+#define USB_DEV_MSK_SOF 0x00000020 // 0 (R/WC)
+#define USB_DEV_MSK_SPD_ENUM_CMPL 0x00000040 // 0 (R/WC)
+
+// for USB_DEV_EP_INTR_REG
+#define USB_DEV_EP0_IN 0x00000001 // 0 (R/WC)
+#define USB_DEV_EP1_IN 0x00000002 // 0 (R/WC)
+#define USB_DEV_EP2_IN 0x00000004 // 0 (R/WC)
+#define USB_DEV_EP3_IN 0x00000008 // 0 (R/WC)
+#define USB_DEV_EP4_IN 0x00000010 // 0 (R/WC)
+#define USB_DEV_EP5_IN 0x00000020 // 0 (R/WC)
+#define USB_DEV_EP6_IN 0x00000040 // 0 (R/WC)
+#define USB_DEV_EP7_IN 0x00000080 // 0 (R/WC)
+#define USB_DEV_EP8_IN 0x00000100 // 0 (R/WC)
+#define USB_DEV_EP9_IN 0x00000200 // 0 (R/WC)
+#define USB_DEV_EP10_IN 0x00000400 // 0 (R/WC)
+#define USB_DEV_EP11_IN 0x00000800 // 0 (R/WC)
+#define USB_DEV_EP12_IN 0x00001000 // 0 (R/WC)
+#define USB_DEV_EP13_IN 0x00002000 // 0 (R/WC)
+#define USB_DEV_EP14_IN 0x00004000 // 0 (R/WC)
+#define USB_DEV_EP15_IN 0x00008000 // 0 (R/WC)
+#define USB_DEV_EP0_OUT 0x00010000 // 0 (R/WC)
+#define USB_DEV_EP1_OUT 0x00020000 // 0 (R/WC)
+#define USB_DEV_EP2_OUT 0x00040000 // 0 (R/WC)
+#define USB_DEV_EP3_OUT 0x00080000 // 0 (R/WC)
+#define USB_DEV_EP4_OUT 0x00100000 // 0 (R/WC)
+#define USB_DEV_EP5_OUT 0x00200000 // 0 (R/WC)
+#define USB_DEV_EP6_OUT 0x00400000 // 0 (R/WC)
+#define USB_DEV_EP7_OUT 0x00800000 // 0 (R/WC)
+#define USB_DEV_EP8_OUT 0x01000000 // 0 (R/WC)
+#define USB_DEV_EP9_OUT 0x02000000 // 0 (R/WC)
+#define USB_DEV_EP10_OUT 0x04000000 // 0 (R/WC)
+#define USB_DEV_EP11_OUT 0x08000000 // 0 (R/WC)
+#define USB_DEV_EP12_OUT 0x10000000 // 0 (R/WC)
+#define USB_DEV_EP13_OUT 0x20000000 // 0 (R/WC)
+#define USB_DEV_EP14_OUT 0x40000000 // 0 (R/WC)
+#define USB_DEV_EP15_OUT 0x80000000 // 0 (R/WC)
+
+// for USB_DEV_EP_INTR_MSK_REG
+#define USB_DEV_MSK_EP0_IN 0x00000001 // 0 (R/WC)
+#define USB_DEV_MSK_EP1_IN 0x00000002 // 0 (R/WC)
+#define USB_DEV_MSK_EP2_IN 0x00000004 // 0 (R/WC)
+#define USB_DEV_MSK_EP3_IN 0x00000008 // 0 (R/WC)
+#define USB_DEV_MSK_EP4_IN 0x00000010 // 0 (R/WC)
+#define USB_DEV_MSK_EP5_IN 0x00000020 // 0 (R/WC)
+#define USB_DEV_MSK_EP6_IN 0x00000040 // 0 (R/WC)
+#define USB_DEV_MSK_EP7_IN 0x00000080 // 0 (R/WC)
+#define USB_DEV_MSK_EP8_IN 0x00000100 // 0 (R/WC)
+#define USB_DEV_MSK_EP9_IN 0x00000200 // 0 (R/WC)
+#define USB_DEV_MSK_EP10_IN 0x00000400 // 0 (R/WC)
+#define USB_DEV_MSK_EP11_IN 0x00000800 // 0 (R/WC)
+#define USB_DEV_MSK_EP12_IN 0x00001000 // 0 (R/WC)
+#define USB_DEV_MSK_EP13_IN 0x00002000 // 0 (R/WC)
+#define USB_DEV_MSK_EP14_IN 0x00004000 // 0 (R/WC)
+#define USB_DEV_MSK_EP15_IN 0x00008000 // 0 (R/WC)
+#define USB_DEV_MSK_EP0_OUT 0x00010000 // 0 (R/WC)
+#define USB_DEV_MSK_EP1_OUT 0x00020000 // 0 (R/WC)
+#define USB_DEV_MSK_EP2_OUT 0x00040000 // 0 (R/WC)
+#define USB_DEV_MSK_EP3_OUT 0x00080000 // 0 (R/WC)
+#define USB_DEV_MSK_EP4_OUT 0x00100000 // 0 (R/WC)
+#define USB_DEV_MSK_EP5_OUT 0x00200000 // 0 (R/WC)
+#define USB_DEV_MSK_EP6_OUT 0x00400000 // 0 (R/WC)
+#define USB_DEV_MSK_EP7_OUT 0x00800000 // 0 (R/WC)
+#define USB_DEV_MSK_EP8_OUT 0x01000000 // 0 (R/WC)
+#define USB_DEV_MSK_EP9_OUT 0x02000000 // 0 (R/WC)
+#define USB_DEV_MSK_EP10_OUT 0x04000000 // 0 (R/WC)
+#define USB_DEV_MSK_EP11_OUT 0x08000000 // 0 (R/WC)
+#define USB_DEV_MSK_EP12_OUT 0x10000000 // 0 (R/WC)
+#define USB_DEV_MSK_EP13_OUT 0x20000000 // 0 (R/WC)
+#define USB_DEV_MSK_EP14_OUT 0x40000000 // 0 (R/WC)
+#define USB_DEV_MSK_EP15_OUT 0x80000000 // 0 (R/WC)
+
+// for USB_DEV_TEST_MODE_REG
+#define USB_DEV_TEST_MD 0x00000001 // 0 (RW)
+
+// for USB_UDC_REG
+#define USB_UDC_EP0_NUM 0x00000000
+#define USB_UDC_EP1_NUM 0x00000001
+#define USB_UDC_EP2_NUM 0x00000002
+#define USB_UDC_EP3_NUM 0x00000003
+#define USB_UDC_EP4_NUM 0x00000004
+#define USB_UDC_EP5_NUM 0x00000005
+#define USB_UDC_EP6_NUM 0x00000006
+#define USB_UDC_EP7_NUM 0x00000007
+#define USB_UDC_EP8_NUM 0x00000008
+#define USB_UDC_EP9_NUM 0x00000009
+#define USB_UDC_EP10_NUM 0x0000000a
+#define USB_UDC_EP11_NUM 0x0000000b
+#define USB_UDC_EP12_NUM 0x0000000c
+#define USB_UDC_EP13_NUM 0x0000000d
+#define USB_UDC_EP14_NUM 0x0000000e
+#define USB_UDC_EP15_NUM 0x0000000f
+
+#define USB_UDC_OUT 0x00000000
+#define USB_UDC_IN 0x00000010
+
+#define USB_UDC_CTRL 0x00000000
+#define USB_UDC_ISO 0x00000020
+#define USB_UDC_BULK 0x00000040
+#define USB_UDC_INTR 0x00000060
+
+#define USB_EP_CTRL_MAX_PKT_SZ 64 // max packet size of control in/out endpoint
+#define USB_EP_BULK_MAX_PKT_SZ_HI 512 // max packet size of bulk in/out endpoint (high speed)
+#define USB_EP_BULK_MAX_PKT_SZ_FU 64 // max packet size of bulk in/out endpoint (full speed)
+#define USB_EP_INTR_MAX_PKT_SZ 64 // max packet size of interrupt in/out endpoint
+#define USB_EP_ISO_MAX_PKT_SZ 512 // max packet size of isochronous in/out endpoint
+
+#define USB_EP_CTRLIN_MAX_PKT_SZ USB_EP_CTRL_MAX_PKT_SZ
+#define USB_EP_CTRLOUT_MAX_PKT_SZ USB_EP_CTRL_MAX_PKT_SZ
+#define USB_EP_BULKIN_MAX_PKT_SZ_HI USB_EP_BULK_MAX_PKT_SZ_HI
+#define USB_EP_BULKOUT_MAX_PKT_SZ_HI USB_EP_BULK_MAX_PKT_SZ_HI
+#define USB_EP_BULKIN_MAX_PKT_SZ_FU USB_EP_BULK_MAX_PKT_SZ_FU
+#define USB_EP_BULKOUT_MAX_PKT_SZ_FU USB_EP_BULK_MAX_PKT_SZ_FU
+#define USB_EP_INTRIN_MAX_PKT_SZ USB_EP_INTR_MAX_PKT_SZ
+#define USB_EP_INTROUT_MAX_PKT_SZ USB_EP_INTR_MAX_PKT_SZ
+#define USB_EP_ISOIN_MAX_PKT_SZ USB_EP_ISO_MAX_PKT_SZ
+#define USB_EP_ISOOUT_MAX_PKT_SZ USB_EP_ISO_MAX_PKT_SZ
+#define USB_EP_ISOIN_TRANSACTIONS 1
+#define USB_EP_ISOOUT_TRANSACTIONS 1
+
+#define USB_UDC_MAX_PKT_SZ (0x1fff << 19)
+#define USB_UDC_CTRLIN_MAX_PKT_SZ (USB_EP_CTRLIN_MAX_PKT_SZ << 19)
+#define USB_UDC_CTRLOUT_MAX_PKT_SZ (USB_EP_CTRLOUT_MAX_PKT_SZ << 19)
+#define USB_UDC_BULKIN_MAX_PKT_SZ_HI (USB_EP_BULKIN_MAX_PKT_SZ_HI << 19)
+#define USB_UDC_BULKOUT_MAX_PKT_SZ_HI (USB_EP_BULKOUT_MAX_PKT_SZ_HI << 19)
+#define USB_UDC_BULKIN_MAX_PKT_SZ_FU (USB_EP_BULKIN_MAX_PKT_SZ_FU << 19)
+#define USB_UDC_BULKOUT_MAX_PKT_SZ_FU (USB_EP_BULKOUT_MAX_PKT_SZ_FU << 19)
+#define USB_UDC_INTRIN_MAX_PKT_SZ (USB_EP_INTRIN_MAX_PKT_SZ << 19)
+#define USB_UDC_INTROUT_MAX_PKT_SZ (USB_EP_INTROUT_MAX_PKT_SZ << 19)
+#define USB_UDC_ISOIN_MAX_PKT_SZ (USB_EP_ISOIN_MAX_PKT_SZ << 19)
+#define USB_UDC_ISOOUT_MAX_PKT_SZ (USB_EP_ISOOUT_MAX_PKT_SZ << 19)
+
+//-------------------------------------
+// DMA status quadlet fields
+//-------------------------------------
+// IN / OUT descriptor specific
+#define USB_DMA_RXTX_BYTES 0x0000ffff // bit mask
+
+// SETUP descriptor specific
+#define USB_DMA_CFG_STS 0x0fff0000 // bit mask
+#define USB_DMA_CFG_NUM 0x0f000000 // bit mask
+#define USB_DMA_INTF_NUM 0x00f00000 // bit mask
+#define USB_DMA_ALT_SET 0x000f0000 // bitmask
+// ISO OUT descriptor only
+#define USB_DMA_FRM_NUM 0x07ff0000 // bit mask
+// IN / OUT descriptor specific
+#define USB_DMA_LAST 0x08000000 // bit mask
+
+#define USB_DMA_RXTX_STS 0x30000000 // bit mask
+#define USB_DMA_RXTX_SUCC 0x00000000 // 00
+#define USB_DMA_RXTX_DES_ERR 0x10000000 // 01
+#define USB_DMA_RXTX_BUF_ERR 0x30000000 // 11
+
+#define USB_DMA_BUF_STS 0xc0000000 // bit mask
+#define USB_DMA_BUF_HOST_RDY 0x00000000 // 00
+#define USB_DMA_BUF_DMA_BUSY 0x40000000 // 01
+#define USB_DMA_BUF_DMA_DONE 0x80000000 // 10
+#define USB_DMA_BUF_HOST_BUSY 0xc0000000 // 11
+
+/* ==========================================================================*/
+
+#endif
+
diff --git a/arch/arm/mach-ambarella/include/plat/wdt.h b/arch/arm/mach-ambarella/include/plat/wdt.h
new file mode 100644
index 00000000..c43703b1
--- /dev/null
+++ b/arch/arm/mach-ambarella/include/plat/wdt.h
@@ -0,0 +1,62 @@
+/*
+ * arch/arm/plat-ambarella/include/plat/wdt.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_AMBARELLA_WDT_H__
+#define __PLAT_AMBARELLA_WDT_H__
+
+/* ==========================================================================*/
+#define WDOG_OFFSET 0xC000
+#define WDOG_BASE (APB_BASE + WDOG_OFFSET)
+#define WDOG_REG(x) (WDOG_BASE + (x))
+
+/* ==========================================================================*/
+#define WDOG_STATUS_OFFSET 0x00
+#define WDOG_RELOAD_OFFSET 0x04
+#define WDOG_RESTART_OFFSET 0x08
+#define WDOG_CONTROL_OFFSET 0x0c
+#define WDOG_TIMEOUT_OFFSET 0x10
+#define WDOG_CLR_TMO_OFFSET 0x14
+#define WDOG_RST_WD_OFFSET 0x18
+
+#define WDOG_STATUS_REG WDOG_REG(WDOG_STATUS_OFFSET)
+#define WDOG_RELOAD_REG WDOG_REG(WDOG_RELOAD_OFFSET)
+#define WDOG_RESTART_REG WDOG_REG(WDOG_RESTART_OFFSET)
+#define WDOG_CONTROL_REG WDOG_REG(WDOG_CONTROL_OFFSET)
+#define WDOG_TIMEOUT_REG WDOG_REG(WDOG_TIMEOUT_OFFSET)
+#define WDOG_CLR_TMO_REG WDOG_REG(WDOG_CLR_TMO_OFFSET)
+#define WDOG_RST_WD_REG WDOG_REG(WDOG_RST_WD_OFFSET)
+
+#define WDOG_CTR_INT_EN 0x00000004
+#define WDOG_CTR_RST_EN 0x00000002
+#define WDOG_CTR_EN 0x00000001
+
+/* WDOG_RESTART_REG only works with magic 0x4755.
+ * Set this value would transferred the value in
+ * WDOG_RELOAD_REG into WDOG_STATUS_REG and would
+ * not trigger the underflow event. */
+#define WDT_RESTART_VAL 0x4755
+
+/* ==========================================================================*/
+
+#endif /* __PLAT_AMBARELLA_WDT_H__ */
+
diff --git a/arch/arm/mach-ambarella/init.c b/arch/arm/mach-ambarella/init.c
new file mode 100644
index 00000000..10234924
--- /dev/null
+++ b/arch/arm/mach-ambarella/init.c
@@ -0,0 +1,484 @@
+/*
+ * arch/arm/plat-ambarella/generic/init.c
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/proc_fs.h>
+#include <linux/memblock.h>
+#include <linux/export.h>
+#include <linux/clk.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+#include <asm/cacheflush.h>
+#include <asm/system_info.h>
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+#include <mach/init.h>
+#include <plat/clk.h>
+#include <asm/hardware/cache-l2x0.h>
+
+/* ==========================================================================*/
+u64 ambarella_dmamask = DMA_BIT_MASK(32);
+EXPORT_SYMBOL(ambarella_dmamask);
+
+/* ==========================================================================*/
+enum {
+ AMBARELLA_IO_DESC_AHB_ID = 0,
+ AMBARELLA_IO_DESC_APB_ID,
+ AMBARELLA_IO_DESC_PPM_ID,
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI)
+ AMBARELLA_IO_DESC_AXI_ID,
+#endif
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC)
+ AMBARELLA_IO_DESC_DRAMC_ID,
+#endif
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_CRYPT)
+ AMBARELLA_IO_DESC_CRYPT_ID,
+#endif
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64)
+ AMBARELLA_IO_DESC_AHB64_ID,
+#endif
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS)
+ AMBARELLA_IO_DESC_DBGBUS_ID,
+ AMBARELLA_IO_DESC_DBGFMEM_ID,
+#endif
+ AMBARELLA_IO_DESC_FRAMEBUF_ID,
+ AMBARELLA_IO_DESC_DSP_ID,
+};
+
+struct ambarella_mem_map_desc {
+ char name[8];
+ struct map_desc io_desc;
+};
+
+static struct ambarella_mem_map_desc ambarella_io_desc[] = {
+ [AMBARELLA_IO_DESC_AHB_ID] = {
+ .name = "AHB",
+ .io_desc = {
+ .virtual = AHB_BASE,
+ .pfn = __phys_to_pfn(AHB_PHYS_BASE),
+ .length = AHB_SIZE,
+#if defined(CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK)
+ .type = MT_DEVICE_NONSHARED,
+#else
+ .type = MT_DEVICE,
+#endif
+ },
+ },
+ [AMBARELLA_IO_DESC_APB_ID] = {
+ .name = "APB",
+ .io_desc = {
+ .virtual = APB_BASE,
+ .pfn = __phys_to_pfn(APB_PHYS_BASE),
+ .length = APB_SIZE,
+#if defined(CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK)
+ .type = MT_DEVICE_NONSHARED,
+#else
+ .type = MT_DEVICE,
+#endif
+ },
+ },
+ [AMBARELLA_IO_DESC_PPM_ID] = {
+ .name = "PPM", /*Private Physical Memory*/
+ .io_desc = {
+ .virtual = AHB_BASE - CONFIG_AMBARELLA_PPM_SIZE,
+ .pfn = __phys_to_pfn(DEFAULT_MEM_START),
+ .length = CONFIG_AMBARELLA_PPM_SIZE,
+#if defined(CONFIG_AMBARELLA_PPM_UNCACHED)
+ .type = MT_DEVICE,
+#else
+ .type = MT_MEMORY,
+#endif
+ },
+ },
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AXI)
+ [AMBARELLA_IO_DESC_AXI_ID] = {
+ .name = "AXI",
+ .io_desc = {
+ .virtual = AXI_BASE,
+ .pfn = __phys_to_pfn(AXI_PHYS_BASE),
+ .length = AXI_SIZE,
+ .type = MT_DEVICE,
+ },
+ },
+#endif
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DRAMC)
+ [AMBARELLA_IO_DESC_DRAMC_ID] = {
+ .name = "DRAMC",
+ .io_desc = {
+ .virtual= DRAMC_BASE,
+ .pfn = __phys_to_pfn(DRAMC_PHYS_BASE),
+ .length = DRAMC_SIZE,
+#if defined(CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK)
+ .type = MT_DEVICE_NONSHARED,
+#else
+ .type = MT_DEVICE,
+#endif
+ },
+ },
+#endif
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_CRYPT)
+ [AMBARELLA_IO_DESC_CRYPT_ID] = {
+ .name = "CRYPT",
+ .io_desc = {
+ .virtual= CRYPT_BASE,
+ .pfn = __phys_to_pfn(CRYPT_PHYS_BASE),
+ .length = CRYPT_SIZE,
+#if defined(CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK)
+ .type = MT_DEVICE_NONSHARED,
+#else
+ .type = MT_DEVICE,
+#endif
+ },
+ },
+#endif
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_AHB64)
+ [AMBARELLA_IO_DESC_AHB64_ID] = {
+ .name = "AHB64",
+ .io_desc = {
+ .virtual= AHB64_BASE,
+ .pfn = __phys_to_pfn(AHB64_PHYS_BASE),
+ .length = AHB64_SIZE,
+ .type = MT_DEVICE,
+ },
+ },
+#endif
+#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_MMAP_DBGBUS)
+ [AMBARELLA_IO_DESC_DBGBUS_ID] = {
+ .name = "DBGBUS",
+ .io_desc = {
+ .virtual= DBGBUS_BASE,
+ .pfn = __phys_to_pfn(DBGBUS_PHYS_BASE),
+ .length = DBGBUS_SIZE,
+ .type = MT_DEVICE,
+ },
+ },
+ [AMBARELLA_IO_DESC_DBGFMEM_ID] = {
+ .name = "DBGFMEM",
+ .io_desc = {
+ .virtual= DBGFMEM_BASE,
+ .pfn = __phys_to_pfn(DBGFMEM_PHYS_BASE),
+ .length = DBGFMEM_SIZE,
+ .type = MT_DEVICE,
+ },
+ },
+#endif
+ [AMBARELLA_IO_DESC_DSP_ID] = {
+ .name = "IAV",
+ .io_desc = {
+ .virtual = 0x00000000,
+ .pfn = 0x00000000,
+ .length = 0x00000000,
+ },
+ },
+ [AMBARELLA_IO_DESC_FRAMEBUF_ID] = {
+ .name = "FRAMEBUF",
+ .io_desc = {
+ .virtual = 0x00000000,
+ .pfn = 0x00000000,
+ .length = 0x00000000,
+ },
+ },
+};
+
+
+static int __init ambarella_dt_scan_iavmem(unsigned long node,
+ const char *uname, int depth, void *data)
+{
+ const char *type;
+ __be32 *reg;
+ unsigned long len;
+ struct ambarella_mem_map_desc *iavmem_desc;
+
+ type = of_get_flat_dt_prop(node, "device_type", NULL);
+ if (type == NULL || strcmp(type, "iavmem") != 0)
+ return 0;
+
+ reg = of_get_flat_dt_prop(node, "reg", &len);
+ if (WARN_ON(!reg || (len != 2 * sizeof(unsigned long))))
+ return 0;
+
+ iavmem_desc = &ambarella_io_desc[AMBARELLA_IO_DESC_DSP_ID];
+ iavmem_desc->io_desc.pfn = __phys_to_pfn(be32_to_cpu(reg[0]));
+ iavmem_desc->io_desc.length = be32_to_cpu(reg[1]);
+
+ pr_info("Ambarella: IAVMEM = 0x%08x[ ],0x%08x\n",
+ be32_to_cpu(reg[0]), be32_to_cpu(reg[1]));
+
+ return 1;
+}
+
+static int __init ambarella_dt_scan_fbmem(unsigned long node,
+ const char *uname, int depth, void *data)
+{
+ const char *type;
+ __be32 *reg;
+ unsigned long len;
+ struct ambarella_mem_map_desc *fbmem_desc;
+
+ type = of_get_flat_dt_prop(node, "device_type", NULL);
+ if (type == NULL || strcmp(type, "fbmem") != 0)
+ return 0;
+
+ reg = of_get_flat_dt_prop(node, "reg", &len);
+ if (WARN_ON(!reg || (len != 2 * sizeof(unsigned long))))
+ return 0;
+
+ fbmem_desc = &ambarella_io_desc[AMBARELLA_IO_DESC_FRAMEBUF_ID];
+ fbmem_desc->io_desc.pfn = __phys_to_pfn(be32_to_cpu(reg[0]));
+ fbmem_desc->io_desc.length = be32_to_cpu(reg[1]);
+
+ pr_info("Ambarella: FBMEM = 0x%08x[ ],0x%08x\n",
+ be32_to_cpu(reg[0]), be32_to_cpu(reg[1]));
+
+ return 1;
+}
+
+void __init ambarella_map_io(void)
+{
+ u32 i, iop, ios, iov;
+
+ for (i = 0; i < AMBARELLA_IO_DESC_DSP_ID; i++) {
+ iop = __pfn_to_phys(ambarella_io_desc[i].io_desc.pfn);
+ ios = ambarella_io_desc[i].io_desc.length;
+ iov = ambarella_io_desc[i].io_desc.virtual;
+ if (ios > 0) {
+ iotable_init(&(ambarella_io_desc[i].io_desc), 1);
+ pr_info("Ambarella: %8s = 0x%08x[0x%08x],0x%08x %d\n",
+ ambarella_io_desc[i].name, iop, iov, ios,
+ ambarella_io_desc[i].io_desc.type);
+ }
+ }
+
+ /* scan and hold the memory information for IAV */
+ of_scan_flat_dt(ambarella_dt_scan_iavmem, NULL);
+ /* scan and hold the memory information for FRAMEBUFFER */
+ of_scan_flat_dt(ambarella_dt_scan_fbmem, NULL);
+}
+
+/* ==========================================================================*/
+static struct proc_dir_entry *ambarella_proc_dir = NULL;
+
+int __init ambarella_create_proc_dir(void)
+{
+ int ret_val = 0;
+
+ ambarella_proc_dir = proc_mkdir("ambarella", NULL);
+ if (!ambarella_proc_dir)
+ ret_val = -ENOMEM;
+
+ return ret_val;
+}
+
+struct proc_dir_entry *get_ambarella_proc_dir(void)
+{
+ return ambarella_proc_dir;
+}
+EXPORT_SYMBOL(get_ambarella_proc_dir);
+
+
+/* ==========================================================================*/
+void __init ambarella_init_machine(void)
+{
+ int ret_val = 0;
+
+#if defined(CONFIG_PLAT_AMBARELLA_LOWER_ARM_PLL)
+ amba_rct_writel(SCALER_ARM_ASYNC_REG, 0xF);
+#endif
+
+ ret_val = ambarella_create_proc_dir();
+ BUG_ON(ret_val != 0);
+
+ ret_val = ambarella_clk_init();
+ BUG_ON(ret_val != 0);
+
+ ret_val = ambarella_init_fio();
+ BUG_ON(ret_val != 0);
+
+ ret_val = ambarella_init_fb();
+ BUG_ON(ret_val != 0);
+
+ ret_val = ambarella_init_pm();
+ BUG_ON(ret_val != 0);
+
+ ret_val = ambarella_init_audio();
+ BUG_ON(ret_val != 0);
+ l2x0_of_init((1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT)
+ | (1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT), ~0);
+
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+void ambarella_restart_machine(char mode, const char *cmd)
+{
+ local_irq_disable();
+ local_fiq_disable();
+ flush_cache_all();
+ amba_rct_writel(SOFT_OR_DLL_RESET_REG, 0x2);
+ amba_rct_writel(SOFT_OR_DLL_RESET_REG, 0x3);
+}
+
+/* ==========================================================================*/
+
+static int __init parse_system_revision(char *p)
+{
+ system_rev = simple_strtoul(p, NULL, 0);
+ return 0;
+}
+early_param("system_rev", parse_system_revision);
+
+u32 ambarella_phys_to_virt(u32 paddr)
+{
+ int i;
+ u32 phystart;
+ u32 phylength;
+ u32 phyoffset;
+ u32 vstart;
+
+ for (i = 0; i < ARRAY_SIZE(ambarella_io_desc); i++) {
+ phystart = __pfn_to_phys(ambarella_io_desc[i].io_desc.pfn);
+ phylength = ambarella_io_desc[i].io_desc.length;
+ vstart = ambarella_io_desc[i].io_desc.virtual;
+ if ((paddr >= phystart) && (paddr < (phystart + phylength))) {
+ phyoffset = paddr - phystart;
+ return (vstart + phyoffset);
+ }
+ }
+
+ return __amb_raw_phys_to_virt(paddr);
+}
+EXPORT_SYMBOL(ambarella_phys_to_virt);
+
+u32 ambarella_virt_to_phys(u32 vaddr)
+{
+ int i;
+ u32 phystart;
+ u32 vlength;
+ u32 voffset;
+ u32 vstart;
+
+ for (i = 0; i < ARRAY_SIZE(ambarella_io_desc); i++) {
+ phystart = __pfn_to_phys(ambarella_io_desc[i].io_desc.pfn);
+ vlength = ambarella_io_desc[i].io_desc.length;
+ vstart = ambarella_io_desc[i].io_desc.virtual;
+ if ((vaddr >= vstart) && (vaddr < (vstart + vlength))) {
+ voffset = vaddr - vstart;
+ return (phystart + voffset);
+ }
+ }
+
+ return __amb_raw_virt_to_phys(vaddr);
+}
+EXPORT_SYMBOL(ambarella_virt_to_phys);
+
+u32 get_ambarella_fbmem_phys(void)
+{
+ return __pfn_to_phys(
+ ambarella_io_desc[AMBARELLA_IO_DESC_FRAMEBUF_ID].io_desc.pfn);
+}
+EXPORT_SYMBOL(get_ambarella_fbmem_phys);
+
+u32 get_ambarella_fbmem_size(void)
+{
+ return ambarella_io_desc[AMBARELLA_IO_DESC_FRAMEBUF_ID].io_desc.length;
+}
+EXPORT_SYMBOL(get_ambarella_fbmem_size);
+
+u32 get_ambarella_iavmem_phys(void)
+{
+ return __pfn_to_phys(
+ ambarella_io_desc[AMBARELLA_IO_DESC_DSP_ID].io_desc.pfn);
+}
+EXPORT_SYMBOL(get_ambarella_iavmem_phys);
+
+u32 get_ambarella_iavmem_size(void)
+{
+ return ambarella_io_desc[AMBARELLA_IO_DESC_DSP_ID].io_desc.length;
+}
+EXPORT_SYMBOL(get_ambarella_iavmem_size);
+
+u32 get_ambarella_ppm_phys(void)
+{
+ return __pfn_to_phys(
+ ambarella_io_desc[AMBARELLA_IO_DESC_PPM_ID].io_desc.pfn);
+}
+EXPORT_SYMBOL(get_ambarella_ppm_phys);
+
+u32 get_ambarella_ppm_virt(void)
+{
+ return ambarella_io_desc[AMBARELLA_IO_DESC_PPM_ID].io_desc.virtual;
+}
+EXPORT_SYMBOL(get_ambarella_ppm_virt);
+
+u32 get_ambarella_ppm_size(void)
+{
+ return ambarella_io_desc[AMBARELLA_IO_DESC_PPM_ID].io_desc.length;
+}
+EXPORT_SYMBOL(get_ambarella_ppm_size);
+
+u32 get_ambarella_ahb_phys(void)
+{
+ return __pfn_to_phys(
+ ambarella_io_desc[AMBARELLA_IO_DESC_AHB_ID].io_desc.pfn);
+}
+EXPORT_SYMBOL(get_ambarella_ahb_phys);
+
+u32 get_ambarella_ahb_virt(void)
+{
+ return ambarella_io_desc[AMBARELLA_IO_DESC_AHB_ID].io_desc.virtual;
+}
+EXPORT_SYMBOL(get_ambarella_ahb_virt);
+
+u32 get_ambarella_ahb_size(void)
+{
+ return ambarella_io_desc[AMBARELLA_IO_DESC_AHB_ID].io_desc.length;
+}
+EXPORT_SYMBOL(get_ambarella_ahb_size);
+
+u32 get_ambarella_apb_phys(void)
+{
+ return __pfn_to_phys(
+ ambarella_io_desc[AMBARELLA_IO_DESC_APB_ID].io_desc.pfn);
+}
+EXPORT_SYMBOL(get_ambarella_apb_phys);
+
+u32 get_ambarella_apb_virt(void)
+{
+ return ambarella_io_desc[AMBARELLA_IO_DESC_APB_ID].io_desc.virtual;
+}
+EXPORT_SYMBOL(get_ambarella_apb_virt);
+
+u32 get_ambarella_apb_size(void)
+{
+ return ambarella_io_desc[AMBARELLA_IO_DESC_APB_ID].io_desc.length;
+}
+EXPORT_SYMBOL(get_ambarella_apb_size);
+
+u32 ambarella_get_poc(void)
+{
+ return amba_rct_readl(SYS_CONFIG_REG);
+}
+EXPORT_SYMBOL(ambarella_get_poc);
+
+
diff --git a/arch/arm/mach-ambarella/misc/Makefile b/arch/arm/mach-ambarella/misc/Makefile
new file mode 100644
index 00000000..69224ee9
--- /dev/null
+++ b/arch/arm/mach-ambarella/misc/Makefile
@@ -0,0 +1,35 @@
+#
+# arch/arm/plat-ambarella/misc/Makefile
+#
+# Author: Anthony Ginger <hfjiang@ambarella.com>
+#
+# Copyright (C) 2004-2011, Ambarella, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+obj-y += hwlock.o
+obj-y += audio.o
+obj-$(CONFIG_PLAT_AMBARELLA_SUPPORT_GDMA) += gdma.o
+obj-y += ambasyncproc.o
+obj-$(CONFIG_AMBARELLA_SUPPORT_AMBENCH) += ambench.o
+obj-y += ambevent.o
+obj-y += ambfb.o
+obj-y += ambsyncproc.o
+obj-y += event.o
+obj-y += iav_helper.o
+obj-$(CONFIG_AMBARELLA_TIMER_HIGHRES) += highres_timer.o
+obj-y += pmu.o
+
diff --git a/arch/arm/mach-ambarella/misc/ambasyncproc.c b/arch/arm/mach-ambarella/misc/ambasyncproc.c
new file mode 100644
index 00000000..a2d25438
--- /dev/null
+++ b/arch/arm/mach-ambarella/misc/ambasyncproc.c
@@ -0,0 +1,120 @@
+/*
+ * arch/arm/plat-ambarella/misc/ambasyncproc.c
+ *
+ * Author: Zhenwu Xue, <zwxue@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/proc_fs.h>
+
+#include <plat/ambasyncproc.h>
+#include <mach/hardware.h>
+
+#define GET_PROC_DATA_FROM_FILEP(filp) \
+ (struct amb_async_proc_info *)(PDE_DATA(filp->f_path.dentry->d_inode))
+
+static int amb_async_proc_open(struct inode *inode, struct file *filp)
+{
+ struct amb_async_proc_info *pinfo;
+
+ pinfo = GET_PROC_DATA_FROM_FILEP(filp);
+
+ mutex_lock(&pinfo->op_mutex);
+ pinfo->use_count++;
+ filp->f_op = &pinfo->fops;
+ filp->private_data = pinfo->private_data;
+ mutex_unlock(&pinfo->op_mutex);
+
+ return 0;
+}
+
+static int amb_async_proc_fasync(int fd, struct file * filp, int on)
+{
+ int retval;
+ struct amb_async_proc_info *pinfo;
+
+ pinfo = GET_PROC_DATA_FROM_FILEP(filp);
+
+ mutex_lock(&pinfo->op_mutex);
+ retval = fasync_helper(fd, filp, on, &pinfo->fasync_queue);
+ mutex_unlock(&pinfo->op_mutex);
+
+ return retval;
+}
+
+static int amb_async_proc_release(struct inode *inode, struct file *filp)
+{
+ int retval;
+ struct amb_async_proc_info *pinfo;
+
+ pinfo = GET_PROC_DATA_FROM_FILEP(filp);
+
+ mutex_lock(&pinfo->op_mutex);
+ retval = fasync_helper(-1, filp, 0, &pinfo->fasync_queue);
+ pinfo->use_count--;
+ mutex_unlock(&pinfo->op_mutex);
+
+ return retval;
+}
+
+int amb_async_proc_create(struct amb_async_proc_info *pinfo)
+{
+ int retval = 0;
+ struct proc_dir_entry *entry;
+
+ if (!pinfo) {
+ retval = -EINVAL;
+ goto amb_async_proc_create_exit;
+ }
+
+ pinfo->fops.open = amb_async_proc_open;
+ pinfo->fops.fasync = amb_async_proc_fasync;
+ pinfo->fops.release = amb_async_proc_release;
+ mutex_init(&pinfo->op_mutex);
+ pinfo->use_count = 0;
+ pinfo->fasync_queue = NULL;
+
+ entry = proc_create_data(pinfo->proc_name, S_IRUGO,
+ get_ambarella_proc_dir(), &pinfo->fops, pinfo);
+ if (!entry) {
+ retval = -EINVAL;
+ }
+
+amb_async_proc_create_exit:
+ return retval;
+}
+EXPORT_SYMBOL(amb_async_proc_create);
+
+int amb_async_proc_remove(struct amb_async_proc_info *pinfo)
+{
+ int retval = 0;
+
+ if (!pinfo) {
+ retval = -EINVAL;
+ } else {
+ remove_proc_entry(pinfo->proc_name, get_ambarella_proc_dir());
+ }
+
+ return retval;
+}
+EXPORT_SYMBOL(amb_async_proc_remove);
+
diff --git a/arch/arm/mach-ambarella/misc/ambench.c b/arch/arm/mach-ambarella/misc/ambench.c
new file mode 100644
index 00000000..e807c3d6
--- /dev/null
+++ b/arch/arm/mach-ambarella/misc/ambench.c
@@ -0,0 +1,198 @@
+/*
+ * arch/arm/plat-ambarella/misc/ambench.c
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2011, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/io.h>
+#include <linux/cpu.h>
+#include <linux/clk.h>
+
+#include <asm/uaccess.h>
+#include <asm/system_info.h>
+
+#include <mach/hardware.h>
+#include <plat/clk.h>
+
+/* ==========================================================================*/
+#ifdef MODULE_PARAM_PREFIX
+#undef MODULE_PARAM_PREFIX
+#endif
+#define MODULE_PARAM_PREFIX "ambarella_config."
+
+#define AMBENCH_MAX_CMD_LENGTH (32)
+
+/* ==========================================================================*/
+typedef void (*ambarella_ambench_fn_t)(void);
+
+struct ambarella_ambench_info {
+ char name[32];
+ ambarella_ambench_fn_t fn;
+};
+
+/* ==========================================================================*/
+static void ambench_apbread(void);
+
+/* ==========================================================================*/
+static const char ambench_proc_name[] = "ambench";
+
+static struct ambarella_ambench_info ambench_list[] = {
+ {"APBRead", ambench_apbread},
+ {"", NULL}
+};
+
+/* ==========================================================================*/
+static int ambarella_ambench_proc_write(struct file *file,
+ const char __user *buffer, size_t count, loff_t *ppos)
+{
+ int retval = 0;
+ char str[AMBENCH_MAX_CMD_LENGTH];
+ int i;
+
+ i = (count < AMBENCH_MAX_CMD_LENGTH) ? count : AMBENCH_MAX_CMD_LENGTH;
+ if (copy_from_user(str, buffer, i)) {
+ pr_err("%s: copy_from_user fail!\n", __func__);
+ retval = -EFAULT;
+ goto ambarella_ambench_proc_write_exit;
+ }
+ str[i - 1] = 0;
+
+ for (i = 0; i < ARRAY_SIZE(ambench_list); i++) {
+ if (ambench_list[i].fn == NULL) {
+ break;
+ }
+ if (strlen(str) == strlen(ambench_list[i].name)
+ && strcmp(str, ambench_list[i].name) == 0) {
+ ambench_list[i].fn();
+ break;
+ }
+ }
+
+ if (strcmp(str, "all") == 0) {
+ for (i = 0; i < ARRAY_SIZE(ambench_list); i++) {
+ if (ambench_list[i].fn == NULL) {
+ break;
+ }
+ ambench_list[i].fn();
+ }
+ }
+
+ if (!retval)
+ retval = count;
+
+ambarella_ambench_proc_write_exit:
+ return retval;
+}
+
+static int ambarella_ambench_proc_show(struct seq_file *m, void *v)
+{
+ int retlen = 0;
+ int i;
+
+ retlen = seq_printf(m, "\nPossible Benchmark:\n");
+ for (i = 0; i < ARRAY_SIZE(ambench_list); i++) {
+ if (ambench_list[i].fn == NULL) {
+ break;
+ }
+ retlen += seq_printf(m, "\t%s\n", ambench_list[i].name);
+ }
+
+ return retlen;
+}
+
+static int ambarella_ambench_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ambarella_ambench_proc_show, PDE_DATA(inode));
+}
+
+static const struct file_operations proc_ambench_fops = {
+ .open = ambarella_ambench_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .write = ambarella_ambench_proc_write,
+};
+
+/* ==========================================================================*/
+static int __init ambarella_init_ambench(void)
+{
+ int retval = 0;
+
+ proc_create_data(ambench_proc_name, (S_IRUGO | S_IWUSR),
+ get_ambarella_proc_dir(), &proc_ambench_fops, NULL);
+
+ return retval;
+}
+late_initcall(ambarella_init_ambench);
+
+/* ==========================================================================*/
+#define APBREAD_RELOAD_NUM (0x10000000)
+static void ambench_apbread(void)
+{
+ u64 raw_counter = 0;
+ u64 amba_counter = 0;
+ unsigned long flags;
+
+ disable_nonboot_cpus();
+ local_irq_save(flags);
+
+ amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
+ amba_writel(TIMER1_STATUS_REG, APBREAD_RELOAD_NUM);
+ amba_writel(TIMER1_RELOAD_REG, 0x0);
+ amba_writel(TIMER1_MATCH1_REG, 0x0);
+ amba_writel(TIMER1_MATCH2_REG, 0x0);
+ amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_OF1);
+ amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_CSL1);
+
+ amba_setbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
+ do {
+ raw_counter++;
+ } while(__raw_readl((const volatile void *)TIMER1_STATUS_REG));
+
+ amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
+ amba_writel(TIMER1_STATUS_REG, APBREAD_RELOAD_NUM);
+ amba_writel(TIMER1_RELOAD_REG, 0x0);
+ amba_writel(TIMER1_MATCH1_REG, 0x0);
+ amba_writel(TIMER1_MATCH2_REG, 0x0);
+ amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_OF1);
+ amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_CSL1);
+
+ amba_setbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
+ do {
+ amba_counter++;
+ } while(amba_readl(TIMER1_STATUS_REG));
+ amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
+
+ local_irq_restore(flags);
+ enable_nonboot_cpus();
+
+ raw_counter *= clk_get_rate(clk_get(NULL, "gclk_apb"));
+ do_div(raw_counter, APBREAD_RELOAD_NUM);
+ amba_counter *= clk_get_rate(clk_get(NULL, "gclk_apb"));
+ do_div(amba_counter, APBREAD_RELOAD_NUM);
+ pr_info("CPU[0x%x] APBRead: raw speed %llu/s!\n",
+ cpu_architecture(), raw_counter);
+ pr_info("CPU[0x%x] APBRead: amba speed %llu/s!\n",
+ cpu_architecture(), amba_counter);
+}
+
diff --git a/arch/arm/mach-ambarella/misc/ambevent.c b/arch/arm/mach-ambarella/misc/ambevent.c
new file mode 100644
index 00000000..5ba91a74
--- /dev/null
+++ b/arch/arm/mach-ambarella/misc/ambevent.c
@@ -0,0 +1,111 @@
+/*
+ * arch/arm/plat-ambarella/misc/ambevent.c
+ *
+ * Author: Zhenwu Xue, <zwxue@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <linux/export.h>
+#include <linux/errno.h>
+#include <linux/bootmem.h>
+#include <linux/platform_device.h>
+#include <plat/ambevent.h>
+
+int amb_event_pool_init(struct amb_event_pool *pool)
+{
+ if (!pool)
+ return -EINVAL;
+
+ memset(pool, 0, sizeof(struct amb_event_pool));
+ mutex_init(&pool->op_mutex);
+ return 0;
+}
+EXPORT_SYMBOL(amb_event_pool_init);
+
+int amb_event_pool_affuse(struct amb_event_pool *pool,
+ struct amb_event event)
+{
+ if (!pool)
+ return -EINVAL;
+
+ if (event.type == AMB_EV_NONE)
+ return 0;
+
+ mutex_lock(&pool->op_mutex);
+ pool->ev_sno++;
+ pool->events[pool->ev_index].sno = pool->ev_sno;
+ pool->events[pool->ev_index].time_code = 0; //FIX ME
+ pool->events[pool->ev_index].type = event.type;
+ memcpy(pool->events[pool->ev_index].data, event.data, sizeof(event.data));
+ pool->ev_index++;
+ mutex_unlock(&pool->op_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL(amb_event_pool_affuse);
+
+int amb_event_pool_query_index(struct amb_event_pool *pool)
+{
+ unsigned char index;
+
+ if (!pool)
+ return -EINVAL;
+
+ mutex_lock(&pool->op_mutex);
+ index = pool->ev_index - 1;
+ mutex_unlock(&pool->op_mutex);
+
+ return (int)index;
+}
+EXPORT_SYMBOL(amb_event_pool_query_index);
+
+int amb_event_pool_query_event(struct amb_event_pool *pool,
+ struct amb_event *event, unsigned char index)
+{
+ int retval = 0;
+
+ if (!pool || !event)
+ return -EINVAL;
+
+ mutex_lock(&pool->op_mutex);
+
+ if (pool->events[index].type == AMB_EV_NONE) {
+ retval = -EAGAIN;
+ goto amb_event_pool_query_event_exit;
+ }
+
+ if (index == pool->ev_index) {
+ retval = -EAGAIN;
+ goto amb_event_pool_query_event_exit;
+ }
+
+ *event = pool->events[index];
+
+amb_event_pool_query_event_exit:
+ mutex_unlock(&pool->op_mutex);
+ return retval;
+}
+EXPORT_SYMBOL(amb_event_pool_query_event);
+
+int amb_event_report_uevent(struct kobject *kobj, enum kobject_action action,
+ char *envp_ext[])
+{
+ return kobject_uevent_env(kobj, action, envp_ext);
+}
+EXPORT_SYMBOL(amb_event_report_uevent);
+
diff --git a/arch/arm/mach-ambarella/misc/ambfb.c b/arch/arm/mach-ambarella/misc/ambfb.c
new file mode 100644
index 00000000..4683653f
--- /dev/null
+++ b/arch/arm/mach-ambarella/misc/ambfb.c
@@ -0,0 +1,223 @@
+/*
+ * arch/arm/plat-ambarella/video/ambfb.c
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/bootmem.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/setup.h>
+
+#include <asm/mach/map.h>
+
+#include <linux/fb.h>
+
+#include <mach/hardware.h>
+#include <plat/fb.h>
+
+/* ==========================================================================*/
+static struct ambarella_platform_fb ambarella_platform_fb0 = {
+ .screen_var = {
+ .xres = 720,
+ .yres = 480,
+ .xres_virtual = 720,
+ .yres_virtual = 480,
+ .xoffset = 0,
+ .yoffset = 0,
+ .bits_per_pixel = 8,
+ .red = {.offset = 0, .length = 8, .msb_right = 0},
+ .green = {.offset = 0, .length = 8, .msb_right = 0},
+ .blue = {.offset = 0, .length = 8, .msb_right = 0},
+ .activate = FB_ACTIVATE_NOW,
+ .height = -1,
+ .width = -1,
+ .pixclock = 36101,
+ .left_margin = 24,
+ .right_margin = 96,
+ .upper_margin = 10,
+ .lower_margin = 32,
+ .hsync_len = 40,
+ .vsync_len = 3,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .screen_fix = {
+ .id = "Ambarella FB",
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_PSEUDOCOLOR,
+ .xpanstep = 1,
+ .ypanstep = 1,
+ .ywrapstep = 1,
+ .accel = FB_ACCEL_NONE,
+ .line_length = 0,
+ .smem_start = 0,
+ .smem_len = 0,
+ },
+ .dsp_status = AMBA_DSP_UNKNOWN_MODE,
+ .fb_status = AMBFB_UNKNOWN_MODE,
+ .color_format = AMBFB_COLOR_CLUT_8BPP,
+ .conversion_buf = {
+ .available = 0,
+ .ping_buf = NULL,
+ .ping_buf_size = 0,
+ .pong_buf = NULL,
+ .pong_buf_size = 0,
+ },
+ .use_prealloc = 0,
+ .prealloc_line_length = 0,
+
+ .pan_display = NULL,
+ .setcmap = NULL,
+ .check_var = NULL,
+ .set_par = NULL,
+ .set_blank = NULL,
+
+ .proc_fb_info = NULL,
+ .proc_file = NULL,
+};
+
+static struct ambarella_platform_fb ambarella_platform_fb1 = {
+ .screen_var = {
+ .xres = 720,
+ .yres = 480,
+ .xres_virtual = 720,
+ .yres_virtual = 480,
+ .xoffset = 0,
+ .yoffset = 0,
+ .bits_per_pixel = 8,
+ .red = {.offset = 0, .length = 8, .msb_right = 0},
+ .green = {.offset = 0, .length = 8, .msb_right = 0},
+ .blue = {.offset = 0, .length = 8, .msb_right = 0},
+ .activate = FB_ACTIVATE_NOW,
+ .height = -1,
+ .width = -1,
+ .pixclock = 36101,
+ .left_margin = 24,
+ .right_margin = 96,
+ .upper_margin = 10,
+ .lower_margin = 32,
+ .hsync_len = 40,
+ .vsync_len = 3,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .screen_fix = {
+ .id = "Ambarella FB",
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_PSEUDOCOLOR,
+ .xpanstep = 1,
+ .ypanstep = 1,
+ .ywrapstep = 1,
+ .accel = FB_ACCEL_NONE,
+ .line_length = 0,
+ .smem_start = 0,
+ .smem_len = 0,
+ },
+ .dsp_status = AMBA_DSP_UNKNOWN_MODE,
+ .fb_status = AMBFB_UNKNOWN_MODE,
+ .color_format = AMBFB_COLOR_CLUT_8BPP,
+ .conversion_buf = {
+ .available = 0,
+ .ping_buf = NULL,
+ .ping_buf_size = 0,
+ .pong_buf = NULL,
+ .pong_buf_size = 0,
+ },
+ .use_prealloc = 0,
+ .prealloc_line_length = 0,
+
+ .pan_display = NULL,
+ .setcmap = NULL,
+ .check_var = NULL,
+ .set_par = NULL,
+ .set_blank = NULL,
+
+ .proc_fb_info = NULL,
+ .proc_file = NULL,
+};
+
+struct ambarella_platform_fb *ambfb_data_ptr[] = {
+ &ambarella_platform_fb0,
+ &ambarella_platform_fb1,
+};
+EXPORT_SYMBOL(ambfb_data_ptr);
+
+int ambarella_fb_get_platform_info(u32 fb_id,
+ struct ambarella_platform_fb *platform_info)
+{
+ struct ambarella_platform_fb *ambfb_data;
+
+ if (fb_id > ARRAY_SIZE(ambfb_data_ptr))
+ return -EPERM;
+
+ ambfb_data = ambfb_data_ptr[fb_id];
+
+ mutex_lock(&ambfb_data->lock);
+ memcpy(platform_info, ambfb_data, sizeof(struct ambarella_platform_fb));
+ mutex_unlock(&ambfb_data->lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(ambarella_fb_get_platform_info);
+
+int ambarella_fb_set_iav_info(u32 fb_id, struct ambarella_fb_iav_info *iav)
+{
+ struct ambarella_platform_fb *ambfb_data;
+
+ if (fb_id > ARRAY_SIZE(ambfb_data_ptr))
+ return -EPERM;
+
+ ambfb_data = ambfb_data_ptr[fb_id];
+
+ mutex_lock(&ambfb_data->lock);
+ ambfb_data->screen_var = iav->screen_var;
+ ambfb_data->screen_fix = iav->screen_fix;
+ ambfb_data->pan_display = iav->pan_display;
+ ambfb_data->setcmap = iav->setcmap;
+ ambfb_data->check_var = iav->check_var;
+ ambfb_data->set_par = iav->set_par;
+ ambfb_data->set_blank = iav->set_blank;
+ ambfb_data->dsp_status = iav->dsp_status;
+ mutex_unlock(&ambfb_data->lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(ambarella_fb_set_iav_info);
+
+int __init ambarella_init_fb(void)
+{
+ struct ambarella_platform_fb *ambfb_data;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ambfb_data_ptr); i++) {
+ ambfb_data = ambfb_data_ptr[i];
+ mutex_init(&ambfb_data->lock);
+ init_waitqueue_head(&ambfb_data->proc_wait);
+ }
+
+ return 0;
+}
+
diff --git a/arch/arm/mach-ambarella/misc/ambsyncproc.c b/arch/arm/mach-ambarella/misc/ambsyncproc.c
new file mode 100644
index 00000000..3358e94f
--- /dev/null
+++ b/arch/arm/mach-ambarella/misc/ambsyncproc.c
@@ -0,0 +1,233 @@
+/*
+ * arch/arm/plat-ambarella/misc/sync_proc.c
+ *
+ * Author: Anthony Ginger, <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/idr.h>
+#include <linux/proc_fs.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/export.h>
+
+#include <asm/uaccess.h>
+#include <asm/page.h>
+#include <asm/atomic.h>
+
+#include <plat/ambsyncproc.h>
+
+int ambsync_proc_hinit(struct ambsync_proc_hinfo *hinfo)
+{
+ hinfo->maxid = AMBA_SYNC_PROC_MAX_ID;
+ init_waitqueue_head(&hinfo->sync_proc_head);
+ atomic_set(&hinfo->sync_proc_flag, 0);
+ idr_init(&hinfo->sync_proc_idr);
+ mutex_init(&hinfo->sync_proc_lock);
+ hinfo->sync_read_proc = NULL;
+
+ return 0;
+}
+EXPORT_SYMBOL(ambsync_proc_hinit);
+
+int ambsync_proc_open(struct inode *inode, struct file *file)
+{
+ int retval = 0;
+ struct ambsync_proc_pinfo *pinfo = file->private_data;
+ struct ambsync_proc_hinfo *hinfo;
+ int id;
+
+ hinfo = (struct ambsync_proc_hinfo *)PDE_DATA(inode);
+ if (!hinfo) {
+ retval = -EPERM;
+ goto ambsync_proc_open_exit;
+ }
+ if (hinfo->maxid > AMBA_SYNC_PROC_MAX_ID) {
+ retval = -EPERM;
+ goto ambsync_proc_open_exit;
+ }
+
+ if (pinfo) {
+ retval = -EPERM;
+ goto ambsync_proc_open_exit;
+ }
+ pinfo = kmalloc(sizeof(*pinfo), GFP_KERNEL);
+ if (!pinfo) {
+ retval = -ENOMEM;
+ goto ambsync_proc_open_exit;
+ }
+ memset(pinfo, 0, sizeof(*pinfo));
+
+ mutex_lock(&hinfo->sync_proc_lock);
+ id = idr_alloc(&hinfo->sync_proc_idr, pinfo, 0, 0, GFP_KERNEL);
+ mutex_unlock(&hinfo->sync_proc_lock);
+ if (id < 0) {
+ retval = id;
+ goto ambsync_proc_open_kfree_p;
+ }
+ if (id > 31) {
+ retval = -ENOMEM;
+ goto ambsync_proc_open_remove_id;
+ }
+
+ if (!(pinfo->page = (char*) __get_free_page(GFP_KERNEL))) {
+ retval = -ENOMEM;
+ goto ambsync_proc_open_remove_id;
+ }
+ pinfo->id = id;
+ pinfo->mask = (0x01 << id);
+
+ file->private_data = pinfo;
+ file->f_version = 0;
+ file->f_mode &= ~FMODE_PWRITE;
+
+ goto ambsync_proc_open_exit;
+
+ambsync_proc_open_remove_id:
+ mutex_lock(&hinfo->sync_proc_lock);
+ idr_remove(&hinfo->sync_proc_idr, id);
+ mutex_unlock(&hinfo->sync_proc_lock);
+
+ambsync_proc_open_kfree_p:
+ kfree(pinfo);
+
+ambsync_proc_open_exit:
+ return retval;
+}
+EXPORT_SYMBOL(ambsync_proc_open);
+
+int ambsync_proc_release(struct inode *inode, struct file *file)
+{
+ int retval = 0;
+ struct ambsync_proc_pinfo *pinfo = file->private_data;
+ struct ambsync_proc_hinfo *hinfo;
+
+ hinfo = (struct ambsync_proc_hinfo *)PDE_DATA(inode);
+ if (!hinfo) {
+ retval = -EPERM;
+ goto ambsync_proc_release_exit;
+ }
+
+ if (!pinfo) {
+ retval = -ENOMEM;
+ goto ambsync_proc_release_exit;
+ }
+
+ mutex_lock(&hinfo->sync_proc_lock);
+ idr_remove(&hinfo->sync_proc_idr, pinfo->id);
+ mutex_unlock(&hinfo->sync_proc_lock);
+
+ free_page((unsigned long)pinfo->page);
+ kfree(pinfo);
+ file->private_data = NULL;
+
+ambsync_proc_release_exit:
+ return retval;
+}
+EXPORT_SYMBOL(ambsync_proc_release);
+
+/* Note: ignore ppos*/
+ssize_t ambsync_proc_read(struct file *file, char __user *buf,
+ size_t size, loff_t *ppos)
+{
+ int retval = 0;
+ struct ambsync_proc_pinfo *pinfo = file->private_data;
+ struct ambsync_proc_hinfo *hinfo;
+ struct inode *inode = file->f_path.dentry->d_inode;
+ char *start;
+ int len;
+ size_t count;
+
+ hinfo = (struct ambsync_proc_hinfo *)PDE_DATA(inode);
+ if (!hinfo) {
+ retval = -EPERM;
+ goto ambsync_proc_read_exit;
+ }
+ if (!hinfo->sync_read_proc) {
+ retval = -EPERM;
+ goto ambsync_proc_read_exit;
+ }
+
+ if (!pinfo) {
+ retval = -ENOMEM;
+ goto ambsync_proc_read_exit;
+ }
+
+ count = min_t(size_t, AMBA_SYNC_PROC_PAGE_SIZE, size);
+ start = pinfo->page;
+ len = 0;
+ while (1) {
+ wait_event_interruptible_timeout(hinfo->sync_proc_head,
+ (atomic_read(&hinfo->sync_proc_flag) & pinfo->mask), hinfo->tmo);
+ atomic_clear_mask(pinfo->mask,
+ (unsigned long *)&hinfo->sync_proc_flag);
+
+ len = hinfo->sync_read_proc(start, hinfo->sync_read_data);
+ if (len < count) {
+ start += len;
+ count -= len;
+ } else if (len == count) {
+ start += len;
+ count -= len;
+ break;
+ } else {
+ break;
+ }
+ }
+ len = start - pinfo->page;
+ if (len == 0) {
+ retval = -EFAULT;
+ } else {
+ if (copy_to_user(buf, pinfo->page, len)) {
+ retval = -EFAULT;
+ } else {
+ retval = len;
+ }
+ }
+
+ambsync_proc_read_exit:
+ return retval;
+}
+EXPORT_SYMBOL(ambsync_proc_read);
+
+ssize_t ambsync_proc_write(struct file *file, const char __user *buf,
+ size_t size, loff_t *ppos)
+{
+ int retval = 0;
+ struct ambsync_proc_hinfo *hinfo;
+ struct inode *inode = file->f_path.dentry->d_inode;
+
+ hinfo = (struct ambsync_proc_hinfo *)PDE_DATA(inode);
+ if (!hinfo) {
+ retval = -EPERM;
+ goto ambsync_proc_write_exit;
+ }
+
+ atomic_set(&hinfo->sync_proc_flag, 0xFFFFFFFF);
+ wake_up_all(&hinfo->sync_proc_head);
+
+ retval = size;
+
+ambsync_proc_write_exit:
+ return retval;
+}
+EXPORT_SYMBOL(ambsync_proc_write);
diff --git a/arch/arm/mach-ambarella/misc/audio.c b/arch/arm/mach-ambarella/misc/audio.c
new file mode 100644
index 00000000..d9645ec8
--- /dev/null
+++ b/arch/arm/mach-ambarella/misc/audio.c
@@ -0,0 +1,105 @@
+/*
+ * arch/arm/plat-ambarella/generic/audio.c
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/export.h>
+#include <linux/notifier.h>
+#include <plat/audio.h>
+
+/* ==========================================================================*/
+static struct srcu_notifier_head audio_notifier_list;
+static struct notifier_block audio_notify;
+static struct ambarella_i2s_interface audio_i2s_intf;
+
+struct ambarella_i2s_interface get_audio_i2s_interface(void)
+{
+ return audio_i2s_intf;
+}
+EXPORT_SYMBOL(get_audio_i2s_interface);
+
+static int audio_notify_transition(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ switch(val) {
+ case AUDIO_NOTIFY_INIT:
+ audio_i2s_intf.state = AUDIO_NOTIFY_INIT;
+ memcpy(&audio_i2s_intf, data,
+ sizeof(struct ambarella_i2s_interface));
+ break;
+
+ case AUDIO_NOTIFY_SETHWPARAMS:
+ audio_i2s_intf.state = AUDIO_NOTIFY_SETHWPARAMS;
+ memcpy(&audio_i2s_intf, data,
+ sizeof(struct ambarella_i2s_interface));
+ break;
+
+ case AUDIO_NOTIFY_REMOVE:
+ memset(&audio_i2s_intf, 0,
+ sizeof(struct ambarella_i2s_interface));
+ audio_i2s_intf.state = AUDIO_NOTIFY_REMOVE;
+ break;
+ default:
+ audio_i2s_intf.state = AUDIO_NOTIFY_UNKNOWN;
+ break;
+ }
+
+ return 0;
+}
+
+void ambarella_audio_notify_transition (
+ struct ambarella_i2s_interface *data, unsigned int type)
+{
+ srcu_notifier_call_chain(&audio_notifier_list, type, data);
+}
+EXPORT_SYMBOL(ambarella_audio_notify_transition);
+
+int ambarella_audio_register_notifier(struct notifier_block *nb)
+{
+ return srcu_notifier_chain_register( &audio_notifier_list, nb);
+}
+EXPORT_SYMBOL(ambarella_audio_register_notifier);
+
+
+int ambarella_audio_unregister_notifier(struct notifier_block *nb)
+{
+ return srcu_notifier_chain_unregister(&audio_notifier_list, nb);
+}
+EXPORT_SYMBOL(ambarella_audio_unregister_notifier);
+
+
+int __init ambarella_init_audio(void)
+{
+ int retval = 0;
+
+ srcu_init_notifier_head(&audio_notifier_list);
+
+ memset(&audio_i2s_intf, 0, sizeof(struct ambarella_i2s_interface));
+ audio_i2s_intf.state = AUDIO_NOTIFY_UNKNOWN;
+
+ audio_notify.notifier_call = audio_notify_transition;
+ retval = ambarella_audio_register_notifier(&audio_notify);
+
+ return retval;
+}
+
diff --git a/arch/arm/mach-ambarella/misc/event.c b/arch/arm/mach-ambarella/misc/event.c
new file mode 100644
index 00000000..e986ca43
--- /dev/null
+++ b/arch/arm/mach-ambarella/misc/event.c
@@ -0,0 +1,73 @@
+/*
+ * arch/arm/plat-ambarella/misc/event.c
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/export.h>
+
+#include <mach/hardware.h>
+#include <plat/event.h>
+
+/* ==========================================================================*/
+static BLOCKING_NOTIFIER_HEAD(blocking_event_list);
+static RAW_NOTIFIER_HEAD(raw_event_list);
+
+/* ==========================================================================*/
+int ambarella_register_event_notifier(void *nb)
+{
+ return blocking_notifier_chain_register(&blocking_event_list, nb);
+}
+EXPORT_SYMBOL(ambarella_register_event_notifier);
+
+int ambarella_unregister_event_notifier(void *nb)
+{
+ return blocking_notifier_chain_unregister(&blocking_event_list, nb);
+}
+EXPORT_SYMBOL(ambarella_unregister_event_notifier);
+
+int ambarella_set_event(unsigned long val, void *v)
+{
+ return blocking_notifier_call_chain(&blocking_event_list, val, v);
+}
+EXPORT_SYMBOL(ambarella_set_event);
+
+int ambarella_register_raw_event_notifier(void *nb)
+{
+ return raw_notifier_chain_register(&raw_event_list, nb);
+}
+EXPORT_SYMBOL(ambarella_register_raw_event_notifier);
+
+int ambarella_unregister_raw_event_notifier(void *nb)
+{
+ return raw_notifier_chain_unregister(&raw_event_list, nb);
+}
+EXPORT_SYMBOL(ambarella_unregister_raw_event_notifier);
+
+int ambarella_set_raw_event(unsigned long val, void *v)
+{
+ return raw_notifier_call_chain(&raw_event_list, val, v);
+}
+EXPORT_SYMBOL(ambarella_set_raw_event);
+
diff --git a/arch/arm/mach-ambarella/misc/gdma.c b/arch/arm/mach-ambarella/misc/gdma.c
new file mode 100644
index 00000000..81c0bc67
--- /dev/null
+++ b/arch/arm/mach-ambarella/misc/gdma.c
@@ -0,0 +1,348 @@
+/*
+ * arch/arm/plat-ambarella/generic/gdma.c
+ *
+ * Author: Louis Sun <lysun@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <mach/hardware.h>
+#include <mach/init.h>
+#include <plat/iav_helper.h>
+#include <plat/gdma.h>
+
+#define TRANSFER_2D_WIDTH (1 << 12 ) /* 4096 */
+#define MAX_TRANSFER_2D_HEIGHT (1 << 11 ) /* 2048 */
+#define MAX_TRANSFER_SIZE_2D_UNIT (TRANSFER_2D_WIDTH * MAX_TRANSFER_2D_HEIGHT) /* 8MB */
+
+#define TRANSFER_1D_WIDTH TRANSFER_2D_WIDTH
+#define MAX_TRANSFER_SIZE_1D_UNIT TRANSFER_1D_WIDTH
+
+/* transfer 6 big blocks (although maximum is 8), because we may do another 1 small block and 1 line. total 8 Ops */
+#define MAX_TRANSFER_SIZE_ONCE (MAX_TRANSFER_SIZE_2D_UNIT * 6) /* 48 MB */
+#define MAX_OPS 8
+
+static struct completion transfer_completion;
+static struct mutex transfer_mutex;
+
+
+/* handle 8MB at one time */
+static inline int transfer_big_unit(u8 *dest_addr, u8 *src_addr, u32 size)
+{
+ int row_count;
+ if (size > MAX_TRANSFER_SIZE_2D_UNIT) {
+ printk("transfer_unit size %d bigger than %d \n",
+ size, MAX_TRANSFER_SIZE_2D_UNIT);
+ return -1;
+ }
+
+ row_count = size / TRANSFER_2D_WIDTH;
+
+ /* copy rows by 2D copy */
+ if (row_count > 0) {
+ amba_writel(GDMA_SRC_1_BASE_REG, (long)src_addr);
+ amba_writel(GDMA_SRC_1_PITCH_REG, TRANSFER_2D_WIDTH);
+ amba_writel(GDMA_DST_BASE_REG, (long)dest_addr);
+ amba_writel(GDMA_DST_PITCH_REG, TRANSFER_2D_WIDTH);
+ amba_writel(GDMA_WIDTH_REG, TRANSFER_2D_WIDTH - 1);
+ amba_writel(GDMA_HEIGHT_REG, row_count - 1);
+#if (GDMA_SUPPORT_ALPHA_BLEND == 1)
+ amba_writel(GDMA_PIXELFORMAT_REG, 0x800);
+ amba_writel(GDMA_ALPHA_REG, 0);
+ amba_writel(GDMA_CLUT_BASE_REG, 0);
+#endif
+
+ /* start 2D copy */
+ amba_writel(GDMA_OPCODE_REG, 1);
+ }
+ return 0;
+
+}
+
+/* use 1D copy to copy max 4KB each time */
+static inline int transfer_small_unit(u8 *dest_addr, u8 *src_addr, u32 size)
+{
+ if (size > TRANSFER_1D_WIDTH) {
+ printk("transfer_unit size %d bigger than %d \n",
+ size, TRANSFER_1D_WIDTH);
+ return -1;
+ }
+
+ /* linear copy */
+ amba_writel(GDMA_SRC_1_BASE_REG, (long)src_addr);
+ amba_writel(GDMA_DST_BASE_REG, (long)dest_addr);
+ amba_writel(GDMA_WIDTH_REG, size - 1);
+#if (GDMA_SUPPORT_ALPHA_BLEND == 1)
+ amba_writel(GDMA_PIXELFORMAT_REG, 0x800);
+ amba_writel(GDMA_ALPHA_REG, 0);
+ amba_writel(GDMA_CLUT_BASE_REG, 0);
+#endif
+
+ /* start linear copy */
+ amba_writel(GDMA_OPCODE_REG, 0);
+
+ return 0;
+}
+
+
+
+/* this is async function, just fill dma registers and let it run*/
+static inline int transfer_once(u8 *dest_addr, u8 *src_addr, u32 size)
+{
+ //total pending count must be no bigger than 8
+ int big_count;
+ int rows_count;
+ int i;
+ u32 transferred_bytes = 0;
+ int remain_bytes ;
+
+ if (size > MAX_TRANSFER_SIZE_ONCE) {
+ printk(" size too big %d for transfer once \n", size);
+ return -1;
+ }
+
+ big_count = size/MAX_TRANSFER_SIZE_2D_UNIT;
+ //big pages (each is 8MB)
+ for (i = big_count ; i > 0; i--) {
+ transfer_big_unit(dest_addr + transferred_bytes,
+ src_addr + transferred_bytes,
+ MAX_TRANSFER_SIZE_2D_UNIT);
+ transferred_bytes += MAX_TRANSFER_SIZE_2D_UNIT;
+ }
+ remain_bytes = size - transferred_bytes;
+
+
+ //transfer rows (align to TRANSFER_2D_WIDTH)
+ rows_count = remain_bytes / TRANSFER_2D_WIDTH;
+ if (rows_count > 0) {
+ transfer_big_unit(dest_addr + transferred_bytes,
+ src_addr + transferred_bytes,
+ TRANSFER_2D_WIDTH * rows_count);
+ transferred_bytes += TRANSFER_2D_WIDTH * rows_count;
+ remain_bytes = size - transferred_bytes;
+ }
+
+ if (remain_bytes > 0) {
+ transfer_small_unit(dest_addr + transferred_bytes,
+ src_addr + transferred_bytes, remain_bytes);
+ }
+
+ return 0;
+}
+
+/* this is synchronous function, will wait till transfer finishes */
+int dma_memcpy(u8 *dest_addr, u8 *src_addr, u32 size)
+{
+ int remain_size = size;
+ int transferred_size = 0;
+ int current_transfer_size;
+
+ if (size <= 0) {
+ return -1;
+ }
+
+#if (GDMA_SUPPORT_ALPHA_BLEND == 1)
+ if (size & 0x1) {
+ printk("Size must be even !\n");
+ return -1;
+ }
+#endif
+
+ mutex_lock(&transfer_mutex);
+
+ ambcache_clean_range((void *)ambarella_phys_to_virt((u32)src_addr), size);
+
+ while (remain_size > 0) {
+ if (remain_size > MAX_TRANSFER_SIZE_ONCE) {
+ remain_size -= MAX_TRANSFER_SIZE_ONCE;
+ current_transfer_size = MAX_TRANSFER_SIZE_ONCE;
+ } else {
+ current_transfer_size = remain_size;
+ remain_size = 0;
+ }
+
+ transfer_once(dest_addr + transferred_size,
+ src_addr + transferred_size, current_transfer_size);
+ wait_for_completion(&transfer_completion);
+ transferred_size += current_transfer_size;
+ }
+
+ ambcache_inv_range((void *)ambarella_phys_to_virt((u32)dest_addr), size);
+
+ mutex_unlock(&transfer_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL(dma_memcpy);
+
+static inline int transfer_pitch_unit(u8 *dest_addr, u8 *src_addr,u16 src_pitch, u16 dest_pitch, u16 width, u16 height)
+{
+
+ if (height <= 0) {
+ return -1;
+ }
+
+ /* copy rows by 2D copy */
+ while (height > MAX_TRANSFER_2D_HEIGHT) {
+ amba_writel(GDMA_SRC_1_BASE_REG, (long)src_addr);
+ amba_writel(GDMA_SRC_1_PITCH_REG, src_pitch);
+ amba_writel(GDMA_DST_BASE_REG, (long)dest_addr);
+ amba_writel(GDMA_DST_PITCH_REG, dest_pitch);
+ amba_writel(GDMA_WIDTH_REG, width - 1);
+ amba_writel(GDMA_HEIGHT_REG, MAX_TRANSFER_2D_HEIGHT - 1);
+#if (GDMA_SUPPORT_ALPHA_BLEND == 1)
+ amba_writel(GDMA_PIXELFORMAT_REG, 0x800);
+ amba_writel(GDMA_ALPHA_REG, 0);
+ amba_writel(GDMA_CLUT_BASE_REG, 0);
+#endif
+
+ /* start 2D copy */
+ amba_writel(GDMA_OPCODE_REG, 1);
+ height = height - MAX_TRANSFER_2D_HEIGHT;
+ src_addr = src_addr + src_pitch * MAX_TRANSFER_2D_HEIGHT;
+ dest_addr = dest_addr + dest_pitch * MAX_TRANSFER_2D_HEIGHT;
+ }
+
+ amba_writel(GDMA_SRC_1_BASE_REG, (long)src_addr);
+ amba_writel(GDMA_SRC_1_PITCH_REG, src_pitch);
+ amba_writel(GDMA_DST_BASE_REG, (long)dest_addr);
+ amba_writel(GDMA_DST_PITCH_REG, dest_pitch);
+ amba_writel(GDMA_WIDTH_REG, width - 1);
+ amba_writel(GDMA_HEIGHT_REG, height - 1);
+#if (GDMA_SUPPORT_ALPHA_BLEND == 1)
+ amba_writel(GDMA_PIXELFORMAT_REG, 0x800);
+ amba_writel(GDMA_ALPHA_REG, 0);
+ amba_writel(GDMA_CLUT_BASE_REG, 0);
+#endif
+
+ /* start 2D copy */
+ amba_writel(GDMA_OPCODE_REG, 1);
+
+ return 0;
+
+}
+
+/* this is synchronous function, will wait till transfer finishes width =< 4096 */
+int dma_pitch_memcpy(struct gdma_param *params)
+{
+ int size = params->src_pitch * params->height;
+
+ if (size <= 0 || params->src_pitch <= 0 || params->dest_pitch <= 0
+ || params->width > TRANSFER_2D_WIDTH) {
+ printk(" invalid value \n");
+ return -1;
+ }
+
+#if (GDMA_SUPPORT_ALPHA_BLEND == 1)
+ if (size & 0x1) {
+ printk("Size must be even !\n");
+ return -1;
+ }
+#endif
+
+ mutex_lock(&transfer_mutex);
+ if (!params->src_non_cached) {
+ ambcache_clean_range((void *)params->src_virt_addr, size);
+ }
+ transfer_pitch_unit((u8 *)params->dest_addr, (u8 *)params->src_addr,
+ params->src_pitch, params->dest_pitch, params->width, params->height);
+
+ wait_for_completion(&transfer_completion);
+
+ if (!params->dest_non_cached) {
+ ambcache_inv_range((void *)params->dest_virt_addr, size);
+ }
+ mutex_unlock(&transfer_mutex);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(dma_pitch_memcpy);
+
+static irqreturn_t gdma_interrupt(int irq, void *dev_id)
+{
+ int pending_ops;
+ pending_ops = amba_readl(GDMA_PENDING_OPS_REG);
+
+ if (pending_ops == 0) {
+ /* if no following transfer */
+ complete(&transfer_completion);
+ } else {
+
+ }
+ return IRQ_HANDLED;
+}
+
+static int hw_init(void)
+{
+ int errorCode;
+ /* request irq, no device id, no irq sharing */
+ errorCode = request_irq(GDMA_IRQ, gdma_interrupt,
+ IRQF_TRIGGER_RISING, "gdma", 0);
+
+ if (errorCode) {
+ printk("gdma irq request failed \n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/* wait till transmit completes */
+static void wait_transmit_complete(void)
+{
+ int pending_ops;
+ pending_ops = amba_readl(GDMA_PENDING_OPS_REG);
+
+ while(pending_ops!= 0) {
+ mdelay(10);
+ }
+}
+
+static int __init gdma_init(void)
+{
+ /* hardware and irq init */
+ if (hw_init() != 0)
+ return -1;
+ /* init completion */
+ init_completion(&transfer_completion);
+ mutex_init(&transfer_mutex);
+
+ return 0;
+}
+
+static void __exit gdma_exit(void)
+{
+ wait_transmit_complete();
+}
+
+MODULE_AUTHOR("Louis Sun <lysun@ambarella.com>");
+MODULE_DESCRIPTION("GDMA driver on Ambarella A5S / S2");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("1.0");
+
+module_init(gdma_init);
+module_exit(gdma_exit);
+
diff --git a/arch/arm/mach-ambarella/misc/highres_timer.c b/arch/arm/mach-ambarella/misc/highres_timer.c
new file mode 100644
index 00000000..2225d61e
--- /dev/null
+++ b/arch/arm/mach-ambarella/misc/highres_timer.c
@@ -0,0 +1,51 @@
+/*
+ * arch/arm/plat-ambarella/misc/highres_timer.c
+ *
+ * Author: Louis Sun <lysun@ambarella.com>
+ *
+ * Copyright (C) 2004-2011, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/hrtimer.h>
+#include <linux/ktime.h>
+
+int highres_timer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode)
+{
+ return hrtimer_start(timer, tim, mode);
+}
+EXPORT_SYMBOL(highres_timer_start);
+
+void highres_timer_init(struct hrtimer *timer, clockid_t clock_id, enum hrtimer_mode mode)
+{
+ hrtimer_init(timer, clock_id, mode);
+}
+EXPORT_SYMBOL(highres_timer_init);
+
+int highres_timer_cancel(struct hrtimer *timer)
+{
+ return hrtimer_cancel(timer);
+}
+EXPORT_SYMBOL(highres_timer_cancel);
+
+MODULE_AUTHOR("Louis Sun <lysun@ambarella.com>");
+MODULE_DESCRIPTION("high resolution timer wrapper");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("1.0");
+
diff --git a/arch/arm/mach-ambarella/misc/hwlock.c b/arch/arm/mach-ambarella/misc/hwlock.c
new file mode 100644
index 00000000..21824f2d
--- /dev/null
+++ b/arch/arm/mach-ambarella/misc/hwlock.c
@@ -0,0 +1,35 @@
+/*
+ * arch/arm/plat-ambarella/generic/reglock.c
+ *
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+
+/* ==========================================================================*/
+DEFINE_SPINLOCK(ambarella_global_hw_lock);
+unsigned long ambarella_global_hw_flags;
+
+/* ==========================================================================*/
+EXPORT_SYMBOL(ambarella_global_hw_lock);
+EXPORT_SYMBOL(ambarella_global_hw_flags);
+
diff --git a/arch/arm/mach-ambarella/misc/iav_helper.c b/arch/arm/mach-ambarella/misc/iav_helper.c
new file mode 100644
index 00000000..09d9bbc4
--- /dev/null
+++ b/arch/arm/mach-ambarella/misc/iav_helper.c
@@ -0,0 +1,110 @@
+/*
+ * arch/arm/plat-ambarella/misc/service.c
+ *
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * Copyright (C) 2012-2016, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <plat/iav_helper.h>
+#include <mach/init.h>
+#include <asm/cacheflush.h>
+
+
+/*===========================================================================*/
+
+static LIST_HEAD(ambarella_svc_list);
+
+int ambarella_register_service(struct ambarella_service *amb_svc)
+{
+ struct ambarella_service *svc;
+
+ if (!amb_svc || !amb_svc->func)
+ return -EINVAL;
+
+ list_for_each_entry(svc, &ambarella_svc_list, node) {
+ if (svc->service == amb_svc->service) {
+ pr_err("%s: service (%d) is already existed\n",
+ __func__, amb_svc->service);
+ return -EEXIST;
+ }
+ }
+
+ list_add_tail(&amb_svc->node, &ambarella_svc_list);
+
+ return 0;
+}
+EXPORT_SYMBOL(ambarella_register_service);
+
+int ambarella_unregister_service(struct ambarella_service *amb_svc)
+{
+ struct ambarella_service *svc;
+
+ if (!amb_svc)
+ return -EINVAL;
+
+ list_for_each_entry(svc, &ambarella_svc_list, node) {
+ if (svc->service == amb_svc->service) {
+ list_del(&svc->node);
+ break;
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(ambarella_unregister_service);
+
+int ambarella_request_service(int service, void *arg, void *result)
+{
+ struct ambarella_service *svc;
+ int found = 0;
+
+ list_for_each_entry(svc, &ambarella_svc_list, node) {
+ if (svc->service == service) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found == 0) {
+ pr_err("%s: no such service (%d)\n", __func__, service);
+ return -ENODEV;
+ }
+
+ return svc->func(arg, result);
+}
+EXPORT_SYMBOL(ambarella_request_service);
+
+/*===========================================================================*/
+
+void ambcache_clean_range(void *addr, unsigned int size)
+{
+ __sync_cache_range_w(addr, size);
+}
+EXPORT_SYMBOL(ambcache_clean_range);
+
+void ambcache_inv_range(void *addr, unsigned int size)
+{
+ __sync_cache_range_r(addr, size);
+}
+
+EXPORT_SYMBOL(ambcache_inv_range);
+
+
diff --git a/arch/arm/mach-ambarella/misc/pmu.c b/arch/arm/mach-ambarella/misc/pmu.c
new file mode 100644
index 00000000..341b4409
--- /dev/null
+++ b/arch/arm/mach-ambarella/misc/pmu.c
@@ -0,0 +1,76 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/pmu.h>
+
+#include <plat/irq.h>
+
+/* ==========================================================================*/
+#if defined(CONFIG_AMBARELLA_PMUSERENR_EN)
+static void pmu_set_userspace_access(void *en)
+{
+ int val = 0;
+ /* Read PMUSERENR Register */
+ asm volatile("mrc p15, 0, %0, c9, c14, 0" : : "r" (val));
+ val &= ~0x1;
+ val |= (int)en;
+ /* Write PMUSERENR Register */
+ asm volatile("mcr p15, 0, %0, c9, c14, 0" : : "r" (val));
+}
+#endif
+
+/* ==========================================================================*/
+#if defined(PMU_IRQ)
+/*
+ * PMU Interrupt is not connected to A5S/A7L/A8/S2,
+ * the counters are still available, and some profiling tools,
+ * such as 'perf' can live with that and collect statistics.
+ *
+ * So we provide PMU_IRQ setup here for all chips.
+ */
+static struct resource ambarella_pmu_resource[] = {
+ DEFINE_RES_IRQ(PMU_IRQ)
+};
+
+static struct platform_device ambarella_pmu = {
+ .name = "arm-pmu",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ambarella_pmu_resource),
+ .resource = ambarella_pmu_resource,
+};
+#endif
+
+/* ==========================================================================*/
+static int __init ambarella_pmu_init(void)
+{
+ int ret_val = 0;
+#if defined(PMU_IRQ)
+ ret_val = platform_device_register(&ambarella_pmu);
+#endif
+#if defined(CONFIG_AMBARELLA_PMUSERENR_EN)
+ pr_info("Enable PMUSERENR on all cores ... ");
+ ret_val = on_each_cpu(pmu_set_userspace_access, (void*)1, 1);
+ pr_info("done\n");
+#endif
+ return ret_val;
+}
+arch_initcall(ambarella_pmu_init);
+
diff --git a/arch/arm/mach-ambarella/pm.c b/arch/arm/mach-ambarella/pm.c
new file mode 100644
index 00000000..13c22ddd
--- /dev/null
+++ b/arch/arm/mach-ambarella/pm.c
@@ -0,0 +1,347 @@
+/*
+ * arch/arm/plat-ambarella/generic/pm.c
+ * Power Management Routines
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/suspend.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/cpu.h>
+#include <linux/power_supply.h>
+#include <linux/of.h>
+#include <asm/cacheflush.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/suspend.h>
+#include <mach/hardware.h>
+#include <mach/init.h>
+#include <plat/drctl.h>
+#include <plat/rtc.h>
+#include <plat/fio.h>
+
+#define SREF_MAGIC_PATTERN 0x43525230
+#define SREF_CPU_JUMP_ADDR 0x000f1000
+
+static int dram_reset_ctrl = -1;
+static int gpio_notify_mcu = -1;
+static int hibernate_gpio_notify_mcu = -1;
+extern int ambarella_suspend_trigger_signal[];
+
+u32 gpio_regbase[] = {GPIO0_BASE, GPIO1_BASE, GPIO2_BASE, GPIO3_BASE,
+ GPIO4_BASE, GPIO5_BASE, GPIO6_BASE};
+
+static unsigned long ambarella_gpio_setup(int);
+/* ==========================================================================*/
+void ambarella_pm_gpiomux(int gpio)
+{
+ u32 bank, offset;
+
+ bank = PINID_TO_BANK(gpio);
+ offset = PINID_TO_OFFSET(gpio);
+
+#if (IOMUX_SUPPORT > 0)
+ /* configure the pin as GPIO mode */
+ amba_clrbitsl(IOMUX_REG(IOMUX_REG_OFFSET(bank, 0)), 0x1 << offset);
+ amba_clrbitsl(IOMUX_REG(IOMUX_REG_OFFSET(bank, 1)), 0x1 << offset);
+ amba_clrbitsl(IOMUX_REG(IOMUX_REG_OFFSET(bank, 2)), 0x1 << offset);
+ amba_writel(IOMUX_REG(IOMUX_CTRL_SET_OFFSET), 0x1);
+ amba_writel(IOMUX_REG(IOMUX_CTRL_SET_OFFSET), 0x0);
+#endif
+
+}
+void ambarella_pm_gpio_output(int gpio, int value)
+{
+ u32 bank, offset;
+
+ bank = PINID_TO_BANK(gpio);
+ offset = PINID_TO_OFFSET(gpio);
+
+ amba_writel(gpio_regbase[bank] + GPIO_ENABLE_OFFSET, 0xffffffff);
+ amba_clrbitsl(gpio_regbase[bank] + GPIO_AFSEL_OFFSET, 0x1 << offset);
+ amba_setbitsl(gpio_regbase[bank] + GPIO_MASK_OFFSET, 0x1 << offset);
+ amba_setbitsl(gpio_regbase[bank] + GPIO_DIR_OFFSET, 0x1 << offset);
+
+ if (!!value)
+ amba_setbitsl(gpio_regbase[bank] + GPIO_DATA_OFFSET, 0x1 << offset);
+ else
+ amba_clrbitsl(gpio_regbase[bank] + GPIO_DATA_OFFSET, 0x1 << offset);
+}
+
+void ambarella_pm_gpio_input(int gpio, int *value)
+{
+ u32 bank, offset;
+
+ bank = PINID_TO_BANK(gpio);
+ offset = PINID_TO_OFFSET(gpio);
+
+ amba_writel(gpio_regbase[bank] + GPIO_ENABLE_OFFSET, 0xffffffff);
+ amba_clrbitsl(gpio_regbase[bank] + GPIO_AFSEL_OFFSET, 0x1 << offset);
+ amba_setbitsl(gpio_regbase[bank] + GPIO_MASK_OFFSET, 0x1 << offset);
+ amba_clrbitsl(gpio_regbase[bank] + GPIO_DIR_OFFSET, 0x1 << offset);
+
+ *value = !!(amba_readl(gpio_regbase[bank] + GPIO_DATA_OFFSET) & 0x1 << offset);
+}
+
+/* ==========================================================================*/
+void ambarella_power_off(void)
+{
+ if (!ambarella_gpio_setup(hibernate_gpio_notify_mcu))
+ return;
+
+ ambarella_pm_gpio_output(hibernate_gpio_notify_mcu, 1);
+ mdelay(100);
+ ambarella_pm_gpio_output(hibernate_gpio_notify_mcu, 0);
+
+ amba_rct_setbitsl(ANA_PWR_REG, ANA_PWR_POWER_DOWN);
+}
+
+void ambarella_power_off_prepare(void)
+{
+
+}
+
+/* ==========================================================================*/
+static void ambarella_disconnect_dram_reset(void)
+{
+
+ if (dram_reset_ctrl == -1)
+ return;
+
+ ambarella_pm_gpiomux(dram_reset_ctrl);
+
+ ambarella_pm_gpio_output(dram_reset_ctrl, 0);
+}
+
+static unsigned long ambarella_gpio_setup(int gpio)
+{
+ unsigned long gpio_info;
+ u32 bank, offset;
+
+ if (gpio == -1)
+ return 0;
+
+ bank = PINID_TO_BANK(gpio);
+ offset = PINID_TO_OFFSET(gpio);
+
+ gpio_info = gpio_regbase[bank] | offset;
+
+ /* Mux GPIO output mode */
+ ambarella_pm_gpio_output(gpio, !ambarella_suspend_trigger_signal[0]);
+ ambarella_pm_gpiomux(gpio);
+
+ return gpio_info;
+}
+
+static void ambarella_set_cpu_jump(int cpu, void *jump_fn)
+{
+ u32 addr_phys;
+ u32 *addr_virt;
+
+ /* must keep consistent with self_refresh.c in bst. */
+ addr_phys = get_ambarella_ppm_phys() + SREF_CPU_JUMP_ADDR;
+ addr_virt = (u32 *)ambarella_phys_to_virt(addr_phys);
+ *addr_virt++ = SREF_MAGIC_PATTERN;
+ *addr_virt = virt_to_phys(jump_fn);
+
+ __cpuc_flush_dcache_area(addr_virt, sizeof(u32) * 2);
+ outer_clean_range(addr_phys, addr_phys + sizeof(u32) * 2);
+}
+
+static int ambarella_cpu_do_idle(unsigned long unused)
+{
+ cpu_do_idle();
+ return 0;
+}
+
+static int ambarella_pm_enter_standby(void)
+{
+ cpu_suspend(0, ambarella_cpu_do_idle);
+ return 0;
+}
+
+static void ambarella_pm_rtc_flush(void)
+{
+ unsigned int alarm;
+ unsigned int time;
+
+ alarm = amba_readl(RTC_REG(RTC_ALAT_OFFSET));
+ amba_writel(RTC_REG(RTC_PWC_ALAT_OFFSET), alarm);
+ time = amba_readl(RTC_REG(RTC_CURT_OFFSET));
+ amba_writel(RTC_REG(RTC_PWC_CURT_OFFSET), time);
+}
+
+static unsigned long ambarella_pm_pwc_trigger(void)
+{
+ /* ensure the power for DRAM keeps on when power off PWC */
+ amba_writel(RTC_REG(RTC_PWC_ENP3_OFFSET), 0x1);
+ amba_writel(RTC_REG(RTC_POS0_OFFSET), 0x10);
+ amba_writel(RTC_REG(RTC_POS1_OFFSET), 0x10);
+ amba_writel(RTC_REG(RTC_POS2_OFFSET), 0x10);
+ amba_writel(RTC_REG(RTC_POS3_OFFSET), 0x10);
+ amba_setbitsl(RTC_REG(RTC_PWC_SET_STATUS_OFFSET), 0x04);
+
+ ambarella_pm_rtc_flush();
+
+ amba_writel(RTC_REG(RTC_RESET_OFFSET), 0x1);
+ mdelay(3);
+ amba_writel(RTC_REG(RTC_RESET_OFFSET), 0x0);
+
+ return 0;
+}
+static void ambarella_pm_pwc_resume(void)
+{
+ /* ensure to power off all powers when power off PWC */
+ amba_writel(RTC_REG(RTC_PWC_ENP3_OFFSET), 0x0);
+ amba_clrbitsl(RTC_REG(RTC_PWC_SET_STATUS_OFFSET), 0x04);
+
+ ambarella_pm_rtc_flush();
+
+ amba_writel(RTC_REG(RTC_RESET_OFFSET), 0x1);
+ while(amba_readl(RTC_REG(RTC_PWC_REG_STA_OFFSET)) & 0x04);
+ amba_writel(RTC_REG(RTC_RESET_OFFSET), 0x0);
+
+}
+
+static unsigned long ambarella_pm_io_trigger(void)
+{
+ /* FIXME: flush internel rtc on chips, even though it is disabled. Because
+ * it has no unexpected effect on system */
+ ambarella_pm_rtc_flush();
+
+ return ambarella_gpio_setup(gpio_notify_mcu);
+}
+
+static void ambarella_pm_io_resume(void)
+{
+ ambarella_pm_rtc_flush();
+}
+
+static int ambarella_pm_enter_mem(void)
+{
+ unsigned long arg = 0;
+#ifdef CONFIG_AMBARELLA_SREF_FIFO_EXEC
+ void *ambarella_suspend_exec = NULL;
+#endif
+
+ ambarella_disconnect_dram_reset();
+
+ if (gpio_notify_mcu == -1)
+ arg = ambarella_pm_pwc_trigger();
+ else
+ arg = ambarella_pm_io_trigger();
+
+ ambarella_set_cpu_jump(0, ambarella_cpu_resume);
+
+#ifdef CONFIG_AMBARELLA_SREF_FIFO_EXEC
+ ambarella_suspend_exec = ambarella_fio_push(ambarella_optimize_suspend,
+ ambarella_optimize_suspend_sz);
+#endif
+ outer_flush_all();
+ outer_disable();
+
+#ifdef CONFIG_AMBARELLA_SREF_FIFO_EXEC
+ cpu_suspend(arg, ambarella_suspend_exec);
+#else
+ cpu_suspend(0, ambarella_finish_suspend);
+#endif
+
+ outer_resume();
+
+ if (gpio_notify_mcu == -1)
+ ambarella_pm_pwc_resume();
+ else
+ ambarella_pm_io_resume();
+
+ return 0;
+}
+
+static int ambarella_pm_suspend_enter(suspend_state_t state)
+{
+ int rval = 0;
+
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ rval = ambarella_pm_enter_standby();
+ break;
+ case PM_SUSPEND_MEM:
+ rval = ambarella_pm_enter_mem();
+ break;
+ case PM_SUSPEND_ON:
+ default:
+ break;
+ }
+
+ return rval;
+}
+
+static int ambarella_pm_suspend_valid(suspend_state_t state)
+{
+ int valid;
+
+ switch (state) {
+ case PM_SUSPEND_ON:
+ case PM_SUSPEND_STANDBY:
+ case PM_SUSPEND_MEM:
+ valid = 1;
+ break;
+ default:
+ valid = 0;
+ break;
+ }
+
+ pr_debug("%s: state[%d]=%d\n", __func__, state, valid);
+
+ return valid;
+}
+
+static struct platform_suspend_ops ambarella_pm_suspend_ops = {
+ .valid = ambarella_pm_suspend_valid,
+ .enter = ambarella_pm_suspend_enter,
+};
+
+/* ==========================================================================*/
+int __init ambarella_init_pm(void)
+{
+ pm_power_off = ambarella_power_off;
+ pm_power_off_prepare = ambarella_power_off_prepare;
+
+ suspend_set_ops(&ambarella_pm_suspend_ops);
+
+ of_property_read_u32(of_chosen, "ambarella,dram-reset-ctrl", &dram_reset_ctrl);
+ of_property_read_u32(of_chosen, "ambarella,gpio-notify-mcu", &gpio_notify_mcu);
+ of_property_read_u32(of_chosen, "ambarella,hibernate-gpio-notify-mcu", &hibernate_gpio_notify_mcu);
+ ambarella_suspend_trigger_signal[0] = !!of_find_property(of_chosen,
+ "ambarella,gpio-trigger-high", NULL);
+
+ WARN(dram_reset_ctrl >= GPIO_MAX_LINES, "Invalid DRAM RESET GPIO: %d\n", dram_reset_ctrl);
+ WARN(gpio_notify_mcu >= GPIO_MAX_LINES, "Invalid MCU NOTIFY GPIO: %d\n", gpio_notify_mcu);
+
+ pr_info("Ambarella power management: Wed Aug 10 2016 %s\n",
+ (gpio_notify_mcu == -1) ? "": ambarella_suspend_trigger_signal[0] ? "[positive edge]":"[negative edge]");
+
+ return 0;
+}
+
diff --git a/arch/arm/mach-ambarella/sleep.S b/arch/arm/mach-ambarella/sleep.S
new file mode 100644
index 00000000..b799c780
--- /dev/null
+++ b/arch/arm/mach-ambarella/sleep.S
@@ -0,0 +1,207 @@
+/*
+ * arch/arm/mach-ambarella/sleep.S
+ *
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * Copyright (C) 2014-2016, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/cache.h>
+#include <mach/hardware.h>
+#include <plat/drctl.h>
+#include <plat/rct.h>
+#include <plat/uart.h>
+
+ .text
+
+ENTRY(ambarella_finish_suspend)
+ isb
+ dsb
+ mov r0, #0
+ ldr r1, =(DRAMC_BASE + DRAM_DDRC_OFFSET)
+ ldr r2, =ANA_PWR_REG
+
+ teq r0, r0
+ bl _ambarella_finish_suspend
+ teq pc, r0
+ bl _ambarella_finish_suspend
+
+ENDPROC(ambarella_finish_suspend)
+
+ /* _ambarella_finish_suspend will be called twice. first is to makesure the
+ * instructions loading in the I-Cache, and the second is to disconnect cpu
+ * with dram, enter self refresh, and power down PWC.
+ */
+ENTRY(_ambarella_finish_suspend)
+ ldrne r3, [r1, #DDRC_CTL_OFFSET]
+ bicne r3, r3, #0x1
+ strne r3, [r1, #DDRC_CTL_OFFSET]
+ movne r3, #0x80000000
+ strne r3, [r1, #DDRC_SELF_REF_OFFSET]
+
+ movne r3, #ANA_PWR_POWER_DOWN
+ strne r3, [r2]
+ moveq pc, lr
+ b .
+
+ENDPROC(_ambarella_finish_suspend)
+
+ENTRY(ambarella_optimize_suspend)
+ dsb
+ isb
+
+ mov r1, #0
+ cmp r0, r1
+ beq suspend_with_pwc
+
+ mov r1, r0
+ mov r2, #0x1f
+ bic r0, r2 /* r0 gpio bank base */
+ and r1, r2 /* r1 gpio offset */
+
+ ldr r2, ambarella_suspend_trigger_signal
+ lsl r2, r1
+ str r2, [r0, #0]
+
+ /* delay 100ms: 0x249F00 is about 0x250000 */
+ mov r3, #0x250000
+
+ mov r4, #RCT_BUS_BASE
+ orr r4, #RCT_OFFSET
+ orr r4, #RCT_TIMER_OFFSET
+ ldr r5, [r4]
+ add r5, r5, r3
+rct_time_loop:
+ ldr r6, [r4]
+ cmp r5, r6
+ bhi rct_time_loop
+
+ ldr r2, ambarella_suspend_trigger_signal
+ eor r2, r2, #1
+ lsl r2, r1
+ str r2, [r0, #0]
+
+ b self_refresh
+
+suspend_with_pwc:
+ mov r0, #RCT_BUS_BASE
+ orr r0, #RCT_OFFSET
+ orr r0, #ANA_PWR_OFFSET
+
+ /* Generate the PD signal */
+ mov r1, #ANA_PWR_POWER_DOWN
+ str r1, [r0]
+
+self_refresh:
+ /* CPU use the delay interval between power-down signal PD
+ and PWC_RSTOB to execute the following code */
+
+ mov r0, #DRAMC_BASE
+ orr r0, r0, #DRAM_DDRC_OFFSET
+
+ ldr r1, [r0, #DDRC_CTL_OFFSET]
+ bic r1, r1, #0x1
+ str r1, [r0, #DDRC_CTL_OFFSET]
+ mov r1, #0x80000000
+ str r1, [r0, #DDRC_SELF_REF_OFFSET]
+1:
+ ldr r1, [r0, #DDRC_SELF_REF_OFFSET]
+ tst r1, #0x10000000
+ beq 1b
+
+ /* Wait for PWC_RSTOB signal to power down cpu */
+ b .
+
+ENDPROC(ambarella_optimize_suspend)
+
+.globl ambarella_suspend_trigger_signal
+ambarella_suspend_trigger_signal:
+ .word 0x00000000
+
+ENTRY(ambarella_optimize_suspend_sz)
+ .word . - ambarella_optimize_suspend
+
+#if (CHIP_REV == S3)
+#define IOMUX_UART0_PIN_CFG 0x00000030
+#else
+#define IOMUX_UART0_PIN_CFG 0x00000180
+#endif
+
+ENTRY(ambarella_cpu_resume)
+ /*
+ * init UART(115200, 8N1) to avoid deadloop in printk.
+ * MMU is not enabled yet, so we use physical address here.
+ */
+ ldr r0, =RCT_PHYS_BASE
+ mov r1, #0x1
+ str r1, [r0, #CG_UART_OFFSET]
+
+ ldr r0, =(APB_PHYS_BASE + UART_OFFSET)
+ mov r1, #0x1
+ str r1, [r0, #UART_SRR_OFFSET]
+ mov r1, #0x0
+ str r1, [r0, #UART_SRR_OFFSET]
+ mov r1, #0x80
+ str r1, [r0, #UART_LC_OFFSET]
+ ldr r1, =(REF_CLK_FREQ/16/115200)
+ str r1, [r0, #UART_DLL_OFFSET]
+ mov r1, #0x00
+ str r1, [r0, #UART_DLH_OFFSET]
+ mov r1, #0x03
+ str r1, [r0, #UART_LC_OFFSET]
+
+ /* configure Tx/Rx pin as hw mode, it's chip specific. */
+#if (IOMUX_SUPPORT > 0)
+ /* gpio39/40 are used for UART0_rx/tx */
+ ldr r0, =(APB_PHYS_BASE + IOMUX_OFFSET)
+ /* read-modify-write */
+ ldr r1, [r0, #IOMUX_REG1_0_OFFSET]
+ orr r1, r1, #IOMUX_UART0_PIN_CFG
+ str r1, [r0, #IOMUX_REG1_0_OFFSET]
+ /* read-modify-write */
+ ldr r1, [r0, #IOMUX_REG1_1_OFFSET]
+ bic r1, r1, #IOMUX_UART0_PIN_CFG
+ str r1, [r0, #IOMUX_REG1_1_OFFSET]
+ /* read-modify-write */
+ ldr r1, [r0, #IOMUX_REG1_2_OFFSET]
+ bic r1, r1, #IOMUX_UART0_PIN_CFG
+ str r1, [r0, #IOMUX_REG1_2_OFFSET]
+ ldr r1, =0x00000001
+ str r1, [r0, #IOMUX_CTRL_SET_OFFSET]
+ ldr r1, =0x00000000
+ str r1, [r0, #IOMUX_CTRL_SET_OFFSET]
+#else
+ /* gpio14/15 are used for UART0_tx/rx */
+ ldr r0, =(APB_PHYS_BASE + GPIO0_OFFSET)
+ ldr r1, [r0, #GPIO_AFSEL_OFFSET]
+ orr r1, #0x0000c000
+ str r1, [r0, #GPIO_AFSEL_OFFSET]
+
+#if (CHIP_REV == S2E)
+ ldr r0, =RCT_PHYS_BASE
+ mov r1, #UART_CLK_SRC_IDSP
+ str r1, [r0, #UART_CLK_SRC_SEL_OFFSET]
+#endif
+
+#endif
+ /* jump to generic resume */
+ b cpu_resume
+ENDPROC(ambarella_cpu_resume)
+
diff --git a/arch/arm/mach-ambarella/smp/Makefile b/arch/arm/mach-ambarella/smp/Makefile
new file mode 100644
index 00000000..6bf90022
--- /dev/null
+++ b/arch/arm/mach-ambarella/smp/Makefile
@@ -0,0 +1,24 @@
+#
+# arch/arm/plat-ambarella/smp/Makefile
+#
+# Author: Anthony Ginger <hfjiang@ambarella.com>
+#
+# Copyright (C) 2004-2011, Ambarella, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+obj-$(CONFIG_SMP) += smp.o headsmp.o
+
diff --git a/arch/arm/mach-ambarella/smp/headsmp.S b/arch/arm/mach-ambarella/smp/headsmp.S
new file mode 100644
index 00000000..a10d926c
--- /dev/null
+++ b/arch/arm/mach-ambarella/smp/headsmp.S
@@ -0,0 +1,55 @@
+/*
+ * arch/arm/plat-ambarella/smp/headsmp.S
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+ __CPUINIT
+
+/*
+ * ambarella specific entry point for secondary CPUs. This provides
+ * a "holding pen" into which all secondary cores are held until we're
+ * ready for them to initialise.
+ */
+ENTRY(ambarella_secondary_startup)
+ mrc p15, 0, r0, c0, c0, 5
+ and r0, r0, #0x00ffffff
+ adr r4, 1f
+ ldmia r4, {r5, r6}
+ sub r4, r4, r5
+ add r6, r6, r4
+pen: ldr r7, [r6]
+ cmp r7, r0
+ bne pen
+
+ /*
+ * we've been released from the holding pen: secondary_stack
+ * should now contain the SVC stack for this core
+ */
+ b secondary_startup
+ENDPROC(ambarella_secondary_startup)
+
+ .align 2
+1: .long .
+ .long pen_release
+
diff --git a/arch/arm/mach-ambarella/smp/smp.c b/arch/arm/mach-ambarella/smp/smp.c
new file mode 100644
index 00000000..138bd802
--- /dev/null
+++ b/arch/arm/mach-ambarella/smp/smp.c
@@ -0,0 +1,266 @@
+/*
+ * arch/arm/plat-ambarella/smp/smp.c
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/bootmem.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/init.h>
+
+static void __iomem *scu_base = __io(AMBARELLA_VA_SCU_BASE);
+static DEFINE_SPINLOCK(boot_lock);
+
+static u32 *cpux_jump_virt = NULL;
+extern void ambarella_secondary_startup(void);
+extern void ambvic_smp_softirq_init(void);
+
+
+/* Write pen_release in a way that is guaranteed to be visible to all
+ * observers, irrespective of whether they're taking part in coherency
+ * or not. This is necessary for the hotplug code to work reliably. */
+static void write_pen_release(int val)
+{
+ pen_release = val;
+ smp_wmb();
+ __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
+ outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+}
+
+static void write_cpux_jump_addr(unsigned int cpu, int addr)
+{
+ cpux_jump_virt[cpu] = addr;
+ smp_wmb();
+ __cpuc_flush_dcache_area(
+ &cpux_jump_virt[cpu], sizeof(cpux_jump_virt[cpu]));
+ outer_clean_range(ambarella_virt_to_phys((u32)&cpux_jump_virt[cpu]),
+ ambarella_virt_to_phys((u32)&cpux_jump_virt[cpu] + 1));
+}
+
+/* running on CPU1 */
+static void __cpuinit ambarella_smp_secondary_init(unsigned int cpu)
+{
+ /* let the primary processor know we're out of the
+ * pen, then head off into the C entry point */
+ write_pen_release(-1);
+
+ /* Synchronise with the boot thread. */
+ spin_lock(&boot_lock);
+ spin_unlock(&boot_lock);
+}
+/* running on CPU0 */
+static int __cpuinit ambarella_smp_boot_secondary(unsigned int cpu,
+ struct task_struct *idle)
+{
+ unsigned long timeout;
+ unsigned long phys_cpu = cpu_logical_map(cpu);
+
+ BUG_ON(cpux_jump_virt == NULL);
+
+ scu_enable(scu_base);
+
+ /* Set synchronisation state between this boot processor
+ * and the secondary one */
+ spin_lock(&boot_lock);
+
+ /* The secondary processor is waiting to be released from
+ * the holding pen - release it, then wait for it to flag
+ * that it has been released by resetting pen_release.
+ *
+ * Note that "pen_release" is the hardware CPU ID, whereas
+ * "cpu" is Linux's internal ID. */
+ write_pen_release(phys_cpu);
+
+ write_cpux_jump_addr(cpu, virt_to_phys(ambarella_secondary_startup));
+
+#ifdef CONFIG_PLAT_AMBARELLA_SUPPORT_VIC
+ /* IPI interrupt on CPU1 may be unmasked, so this init is necessary */
+ ambvic_smp_softirq_init();
+#endif
+
+ /* Send the secondary CPU a soft interrupt, thereby causing
+ * the boot monitor to read the system wide flags register,
+ * and branch to the address found there. */
+ timeout = jiffies + (1 * HZ);
+ while (time_before(jiffies, timeout)) {
+ smp_rmb();
+
+ arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+ if (pen_release == -1)
+ break;
+
+ udelay(10);
+ }
+
+ spin_unlock(&boot_lock);
+
+ return pen_release != -1 ? -ENOSYS : 0;
+}
+
+/* running on CPU0 */
+static void __init ambarella_smp_init_cpus(void)
+{
+ int i;
+ unsigned int ncores;
+
+ ncores = scu_get_core_count(scu_base);
+ if (ncores > nr_cpu_ids) {
+ pr_warning("SMP: cores(%u) greater than maximum(%u), clipping\n",
+ ncores, nr_cpu_ids);
+ ncores = nr_cpu_ids;
+ }
+
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+}
+
+/* running on CPU0 */
+static void __init ambarella_smp_prepare_cpus(unsigned int max_cpus)
+{
+ u32 cpux_jump, start_limit, end_limit;
+ int i, rval;
+
+ rval = of_property_read_u32(of_chosen, "ambarella,cpux_jump", &cpux_jump);
+ if (rval < 0) {
+ pr_err("No jump address for secondary cpu!\n");
+ return;
+ }
+
+ start_limit = get_ambarella_ppm_phys();
+ end_limit = get_ambarella_ppm_phys() + get_ambarella_ppm_size();
+ if (cpux_jump < start_limit || cpux_jump > end_limit) {
+ pr_err("Invalid secondary cpu jump address, 0x%08x!\n", cpux_jump);
+ return;
+ }
+
+ cpux_jump_virt = (u32 *)ambarella_phys_to_virt(cpux_jump);
+
+ for (i = 0; i < max_cpus; i++)
+ set_cpu_present(i, true);
+
+ scu_enable(scu_base);
+
+ for (i = 1; i < max_cpus; i++)
+ write_cpux_jump_addr(i, virt_to_phys(ambarella_secondary_startup));
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static inline void cpu_enter_lowpower(void)
+{
+ unsigned int v;
+
+ flush_cache_all();
+ asm volatile(
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " bic %0, %0, #(1 << 6)\n"
+ " bic %0, %0, #(1 << 0)\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ " mrc p15, 0, %0, c1, c0, 0\n"
+ " bic %0, %0, #(1 << 2)\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ : "=&r" (v)
+ : "r" (0)
+ : "cc");
+}
+
+static inline void cpu_leave_lowpower(void)
+{
+ unsigned int v;
+
+ asm volatile(
+ " mrc p15, 0, %0, c1, c0, 0\n"
+ " orr %0, %0, #(1 << 2)\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " orr %0, %0, #(1 << 6)\n"
+ " orr %0, %0, #(1 << 0)\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ : "=&r" (v)
+ :
+ : "cc");
+}
+
+static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
+{
+ for (;;) {
+ wfi();
+
+ if (pen_release == cpu_logical_map(cpu)) {
+ /* OK, proper wakeup, we're done */
+ break;
+ }
+
+ /* Getting here, means that we have come out of WFI without
+ * having been woken up - this shouldn't happen
+ *
+ * Just note it happening - when we're woken, we can report
+ * its occurrence. */
+ (*spurious)++;
+ }
+}
+
+/* running on CPU1 */
+static void ambarella_smp_cpu_die(unsigned int cpu)
+{
+ int spurious = 0;
+
+ cpu_enter_lowpower();
+
+ platform_do_lowpower(cpu, &spurious);
+
+ cpu_leave_lowpower();
+
+ if (spurious)
+ pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
+}
+
+/* running on CPU1 */
+static int ambarella_smp_cpu_disable(unsigned int cpu)
+{
+ return cpu == 0 ? -EPERM : 0;
+}
+#endif
+
+struct smp_operations ambarella_smp_ops __initdata = {
+ .smp_init_cpus = ambarella_smp_init_cpus,
+ .smp_prepare_cpus = ambarella_smp_prepare_cpus,
+ .smp_boot_secondary = ambarella_smp_boot_secondary,
+ .smp_secondary_init = ambarella_smp_secondary_init,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_disable = ambarella_smp_cpu_disable,
+ .cpu_die = ambarella_smp_cpu_die,
+#endif
+};
+
diff --git a/arch/arm/mach-ambarella/soc/Makefile b/arch/arm/mach-ambarella/soc/Makefile
new file mode 100644
index 00000000..0e32c6fb
--- /dev/null
+++ b/arch/arm/mach-ambarella/soc/Makefile
@@ -0,0 +1,30 @@
+#
+# arch/arm/mach-ambarella/soc/Makefile
+#
+# Author: Cao Rongrong <rrcao@ambarella.com>
+#
+# Copyright (C) 2012-2016, Ambarella, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+obj-$(CONFIG_PLAT_AMBARELLA_A5S) += a5s.o
+obj-$(CONFIG_PLAT_AMBARELLA_A7L) += a7l.o
+obj-$(CONFIG_PLAT_AMBARELLA_S2_CORTEX) += s2-cortex.o
+obj-$(CONFIG_PLAT_AMBARELLA_S2E) += s2e.o
+obj-$(CONFIG_PLAT_AMBARELLA_S2L) += s2l.o
+obj-$(CONFIG_PLAT_AMBARELLA_S3) += s3.o
+obj-$(CONFIG_PLAT_AMBARELLA_S3L) += s3l.o
+
diff --git a/arch/arm/mach-ambarella/soc/a5s.c b/arch/arm/mach-ambarella/soc/a5s.c
new file mode 100644
index 00000000..5a8673ff
--- /dev/null
+++ b/arch/arm/mach-ambarella/soc/a5s.c
@@ -0,0 +1,56 @@
+/*
+ * arch/arm/mach-ambarella/init-coconut.c
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/irqchip.h>
+#include <linux/of_platform.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/system_info.h>
+#include <mach/hardware.h>
+#include <mach/init.h>
+
+static const char * const a5s_dt_board_compat[] = {
+ "ambarella,a5s",
+ NULL,
+};
+
+DT_MACHINE_START(A5S_DT, "Ambarella A5S (Flattened Device Tree)")
+ .restart_mode = 's',
+ .map_io = ambarella_map_io,
+ .init_early = ambarella_init_early,
+ .init_irq = irqchip_init,
+ .init_time = ambarella_timer_init,
+ .init_machine = ambarella_init_machine,
+ .restart = ambarella_restart_machine,
+ .dt_compat = a5s_dt_board_compat,
+MACHINE_END
+
diff --git a/arch/arm/mach-ambarella/soc/a7l.c b/arch/arm/mach-ambarella/soc/a7l.c
new file mode 100644
index 00000000..cbde2926
--- /dev/null
+++ b/arch/arm/mach-ambarella/soc/a7l.c
@@ -0,0 +1,53 @@
+/*
+ * arch/arm/mach-ambarella/init-durian.c
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/irqchip.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/system_info.h>
+
+#include <mach/hardware.h>
+#include <mach/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+
+#include <linux/input.h>
+
+/* ==========================================================================*/
+MACHINE_START(A7L_DT, "Durian")
+ .atag_offset = 0x100,
+ .restart_mode = 's',
+ .map_io = ambarella_map_io,
+ .init_early = ambarella_init_early,
+ .init_irq = irqchip_init,
+ .init_time = ambarella_timer_init,
+ .init_machine = ambarella_init_machine,
+ .restart = ambarella_restart_machine,
+MACHINE_END
+
diff --git a/arch/arm/mach-ambarella/soc/s2-cortex.c b/arch/arm/mach-ambarella/soc/s2-cortex.c
new file mode 100644
index 00000000..833fb5a3
--- /dev/null
+++ b/arch/arm/mach-ambarella/soc/s2-cortex.c
@@ -0,0 +1,62 @@
+/*
+ * arch/arm/mach-ambarella/init-ginkgo.c
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/clk.h>
+#include <linux/of_platform.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/arm-gic.h>
+#include <asm/gpio.h>
+#include <asm/system_info.h>
+
+#include <mach/hardware.h>
+#include <mach/init.h>
+#include <mach/common.h>
+
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+
+
+static const char * const s2_dt_board_compat[] = {
+ "ambarella,s2",
+ NULL,
+};
+
+DT_MACHINE_START(S2_DT, "Ambarella S2 (Flattened Device Tree)")
+ .restart_mode = 's',
+ .smp = smp_ops(ambarella_smp_ops),
+ .map_io = ambarella_map_io,
+ .init_early = ambarella_init_early,
+ .init_irq = irqchip_init,
+ .init_time = ambarella_timer_init,
+ .init_machine = ambarella_init_machine,
+ .restart = ambarella_restart_machine,
+ .dt_compat = s2_dt_board_compat,
+MACHINE_END
+
diff --git a/arch/arm/mach-ambarella/soc/s2e.c b/arch/arm/mach-ambarella/soc/s2e.c
new file mode 100644
index 00000000..cefd147b
--- /dev/null
+++ b/arch/arm/mach-ambarella/soc/s2e.c
@@ -0,0 +1,48 @@
+/*
+ * arch/arm/mach-ambarella/soc/s2e.c
+ *
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * Copyright (C) 2012-2016, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of_platform.h>
+#include <linux/irqchip.h>
+#include <asm/mach/arch.h>
+#include <mach/init.h>
+#include <mach/common.h>
+
+static const char * const s2e_dt_board_compat[] = {
+ "ambarella,s2e",
+ NULL,
+};
+
+DT_MACHINE_START(S2E_DT, "Ambarella S2E (Flattened Device Tree)")
+ .restart_mode = 's',
+ .smp = smp_ops(ambarella_smp_ops),
+ .map_io = ambarella_map_io,
+ .init_early = ambarella_init_early,
+ .init_irq = irqchip_init,
+ .init_time = ambarella_timer_init,
+ .init_machine = ambarella_init_machine,
+ .restart = ambarella_restart_machine,
+ .dt_compat = s2e_dt_board_compat,
+MACHINE_END
+
diff --git a/arch/arm/mach-ambarella/soc/s2l.c b/arch/arm/mach-ambarella/soc/s2l.c
new file mode 100644
index 00000000..3525c040
--- /dev/null
+++ b/arch/arm/mach-ambarella/soc/s2l.c
@@ -0,0 +1,46 @@
+/*
+ * arch/arm/mach-ambarella/init-ixora.c
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2013, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of_platform.h>
+#include <linux/irqchip.h>
+#include <asm/mach/arch.h>
+#include <mach/init.h>
+
+static const char * const s2l_dt_board_compat[] = {
+ "ambarella,s2l",
+ NULL,
+};
+
+DT_MACHINE_START(S2L_DT, "Ambarella S2L (Flattened Device Tree)")
+ .restart_mode = 's',
+ .map_io = ambarella_map_io,
+ .init_early = ambarella_init_early,
+ .init_irq = irqchip_init,
+ .init_time = ambarella_timer_init,
+ .init_machine = ambarella_init_machine,
+ .restart = ambarella_restart_machine,
+ .dt_compat = s2l_dt_board_compat,
+MACHINE_END
+
diff --git a/arch/arm/mach-ambarella/soc/s3.c b/arch/arm/mach-ambarella/soc/s3.c
new file mode 100644
index 00000000..d2b7daa4
--- /dev/null
+++ b/arch/arm/mach-ambarella/soc/s3.c
@@ -0,0 +1,48 @@
+/*
+ * arch/arm/mach-ambarella/soc/s3.c
+ *
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * Copyright (C) 2012-2016, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of_platform.h>
+#include <linux/irqchip.h>
+#include <asm/mach/arch.h>
+#include <mach/init.h>
+#include <mach/common.h>
+
+static const char * const s3_dt_board_compat[] = {
+ "ambarella,s3",
+ NULL,
+};
+
+DT_MACHINE_START(S3_DT, "Ambarella S3 (Flattened Device Tree)")
+ .restart_mode = 's',
+ .smp = smp_ops(ambarella_smp_ops),
+ .map_io = ambarella_map_io,
+ .init_early = ambarella_init_early,
+ .init_irq = irqchip_init,
+ .init_time = ambarella_timer_init,
+ .init_machine = ambarella_init_machine,
+ .restart = ambarella_restart_machine,
+ .dt_compat = s3_dt_board_compat,
+MACHINE_END
+
diff --git a/arch/arm/mach-ambarella/soc/s3l.c b/arch/arm/mach-ambarella/soc/s3l.c
new file mode 100644
index 00000000..0cf97229
--- /dev/null
+++ b/arch/arm/mach-ambarella/soc/s3l.c
@@ -0,0 +1,46 @@
+/*
+ * arch/arm/mach-ambarella/init-ixora.c
+ *
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * Copyright (C) 2012-2016, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of_platform.h>
+#include <linux/irqchip.h>
+#include <asm/mach/arch.h>
+#include <mach/init.h>
+
+static const char * const s3l_dt_board_compat[] = {
+ "ambarella,s3l",
+ NULL,
+};
+
+DT_MACHINE_START(S3L_DT, "Ambarella S3L (Flattened Device Tree)")
+ .restart_mode = 's',
+ .map_io = ambarella_map_io,
+ .init_early = ambarella_init_early,
+ .init_irq = irqchip_init,
+ .init_time = ambarella_timer_init,
+ .init_machine = ambarella_init_machine,
+ .restart = ambarella_restart_machine,
+ .dt_compat = s3l_dt_board_compat,
+MACHINE_END
+
diff --git a/arch/arm/mach-ambarella/timer.c b/arch/arm/mach-ambarella/timer.c
new file mode 100644
index 00000000..167c9f74
--- /dev/null
+++ b/arch/arm/mach-ambarella/timer.c
@@ -0,0 +1,622 @@
+/*
+ * arch/arm/plat-ambarella/generic/timer.c
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2012, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Default clock is from APB.
+ */
+
+#include <linux/semaphore.h>
+#include <linux/interrupt.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <asm/mach/time.h>
+#include <asm/smp_twd.h>
+#include <asm/sched_clock.h>
+#include <asm/localtimer.h>
+#include <plat/timer.h>
+#include <plat/event.h>
+
+static void __iomem *ce_base = NULL;
+static void __iomem *ce_ctrl_reg = NULL;
+static u32 ce_ctrl_offset = -1;
+
+static void __iomem *cs_base = NULL;
+static void __iomem *cs_ctrl_reg = NULL;
+static u32 cs_ctrl_offset = -1;
+
+#define AMBARELLA_TIMER_FREQ clk_get_rate(clk_get(NULL, "gclk_apb"))
+#define AMBARELLA_TIMER_RATING (300)
+
+static struct clock_event_device ambarella_clkevt;
+static struct clocksource ambarella_clksrc;
+static u32 ambarella_read_sched_clock(void);
+
+/* ==========================================================================*/
+struct amb_timer_pm_reg {
+ u32 clk_rate;
+ u32 ctrl_reg;
+ u32 status_reg;
+ u32 reload_reg;
+ u32 match1_reg;
+ u32 match2_reg;
+};
+
+static struct amb_timer_pm_reg amb_timer_ce_pm;
+static struct amb_timer_pm_reg amb_timer_cs_pm;
+
+static void ambarella_timer_suspend(u32 is_ce)
+{
+ struct amb_timer_pm_reg *amb_timer_pm;
+ void __iomem *regbase;
+ void __iomem *ctrl_reg;
+ u32 ctrl_offset;
+
+ amb_timer_pm = is_ce ? &amb_timer_ce_pm : &amb_timer_cs_pm;
+ regbase = is_ce ? ce_base : cs_base;
+ ctrl_reg = is_ce ? ce_ctrl_reg : cs_ctrl_reg;
+ ctrl_offset = is_ce ? ce_ctrl_offset : cs_ctrl_offset;
+
+ amb_timer_pm->clk_rate = AMBARELLA_TIMER_FREQ;
+ amb_timer_pm->ctrl_reg = (amba_readl(ctrl_reg) >> ctrl_offset) & 0xf;
+ amb_timer_pm->status_reg = amba_readl(regbase + TIMER_STATUS_OFFSET);
+ amb_timer_pm->reload_reg = amba_readl(regbase + TIMER_RELOAD_OFFSET);
+ amb_timer_pm->match1_reg = amba_readl(regbase + TIMER_MATCH1_OFFSET);
+ amb_timer_pm->match2_reg = amba_readl(regbase + TIMER_MATCH2_OFFSET);
+
+ amba_clrbitsl(ctrl_reg, 0xf << ctrl_offset);
+}
+
+static void ambarella_timer_resume(u32 is_ce)
+{
+ struct clock_event_device *clkevt = &ambarella_clkevt;
+ struct clocksource *clksrc = &ambarella_clksrc;
+ struct amb_timer_pm_reg *amb_timer_pm;
+ void __iomem *regbase;
+ void __iomem *ctrl_reg;
+ u32 ctrl_offset, clk_rate;
+
+ amb_timer_pm = is_ce ? &amb_timer_ce_pm : &amb_timer_cs_pm;
+ regbase = is_ce ? ce_base : cs_base;
+ ctrl_reg = is_ce ? ce_ctrl_reg : cs_ctrl_reg;
+ ctrl_offset = is_ce ? ce_ctrl_offset : cs_ctrl_offset;
+
+ amba_clrbitsl(ctrl_reg, 0xf << ctrl_offset);
+
+ amba_writel(regbase + TIMER_STATUS_OFFSET, amb_timer_pm->status_reg);
+ amba_writel(regbase + TIMER_RELOAD_OFFSET, amb_timer_pm->reload_reg);
+ amba_writel(regbase + TIMER_MATCH1_OFFSET, amb_timer_pm->match1_reg);
+ amba_writel(regbase + TIMER_MATCH2_OFFSET, amb_timer_pm->match2_reg);
+
+ clk_rate = AMBARELLA_TIMER_FREQ;
+ if (amb_timer_pm->clk_rate == clk_rate)
+ goto resume_exit;
+
+ amb_timer_pm->clk_rate = clk_rate;
+
+ if (is_ce) {
+ clockevents_update_freq(clkevt, clk_rate);
+ } else {
+ clocksource_change_rating(clksrc, 0);
+ __clocksource_updatefreq_hz(clksrc, clk_rate);
+ clocksource_change_rating(clksrc, AMBARELLA_TIMER_RATING);
+ }
+
+resume_exit:
+ amba_setbitsl(ctrl_reg, amb_timer_pm->ctrl_reg << ctrl_offset);
+}
+
+
+/* ==========================================================================*/
+static inline void ambarella_ce_timer_disable(void __iomem *ctrl_reg, u32 offs)
+{
+ amba_clrbitsl(ctrl_reg, TIMER_CTRL_EN << offs);
+}
+
+static inline void ambarella_ce_timer_enable(void __iomem *ctrl_reg, u32 offs)
+{
+ amba_setbitsl(ctrl_reg, TIMER_CTRL_EN << offs);
+}
+
+static inline void ambarella_ce_timer_misc(void __iomem *ctrl_reg, u32 offs)
+{
+ amba_setbitsl(ctrl_reg, TIMER_CTRL_OF << offs);
+ amba_clrbitsl(ctrl_reg, TIMER_CTRL_CSL << offs);
+}
+
+static inline void ambarella_ce_timer_set_periodic
+ (void __iomem *base_reg, void __iomem *ctrl_reg, u32 offs)
+{
+ u32 cnt = AMBARELLA_TIMER_FREQ / HZ;
+
+ amba_writel(base_reg + TIMER_STATUS_OFFSET, cnt);
+ amba_writel(base_reg + TIMER_RELOAD_OFFSET, cnt);
+ amba_writel(base_reg + TIMER_MATCH1_OFFSET, 0x0);
+ amba_writel(base_reg + TIMER_MATCH2_OFFSET, 0x0);
+
+ ambarella_ce_timer_misc(ctrl_reg, offs);
+}
+
+static inline void ambarella_ce_timer_set_oneshot
+ (void __iomem *base_reg, void __iomem *ctrl_reg, u32 offs)
+{
+ amba_writel(base_reg + TIMER_STATUS_OFFSET, 0x0);
+ amba_writel(base_reg + TIMER_RELOAD_OFFSET, 0xffffffff);
+ amba_writel(base_reg + TIMER_MATCH1_OFFSET, 0x0);
+ amba_writel(base_reg + TIMER_MATCH2_OFFSET, 0x0);
+
+ ambarella_ce_timer_misc(ctrl_reg, offs);
+}
+
+static void inline ambarella_ce_set_mode(
+ void __iomem *base_reg, void __iomem *ctrl_reg, u32 ctrl_offset,
+ enum clock_event_mode mode, struct clock_event_device *clkevt)
+{
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ ambarella_ce_timer_disable(ctrl_reg, ctrl_offset);
+ ambarella_ce_timer_set_periodic(base_reg, ctrl_reg, ctrl_offset);
+ ambarella_ce_timer_enable(ctrl_reg, ctrl_offset);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ ambarella_ce_timer_disable(ctrl_reg, ctrl_offset);
+ ambarella_ce_timer_set_oneshot(base_reg, ctrl_reg, ctrl_offset);
+ ambarella_ce_timer_enable(ctrl_reg, ctrl_offset);
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ ambarella_ce_timer_disable(ctrl_reg, ctrl_offset);
+ break;
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
+ pr_debug("%s:%d\n", __func__, mode);
+}
+
+static void inline ambarella_ce_set_next_event(void __iomem *base_reg,
+ unsigned long delta, struct clock_event_device *clkevt)
+{
+ amba_writel(base_reg + TIMER_STATUS_OFFSET, delta);
+}
+
+/* ==========================================================================*/
+
+static void ambarella_global_ce_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *clkevt)
+{
+ ambarella_ce_set_mode(ce_base, ce_ctrl_reg, ce_ctrl_offset, mode, clkevt);
+}
+
+static int ambarella_global_ce_set_next_event(unsigned long delta,
+ struct clock_event_device *clkevt)
+{
+ ambarella_ce_set_next_event(ce_base, delta, clkevt);
+ return 0;
+}
+
+static void ambarella_global_ce_suspend(struct clock_event_device *dev)
+{
+ ambarella_timer_suspend(1);
+}
+
+static void ambarella_global_ce_resume(struct clock_event_device *dev)
+{
+ ambarella_timer_resume(1);
+}
+
+static struct clock_event_device ambarella_clkevt = {
+ .name = "ambarella-clkevt",
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .rating = AMBARELLA_TIMER_RATING,
+ .set_next_event = ambarella_global_ce_set_next_event,
+ .set_mode = ambarella_global_ce_set_mode,
+ .mode = CLOCK_EVT_MODE_UNUSED,
+ .suspend = ambarella_global_ce_suspend,
+ .resume = ambarella_global_ce_resume,
+};
+
+static irqreturn_t ambarella_global_ce_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *clkevt = &ambarella_clkevt;
+
+ clkevt->event_handler(clkevt);
+ return IRQ_HANDLED;
+}
+
+static struct irqaction ambarella_ce_timer_irq = {
+ .name = "ambarella-ce-timer",
+ .flags = IRQF_TIMER | IRQF_TRIGGER_RISING,
+ .handler = ambarella_global_ce_interrupt,
+};
+
+/* ==========================================================================*/
+static inline void ambarella_cs_timer_init(void)
+{
+ amba_clrbitsl(cs_ctrl_reg, TIMER_CTRL_EN << cs_ctrl_offset);
+ amba_clrbitsl(cs_ctrl_reg, TIMER_CTRL_OF << cs_ctrl_offset);
+ amba_clrbitsl(cs_ctrl_reg, TIMER_CTRL_CSL << cs_ctrl_offset);
+ amba_writel(cs_base + TIMER_STATUS_OFFSET, 0xffffffff);
+ amba_writel(cs_base + TIMER_RELOAD_OFFSET, 0xffffffff);
+ amba_writel(cs_base + TIMER_MATCH1_OFFSET, 0x0);
+ amba_writel(cs_base + TIMER_MATCH2_OFFSET, 0x0);
+ amba_setbitsl(cs_ctrl_reg, TIMER_CTRL_EN << cs_ctrl_offset);
+}
+
+static cycle_t ambarella_cs_timer_read(struct clocksource *cs)
+{
+ return (-(u32)amba_readl(cs_base + TIMER_STATUS_OFFSET));
+}
+
+static void ambarella_cs_timer_suspend(struct clocksource *dev)
+{
+ ambarella_timer_suspend(0);
+}
+
+static void ambarella_cs_timer_resume(struct clocksource *dev)
+{
+ ambarella_timer_resume(0);
+}
+
+static struct clocksource ambarella_clksrc = {
+ .name = "ambarella-cs-timer",
+ .rating = AMBARELLA_TIMER_RATING,
+ .read = ambarella_cs_timer_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ .suspend = ambarella_cs_timer_suspend,
+ .resume = ambarella_cs_timer_resume,
+};
+
+static u32 notrace ambarella_read_sched_clock(void)
+{
+ return (-(u32)amba_readl(cs_base + TIMER_STATUS_OFFSET));
+}
+
+/* ==========================================================================*/
+/*define a event struct to update timer*/
+struct ambarella_timer_notifier {
+ struct notifier_block system_event;
+ struct semaphore system_event_sem;
+} amba_timer_notifier;
+
+static int ambarella_timer_system_event(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ unsigned long flags;
+
+ switch (val) {
+ case AMBA_EVENT_PRE_CPUFREQ:
+ down(&(amba_timer_notifier.system_event_sem));
+ break;
+
+ case AMBA_EVENT_POST_CPUFREQ:
+ local_irq_save(flags);
+ clockevents_update_freq(&ambarella_clkevt, AMBARELLA_TIMER_FREQ);
+
+ clocksource_change_rating(&ambarella_clksrc, 0);
+ __clocksource_updatefreq_hz(&ambarella_clksrc, AMBARELLA_TIMER_FREQ);
+ clocksource_change_rating(&ambarella_clksrc, AMBARELLA_TIMER_RATING);
+ local_irq_restore(flags);
+ up(&(amba_timer_notifier.system_event_sem));
+ break;
+
+ default:
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+/* ==========================================================================*/
+static const struct of_device_id clock_event_match[] __initconst = {
+ { .compatible = "ambarella,clock-event" },
+ { },
+};
+
+static const struct of_device_id clock_source_match[] __initconst = {
+ { .compatible = "ambarella,clock-source" },
+ { },
+};
+
+static void __init ambarella_clockevent_init(void)
+{
+ struct device_node *np;
+ struct clock_event_device *clkevt;
+ int rval, irq;
+
+ np = of_find_matching_node(NULL, clock_event_match);
+ if (!np) {
+ pr_err("Can't find clock event node\n");
+ return;
+ }
+
+ ce_base = of_iomap(np, 0);
+ if (!ce_base) {
+ pr_err("%s: Failed to map event base\n", __func__);
+ return;
+ }
+
+ ce_ctrl_reg = of_iomap(np, 1);
+ if (!ce_ctrl_reg) {
+ pr_err("%s: Failed to map timer-ctrl base\n", __func__);
+ return;
+ }
+
+ irq = irq_of_parse_and_map(np, 0);
+ if (irq <= 0) {
+ pr_err("%s: Can't get irq\n", __func__);
+ return;
+ }
+
+ rval = of_property_read_u32(np, "ctrl-offset", &ce_ctrl_offset);
+ if (rval < 0) {
+ pr_err("%s: Can't get ctrl offset\n", __func__);
+ return;
+ }
+
+ of_node_put(np);
+
+ clkevt = &ambarella_clkevt;
+ clkevt->cpumask = cpumask_of(0);
+ clkevt->irq = irq;
+
+ rval = setup_irq(clkevt->irq, &ambarella_ce_timer_irq);
+ if (rval) {
+ printk(KERN_ERR "Failed to register timer IRQ: %d\n", rval);
+ BUG();
+ }
+
+ clockevents_config_and_register(clkevt, AMBARELLA_TIMER_FREQ, 1, 0xffffffff);
+}
+
+static void __init ambarella_clocksource_init(void)
+{
+ struct device_node *np;
+ struct clocksource *clksrc;
+ int rval;
+
+ np = of_find_matching_node(NULL, clock_source_match);
+ if (!np) {
+ pr_err("Can't find clock source node\n");
+ return;
+ }
+
+ cs_base = of_iomap(np, 0);
+ if (!cs_base) {
+ pr_err("%s: Failed to map source base\n", __func__);
+ return;
+ }
+
+ cs_ctrl_reg = of_iomap(np, 1);
+ if (!cs_ctrl_reg) {
+ pr_err("%s: Failed to map timer-ctrl base\n", __func__);
+ return;
+ }
+
+ rval = of_property_read_u32(np, "ctrl-offset", &cs_ctrl_offset);
+ if (rval < 0) {
+ pr_err("%s: Can't get ctrl offset\n", __func__);
+ return;
+ }
+
+ of_node_put(np);
+
+ clksrc = &ambarella_clksrc;
+
+ ambarella_cs_timer_init();
+
+ clocksource_register_hz(clksrc, AMBARELLA_TIMER_FREQ);
+
+ pr_debug("%s: mult = %u, shift = %u\n",
+ clksrc->name, clksrc->mult, clksrc->shift);
+
+ setup_sched_clock(ambarella_read_sched_clock, 32, AMBARELLA_TIMER_FREQ);
+
+ /*add notifier to update the timer when the cpu frequency is changed*/
+ sema_init(&amba_timer_notifier.system_event_sem, 1);
+ amba_timer_notifier.system_event.notifier_call = ambarella_timer_system_event;
+ ambarella_register_event_notifier(&amba_timer_notifier.system_event);
+}
+
+#ifdef CONFIG_HAVE_ARM_TWD
+static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, AMBARELLA_VA_PT_WD_BASE, IRQ_LOCALTIMER);
+
+static void __init ambarella_smp_twd_init(void)
+{
+ int err = twd_local_timer_register(&twd_local_timer);
+ if (err)
+ pr_err("twd_local_timer_register failed %d\n", err);
+}
+#endif
+
+#ifdef CONFIG_PLAT_AMBARELLA_LOCAL_TIMERS
+
+struct ambarella_local_clkevt {
+ struct clock_event_device *evt;
+ void __iomem *base;
+ void __iomem *ctrl_reg;
+ u32 ctrl_offset;
+ char name[16];
+};
+
+static DEFINE_PER_CPU(struct ambarella_local_clkevt, percpu_clkevt);
+
+static void __iomem *local_clkevt_base[NR_CPUS];
+static void __iomem *local_clkevt_ctrl_reg[NR_CPUS];
+static int local_clkevt_irq[NR_CPUS];
+static u32 local_clkevt_ctrl_offset[NR_CPUS];
+static struct irqaction local_clkevt_irqaction[NR_CPUS];
+
+/* ==========================================================================*/
+
+static void ambarella_local_ce_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *clkevt)
+{
+ struct ambarella_local_clkevt *local_clkevt;
+ void __iomem *base_reg;
+ void __iomem *ctrl_reg;
+ u32 ctrl_offset;
+
+ local_clkevt = this_cpu_ptr(&percpu_clkevt);
+ base_reg = local_clkevt->base;
+ ctrl_reg = local_clkevt->ctrl_reg;
+ ctrl_offset = local_clkevt->ctrl_offset;
+
+ ambarella_ce_set_mode(base_reg, ctrl_reg, ctrl_offset, mode, clkevt);
+}
+
+
+static int ambarella_local_ce_set_next_event(unsigned long delta,
+ struct clock_event_device *clkevt)
+{
+ struct ambarella_local_clkevt *local_clkevt;
+
+ local_clkevt = this_cpu_ptr(&percpu_clkevt);
+ ambarella_ce_set_next_event(local_clkevt->base, delta, clkevt);
+
+ return 0;
+}
+
+static irqreturn_t ambarella_local_ce_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *clkevt = dev_id;
+
+ clkevt->event_handler(clkevt);
+ return IRQ_HANDLED;
+}
+
+static int __cpuinit ambarella_local_timer_setup(struct clock_event_device *evt)
+{
+ struct ambarella_local_clkevt *local_clkevt;
+ unsigned int cpu = smp_processor_id();
+ int rval;
+
+ local_clkevt = this_cpu_ptr(&percpu_clkevt);
+ local_clkevt->evt = evt;
+ local_clkevt->base = local_clkevt_base[cpu];
+ local_clkevt->ctrl_reg = local_clkevt_ctrl_reg[cpu];
+ local_clkevt->ctrl_offset = local_clkevt_ctrl_offset[cpu];
+ sprintf(local_clkevt->name, "local_clkevt%d", cpu);
+
+ evt->name = local_clkevt->name;
+ evt->cpumask = cpumask_of(cpu);
+ evt->set_next_event = ambarella_local_ce_set_next_event;
+ evt->set_mode = ambarella_local_ce_set_mode;
+ evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
+ evt->rating = AMBARELLA_TIMER_RATING + 30;
+
+ clockevents_config_and_register(evt, AMBARELLA_TIMER_FREQ, 1, 0xffffffff);
+
+ evt->irq = local_clkevt_irq[cpu];
+ local_clkevt_irqaction[cpu].name = local_clkevt->name;
+ local_clkevt_irqaction[cpu].flags =
+ IRQF_TIMER | IRQF_TRIGGER_RISING | IRQF_NOBALANCING;
+ local_clkevt_irqaction[cpu].handler = ambarella_local_ce_interrupt;
+ local_clkevt_irqaction[cpu].dev_id = evt;
+
+ irq_set_affinity(evt->irq, cpumask_of(cpu));
+ rval = setup_irq(evt->irq, &local_clkevt_irqaction[cpu]);
+ if (rval) {
+ printk(KERN_ERR "Failed to register local timer IRQ: %d\n", rval);
+ BUG();
+ }
+
+ return 0;
+}
+
+
+static void ambarella_local_timer_stop(struct clock_event_device *evt)
+{
+ unsigned int cpu = smp_processor_id();
+
+ evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
+ remove_irq(evt->irq, &local_clkevt_irqaction[cpu]);
+}
+
+static struct local_timer_ops ambarella_local_timer_ops __cpuinitdata = {
+ .setup = ambarella_local_timer_setup,
+ .stop = ambarella_local_timer_stop,
+};
+
+/* ==========================================================================*/
+static const struct of_device_id local_clkevt_match[] __initconst = {
+ { .compatible = "ambarella,local-clock-event" },
+ { },
+};
+
+static void __init ambarella_local_clockevent_init(void)
+{
+ struct device_node *np;
+ int i, rval;
+
+ np = of_find_matching_node(NULL, local_clkevt_match);
+ if (!np) {
+ pr_err("Can't find local clock event node\n");
+ return;
+ }
+
+ for (i = 0; i < NR_CPUS; i++) {
+ local_clkevt_base[i] = of_iomap(np, i * 2);
+ if (!local_clkevt_base[i]) {
+ pr_err("%s: Failed to map event base[%d]\n", __func__, i);
+ return;
+ }
+
+ local_clkevt_ctrl_reg[i] = of_iomap(np, i * 2 + 1);
+ if (!local_clkevt_ctrl_reg[i]) {
+ pr_err("%s: Failed to map event base[%d]\n", __func__, i);
+ return;
+ }
+
+ local_clkevt_irq[i] = irq_of_parse_and_map(np, i);
+ if (local_clkevt_irq[i] <= 0) {
+ pr_err("%s: Can't get irq\n", __func__);
+ return;
+ }
+ }
+
+ rval = of_property_read_u32_array(np, "ctrl-offset",
+ local_clkevt_ctrl_offset, NR_CPUS);
+ if (rval < 0) {
+ pr_err("%s: Can't get local ctrl offset\n", __func__);
+ return;
+ }
+
+ of_node_put(np);
+
+ local_timer_register(&ambarella_local_timer_ops);
+}
+
+#endif
+
+
+void __init ambarella_timer_init(void)
+{
+ ambarella_clockevent_init();
+ ambarella_clocksource_init();
+
+#ifdef CONFIG_HAVE_ARM_TWD
+ ambarella_smp_twd_init();
+#endif
+#ifdef CONFIG_PLAT_AMBARELLA_LOCAL_TIMERS
+ ambarella_local_clockevent_init();
+#endif
+}
+
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index c6926eae..1e1df25d 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -878,6 +878,63 @@ config CACHE_PL310
This option enables optimisations for the PL310 cache
controller.
+config CACHE_PL310_EARLY_BRESP
+ bool "Enable early write response (BRESP) optmisation"
+ depends on CACHE_PL310
+ default n
+ help
+ The AXI protocol specifies that the write response can only be
+ sent back to an AXI master when the last write data has been
+ accepted. This optimization enables the L2CC (L2C-310) to send
+ the write response of certain write transactions as soon as the
+ store buffer accepts the write address
+
+config CACHE_PL310_PREFETCH_OFFSET
+ int "Prefetch offset"
+ range 0 31
+ depends on CACHE_PL310
+ default 0
+ help
+ When prefetch is enabled, if one of the slave ports receives
+ a cacheable read transaction, a cache lookup is performed on
+ the subsequent cache line. Bits [4:0] of the Prefetch Control
+ Register provide the address of the subsequent cache line.
+ If a miss occurs, the cache line is fetched from L3, and
+ allocated to the L2 cache.
+
+config CACHE_PL310_FULL_LINE_OF_ZERO
+ bool "Enable write full line of zero optimisation"
+ depends on CACHE_PL310
+ default n
+ help
+ When the L2CC (L2C-310) AXI slave ports receive a write
+ transaction with AWUSERSx[10], it indicates that the write
+ actually targets a whole cache line and that all data of
+ this cache line must be reset to zero. The Cortex-A9 processor
+ is likely to use this feature when a CPU is executing a memset
+ routine to initialise a particular memory area.
+
+ When the L2CC (L2C-310) receives such a write transaction it
+ ignores the AXI attributes attached to the transaction, size,
+ length, data, and strobes for example, because the whole cache
+ line must be reset.
+
+config CACHE_PL310_DOUBLE_LINEFILL
+ bool "Enable double linefill optimisation"
+ depends on CACHE_PL310
+ default n
+ help
+ The L2C-310 cache line length is 32-byte. Therefore, by default,
+ on each L2 cache miss, L2C-310 issues 32-byte linefills,
+ 4 x 64-bit read bursts, to the L3 memory system. L2C-310 can issue
+ 64-byte linefills, 8 x 64-bit read bursts, on an L2 cache miss.
+
+ When the L2C-310 is waiting for the data from L3, it performs a
+ lookup on the second cache line targeted by the 64-byte linefill.
+ If it misses, data corresponding to the second cache line are
+ allocated to the L2 cache. If it hits, data corresponding to the
+ second cache line are discarded.
+
config CACHE_TAUROS2
bool "Enable the Tauros2 L2 cache controller"
depends on (ARCH_DOVE || ARCH_MMP || CPU_PJ4)
@@ -909,7 +966,7 @@ config ARM_L1_CACHE_SHIFT
config ARM_DMA_MEM_BUFFERABLE
bool "Use non-cacheable memory for DMA" if (CPU_V6 || CPU_V6K) && !CPU_V7
depends on !(MACH_REALVIEW_PB1176 || REALVIEW_EB_ARM11MP || \
- MACH_REALVIEW_PB11MP)
+ MACH_REALVIEW_PB11MP || PLAT_AMBARELLA)
default y if CPU_V6 || CPU_V6K || CPU_V7
help
Historically, the kernel has used strongly ordered mappings to
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index 1fe0bf5c..a8e039cf 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -971,6 +971,14 @@ static int __init alignment_init(void)
set_cr(cr_alignment);
ai_usermode = safe_usermode(ai_usermode, false);
}
+#if defined(CONFIG_PLAT_AMBARELLA_A5S)
+ cr_alignment |= CR_A;
+ cr_no_alignment |= CR_A;
+ cr_alignment &= ~CR_U;
+ cr_no_alignment &= ~CR_U;
+ set_cr(cr_alignment);
+ ai_usermode = UM_FIXUP;
+#endif
#endif
hook_fault_code(FAULT_CODE_ALIGNMENT, do_alignment, SIGBUS, BUS_ADRALN,
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index c465faca..4bd092cf 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -34,6 +34,7 @@ static DEFINE_RAW_SPINLOCK(l2x0_lock);
static u32 l2x0_way_mask; /* Bitmask of active ways */
static u32 l2x0_size;
static unsigned long sync_reg_offset = L2X0_CACHE_SYNC;
+static const char *l2x0_type = NULL;
/* Aurora don't have the cache ID register available, so we have to
* pass it though the device tree */
@@ -133,6 +134,10 @@ static void l2x0_cache_sync(void)
unsigned long flags;
raw_spin_lock_irqsave(&l2x0_lock, flags);
+ if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
+ raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+ return;
+ }
cache_sync();
raw_spin_unlock_irqrestore(&l2x0_lock, flags);
}
@@ -152,6 +157,10 @@ static void l2x0_flush_all(void)
/* clean all ways */
raw_spin_lock_irqsave(&l2x0_lock, flags);
+ if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
+ raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+ return;
+ }
__l2x0_flush_all();
raw_spin_unlock_irqrestore(&l2x0_lock, flags);
}
@@ -162,6 +171,10 @@ static void l2x0_clean_all(void)
/* clean all ways */
raw_spin_lock_irqsave(&l2x0_lock, flags);
+ if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
+ raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+ return;
+ }
writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_WAY);
cache_wait_way(l2x0_base + L2X0_CLEAN_WAY, l2x0_way_mask);
cache_sync();
@@ -188,6 +201,10 @@ static void l2x0_inv_range(unsigned long start, unsigned long end)
unsigned long flags;
raw_spin_lock_irqsave(&l2x0_lock, flags);
+ if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
+ raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+ return;
+ }
if (start & (CACHE_LINE_SIZE - 1)) {
start &= ~(CACHE_LINE_SIZE - 1);
debug_writel(0x03);
@@ -232,6 +249,10 @@ static void l2x0_clean_range(unsigned long start, unsigned long end)
}
raw_spin_lock_irqsave(&l2x0_lock, flags);
+ if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
+ raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+ return;
+ }
start &= ~(CACHE_LINE_SIZE - 1);
while (start < end) {
unsigned long blk_end = start + min(end - start, 4096UL);
@@ -262,6 +283,10 @@ static void l2x0_flush_range(unsigned long start, unsigned long end)
}
raw_spin_lock_irqsave(&l2x0_lock, flags);
+ if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
+ raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+ return;
+ }
start &= ~(CACHE_LINE_SIZE - 1);
while (start < end) {
unsigned long blk_end = start + min(end - start, 4096UL);
@@ -283,6 +308,25 @@ static void l2x0_flush_range(unsigned long start, unsigned long end)
raw_spin_unlock_irqrestore(&l2x0_lock, flags);
}
+static void l2x0_enable(void)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&l2x0_lock, flags);
+ if (readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN) {
+ raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+ return;
+ }
+
+ writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
+ cache_wait_way(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
+ cache_sync();
+ writel_relaxed(1, l2x0_base + L2X0_CTRL);
+ raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+
+ printk(KERN_DEBUG "%s cache controller enabled\n", l2x0_type);
+}
+
static void l2x0_disable(void)
{
unsigned long flags;
@@ -294,6 +338,18 @@ static void l2x0_disable(void)
raw_spin_unlock_irqrestore(&l2x0_lock, flags);
}
+static int l2x0_is_enabled(void)
+{
+ unsigned long flags;
+ u32 status;
+
+ raw_spin_lock_irqsave(&l2x0_lock, flags);
+ status = readl_relaxed(l2x0_base + L2X0_CTRL);
+ raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+
+ return (status & L2X0_CTRL_EN);
+}
+
static void l2x0_unlock(u32 cache_id)
{
int lockregs;
@@ -320,14 +376,14 @@ static void l2x0_unlock(u32 cache_id)
}
}
-void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
+void l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
{
u32 aux;
u32 cache_id;
u32 way_size = 0;
int ways;
int way_size_shift = L2X0_WAY_SIZE_SHIFT;
- const char *type;
+// const char *type;
l2x0_base = base;
if (cache_id_part_number_from_dt)
@@ -346,7 +402,7 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
ways = 16;
else
ways = 8;
- type = "L310";
+ l2x0_type = "L310";
#ifdef CONFIG_PL310_ERRATA_753970
/* Unmapped register. */
sync_reg_offset = L2X0_DUMMY_REG;
@@ -356,7 +412,7 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
break;
case L2X0_CACHE_ID_PART_L210:
ways = (aux >> 13) & 0xf;
- type = "L210";
+ l2x0_type = "L210";
break;
case AURORA_CACHE_ID:
@@ -364,12 +420,12 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
ways = (aux >> 13) & 0xf;
ways = 2 << ((ways + 1) >> 2);
way_size_shift = AURORA_WAY_SIZE_SHIFT;
- type = "Aurora";
+ l2x0_type = "Aurora";
break;
default:
/* Assume unknown chips have 8 ways */
ways = 8;
- type = "L2x0 series";
+ l2x0_type = "L2x0 series";
break;
}
@@ -414,10 +470,13 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
outer_cache.sync = l2x0_cache_sync;
outer_cache.flush_all = l2x0_flush_all;
outer_cache.inv_all = l2x0_inv_all;
+ outer_cache.clean_all = l2x0_clean_all;
outer_cache.disable = l2x0_disable;
+ outer_cache.enable = l2x0_enable;
+ outer_cache.is_enabled = l2x0_is_enabled;
}
- printk(KERN_INFO "%s cache controller enabled\n", type);
+ printk(KERN_INFO "%s cache controller enabled\n", l2x0_type);
printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n",
ways, cache_id, aux, l2x0_size);
}
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 4c7d5cdd..5cc87612 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -418,7 +418,9 @@ static void __init build_mem_type_table(void)
* (Uncached Normal memory)
*/
mem_types[MT_DEVICE].prot_sect |= PMD_SECT_TEX(1);
+#if !defined(CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK)
mem_types[MT_DEVICE_NONSHARED].prot_sect |= PMD_SECT_TEX(1);
+#endif
mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_BUFFERABLE;
} else if (cpu_is_xsc3()) {
/*
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 4562ebf8..2fde3b21 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -324,6 +324,12 @@ __v7_setup:
mcrlt p15, 0, r10, c15, c0, 1 @ write diagnostic register
1:
#endif
+ mrc p15, 0, r10, c1, c0, 1 @ read aux control register
+ orr r10, r10, #(1 << 2) @ set Dside prefetch to 1
+#ifdef CONFIG_CACHE_PL310
+ orr r10, r10, #(1 << 1) @ set Prefetch hint to 1
+#endif
+ mcr p15, 0, r10, c1, c0, 1 @ write aux control register
3: mov r10, #0
mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index a10297da..6c84ce0a 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -232,6 +232,7 @@ micro9m MACH_MICRO9M MICRO9M 1169
bug MACH_BUG BUG 1179
at91sam9263ek MACH_AT91SAM9263EK AT91SAM9263EK 1202
em7210 MACH_EM7210 EM7210 1212
+ambarella MACH_AMBARELLA AMBARELLA 1223
vpac270 MACH_VPAC270 VPAC270 1227
treo680 MACH_TREO680 TREO680 1230
zylonite MACH_ZYLONITE ZYLONITE 1233
@@ -491,6 +492,8 @@ smdkc210 MACH_SMDKC210 SMDKC210 2838
t5325 MACH_T5325 T5325 2846
income MACH_INCOME INCOME 2849
goni MACH_GONI GONI 2862
+coconut MACH_COCONUT COCONUT 2872
+durian MACH_DURIAN DURIAN 2873
bv07 MACH_BV07 BV07 2882
openrd_ultimate MACH_OPENRD_ULTIMATE OPENRD_ULTIMATE 2884
devixp MACH_DEVIXP DEVIXP 2885
@@ -522,6 +525,7 @@ torbreck MACH_TORBRECK TORBRECK 3090
prima2_evb MACH_PRIMA2_EVB PRIMA2_EVB 3103
paz00 MACH_PAZ00 PAZ00 3128
acmenetusfoxg20 MACH_ACMENETUSFOXG20 ACMENETUSFOXG20 3129
+elephant MACH_ELEPHANT ELEPHANT 3180
ag5evm MACH_AG5EVM AG5EVM 3189
ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206
wlf_cragg_6410 MACH_WLF_CRAGG_6410 WLF_CRAGG_6410 3207
@@ -619,6 +623,8 @@ th_link_eth MACH_TH_LINK_ETH TH_LINK_ETH 4156
tn_muninn MACH_TN_MUNINN TN_MUNINN 4157
rampage MACH_RAMPAGE RAMPAGE 4158
visstrim_mv10 MACH_VISSTRIM_MV10 VISSTRIM_MV10 4159
+hyacinth_0 MACH_HYACINTH_0 HYACINTH_0 4221
+hyacinth_1 MACH_HYACINTH_1 HYACINTH_1 4222
mx28_wilma MACH_MX28_WILMA MX28_WILMA 4164
msm8625_ffa MACH_MSM8625_FFA MSM8625_FFA 4166
vpu101 MACH_VPU101 VPU101 4167
@@ -1007,3 +1013,6 @@ eco5_bx2 MACH_ECO5_BX2 ECO5_BX2 4572
eukrea_cpuimx28sd MACH_EUKREA_CPUIMX28SD EUKREA_CPUIMX28SD 4573
domotab MACH_DOMOTAB DOMOTAB 4574
pfla03 MACH_PFLA03 PFLA03 4575
+ixora MACH_IXORA IXORA 4603
+juglans MACH_JUGLANS JUGLANS 4604
+ambs2e MACH_AMBS2E AMBS2E 5009
\ No newline at end of file
diff --git a/arch/blackfin/include/asm/ftrace.h b/arch/blackfin/include/asm/ftrace.h
index 8a029505..2f1c3c26 100644
--- a/arch/blackfin/include/asm/ftrace.h
+++ b/arch/blackfin/include/asm/ftrace.h
@@ -66,16 +66,7 @@ extern inline void *return_address(unsigned int level)
#endif /* CONFIG_FRAME_POINTER */
-#define HAVE_ARCH_CALLER_ADDR
-
-/* inline function or macro may lead to unexpected result */
-#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
-#define CALLER_ADDR1 ((unsigned long)return_address(1))
-#define CALLER_ADDR2 ((unsigned long)return_address(2))
-#define CALLER_ADDR3 ((unsigned long)return_address(3))
-#define CALLER_ADDR4 ((unsigned long)return_address(4))
-#define CALLER_ADDR5 ((unsigned long)return_address(5))
-#define CALLER_ADDR6 ((unsigned long)return_address(6))
+#define ftrace_return_address(n) return_address(n)
#endif /* __ASSEMBLY__ */
diff --git a/arch/parisc/include/asm/ftrace.h b/arch/parisc/include/asm/ftrace.h
index 72c0fafa..544ed8ef 100644
--- a/arch/parisc/include/asm/ftrace.h
+++ b/arch/parisc/include/asm/ftrace.h
@@ -24,15 +24,7 @@ extern void return_to_handler(void);
extern unsigned long return_address(unsigned int);
-#define HAVE_ARCH_CALLER_ADDR
-
-#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
-#define CALLER_ADDR1 return_address(1)
-#define CALLER_ADDR2 return_address(2)
-#define CALLER_ADDR3 return_address(3)
-#define CALLER_ADDR4 return_address(4)
-#define CALLER_ADDR5 return_address(5)
-#define CALLER_ADDR6 return_address(6)
+#define ftrace_return_address(n) return_address(n)
#endif /* __ASSEMBLY__ */
diff --git a/arch/sh/include/asm/ftrace.h b/arch/sh/include/asm/ftrace.h
index 13e99664..e79fb6eb 100644
--- a/arch/sh/include/asm/ftrace.h
+++ b/arch/sh/include/asm/ftrace.h
@@ -40,15 +40,7 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr)
/* arch/sh/kernel/return_address.c */
extern void *return_address(unsigned int);
-#define HAVE_ARCH_CALLER_ADDR
-
-#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
-#define CALLER_ADDR1 ((unsigned long)return_address(1))
-#define CALLER_ADDR2 ((unsigned long)return_address(2))
-#define CALLER_ADDR3 ((unsigned long)return_address(3))
-#define CALLER_ADDR4 ((unsigned long)return_address(4))
-#define CALLER_ADDR5 ((unsigned long)return_address(5))
-#define CALLER_ADDR6 ((unsigned long)return_address(6))
+#define ftrace_return_address(n) return_address(n)
#endif /* __ASSEMBLY__ */
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 2b086a6a..c1656c85 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -17,6 +17,7 @@ config XTENSA
select CLONE_BACKWARDS
select IRQ_DOMAIN
select HAVE_OPROFILE
+ select HAVE_FUNCTION_TRACER
help
Xtensa processors are 32-bit RISC machines designed by Tensilica
primarily for embedded systems. These processors are both
diff --git a/arch/xtensa/boot/lib/Makefile b/arch/xtensa/boot/lib/Makefile
index ad8952e8..6868f2ca 100644
--- a/arch/xtensa/boot/lib/Makefile
+++ b/arch/xtensa/boot/lib/Makefile
@@ -7,6 +7,13 @@ zlib := inffast.c inflate.c inftrees.c
lib-y += $(zlib:.c=.o) zmem.o
ccflags-y := -Ilib/zlib_inflate
+ifdef CONFIG_FUNCTION_TRACER
+CFLAGS_REMOVE_inflate.o = -pg
+CFLAGS_REMOVE_zmem.o = -pg
+CFLAGS_REMOVE_inftrees.o = -pg
+CFLAGS_REMOVE_inffast.o = -pg
+endif
+
quiet_cmd_copy_zlib = COPY $@
cmd_copy_zlib = cat $< > $@
diff --git a/arch/xtensa/include/asm/ftrace.h b/arch/xtensa/include/asm/ftrace.h
index 36dc7a68..6c6d9a9f 100644
--- a/arch/xtensa/include/asm/ftrace.h
+++ b/arch/xtensa/include/asm/ftrace.h
@@ -12,22 +12,29 @@
#include <asm/processor.h>
-#define HAVE_ARCH_CALLER_ADDR
-#define CALLER_ADDR0 ({ unsigned long a0, a1; \
+#ifndef __ASSEMBLY__
+#define ftrace_return_address0 ({ unsigned long a0, a1; \
__asm__ __volatile__ ( \
"mov %0, a0\n" \
"mov %1, a1\n" \
- : "=r"(a0), "=r"(a1) : : ); \
+ : "=r"(a0), "=r"(a1)); \
MAKE_PC_FROM_RA(a0, a1); })
+
#ifdef CONFIG_FRAME_POINTER
extern unsigned long return_address(unsigned level);
-#define CALLER_ADDR1 return_address(1)
-#define CALLER_ADDR2 return_address(2)
-#define CALLER_ADDR3 return_address(3)
-#else
-#define CALLER_ADDR1 (0)
-#define CALLER_ADDR2 (0)
-#define CALLER_ADDR3 (0)
+#define ftrace_return_address(n) return_address(n)
#endif
+#endif /* __ASSEMBLY__ */
+
+#ifdef CONFIG_FUNCTION_TRACER
+
+#define MCOUNT_ADDR ((unsigned long)(_mcount))
+#define MCOUNT_INSN_SIZE 3
+
+#ifndef __ASSEMBLY__
+extern void _mcount(void);
+#define mcount _mcount
+#endif /* __ASSEMBLY__ */
+#endif /* CONFIG_FUNCTION_TRACER */
#endif /* _XTENSA_FTRACE_H */
diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile
index 1e7fc87a..f90265ec 100644
--- a/arch/xtensa/kernel/Makefile
+++ b/arch/xtensa/kernel/Makefile
@@ -11,6 +11,7 @@ obj-y := align.o coprocessor.o entry.o irq.o pci-dma.o platform.o process.o \
obj-$(CONFIG_KGDB) += xtensa-stub.o
obj-$(CONFIG_PCI) += pci.o
obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o
+obj-$(CONFIG_FUNCTION_TRACER) += mcount.o
AFLAGS_head.o += -mtext-section-literals
diff --git a/arch/xtensa/kernel/mcount.S b/arch/xtensa/kernel/mcount.S
new file mode 100644
index 00000000..0eeda2e4
--- /dev/null
+++ b/arch/xtensa/kernel/mcount.S
@@ -0,0 +1,50 @@
+/*
+ * arch/xtensa/kernel/mcount.S
+ *
+ * Xtensa specific mcount support
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2013 Tensilica Inc.
+ */
+
+#include <linux/linkage.h>
+#include <asm/ftrace.h>
+
+/*
+ * Entry condition:
+ *
+ * a2: a0 of the caller
+ */
+
+ENTRY(_mcount)
+
+ entry a1, 16
+
+ movi a4, ftrace_trace_function
+ l32i a4, a4, 0
+ movi a3, ftrace_stub
+ bne a3, a4, 1f
+ retw
+
+1: xor a7, a2, a1
+ movi a3, 0x3fffffff
+ and a7, a7, a3
+ xor a7, a7, a1
+
+ xor a6, a0, a1
+ and a6, a6, a3
+ xor a6, a6, a1
+ addi a6, a6, -MCOUNT_INSN_SIZE
+ callx4 a4
+
+ retw
+
+ENDPROC(_mcount)
+
+ENTRY(ftrace_stub)
+ entry a1, 16
+ retw
+ENDPROC(ftrace_stub)
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c
index 42c53c87..d8507f81 100644
--- a/arch/xtensa/kernel/xtensa_ksyms.c
+++ b/arch/xtensa/kernel/xtensa_ksyms.c
@@ -124,3 +124,7 @@ extern long common_exception_return;
extern long _spill_registers;
EXPORT_SYMBOL(common_exception_return);
EXPORT_SYMBOL(_spill_registers);
+
+#ifdef CONFIG_FUNCTION_TRACER
+EXPORT_SYMBOL(_mcount);
+#endif
diff --git a/block/partitions/Kconfig b/block/partitions/Kconfig
index 75a54e1a..2dfa35ae 100644
--- a/block/partitions/Kconfig
+++ b/block/partitions/Kconfig
@@ -249,3 +249,11 @@ config SYSV68_PARTITION
partition table format used by Motorola Delta machines (using
sysv68).
Otherwise, say N.
+
+config AMBPTB_PARTITION
+ bool "Ambarella partition table support" if PARTITION_ADVANCED
+ default y if ARCH_AMBARELLA
+ help
+ Say Y here if you would like to be able to read the MMC/SD
+ partition table format used by Amboot.
+ Otherwise, say N.
diff --git a/block/partitions/Makefile b/block/partitions/Makefile
index 03af8eac..7ea7ecd4 100644
--- a/block/partitions/Makefile
+++ b/block/partitions/Makefile
@@ -18,3 +18,5 @@ obj-$(CONFIG_IBM_PARTITION) += ibm.o
obj-$(CONFIG_EFI_PARTITION) += efi.o
obj-$(CONFIG_KARMA_PARTITION) += karma.o
obj-$(CONFIG_SYSV68_PARTITION) += sysv68.o
+obj-$(CONFIG_AMBPTB_PARTITION) += ambptb.o
+
diff --git a/block/partitions/ambptb.c b/block/partitions/ambptb.c
new file mode 100644
index 00000000..528482a5
--- /dev/null
+++ b/block/partitions/ambptb.c
@@ -0,0 +1,117 @@
+/*
+ * fs/partitions/ambptb.c
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "check.h"
+#include "ambptb.h"
+#include <plat/ptb.h>
+#include <linux/of.h>
+
+//#define ambptb_prt
+
+#ifdef ambptb_prt
+#define ambptb_prt printk
+#else
+#define ambptb_prt(format, arg...) do {} while (0)
+#endif
+
+int ambptb_partition(struct parsed_partitions *state)
+{
+ int i, val, slot = 1;
+ unsigned char *data;
+ Sector sect;
+ u32 sect_size, sect_offset, sect_address, ptb_address;
+ flpart_meta_t *ptb_meta;
+ char ptb_tmp[1 + BDEVNAME_SIZE + 1];
+ int result = 0;
+ struct device_node * np;
+
+ sect_size = bdev_logical_block_size(state->bdev);
+ sect_offset = (sizeof(ptb_header_t) + sizeof(flpart_table_t)) % sect_size;
+
+ np = of_find_node_with_property(NULL, "amb,ptb_address");
+ if(!np)
+ return -1;
+
+ val = of_property_read_u32(np, "amb,ptb_address", &ptb_address);
+ if(val < 0)
+ return -1;
+
+ sect_address = (ptb_address * sect_size + sizeof(ptb_header_t) + sizeof(flpart_table_t)) / sect_size;
+ data = read_part_sector(state, sect_address, &sect);
+ if (!data) {
+ result = -1;
+ goto ambptb_partition_exit;
+ }
+
+ ptb_meta = (flpart_meta_t *)(data + sect_offset);
+ ambptb_prt("%s: magic[0x%08X]\n", __func__, ptb_meta->magic);
+ if (ptb_meta->magic == PTB_META_MAGIC3) {
+ for (i = 0; i < PART_MAX; i++) {
+ if (slot >= state->limit)
+ break;
+
+ if (((ptb_meta->part_info[i].dev & PART_DEV_EMMC) ==
+ PART_DEV_EMMC) &&
+ (ptb_meta->part_info[i].nblk)) {
+ state->parts[slot].from =
+ ptb_meta->part_info[i].sblk;
+ state->parts[slot].size =
+ ptb_meta->part_info[i].nblk;
+ snprintf(ptb_tmp, sizeof(ptb_tmp), " %s",
+ ptb_meta->part_info[i].name);
+ strlcat(state->pp_buf, ptb_tmp, PAGE_SIZE);
+ ambptb_prt("%s: %s [p%d]\n", __func__,
+ ptb_meta->part_info[i].name, slot);
+ slot++;
+ }
+ }
+ strlcat(state->pp_buf, "\n", PAGE_SIZE);
+ result = 1;
+ } else if ((ptb_meta->magic == PTB_META_MAGIC) ||
+ (ptb_meta->magic == PTB_META_MAGIC2)) {
+ for (i = 0; i < PART_MAX; i++) {
+ if (slot >= state->limit)
+ break;
+ if ((ptb_meta->part_info[i].dev == BOOT_DEV_SM) &&
+ (ptb_meta->part_info[i].nblk)) {
+ state->parts[slot].from =
+ ptb_meta->part_info[i].sblk;
+ state->parts[slot].size =
+ ptb_meta->part_info[i].nblk;
+ snprintf(ptb_tmp, sizeof(ptb_tmp), " %s",
+ ptb_meta->part_info[i].name);
+ strlcat(state->pp_buf, ptb_tmp, PAGE_SIZE);
+ ambptb_prt("%s: %s [p%d]\n", __func__,
+ ptb_meta->part_info[i].name, slot);
+ slot++;
+ }
+ }
+ strlcat(state->pp_buf, "\n", PAGE_SIZE);
+ result = 1;
+ }
+ put_dev_sector(sect);
+
+ambptb_partition_exit:
+ return result;
+}
+
diff --git a/block/partitions/ambptb.h b/block/partitions/ambptb.h
new file mode 100644
index 00000000..90d19577
--- /dev/null
+++ b/block/partitions/ambptb.h
@@ -0,0 +1,25 @@
+/*
+ * fs/partitions/ambptb.h
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2010, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+int ambptb_partition(struct parsed_partitions *state);
+
diff --git a/block/partitions/check.c b/block/partitions/check.c
index 19ba207e..1a13b19c 100644
--- a/block/partitions/check.c
+++ b/block/partitions/check.c
@@ -34,6 +34,7 @@
#include "efi.h"
#include "karma.h"
#include "sysv68.h"
+#include "ambptb.h"
int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/
@@ -103,6 +104,9 @@ static int (*check_part[])(struct parsed_partitions *) = {
#endif
#ifdef CONFIG_SYSV68_PARTITION
sysv68_partition,
+#endif
+#ifdef CONFIG_AMBPTB_PARTITION
+ ambptb_partition,
#endif
NULL
};
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c
index a79e7e9a..a49a9be4 100644
--- a/crypto/blkcipher.c
+++ b/crypto/blkcipher.c
@@ -34,6 +34,8 @@ enum {
BLKCIPHER_WALK_SLOW = 1 << 1,
BLKCIPHER_WALK_COPY = 1 << 2,
BLKCIPHER_WALK_DIFF = 1 << 3,
+ AMBA_CIPHER_COPY = 1 << 4,
+ // add for amba crypto interrupt mode -- cddiao <cddiao@ambarella.com>
};
static int blkcipher_walk_next(struct blkcipher_desc *desc,
diff --git a/crypto/des_generic.c b/crypto/des_generic.c
index 3ec60713..1bdfab31 100644
--- a/crypto/des_generic.c
+++ b/crypto/des_generic.c
@@ -367,7 +367,7 @@ static const u32 pc2[1024] = {
/* S-box lookup tables */
-static const u32 S1[64] = {
+static const u32 S_1[64] = {
0x01010400, 0x00000000, 0x00010000, 0x01010404,
0x01010004, 0x00010404, 0x00000004, 0x00010000,
0x00000400, 0x01010400, 0x01010404, 0x00000400,
@@ -386,7 +386,7 @@ static const u32 S1[64] = {
0x00010004, 0x00010400, 0x00000000, 0x01010004
};
-static const u32 S2[64] = {
+static const u32 S_2[64] = {
0x80108020, 0x80008000, 0x00008000, 0x00108020,
0x00100000, 0x00000020, 0x80100020, 0x80008020,
0x80000020, 0x80108020, 0x80108000, 0x80000000,
@@ -405,7 +405,7 @@ static const u32 S2[64] = {
0x80000000, 0x80100020, 0x80108020, 0x00108000
};
-static const u32 S3[64] = {
+static const u32 S_3[64] = {
0x00000208, 0x08020200, 0x00000000, 0x08020008,
0x08000200, 0x00000000, 0x00020208, 0x08000200,
0x00020008, 0x08000008, 0x08000008, 0x00020000,
@@ -424,7 +424,7 @@ static const u32 S3[64] = {
0x00020208, 0x00000008, 0x08020008, 0x00020200
};
-static const u32 S4[64] = {
+static const u32 S_4[64] = {
0x00802001, 0x00002081, 0x00002081, 0x00000080,
0x00802080, 0x00800081, 0x00800001, 0x00002001,
0x00000000, 0x00802000, 0x00802000, 0x00802081,
@@ -443,7 +443,7 @@ static const u32 S4[64] = {
0x00000080, 0x00800000, 0x00002000, 0x00802080
};
-static const u32 S5[64] = {
+static const u32 S_5[64] = {
0x00000100, 0x02080100, 0x02080000, 0x42000100,
0x00080000, 0x00000100, 0x40000000, 0x02080000,
0x40080100, 0x00080000, 0x02000100, 0x40080100,
@@ -462,7 +462,7 @@ static const u32 S5[64] = {
0x00000000, 0x40080000, 0x02080100, 0x40000100
};
-static const u32 S6[64] = {
+static const u32 S_6[64] = {
0x20000010, 0x20400000, 0x00004000, 0x20404010,
0x20400000, 0x00000010, 0x20404010, 0x00400000,
0x20004000, 0x00404010, 0x00400000, 0x20000010,
@@ -481,7 +481,7 @@ static const u32 S6[64] = {
0x20404000, 0x20000000, 0x00400010, 0x20004010
};
-static const u32 S7[64] = {
+static const u32 S_7[64] = {
0x00200000, 0x04200002, 0x04000802, 0x00000000,
0x00000800, 0x04000802, 0x00200802, 0x04200800,
0x04200802, 0x00200000, 0x00000000, 0x04000002,
@@ -500,7 +500,7 @@ static const u32 S7[64] = {
0x04000002, 0x04000800, 0x00000800, 0x00200002
};
-static const u32 S8[64] = {
+static const u32 S_8[64] = {
0x10001040, 0x00001000, 0x00040000, 0x10041040,
0x10000000, 0x10001040, 0x00000040, 0x10000000,
0x00040040, 0x10040000, 0x10041040, 0x00041000,
@@ -591,14 +591,14 @@ static const u32 S8[64] = {
B = K[0]; A = K[1]; K += d; \
B ^= R; A ^= R; \
B &= 0x3f3f3f3f; ROR(A, 4); \
- L ^= S8[0xff & B]; A &= 0x3f3f3f3f; \
- L ^= S6[0xff & (B >> 8)]; B >>= 16; \
- L ^= S7[0xff & A]; \
- L ^= S5[0xff & (A >> 8)]; A >>= 16; \
- L ^= S4[0xff & B]; \
- L ^= S2[0xff & (B >> 8)]; \
- L ^= S3[0xff & A]; \
- L ^= S1[0xff & (A >> 8)];
+ L ^= S_8[0xff & B]; A &= 0x3f3f3f3f; \
+ L ^= S_6[0xff & (B >> 8)]; B >>= 16; \
+ L ^= S_7[0xff & A]; \
+ L ^= S_5[0xff & (A >> 8)]; A >>= 16; \
+ L ^= S_4[0xff & B]; \
+ L ^= S_2[0xff & (B >> 8)]; \
+ L ^= S_3[0xff & A]; \
+ L ^= S_1[0xff & (A >> 8)];
/*
* PC2 lookup tables are organized as 2 consecutive sets of 4 interleaved
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index 10b14d45..dea026c9 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -36,6 +36,14 @@
#define _AHCI_H
#include <linux/clk.h>
+
+#if defined(CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK)
+#undef writel
+#undef readl
+#define writel(v, p) amba_writel(p, v)
+#define readl(p) amba_readl(p)
+#endif
+
#include <linux/libata.h>
/* Enclosure Management Control */
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 4e22ce3e..9b10139b 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -1,7 +1,7 @@
# Makefile for the Linux device tree
obj-y := core.o bus.o dd.o syscore.o \
- driver.o class.o platform.o \
+ driver.o class.o platform.o ambbus.o ambpriv.o \
cpu.o firmware.o init.o map.o devres.o \
attribute_container.o transport_class.o \
topology.o
diff --git a/drivers/base/ambbus.c b/drivers/base/ambbus.c
new file mode 100644
index 00000000..6866d986
--- /dev/null
+++ b/drivers/base/ambbus.c
@@ -0,0 +1,180 @@
+/*
+ * AMB bus.
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/ambbus.h>
+
+static struct device amb_bus = {
+ .init_name = "ambbus"
+};
+
+struct amb_dev {
+ struct device dev;
+ struct device *next;
+};
+
+#define to_amb_dev(x) container_of((x), struct amb_dev, dev)
+
+static int amb_bus_match(struct device *dev, struct device_driver *driver)
+{
+ struct amb_driver *amb_driver = to_amb_driver(driver);
+
+ if (dev->platform_data == amb_driver) {
+ if (!amb_driver->match || amb_driver->match(dev))
+ return 1;
+ dev->platform_data = NULL;
+ }
+ return 0;
+}
+
+static int amb_bus_probe(struct device *dev)
+{
+ struct amb_driver *amb_driver = dev->platform_data;
+
+ if (amb_driver->probe)
+ return amb_driver->probe(dev);
+
+ return 0;
+}
+
+static int amb_bus_remove(struct device *dev)
+{
+ struct amb_driver *amb_driver = dev->platform_data;
+
+ if (amb_driver->remove)
+ return amb_driver->remove(dev);
+
+ return 0;
+}
+
+static void amb_bus_shutdown(struct device *dev)
+{
+ struct amb_driver *amb_driver = dev->platform_data;
+
+ if (amb_driver->shutdown)
+ amb_driver->shutdown(dev);
+}
+
+static int amb_bus_suspend(struct device *dev, pm_message_t state)
+{
+ struct amb_driver *amb_driver = dev->platform_data;
+
+ if (amb_driver->suspend)
+ return amb_driver->suspend(dev, state);
+
+ return 0;
+}
+
+static int amb_bus_resume(struct device *dev)
+{
+ struct amb_driver *amb_driver = dev->platform_data;
+
+ if (amb_driver->resume)
+ return amb_driver->resume(dev);
+
+ return 0;
+}
+
+static struct bus_type amb_bus_type = {
+ .name = "ambbus",
+ .match = amb_bus_match,
+ .probe = amb_bus_probe,
+ .remove = amb_bus_remove,
+ .shutdown = amb_bus_shutdown,
+ .suspend = amb_bus_suspend,
+ .resume = amb_bus_resume
+};
+
+static void amb_dev_release(struct device *dev)
+{
+ kfree(to_amb_dev(dev));
+}
+
+void amb_unregister_driver(struct amb_driver *amb_driver)
+{
+ struct device *dev = amb_driver->devices;
+
+ while (dev) {
+ struct device *tmp = to_amb_dev(dev)->next;
+ device_unregister(dev);
+ dev = tmp;
+ }
+ driver_unregister(&amb_driver->driver);
+}
+EXPORT_SYMBOL(amb_unregister_driver);
+
+int amb_register_driver(struct amb_driver *amb_driver)
+{
+ int error;
+ unsigned int id;
+
+ amb_driver->driver.bus = &amb_bus_type;
+ amb_driver->devices = NULL;
+
+ error = driver_register(&amb_driver->driver);
+ if (error)
+ return error;
+
+ for (id = 0; id < 1; id++) {
+ struct amb_dev *amb_dev;
+
+ amb_dev = kzalloc(sizeof *amb_dev, GFP_KERNEL);
+ if (!amb_dev) {
+ error = -ENOMEM;
+ break;
+ }
+
+ amb_dev->dev.parent = &amb_bus;
+ amb_dev->dev.bus = &amb_bus_type;
+
+ dev_set_name(&amb_dev->dev, "%s",
+ amb_driver->driver.name);
+ amb_dev->dev.platform_data = amb_driver;
+ amb_dev->dev.release = amb_dev_release;
+
+ amb_dev->dev.coherent_dma_mask = DMA_BIT_MASK(24);
+ amb_dev->dev.dma_mask = &amb_dev->dev.coherent_dma_mask;
+
+ error = device_register(&amb_dev->dev);
+ if (error) {
+ put_device(&amb_dev->dev);
+ break;
+ }
+
+ if (amb_dev->dev.platform_data) {
+ amb_dev->next = amb_driver->devices;
+ amb_driver->devices = &amb_dev->dev;
+ } else
+ device_unregister(&amb_dev->dev);
+ }
+
+ if (!error && !amb_driver->devices)
+ error = -ENODEV;
+
+ if (error)
+ amb_unregister_driver(amb_driver);
+
+ return error;
+}
+EXPORT_SYMBOL(amb_register_driver);
+
+static int __init amb_bus_init(void)
+{
+ int error;
+
+ error = bus_register(&amb_bus_type);
+ if (!error) {
+ error = device_register(&amb_bus);
+ if (error)
+ bus_unregister(&amb_bus_type);
+ }
+ return error;
+}
+
+device_initcall(amb_bus_init);
diff --git a/drivers/base/ambpriv.c b/drivers/base/ambpriv.c
new file mode 100644
index 00000000..135b6312
--- /dev/null
+++ b/drivers/base/ambpriv.c
@@ -0,0 +1,796 @@
+/*
+ * ambpriv.c
+ *
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * Copyright (C) 2012-2016, Ambarella, Inc.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/pm_runtime.h>
+#include <linux/ambpriv_device.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include "base.h"
+
+#define to_ambpriv_driver(drv) (container_of((drv), struct ambpriv_driver, driver))
+
+struct device ambpriv_bus = {
+ .init_name = "ambpriv",
+};
+
+static int of_ambpriv_match_device(struct device *dev, void *match)
+{
+ return !!of_match_device(match, dev);
+}
+
+struct ambpriv_device *of_find_ambpriv_device_by_match(struct of_device_id *match)
+{
+ struct device *dev;
+
+ dev = bus_find_device(&ambpriv_bus_type, NULL, match, of_ambpriv_match_device);
+ return dev ? to_ambpriv_device(dev) : NULL;
+}
+EXPORT_SYMBOL(of_find_ambpriv_device_by_match);
+
+static int of_ambpriv_node_device(struct device *dev, void *data)
+{
+ return dev->of_node == data;
+}
+
+struct ambpriv_device *of_find_ambpriv_device_by_node(struct device_node *np)
+{
+ struct device *dev;
+
+ dev = bus_find_device(&ambpriv_bus_type, NULL, np, of_ambpriv_node_device);
+ return dev ? to_ambpriv_device(dev) : NULL;
+}
+EXPORT_SYMBOL(of_find_ambpriv_device_by_node);
+
+int ambpriv_get_irq(struct ambpriv_device *dev, unsigned int num)
+{
+ struct resource *r = NULL;
+ int i;
+
+ if (dev == NULL)
+ return -ENODEV;
+
+ for (i = 0; i < dev->num_resources; i++) {
+ r = &dev->resource[i];
+ if ((resource_type(r) == IORESOURCE_IRQ) && num-- == 0)
+ break;
+ }
+
+ if (i == dev->num_resources)
+ return -ENXIO;
+
+ if (r && r->flags & IORESOURCE_BITS)
+ irqd_set_trigger_type(irq_get_irq_data(r->start),
+ r->flags & IORESOURCE_BITS);
+
+ return r->start;
+}
+EXPORT_SYMBOL(ambpriv_get_irq);
+
+int ambpriv_get_irq_by_name(struct ambpriv_device *dev, const char *name)
+{
+ struct resource *r = NULL;
+ int i;
+
+ if (dev == NULL)
+ return -ENODEV;
+
+ for (i = 0; i < dev->num_resources; i++) {
+ r = &dev->resource[i];
+
+ if (unlikely(!r->name))
+ continue;
+
+ if ((resource_type(r) == IORESOURCE_IRQ) && !strcmp(r->name, name))
+ break;
+ }
+
+ if (i == dev->num_resources)
+ return -ENXIO;
+
+ return r->start;
+}
+EXPORT_SYMBOL(ambpriv_get_irq_by_name);
+
+static struct ambpriv_device *of_ambpriv_device_alloc(struct device_node *np,
+ struct device *parent)
+{
+ struct ambpriv_device *dev;
+ const __be32 *reg_prop;
+ struct resource *res;
+ int psize, i, num_reg = 0, num_irq;
+
+ dev = ambpriv_device_alloc("", -1);
+ if (!dev)
+ return NULL;
+
+ reg_prop = of_get_property(np, "reg", &psize);
+ if (reg_prop)
+ num_reg = psize / sizeof(u32) / 2;
+
+
+ num_irq = of_irq_count(np);
+
+ if (num_reg || num_irq) {
+ res = kzalloc(sizeof(*res) * (num_irq + num_reg), GFP_KERNEL);
+ if (!res) {
+ ambpriv_device_put(dev);
+ return NULL;
+ }
+
+ dev->resource = res;
+ dev->num_resources = num_reg + num_irq;
+
+ for (i = 0; i < num_reg; i++, res++, reg_prop += 2) {
+ res->start = be32_to_cpup(reg_prop);
+ res->end = res->start + be32_to_cpup(reg_prop + 1) - 1;
+ res->flags = IORESOURCE_MEM;
+ }
+
+ of_irq_to_resource_table(np, res, num_irq);
+ }
+
+ dev->dev.of_node = of_node_get(np);
+ dev->dev.parent = parent ? : &ambpriv_bus;
+ of_device_make_bus_id(&dev->dev);
+ dev->name = dev_name(&dev->dev);
+
+ return dev;
+}
+
+static struct ambpriv_device *of_ambpriv_device_create_pdata(
+ struct device_node *np, struct device *parent)
+{
+ struct ambpriv_device *dev;
+
+ dev = of_ambpriv_device_alloc(np, parent);
+ if (!dev)
+ return NULL;
+
+ if (ambpriv_device_add(dev) < 0) {
+ ambpriv_device_put(dev);
+ return NULL;
+ }
+
+ return dev;
+}
+
+static int of_ambpriv_bus_create(struct device_node *bus,
+ const struct of_device_id *matches, struct device *parent)
+{
+ struct device_node *child;
+ struct ambpriv_device *dev;
+ int rc = 0;
+
+ /* Make sure it has a compatible property */
+ if (!of_get_property(bus, "compatible", NULL))
+ return 0;
+
+ dev = of_ambpriv_device_create_pdata(bus, parent);
+ if (!dev || !of_match_node(matches, bus))
+ return 0;
+
+ for_each_child_of_node(bus, child) {
+ rc = of_ambpriv_bus_create(child, matches, &dev->dev);
+ if (rc) {
+ of_node_put(child);
+ break;
+ }
+ }
+
+ return rc;
+}
+
+static const struct of_device_id of_ambpriv_bus_match_table[] = {
+ { .compatible = "ambpriv-bus", },
+ {} /* Empty terminated list */
+};
+
+static int __init of_ambpriv_populate(void)
+{
+ struct device_node *root, *child;
+ int rval;
+
+ root = of_find_node_by_path("/iav");
+ if (!root)
+ return -EINVAL;
+
+ for_each_child_of_node(root, child) {
+ rval = of_ambpriv_bus_create(child, of_ambpriv_bus_match_table, NULL);
+ if (rval) {
+ of_node_put(child);
+ break;
+ }
+ }
+
+ of_node_put(root);
+
+ return 0;
+}
+late_initcall(of_ambpriv_populate);
+
+
+int ambpriv_add_devices(struct ambpriv_device **devs, int num)
+{
+ int i, ret = 0;
+
+ for (i = 0; i < num; i++) {
+ ret = ambpriv_device_register(devs[i]);
+ if (ret) {
+ while (--i >= 0)
+ ambpriv_device_unregister(devs[i]);
+ break;
+ }
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(ambpriv_add_devices);
+
+struct ambpriv_object {
+ struct ambpriv_device ambdev;
+ char name[1];
+};
+
+void ambpriv_device_put(struct ambpriv_device *ambdev)
+{
+ if (ambdev)
+ put_device(&ambdev->dev);
+}
+EXPORT_SYMBOL(ambpriv_device_put);
+
+static void ambpriv_device_release(struct device *dev)
+{
+ struct ambpriv_object *pa;
+
+ pa = container_of(dev, struct ambpriv_object, ambdev.dev);
+ kfree(pa->ambdev.dev.platform_data);
+ kfree(pa->ambdev.resource);
+ kfree(pa);
+}
+
+struct ambpriv_device *ambpriv_device_alloc(const char *name, int id)
+{
+ struct ambpriv_object *pa;
+
+ pa = kzalloc(sizeof(struct ambpriv_object) + strlen(name), GFP_KERNEL);
+ if (pa) {
+ strcpy(pa->name, name);
+ pa->ambdev.name = pa->name;
+ pa->ambdev.id = id;
+ device_initialize(&pa->ambdev.dev);
+ pa->ambdev.dev.release = ambpriv_device_release;
+ }
+
+ return pa ? &pa->ambdev : NULL;
+}
+EXPORT_SYMBOL(ambpriv_device_alloc);
+
+int ambpriv_device_add_resources(struct ambpriv_device *ambdev,
+ const struct resource *res, unsigned int num)
+{
+ struct resource *r;
+
+ if (!res)
+ return 0;
+
+ r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL);
+ if (r) {
+ ambdev->resource = r;
+ ambdev->num_resources = num;
+ return 0;
+ }
+ return -ENOMEM;
+}
+EXPORT_SYMBOL(ambpriv_device_add_resources);
+
+int ambpriv_device_add_data(struct ambpriv_device *ambdev, const void *data,
+ size_t size)
+{
+ void *d;
+
+ if (!data)
+ return 0;
+
+ d = kmemdup(data, size, GFP_KERNEL);
+ if (d) {
+ ambdev->dev.platform_data = d;
+ return 0;
+ }
+ return -ENOMEM;
+}
+EXPORT_SYMBOL(ambpriv_device_add_data);
+
+int ambpriv_device_add(struct ambpriv_device *ambdev)
+{
+ int i, ret = 0;
+
+ if (!ambdev)
+ return -EINVAL;
+
+ if (!ambdev->dev.parent)
+ ambdev->dev.parent = &ambpriv_bus;
+
+ ambdev->dev.bus = &ambpriv_bus_type;
+
+ if (ambdev->id != -1)
+ dev_set_name(&ambdev->dev, "%s.%d", ambdev->name, ambdev->id);
+ else
+ dev_set_name(&ambdev->dev, "%s", ambdev->name);
+
+ for (i = 0; i < ambdev->num_resources; i++) {
+ struct resource *p, *r = &ambdev->resource[i];
+
+ if (r->name == NULL)
+ r->name = dev_name(&ambdev->dev);
+
+ p = r->parent;
+ if (!p) {
+ if (resource_type(r) == IORESOURCE_MEM)
+ p = &iomem_resource;
+ else if (resource_type(r) == IORESOURCE_IO)
+ p = &ioport_resource;
+ }
+
+ if (p && insert_resource(p, r)) {
+ printk(KERN_ERR
+ "%s: failed to claim resource %d\n",
+ dev_name(&ambdev->dev), i);
+ ret = -EBUSY;
+ goto failed;
+ }
+ }
+
+ pr_debug("Registering ambpriv device '%s'. Parent at %s\n",
+ dev_name(&ambdev->dev), dev_name(ambdev->dev.parent));
+
+ ret = device_add(&ambdev->dev);
+ if (ret == 0)
+ return ret;
+
+ failed:
+ while (--i >= 0) {
+ struct resource *r = &ambdev->resource[i];
+ unsigned long type = resource_type(r);
+
+ if (type == IORESOURCE_MEM || type == IORESOURCE_IO)
+ release_resource(r);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(ambpriv_device_add);
+
+void ambpriv_device_del(struct ambpriv_device *ambdev)
+{
+ int i;
+
+ if (ambdev) {
+ device_del(&ambdev->dev);
+
+ for (i = 0; i < ambdev->num_resources; i++) {
+ struct resource *r = &ambdev->resource[i];
+ unsigned long type = resource_type(r);
+
+ if (type == IORESOURCE_MEM || type == IORESOURCE_IO)
+ release_resource(r);
+ }
+ }
+}
+EXPORT_SYMBOL(ambpriv_device_del);
+
+int ambpriv_device_register(struct ambpriv_device *ambdev)
+{
+ device_initialize(&ambdev->dev);
+ return ambpriv_device_add(ambdev);
+}
+EXPORT_SYMBOL(ambpriv_device_register);
+
+void ambpriv_device_unregister(struct ambpriv_device *ambdev)
+{
+ ambpriv_device_del(ambdev);
+ ambpriv_device_put(ambdev);
+}
+EXPORT_SYMBOL(ambpriv_device_unregister);
+
+static int ambpriv_drv_probe(struct device *_dev)
+{
+ struct ambpriv_driver *drv = to_ambpriv_driver(_dev->driver);
+ struct ambpriv_device *dev = to_ambpriv_device(_dev);
+
+ return drv->probe(dev);
+}
+
+static int ambpriv_drv_remove(struct device *_dev)
+{
+ struct ambpriv_driver *drv = to_ambpriv_driver(_dev->driver);
+ struct ambpriv_device *dev = to_ambpriv_device(_dev);
+
+ return drv->remove(dev);
+}
+
+static void ambpriv_drv_shutdown(struct device *_dev)
+{
+ struct ambpriv_driver *drv = to_ambpriv_driver(_dev->driver);
+ struct ambpriv_device *dev = to_ambpriv_device(_dev);
+
+ drv->shutdown(dev);
+}
+
+int ambpriv_driver_register(struct ambpriv_driver *drv)
+{
+ drv->driver.bus = &ambpriv_bus_type;
+ if (drv->probe)
+ drv->driver.probe = ambpriv_drv_probe;
+ if (drv->remove)
+ drv->driver.remove = ambpriv_drv_remove;
+ if (drv->shutdown)
+ drv->driver.shutdown = ambpriv_drv_shutdown;
+
+ return driver_register(&drv->driver);
+}
+EXPORT_SYMBOL(ambpriv_driver_register);
+
+void ambpriv_driver_unregister(struct ambpriv_driver *drv)
+{
+ driver_unregister(&drv->driver);
+}
+EXPORT_SYMBOL(ambpriv_driver_unregister);
+
+struct ambpriv_device * __init_or_module ambpriv_create_bundle(
+ struct ambpriv_driver *driver,
+ struct resource *res, unsigned int n_res,
+ const void *data, size_t size)
+{
+ struct ambpriv_device *ambdev;
+ int error;
+
+ ambdev = of_find_ambpriv_device_by_match(
+ (struct of_device_id *)driver->driver.of_match_table);
+ if (ambdev)
+ goto register_drv;
+
+ ambdev = ambpriv_device_alloc(driver->driver.name, -1);
+ if (!ambdev) {
+ error = -ENOMEM;
+ goto err_out;
+ }
+
+ error = ambpriv_device_add_resources(ambdev, res, n_res);
+ if (error)
+ goto err_pdev_put;
+
+ error = ambpriv_device_add_data(ambdev, data, size);
+ if (error)
+ goto err_pdev_put;
+
+ error = ambpriv_device_add(ambdev);
+ if (error)
+ goto err_pdev_put;
+
+register_drv:
+ error = ambpriv_driver_register(driver);
+ if (error)
+ goto err_pdev_del;
+
+ return ambdev;
+
+err_pdev_del:
+ ambpriv_device_del(ambdev);
+err_pdev_put:
+ ambpriv_device_put(ambdev);
+err_out:
+ return ERR_PTR(error);
+}
+EXPORT_SYMBOL(ambpriv_create_bundle);
+
+static int ambpriv_match(struct device *dev, struct device_driver *drv)
+{
+ struct ambpriv_device *ambdev = to_ambpriv_device(dev);
+
+ if (of_driver_match_device(dev, drv))
+ return 1;
+
+ return (strcmp(ambdev->name, drv->name) == 0);
+}
+
+#ifdef CONFIG_PM_SLEEP
+
+static int ambpriv_pm_prepare(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (drv && drv->pm && drv->pm->prepare)
+ ret = drv->pm->prepare(dev);
+
+ return ret;
+}
+
+static void ambpriv_pm_complete(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+
+ if (drv && drv->pm && drv->pm->complete)
+ drv->pm->complete(dev);
+}
+
+#else /* !CONFIG_PM_SLEEP */
+
+#define ambpriv_pm_prepare NULL
+#define ambpriv_pm_complete NULL
+
+#endif /* !CONFIG_PM_SLEEP */
+
+#ifdef CONFIG_SUSPEND
+
+int __weak ambpriv_pm_suspend(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm && drv->pm->suspend)
+ ret = drv->pm->suspend(dev);
+
+ return ret;
+}
+
+int __weak ambpriv_pm_suspend_noirq(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm && drv->pm->suspend_noirq)
+ ret = drv->pm->suspend_noirq(dev);
+
+ return ret;
+}
+
+int __weak ambpriv_pm_resume(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm && drv->pm->resume)
+ ret = drv->pm->resume(dev);
+
+ return ret;
+}
+
+int __weak ambpriv_pm_resume_noirq(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm && drv->pm->resume_noirq)
+ ret = drv->pm->resume_noirq(dev);
+
+ return ret;
+}
+
+#else /* !CONFIG_SUSPEND */
+
+#define ambpriv_pm_suspend NULL
+#define ambpriv_pm_resume NULL
+#define ambpriv_pm_suspend_noirq NULL
+#define ambpriv_pm_resume_noirq NULL
+
+#endif /* !CONFIG_SUSPEND */
+
+#ifdef CONFIG_HIBERNATION
+
+static int ambpriv_pm_freeze(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm && drv->pm->freeze)
+ ret = drv->pm->freeze(dev);
+
+ return ret;
+}
+
+static int ambpriv_pm_freeze_noirq(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm && drv->pm->freeze_noirq)
+ ret = drv->pm->freeze_noirq(dev);
+
+ return ret;
+}
+
+static int ambpriv_pm_thaw(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm && drv->pm->thaw)
+ ret = drv->pm->thaw(dev);
+
+ return ret;
+}
+
+static int ambpriv_pm_thaw_noirq(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm && drv->pm->thaw_noirq)
+ ret = drv->pm->thaw_noirq(dev);
+
+ return ret;
+}
+
+static int ambpriv_pm_poweroff(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm && drv->pm->poweroff)
+ ret = drv->pm->poweroff(dev);
+
+ return ret;
+}
+
+static int ambpriv_pm_poweroff_noirq(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm && drv->pm->poweroff_noirq)
+ ret = drv->pm->poweroff_noirq(dev);
+
+ return ret;
+}
+
+static int ambpriv_pm_restore(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm && drv->pm->restore)
+ ret = drv->pm->restore(dev);
+
+ return ret;
+}
+
+static int ambpriv_pm_restore_noirq(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm && drv->pm->restore_noirq)
+ ret = drv->pm->restore_noirq(dev);
+
+ return ret;
+}
+
+#else /* !CONFIG_HIBERNATION */
+
+#define ambpriv_pm_freeze NULL
+#define ambpriv_pm_thaw NULL
+#define ambpriv_pm_poweroff NULL
+#define ambpriv_pm_restore NULL
+#define ambpriv_pm_freeze_noirq NULL
+#define ambpriv_pm_thaw_noirq NULL
+#define ambpriv_pm_poweroff_noirq NULL
+#define ambpriv_pm_restore_noirq NULL
+
+#endif /* !CONFIG_HIBERNATION */
+
+#ifdef CONFIG_PM_RUNTIME
+
+int __weak ambpriv_pm_runtime_suspend(struct device *dev)
+{
+ return pm_generic_runtime_suspend(dev);
+};
+
+int __weak ambpriv_pm_runtime_resume(struct device *dev)
+{
+ return pm_generic_runtime_resume(dev);
+};
+
+int __weak ambpriv_pm_runtime_idle(struct device *dev)
+{
+ return pm_generic_runtime_idle(dev);
+};
+
+#else /* !CONFIG_PM_RUNTIME */
+
+#define ambpriv_pm_runtime_suspend NULL
+#define ambpriv_pm_runtime_resume NULL
+#define ambpriv_pm_runtime_idle NULL
+
+#endif /* !CONFIG_PM_RUNTIME */
+
+static const struct dev_pm_ops ambpriv_dev_pm_ops = {
+ .prepare = ambpriv_pm_prepare,
+ .complete = ambpriv_pm_complete,
+ .suspend = ambpriv_pm_suspend,
+ .resume = ambpriv_pm_resume,
+ .freeze = ambpriv_pm_freeze,
+ .thaw = ambpriv_pm_thaw,
+ .poweroff = ambpriv_pm_poweroff,
+ .restore = ambpriv_pm_restore,
+ .suspend_noirq = ambpriv_pm_suspend_noirq,
+ .resume_noirq = ambpriv_pm_resume_noirq,
+ .freeze_noirq = ambpriv_pm_freeze_noirq,
+ .thaw_noirq = ambpriv_pm_thaw_noirq,
+ .poweroff_noirq = ambpriv_pm_poweroff_noirq,
+ .restore_noirq = ambpriv_pm_restore_noirq,
+ .runtime_suspend = ambpriv_pm_runtime_suspend,
+ .runtime_resume = ambpriv_pm_runtime_resume,
+ .runtime_idle = ambpriv_pm_runtime_idle,
+};
+
+struct bus_type ambpriv_bus_type = {
+ .name = "ambpriv",
+ .match = ambpriv_match,
+ .pm = &ambpriv_dev_pm_ops,
+};
+EXPORT_SYMBOL(ambpriv_bus_type);
+
+int __init ambpriv_bus_init(void)
+{
+ int error;
+
+ error = device_register(&ambpriv_bus);
+ if (error)
+ return error;
+ error = bus_register(&ambpriv_bus_type);
+ if (error)
+ device_unregister(&ambpriv_bus);
+ return error;
+}
+
+core_initcall(ambpriv_bus_init);
+
diff --git a/drivers/char/.gitignore b/drivers/char/.gitignore
new file mode 100644
index 00000000..7bcea53c
--- /dev/null
+++ b/drivers/char/.gitignore
@@ -0,0 +1,2 @@
+consolemap_deftbl.c
+defkeymap.c
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 6e57543f..928233b3 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -150,3 +150,12 @@ config ARM_SPEAR_CPUFREQ
default y
help
This adds the CPUFreq driver support for SPEAr SOCs.
+
+config ARM_AMBARALLA_CPUFREQ
+ bool "Ambarella CPUFreq Driver"
+ depends on ARCH_AMBARELLA
+ default y
+ help
+ This adds the CPUFreq driver for Ambarella SoC.
+ If in doubt, say N.
+
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 3b95322f..8cefc80d 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -3,7 +3,7 @@ obj-$(CONFIG_CPU_FREQ) += cpufreq.o
# CPUfreq stats
obj-$(CONFIG_CPU_FREQ_STAT) += cpufreq_stats.o
-# CPUfreq governors
+# CPUfreq governors
obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE) += cpufreq_performance.o
obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o
obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o
@@ -50,6 +50,7 @@ obj-$(CONFIG_ARM_BIG_LITTLE_CPUFREQ) += arm_big_little.o
# LITTLE drivers, so that it is probed last.
obj-$(CONFIG_ARM_DT_BL_CPUFREQ) += arm_big_little_dt.o
+obj-$(CONFIG_ARM_AMBARALLA_CPUFREQ) += ambarella-cpufreq.o
obj-$(CONFIG_ARCH_DAVINCI) += davinci-cpufreq.o
obj-$(CONFIG_UX500_SOC_DB8500) += dbx500-cpufreq.o
obj-$(CONFIG_ARM_EXYNOS_CPUFREQ) += exynos-cpufreq.o
diff --git a/drivers/cpufreq/ambarella-cpufreq.c b/drivers/cpufreq/ambarella-cpufreq.c
new file mode 100644
index 00000000..5831980a
--- /dev/null
+++ b/drivers/cpufreq/ambarella-cpufreq.c
@@ -0,0 +1,285 @@
+/*
+ * drivers/cpufreq/ambarella-cpufreq.c
+ *
+ * CPU Frequency Scaling for Ambarella platform
+ *
+ * Copyright (C) 2015 ST Ambarella Shanghai Co., Ltd.
+ * XianqingZheng <xqzheng@ambarella.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <plat/event.h>
+#include <linux/io.h>
+#include <plat/rct.h>
+
+//#define amba_cpufreq_debug //used at debug mode
+
+#ifdef amba_cpufreq_debug
+#define amba_cpufreq_prt printk
+#else
+#define amba_cpufreq_prt(format, arg...) do {} while (0)
+#endif
+
+/* Ambarella CPUFreq driver data structure */
+static struct {
+ struct clk *core_clk;
+ struct clk *cortex_clk;
+ unsigned int transition_latency;
+ struct cpufreq_frequency_table *cortex_clktbl;
+ struct cpufreq_frequency_table *core_clktbl;
+} amba_cpufreq;
+
+static int amba_cpufreq_verify(struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy, amba_cpufreq.cortex_clktbl);
+}
+
+static unsigned int amba_cpufreq_get(unsigned int cpu)
+{
+ return clk_get_rate(amba_cpufreq.cortex_clk) / 1000;
+}
+
+static int amba_cpufreq_target(struct cpufreq_policy *policy,
+ unsigned int target_freq, unsigned int relation)
+{
+ struct cpufreq_freqs freqs;
+ unsigned long cortex_newfreq, core_newfreq;
+ int index, ret;
+ unsigned int cur_freq;
+
+ if(target_freq < 96000) {
+ printk("Target frequency is too low, cortex is not stable, it should be more than 96000\n");
+ return -EINVAL;
+ }
+
+ if (cpufreq_frequency_table_target(policy, amba_cpufreq.cortex_clktbl,
+ target_freq, relation, &index))
+ return -EINVAL;
+
+ freqs.old = amba_cpufreq_get(0);
+ cortex_newfreq = amba_cpufreq.cortex_clktbl[index].frequency * 1000;
+ core_newfreq = amba_cpufreq.core_clktbl[index].frequency * 1000;
+ freqs.new = cortex_newfreq / 1000;
+
+ amba_cpufreq_prt(KERN_INFO "prepare to switch the frequency from %d KHz to %d KHz\n"
+ ,freqs.old, freqs.new);
+
+ cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
+ ambarella_set_event(AMBA_EVENT_PRE_CPUFREQ, NULL);
+
+ ret = clk_set_rate(amba_cpufreq.cortex_clk, cortex_newfreq);
+ /* Get current rate after clk_set_rate, in case of failure */
+ if (ret) {
+ pr_err("CPU Freq: cpu clk_set_rate failed: %d\n", ret);
+ freqs.new = clk_get_rate(amba_cpufreq.cortex_clk) / 1000;
+ }
+
+ ret = clk_set_rate(amba_cpufreq.core_clk, core_newfreq);
+ /* Get current rate after clk_set_rate, in case of failure */
+ if (ret) {
+ pr_err("CPU Freq: cpu clk_set_rate failed: %d\n", ret);
+ }
+
+#if (CHIP_REV == S2L) || (CHIP_REV == S3L)
+ if(amba_cpufreq.core_clktbl[index].frequency <= 96000) {
+ /*Disable IDSP/VDSP to Save Power*/
+ amba_writel(CKEN_CLUSTER_REG, 0x540);
+ } else {
+ /*Enable IDSP/VDSP to Save Power*/
+ amba_writel(CKEN_CLUSTER_REG, 0x3fff);
+ }
+#endif
+ cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
+ ambarella_set_event(AMBA_EVENT_POST_CPUFREQ, NULL);
+
+ cur_freq = clk_get_rate(amba_cpufreq.cortex_clk) / 1000;
+ amba_cpufreq_prt(KERN_INFO "current frequency of cortex clock is:%d KHz\n",
+ cur_freq);
+
+
+ return ret;
+}
+
+static int amba_cpufreq_init(struct cpufreq_policy *policy)
+{
+ int ret;
+
+ ret = cpufreq_frequency_table_cpuinfo(policy, amba_cpufreq.cortex_clktbl);
+ if (ret) {
+ pr_err("cpufreq_frequency_table_cpuinfo() failed");
+ return ret;
+ }
+
+ cpufreq_frequency_table_get_attr(amba_cpufreq.cortex_clktbl, policy->cpu);
+ policy->cpuinfo.transition_latency = amba_cpufreq.transition_latency;
+ policy->cur = amba_cpufreq_get(0);
+
+ cpumask_setall(policy->cpus);
+
+ return 0;
+}
+
+static int amba_cpufreq_exit(struct cpufreq_policy *policy)
+{
+ cpufreq_frequency_table_put_attr(policy->cpu);
+ return 0;
+}
+
+static struct freq_attr *amba_cpufreq_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static struct cpufreq_driver amba_cpufreq_driver = {
+ .name = "amba-cpufreq",
+ .flags = CPUFREQ_STICKY,
+ .verify = amba_cpufreq_verify,
+ .target = amba_cpufreq_target,
+ .get = amba_cpufreq_get,
+ .init = amba_cpufreq_init,
+ .exit = amba_cpufreq_exit,
+ .attr = amba_cpufreq_attr,
+};
+
+static int amba_cpufreq_driver_init(void)
+{
+ struct device_node *np;
+ const struct property *prop;
+ struct cpufreq_frequency_table *cortex_freqtbl;
+ struct cpufreq_frequency_table *core_freqtbl;
+ const __be32 *val;
+ int cnt, i, ret, clk_div;
+
+ printk("ambarella cpufreq driver init\n");
+ np = of_find_node_by_path("/cpus");
+ if (!np) {
+ pr_err("No cpu node found");
+ return -ENODEV;
+ }
+
+ ret = of_property_read_u32(np, "amb,core-div", &clk_div);
+ if (ret != 0 || !((clk_div == 1 || clk_div == 2))) {
+ /*Default is that the pll_out_core is twice gclk_core */
+ clk_div = 2;
+ }
+
+ if (of_property_read_u32(np, "clock-latency",
+ &amba_cpufreq.transition_latency))
+ amba_cpufreq.transition_latency = CPUFREQ_ETERNAL;
+
+ prop = of_find_property(np, "cpufreq_tbl", NULL);
+ if (!prop || !prop->value) {
+ pr_err("Invalid cpufreq_tbl");
+ ret = -ENODEV;
+ goto out_put_node;
+ }
+
+ cnt = prop->length / sizeof(u32) / 2;
+ val = prop->value;
+
+ cortex_freqtbl = kmalloc(sizeof(*cortex_freqtbl) * (cnt + 2), GFP_KERNEL);
+ if (!cortex_freqtbl) {
+ ret = -ENOMEM;
+ goto out_put_node;
+ }
+
+ core_freqtbl = kmalloc(sizeof(*core_freqtbl) * (cnt + 2), GFP_KERNEL);
+ if (!core_freqtbl) {
+ ret = -ENOMEM;
+ goto out_put_node;
+ }
+
+ for (i = 0; i < cnt; i++) {
+ core_freqtbl[i].index = i;
+ /*pll_out_core = clk_div * gclk_core;*/
+ core_freqtbl[i].frequency = be32_to_cpup(val) * clk_div;
+
+ cortex_freqtbl[i].index = i;
+ cortex_freqtbl[i].frequency = be32_to_cpup((val + 1));
+ val = val + 2;
+
+ }
+
+ cortex_freqtbl[i].index = i;
+ cortex_freqtbl[i].frequency = clk_get_rate(clk_get(NULL, "gclk_cortex")) / 1000;
+
+ core_freqtbl[i].index = i;
+ core_freqtbl[i].frequency = clk_get_rate(clk_get(NULL, "gclk_core")) / 1000 * clk_div;
+
+ i++;
+ cortex_freqtbl[i].index = i;
+ cortex_freqtbl[i].frequency = CPUFREQ_TABLE_END;
+
+ core_freqtbl[i].index = i;
+ core_freqtbl[i].frequency = CPUFREQ_TABLE_END;
+
+ amba_cpufreq.cortex_clktbl = cortex_freqtbl;
+ amba_cpufreq.core_clktbl = core_freqtbl;
+
+ of_node_put(np);
+
+ amba_cpufreq.core_clk = clk_get(NULL, "pll_out_core");
+ if (IS_ERR(amba_cpufreq.core_clk)) {
+ pr_err("Unable to get core clock\n");
+ ret = PTR_ERR(amba_cpufreq.core_clk);
+ goto out_put_mem;
+ }
+
+ amba_cpufreq.cortex_clk = clk_get(NULL, "gclk_cortex");
+ if (IS_ERR(amba_cpufreq.cortex_clk)) {
+ pr_err("Unable to get cotex clock\n");
+ ret = PTR_ERR(amba_cpufreq.cortex_clk);
+ goto out_put_mem;
+ }
+
+ ret = cpufreq_register_driver(&amba_cpufreq_driver);
+ if (!ret)
+ return 0;
+
+ pr_err("failed register driver: %d\n", ret);
+ clk_put(amba_cpufreq.core_clk);
+ clk_put(amba_cpufreq.cortex_clk);
+
+out_put_mem:
+ kfree(cortex_freqtbl);
+ kfree(core_freqtbl);
+ return ret;
+
+out_put_node:
+ of_node_put(np);
+ return ret;
+}
+
+module_init(amba_cpufreq_driver_init);
+
+static void __exit amba_cpufreq_driver_exit(void)
+{
+ cpufreq_unregister_driver(&amba_cpufreq_driver);
+ if(amba_cpufreq.cortex_clktbl != NULL) {
+ kfree(amba_cpufreq.cortex_clktbl);
+ amba_cpufreq.cortex_clktbl = NULL;
+ }
+
+ if(amba_cpufreq.core_clktbl != NULL) {
+ kfree(amba_cpufreq.core_clktbl);
+ amba_cpufreq.core_clktbl = NULL;
+ }
+
+}
+module_exit(amba_cpufreq_driver_exit);
+
+
+MODULE_AUTHOR("XianqingZheng <xqzheng@ambarella.com>");
+MODULE_DESCRIPTION("Ambarella CPUFreq driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index 0d8bd55e..3753df3f 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
obj-$(CONFIG_CPU_IDLE_CALXEDA) += cpuidle-calxeda.o
obj-$(CONFIG_ARCH_KIRKWOOD) += cpuidle-kirkwood.o
+obj-$(CONFIG_ARCH_AMBARELLA) += cpuidle-ambarella.o
diff --git a/drivers/cpuidle/cpuidle-ambarella.c b/drivers/cpuidle/cpuidle-ambarella.c
new file mode 100644
index 00000000..5ada4d09
--- /dev/null
+++ b/drivers/cpuidle/cpuidle-ambarella.c
@@ -0,0 +1,280 @@
+/*
+ * Copyright 2015 ambarella, Inc.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Maintainer: Jorney Tu <qtu@ambarella.com>
+ */
+
+#include <linux/cpuidle.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+#include <linux/suspend.h>
+#include <asm/cpuidle.h>
+#include <asm/proc-fns.h>
+#include <asm/smp_scu.h>
+#include <linux/interrupt.h>
+#include <linux/percpu.h>
+#include <linux/cpu.h>
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include "../../kernel/time/tick-internal.h"
+
+#define DEFAULT_FREQENCY_INDEX 1
+
+#define MIN(x,y) ( (x) < (y) ? (x) : (y) )
+
+#define CPUIDLE_DBG 0
+
+#if CPUIDLE_DBG
+#define dbg_print(fmt, args...) printk(fmt, ##args)
+#else
+#define dbg_print(fmt, args...) do{}while(0)
+#endif
+
+
+struct ambarella_cpuidle_info {
+ unsigned int core_old_freqency ;
+ unsigned int cortex_old_freqency ;
+
+ unsigned int freq_tbl_cnt;
+ struct cpufreq_frequency_table *freq_tbl;
+
+ struct clk *core_clk ; // pll_out_core !!!
+ struct clk *cortex_clk ;
+};
+
+static struct ambarella_cpuidle_info *info = NULL;
+
+static int ambarella_cpufreq_probe(void)
+{
+ const struct property *prop;
+ struct cpufreq_frequency_table *freqs;
+ struct device_node *np;
+ int i, count;
+ int ret = 0;
+ const __be32 *value;
+
+ info = kmalloc(sizeof(struct ambarella_cpuidle_info), GFP_KERNEL);
+ if (!info) {
+ pr_err("kmalloc ambarella_cpuidle_info failed !\n");
+ return -ENOMEM;
+ }
+
+ np = of_find_node_by_path("/cpus");
+ if (!np) {
+ pr_err("No cpu node found");
+ ret = -EFAULT;
+ goto info_mem;
+ }
+
+ prop = of_find_property(np, "cpufreq_tbl", NULL);
+ if (!prop || !prop->value) {
+ pr_err("Invalid cpufreq_tbl");
+ ret = -ENODEV;
+ goto node_put;
+ }
+
+ count = prop->length / sizeof(u32);
+ value = prop->value;
+
+ freqs = kmalloc(sizeof(struct cpufreq_frequency_table) * count,GFP_KERNEL);
+ if (!freqs) {
+ ret = -ENOMEM;
+ goto node_put;
+ }
+
+
+ for (i = 0; i < count; i++) {
+ freqs[i].index = i;
+ freqs[i].frequency = be32_to_cpup(value++);
+ }
+
+ info->freq_tbl_cnt = count;
+ info->freq_tbl = freqs;
+
+ info->core_clk = clk_get(NULL, "pll_out_core");
+ if (IS_ERR(info->core_clk)){
+ pr_err("unable get core clk\n");
+ ret = -EFAULT;
+ goto freq_mem;
+ }
+
+ info->cortex_clk = clk_get(NULL, "gclk_cortex");
+ if (IS_ERR(info->cortex_clk)){
+ pr_err("unable get cortex clk\n");
+ ret = -EFAULT;
+ goto freq_mem;
+ }
+
+ of_node_put(np);
+ return ret;
+
+freq_mem:
+ kfree(freqs);
+node_put:
+ of_node_put(np);
+info_mem:
+ kfree(info);
+ return ret;
+}
+
+static unsigned int ambarella_cur_freq(struct clk *clk)
+{
+ return clk_get_rate(clk) / 1000;
+}
+
+static int ambarella_cpufreq_switch(unsigned int index)
+{
+ int ret ;
+ unsigned int core_new_freqency = 0;
+ unsigned int cortex_new_freqency = 0;
+
+ if(index < 0 || 2 * index > info->freq_tbl_cnt)
+ index = 0;
+
+ info->core_old_freqency = ambarella_cur_freq(info->core_clk) / 2;
+ info->cortex_old_freqency = ambarella_cur_freq(info->cortex_clk);
+
+ core_new_freqency = info->freq_tbl[index * 2].frequency;
+ cortex_new_freqency = info->freq_tbl[index * 2 + 1].frequency;
+
+ ret = clk_set_rate(info->core_clk, core_new_freqency * 1000 * 2);
+ if (ret){
+ pr_err("Core clock set failed\n");
+ return -1;
+ }
+
+ ret = clk_set_rate(info->cortex_clk, cortex_new_freqency * 1000);
+ if (ret){
+ pr_err("Cortex clock set failed\n");
+ return -1;
+ }
+
+ dbg_print("Switch Core frequency from %d to %d\n", info->core_old_freqency, core_new_freqency);
+ dbg_print("Switch Cortex frequency from %d to %d\n", info->cortex_old_freqency, cortex_new_freqency);
+ return 0;
+}
+
+static int ambarella_cpufreq_recover(void)
+{
+ int ret ;
+ unsigned int core_new_freqency = 0;
+ unsigned int cortex_new_freqency = 0;
+
+ core_new_freqency = info->core_old_freqency;
+ cortex_new_freqency = info->cortex_old_freqency;
+
+ info->core_old_freqency = ambarella_cur_freq(info->core_clk) / 2;
+ info->cortex_old_freqency = ambarella_cur_freq(info->cortex_clk);
+
+ ret = clk_set_rate(info->core_clk, core_new_freqency * 1000 * 2);
+ if (ret){
+ pr_err("Core clock set failed\n");
+ return -1;
+ }
+
+ ret = clk_set_rate(info->cortex_clk, cortex_new_freqency * 1000);
+ if (ret){
+ pr_err("Cortex clock set failed\n");
+ return -1;
+ }
+
+ dbg_print("Recover Core frequency from %d to %d\n", info->core_old_freqency, core_new_freqency);
+ dbg_print("Recover Cortex frequency from %d to %d\n", info->cortex_old_freqency, cortex_new_freqency);
+ return 0;
+}
+
+static int disable_percpu_timer(void)
+{
+
+ struct clock_event_device *dev;
+ struct tick_device *td;
+ int cpu;
+
+ cpu = smp_processor_id();
+ td = &per_cpu(tick_cpu_device, cpu);
+ dev = td->evtdev;
+ clockevents_set_mode(dev, CLOCK_EVT_MODE_SHUTDOWN);
+
+ return 0;
+}
+
+static int enable_percpu_timer(void)
+{
+
+ struct clock_event_device *dev;
+ struct tick_device *td;
+ int cpu;
+
+ cpu = smp_processor_id();
+ td = &per_cpu(tick_cpu_device, cpu);
+ dev = td->evtdev;
+ clockevents_set_mode(dev, CLOCK_EVT_MODE_ONESHOT);
+
+ return 0;
+}
+
+static void ambarella_idle_exec(unsigned int freq_index)
+{
+
+ ambarella_cpufreq_switch(freq_index);
+
+ disable_percpu_timer();
+
+ cpu_do_idle();
+
+ enable_percpu_timer();
+
+ ambarella_cpufreq_recover();
+}
+
+static int ambarella_pwrdown_idle(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv,
+ int index)
+{
+ ambarella_idle_exec(DEFAULT_FREQENCY_INDEX);
+
+ return index;
+}
+
+static struct cpuidle_driver ambarella_idle_driver = {
+ .name = "ambarella_idle",
+ .states = {
+ ARM_CPUIDLE_WFI_STATE,
+ {
+ .name = "FG",
+ .desc = "FREQ Gate",
+ .flags = CPUIDLE_FLAG_TIMER_STOP,
+ .exit_latency = 30,
+ .power_usage = 50,
+ .target_residency = 400000, // for judging cpu idle time
+ .enter = ambarella_pwrdown_idle,
+ },
+ },
+ .state_count = 2,
+};
+
+static int __init ambarella_cpuidle_init(void)
+{
+
+ if (ambarella_cpufreq_probe())
+ return -EFAULT;
+
+ return cpuidle_register(&ambarella_idle_driver, NULL);
+}
+module_init(ambarella_cpuidle_init);
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index dffb8552..465af1e8 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -232,6 +232,14 @@ config CRYPTO_DEV_IXP4XX
help
Driver for the IXP4xx NPE crypto engine.
+config CRYPTO_DEV_AMBARELLA
+ tristate "Driver for Ambarella HW CRYPTO"
+ depends on PLAT_AMBARELLA_SUPPORT_HW_CRYPTO
+ select CRYPTO_AES
+ select CRYPTO_DES
+ help
+ Driver for Ambarella Soc crypto engine.
+
config CRYPTO_DEV_PPC4XX
tristate "Driver AMCC PPC4xx crypto accelerator"
depends on PPC && 4xx
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 38ce13d3..4a99d530 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_CRYPTO_DEV_MV_CESA) += mv_cesa.o
obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam/
obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o
+obj-$(CONFIG_CRYPTO_DEV_AMBARELLA) += ambarella_crypto.o
obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/
obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o
obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o
diff --git a/drivers/crypto/ambarella_crypto.c b/drivers/crypto/ambarella_crypto.c
new file mode 100644
index 00000000..53f72e2e
--- /dev/null
+++ b/drivers/crypto/ambarella_crypto.c
@@ -0,0 +1,1360 @@
+/*
+ * ambarella_crypto.c
+ *
+ * History:
+ * 2009/09/07 - [Qiao Wang]
+ * 2013/01/04 - [Johnson Diao]
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/completion.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <linux/of.h>
+#include <linux/cryptohash.h>
+#include <crypto/algapi.h>
+#include <crypto/aes.h>
+#include <crypto/des.h>
+#include <crypto/sha.h>
+#include <crypto/md5.h>
+#include <crypto/internal/hash.h>
+#include <mach/hardware.h>
+#include <plat/crypto.h>
+
+DEFINE_MUTEX(engine_lock);
+#define AMBA_CIPHER_COPY (1<<4)
+
+static DECLARE_COMPLETION(g_aes_irq_wait);
+static DECLARE_COMPLETION(g_des_irq_wait);
+static DECLARE_COMPLETION(g_md5_sha1_irq_wait);
+
+static struct workqueue_struct *handle_queue;
+static struct work_struct work;
+
+static int config_polling_mode = 0;
+module_param(config_polling_mode, int, S_IRUGO);
+
+static const char *ambdev_name =
+ "Ambarella Media Processor Cryptography Engine";
+
+struct des_ctx {
+ u32 expkey[DES_EXPKEY_WORDS];
+};
+#define AMBA_AES_BLOCK 16
+static md5_digest_t g_md5_digest __attribute__((__aligned__(4)));
+static md5_data_t g_md5_data __attribute__((__aligned__(4)));
+static sha1_digest_t g_sha1_digest __attribute__((__aligned__(4)));
+static sha1_data_t g_sha1_data __attribute__((__aligned__(4)));
+/******************* Basic Function ***************************************/
+static unsigned long long int __ambarella_crypto_aligned_read64(u32 src)
+{
+ long long unsigned int ret;
+ __asm__ __volatile__ (
+ "ldrd %0,[%1]\n"
+ : "=&r"(ret)
+ : "r"(src)
+ );
+ return ret;
+}
+
+static void __ambarella_crypto_aligned_write64(u32 low, u32 high,u32 dst)
+{
+ __asm__ __volatile__ (
+ "mov r4, %0 \n\t"
+ "mov r5, %1 \n\t"
+ "strd r4, [%2] \n\t"
+ :
+ : "r"(low) , "r"(high),"r"(dst)
+ : "r4", "r5", "memory" );
+}
+
+static int _ambarella_crypto_aligned_read64(u32 * buf,u32 * addr, unsigned int len) {
+ int errCode = -1;
+ int i;
+ if ( ( 0 == (((u32) addr) & 0x07) ) && (0 == (len%8))) {
+ /* address and length should be 64 bit aligned */
+ for (i = 0; i < len/8; i++) {
+ *(unsigned long long int *)(buf + 2*i) = __ambarella_crypto_aligned_read64((u32)(addr + 2*i));
+ }
+ errCode = 0;
+ };
+ return errCode;
+
+}
+
+static int _ambarella_crypto_aligned_write64(u32 * addr,u32 * buf, unsigned int len ) {
+ int errCode = -1;
+ int i;
+ if ( ( 0 == (((u32) addr) & 0x07) ) && (0 == (len%8))) {
+ /* address and length should be 64 bit aligned */
+ for (i = 0; i < len/8; i++) {
+ __ambarella_crypto_aligned_write64(*(u32 *)(buf + 2*i), *(u32 *)(buf + 2*i+1),(u32)(addr + 2*i));
+ }
+ errCode = 0;
+ };
+ return errCode;
+
+}
+
+//merge temp buffer
+#define MAX_MERGE_SIZE 8
+__attribute__ ((aligned (4))) u32 merg[MAX_MERGE_SIZE]={};
+
+struct ambarella_crypto_info {
+ void __iomem *regbase;
+
+ bool binary_mode;
+ bool cap_md5_sha1;
+ bool data_swap;
+ bool reg_64bit;
+};
+struct aes_fun_t{
+ void (*opcode)(u32);
+ void (*wdata)(u32*,u32*,int);
+ void (*rdata)(u32*,u32*,int);
+ u32* (*reg_enc)(void);
+ u32* (*reg_dec)(void);
+}aes_fun;
+u32* aes_reg_enc_dec_32(void)
+{
+ return((u32*)CRYPT_A_INPUT1);
+}
+u32* aes_reg_enc_64(void)
+{
+ return( (u32*)CRYPT_A_INPUT1);
+}
+
+u32* aes_reg_dec_64(void)
+{
+ // When run the a5s or other with 32-bit register,this defined is NULL ,
+ //so make sure correct in ambarella_crypto_probe
+ return( (u32*)CRYPT_A_INPUT2);
+}
+
+void swap_write(u32 *offset,u32 *src,int size)
+{
+ int point=0;
+ int len=size;
+
+ for(size=(size>>2)-1;size >= 0;size--,point++){
+ *(merg+point) = ntohl(*(src+size));
+ }
+ //the iONE registers need to accessed by 64-bit boundaries
+ _ambarella_crypto_aligned_write64(offset,merg,len);
+
+}
+
+void swap_read(u32 *offset,u32 *src,int size)
+{
+ int point=0,len=size;
+
+ //the iONE registers need to accessed by 64-bit boundaries
+ _ambarella_crypto_aligned_read64(merg,src,len);
+ for(size=(size>>2)-1;size >= 0;size--,point++){
+ *(offset+point) = ntohl(*(merg+size));
+ }
+}
+
+void aes_opcode(u32 flag)
+{
+ // When run the a7 or higher version with 64-bit register,this defined is NULL,
+ //so make sure correct in ambarella_crypto_probe
+ amba_writel(CRYPT_A_OPCODE, flag);
+}
+
+void null_fun(u32 flag) {}
+/***************** AES Function **********************************/
+static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
+{
+ struct crypto_aes_ctx *ctx=crypto_tfm_ctx(tfm);
+ const __le32 *src = (const __le32 *)in;
+ __le32 *dst = (__le32 *)out;
+ u32 ready;
+ u32 *offset=NULL;
+ do{}while(mutex_trylock(&engine_lock) == 0);
+ switch (ctx->key_length){
+ case 16:
+ offset = (u32*)CRYPT_A_128_96_REG;
+ aes_fun.wdata(offset,ctx->key_enc,16);
+ break;
+ case 24:
+ offset = (u32*)CRYPT_A_192_160_REG;
+ aes_fun.wdata(offset,ctx->key_enc,24);
+ break;
+ case 32:
+ offset = (u32*)CRYPT_A_256_224_REG;
+ aes_fun.wdata(offset,ctx->key_enc,32);
+ break;
+ }
+ //enc or dec option mode
+ aes_fun.opcode(AMBA_HW_ENCRYPT_CMD);
+
+ //get the input offset
+ offset = aes_fun.reg_enc();
+
+ //input the src
+ aes_fun.wdata(offset,(u32*)src,16);
+
+ do{
+ ready = amba_readl(CRYPT_A_OUTPUT_READY_REG);
+ }while(ready != 1);
+
+ //get the output
+ offset = (u32*)CRYPT_A_OUTPUT_96_REG;
+ aes_fun.rdata(dst,offset,16);
+ mutex_unlock(&engine_lock);
+}
+
+
+static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
+{
+ struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm);
+ const __le32 *src = (const __le32 *)in;
+ __le32 *dst = (__le32 *)out;
+ u32 ready;
+ u32 *offset=NULL;
+
+ do{}while(mutex_trylock(&engine_lock) == 0);
+ switch (ctx->key_length) {
+ case 16:
+ offset = (u32*)CRYPT_A_128_96_REG;
+ aes_fun.wdata(offset,ctx->key_enc,16);
+ break;
+ case 24:
+ offset = (u32*)CRYPT_A_192_160_REG;
+ aes_fun.wdata(offset,ctx->key_enc,24);
+ break;
+ case 32:
+ offset = (u32*)CRYPT_A_256_224_REG;
+ aes_fun.wdata(offset,ctx->key_enc,32);
+ break;
+ }
+ //enc or dec option mode
+ aes_fun.opcode(AMBA_HW_DECRYPT_CMD);
+
+ //get the input offset
+ offset = aes_fun.reg_dec();
+
+ //input the src
+ aes_fun.wdata(offset,(u32*)src,16);
+
+ do{
+ ready = amba_readl(CRYPT_A_OUTPUT_READY_REG);
+ }while(ready != 1);
+
+
+ //get the output
+ offset = (u32*)CRYPT_A_OUTPUT_96_REG;
+ aes_fun.rdata(dst,offset,16);
+ mutex_unlock(&engine_lock);
+}
+
+static struct crypto_alg aes_alg = {
+ .cra_name = "aes",
+ .cra_driver_name = "aes-ambarella",
+ .cra_priority = AMBARELLA_CRA_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypto_aes_ctx),
+ .cra_alignmask = AMBARELLA_CRYPTO_ALIGNMENT - 1,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
+ .cra_u = {
+ .cipher = {
+ .cia_min_keysize = AES_MIN_KEY_SIZE,
+ .cia_max_keysize = AES_MAX_KEY_SIZE,
+ .cia_setkey = crypto_aes_set_key,
+ .cia_encrypt = aes_encrypt,
+ .cia_decrypt = aes_decrypt,
+ }
+ }
+};
+
+/****************** DES Function **************************/
+struct des_fun_t{
+ void (*opcode)(u32);
+ void (*wdata)(u32*,u32*,int);
+ void (*rdata)(u32*,u32*,int);
+ u32* (*reg_enc)(void);
+ u32* (*reg_dec)(void);
+}des_fun;
+
+u32* des_reg_enc_dec_32(void)
+{
+ return((u32*)CRYPT_D_INPUT1);
+}
+
+u32* des_reg_enc_64(void)
+{
+ return((u32*)CRYPT_D_INPUT1);
+}
+
+u32* des_reg_dec_64(void)
+{
+ // When run the a5s or other with 32-bit register,this defined is NULL ,
+ //so make sure correct in ambarella_crypto_probe
+ return((u32*)CRYPT_D_INPUT2);
+}
+
+void des_opcode(u32 flag)
+{
+ // When run the a7 or higher version with 64-bit register,this defined is NULL,
+ //so make sure correct in ambarella_crypto_probe
+ amba_writel(CRYPT_D_OPCODE, flag);
+}
+
+static int des_setkey(struct crypto_tfm *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct des_ctx *dctx = crypto_tfm_ctx(tfm);
+ u32 *flags = &tfm->crt_flags;
+ u32 tmp[DES_EXPKEY_WORDS];
+ int ret;
+
+
+ /* Expand to tmp */
+ ret = des_ekey(tmp, key);
+
+ if (unlikely(ret == 0) && (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
+ *flags |= CRYPTO_TFM_RES_WEAK_KEY;
+ return -EINVAL;
+ }
+
+ /* Copy to output */
+ memcpy(dctx->expkey, key, keylen);
+
+ return 0;
+}
+
+static void des_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
+{
+ struct des_ctx *ctx = crypto_tfm_ctx(tfm);
+ const __le32 *src = (const __le32 *)in;
+ __le32 *dst = (__le32 *)out;
+ u32 ready;
+ u32 *offset=NULL;
+
+ do{}while(mutex_trylock(&engine_lock) == 0);
+ //set key
+ des_fun.wdata((u32*)CRYPT_D_HI_REG,ctx->expkey,8);
+
+ //enc or dec option mode
+ des_fun.opcode(AMBA_HW_ENCRYPT_CMD);
+
+ //get the input offset
+ offset = des_fun.reg_enc();
+
+ //input the src
+ des_fun.wdata(offset,(u32*)src,8);
+
+ do{
+ ready = amba_readl(CRYPT_D_OUTPUT_READY_REG);
+ }while(ready != 1);
+
+
+ //get the output
+ offset = (u32*)CRYPT_D_OUTPUT_HI_REG;
+ des_fun.rdata(dst,offset,8);
+ mutex_unlock(&engine_lock);
+}
+
+static void des_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
+{
+ struct des_ctx *ctx = crypto_tfm_ctx(tfm);
+ const __le32 *src = (const __le32 *)in;
+ __le32 *dst = (__le32 *)out;
+ u32 ready;
+ u32 *offset=NULL;
+
+ do{}while(mutex_trylock(&engine_lock) == 0);
+ //set key
+ des_fun.wdata((u32*)CRYPT_D_HI_REG,ctx->expkey,8);
+
+ //enc or dec option mode
+ des_fun.opcode(AMBA_HW_DECRYPT_CMD);
+
+ //get the input offset
+ offset = des_fun.reg_dec();
+
+ //input the src
+ des_fun.wdata(offset,(u32*)src,8);
+
+ do{
+ ready = amba_readl(CRYPT_D_OUTPUT_READY_REG);
+ }while(ready != 1);
+
+ //get the output
+ offset = (u32*)CRYPT_D_OUTPUT_HI_REG;
+ des_fun.rdata(dst,offset,8);
+ mutex_unlock(&engine_lock);
+
+}
+
+
+static struct crypto_alg des_alg = {
+ .cra_name = "des",
+ .cra_driver_name = "des-ambarella",
+ .cra_priority = AMBARELLA_CRA_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = DES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct des_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_alignmask = AMBARELLA_CRYPTO_ALIGNMENT - 1,
+ .cra_list = LIST_HEAD_INIT(des_alg.cra_list),
+ .cra_u = {
+ .cipher = {
+ .cia_min_keysize = DES_KEY_SIZE,
+ .cia_max_keysize = DES_KEY_SIZE,
+ .cia_setkey = des_setkey,
+ .cia_encrypt = des_encrypt,
+ .cia_decrypt = des_decrypt
+ }
+ }
+};
+/******************** ECB(AES) Function ***************************************************/
+
+#define MAX_BLOCK 8192
+#define AES_MAX_KEYLENGTH (15 * 16)
+#define AES_MAX_KEYLENGTH_U32 (AES_MAX_KEYLENGTH / sizeof(u32))
+struct amba_ecb_ctx {
+ u32 enc_key[AES_MAX_KEYLENGTH_U32];
+ int key_len;
+};
+
+struct request_ops{
+ enum{
+ enc,
+ dec,
+ }op;
+ struct ablkcipher_walk walk;
+};
+
+static struct pri_queue {
+ struct crypto_queue queue;
+ spinlock_t lock;
+
+ enum {
+ IDLE,
+ BUSY,
+ }status;
+
+}amba_queue;
+
+static void handle_aes_encrypt(struct amba_ecb_ctx *ctx, u8 *out, u8* in)
+{
+ u32 *offset=NULL;
+ __le32 *src = (__le32 *)in;
+ __le32 *dst = (__le32 *)out;
+ int ready=0;
+
+ switch (ctx->key_len){
+ case 16:
+ offset = (u32*)CRYPT_A_128_96_REG;
+ aes_fun.wdata(offset,ctx->enc_key,16);
+ break;
+ case 24:
+ offset = (u32*)CRYPT_A_192_160_REG;
+ aes_fun.wdata(offset,ctx->enc_key,24);
+ break;
+ case 32:
+ offset = (u32*)CRYPT_A_256_224_REG;
+ aes_fun.wdata(offset,ctx->enc_key,32);
+ break;
+ }
+ aes_fun.opcode(AMBA_HW_ENCRYPT_CMD);
+ offset = aes_fun.reg_enc();
+ aes_fun.wdata(offset,(u32*)src,16);
+
+ do{
+ ready = try_wait_for_completion(&g_aes_irq_wait);
+ }while(ready != 1);
+
+ offset = (u32*)CRYPT_A_OUTPUT_96_REG;
+ aes_fun.rdata(dst,offset,16);
+
+}
+static void handle_aes_decrypt(struct amba_ecb_ctx *ctx, u8 *out, u8* in)
+{
+ u32 *offset=NULL;
+ __le32 *src = (__le32 *)in;
+ __le32 *dst = (__le32 *)out;
+ int ready = 0;
+
+
+ switch (ctx->key_len){
+ case 16:
+ offset = (u32*)CRYPT_A_128_96_REG;
+ aes_fun.wdata(offset,ctx->enc_key,16);
+ break;
+ case 24:
+ offset = (u32*)CRYPT_A_192_160_REG;
+ aes_fun.wdata(offset,ctx->enc_key,24);
+ break;
+ case 32:
+ offset = (u32*)CRYPT_A_256_224_REG;
+ aes_fun.wdata(offset,ctx->enc_key,32);
+ break;
+ }
+
+ aes_fun.opcode(AMBA_HW_DECRYPT_CMD);
+ offset = aes_fun.reg_dec();
+ aes_fun.wdata(offset,(u32*)src,16);
+
+ do{
+ ready = try_wait_for_completion(&g_aes_irq_wait);
+ }while(ready != 1);
+
+ offset = (u32*)CRYPT_A_OUTPUT_96_REG;
+ aes_fun.rdata(dst,offset,16);
+
+}
+
+static int handle_ecb_aes_req(struct ablkcipher_request *req)
+{
+ int nbytes,err;
+ struct amba_ecb_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
+ struct crypto_async_request *base = &req->base;
+ struct request_ops *req_ctx = ablkcipher_request_ctx(req);
+ struct crypto_tfm *tfm = req->base.tfm;
+ struct blkcipher_desc desc = {
+ .tfm = __crypto_blkcipher_cast(tfm),
+ .info = req->info,
+ .flags = req->base.flags,
+ };
+ void (*fun)(struct amba_ecb_ctx *ctx, u8 *out, u8* in);
+ struct blkcipher_walk walk;
+
+ walk.flags |= AMBA_CIPHER_COPY;
+ blkcipher_walk_init(&walk, req->dst, req->src, req->nbytes);
+
+
+ if (req_ctx->op == enc){
+ fun = handle_aes_encrypt;
+ }else{
+ fun = handle_aes_decrypt;
+ }
+
+
+ err = blkcipher_walk_virt(&desc, &walk);
+
+ while ((nbytes = walk.nbytes)) {
+ u8 *wsrc = walk.src.virt.addr;
+ u8 *wdst = walk.dst.virt.addr;
+
+ do {
+ fun(ctx, wdst, wsrc);
+
+ wsrc += AMBA_AES_BLOCK;
+ wdst += AMBA_AES_BLOCK;
+ } while ((nbytes -= AMBA_AES_BLOCK) >= AMBA_AES_BLOCK);
+
+ err = blkcipher_walk_done(&desc, &walk, nbytes);
+ }
+
+
+ local_bh_disable();
+ base->complete(base,err);
+ local_bh_enable();
+ return 0;
+}
+
+static void do_queue(void)
+{
+ struct crypto_async_request *async_req = NULL;
+ struct crypto_async_request *backlog=NULL;
+ spin_lock_irq(&amba_queue.lock);
+ if (amba_queue.status == IDLE){
+ backlog = crypto_get_backlog(&amba_queue.queue);
+ async_req = crypto_dequeue_request(&amba_queue.queue);
+ if(async_req){
+ BUG_ON(amba_queue.status != IDLE);
+ amba_queue.status = BUSY;
+ }
+ }
+ spin_unlock_irq(&amba_queue.lock);
+ if (backlog){
+ backlog->complete(backlog,-EINPROGRESS);
+ backlog = NULL;
+ }
+ if (async_req){
+ struct ablkcipher_request *req =
+ container_of(async_req,
+ struct ablkcipher_request,
+ base);
+ // handle the request
+ handle_ecb_aes_req(req);
+ amba_queue.status = IDLE;
+ }
+ return;
+}
+
+static int ecb_aes_set_key(struct crypto_ablkcipher *cipher,const u8 *key,
+ unsigned int len)
+{
+ struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher);
+ struct amba_ecb_ctx *ctx = crypto_tfm_ctx(tfm);
+ switch (len){
+ case 16:
+ case 24:
+ case 32:
+ break;
+ default:
+ crypto_ablkcipher_set_flags(cipher,CRYPTO_TFM_RES_BAD_KEY_LEN);
+ return -EINVAL;
+ }
+ ctx->key_len = len;
+ memcpy(ctx->enc_key,key,len);
+ return 0;
+}
+
+static int amba_handle_req(struct ablkcipher_request *req)
+{
+ int ret;
+ unsigned long flags;
+
+ spin_lock_irqsave(&amba_queue.lock,flags);
+ ret = crypto_enqueue_request(&amba_queue.queue,&req->base);
+ spin_unlock_irqrestore(&amba_queue.lock,flags);
+
+ queue_work(handle_queue,&work);
+
+ return ret;
+}
+
+static int ecb_aes_encrypt(struct ablkcipher_request *req)
+{
+ struct request_ops *req_ctx = ablkcipher_request_ctx(req);
+ req_ctx->op = enc;
+ return amba_handle_req(req);
+}
+
+static int ecb_aes_decrypt(struct ablkcipher_request *req)
+{
+ struct request_ops *req_ctx = ablkcipher_request_ctx(req);
+ req_ctx->op = dec;
+ return amba_handle_req(req);
+}
+
+static int aes_cra_init(struct crypto_tfm *tfm)
+{
+ return 0;
+}
+
+
+static struct crypto_alg ecb_aes_alg = {
+ .cra_name = "ecb(aes)",
+ .cra_driver_name = "ecb-aes-ambarella",
+ .cra_priority = AMBARELLA_COMPOSITE_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct amba_ecb_ctx),
+ .cra_alignmask = AMBARELLA_CRYPTO_ALIGNMENT - 1,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_init = aes_cra_init,
+ .cra_u = {
+ .ablkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .setkey = ecb_aes_set_key,
+ .encrypt = ecb_aes_encrypt,
+ .decrypt = ecb_aes_decrypt,
+ }
+ }
+};
+
+static int cbc_aes_encrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ int err = 0;
+
+ return err;
+}
+
+static int cbc_aes_decrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ int err = 0;
+
+ return err;
+}
+
+static struct crypto_alg cbc_aes_alg = {
+ .cra_name = "cbc(aes)",
+ .cra_driver_name = "cbc-aes-ambarella",
+ .cra_priority = AMBARELLA_COMPOSITE_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypto_aes_ctx),
+ .cra_alignmask = AMBARELLA_CRYPTO_ALIGNMENT - 1,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(cbc_aes_alg.cra_list),
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = crypto_aes_set_key,
+ .encrypt = cbc_aes_encrypt,
+ .decrypt = cbc_aes_decrypt,
+ }
+ }
+};
+/************************************MD5 START**************************/
+
+struct md5_sha1_fun_t{
+ void (*wdata)(u32*,u32*,int);
+ void (*rdata)(u32*,u32*,int);
+}md5_sha1_fun;
+
+static void ambarella_md5_transform(u32 *hash, u32 const *in)
+{
+ u32 ready;
+ do{}while(mutex_trylock(&engine_lock) == 0);
+
+ memcpy(&g_md5_digest.digest_0, hash, 16);
+
+ do{
+ ready= amba_readl(CRYPT_MD5_SHA1_READY_INPUT);
+ }while(ready != 1);
+
+ md5_sha1_fun.wdata((u32 *)CRYPT_MD5_INIT_31_0,&(g_md5_digest.digest_0),16);
+
+ do{
+ ready= amba_readl(CRYPT_MD5_SHA1_READY_INPUT);
+ }while(ready != 1);
+
+ memcpy(&g_md5_data.data[0], in, 64);
+
+ md5_sha1_fun.wdata((u32 *)CRYPT_MD5_INPUT_31_0,&(g_md5_data.data[0]),64);
+
+ if(unlikely(config_polling_mode == 0)) {
+ do{
+ ready = try_wait_for_completion(&g_md5_sha1_irq_wait);
+ }while(ready != 1);
+ }else{
+ do{
+ ready = amba_readl(CRYPT_MD5_OUTPUT_READY);
+ }while(ready != 1);
+ }
+
+ md5_sha1_fun.rdata(&(g_md5_digest.digest_0),(u32 *)CRYPT_MD5_OUTPUT_31_0, 16);
+
+ memcpy(hash, &g_md5_digest.digest_0, 16);
+
+ mutex_unlock(&engine_lock);
+}
+
+static inline void le32_to_cpu_array(u32 *buf, unsigned int words)
+{
+ while (words--) {
+ __le32_to_cpus(buf);
+ buf++;
+ }
+}
+
+static inline void cpu_to_le32_array(u32 *buf, unsigned int words)
+{
+ while (words--) {
+ __cpu_to_le32s(buf);
+ buf++;
+ }
+}
+
+static inline void ambarella_md5_transform_helper(struct md5_state *ctx)
+{
+ le32_to_cpu_array(ctx->block, sizeof(ctx->block)/sizeof(u32));
+ ambarella_md5_transform(ctx->hash, ctx->block);
+}
+
+static int ambarella_md5_init(struct shash_desc *desc)
+{
+ struct md5_state *mctx = shash_desc_ctx(desc);
+ mctx->hash[0] = 0x67452301;
+ mctx->hash[1] = 0xefcdab89;
+ mctx->hash[2] = 0x98badcfe;
+ mctx->hash[3] = 0x10325476;
+ mctx->byte_count = 0;
+ return 0;
+}
+
+static int ambarella_md5_update(struct shash_desc *desc, const u8 *data, unsigned int len)
+{
+ struct md5_state *mctx = shash_desc_ctx(desc);
+ const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
+ mctx->byte_count += len;
+
+ if (avail > len) {
+ memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
+ data, len);
+ return 0;
+ }
+
+ memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
+ data, avail);
+
+ ambarella_md5_transform_helper(mctx);
+ data += avail;
+ len -= avail;
+
+ while (len >= sizeof(mctx->block)) {
+ memcpy(mctx->block, data, sizeof(mctx->block));
+ ambarella_md5_transform_helper(mctx);
+ data += sizeof(mctx->block);
+ len -= sizeof(mctx->block);
+ }
+
+ memcpy(mctx->block, data, len);
+
+ return 0;
+}
+
+static int ambarella_md5_final(struct shash_desc *desc, u8 *out)
+{
+ struct md5_state *mctx = shash_desc_ctx(desc);
+ const unsigned int offset = mctx->byte_count & 0x3f;
+ char *p = (char *)mctx->block + offset;
+ int padding = 56 - (offset + 1);
+ *p++ = 0x80;
+ if (padding < 0) {
+ memset(p, 0x00, padding + sizeof (u64));
+ ambarella_md5_transform_helper(mctx);
+ p = (char *)mctx->block;
+ padding = 56;
+ }
+
+ memset(p, 0, padding);
+ mctx->block[14] = mctx->byte_count << 3;
+ mctx->block[15] = mctx->byte_count >> 29;
+ le32_to_cpu_array(mctx->block, (sizeof(mctx->block) -
+ sizeof(u64)) / sizeof(u32));
+ ambarella_md5_transform(mctx->hash, mctx->block);
+ cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(u32));
+ memcpy(out, mctx->hash, sizeof(mctx->hash));
+ memset(mctx, 0, sizeof(*mctx));
+ return 0;
+}
+
+static int ambarella_md5_export(struct shash_desc *desc, void *out)
+{
+ struct md5_state *ctx = shash_desc_ctx(desc);
+ memcpy(out, ctx, sizeof(*ctx));
+ return 0;
+}
+
+static int ambarella_md5_import(struct shash_desc *desc, const void *in)
+{
+ struct md5_state *ctx = shash_desc_ctx(desc);
+ memcpy(ctx, in, sizeof(*ctx));
+ return 0;
+}
+
+static struct shash_alg md5_alg = {
+ .digestsize = MD5_DIGEST_SIZE,
+ .init = ambarella_md5_init,
+ .update = ambarella_md5_update,
+ .final = ambarella_md5_final,
+ .export = ambarella_md5_export,
+ .import = ambarella_md5_import,
+ .descsize = sizeof(struct md5_state),
+ .statesize = sizeof(struct md5_state),
+ .base = {
+ .cra_name = "md5",
+ .cra_driver_name= "md5-ambarella",
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+};
+/************************************MD5 END**************************/
+
+/************************************SHA1 START**************************/
+static inline void be32_to_cpu_array(u32 *buf, unsigned int words)
+{
+ while (words--) {
+ __be32_to_cpus(buf);
+ buf++;
+ }
+}
+
+static inline void cpu_to_be32_array(u32 *buf, unsigned int words)
+{
+ while (words--) {
+ __cpu_to_be32s(buf);
+ buf++;
+ }
+}
+
+static int ambarella_sha1_init(struct shash_desc *desc)
+{
+ struct sha1_state *sctx = shash_desc_ctx(desc);
+ *sctx = (struct sha1_state){
+ .state = { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 },
+ };
+ return 0;
+}
+
+void md5_sha1_write64(u32 * addr,u32 * buf, unsigned int len )
+{
+ /* len%8 ,align at 64bit*/
+ if ((len&0x7)){
+ len += (len&0x7);
+ }
+ _ambarella_crypto_aligned_write64(addr,buf,len);
+}
+
+void md5_sha1_read64(u32 * addr,u32 * buf, unsigned int len )
+{
+ /* len%8 ,align at 64bit*/
+ if ((len&0x7)){
+ len += (len&0x7);
+ }
+ _ambarella_crypto_aligned_read64(addr,buf,len);
+}
+
+void ambarella_sha1_transform(__u32 *digest, const char *in, __u32 *W)
+{
+ u32 ready;
+
+ do{}while(mutex_trylock(&engine_lock) == 0);
+
+ cpu_to_be32_array(digest, 5);
+ memcpy(&g_sha1_digest.digest_0, digest, 16);
+ g_sha1_digest.digest_128 = digest[4];
+
+ do{
+ ready= amba_readl(CRYPT_MD5_SHA1_READY_INPUT);
+ }while(ready != 1);
+
+ md5_sha1_fun.wdata((u32 *)CRYPT_SHA1_INIT_31_0,&(g_sha1_digest.digest_0),20);
+ do{
+ ready= amba_readl(CRYPT_MD5_SHA1_READY_INPUT);
+ }while(ready != 1);
+
+ memcpy(&g_sha1_data.data[0], in, 64);
+
+ md5_sha1_fun.wdata((u32 *)CRYPT_SHA1_INPUT_31_0,&(g_sha1_data.data[0]),64);
+
+ if(likely(config_polling_mode == 0)) {
+ do{
+ ready = try_wait_for_completion(&g_md5_sha1_irq_wait);
+ }while(ready != 1);
+
+ }else{
+ do{
+ ready = amba_readl(CRYPT_SHA1_OUTPUT_READY);
+ }while(ready != 1);
+ }
+
+ md5_sha1_fun.rdata(&(g_sha1_digest.digest_0),(u32 *)CRYPT_SHA1_OUTPUT_31_0,20);
+
+ memcpy(digest, &g_sha1_digest.digest_0, 20);
+ cpu_to_be32_array(digest, 5);
+
+ mutex_unlock(&engine_lock);
+}
+
+
+
+static int ambarella_sha1_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+{
+ struct sha1_state *sctx = shash_desc_ctx(desc);
+ unsigned int partial, done;
+ const u8 *src;
+
+ partial = sctx->count & 0x3f;
+ sctx->count += len;
+ done = 0;
+ src = data;
+
+ if ((partial + len) > 63) {
+ u32 temp[SHA_WORKSPACE_WORDS];
+
+ if (partial) {
+ done = -partial;
+ memcpy(sctx->buffer + partial, data, done + 64);
+ src = sctx->buffer;
+ }
+
+ do {
+ ambarella_sha1_transform(sctx->state, src, temp);
+ done += 64;
+ src = data + done;
+ } while (done + 63 < len);
+
+ memset(temp, 0, sizeof(temp));
+ partial = 0;
+ }
+ memcpy(sctx->buffer + partial, src, len - done);
+
+ return 0;
+}
+
+/* Add padding and return the message digest. */
+static int ambarella_sha1_final(struct shash_desc *desc, u8 *out)
+{
+ struct sha1_state *sctx = shash_desc_ctx(desc);
+ __be32 *dst = (__be32 *)out;
+ u32 i, index, padlen;
+ __be64 bits;
+ static const u8 padding[64] = { 0x80, };
+
+ bits = cpu_to_be64(sctx->count << 3);
+
+ /* Pad out to 56 mod 64 */
+ index = sctx->count & 0x3f;
+ padlen = (index < 56) ? (56 - index) : ((64+56) - index);
+ ambarella_sha1_update(desc, padding, padlen);
+
+ /* Append length */
+ ambarella_sha1_update(desc, (const u8 *)&bits, sizeof(bits));
+
+ /* Store state in digest */
+ for (i = 0; i < 5; i++)
+ dst[i] = cpu_to_be32(sctx->state[i]);
+
+ /* Wipe context */
+ memset(sctx, 0, sizeof *sctx);
+
+ return 0;
+}
+
+static int ambarella_sha1_export(struct shash_desc *desc, void *out)
+{
+ struct sha1_state *sctx = shash_desc_ctx(desc);
+ memcpy(out, sctx, sizeof(*sctx));
+ return 0;
+}
+
+static int ambarella_sha1_import(struct shash_desc *desc, const void *in)
+{
+ struct sha1_state *sctx = shash_desc_ctx(desc);
+ memcpy(sctx, in, sizeof(*sctx));
+ return 0;
+}
+
+
+static struct shash_alg sha1_alg = {
+ .digestsize = SHA1_DIGEST_SIZE,
+ .init = ambarella_sha1_init,
+ .update = ambarella_sha1_update,
+ .final = ambarella_sha1_final,
+ .export = ambarella_sha1_export,
+ .import = ambarella_sha1_import,
+ .descsize = sizeof(struct sha1_state),
+ .statesize = sizeof(struct sha1_state),
+ .base = {
+ .cra_name = "sha1",
+ .cra_driver_name= "sha1-ambarella",
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA1_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+};
+
+/************************************SHA1 END****************************/
+
+static irqreturn_t ambarella_aes_irq(int irqno, void *dev_id)
+{
+ complete(&g_aes_irq_wait);
+
+ return IRQ_HANDLED;
+}
+static irqreturn_t ambarella_des_irq(int irqno, void *dev_id)
+{
+ complete(&g_des_irq_wait);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t ambarella_md5_sha1_irq(int irqno, void *dev_id)
+{
+ complete(&g_md5_sha1_irq_wait);
+
+ return IRQ_HANDLED;
+}
+
+static int ambarella_crypto_of_parse(struct platform_device *pdev,
+ struct ambarella_crypto_info *pinfo)
+{
+ struct device_node *np = pdev->dev.of_node;
+
+ pinfo->binary_mode = !!of_find_property(np, "amb,binary-mode", NULL);
+ pinfo->cap_md5_sha1 = !!of_find_property(np, "amb,cap-md5-sha1", NULL);
+ pinfo->data_swap = !!of_find_property(np, "amb,data-swap", NULL);
+ pinfo->reg_64bit = !!of_find_property(np, "amb,reg-64bit", NULL);
+
+ return 0;
+}
+
+static int ambarella_crypto_probe(struct platform_device *pdev)
+{
+ struct resource *mem = 0;
+ struct ambarella_crypto_info *pinfo = 0;
+ int aes_irq, des_irq, md5_irq, sha1_irq;
+ int errCode;
+
+ pinfo = devm_kzalloc(&pdev->dev, sizeof(*pinfo), GFP_KERNEL);
+ if (pinfo == NULL) {
+ dev_err(&pdev->dev, "Out of memory!\n");
+ return -ENOMEM;
+ }
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (mem == NULL) {
+ dev_err(&pdev->dev, "Get crypto mem resource failed!\n");
+ return -ENXIO;
+ }
+
+ pinfo->regbase = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
+ if (!pinfo->regbase) {
+ dev_err(&pdev->dev, "devm_ioremap() failed\n");
+ return -ENOMEM;
+ }
+
+ platform_set_drvdata(pdev, pinfo);
+
+ ambarella_crypto_of_parse(pdev, pinfo);
+
+ if(likely(config_polling_mode == 0)) {
+ aes_irq = platform_get_irq_byname(pdev,"aes-irq");
+ if (aes_irq < 0) {
+ dev_err(&pdev->dev, "Get crypto aes irq failed!\n");
+ return aes_irq;
+ }
+
+ des_irq = platform_get_irq_byname(pdev,"des-irq");
+ if (des_irq < 0) {
+ dev_err(&pdev->dev, "Get crypto des irq failed!\n");
+ return aes_irq;
+ }
+
+ errCode = devm_request_irq(&pdev->dev, aes_irq,
+ ambarella_aes_irq, IRQF_TRIGGER_RISING,
+ dev_name(&pdev->dev), pinfo);
+ if (errCode < 0) {
+ dev_err(&pdev->dev, "Request aes irq failed!\n");
+ return errCode;
+ }
+ errCode = devm_request_irq(&pdev->dev, des_irq,
+ ambarella_des_irq, IRQF_TRIGGER_RISING,
+ dev_name(&pdev->dev), pinfo);
+ if (errCode < 0) {
+ dev_err(&pdev->dev, "Request des irq failed!\n");
+ return errCode;
+ }
+
+ amba_writel(CRYPT_A_INT_EN_REG, 0x0001);
+ amba_writel(CRYPT_D_INT_EN_REG, 0x0001);
+
+ if (pinfo->cap_md5_sha1 == 1) {
+ md5_irq = platform_get_irq_byname(pdev,"md5-irq");
+ if (md5_irq < 0){
+ dev_err(&pdev->dev, "Get crypto md5 irq failed!\n");
+ return md5_irq;
+ }
+
+ sha1_irq = platform_get_irq_byname(pdev,"sha1-irq");
+ if (sha1_irq < 0){
+ dev_err(&pdev->dev, "Get crypto sha1 irq failed!\n");
+ return sha1_irq;
+ }
+
+ /* md5 and sha1 opentions can't be interleaved, so we
+ * use the same return irq func */
+ errCode = devm_request_irq(&pdev->dev, md5_irq,
+ ambarella_md5_sha1_irq,
+ IRQF_TRIGGER_RISING,
+ dev_name(&pdev->dev), pinfo);
+ if (errCode < 0) {
+ dev_err(&pdev->dev, "Request md5 irq failed!\n");
+ return errCode;
+ }
+
+ errCode = devm_request_irq(&pdev->dev, sha1_irq,
+ ambarella_md5_sha1_irq,
+ IRQF_TRIGGER_RISING,
+ dev_name(&pdev->dev), pinfo);
+ if (errCode < 0) {
+ dev_err(&pdev->dev, "Request sha1 irq failed!\n");
+ return errCode;
+ }
+
+ amba_writel(CRYPT_MD5_INT_EN, 0x0001);
+ amba_writel(CRYPT_SHA1_INT_EN, 0x0001);
+ }
+ //init workqueue
+
+ spin_lock_init(&amba_queue.lock);
+ handle_queue = create_workqueue("Crypto Ablk Workqueue");
+ INIT_WORK(&work,(void *)do_queue);
+
+ //register ecb aes ,des
+ errCode = crypto_register_alg(&ecb_aes_alg);
+ if (errCode <0) {
+ dev_err(&pdev->dev,"register ecb_aes_alg failed. \n");
+ return errCode;
+ }
+
+ crypto_init_queue(&amba_queue.queue,50);
+ } else {
+ errCode = crypto_register_alg(&aes_alg);
+ if (errCode <0) {
+ dev_err(&pdev->dev, "reigster aes_alg failed.\n");
+ return errCode;
+ }
+ }
+
+ if (pinfo->binary_mode){
+ aes_fun.opcode = aes_opcode;
+ des_fun.opcode = des_opcode;
+ }else{
+ aes_fun.opcode = null_fun;
+ des_fun.opcode = null_fun;
+ }
+
+ if (pinfo->data_swap){
+ aes_fun.wdata = swap_write;
+ aes_fun.rdata = swap_read;
+ des_fun.wdata = swap_write;
+ des_fun.rdata = swap_read;
+ }else{
+ aes_fun.wdata = (void*)memcpy;
+ aes_fun.rdata = (void*)memcpy;
+ des_fun.wdata = (void*)memcpy;
+ des_fun.rdata = (void*)memcpy;
+ }
+
+ if (pinfo->reg_64bit){
+ aes_fun.reg_enc = aes_reg_enc_64;
+ aes_fun.reg_dec = aes_reg_dec_64;
+ des_fun.reg_enc = des_reg_enc_64;
+ des_fun.reg_dec = des_reg_dec_64;
+ }else{
+ aes_fun.reg_enc = aes_reg_enc_dec_32;
+ aes_fun.reg_dec = aes_reg_enc_dec_32;
+ des_fun.reg_enc = des_reg_enc_dec_32;
+ des_fun.reg_dec = des_reg_enc_dec_32;
+ }
+
+ if (pinfo->cap_md5_sha1) {
+ md5_sha1_fun.wdata = (void*)md5_sha1_write64;
+ md5_sha1_fun.rdata = (void*)md5_sha1_read64;
+
+ if ((errCode = crypto_register_shash(&sha1_alg))) {
+ dev_err(&pdev->dev, "reigster sha1_alg failed.\n");
+ goto crypto_errCode_free_md5_sha1_irq;
+ }
+ if ((errCode = crypto_register_shash(&md5_alg))) {
+ dev_err(&pdev->dev, "reigster md5_alg failed.\n");
+ goto crypto_errCode_free_sha1;
+ }
+ }
+
+ if ((errCode = crypto_register_alg(&des_alg))) {
+ dev_err(&pdev->dev, "reigster des_alg failed.\n");
+ goto crypto_errCode_free_md5;
+ }
+
+ dev_notice(&pdev->dev,"%s probed(%s mode).\n", ambdev_name,
+ config_polling_mode ? "polling" : "interrupt");
+
+ return 0;
+
+crypto_errCode_free_md5:
+ if (pinfo->cap_md5_sha1)
+ crypto_unregister_shash(&md5_alg);
+
+crypto_errCode_free_sha1:
+ if (pinfo->cap_md5_sha1)
+ crypto_unregister_shash(&sha1_alg);
+
+crypto_errCode_free_md5_sha1_irq:
+ if(unlikely(config_polling_mode == 0)){
+ destroy_workqueue(handle_queue);
+ crypto_unregister_alg(&ecb_aes_alg);
+ }else{
+ crypto_unregister_alg(&aes_alg);
+ }
+
+ return errCode;
+}
+
+static int ambarella_crypto_remove(struct platform_device *pdev)
+{
+ struct ambarella_crypto_info *pinfo;
+ int errCode = 0;
+
+ pinfo = platform_get_drvdata(pdev);
+
+ if (pinfo->cap_md5_sha1) {
+ crypto_unregister_shash(&sha1_alg);
+ crypto_unregister_shash(&md5_alg);
+ }
+ crypto_unregister_alg(&des_alg);
+
+ if (config_polling_mode == 0) {
+ destroy_workqueue(handle_queue);
+ crypto_unregister_alg(&ecb_aes_alg);
+
+ platform_set_drvdata(pdev, NULL);
+ } else {
+ crypto_unregister_alg(&aes_alg);
+ }
+
+ dev_notice(&pdev->dev, "%s removed.\n", ambdev_name);
+
+ return errCode;
+}
+
+static const struct of_device_id ambarella_crypto_dt_ids[] = {
+ {.compatible = "ambarella,crypto", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ambarella_crypto_dt_ids);
+
+static struct platform_driver ambarella_crypto_driver = {
+ .probe = ambarella_crypto_probe,
+ .remove = ambarella_crypto_remove,
+#ifdef CONFIG_PM
+ .suspend = NULL,
+ .resume = NULL,
+#endif
+ .driver = {
+ .name = "ambarella-crypto",
+ .owner = THIS_MODULE,
+ .of_match_table = ambarella_crypto_dt_ids,
+ },
+};
+
+module_platform_driver(ambarella_crypto_driver);
+
+MODULE_DESCRIPTION("Ambarella Cryptography Engine");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Qiao Wang");
+MODULE_ALIAS("crypo-all");
+
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 0ba5a951..4933aa6a 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -312,6 +312,17 @@ config MMP_PDMA
help
Support the MMP PDMA engine for PXA and MMP platfrom.
+config AMBARELLA_DMA
+ tristate "Ambarella DMA Engine System support"
+ depends on PLAT_AMBARELLA
+ select DMA_ENGINE
+ help
+ Support the Ambarella DMA Engine. This engine is integrated into
+ Ambarella chip.
+
+ Say Y here if you have such a chipest.
+ If unsure,say N.
+
config DMA_ENGINE
bool
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index a2b0df59..613c2d4c 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -38,3 +38,4 @@ obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
obj-$(CONFIG_DMA_OMAP) += omap-dma.o
obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
+obj-$(CONFIG_AMBARELLA_DMA) += ambarella_dma.o
diff --git a/drivers/dma/ambarella_dma.c b/drivers/dma/ambarella_dma.c
new file mode 100644
index 00000000..21d04852
--- /dev/null
+++ b/drivers/dma/ambarella_dma.c
@@ -0,0 +1,1337 @@
+/*
+ * drivers/dma/ambarella_dma.c -- Ambarella DMA engine driver
+ *
+ * History:
+ * 2012/05/10 - Ken He <jianhe@ambarella.com> created file
+ *
+ * Coryright (c) 2008-2012, Ambarella, Inc.
+ * http://www.ambarella.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmapool.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_dma.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <mach/hardware.h>
+#include <plat/dma.h>
+#include <plat/rct.h>
+#include "dmaengine.h"
+#include "ambarella_dma.h"
+
+int ambarella_dma_channel_id(void *chan)
+{
+ return to_ambdma_chan((struct dma_chan *)chan)->id;
+}
+EXPORT_SYMBOL(ambarella_dma_channel_id);
+
+static int ambdma_proc_show(struct seq_file *m, void *v)
+{
+ struct ambdma_device *amb_dma = m->private;
+ struct ambdma_chan *amb_chan;
+ const char *sw_status;
+ const char *hw_status;
+ int i, len = 0;
+
+ for (i = 0; i < NUM_DMA_CHANNELS; i++) {
+ amb_chan = &amb_dma->amb_chan[i];
+
+ switch(amb_chan->status) {
+ case AMBDMA_STATUS_IDLE:
+ sw_status = "idle";
+ break;
+ case AMBDMA_STATUS_BUSY:
+ sw_status = "busy";
+ break;
+ case AMBDMA_STATUS_STOPPING:
+ sw_status = "stopping";
+ break;
+ default:
+ sw_status = "unknown";
+ break;
+ }
+
+ if (ambdma_chan_is_enabled(amb_chan))
+ hw_status = "running";
+ else
+ hw_status = "stopped";
+
+ len += seq_printf(m, "channel %d: %s, %d, %s, %s\n",
+ amb_chan->id, dma_chan_name(&amb_chan->chan),
+ amb_chan->chan.client_count, sw_status, hw_status);
+ }
+
+ len += seq_printf(m, "\nInput channel ID to stop specific dma channel:\n");
+ len += seq_printf(m, " example: echo 3 > dma\n\n");
+
+ return len;
+}
+
+static int ambdma_proc_write(struct file *file,
+ const char __user *buffer, size_t count, loff_t *ppos)
+{
+ struct ambdma_device *amb_dma = PDE_DATA(file_inode(file));
+ int id, ret;
+
+ ret = kstrtouint_from_user(buffer, count, 0, &id);
+ if (ret)
+ return ret;
+
+ if (id >= NUM_DMA_CHANNELS) {
+ printk("Invalid channel id\n");
+ return -EINVAL;
+ }
+
+ dmaengine_terminate_all(&amb_dma->amb_chan[id].chan);
+
+ return count;
+}
+
+static int ambdma_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ambdma_proc_show, PDE_DATA(inode));
+}
+
+static const struct file_operations proc_ambdma_fops = {
+ .open = ambdma_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .write = ambdma_proc_write,
+};
+
+static struct ambdma_desc *ambdma_alloc_desc(struct dma_chan *chan, gfp_t gfp_flags)
+{
+ struct ambdma_chan *amb_chan = to_ambdma_chan(chan);
+ struct ambdma_device *amb_dma = amb_chan->amb_dma;
+ struct ambdma_desc *amb_desc = NULL;
+ dma_addr_t phys;
+
+ amb_desc = kzalloc(sizeof(struct ambdma_desc), gfp_flags);
+ if (!amb_desc)
+ return NULL;
+
+ amb_desc->lli = dma_pool_alloc(amb_dma->lli_pool, gfp_flags, &phys);
+ if (!amb_desc->lli) {
+ kfree(amb_desc);
+ return NULL;
+ }
+
+ INIT_LIST_HEAD(&amb_desc->tx_list);
+ dma_async_tx_descriptor_init(&amb_desc->txd, chan);
+ /* txd.flags will be overwritten in prep functions */
+ amb_desc->txd.flags = DMA_CTRL_ACK;
+ amb_desc->txd.tx_submit = ambdma_tx_submit;
+ amb_desc->txd.phys = phys;
+ amb_desc->is_cyclic = 0;
+
+ return amb_desc;
+}
+
+static void ambdma_free_desc(struct dma_chan *chan, struct ambdma_desc *amb_desc)
+{
+ struct ambdma_chan *amb_chan = to_ambdma_chan(chan);
+ struct ambdma_device *amb_dma = amb_chan->amb_dma;
+
+ dma_pool_free(amb_dma->lli_pool, amb_desc->lli, amb_desc->txd.phys);
+ kfree(amb_desc);
+}
+
+static struct ambdma_desc *ambdma_get_desc(struct ambdma_chan *amb_chan)
+{
+ struct ambdma_desc *desc, *_desc;
+ struct ambdma_desc *ret = NULL;
+ unsigned long flags;
+
+ spin_lock_irqsave(&amb_chan->lock, flags);
+ list_for_each_entry_safe(desc, _desc, &amb_chan->free_list, desc_node) {
+ if (async_tx_test_ack(&desc->txd)) {
+ list_del_init(&desc->desc_node);
+ ret = desc;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&amb_chan->lock, flags);
+
+ /* no more descriptor available in initial pool: create one more */
+ if (!ret) {
+ ret = ambdma_alloc_desc(&amb_chan->chan, GFP_ATOMIC);
+ if (ret) {
+ spin_lock_irqsave(&amb_chan->lock, flags);
+ amb_chan->descs_allocated++;
+ spin_unlock_irqrestore(&amb_chan->lock, flags);
+ } else {
+ pr_err("%s: no more descriptors available\n", __func__);
+ }
+ }
+
+ return ret;
+}
+
+
+static void ambdma_put_desc(struct ambdma_chan *amb_chan,
+ struct ambdma_desc *amb_desc)
+{
+ unsigned long flags;
+
+ if (amb_desc) {
+ spin_lock_irqsave(&amb_chan->lock, flags);
+ list_splice_init(&amb_desc->tx_list, &amb_chan->free_list);
+ list_add_tail(&amb_desc->desc_node, &amb_chan->free_list);
+ spin_unlock_irqrestore(&amb_chan->lock, flags);
+ }
+}
+
+static void ambdma_return_desc(struct ambdma_chan *amb_chan,
+ struct ambdma_desc *amb_desc)
+{
+ /* move children to free_list */
+ list_splice_init(&amb_desc->tx_list, &amb_chan->free_list);
+ /* move myself to free_list */
+ list_move_tail(&amb_desc->desc_node, &amb_chan->free_list);
+
+}
+
+static void ambdma_chain_complete(struct ambdma_chan *amb_chan,
+ struct ambdma_desc *amb_desc)
+{
+ struct dma_async_tx_descriptor *txd = &amb_desc->txd;
+
+ dma_cookie_complete(txd);
+
+ ambdma_return_desc(amb_chan, amb_desc);
+
+ spin_unlock(&amb_chan->lock);
+ if (txd->callback && (txd->flags & DMA_PREP_INTERRUPT))
+ txd->callback(txd->callback_param);
+ spin_lock(&amb_chan->lock);
+
+ dma_run_dependencies(txd);
+}
+
+
+static void ambdma_complete_all(struct ambdma_chan *amb_chan)
+{
+ struct ambdma_desc *amb_desc, *_desc;
+ LIST_HEAD(list);
+
+ list_splice_init(&amb_chan->active_list, &list);
+
+ /* submit queued descriptors ASAP, i.e. before we go through
+ * the completed ones. */
+ if (!list_empty(&amb_chan->queue)) {
+ list_splice_init(&amb_chan->queue, &amb_chan->active_list);
+ ambdma_dostart(amb_chan, ambdma_first_active(amb_chan));
+ }
+
+ list_for_each_entry_safe(amb_desc, _desc, &list, desc_node)
+ ambdma_chain_complete(amb_chan, amb_desc);
+}
+
+static void ambdma_advance_work(struct ambdma_chan *amb_chan)
+{
+ if (list_empty(&amb_chan->active_list) || list_is_singular(&amb_chan->active_list)) {
+ ambdma_complete_all(amb_chan);
+ } else {
+ ambdma_chain_complete(amb_chan, ambdma_first_active(amb_chan));
+ /* active_list has been updated by ambdma_chain_complete(),
+ * so ambdma_first_active() will get another amb_desc. */
+ ambdma_dostart(amb_chan, ambdma_first_active(amb_chan));
+ }
+}
+
+static void ambdma_handle_error(struct ambdma_chan *amb_chan,
+ struct ambdma_desc *bad_desc)
+{
+ list_del_init(&bad_desc->desc_node);
+
+ /* try to submit queued descriptors to restart dma */
+ list_splice_init(&amb_chan->queue, amb_chan->active_list.prev);
+ if (!list_empty(&amb_chan->active_list))
+ ambdma_dostart(amb_chan, ambdma_first_active(amb_chan));
+
+ pr_crit("%s: DMA error on channel %d: 0x%08x\n",
+ __func__, amb_chan->id, bad_desc->lli->rpt);
+
+ /* pretend the descriptor completed successfully */
+ ambdma_chain_complete(amb_chan, bad_desc);
+}
+
+static void ambdma_tasklet(unsigned long data)
+{
+ struct ambdma_chan *amb_chan = (struct ambdma_chan *)data;
+ struct ambdma_desc *amb_desc = NULL;
+ enum ambdma_status old_status;
+ unsigned long flags;
+
+ spin_lock_irqsave(&amb_chan->lock, flags);
+
+ old_status = amb_chan->status;
+ if (!ambdma_chan_is_enabled(amb_chan)) {
+ amb_chan->status = AMBDMA_STATUS_IDLE;
+ if (!list_empty(&amb_chan->stopping_list))
+ ambdma_return_desc(amb_chan, ambdma_first_stopping(amb_chan));
+ }
+
+ /* someone might have called terminate all */
+ if (list_empty(&amb_chan->active_list))
+ goto tasklet_out;
+
+ /* note: if the DMA channel is stopped by DMA_TERMINATE_ALL rather
+ * than naturally end, then ambdma_first_active() will return the next
+ * descriptor that need to be started, but not the descriptor that
+ * invoke this tasklet (IRQ) */
+ amb_desc = ambdma_first_active(amb_chan);
+
+ if (!amb_desc->is_cyclic && amb_chan->status != AMBDMA_STATUS_IDLE) {
+ pr_err("%s: channel(%d) invalid status\n", __func__, amb_chan->id);
+ goto tasklet_out;
+ }
+
+ if (old_status == AMBDMA_STATUS_BUSY) {
+ /* the IRQ is triggered by DMA stopping naturally or by errors.*/
+ if (ambdma_desc_is_error(amb_desc)) {
+ ambdma_handle_error(amb_chan, amb_desc);
+ } else if (amb_desc->is_cyclic) {
+ spin_unlock(&amb_chan->lock);
+ if (amb_desc->txd.callback)
+ amb_desc->txd.callback(amb_desc->txd.callback_param);
+ spin_lock(&amb_chan->lock);
+ } else {
+ ambdma_advance_work(amb_chan);
+ }
+ } else if (old_status == AMBDMA_STATUS_STOPPING) {
+ /* the DMA channel is stopped by DMA_TERMINATE_ALL. */
+ ambdma_dostart(amb_chan, amb_desc);
+ }
+
+tasklet_out:
+ spin_unlock_irqrestore(&amb_chan->lock, flags);
+}
+
+static irqreturn_t ambdma_dma_irq_handler(int irq, void *dev_data)
+{
+ struct ambdma_device *amb_dma = dev_data;
+ u32 i, int_src;
+ irqreturn_t ret = IRQ_NONE;
+
+ int_src = amba_readl(DMA_REG(DMA_INT_OFFSET));
+
+ if (int_src == 0)
+ return IRQ_HANDLED;
+
+ for (i = 0; i < NUM_DMA_CHANNELS; i++) {
+ spin_lock(&amb_dma->amb_chan[i].lock);
+ if (int_src & (1 << i)) {
+ amba_writel(DMA_CHAN_STA_REG(i), 0);
+ tasklet_schedule(&amb_dma->amb_chan[i].tasklet);
+ ret = IRQ_HANDLED;
+ }
+ spin_unlock(&amb_dma->amb_chan[i].lock);
+ }
+
+ return ret;
+}
+
+static int ambdma_stop_channel(struct ambdma_chan *amb_chan)
+{
+ struct ambdma_device *amb_dma = amb_chan->amb_dma;
+ struct ambdma_desc *first, *amb_desc;
+ int id = amb_chan->id;
+
+ if (amb_chan->status == AMBDMA_STATUS_BUSY) {
+ if (amb_chan->force_stop == 0 || amb_dma->support_prs) {
+ /* if force_stop == 0, the DMA channel is still running
+ * at this moment. And if the chip doesn't support early
+ * end, normally there are still two IRQs will be triggered
+ * untill DMA channel stops. */
+ first = ambdma_first_active(amb_chan);
+ first->lli->attr |= DMA_DESC_EOC;
+ list_for_each_entry(amb_desc, &first->tx_list, desc_node) {
+ amb_desc->lli->attr |= DMA_DESC_EOC;
+ }
+ amb_chan->status = AMBDMA_STATUS_STOPPING;
+ /* active_list is still being used by DMA controller,
+ * so move it to stopping_list to avoid being
+ * initialized by next transfer */
+ list_move_tail(&first->desc_node, &amb_chan->stopping_list);
+
+ if (amb_dma->support_prs)
+ amba_setbitsl(DMA_REG(DMA_EARLY_END_OFFSET), 0x1 << id);
+ } else {
+ /* Disable DMA: this sequence is not mentioned at APM.*/
+ amba_writel(DMA_CHAN_STA_REG(id), DMA_CHANX_STA_OD);
+ amba_writel(DMA_CHAN_DA_REG(id), amb_dma->dummy_lli_phys);
+ amba_writel(DMA_CHAN_CTR_REG(id),
+ DMA_CHANX_CTR_WM | DMA_CHANX_CTR_NI);
+ udelay(1);
+ /* avoid to trigger dummy IRQ.*/
+ amba_writel(DMA_CHAN_STA_REG(id), 0x0);
+ amb_chan->force_stop = 0;
+ if (ambdma_chan_is_enabled(amb_chan)) {
+ pr_err("%s: stop dma channel(%d) failed\n",
+ __func__, id);
+ return -EIO;
+ }
+ amb_chan->status = AMBDMA_STATUS_IDLE;
+ }
+ }
+
+ return 0;
+}
+
+static int ambdma_pause_channel(struct ambdma_chan *amb_chan)
+{
+ struct ambdma_device *amb_dma = amb_chan->amb_dma;
+
+ if (!amb_dma->support_prs)
+ return -ENXIO;
+
+ amba_setbitsl(DMA_REG(DMA_PAUSE_SET_OFFSET), 1 << amb_chan->id);
+
+ return 0;
+}
+
+static int ambdma_resume_channel(struct ambdma_chan *amb_chan)
+{
+ struct ambdma_device *amb_dma = amb_chan->amb_dma;
+
+ if (!amb_dma->support_prs)
+ return -ENXIO;
+
+ amba_setbitsl(DMA_REG(DMA_PAUSE_CLR_OFFSET), 1 << amb_chan->id);
+
+ return 0;
+}
+
+static void ambdma_dostart(struct ambdma_chan *amb_chan, struct ambdma_desc *first)
+{
+ int id = amb_chan->id;
+
+ /* if DMA channel is not idle right now, the DMA descriptor
+ * will be started at ambdma_tasklet(). */
+ if (amb_chan->status > AMBDMA_STATUS_IDLE)
+ return;
+
+ if (ambdma_chan_is_enabled(amb_chan)) {
+ pr_err("%s: channel(%d) should be idle here\n", __func__, id);
+ return;
+ }
+
+ amba_writel(DMA_CHAN_STA_REG(id), 0x0);
+ amba_writel(DMA_CHAN_DA_REG(id), first->txd.phys);
+ amba_writel(DMA_CHAN_CTR_REG(id), DMA_CHANX_CTR_EN | DMA_CHANX_CTR_D);
+ amb_chan->status = AMBDMA_STATUS_BUSY;
+}
+
+static dma_cookie_t ambdma_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+ struct ambdma_desc *amb_desc;
+ struct ambdma_chan *amb_chan;
+ dma_cookie_t cookie;
+ unsigned long flags;
+
+ amb_desc = to_ambdma_desc(tx);
+ amb_chan = to_ambdma_chan(tx->chan);
+
+ spin_lock_irqsave(&amb_chan->lock, flags);
+
+ cookie = dma_cookie_assign(tx);
+
+ if (list_empty(&amb_chan->active_list)) {
+ list_add_tail(&amb_desc->desc_node, &amb_chan->active_list);
+ ambdma_dostart(amb_chan, amb_desc);
+ } else {
+ list_add_tail(&amb_desc->desc_node, &amb_chan->queue);
+ }
+
+ spin_unlock_irqrestore(&amb_chan->lock, flags);
+
+ return cookie;
+}
+
+/* DMA Engine API begin */
+static int ambdma_alloc_chan_resources(struct dma_chan *chan)
+{
+ struct ambdma_chan *amb_chan;
+ struct ambdma_desc *amb_desc;
+ LIST_HEAD(tmp_list);
+ unsigned long flags;
+ int i;
+
+ amb_chan = to_ambdma_chan(chan);
+
+ if (amb_chan->status == AMBDMA_STATUS_BUSY) {
+ pr_err("%s: channel(%d) not idle!\n", __func__, amb_chan->id);
+ return -EIO;
+ }
+
+ /* Alloc descriptors for this channel */
+ for (i = 0; i < NR_DESCS_PER_CHANNEL; i++) {
+ amb_desc = ambdma_alloc_desc(chan, GFP_KERNEL);
+ if (amb_desc == NULL) {
+ struct ambdma_desc *d, *_d;
+ list_for_each_entry_safe(d, _d, &tmp_list, desc_node) {
+ ambdma_free_desc(chan, d);
+ }
+ pr_err("%s: failed to allocate descriptor\n", __func__);
+ return -ENOMEM;
+ }
+
+ list_add_tail(&amb_desc->desc_node, &tmp_list);
+ }
+
+ spin_lock_irqsave(&amb_chan->lock, flags);
+ amb_chan->descs_allocated = i;
+ list_splice_init(&tmp_list, &amb_chan->free_list);
+ dma_cookie_init(chan);
+ amb_chan->force_stop = 0;
+ spin_unlock_irqrestore(&amb_chan->lock, flags);
+
+ return amb_chan->descs_allocated;
+}
+
+static void ambdma_free_chan_resources(struct dma_chan *chan)
+{
+ struct ambdma_chan *amb_chan;
+ struct ambdma_desc *amb_desc, *_desc;
+ LIST_HEAD(list);
+ unsigned long flags;
+
+ amb_chan = to_ambdma_chan(chan);
+
+ spin_lock_irqsave(&amb_chan->lock, flags);
+ BUG_ON(!list_empty(&amb_chan->active_list));
+ BUG_ON(!list_empty(&amb_chan->queue));
+ BUG_ON(amb_chan->status == AMBDMA_STATUS_BUSY);
+
+ list_splice_init(&amb_chan->free_list, &list);
+ amb_chan->descs_allocated = 0;
+ spin_unlock_irqrestore(&amb_chan->lock, flags);
+
+ list_for_each_entry_safe(amb_desc, _desc, &list, desc_node)
+ ambdma_free_desc(chan, amb_desc);
+}
+
+/* If this function is called when the dma channel is transferring data,
+ * you may get inaccuracy result. */
+static u32 ambdma_get_bytes_left(struct dma_chan *chan, dma_cookie_t cookie)
+{
+ struct ambdma_chan *amb_chan = to_ambdma_chan(chan);
+ struct ambdma_desc *first = NULL, *amb_desc;
+ unsigned long flags;
+ u32 count = 0;
+
+ spin_lock_irqsave(&amb_chan->lock, flags);
+
+ /* according to the cookie, find amb_desc in active_list. */
+ if (!list_empty(&amb_chan->active_list)) {
+ amb_desc = ambdma_first_active(amb_chan);
+ if (amb_desc->txd.cookie == cookie)
+ first = amb_desc;
+ }
+
+ /* if it's in active list, we should get the count for non-completed
+ * desc from the dma channel status register, and get the count for
+ * completed desc from the "rpt" field in desc. */
+ if (first) {
+ count = amba_readl(DMA_CHAN_STA_REG(amb_chan->id));
+ count &= AMBARELLA_DMA_MAX_LENGTH;
+
+ count += ambdma_desc_transfer_count(first);
+ if (!list_empty(&first->tx_list)) {
+ list_for_each_entry(amb_desc, &first->tx_list, desc_node) {
+ count += ambdma_desc_transfer_count(amb_desc);
+ }
+ }
+ } else if (!list_empty(&amb_chan->queue)) {
+ /* if it's in queue list, all of the desc have not been started,
+ * so the transferred count is always 0. */
+ list_for_each_entry(amb_desc, &amb_chan->queue, desc_node) {
+ if (amb_desc->txd.cookie == cookie) {
+ first = amb_desc;
+ count = 0;
+ break;
+ }
+ }
+ }
+
+ spin_unlock_irqrestore(&amb_chan->lock, flags);
+
+ BUG_ON(!first);
+
+ return first->len - count;
+}
+
+static enum dma_status ambdma_tx_status(struct dma_chan *chan,
+ dma_cookie_t cookie, struct dma_tx_state *txstate)
+{
+ enum dma_status ret;
+
+ ret = dma_cookie_status(chan, cookie, txstate);
+ if (ret != DMA_SUCCESS)
+ dma_set_residue(txstate, ambdma_get_bytes_left(chan, cookie));
+
+ return ret;
+}
+
+static void ambdma_issue_pending(struct dma_chan *chan)
+{
+ struct ambdma_chan *amb_chan = to_ambdma_chan(chan);
+ unsigned long flags;
+
+ spin_lock_irqsave(&amb_chan->lock, flags);
+
+ /* if dma channel is not idle, will active queue list in tasklet. */
+ if (amb_chan->status == AMBDMA_STATUS_IDLE) {
+ if (!list_empty(&amb_chan->active_list))
+ pr_err("%s: active_list should be empty here\n", __func__);
+ else
+ ambdma_advance_work(amb_chan);
+ }
+
+ spin_unlock_irqrestore(&amb_chan->lock, flags);
+}
+
+static int ambdma_device_control(struct dma_chan *chan,
+ enum dma_ctrl_cmd cmd, unsigned long arg)
+{
+ struct ambdma_chan *amb_chan = to_ambdma_chan(chan);
+ struct dma_slave_config *config = (void *)arg;
+ enum dma_slave_buswidth width = 0;
+ int ret = 0, maxburst;
+ struct ambdma_desc *amb_desc, *_desc;
+ LIST_HEAD(list);
+ unsigned long flags;
+
+ switch (cmd) {
+ case DMA_TERMINATE_ALL:
+ spin_lock_irqsave(&amb_chan->lock, flags);
+ ambdma_stop_channel(amb_chan);
+
+ /* active_list entries will end up before queued entries */
+ list_splice_init(&amb_chan->queue, &list);
+ list_splice_init(&amb_chan->active_list, &list);
+
+ /* Flush all pending and queued descriptors */
+ list_for_each_entry_safe(amb_desc, _desc, &list, desc_node) {
+ /* move children to free_list */
+ list_splice_init(&amb_desc->tx_list, &amb_chan->free_list);
+ /* move myself to free_list */
+ list_move_tail(&amb_desc->desc_node, &amb_chan->free_list);
+ }
+ spin_unlock_irqrestore(&amb_chan->lock, flags);
+
+ break;
+ case DMA_SLAVE_CONFIG:
+ /* We only support mem to dev or dev to mem transfers */
+ switch (config->direction) {
+ case DMA_MEM_TO_DEV:
+ width = config->dst_addr_width;
+ maxburst = config->dst_maxburst;
+ amb_chan->rt_addr = config->dst_addr;
+ amb_chan->rt_attr = DMA_DESC_RM | DMA_DESC_NI |
+ DMA_DESC_IE | DMA_DESC_ST;
+ break;
+ case DMA_DEV_TO_MEM:
+ width = config->src_addr_width;
+ maxburst = config->src_maxburst;
+ amb_chan->rt_addr = config->src_addr;
+ amb_chan->rt_attr = DMA_DESC_WM | DMA_DESC_NI |
+ DMA_DESC_IE | DMA_DESC_ST;
+ break;
+ default:
+ return -ENXIO;
+ }
+
+ /* bus width for descriptor mode control_info [ts fileds] */
+ switch (width) {
+ case DMA_SLAVE_BUSWIDTH_8_BYTES:
+ amb_chan->rt_attr |= DMA_DESC_TS_8B;
+ break;
+ case DMA_SLAVE_BUSWIDTH_4_BYTES:
+ amb_chan->rt_attr |= DMA_DESC_TS_4B;
+ break;
+ case DMA_SLAVE_BUSWIDTH_2_BYTES:
+ amb_chan->rt_attr |= DMA_DESC_TS_2B;
+ break;
+ case DMA_SLAVE_BUSWIDTH_1_BYTE:
+ amb_chan->rt_attr |= DMA_DESC_TS_1B;
+ break;
+ default:
+ break;
+ }
+
+ /* burst for descriptor mode control_info [blk fileds] */
+ switch (maxburst) {
+ case 1024:
+ amb_chan->rt_attr |= DMA_DESC_BLK_1024B;
+ break;
+ case 512:
+ amb_chan->rt_attr |= DMA_DESC_BLK_512B;
+ break;
+ case 256:
+ amb_chan->rt_attr |= DMA_DESC_BLK_256B;
+ break;
+ case 128:
+ amb_chan->rt_attr |= DMA_DESC_BLK_128B;
+ break;
+ case 64:
+ amb_chan->rt_attr |= DMA_DESC_BLK_64B;
+ break;
+ case 32:
+ amb_chan->rt_attr |= DMA_DESC_BLK_32B;
+ break;
+ case 16:
+ amb_chan->rt_attr |= DMA_DESC_BLK_16B;
+ break;
+ case 8:
+ amb_chan->rt_attr |= DMA_DESC_BLK_8B;
+ break;
+ default:
+ break;
+ }
+
+ break;
+ case DMA_PAUSE:
+ spin_lock_irqsave(&amb_chan->lock, flags);
+ ret = ambdma_pause_channel(amb_chan);
+ spin_unlock_irqrestore(&amb_chan->lock, flags);
+ break;
+ case DMA_RESUME:
+ spin_lock_irqsave(&amb_chan->lock, flags);
+ ret = ambdma_resume_channel(amb_chan);
+ spin_unlock_irqrestore(&amb_chan->lock, flags);
+ break;
+ default:
+ ret = -ENXIO;
+ }
+
+ return ret;
+}
+
+static struct dma_async_tx_descriptor *ambdma_prep_dma_cyclic(
+ struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
+ size_t period_len, enum dma_transfer_direction direction,
+ unsigned long flags, void *context)
+{
+ struct ambdma_chan *amb_chan = to_ambdma_chan(chan);
+ struct ambdma_device *amb_dma = amb_chan->amb_dma;
+ struct ambdma_desc *amb_desc, *first = NULL, *prev = NULL;
+ int left_len = buf_len;
+
+ if (buf_len == 0 || period_len == 0) {
+ pr_err("%s: buf/period length is zero!\n", __func__);
+ return NULL;
+ }
+
+ if (!IS_ALIGNED(buf_addr, 1<<(amb_dma->copy_align)) ||
+ !IS_ALIGNED(period_len, 1<<(amb_dma->copy_align))) {
+ pr_err("%s: buf_addr/period_len is not %dbytes aligned! (%d,%d)\n",
+ __func__, 1<<(amb_dma->copy_align), buf_addr, period_len);
+ return NULL;
+ }
+
+ do {
+ amb_desc = ambdma_get_desc(amb_chan);
+ if (!amb_desc)
+ goto dma_cyclic_err;
+
+ amb_desc->is_cyclic = 1;
+
+ if (period_len > left_len)
+ period_len = left_len;
+
+ if (direction == DMA_MEM_TO_DEV) {
+ amb_desc->lli->src = buf_addr;
+ amb_desc->lli->dst = amb_chan->rt_addr;
+ } else if (direction == DMA_DEV_TO_MEM) {
+ amb_desc->lli->src = amb_chan->rt_addr;
+ amb_desc->lli->dst = buf_addr;
+ } else {
+ goto dma_cyclic_err;
+ }
+ /* trigger interrupt after each dma transaction ends. */
+ amb_desc->lli->attr = amb_chan->rt_attr | DMA_DESC_ID;
+ amb_desc->lli->xfr_count = period_len;
+ /* rpt_addr points to amb_desc->lli->rpt */
+ amb_desc->lli->rpt_addr =
+ amb_desc->txd.phys + sizeof(struct ambdma_lli) - 4;
+ /* here we initialize rpt to 0 */
+ amb_desc->lli->rpt = 0;
+
+ if (first == NULL)
+ first = amb_desc;
+ else {
+ prev->lli->next_desc = amb_desc->txd.phys;
+ list_add_tail(&amb_desc->desc_node, &first->tx_list);
+ }
+
+ prev = amb_desc;
+
+ left_len -= period_len;
+ buf_addr += period_len;
+
+ /* our dma controller can't transfer data larger than 4M Bytes,
+ * but it seems that no use case will transfer so large data,
+ * so we just trigger a BUG here for reminder. */
+ BUG_ON(amb_desc->lli->xfr_count > AMBARELLA_DMA_MAX_LENGTH);
+ } while (left_len > 0);
+
+ /* lets make a cyclic list */
+ amb_desc->lli->next_desc = first->txd.phys;
+
+ /* First descriptor of the chain embedds additional information */
+ first->txd.cookie = -EBUSY;
+ first->len = buf_len;
+
+ return &first->txd;
+
+dma_cyclic_err:
+ dev_err(&chan->dev->device, "prep_dma_cyclic error: %p\n", amb_desc);
+ ambdma_put_desc(amb_chan, first);
+ return NULL;
+}
+
+
+static struct dma_async_tx_descriptor *ambdma_prep_slave_sg(
+ struct dma_chan *chan, struct scatterlist *sgl,
+ unsigned int sg_len, enum dma_transfer_direction direction,
+ unsigned long flags, void *context)
+{
+ struct ambdma_chan *amb_chan = to_ambdma_chan(chan);
+ struct ambdma_desc *amb_desc, *first = NULL, *prev = NULL;
+ struct scatterlist *sgent;
+ size_t total_len = 0;
+ unsigned i = 0;
+
+ if (sg_len == 0) {
+ pr_err("%s: sg length is zero!\n", __func__);
+ return NULL;
+ }
+
+ for_each_sg(sgl, sgent, sg_len, i) {
+ amb_desc = ambdma_get_desc(amb_chan);
+ if (!amb_desc)
+ goto slave_sg_err;
+
+ amb_desc->is_cyclic = 0;
+
+ if (direction == DMA_MEM_TO_DEV) {
+ amb_desc->lli->src = sg_dma_address(sgent);
+ amb_desc->lli->dst = amb_chan->rt_addr;
+ } else if (direction == DMA_DEV_TO_MEM) {
+ amb_desc->lli->src = amb_chan->rt_addr;
+ amb_desc->lli->dst = sg_dma_address(sgent);
+ } else {
+ goto slave_sg_err;
+ }
+ amb_desc->lli->attr = amb_chan->rt_attr;
+ amb_desc->lli->xfr_count = sg_dma_len(sgent);
+ /* rpt_addr points to amb_desc->lli->rpt */
+ amb_desc->lli->rpt_addr =
+ amb_desc->txd.phys + sizeof(struct ambdma_lli) - 4;
+ /* here we initialize rpt to 0 */
+ amb_desc->lli->rpt = 0;
+
+ if (first == NULL)
+ first = amb_desc;
+ else {
+ prev->lli->next_desc = amb_desc->txd.phys;
+ list_add_tail(&amb_desc->desc_node, &first->tx_list);
+ }
+
+ prev = amb_desc;
+ total_len += amb_desc->lli->xfr_count;
+
+ /* our dma controller can't transfer data larger than 4M Bytes,
+ * but it seems that no use case will transfer so large data,
+ * so we just trigger a BUG here for reminder. */
+ BUG_ON(amb_desc->lli->xfr_count > AMBARELLA_DMA_MAX_LENGTH);
+ }
+
+ /* set EOC flag to specify the last descriptor */
+ amb_desc->lli->attr |= DMA_DESC_EOC;
+
+ /* First descriptor of the chain embedds additional information */
+ first->txd.cookie = -EBUSY;
+ first->txd.flags = flags; /* client is in control of this ack */
+ first->len = total_len;
+
+ return &first->txd;
+
+slave_sg_err:
+ dev_err(&chan->dev->device, "prep_slave_sg error: %p\n", amb_desc);
+ ambdma_put_desc(amb_chan, first);
+ return NULL;
+}
+
+static struct dma_async_tx_descriptor *ambdma_prep_dma_memcpy(
+ struct dma_chan *chan, dma_addr_t dst, dma_addr_t src,
+ size_t len, unsigned long flags)
+{
+ struct ambdma_chan *amb_chan = to_ambdma_chan(chan);
+ struct ambdma_device *amb_dma = amb_chan->amb_dma;
+ struct ambdma_desc *amb_desc = NULL, *first = NULL, *prev = NULL;
+ size_t left_len = len, xfer_count;
+
+ if (unlikely(!len)) {
+ pr_info("%s: length is zero!\n", __func__);
+ return NULL;
+ }
+
+ if (!IS_ALIGNED(dst, 1<<(amb_dma->copy_align)) ||
+ !IS_ALIGNED(src, 1<<(amb_dma->copy_align))) {
+ pr_err("%s: dst/src is not %dbytes aligned! (%d,%d)\n",
+ __func__, 1<<(amb_dma->copy_align), dst, src);
+ return NULL;
+ }
+
+ do{
+ amb_desc = ambdma_get_desc(amb_chan);
+ if (!amb_desc)
+ goto dma_memcpy_err;
+
+ amb_desc->is_cyclic = 0;
+
+ amb_desc->lli->src = src;
+ amb_desc->lli->dst = dst;
+ amb_desc->lli->attr = DMA_DESC_RM | DMA_DESC_WM | DMA_DESC_IE |
+ DMA_DESC_ST | DMA_DESC_BLK_32B | DMA_DESC_TS_4B;
+ xfer_count = min(left_len, (size_t)AMBARELLA_DMA_MAX_LENGTH);
+ amb_desc->lli->xfr_count = xfer_count;
+ /* rpt_addr points to amb_desc->lli->rpt */
+ amb_desc->lli->rpt_addr =
+ amb_desc->txd.phys + sizeof(struct ambdma_lli) - 4;
+ /* here we initialize rpt to 0 */
+ amb_desc->lli->rpt = 0;
+
+ if (first == NULL)
+ first = amb_desc;
+ else {
+ prev->lli->next_desc = amb_desc->txd.phys;
+ list_add_tail(&amb_desc->desc_node, &first->tx_list);
+ }
+
+ prev = amb_desc;
+
+ src += xfer_count;
+ dst += xfer_count;
+ left_len -= xfer_count;
+
+ } while (left_len > 0);
+
+ /* set EOC flag to specify the last descriptor */
+ amb_desc->lli->attr |= DMA_DESC_EOC;
+
+ /* First descriptor of the chain embedds additional information */
+ first->txd.cookie = -EBUSY;
+ first->txd.flags = flags; /* client is in control of this ack */
+ first->len = len;
+
+ return &first->txd;
+
+dma_memcpy_err:
+ dev_err(&chan->dev->device, "prep_dma_memcpy error: %p\n", amb_desc);
+ ambdma_put_desc(amb_chan, first);
+
+ return NULL;
+}
+
+struct amba_dma_filter_param {
+ struct device_node *of_node;
+ unsigned int chan_id;
+ unsigned int dma_type;
+ //unsigned int force_stop;
+};
+
+static bool amba_dma_filter_fn(struct dma_chan *chan, void *fn_param)
+{
+ struct amba_dma_filter_param *param = fn_param;
+ //struct ambdma_chan *amb_chan = to_ambdma_chan(chan);
+ //struct ambdma_device *amb_dma = amb_chan->amb_dma;
+
+ if (chan->chan_id != param->chan_id)
+ return false;
+
+ //amb_chan->chan.private = &param->force_stop;
+ return true;
+}
+
+static struct dma_chan *amb_dma_xlate(struct of_phandle_args *dma_spec,
+ struct of_dma *ofdma)
+{
+ struct ambdma_device *amb_dma = ofdma->of_dma_data;
+ dma_cap_mask_t mask;
+ struct amba_dma_filter_param param;
+
+ if (dma_spec->args_count != 2)
+ return NULL;
+ if (dma_spec->args[1] == 1)
+ mask = amb_dma->dma_slave.cap_mask;
+ else
+ mask = amb_dma->dma_memcpy.cap_mask;
+
+ param.of_node = ofdma->of_node;
+ param.chan_id = dma_spec->args[0];
+
+ if (param.chan_id >= amb_dma->nr_channels)
+ return NULL;
+
+ return dma_request_channel(mask, amba_dma_filter_fn, &param);
+}
+
+static int ambarella_dma_probe(struct platform_device *pdev)
+{
+ struct ambdma_device *amb_dma;
+ struct ambdma_chan *amb_chan;
+ struct device_node *np = pdev->dev.of_node;
+ const char *prop_name = "dma-trans-type";
+ int val, i, ret = 0;
+
+ /* alloc the amba dma engine struct */
+ amb_dma = kzalloc(sizeof(*amb_dma), GFP_KERNEL);
+ if (amb_dma == NULL) {
+ ret = -ENOMEM;
+ goto ambdma_dma_probe_exit;
+ }
+
+ amb_dma->dma_irq = platform_get_irq(pdev, 0);
+ if (amb_dma->dma_irq < 0) {
+ ret = -EINVAL;
+ goto ambdma_dma_probe_exit1;
+ }
+
+ /* create a pool of consistent memory blocks for hardware descriptors */
+ amb_dma->lli_pool = dma_pool_create("ambdma_lli_pool",
+ &pdev->dev, sizeof(struct ambdma_lli), 16, 0);
+ if (!amb_dma->lli_pool) {
+ dev_err(&pdev->dev, "No memory for descriptors dma pool\n");
+ ret = -ENOMEM;
+ goto ambdma_dma_probe_exit1;
+ }
+
+ /* alloc dummy_lli and dummy_data for terminate usage. */
+ amb_dma->dummy_lli = dma_pool_alloc(amb_dma->lli_pool,
+ GFP_KERNEL, &amb_dma->dummy_lli_phys);
+ if (amb_dma->dummy_lli == NULL) {
+ ret = -ENOMEM;
+ goto ambdma_dma_probe_exit2;
+ }
+
+ amb_dma->dummy_data = dma_pool_alloc(amb_dma->lli_pool,
+ GFP_KERNEL, &amb_dma->dummy_data_phys);
+ if (amb_dma->dummy_data == NULL) {
+ ret = -ENOMEM;
+ goto ambdma_dma_probe_exit3;
+ }
+
+ amb_dma->dummy_lli->attr = DMA_DESC_EOC | DMA_DESC_WM |
+ DMA_DESC_NI | DMA_DESC_IE |
+ DMA_DESC_ST | DMA_DESC_ID;
+ amb_dma->dummy_lli->next_desc = amb_dma->dummy_lli_phys;
+ amb_dma->dummy_lli->xfr_count = 0;
+ amb_dma->dummy_lli->src = 0;
+ amb_dma->dummy_lli->dst = amb_dma->dummy_data_phys;
+ /* rpt_addr points to ambdma_lli->rpt field */
+ amb_dma->dummy_lli->rpt_addr =
+ amb_dma->dummy_lli_phys + sizeof(struct ambdma_lli) - 4;
+
+ of_property_read_u32(np, "amb,copy-align", &amb_dma->copy_align);
+ amb_dma->support_prs = !!of_find_property(np, "amb,support-prs", NULL);
+ ret = of_property_read_u32(np, "dma-channels", &amb_dma->nr_channels);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to read dma-channels\n");
+ return ret;
+ }
+ ret = of_property_read_u32(np, "dma-requests", &amb_dma->dma_requests);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to read dma-requests\n");
+ return ret;
+ }
+
+ ret = of_property_read_u32_array(np, prop_name, amb_dma->dma_channel_type, amb_dma->nr_channels);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to read dma-trans-type\n");
+ return ret;
+ }
+
+ /* Init dma_device struct */
+ dma_cap_zero(amb_dma->dma_slave.cap_mask);
+ dma_cap_set(DMA_PRIVATE, amb_dma->dma_slave.cap_mask);
+ dma_cap_set(DMA_SLAVE, amb_dma->dma_slave.cap_mask);
+ dma_cap_set(DMA_CYCLIC, amb_dma->dma_slave.cap_mask);
+ INIT_LIST_HEAD(&amb_dma->dma_slave.channels);
+ amb_dma->dma_slave.device_alloc_chan_resources = ambdma_alloc_chan_resources;
+ amb_dma->dma_slave.device_free_chan_resources = ambdma_free_chan_resources;
+ amb_dma->dma_slave.device_tx_status = ambdma_tx_status;
+ amb_dma->dma_slave.device_issue_pending = ambdma_issue_pending;
+ amb_dma->dma_slave.device_prep_dma_cyclic = ambdma_prep_dma_cyclic;
+ amb_dma->dma_slave.device_prep_slave_sg = ambdma_prep_slave_sg;
+ amb_dma->dma_slave.device_control = ambdma_device_control;
+ amb_dma->dma_slave.dev = &pdev->dev;
+
+ dma_cap_zero(amb_dma->dma_memcpy.cap_mask);
+ dma_cap_set(DMA_MEMCPY, amb_dma->dma_memcpy.cap_mask);
+ INIT_LIST_HEAD(&amb_dma->dma_memcpy.channels);
+ amb_dma->dma_memcpy.device_alloc_chan_resources = ambdma_alloc_chan_resources;
+ amb_dma->dma_memcpy.device_free_chan_resources = ambdma_free_chan_resources;
+ amb_dma->dma_memcpy.device_tx_status = ambdma_tx_status;
+ amb_dma->dma_memcpy.device_issue_pending = ambdma_issue_pending;
+ amb_dma->dma_memcpy.device_prep_dma_memcpy = ambdma_prep_dma_memcpy;
+ amb_dma->dma_memcpy.dev = &pdev->dev;
+ amb_dma->dma_memcpy.copy_align = (u8)(amb_dma->copy_align);
+
+ /* init dma_chan struct */
+ for (i = 0; i < NUM_DMA_CHANNELS; i++) {
+ amb_chan = &amb_dma->amb_chan[i];
+
+ spin_lock_init(&amb_chan->lock);
+ amb_chan->amb_dma = amb_dma;
+ amb_chan->id = i;
+ amb_chan->status = AMBDMA_STATUS_IDLE;
+ INIT_LIST_HEAD(&amb_chan->active_list);
+ INIT_LIST_HEAD(&amb_chan->queue);
+ INIT_LIST_HEAD(&amb_chan->free_list);
+ INIT_LIST_HEAD(&amb_chan->stopping_list);
+
+ tasklet_init(&amb_chan->tasklet, ambdma_tasklet,
+ (unsigned long)amb_chan);
+ dma_cookie_init(&amb_chan->chan);
+
+ if (amb_dma->dma_channel_type[i] != 0) {
+ amb_chan->chan.device = &amb_dma->dma_slave;
+ list_add_tail(&amb_chan->chan.device_node,
+ &amb_dma->dma_slave.channels);
+ } else {
+ amb_chan->chan.device = &amb_dma->dma_memcpy;
+ list_add_tail(&amb_chan->chan.device_node,
+ &amb_dma->dma_memcpy.channels);
+ }
+ }
+
+#if (DMA_SUPPORT_SELECT_CHANNEL == 1)
+ val = 0;
+ ret = of_property_read_u32_array(np, "dma-channel-sel",
+ amb_dma->dma_channel_sel, amb_dma->nr_channels);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to read dma-channel-sel\n");
+ }
+ for (i = 0; i < NUM_DMA_CHANNELS; i++) {
+ if (ret)
+ val |= i << (i * 4);
+ else
+ val |= (amb_dma->dma_channel_sel[i]) << (i * 4);
+ }
+ amba_writel(AHBSP_DMA_CHANNEL_SEL_REG, val);
+#endif
+
+ /* although FIOS DMA has its own driver, we also init FIOS DMA
+ * status here, orelse dummy FIOS DMA interrupts may occurred
+ * without its driver installed. */
+ for (i = 0; i < NUM_DMA_CHANNELS; i++) {
+ /* I2S_RX_DMA_CHAN and I2S_TX_DMA_CHAN may be used
+ * for fastboot in Amboot */
+ if ((i == I2S_RX_DMA_CHAN || i == I2S_TX_DMA_CHAN)
+ && ambdma_chan_is_enabled(&amb_dma->amb_chan[i])) {
+ amb_dma->amb_chan[i].status = AMBDMA_STATUS_BUSY;
+ amb_dma->amb_chan[i].force_stop = 1;
+ continue;
+ }
+
+ amba_writel(DMA_CHAN_STA_REG(i), 0);
+ val = DMA_CHANX_CTR_WM | DMA_CHANX_CTR_RM | DMA_CHANX_CTR_NI;
+ amba_writel(DMA_CHAN_CTR_REG(i), val);
+ }
+
+ ret = request_irq(amb_dma->dma_irq, ambdma_dma_irq_handler,
+ IRQF_SHARED | IRQF_TRIGGER_HIGH,
+ dev_name(&pdev->dev), amb_dma);
+ if (ret)
+ goto ambdma_dma_probe_exit4;
+
+ ret = dma_async_device_register(&amb_dma->dma_slave);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed to register slave DMA device: %d\n", ret);
+ goto ambdma_dma_probe_exit5;
+ }
+
+ ret = dma_async_device_register(&amb_dma->dma_memcpy);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed to register memcpy DMA device: %d\n", ret);
+ goto ambdma_dma_probe_exit6;
+ }
+
+ proc_create_data("dma", S_IRUGO|S_IWUSR,
+ get_ambarella_proc_dir(), &proc_ambdma_fops, amb_dma);
+
+ platform_set_drvdata(pdev, amb_dma);
+
+ if (np) {
+ ret = of_dma_controller_register(np, amb_dma_xlate, amb_dma);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed to register controller\n");
+ goto ambdma_dma_probe_exit6;
+ }
+ }
+
+ dev_info(&pdev->dev, "Ambarella DMA Engine \n");
+
+ return 0;
+
+ambdma_dma_probe_exit6:
+ dma_async_device_unregister(&amb_dma->dma_slave);
+
+ambdma_dma_probe_exit5:
+ free_irq(amb_dma->dma_irq, amb_dma);
+
+ambdma_dma_probe_exit4:
+ dma_pool_free(amb_dma->lli_pool, amb_dma->dummy_data,
+ amb_dma->dummy_data_phys);
+
+ambdma_dma_probe_exit3:
+ dma_pool_free(amb_dma->lli_pool, amb_dma->dummy_lli,
+ amb_dma->dummy_lli_phys);
+
+ambdma_dma_probe_exit2:
+ dma_pool_destroy(amb_dma->lli_pool);
+
+ambdma_dma_probe_exit1:
+ kfree(amb_dma);
+
+ambdma_dma_probe_exit:
+ return ret;
+}
+
+static int ambarella_dma_remove(struct platform_device *pdev)
+{
+ struct ambdma_device *amb_dma = platform_get_drvdata(pdev);
+ struct ambdma_chan *amb_chan;
+ int i;
+
+ for (i = 0; i < NUM_DMA_CHANNELS; i++) {
+ amb_chan = &amb_dma->amb_chan[i];
+ ambdma_stop_channel(amb_chan);
+
+ tasklet_disable(&amb_chan->tasklet);
+ tasklet_kill(&amb_chan->tasklet);
+ }
+
+ if (pdev->dev.of_node)
+ of_dma_controller_free(pdev->dev.of_node);
+
+ dma_async_device_unregister(&amb_dma->dma_memcpy);
+ dma_async_device_unregister(&amb_dma->dma_slave);
+
+ free_irq(amb_dma->dma_irq, amb_dma);
+ dma_pool_free(amb_dma->lli_pool, amb_dma->dummy_lli,
+ amb_dma->dummy_lli_phys);
+ dma_pool_free(amb_dma->lli_pool, amb_dma->dummy_data,
+ amb_dma->dummy_data_phys);
+ dma_pool_destroy(amb_dma->lli_pool);
+
+ kfree(amb_dma);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+#if (DMA_SUPPORT_SELECT_CHANNEL == 1)
+static u32 ambdma_chan_sel_val = 0;
+#endif
+static int ambarella_dma_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct ambdma_device *amb_dma = platform_get_drvdata(pdev);
+ struct ambdma_chan *amb_chan;
+ int i;
+
+ /* save dma channel register */
+ for (i = 0; i < NUM_DMA_CHANNELS; i++) {
+ amb_chan = &amb_dma->amb_chan[i];
+ amb_chan->ch_ctl = amba_readl(DMA_CHAN_CTR_REG(i));
+ amb_chan->ch_da = amba_readl(DMA_CHAN_DA_REG(i));
+ amb_chan->ch_sta = amba_readl(DMA_CHAN_STA_REG(i));
+ }
+#if (DMA_SUPPORT_SELECT_CHANNEL == 1)
+ ambdma_chan_sel_val = amba_readl(AHBSP_DMA_CHANNEL_SEL_REG);
+#endif
+ return 0;
+
+}
+
+static int ambarella_dma_resume(struct platform_device *pdev)
+{
+ struct ambdma_device *amb_dma = platform_get_drvdata(pdev);
+ struct ambdma_chan *amb_chan;
+ int i;
+
+#if (DMA_SUPPORT_SELECT_CHANNEL == 1)
+ amba_writel(AHBSP_DMA_CHANNEL_SEL_REG, ambdma_chan_sel_val);
+#endif
+ /* restore dma channel register */
+ for (i = 0; i < NUM_DMA_CHANNELS; i++) {
+ amb_chan = &amb_dma->amb_chan[i];
+ amba_writel(DMA_CHAN_STA_REG(i), amb_chan->ch_sta);
+ amba_writel(DMA_CHAN_DA_REG(i), amb_chan->ch_da);
+ amba_writel(DMA_CHAN_CTR_REG(i), amb_chan->ch_ctl);
+ }
+
+ return 0;
+}
+#endif
+
+
+static const struct of_device_id ambarella_dma_dt_ids[] = {
+ {.compatible = "ambarella,dma", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ambarella_dma_dt_ids);
+
+static struct platform_driver ambarella_dma_driver = {
+ .probe = ambarella_dma_probe,
+ .remove = ambarella_dma_remove,
+#ifdef CONFIG_PM
+ .suspend = ambarella_dma_suspend,
+ .resume = ambarella_dma_resume,
+#endif
+ .driver = {
+ .name = "ambarella-dma",
+ .owner = THIS_MODULE,
+ .of_match_table = ambarella_dma_dt_ids,
+ },
+};
+
+static int __init ambarella_dma_init(void)
+{
+ return platform_driver_register(&ambarella_dma_driver);
+}
+
+static void __exit ambarella_dma_exit(void)
+{
+ platform_driver_unregister(&ambarella_dma_driver);
+}
+
+subsys_initcall(ambarella_dma_init);
+module_exit(ambarella_dma_exit);
+
+MODULE_DESCRIPTION("Ambarella DMA Engine System Driver");
+MODULE_AUTHOR("Jian He <jianhe@ambarella.com>");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/dma/ambarella_dma.h b/drivers/dma/ambarella_dma.h
new file mode 100644
index 00000000..5c82ba39
--- /dev/null
+++ b/drivers/dma/ambarella_dma.h
@@ -0,0 +1,143 @@
+/*
+* linux/drivers/dma/ambarella_dma.h
+*
+* Header file for Ambarella DMA Controller driver
+*
+* History:
+* 2012/07/10 - [Cao Rongrong] created file
+*
+* Copyright (C) 2012 by Ambarella, Inc.
+* http://www.ambarella.com
+*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef _AMBARELLA_DMA_H
+#define _AMBARELLA_DMA_H
+
+#define NR_DESCS_PER_CHANNEL 64
+#define AMBARELLA_DMA_MAX_LENGTH ((1 << 22) - 1)
+
+enum ambdma_status {
+ AMBDMA_STATUS_IDLE = 0,
+ AMBDMA_STATUS_BUSY,
+ AMBDMA_STATUS_STOPPING,
+};
+
+/* lli == Linked List Item; aka DMA buffer descriptor, used by hardware */
+struct ambdma_lli {
+ dma_addr_t src;
+ dma_addr_t dst;
+ dma_addr_t next_desc;
+ dma_addr_t rpt_addr;
+ u32 xfr_count;
+ u32 attr;
+ u32 rsvd;
+ u32 rpt;
+};
+
+struct ambdma_desc {
+ struct ambdma_lli *lli;
+
+ struct dma_async_tx_descriptor txd;
+ struct list_head tx_list;
+ struct list_head desc_node;
+ size_t len;
+ bool is_cyclic;
+};
+
+struct ambdma_chan {
+ struct dma_chan chan;
+ struct ambdma_device *amb_dma;
+ int id;
+
+ struct tasklet_struct tasklet;
+ spinlock_t lock;
+
+ u32 descs_allocated;
+ struct list_head active_list;
+ struct list_head queue;
+ struct list_head free_list;
+ struct list_head stopping_list;
+
+ dma_addr_t rt_addr;
+ u32 rt_attr;
+ u32 force_stop;
+ u32 ch_ctl;
+ u32 ch_sta;
+ u32 ch_da;
+ enum ambdma_status status;
+};
+
+struct ambdma_device {
+ struct dma_device dma_slave;
+ struct dma_device dma_memcpy;
+ struct ambdma_chan amb_chan[NUM_DMA_CHANNELS];
+ struct dma_pool *lli_pool;
+ int dma_irq;
+ /* dummy_desc is used to stop DMA immediately. */
+ struct ambdma_lli *dummy_lli;
+ dma_addr_t dummy_lli_phys;
+ u32 *dummy_data;
+ dma_addr_t dummy_data_phys;
+ u32 copy_align;
+ /* support pause/resume/stop */
+ u32 support_prs : 1;
+ u32 nr_channels;
+ u32 dma_requests;
+ u32 dma_channel_type[NUM_DMA_CHANNELS];
+ u32 dma_channel_sel[NUM_DMA_CHANNELS];
+};
+
+
+static inline struct ambdma_desc *to_ambdma_desc(
+ struct dma_async_tx_descriptor *txd)
+{
+ return container_of(txd, struct ambdma_desc, txd);
+}
+
+static inline struct ambdma_desc *ambdma_first_active(
+ struct ambdma_chan *amb_chan)
+{
+ return list_first_entry(&amb_chan->active_list,
+ struct ambdma_desc, desc_node);
+}
+
+static inline struct ambdma_desc *ambdma_first_stopping(
+ struct ambdma_chan *amb_chan)
+{
+ return list_first_entry(&amb_chan->stopping_list,
+ struct ambdma_desc, desc_node);
+}
+
+static inline struct ambdma_chan *to_ambdma_chan(struct dma_chan *chan)
+{
+ return container_of(chan, struct ambdma_chan, chan);
+}
+
+static inline int ambdma_desc_is_error(struct ambdma_desc *amb_desc)
+{
+ return (amb_desc->lli->rpt & (DMA_CHANX_STA_OE | DMA_CHANX_STA_ME |
+ DMA_CHANX_STA_BE | DMA_CHANX_STA_RWE |
+ DMA_CHANX_STA_AE)) != 0x0;
+}
+
+static inline int ambdma_desc_transfer_count(struct ambdma_desc *amb_desc)
+{
+ return amb_desc->lli->rpt & AMBARELLA_DMA_MAX_LENGTH;
+}
+
+static inline int ambdma_chan_is_enabled(struct ambdma_chan *amb_chan)
+{
+ return !!(amba_readl(DMA_CHAN_CTR_REG(amb_chan->id)) & DMA_CHANX_CTR_EN);
+}
+
+static dma_cookie_t ambdma_tx_submit(struct dma_async_tx_descriptor *tx);
+static void ambdma_dostart(struct ambdma_chan *amb_chan,
+ struct ambdma_desc *first);
+
+#endif
+
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 0cb2d656..211e979f 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o
obj-$(CONFIG_GPIO_ADNP) += gpio-adnp.o
obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o
obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o
+obj-$(CONFIG_ARCH_AMBARELLA) += gpio-ambarella.o
obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8111.o
obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o
obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o
diff --git a/drivers/gpio/gpio-ambarella.c b/drivers/gpio/gpio-ambarella.c
new file mode 100644
index 00000000..997226ac
--- /dev/null
+++ b/drivers/gpio/gpio-ambarella.c
@@ -0,0 +1,646 @@
+/*
+ * drivers/pinctrl/ambarella/pinctrl-amb.c
+ *
+ * History:
+ * 2013/12/18 - [Cao Rongrong] created file
+ *
+ * Copyright (C) 2012-2016, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/syscore_ops.h>
+#include <linux/irqdomain.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/irqchip/chained_irq.h>
+#include <plat/iav_helper.h>
+#include <plat/pinctrl.h>
+
+#if defined(CONFIG_PM)
+struct amb_gpio_regs {
+ u32 irq_wake_mask;
+ u32 data;
+ u32 dir;
+ u32 is;
+ u32 ibe;
+ u32 iev;
+ u32 ie;
+ u32 afsel;
+ u32 mask;
+};
+
+struct amb_gpio_regs amb_gpio_pm[GPIO_INSTANCES];
+#endif
+
+struct amb_gpio_chip {
+ int irq[GPIO_INSTANCES];
+ void __iomem *regbase[GPIO_INSTANCES];
+ void __iomem *iomux_base;
+ struct gpio_chip *gc;
+ struct irq_domain *domain;
+ struct ambarella_service gpio_service;
+};
+
+static int ambarella_gpio_service(void *arg, void *result);
+
+/* gpiolib gpio_request callback function */
+static int amb_gpio_request(struct gpio_chip *gc, unsigned pin)
+{
+ return pinctrl_request_gpio(gc->base + pin);
+}
+
+/* gpiolib gpio_set callback function */
+static void amb_gpio_free(struct gpio_chip *gc, unsigned pin)
+{
+ pinctrl_free_gpio(gc->base + pin);
+}
+
+/* gpiolib gpio_free callback function */
+static void amb_gpio_set(struct gpio_chip *gc, unsigned pin, int value)
+{
+ struct amb_gpio_chip *amb_gpio = dev_get_drvdata(gc->dev);
+ void __iomem *regbase;
+ u32 bank, offset, mask;
+
+ bank = PINID_TO_BANK(pin);
+ offset = PINID_TO_OFFSET(pin);
+ regbase = amb_gpio->regbase[bank];
+ mask = (0x1 << offset);
+
+ amba_writel(regbase + GPIO_MASK_OFFSET, mask);
+ if (value == GPIO_LOW)
+ mask = 0;
+ amba_writel(regbase + GPIO_DATA_OFFSET, mask);
+}
+
+/* gpiolib gpio_get callback function */
+static int amb_gpio_get(struct gpio_chip *gc, unsigned pin)
+{
+ struct amb_gpio_chip *amb_gpio = dev_get_drvdata(gc->dev);
+ void __iomem *regbase;
+ u32 bank, offset, mask, data;
+
+ bank = PINID_TO_BANK(pin);
+ offset = PINID_TO_OFFSET(pin);
+ regbase = amb_gpio->regbase[bank];
+ mask = (0x1 << offset);
+
+ amba_writel(regbase + GPIO_MASK_OFFSET, mask);
+ data = amba_readl(regbase + GPIO_DATA_OFFSET);
+ data = (data >> offset) & 0x1;
+
+ return (data ? GPIO_HIGH : GPIO_LOW);
+}
+
+/* gpiolib gpio_direction_input callback function */
+static int amb_gpio_direction_input(struct gpio_chip *gc, unsigned pin)
+{
+ return pinctrl_gpio_direction_input(gc->base + pin);
+}
+
+/* gpiolib gpio_direction_output callback function */
+static int amb_gpio_direction_output(struct gpio_chip *gc,
+ unsigned pin, int value)
+{
+ int rval;
+
+ rval = pinctrl_gpio_direction_output(gc->base + pin);
+ if (rval < 0)
+ return rval;
+
+ amb_gpio_set(gc, pin, value);
+
+ return 0;
+}
+
+/* gpiolib gpio_to_irq callback function */
+static int amb_gpio_to_irq(struct gpio_chip *gc, unsigned pin)
+{
+ struct amb_gpio_chip *amb_gpio = dev_get_drvdata(gc->dev);
+
+ return irq_create_mapping(amb_gpio->domain, pin);
+}
+
+static void amb_gpio_dbg_show(struct seq_file *s, struct gpio_chip *gc)
+{
+ struct amb_gpio_chip *amb_gpio = dev_get_drvdata(gc->dev);
+ void __iomem *iomux_base = amb_gpio->iomux_base;
+ void __iomem *regbase;
+ u32 afsel = 0, data = 0, dir = 0, mask = 0;
+ u32 iomux0 = 0, iomux1 = 0, iomux2 = 0, alt = 0;
+ u32 i, bank, offset;
+
+ for (i = 0; i < gc->ngpio; i++) {
+ offset = PINID_TO_OFFSET(i);
+ if (offset == 0) {
+ bank = PINID_TO_BANK(i);
+ regbase = amb_gpio->regbase[bank];
+
+ afsel = amba_readl(regbase + GPIO_AFSEL_OFFSET);
+ dir = amba_readl(regbase + GPIO_DIR_OFFSET);
+ mask = amba_readl(regbase + GPIO_MASK_OFFSET);
+ amba_writel(regbase + GPIO_MASK_OFFSET, ~afsel);
+ data = amba_readl(regbase + GPIO_DATA_OFFSET);
+ amba_writel(regbase + GPIO_MASK_OFFSET, mask);
+
+ seq_printf(s, "\nGPIO[%d]:\t[%d - %d]\n",
+ bank, i, i + GPIO_BANK_SIZE - 1);
+ seq_printf(s, "GPIO_BASE:\t0x%08X\n", (u32)regbase);
+ seq_printf(s, "GPIO_AFSEL:\t0x%08X\n", afsel);
+ seq_printf(s, "GPIO_DIR:\t0x%08X\n", dir);
+ seq_printf(s, "GPIO_MASK:\t0x%08X:0x%08X\n", mask, ~afsel);
+ seq_printf(s, "GPIO_DATA:\t0x%08X\n", data);
+
+ if (iomux_base != NULL) {
+ iomux0 = amba_readl(iomux_base + bank * 12);
+ iomux1 = amba_readl(iomux_base + bank * 12 + 4);
+ iomux2 = amba_readl(iomux_base + bank * 12 + 8);
+ seq_printf(s, "IOMUX_REG%d_0:\t0x%08X\n", bank, iomux0);
+ seq_printf(s, "IOMUX_REG%d_1:\t0x%08X\n", bank, iomux1);
+ seq_printf(s, "IOMUX_REG%d_2:\t0x%08X\n", bank, iomux2);
+ }
+ }
+
+ seq_printf(s, " gpio-%-3d", gc->base + i);
+ if (iomux_base != NULL) {
+ alt = ((iomux2 >> offset) & 1) << 2;
+ alt |= ((iomux1 >> offset) & 1) << 1;
+ alt |= ((iomux0 >> offset) & 1) << 0;
+ if (alt != 0)
+ seq_printf(s, " [HW ] (alt%d)\n", alt);
+ else {
+ const char *label = gpiochip_is_requested(gc, i);
+ label = label ? : "";
+ seq_printf(s, " [GPIO] (%-20.20s) %s %s\n", label,
+ (dir & (1 << offset)) ? "out" : "in ",
+ (data & (1 << offset)) ? "hi" : "lo");
+ }
+ } else {
+ if (afsel & (1 << offset)) {
+ seq_printf(s, " [HW ]\n");
+ } else {
+ const char *label = gpiochip_is_requested(gc, i);
+ label = label ? : "";
+ seq_printf(s, " [GPIO] (%-20.20s) %s %s\n", label,
+ (dir & (1 << offset)) ? "out" : "in ",
+ (data & (1 << offset)) ? "hi" : "lo");
+ }
+ }
+ }
+}
+
+static struct gpio_chip amb_gc = {
+ .label = "ambarella-gpio",
+ .base = 0,
+ .ngpio = AMBGPIO_SIZE,
+ .request = amb_gpio_request,
+ .free = amb_gpio_free,
+ .direction_input = amb_gpio_direction_input,
+ .direction_output = amb_gpio_direction_output,
+ .get = amb_gpio_get,
+ .set = amb_gpio_set,
+ .to_irq = amb_gpio_to_irq,
+ .dbg_show = amb_gpio_dbg_show,
+ .owner = THIS_MODULE,
+};
+
+static void amb_gpio_irq_enable(struct irq_data *data)
+{
+ struct amb_gpio_chip *amb_gpio = dev_get_drvdata(amb_gc.dev);
+ void __iomem *regbase = irq_data_get_irq_chip_data(data);
+ void __iomem *iomux_base = amb_gpio->iomux_base;
+ u32 i, bank, offset, val;
+
+ bank = PINID_TO_BANK(data->hwirq);
+ offset = PINID_TO_OFFSET(data->hwirq);
+
+ /* make sure the pin is in gpio input mode */
+ if (!gpiochip_is_requested(&amb_gc, data->hwirq)) {
+ amba_clrbitsl(regbase + GPIO_AFSEL_OFFSET, 0x1 << offset);
+ amba_clrbitsl(regbase + GPIO_DIR_OFFSET, 0x1 << offset);
+
+ if (iomux_base) {
+ for (i = 0; i < 3; i++) {
+ val = amba_readl(iomux_base + IOMUX_REG_OFFSET(bank, i));
+ val &= (~(0x1 << offset));
+ amba_writel(iomux_base + IOMUX_REG_OFFSET(bank, i), val);
+ }
+ amba_writel(iomux_base + IOMUX_CTRL_SET_OFFSET, 0x1);
+ amba_writel(iomux_base + IOMUX_CTRL_SET_OFFSET, 0x0);
+ }
+ }
+
+ amba_writel(regbase + GPIO_IC_OFFSET, 0x1 << offset);
+ amba_setbitsl(regbase + GPIO_IE_OFFSET, 0x1 << offset);
+}
+
+static void amb_gpio_irq_disable(struct irq_data *data)
+{
+ void __iomem *regbase = irq_data_get_irq_chip_data(data);
+ u32 offset = PINID_TO_OFFSET(data->hwirq);
+
+ amba_clrbitsl(regbase + GPIO_IE_OFFSET, 0x1 << offset);
+ amba_writel(regbase + GPIO_IC_OFFSET, 0x1 << offset);
+}
+
+static void amb_gpio_irq_ack(struct irq_data *data)
+{
+ void __iomem *regbase = irq_data_get_irq_chip_data(data);
+ u32 offset = PINID_TO_OFFSET(data->hwirq);
+
+ amba_writel(regbase + GPIO_IC_OFFSET, 0x1 << offset);
+}
+
+static void amb_gpio_irq_mask(struct irq_data *data)
+{
+ void __iomem *regbase = irq_data_get_irq_chip_data(data);
+ u32 offset = PINID_TO_OFFSET(data->hwirq);
+
+ amba_clrbitsl(regbase + GPIO_IE_OFFSET, 0x1 << offset);
+}
+
+static void amb_gpio_irq_mask_ack(struct irq_data *data)
+{
+ void __iomem *regbase = irq_data_get_irq_chip_data(data);
+ u32 offset = PINID_TO_OFFSET(data->hwirq);
+
+ amba_clrbitsl(regbase + GPIO_IE_OFFSET, 0x1 << offset);
+ amba_writel(regbase + GPIO_IC_OFFSET, 0x1 << offset);
+}
+
+static void amb_gpio_irq_unmask(struct irq_data *data)
+{
+ void __iomem *regbase = irq_data_get_irq_chip_data(data);
+ u32 offset = PINID_TO_OFFSET(data->hwirq);
+
+ amba_setbitsl(regbase + GPIO_IE_OFFSET, 0x1 << offset);
+}
+
+static int amb_gpio_irq_set_type(struct irq_data *data, unsigned int type)
+{
+ void __iomem *regbase = irq_data_get_irq_chip_data(data);
+ struct irq_desc *desc = irq_to_desc(data->irq);
+ u32 offset = PINID_TO_OFFSET(data->hwirq);
+ u32 mask, bit, sense, bothedges, event;
+
+ mask = ~(0x1 << offset);
+ bit = (0x1 << offset);
+ sense = amba_readl(regbase + GPIO_IS_OFFSET);
+ bothedges = amba_readl(regbase + GPIO_IBE_OFFSET);
+ event = amba_readl(regbase + GPIO_IEV_OFFSET);
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ sense &= mask;
+ bothedges &= mask;
+ event |= bit;
+ desc->handle_irq = handle_edge_irq;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ sense &= mask;
+ bothedges &= mask;
+ event &= mask;
+ desc->handle_irq = handle_edge_irq;
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ sense &= mask;
+ bothedges |= bit;
+ event &= mask;
+ desc->handle_irq = handle_edge_irq;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ sense |= bit;
+ bothedges &= mask;
+ event |= bit;
+ desc->handle_irq = handle_level_irq;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ sense |= bit;
+ bothedges &= mask;
+ event &= mask;
+ desc->handle_irq = handle_level_irq;
+ break;
+ default:
+ pr_err("%s: irq[%d] type[%d] fail!\n",
+ __func__, data->irq, type);
+ return -EINVAL;
+ }
+
+ amba_writel(regbase + GPIO_IS_OFFSET, sense);
+ amba_writel(regbase + GPIO_IBE_OFFSET, bothedges);
+ amba_writel(regbase + GPIO_IEV_OFFSET, event);
+ /* clear obsolete irq */
+ amba_writel(regbase + GPIO_IC_OFFSET, 0x1 << offset);
+
+ return 0;
+}
+
+static int amb_gpio_irq_set_wake(struct irq_data *data, unsigned int on)
+{
+#if defined(CONFIG_PM)
+ u32 bank = PINID_TO_BANK(data->hwirq);
+ u32 offset = PINID_TO_OFFSET(data->hwirq);
+
+ if (on) {
+ amb_gpio_pm[bank].irq_wake_mask |= (1 << offset);
+ } else {
+ amb_gpio_pm[bank].irq_wake_mask &= ~(1 << offset);
+ }
+#endif
+ return 0;
+}
+
+static struct irq_chip amb_gpio_irqchip = {
+ .name = "GPIO",
+ .irq_enable = amb_gpio_irq_enable,
+ .irq_disable = amb_gpio_irq_disable,
+ .irq_ack = amb_gpio_irq_ack,
+ .irq_mask = amb_gpio_irq_mask,
+ .irq_mask_ack = amb_gpio_irq_mask_ack,
+ .irq_unmask = amb_gpio_irq_unmask,
+ .irq_set_type = amb_gpio_irq_set_type,
+ .irq_set_wake = amb_gpio_irq_set_wake,
+ .flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_MASK_ON_SUSPEND,
+};
+
+static int amb_gpio_irqdomain_map(struct irq_domain *d,
+ unsigned int irq, irq_hw_number_t hwirq)
+{
+ struct amb_gpio_chip *amb_gpio;
+
+ amb_gpio = (struct amb_gpio_chip *)d->host_data;
+
+ irq_set_chip_and_handler(irq, &amb_gpio_irqchip, handle_level_irq);
+ irq_set_chip_data(irq, amb_gpio->regbase[PINID_TO_BANK(hwirq)]);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+
+ return 0;
+}
+
+const struct irq_domain_ops amb_gpio_irq_domain_ops = {
+ .map = amb_gpio_irqdomain_map,
+ .xlate = irq_domain_xlate_twocell,
+};
+
+static void amb_gpio_handle_irq(unsigned int irq, struct irq_desc *desc)
+{
+ struct irq_chip *irqchip;
+ struct amb_gpio_chip *amb_gpio;
+ u32 i, gpio_mis, gpio_hwirq, gpio_irq;
+
+ irqchip = irq_desc_get_chip(desc);
+ chained_irq_enter(irqchip, desc);
+
+ amb_gpio = irq_get_handler_data(irq);
+
+ /* find the GPIO bank generating this irq */
+ for (i = 0; i < GPIO_INSTANCES; i++) {
+ if (amb_gpio->irq[i] == irq)
+ break;
+ }
+
+ if (i == GPIO_INSTANCES)
+ return;
+
+ gpio_mis = amba_readl(amb_gpio->regbase[i] + GPIO_MIS_OFFSET);
+ if (gpio_mis) {
+ gpio_hwirq = i * GPIO_BANK_SIZE + ffs(gpio_mis) - 1;
+ gpio_irq = irq_find_mapping(amb_gpio->domain, gpio_hwirq);
+ generic_handle_irq(gpio_irq);
+ }
+
+ chained_irq_exit(irqchip, desc);
+}
+
+static int amb_gpio_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *parent;
+ struct amb_gpio_chip *amb_gpio;
+ int i, rval;
+
+ amb_gpio = devm_kzalloc(&pdev->dev, sizeof(*amb_gpio), GFP_KERNEL);
+ if (!amb_gpio) {
+ dev_err(&pdev->dev, "failed to allocate memory for private data\n");
+ return -ENOMEM;
+ }
+
+ parent = of_get_parent(np);
+
+ for (i = 0; i < GPIO_INSTANCES; i++) {
+ amb_gpio->regbase[i] = of_iomap(parent, i);
+ if (amb_gpio->regbase[i] == NULL) {
+ dev_err(&pdev->dev, "devm_ioremap() failed\n");
+ return -ENOMEM;
+ }
+
+ amba_writel(amb_gpio->regbase[i] + GPIO_ENABLE_OFFSET, 0xffffffff);
+
+ amb_gpio->irq[i] = irq_of_parse_and_map(np, i);
+ if (amb_gpio->irq[i] == 0) {
+ dev_err(&pdev->dev, "no irq for gpio[%d]!\n", i);
+ return -ENXIO;
+ }
+ }
+
+ /* iomux_base will get NULL if not existed */
+ amb_gpio->iomux_base = of_iomap(parent, i);
+
+ of_node_put(parent);
+
+ amb_gpio->gc = &amb_gc;
+ amb_gpio->gc->dev = &pdev->dev;
+ rval = gpiochip_add(amb_gpio->gc);
+ if (rval) {
+ dev_err(&pdev->dev,
+ "failed to register gpio_chip %s\n", amb_gpio->gc->label);
+ return rval;
+ }
+
+ /* Initialize GPIO irq */
+ amb_gpio->domain = irq_domain_add_linear(np, amb_gpio->gc->ngpio,
+ &amb_gpio_irq_domain_ops, amb_gpio);
+ if (!amb_gpio->domain) {
+ pr_err("%s: Failed to create irqdomain\n", np->full_name);
+ return -ENOSYS;
+ }
+
+ for (i = 0; i < GPIO_INSTANCES; i++) {
+ irq_set_irq_type(amb_gpio->irq[i], IRQ_TYPE_LEVEL_HIGH);
+ irq_set_handler_data(amb_gpio->irq[i], amb_gpio);
+ irq_set_chained_handler(amb_gpio->irq[i], amb_gpio_handle_irq);
+ }
+
+ platform_set_drvdata(pdev, amb_gpio);
+
+ dev_info(&pdev->dev, "Ambarella GPIO driver registered\n");
+
+ /* register ambarella gpio service for private operation */
+ amb_gpio->gpio_service.service = AMBARELLA_SERVICE_GPIO;
+ amb_gpio->gpio_service.func = ambarella_gpio_service;
+ ambarella_register_service(&amb_gpio->gpio_service);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int amb_gpio_irq_suspend(void)
+{
+ struct amb_gpio_chip *amb_gpio;
+ struct amb_gpio_regs *pm;
+ void __iomem *regbase;
+ int i;
+
+ amb_gpio = dev_get_drvdata(amb_gc.dev);
+ if (amb_gpio == NULL) {
+ pr_err("No device for ambarella gpio irq\n");
+ return -ENODEV;
+ }
+
+ for (i = 0; i < GPIO_INSTANCES; i++) {
+ regbase = amb_gpio->regbase[i];
+ pm = &amb_gpio_pm[i];
+ pm->afsel = amba_readl(regbase + GPIO_AFSEL_OFFSET);
+ pm->dir = amba_readl(regbase + GPIO_DIR_OFFSET);
+ pm->is = amba_readl(regbase + GPIO_IS_OFFSET);
+ pm->ibe = amba_readl(regbase + GPIO_IBE_OFFSET);
+ pm->iev = amba_readl(regbase + GPIO_IEV_OFFSET);
+ pm->ie = amba_readl(regbase + GPIO_IE_OFFSET);
+ pm->mask = ~pm->afsel;
+ amba_writel(regbase + GPIO_MASK_OFFSET, pm->mask);
+ pm->data = amba_readl(regbase + GPIO_DATA_OFFSET);
+
+ if (pm->irq_wake_mask) {
+ amba_writel(regbase + GPIO_IE_OFFSET, pm->irq_wake_mask);
+ pr_info("gpio_irq[%p]: irq_wake[0x%08X]\n",
+ regbase, pm->irq_wake_mask);
+ }
+ }
+
+ return 0;
+}
+
+static void amb_gpio_irq_resume(void)
+{
+ struct amb_gpio_chip *amb_gpio;
+ struct amb_gpio_regs *pm;
+ void __iomem *regbase;
+ int i;
+
+ amb_gpio = dev_get_drvdata(amb_gc.dev);
+ if (amb_gpio == NULL) {
+ pr_err("No device for ambarella gpio irq\n");
+ return;
+ }
+
+ for (i = 0; i < GPIO_INSTANCES; i++) {
+ regbase = amb_gpio->regbase[i];
+ pm = &amb_gpio_pm[i];
+ amba_writel(regbase + GPIO_AFSEL_OFFSET, pm->afsel);
+ amba_writel(regbase + GPIO_DIR_OFFSET, pm->dir);
+ amba_writel(regbase + GPIO_MASK_OFFSET, pm->mask);
+ amba_writel(regbase + GPIO_DATA_OFFSET, pm->data);
+ amba_writel(regbase + GPIO_IS_OFFSET, pm->is);
+ amba_writel(regbase + GPIO_IBE_OFFSET, pm->ibe);
+ amba_writel(regbase + GPIO_IEV_OFFSET, pm->iev);
+ amba_writel(regbase + GPIO_IE_OFFSET, pm->ie);
+ amba_writel(regbase + GPIO_ENABLE_OFFSET, 0xffffffff);
+ }
+}
+
+struct syscore_ops amb_gpio_irq_syscore_ops = {
+ .suspend = amb_gpio_irq_suspend,
+ .resume = amb_gpio_irq_resume,
+};
+
+#endif
+
+static const struct of_device_id amb_gpio_dt_match[] = {
+ { .compatible = "ambarella,gpio" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, amb_gpio_dt_match);
+
+static struct platform_driver amb_gpio_driver = {
+ .probe = amb_gpio_probe,
+ .driver = {
+ .name = "ambarella-gpio",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(amb_gpio_dt_match),
+ },
+};
+
+static int __init amb_gpio_drv_register(void)
+{
+#ifdef CONFIG_PM
+ register_syscore_ops(&amb_gpio_irq_syscore_ops);
+#endif
+
+ return platform_driver_register(&amb_gpio_driver);
+}
+postcore_initcall(amb_gpio_drv_register);
+
+MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
+MODULE_DESCRIPTION("Ambarella SoC GPIO driver");
+MODULE_LICENSE("GPL v2");
+
+static int ambarella_gpio_service(void *arg, void *result)
+{
+ struct ambsvc_gpio *gpio_svc = arg;
+ u32 *value = result;
+ int rval = 0;
+
+ BUG_ON(!gpio_svc);
+
+ switch (gpio_svc->svc_id) {
+ case AMBSVC_GPIO_REQUEST:
+ {
+ rval = gpio_request(gpio_svc->gpio, "gpio");
+ break;
+ }
+ case AMBSVC_GPIO_OUTPUT:
+ rval = gpio_direction_output(gpio_svc->gpio, gpio_svc->value);
+ break;
+
+ case AMBSVC_GPIO_INPUT:
+ rval = gpio_direction_input(gpio_svc->gpio);
+ if (rval >= 0 && value)
+ *value = gpio_get_value_cansleep(gpio_svc->gpio);
+ break;
+
+ case AMBSVC_GPIO_FREE:
+ gpio_free(gpio_svc->gpio);
+ break;
+
+ case AMBSVC_GPIO_TO_IRQ:
+ *value = gpio_to_irq(gpio_svc->gpio);
+ break;
+
+ default:
+ pr_err("%s: Invalid gpio service (%d)\n", __func__, gpio_svc->svc_id);
+ rval = -EINVAL;
+ break;
+ }
+
+ return rval;
+}
+
diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c
index e8faf53f..365324f2 100644
--- a/drivers/gpio/gpio-pcf857x.c
+++ b/drivers/gpio/gpio-pcf857x.c
@@ -27,8 +27,10 @@
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <linux/workqueue.h>
static const struct i2c_device_id pcf857x_id[] = {
@@ -50,6 +52,27 @@ static const struct i2c_device_id pcf857x_id[] = {
};
MODULE_DEVICE_TABLE(i2c, pcf857x_id);
+#ifdef CONFIG_OF
+static const struct of_device_id pcf857x_of_table[] = {
+ { .compatible = "nxp,pcf8574" },
+ { .compatible = "nxp,pcf8574a" },
+ { .compatible = "nxp,pca8574" },
+ { .compatible = "nxp,pca9670" },
+ { .compatible = "nxp,pca9672" },
+ { .compatible = "nxp,pca9674" },
+ { .compatible = "nxp,pcf8575" },
+ { .compatible = "nxp,pca8575" },
+ { .compatible = "nxp,pca9671" },
+ { .compatible = "nxp,pca9673" },
+ { .compatible = "nxp,pca9675" },
+ { .compatible = "maxim,max7328" },
+ { .compatible = "maxim,max7329" },
+ { .compatible = "ti,tca9554" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, pcf857x_of_table);
+#endif
+
/*
* The pcf857x, pca857x, and pca967x chips only expose one read and one
* write register. Writing a "one" bit (to match the reset state) lets
@@ -66,12 +89,11 @@ struct pcf857x {
struct gpio_chip chip;
struct i2c_client *client;
struct mutex lock; /* protect 'out' */
- struct work_struct work; /* irq demux work */
struct irq_domain *irq_domain; /* for irq demux */
spinlock_t slock; /* protect irq demux */
unsigned out; /* software latch */
unsigned status; /* current status */
- int irq; /* real irq number */
+ unsigned irq_mapped; /* mapped gpio irqs */
int (*write)(struct i2c_client *client, unsigned data);
int (*read)(struct i2c_client *client);
@@ -164,48 +186,54 @@ static void pcf857x_set(struct gpio_chip *chip, unsigned offset, int value)
static int pcf857x_to_irq(struct gpio_chip *chip, unsigned offset)
{
struct pcf857x *gpio = container_of(chip, struct pcf857x, chip);
+ int ret;
+
+ ret = irq_create_mapping(gpio->irq_domain, offset);
+ if (ret > 0)
+ gpio->irq_mapped |= (1 << offset);
- return irq_create_mapping(gpio->irq_domain, offset);
+ return ret;
}
-static void pcf857x_irq_demux_work(struct work_struct *work)
+static irqreturn_t pcf857x_irq(int irq, void *data)
{
- struct pcf857x *gpio = container_of(work,
- struct pcf857x,
- work);
+ struct pcf857x *gpio = data;
unsigned long change, i, status, flags;
status = gpio->read(gpio->client);
spin_lock_irqsave(&gpio->slock, flags);
- change = gpio->status ^ status;
+ /*
+ * call the interrupt handler iff gpio is used as
+ * interrupt source, just to avoid bad irqs
+ */
+
+ change = ((gpio->status ^ status) & gpio->irq_mapped);
for_each_set_bit(i, &change, gpio->chip.ngpio)
generic_handle_irq(irq_find_mapping(gpio->irq_domain, i));
gpio->status = status;
spin_unlock_irqrestore(&gpio->slock, flags);
-}
-
-static irqreturn_t pcf857x_irq_demux(int irq, void *data)
-{
- struct pcf857x *gpio = data;
-
- /*
- * pcf857x can't read/write data here,
- * since i2c data access might go to sleep.
- */
- schedule_work(&gpio->work);
return IRQ_HANDLED;
}
-static int pcf857x_irq_domain_map(struct irq_domain *domain, unsigned int virq,
+static int pcf857x_irq_domain_map(struct irq_domain *domain, unsigned int irq,
irq_hw_number_t hw)
{
- irq_set_chip_and_handler(virq,
+ struct pcf857x *gpio = domain->host_data;
+
+ irq_set_chip_and_handler(irq,
&dummy_irq_chip,
handle_level_irq);
+#ifdef CONFIG_ARM
+ set_irq_flags(irq, IRQF_VALID);
+#else
+ irq_set_noprobe(irq);
+#endif
+ gpio->irq_mapped |= (1 << hw);
+
return 0;
}
@@ -218,12 +246,9 @@ static void pcf857x_irq_domain_cleanup(struct pcf857x *gpio)
if (gpio->irq_domain)
irq_domain_remove(gpio->irq_domain);
- if (gpio->irq)
- free_irq(gpio->irq, gpio);
}
static int pcf857x_irq_domain_init(struct pcf857x *gpio,
- struct pcf857x_platform_data *pdata,
struct i2c_client *client)
{
int status;
@@ -231,20 +256,21 @@ static int pcf857x_irq_domain_init(struct pcf857x *gpio,
gpio->irq_domain = irq_domain_add_linear(client->dev.of_node,
gpio->chip.ngpio,
&pcf857x_irq_domain_ops,
- NULL);
+ gpio);
if (!gpio->irq_domain)
goto fail;
/* enable real irq */
- status = request_irq(client->irq, pcf857x_irq_demux, 0,
- dev_name(&client->dev), gpio);
+ status = devm_request_threaded_irq(&client->dev, client->irq,
+ NULL, pcf857x_irq, IRQF_ONESHOT |
+ IRQF_TRIGGER_FALLING | IRQF_SHARED,
+ dev_name(&client->dev), gpio);
+
if (status)
goto fail;
/* enable gpio_to_irq() */
- INIT_WORK(&gpio->work, pcf857x_irq_demux_work);
gpio->chip.to_irq = pcf857x_to_irq;
- gpio->irq = client->irq;
return 0;
@@ -258,14 +284,18 @@ fail:
static int pcf857x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- struct pcf857x_platform_data *pdata;
+ struct pcf857x_platform_data *pdata = dev_get_platdata(&client->dev);
+ struct device_node *np = client->dev.of_node;
struct pcf857x *gpio;
+ unsigned int n_latch = 0;
int status;
- pdata = client->dev.platform_data;
- if (!pdata) {
+ if (IS_ENABLED(CONFIG_OF) && np)
+ of_property_read_u32(np, "lines-initial-states", &n_latch);
+ else if (pdata)
+ n_latch = pdata->n_latch;
+ else
dev_dbg(&client->dev, "no platform data\n");
- }
/* Allocate, initialize, and register this gpio_chip. */
gpio = devm_kzalloc(&client->dev, sizeof(*gpio), GFP_KERNEL);
@@ -286,11 +316,11 @@ static int pcf857x_probe(struct i2c_client *client,
gpio->chip.ngpio = id->driver_data;
/* enable gpio_to_irq() if platform has settings */
- if (pdata && client->irq) {
- status = pcf857x_irq_domain_init(gpio, pdata, client);
+ if (client->irq) {
+ status = pcf857x_irq_domain_init(gpio, client);
if (status < 0) {
dev_err(&client->dev, "irq_domain init failed\n");
- goto fail;
+ goto fail_irq_domain;
}
}
@@ -358,11 +388,11 @@ static int pcf857x_probe(struct i2c_client *client,
* may cause transient glitching since it can't know the last value
* written (some pins may need to be driven low).
*
- * Using pdata->n_latch avoids that trouble. When left initialized
- * to zero, our software copy of the "latch" then matches the chip's
- * all-ones reset state. Otherwise it flags pins to be driven low.
+ * Using n_latch avoids that trouble. When left initialized to zero,
+ * our software copy of the "latch" then matches the chip's all-ones
+ * reset state. Otherwise it flags pins to be driven low.
*/
- gpio->out = pdata ? ~pdata->n_latch : ~0;
+ gpio->out = ~n_latch;
gpio->status = gpio->out;
status = gpiochip_add(&gpio->chip);
@@ -385,12 +415,13 @@ static int pcf857x_probe(struct i2c_client *client,
return 0;
fail:
- dev_dbg(&client->dev, "probe error %d for '%s'\n",
- status, client->name);
-
- if (pdata && client->irq)
+ if (client->irq)
pcf857x_irq_domain_cleanup(gpio);
+fail_irq_domain:
+ dev_dbg(&client->dev, "probe error %d for '%s'\n",
+ status, client->name);
+
return status;
}
@@ -411,7 +442,7 @@ static int pcf857x_remove(struct i2c_client *client)
}
}
- if (pdata && client->irq)
+ if (client->irq)
pcf857x_irq_domain_cleanup(gpio);
status = gpiochip_remove(&gpio->chip);
@@ -424,6 +455,7 @@ static struct i2c_driver pcf857x_driver = {
.driver = {
.name = "pcf857x",
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(pcf857x_of_table),
},
.probe = pcf857x_probe,
.remove = pcf857x_remove,
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 33cb87f7..24c6c8b2 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -30,6 +30,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/kernel.h>
#include <linux/moduleparam.h>
#include "intel_drv.h"
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index f25f2983..471dd1ae 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1528,6 +1528,13 @@ config SENSORS_MC13783_ADC
help
Support for the A/D converter on MC13783 and MC13892 PMIC.
+config SENSORS_AMBARELLA_ADC_TEMPER
+ tristate "AMBARELLA ADC temper"
+ help
+ If you say yes here you get support for the hardware
+ monitoring functionality of the Ambarella ADC temperature
+ monitoring functionality.
+
if ACPI
comment "ACPI drivers"
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index d4fe13ee..0ef7d3a2 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -307,6 +307,18 @@ config I2C_POWERMAC
comment "I2C system bus drivers (mostly embedded / system-on-chip)"
+config I2C_AMBARELLA
+ tristate "Ambarella Media Soc I2C bus support"
+ depends on PLAT_AMBARELLA
+ select I2C_MUX if PLAT_AMBARELLA_SUPPORT_I2C_MUX
+ select I2C_MUX_AMBARELLA if PLAT_AMBARELLA_SUPPORT_I2C_MUX
+ help
+ This driver supports the Ambarella Media Soc
+ I2C Bus master controller
+
+ This driver can also be built as a module. If so, the module
+ will be called ambarella_i2c.
+
config I2C_AT91
tristate "Atmel AT91 I2C Two-Wire interface (TWI)"
depends on ARCH_AT91
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 8f4fc23b..57d318b2 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o
obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o
# Embedded system I2C/SMBus host controller drivers
+obj-$(CONFIG_I2C_AMBARELLA) += i2c-ambarella.o
obj-$(CONFIG_I2C_AT91) += i2c-at91.o
obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o
obj-$(CONFIG_I2C_BCM2835) += i2c-bcm2835.o
diff --git a/drivers/i2c/busses/i2c-ambarella.c b/drivers/i2c/busses/i2c-ambarella.c
new file mode 100644
index 00000000..fd1499e5
--- /dev/null
+++ b/drivers/i2c/busses/i2c-ambarella.c
@@ -0,0 +1,759 @@
+/*
+ * drivers/i2c/busses/ambarella_i2c.c
+ *
+ * Anthony Ginger, <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/of_i2c.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/semaphore.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/clk.h>
+#include <asm/dma.h>
+
+#include <mach/hardware.h>
+#include <plat/idc.h>
+#include <plat/event.h>
+
+#ifndef CONFIG_I2C_AMBARELLA_RETRIES
+#define CONFIG_I2C_AMBARELLA_RETRIES (3)
+#endif
+
+#ifndef CONFIG_I2C_AMBARELLA_ACK_TIMEOUT
+#define CONFIG_I2C_AMBARELLA_ACK_TIMEOUT (3 * HZ)
+#endif
+
+#define CONFIG_I2C_AMBARELLA_BULK_RETRY_NUM (4)
+
+/* must keep consistent with the name in device tree source, and the name
+ * of corresponding i2c client will be overwritten when it's in used. */
+#define AMBARELLA_I2C_VIN_FDT_NAME "ambvin"
+#define AMBARELLA_I2C_VIN_MAX_NUM 8
+
+enum ambarella_i2c_state {
+ AMBA_I2C_STATE_IDLE,
+ AMBA_I2C_STATE_START,
+ AMBA_I2C_STATE_START_TEN,
+ AMBA_I2C_STATE_START_NEW,
+ AMBA_I2C_STATE_READ,
+ AMBA_I2C_STATE_READ_STOP,
+ AMBA_I2C_STATE_WRITE,
+ AMBA_I2C_STATE_WRITE_WAIT_ACK,
+ AMBA_I2C_STATE_BULK_WRITE,
+ AMBA_I2C_STATE_NO_ACK,
+ AMBA_I2C_STATE_ERROR
+};
+
+struct ambarella_i2c_dev_info {
+ unsigned char __iomem *regbase;
+
+ struct device *dev;
+ unsigned int irq;
+ struct i2c_adapter adap;
+ enum ambarella_i2c_state state;
+
+ u32 clk_limit;
+ u32 bulk_num;
+ u32 duty_cycle;
+ u32 stretch_scl;
+ u32 turbo_mode;
+
+ struct i2c_msg *msgs;
+ __u16 msg_num;
+ __u16 msg_addr;
+ wait_queue_head_t msg_wait;
+ unsigned int msg_index;
+
+ struct notifier_block system_event;
+ struct semaphore system_event_sem;
+};
+
+int ambpriv_i2c_update_addr(const char *name, int bus, int addr)
+{
+ struct device_node *np;
+ struct i2c_adapter *adap;
+ struct i2c_client *client;
+ char buf[32];
+ int i;
+
+ adap = i2c_get_adapter(bus);
+ if (!adap) {
+ pr_err("No such i2c controller: %d\n", bus);
+ return -ENODEV;
+ }
+
+ for (i = 0; i < AMBARELLA_I2C_VIN_MAX_NUM; i++) {
+ snprintf(buf, 32, "%s%d", AMBARELLA_I2C_VIN_FDT_NAME, i);
+ np = of_get_child_by_name(adap->dev.of_node, buf);
+ if (!np) {
+ pr_err("ambpriv i2c: No FDT node named [%s]\n", buf);
+ return -ENODEV;
+ }
+
+ client = of_find_i2c_device_by_node(np);
+ if (!client) {
+ pr_err("failed to find i2c client\n");
+ return -ENODEV;
+ }
+
+ if (!strcmp(client->name, AMBARELLA_I2C_VIN_FDT_NAME) ||
+ !strcmp(client->name, name))
+ break;
+ }
+
+ if (i >= AMBARELLA_I2C_VIN_MAX_NUM) {
+ pr_err("fake vin sensor in device tree is not enough.\n");
+ return -ENODEV;
+ }
+
+ client->addr = addr;
+ strlcpy(client->name, name, I2C_NAME_SIZE);
+
+ return 0;
+}
+EXPORT_SYMBOL(ambpriv_i2c_update_addr);
+
+static inline void ambarella_i2c_set_clk(struct ambarella_i2c_dev_info *pinfo)
+{
+ unsigned int apb_clk;
+ __u32 idc_prescale;
+
+ apb_clk = clk_get_rate(clk_get(NULL, "gclk_apb"));
+
+ amba_writel(pinfo->regbase + IDC_ENR_OFFSET, IDC_ENR_REG_DISABLE);
+
+ idc_prescale =( ((apb_clk / pinfo->clk_limit) - 2)/(4 + pinfo->duty_cycle)) - 1;
+
+ dev_dbg(pinfo->dev, "apb_clk[%dHz]\n", apb_clk);
+ dev_dbg(pinfo->dev, "idc_prescale[%d]\n", idc_prescale);
+ dev_dbg(pinfo->dev, "duty_cycle[%d]\n", pinfo->duty_cycle);
+ dev_dbg(pinfo->dev, "clk[%dHz]\n",
+ (apb_clk / ((idc_prescale + 1) << 2)));
+
+ amba_writeb(pinfo->regbase + IDC_PSLL_OFFSET,
+ (idc_prescale & 0xff));
+ amba_writeb(pinfo->regbase + IDC_PSLH_OFFSET,
+ ((idc_prescale & 0xff00) >> 8));
+
+ amba_writeb(pinfo->regbase + IDC_DUTYCYCLE_OFFSET, pinfo->duty_cycle);
+ amba_writeb(pinfo->regbase + IDC_STRETCHSCL_OFFSET, pinfo->stretch_scl);
+
+ amba_writel(pinfo->regbase + IDC_ENR_OFFSET, IDC_ENR_REG_ENABLE);
+}
+
+static int ambarella_i2c_system_event(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ int errorCode = NOTIFY_OK;
+ struct platform_device *pdev;
+ struct ambarella_i2c_dev_info *pinfo;
+
+ pinfo = container_of(nb, struct ambarella_i2c_dev_info, system_event);
+ pdev = to_platform_device(pinfo->dev);
+
+ switch (val) {
+ case AMBA_EVENT_PRE_CPUFREQ:
+ pr_debug("%s[%d]: Pre Change\n", __func__, pdev->id);
+ down(&pinfo->system_event_sem);
+ break;
+
+ case AMBA_EVENT_POST_CPUFREQ:
+ pr_debug("%s[%d]: Post Change\n", __func__, pdev->id);
+ ambarella_i2c_set_clk(pinfo);
+ up(&pinfo->system_event_sem);
+ break;
+
+ default:
+ break;
+ }
+
+ return errorCode;
+}
+
+static inline void ambarella_i2c_hw_init(struct ambarella_i2c_dev_info *pinfo)
+{
+ ambarella_i2c_set_clk(pinfo);
+
+ pinfo->msgs = NULL;
+ pinfo->msg_num = 0;
+ pinfo->state = AMBA_I2C_STATE_IDLE;
+}
+
+static inline void ambarella_i2c_start_single_msg(
+ struct ambarella_i2c_dev_info *pinfo)
+{
+ if (pinfo->msgs->flags & I2C_M_TEN) {
+ pinfo->state = AMBA_I2C_STATE_START_TEN;
+ amba_writeb(pinfo->regbase + IDC_DATA_OFFSET,
+ (0xf0 | ((pinfo->msg_addr >> 8) & 0x07)));
+ } else {
+ pinfo->state = AMBA_I2C_STATE_START;
+ amba_writeb(pinfo->regbase + IDC_DATA_OFFSET,
+ (pinfo->msg_addr & 0xff));
+ }
+
+ amba_writel(pinfo->regbase + IDC_CTRL_OFFSET, IDC_CTRL_START);
+}
+
+static inline void ambarella_i2c_bulk_write(
+ struct ambarella_i2c_dev_info *pinfo,
+ __u32 fifosize)
+{
+ while (fifosize--) {
+ amba_writeb(pinfo->regbase + IDC_FMDATA_OFFSET,
+ pinfo->msgs->buf[pinfo->msg_index++]);
+ if (pinfo->msg_index >= pinfo->msgs->len)
+ break;
+ };
+
+ /* the last fifo data MUST be STOP+IF */
+ amba_writel(pinfo->regbase + IDC_FMCTRL_OFFSET,
+ IDC_FMCTRL_IF | IDC_FMCTRL_STOP);
+}
+
+static inline void ambarella_i2c_start_bulk_msg_write(
+ struct ambarella_i2c_dev_info *pinfo)
+{
+ __u32 fifosize = IDC_FIFO_BUF_SIZE;
+
+ pinfo->state = AMBA_I2C_STATE_BULK_WRITE;
+
+ amba_writel(pinfo->regbase + IDC_CTRL_OFFSET, 0);
+ amba_writel(pinfo->regbase + IDC_FMCTRL_OFFSET, IDC_FMCTRL_START);
+
+ if (pinfo->msgs->flags & I2C_M_TEN) {
+ amba_writeb(pinfo->regbase + IDC_FMDATA_OFFSET,
+ (0xf0 | ((pinfo->msg_addr >> 8) & 0x07)));
+ fifosize--;
+ }
+ amba_writeb(pinfo->regbase + IDC_FMDATA_OFFSET,
+ (pinfo->msg_addr & 0xff));
+ fifosize -= 2;
+
+ ambarella_i2c_bulk_write(pinfo, fifosize);
+}
+
+static inline void ambarella_i2c_start_current_msg(
+ struct ambarella_i2c_dev_info *pinfo)
+{
+ pinfo->msg_index = 0;
+ pinfo->msg_addr = (pinfo->msgs->addr << 1);
+
+ if (pinfo->msgs->flags & I2C_M_RD)
+ pinfo->msg_addr |= 1;
+
+ if (pinfo->msgs->flags & I2C_M_REV_DIR_ADDR)
+ pinfo->msg_addr ^= 1;
+
+ if (pinfo->msgs->flags & I2C_M_RD) {
+ ambarella_i2c_start_single_msg(pinfo);
+ } else if (pinfo->turbo_mode) {
+ ambarella_i2c_start_bulk_msg_write(pinfo);
+ } else {
+ ambarella_i2c_start_single_msg(pinfo);
+ }
+
+ dev_dbg(pinfo->dev, "msg_addr[0x%x], len[0x%x]",
+ pinfo->msg_addr, pinfo->msgs->len);
+}
+
+static inline void ambarella_i2c_stop(
+ struct ambarella_i2c_dev_info *pinfo,
+ enum ambarella_i2c_state state,
+ __u32 *pack_control)
+{
+ if(state != AMBA_I2C_STATE_IDLE) {
+ *pack_control |= IDC_CTRL_ACK;
+ }
+
+ pinfo->state = state;
+ pinfo->msgs = NULL;
+ pinfo->msg_num = 0;
+
+ *pack_control |= IDC_CTRL_STOP;
+
+ if(pinfo->state == AMBA_I2C_STATE_IDLE)
+ wake_up(&pinfo->msg_wait);
+}
+
+static inline __u32 ambarella_i2c_check_ack(
+ struct ambarella_i2c_dev_info *pinfo,
+ __u32 *pack_control,
+ __u32 retry_counter)
+{
+ __u32 retVal = IDC_CTRL_ACK;
+
+ambarella_i2c_check_ack_enter:
+ if (unlikely((*pack_control) & IDC_CTRL_ACK)) {
+ if (pinfo->msgs->flags & I2C_M_IGNORE_NAK)
+ goto ambarella_i2c_check_ack_exit;
+
+ if ((pinfo->msgs->flags & I2C_M_RD) &&
+ (pinfo->msgs->flags & I2C_M_NO_RD_ACK))
+ goto ambarella_i2c_check_ack_exit;
+
+ if (retry_counter--) {
+ udelay(100);
+ *pack_control = amba_readl(pinfo->regbase
+ + IDC_CTRL_OFFSET);
+ goto ambarella_i2c_check_ack_enter;
+ }
+ retVal = 0;
+ *pack_control = 0;
+ ambarella_i2c_stop(pinfo,
+ AMBA_I2C_STATE_NO_ACK, pack_control);
+ }
+
+ambarella_i2c_check_ack_exit:
+ return retVal;
+}
+
+static irqreturn_t ambarella_i2c_irq(int irqno, void *dev_id)
+{
+ struct ambarella_i2c_dev_info *pinfo;
+ __u32 status_reg;
+ __u32 control_reg;
+ __u32 ack_control = IDC_CTRL_CLS;
+
+ pinfo = (struct ambarella_i2c_dev_info *)dev_id;
+
+ status_reg = amba_readl(pinfo->regbase + IDC_STS_OFFSET);
+ control_reg = amba_readl(pinfo->regbase + IDC_CTRL_OFFSET);
+
+ dev_dbg(pinfo->dev, "state[0x%x]\n", pinfo->state);
+ dev_dbg(pinfo->dev, "status_reg[0x%x]\n", status_reg);
+ dev_dbg(pinfo->dev, "control_reg[0x%x]\n", control_reg);
+
+ switch (pinfo->state) {
+ case AMBA_I2C_STATE_START:
+ if (ambarella_i2c_check_ack(pinfo, &control_reg,
+ 1) == IDC_CTRL_ACK) {
+ if (pinfo->msgs->flags & I2C_M_RD) {
+ if (pinfo->msgs->len == 1)
+ ack_control |= IDC_CTRL_ACK;
+ pinfo->state = AMBA_I2C_STATE_READ;
+ } else {
+ pinfo->state = AMBA_I2C_STATE_WRITE;
+ goto amba_i2c_irq_write;
+ }
+ } else {
+ ack_control = control_reg;
+ }
+ break;
+ case AMBA_I2C_STATE_START_TEN:
+ pinfo->state = AMBA_I2C_STATE_START;
+ amba_writeb(pinfo->regbase + IDC_DATA_OFFSET,
+ (pinfo->msg_addr & 0xff));
+ break;
+ case AMBA_I2C_STATE_START_NEW:
+amba_i2c_irq_start_new:
+ ambarella_i2c_start_current_msg(pinfo);
+ goto amba_i2c_irq_exit;
+ break;
+ case AMBA_I2C_STATE_READ_STOP:
+ pinfo->msgs->buf[pinfo->msg_index] =
+ amba_readb(pinfo->regbase + IDC_DATA_OFFSET);
+ pinfo->msg_index++;
+amba_i2c_irq_read_stop:
+ ambarella_i2c_stop(pinfo, AMBA_I2C_STATE_IDLE, &ack_control);
+ break;
+ case AMBA_I2C_STATE_READ:
+ pinfo->msgs->buf[pinfo->msg_index] =
+ amba_readb(pinfo->regbase + IDC_DATA_OFFSET);
+ pinfo->msg_index++;
+
+ if (pinfo->msg_index >= pinfo->msgs->len - 1) {
+ if (pinfo->msg_num > 1) {
+ pinfo->msgs++;
+ pinfo->state = AMBA_I2C_STATE_START_NEW;
+ pinfo->msg_num--;
+ } else {
+ if (pinfo->msg_index > pinfo->msgs->len - 1) {
+ goto amba_i2c_irq_read_stop;
+ } else {
+ pinfo->state = AMBA_I2C_STATE_READ_STOP;
+ ack_control |= IDC_CTRL_ACK;
+ }
+ }
+ }
+ break;
+ case AMBA_I2C_STATE_WRITE:
+amba_i2c_irq_write:
+ pinfo->state = AMBA_I2C_STATE_WRITE_WAIT_ACK;
+ amba_writeb(pinfo->regbase + IDC_DATA_OFFSET,
+ pinfo->msgs->buf[pinfo->msg_index]);
+ break;
+ case AMBA_I2C_STATE_WRITE_WAIT_ACK:
+ if (ambarella_i2c_check_ack(pinfo, &control_reg,
+ 1) == IDC_CTRL_ACK) {
+ pinfo->state = AMBA_I2C_STATE_WRITE;
+ pinfo->msg_index++;
+
+ if (pinfo->msg_index >= pinfo->msgs->len) {
+ if (pinfo->msg_num > 1) {
+ pinfo->msgs++;
+ pinfo->state = AMBA_I2C_STATE_START_NEW;
+ pinfo->msg_num--;
+ goto amba_i2c_irq_start_new;
+ }
+ ambarella_i2c_stop(pinfo,
+ AMBA_I2C_STATE_IDLE, &ack_control);
+ } else {
+ goto amba_i2c_irq_write;
+ }
+ } else {
+ ack_control = control_reg;
+ }
+ break;
+ case AMBA_I2C_STATE_BULK_WRITE:
+ while (((status_reg & 0xF0) != 0x50) && ((status_reg & 0xF0) != 0x00)) {
+ cpu_relax();
+ status_reg = amba_readl(pinfo->regbase + IDC_STS_OFFSET);
+ };
+ if (pinfo->msg_num > 1) {
+ pinfo->msgs++;
+ pinfo->state = AMBA_I2C_STATE_START_NEW;
+ pinfo->msg_num--;
+ goto amba_i2c_irq_start_new;
+ }
+ ambarella_i2c_stop(pinfo, AMBA_I2C_STATE_IDLE, &ack_control);
+ goto amba_i2c_irq_exit;
+ default:
+ dev_err(pinfo->dev, "ambarella_i2c_irq in wrong state[0x%x]\n",
+ pinfo->state);
+ dev_err(pinfo->dev, "status_reg[0x%x]\n", status_reg);
+ dev_err(pinfo->dev, "control_reg[0x%x]\n", control_reg);
+ ack_control = IDC_CTRL_STOP | IDC_CTRL_ACK;
+ pinfo->state = AMBA_I2C_STATE_ERROR;
+ break;
+ }
+
+ amba_writel(pinfo->regbase + IDC_CTRL_OFFSET, ack_control);
+
+amba_i2c_irq_exit:
+ return IRQ_HANDLED;
+}
+
+static int ambarella_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+ int num)
+{
+ struct ambarella_i2c_dev_info *pinfo;
+ int errorCode = -EPERM;
+ int retryCount;
+ long timeout;
+ int i;
+
+ pinfo = (struct ambarella_i2c_dev_info *)i2c_get_adapdata(adap);
+
+ /* check data length for FIFO mode */
+ if (unlikely(pinfo->turbo_mode)) {
+ pinfo->msgs = msgs;
+ pinfo->msg_num = num;
+ for (i = 0 ; i < pinfo->msg_num; i++) {
+ if ((!(pinfo->msgs->flags & I2C_M_RD)) &&
+ (pinfo->msgs->len > IDC_FIFO_BUF_SIZE - 2)) {
+ dev_err(pinfo->dev,
+ "Turbo(FIFO) mode can only support <= "
+ "%d bytes writing, but message[%d]: %d bytes applied!\n",
+ IDC_FIFO_BUF_SIZE - 2, i, pinfo->msgs->len);
+
+ return -EPERM;
+ }
+ pinfo->msgs++;
+ }
+ }
+
+ down(&pinfo->system_event_sem);
+
+ for (retryCount = 0; retryCount < adap->retries; retryCount++) {
+ errorCode = 0;
+ if (pinfo->state != AMBA_I2C_STATE_IDLE)
+ ambarella_i2c_hw_init(pinfo);
+ pinfo->msgs = msgs;
+ pinfo->msg_num = num;
+
+ ambarella_i2c_start_current_msg(pinfo);
+ timeout = wait_event_timeout(pinfo->msg_wait,
+ pinfo->msg_num == 0, adap->timeout);
+ if (timeout <= 0) {
+ pinfo->state = AMBA_I2C_STATE_NO_ACK;
+ }
+ dev_dbg(pinfo->dev, "%ld jiffies left.\n", timeout);
+
+ if (pinfo->state != AMBA_I2C_STATE_IDLE) {
+ errorCode = -EBUSY;
+ } else {
+ break;
+ }
+ }
+
+ up(&pinfo->system_event_sem);
+
+ if (errorCode) {
+ if (pinfo->state == AMBA_I2C_STATE_NO_ACK) {
+ dev_err(pinfo->dev,
+ "No ACK from address 0x%x, %d:%d!\n",
+ pinfo->msg_addr, pinfo->msg_num,
+ pinfo->msg_index);
+ }
+ return errorCode;
+ }
+
+ return num;
+}
+
+static u32 ambarella_i2c_func(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm ambarella_i2c_algo = {
+ .master_xfer = ambarella_i2c_xfer,
+ .functionality = ambarella_i2c_func,
+};
+
+static int ambarella_i2c_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ int errorCode;
+ struct ambarella_i2c_dev_info *pinfo;
+ struct i2c_adapter *adap;
+ struct resource *mem;
+ u32 i2c_class = 0;
+
+ pinfo = devm_kzalloc(&pdev->dev, sizeof(*pinfo), GFP_KERNEL);
+ if (pinfo == NULL) {
+ dev_err(&pdev->dev, "Out of memory!\n");
+ return -ENOMEM;
+ }
+ pinfo->dev = &pdev->dev;
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (mem == NULL) {
+ dev_err(&pdev->dev, "Get I2C mem resource failed!\n");
+ return -ENXIO;
+ }
+
+ pinfo->regbase = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
+ if (!pinfo->regbase) {
+ dev_err(&pdev->dev, "devm_ioremap() failed\n");
+ return -ENOMEM;
+ }
+
+ pinfo->irq = platform_get_irq(pdev, 0);
+ if (pinfo->irq < 0) {
+ dev_err(&pdev->dev, "no irq for i2c%d!\n", pdev->id);
+ return -ENODEV;
+ }
+
+ errorCode = of_property_read_u32(np, "amb,i2c-class", &i2c_class);
+ if (errorCode < 0) {
+ dev_err(&pdev->dev, "Get i2c_class failed!\n");
+ return -ENODEV;
+ }
+
+ i2c_class &= (I2C_CLASS_HWMON | I2C_CLASS_DDC | I2C_CLASS_SPD);
+ if (i2c_class == 0){
+ dev_err(&pdev->dev, "Invalid i2c_class (0x%x)!\n", i2c_class);
+ return -EINVAL;
+ }
+
+ errorCode = of_property_read_u32(np, "clock-frequency", &pinfo->clk_limit);
+ if (errorCode < 0) {
+ dev_err(&pdev->dev, "Get clock-frequenc failed!\n");
+ return -ENODEV;
+ }
+
+ if (pinfo->clk_limit < 1000 || pinfo->clk_limit > 400000)
+ pinfo->clk_limit = 100000;
+
+ errorCode = of_property_read_u32(np, "amb,duty-cycle", &pinfo->duty_cycle);
+ if (errorCode < 0) {
+ dev_dbg(&pdev->dev, "Missing duty-cycle, assuming 1:1!\n");
+ pinfo->duty_cycle = 0;
+ }
+
+ if (pinfo->duty_cycle > 2)
+ pinfo->duty_cycle = 2;
+
+ errorCode = of_property_read_u32(np, "amb,stretch-scl", &pinfo->stretch_scl);
+ if (errorCode < 0) {
+ dev_dbg(&pdev->dev, "Missing stretch-scl, assuming 1!\n");
+ pinfo->stretch_scl = 1;
+ }
+
+ /* check if using turbo mode */
+ if (of_find_property(pdev->dev.of_node, "amb,turbo-mode", NULL)) {
+ pinfo->turbo_mode = 1;
+ dev_info(&pdev->dev,"Turbo(FIFO) mode is used(ignore device ACK)!\n");
+ } else {
+ pinfo->turbo_mode = 0;
+ }
+
+ init_waitqueue_head(&pinfo->msg_wait);
+ sema_init(&pinfo->system_event_sem, 1);
+
+ ambarella_i2c_hw_init(pinfo);
+
+ platform_set_drvdata(pdev, pinfo);
+
+ errorCode = devm_request_irq(&pdev->dev, pinfo->irq, ambarella_i2c_irq,
+ IRQF_TRIGGER_RISING, dev_name(&pdev->dev), pinfo);
+ if (errorCode) {
+ dev_err(&pdev->dev, "Request IRQ failed!\n");
+ return errorCode;
+ }
+
+ adap = &pinfo->adap;
+ i2c_set_adapdata(adap, pinfo);
+ adap->owner = THIS_MODULE;
+ adap->dev.parent = &pdev->dev;
+ adap->dev.of_node = np;
+ adap->class = i2c_class;
+ strlcpy(adap->name, pdev->name, sizeof(adap->name));
+ adap->algo = &ambarella_i2c_algo;
+ adap->nr = of_alias_get_id(np, "i2c");
+ adap->retries = CONFIG_I2C_AMBARELLA_RETRIES;
+
+ errorCode = i2c_add_numbered_adapter(adap);
+ if (errorCode) {
+ dev_err(&pdev->dev, "Adding I2C adapter failed!\n");
+ return errorCode;
+ }
+
+ of_i2c_register_devices(adap);
+
+ pinfo->system_event.notifier_call = ambarella_i2c_system_event;
+ ambarella_register_event_notifier(&pinfo->system_event);
+
+ dev_info(&pdev->dev, "Ambarella I2C adapter[%d] probed!\n", adap->nr);
+
+ return 0;
+}
+
+static int ambarella_i2c_remove(struct platform_device *pdev)
+{
+ struct ambarella_i2c_dev_info *pinfo;
+ int errorCode = 0;
+
+ pinfo = platform_get_drvdata(pdev);
+ if (pinfo) {
+ ambarella_unregister_event_notifier(&pinfo->system_event);
+ i2c_del_adapter(&pinfo->adap);
+ }
+
+ dev_notice(&pdev->dev,
+ "Remove Ambarella Media Processor I2C adapter[%s] [%d].\n",
+ dev_name(&pinfo->adap.dev), errorCode);
+
+ return errorCode;
+}
+
+#ifdef CONFIG_PM
+static int ambarella_i2c_suspend(struct device *dev)
+{
+ int errorCode = 0;
+ struct platform_device *pdev;
+ struct ambarella_i2c_dev_info *pinfo;
+
+ pdev = to_platform_device(dev);
+ pinfo = platform_get_drvdata(pdev);
+ if (pinfo) {
+ down(&pinfo->system_event_sem);
+ disable_irq(pinfo->irq);
+ }
+
+ dev_dbg(&pdev->dev, "%s\n", __func__);
+
+ return errorCode;
+}
+
+static int ambarella_i2c_resume(struct device *dev)
+{
+ int errorCode = 0;
+ struct platform_device *pdev;
+ struct ambarella_i2c_dev_info *pinfo;
+
+ pdev = to_platform_device(dev);
+ pinfo = platform_get_drvdata(pdev);
+ if (pinfo) {
+ ambarella_i2c_hw_init(pinfo);
+ enable_irq(pinfo->irq);
+ up(&pinfo->system_event_sem);
+ }
+
+ dev_dbg(&pdev->dev, "%s\n", __func__);
+
+ return errorCode;
+}
+
+static const struct dev_pm_ops ambarella_i2c_dev_pm_ops = {
+ .suspend_late = ambarella_i2c_suspend,
+ .resume_early = ambarella_i2c_resume,
+ .freeze = ambarella_i2c_suspend,
+ .thaw = ambarella_i2c_resume,
+};
+#endif
+
+static const struct of_device_id ambarella_i2c_of_match[] = {
+ {.compatible = "ambarella,i2c", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ambarella_i2c_of_match);
+
+static struct platform_driver ambarella_i2c_driver = {
+ .probe = ambarella_i2c_probe,
+ .remove = ambarella_i2c_remove,
+ .driver = {
+ .name = "ambarella-i2c",
+ .owner = THIS_MODULE,
+ .of_match_table = ambarella_i2c_of_match,
+#ifdef CONFIG_PM
+ .pm = &ambarella_i2c_dev_pm_ops,
+#endif
+ },
+};
+
+static int __init ambarella_i2c_init(void)
+{
+ return platform_driver_register(&ambarella_i2c_driver);
+}
+
+static void __exit ambarella_i2c_exit(void)
+{
+ platform_driver_unregister(&ambarella_i2c_driver);
+}
+
+subsys_initcall(ambarella_i2c_init);
+module_exit(ambarella_i2c_exit);
+
+MODULE_DESCRIPTION("Ambarella Media Processor I2C Bus Controller");
+MODULE_AUTHOR("Anthony Ginger, <hfjiang@ambarella.com>");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig
index 4f40a10c..6a4316e4 100644
--- a/drivers/iio/imu/Kconfig
+++ b/drivers/iio/imu/Kconfig
@@ -38,3 +38,4 @@ config IIO_ADIS_LIB_BUFFER
family.
source "drivers/iio/imu/inv_mpu6050/Kconfig"
+source "drivers/iio/imu/inv_mpu9250/Kconfig"
diff --git a/drivers/iio/imu/Makefile b/drivers/iio/imu/Makefile
index f2f56cea..8993e588 100644
--- a/drivers/iio/imu/Makefile
+++ b/drivers/iio/imu/Makefile
@@ -13,3 +13,4 @@ adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_buffer.o
obj-$(CONFIG_IIO_ADIS_LIB) += adis_lib.o
obj-y += inv_mpu6050/
+obj-y += inv_mpu9250/
diff --git a/drivers/iio/imu/inv_mpu9250/Kconfig b/drivers/iio/imu/inv_mpu9250/Kconfig
new file mode 100644
index 00000000..eef999c3
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu9250/Kconfig
@@ -0,0 +1,30 @@
+#
+# inv-mpu9250 drivers for Invensense MPU devices and combos
+#
+
+config INV_MPU9250_IIO
+ tristate
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+
+config INV_MPU9250_I2C
+ tristate "Invensense MPU9250 devices (I2C)"
+ depends on I2C_MUX
+ select INV_MPU9250_IIO
+ select REGMAP_I2C
+ help
+ This driver supports the Invensense MPU9250 motion tracking
+ devices over I2C.
+ This driver can be built as a module. The module will be called
+ inv-mpu9250-i2c.
+
+config INV_MPU9250_SPI
+ tristate "Invensense MPU9250 devices (SPI)"
+ depends on SPI_MASTER
+ select INV_MPU9250_IIO
+ select REGMAP_SPI
+ help
+ This driver supports the Invensense MPU9250 motion tracking
+ devices over SPI.
+ This driver can be built as a module. The module will be called
+ inv-mpu9250-spi.
diff --git a/drivers/iio/imu/inv_mpu9250/Makefile b/drivers/iio/imu/inv_mpu9250/Makefile
new file mode 100644
index 00000000..88aa5f70
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu9250/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for Invensense MPU9250 device.
+#
+
+obj-$(CONFIG_INV_MPU9250_IIO) += inv-mpu9250.o
+inv-mpu9250-objs := inv_mpu_core.o inv_mpu_ring.o inv_mpu_trigger.o
+
+obj-$(CONFIG_INV_MPU9250_I2C) += inv-mpu9250-i2c.o
+inv-mpu9250-i2c-objs := inv_mpu_i2c.o inv_mpu_acpi.o
+
+obj-$(CONFIG_INV_MPU9250_SPI) += inv-mpu9250-spi.o
+inv-mpu9250-spi-objs := inv_mpu_spi.o inv_mpu_i2cmst.o
\ No newline at end of file
diff --git a/drivers/iio/imu/inv_mpu9250/inv_mpu_acpi.c b/drivers/iio/imu/inv_mpu9250/inv_mpu_acpi.c
new file mode 100644
index 00000000..f62b8bd9
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu9250/inv_mpu_acpi.c
@@ -0,0 +1,213 @@
+/*
+ * inv_mpu_acpi: ACPI processing for creating client devices
+ * Copyright (c) 2015, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+
+#ifdef CONFIG_ACPI
+
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/dmi.h>
+#include <linux/acpi.h>
+#include "inv_mpu_iio.h"
+
+enum inv_mpu_product_name {
+ INV_MPU_NOT_MATCHED,
+ INV_MPU_ASUS_T100TA,
+};
+
+static enum inv_mpu_product_name matched_product_name;
+
+static int __init asus_t100_matched(const struct dmi_system_id *d)
+{
+ matched_product_name = INV_MPU_ASUS_T100TA;
+
+ return 0;
+}
+
+static const struct dmi_system_id inv_mpu_dev_list[] = {
+ {
+ .callback = asus_t100_matched,
+ .ident = "Asus Transformer Book T100",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "T100TA"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"),
+ },
+ },
+ /* Add more matching tables here..*/
+ {}
+};
+
+static int asus_acpi_get_sensor_info(struct acpi_device *adev,
+ struct i2c_client *client,
+ struct i2c_board_info *info)
+{
+ struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+ int i;
+ acpi_status status;
+ union acpi_object *cpm;
+
+ status = acpi_evaluate_object(adev->handle, "CNF0", NULL, &buffer);
+ if (ACPI_FAILURE(status))
+ return -ENODEV;
+
+ cpm = buffer.pointer;
+ for (i = 0; i < cpm->package.count; ++i) {
+ union acpi_object *elem;
+ int j;
+
+ elem = &cpm->package.elements[i];
+ for (j = 0; j < elem->package.count; ++j) {
+ union acpi_object *sub_elem;
+
+ sub_elem = &elem->package.elements[j];
+ if (sub_elem->type == ACPI_TYPE_STRING)
+ strlcpy(info->type, sub_elem->string.pointer,
+ sizeof(info->type));
+ else if (sub_elem->type == ACPI_TYPE_INTEGER) {
+ if (sub_elem->integer.value != client->addr) {
+ info->addr = sub_elem->integer.value;
+ break; /* Not a MPU6500 primary */
+ }
+ }
+ }
+ }
+
+ kfree(buffer.pointer);
+
+ return cpm->package.count;
+}
+
+static int acpi_i2c_check_resource(struct acpi_resource *ares, void *data)
+{
+ u32 *addr = data;
+
+ if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
+ struct acpi_resource_i2c_serialbus *sb;
+
+ sb = &ares->data.i2c_serial_bus;
+ if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_I2C) {
+ if (*addr)
+ *addr |= (sb->slave_address << 16);
+ else
+ *addr = sb->slave_address;
+ }
+ }
+
+ /* Tell the ACPI core that we already copied this address */
+ return 1;
+}
+
+static int inv_mpu_process_acpi_config(struct i2c_client *client,
+ unsigned short *primary_addr,
+ unsigned short *secondary_addr)
+{
+ const struct acpi_device_id *id;
+ struct acpi_device *adev;
+ u32 i2c_addr = 0;
+ LIST_HEAD(resources);
+ int ret;
+
+ id = acpi_match_device(client->dev.driver->acpi_match_table,
+ &client->dev);
+ if (!id)
+ return -ENODEV;
+
+ adev = ACPI_COMPANION(&client->dev);
+ if (!adev)
+ return -ENODEV;
+
+ ret = acpi_dev_get_resources(adev, &resources,
+ acpi_i2c_check_resource, &i2c_addr);
+ if (ret < 0)
+ return ret;
+
+ acpi_dev_free_resource_list(&resources);
+ *primary_addr = i2c_addr & 0x0000ffff;
+ *secondary_addr = (i2c_addr & 0xffff0000) >> 16;
+
+ return 0;
+}
+
+int inv_mpu_acpi_create_mux_client(struct i2c_client *client)
+{
+ struct inv_mpu6050_state *st = iio_priv(dev_get_drvdata(&client->dev));
+
+ st->mux_client = NULL;
+ if (ACPI_HANDLE(&client->dev)) {
+ struct i2c_board_info info;
+ struct acpi_device *adev;
+ int ret = -1;
+
+ adev = ACPI_COMPANION(&client->dev);
+ memset(&info, 0, sizeof(info));
+
+ dmi_check_system(inv_mpu_dev_list);
+ switch (matched_product_name) {
+ case INV_MPU_ASUS_T100TA:
+ ret = asus_acpi_get_sensor_info(adev, client,
+ &info);
+ break;
+ /* Add more matched product processing here */
+ default:
+ break;
+ }
+
+ if (ret < 0) {
+ /* No matching DMI, so create device on INV6XX type */
+ unsigned short primary, secondary;
+
+ ret = inv_mpu_process_acpi_config(client, &primary,
+ &secondary);
+ if (!ret && secondary) {
+ char *name;
+
+ info.addr = secondary;
+ strlcpy(info.type, dev_name(&adev->dev),
+ sizeof(info.type));
+ name = strchr(info.type, ':');
+ if (name)
+ *name = '\0';
+ strlcat(info.type, "-client",
+ sizeof(info.type));
+ } else
+ return 0; /* no secondary addr, which is OK */
+ }
+ st->mux_client = i2c_new_device(st->muxc->adapter[0], &info);
+ if (!st->mux_client)
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+void inv_mpu_acpi_delete_mux_client(struct i2c_client *client)
+{
+ struct inv_mpu6050_state *st = iio_priv(dev_get_drvdata(&client->dev));
+
+ if (st->mux_client)
+ i2c_unregister_device(st->mux_client);
+}
+#else
+
+#include "inv_mpu_iio.h"
+
+int inv_mpu_acpi_create_mux_client(struct i2c_client *client)
+{
+ return 0;
+}
+
+void inv_mpu_acpi_delete_mux_client(struct i2c_client *client)
+{
+}
+#endif
diff --git a/drivers/iio/imu/inv_mpu9250/inv_mpu_core.c b/drivers/iio/imu/inv_mpu9250/inv_mpu_core.c
new file mode 100644
index 00000000..a2c8afb6
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu9250/inv_mpu_core.c
@@ -0,0 +1,932 @@
+/*
+* Copyright (C) 2012 Invensense, Inc.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*/
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/sysfs.h>
+#include <linux/jiffies.h>
+#include <linux/irq.h>
+#include <linux/regmap.h>
+#include <linux/interrupt.h>
+#include <linux/kfifo.h>
+#include <linux/spinlock.h>
+#include <linux/iio/iio.h>
+#include <linux/acpi.h>
+#include "inv_mpu_iio.h"
+
+/*
+ * this is the gyro scale translated from dynamic range plus/minus
+ * {250, 500, 1000, 2000} to rad/s
+ */
+static const int gyro_scale_6050[] = {133090, 266181, 532362, 1064724};
+
+/*
+ * this is the accel scale translated from dynamic range plus/minus
+ * {2, 4, 8, 16} to m/s^2
+ */
+static const int accel_scale[] = {598, 1196, 2392, 4785};
+
+static const struct inv_mpu6050_reg_map reg_set_6500 = {
+ .sample_rate_div = INV_MPU6050_REG_SAMPLE_RATE_DIV,
+ .lpf = INV_MPU6050_REG_CONFIG,
+ .user_ctrl = INV_MPU6050_REG_USER_CTRL,
+ .fifo_en = INV_MPU6050_REG_FIFO_EN,
+ .gyro_config = INV_MPU6050_REG_GYRO_CONFIG,
+ .accl_config = INV_MPU6050_REG_ACCEL_CONFIG,
+ .fifo_count_h = INV_MPU6050_REG_FIFO_COUNT_H,
+ .fifo_r_w = INV_MPU6050_REG_FIFO_R_W,
+ .raw_gyro = INV_MPU6050_REG_RAW_GYRO,
+ .raw_accl = INV_MPU6050_REG_RAW_ACCEL,
+ .temperature = INV_MPU6050_REG_TEMPERATURE,
+ .int_enable = INV_MPU6050_REG_INT_ENABLE,
+ .pwr_mgmt_1 = INV_MPU6050_REG_PWR_MGMT_1,
+ .pwr_mgmt_2 = INV_MPU6050_REG_PWR_MGMT_2,
+ .int_pin_cfg = INV_MPU6050_REG_INT_PIN_CFG,
+ .accl_offset = INV_MPU6500_REG_ACCEL_OFFSET,
+ .gyro_offset = INV_MPU6050_REG_GYRO_OFFSET,
+};
+
+static const struct inv_mpu6050_reg_map reg_set_6050 = {
+ .sample_rate_div = INV_MPU6050_REG_SAMPLE_RATE_DIV,
+ .lpf = INV_MPU6050_REG_CONFIG,
+ .user_ctrl = INV_MPU6050_REG_USER_CTRL,
+ .fifo_en = INV_MPU6050_REG_FIFO_EN,
+ .gyro_config = INV_MPU6050_REG_GYRO_CONFIG,
+ .accl_config = INV_MPU6050_REG_ACCEL_CONFIG,
+ .fifo_count_h = INV_MPU6050_REG_FIFO_COUNT_H,
+ .fifo_r_w = INV_MPU6050_REG_FIFO_R_W,
+ .raw_gyro = INV_MPU6050_REG_RAW_GYRO,
+ .raw_accl = INV_MPU6050_REG_RAW_ACCEL,
+ .temperature = INV_MPU6050_REG_TEMPERATURE,
+ .int_enable = INV_MPU6050_REG_INT_ENABLE,
+ .pwr_mgmt_1 = INV_MPU6050_REG_PWR_MGMT_1,
+ .pwr_mgmt_2 = INV_MPU6050_REG_PWR_MGMT_2,
+ .int_pin_cfg = INV_MPU6050_REG_INT_PIN_CFG,
+ .accl_offset = INV_MPU6050_REG_ACCEL_OFFSET,
+ .gyro_offset = INV_MPU6050_REG_GYRO_OFFSET,
+};
+
+static const struct inv_mpu6050_chip_config chip_config_6050 = {
+ .fsr = INV_MPU6050_FSR_2000DPS,
+ .lpf = INV_MPU6050_FILTER_20HZ,
+ .fifo_rate = INV_MPU6050_INIT_FIFO_RATE,
+ .gyro_fifo_enable = false,
+ .accl_fifo_enable = false,
+ .accl_fs = INV_MPU6050_FS_02G,
+};
+
+/* Indexed by enum inv_devices */
+static const struct inv_mpu6050_hw hw_info[] = {
+ {
+ .whoami = INV_MPU6050_WHOAMI_VALUE,
+ .name = "MPU6050",
+ .reg = &reg_set_6050,
+ .config = &chip_config_6050,
+ },
+ {
+ .whoami = INV_MPU6500_WHOAMI_VALUE,
+ .name = "MPU6500",
+ .reg = &reg_set_6500,
+ .config = &chip_config_6050,
+ },
+ {
+ .whoami = INV_MPU6000_WHOAMI_VALUE,
+ .name = "MPU6000",
+ .reg = &reg_set_6050,
+ .config = &chip_config_6050,
+ },
+ {
+ .whoami = INV_MPU9150_WHOAMI_VALUE,
+ .name = "MPU9150",
+ .reg = &reg_set_6050,
+ .config = &chip_config_6050,
+ },
+ {
+ .whoami = INV_MPU9250_WHOAMI_VALUE,
+ .name = "MPU9250",
+ .reg = &reg_set_6500,
+ .config = &chip_config_6050,
+ },
+};
+
+int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask)
+{
+ unsigned int d, mgmt_1;
+ int result;
+ /*
+ * switch clock needs to be careful. Only when gyro is on, can
+ * clock source be switched to gyro. Otherwise, it must be set to
+ * internal clock
+ */
+ if (mask == INV_MPU6050_BIT_PWR_GYRO_STBY) {
+ result = regmap_read(st->map, st->reg->pwr_mgmt_1, &mgmt_1);
+ if (result)
+ return result;
+
+ mgmt_1 &= ~INV_MPU6050_BIT_CLK_MASK;
+ }
+
+ if ((mask == INV_MPU6050_BIT_PWR_GYRO_STBY) && (!en)) {
+ /*
+ * turning off gyro requires switch to internal clock first.
+ * Then turn off gyro engine
+ */
+ mgmt_1 |= INV_CLK_INTERNAL;
+ result = regmap_write(st->map, st->reg->pwr_mgmt_1, mgmt_1);
+ if (result)
+ return result;
+ }
+
+ result = regmap_read(st->map, st->reg->pwr_mgmt_2, &d);
+ if (result)
+ return result;
+ if (en)
+ d &= ~mask;
+ else
+ d |= mask;
+ result = regmap_write(st->map, st->reg->pwr_mgmt_2, d);
+ if (result)
+ return result;
+
+ if (en) {
+ /* Wait for output stabilize */
+ msleep(INV_MPU6050_TEMP_UP_TIME);
+ if (mask == INV_MPU6050_BIT_PWR_GYRO_STBY) {
+ /* switch internal clock to PLL */
+ mgmt_1 |= INV_CLK_PLL;
+ result = regmap_write(st->map,
+ st->reg->pwr_mgmt_1, mgmt_1);
+ if (result)
+ return result;
+ }
+ }
+
+ return 0;
+}
+
+int inv_mpu6050_set_power_itg(struct inv_mpu6050_state *st, bool power_on)
+{
+ int result = 0;
+
+ if (power_on) {
+ /* Already under indio-dev->mlock mutex */
+ if (!st->powerup_count)
+ result = regmap_write(st->map, st->reg->pwr_mgmt_1, 0);
+ if (!result)
+ st->powerup_count++;
+ } else {
+ st->powerup_count--;
+ if (!st->powerup_count)
+ result = regmap_write(st->map, st->reg->pwr_mgmt_1,
+ INV_MPU6050_BIT_SLEEP);
+ }
+
+ if (result)
+ return result;
+
+ if (power_on)
+ usleep_range(INV_MPU6050_REG_UP_TIME_MIN,
+ INV_MPU6050_REG_UP_TIME_MAX);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(inv_mpu6050_set_power_itg);
+
+/**
+ * inv_mpu6050_init_config() - Initialize hardware, disable FIFO.
+ *
+ * Initial configuration:
+ * FSR: ± 2000DPS
+ * DLPF: 20Hz
+ * FIFO rate: 50Hz
+ * Clock source: Gyro PLL
+ */
+static int inv_mpu6050_init_config(struct iio_dev *indio_dev)
+{
+ int result;
+ u8 d;
+ struct inv_mpu6050_state *st = iio_priv(indio_dev);
+
+ result = inv_mpu6050_set_power_itg(st, true);
+ if (result)
+ return result;
+ d = (INV_MPU6050_FSR_2000DPS << INV_MPU6050_GYRO_CONFIG_FSR_SHIFT);
+ result = regmap_write(st->map, st->reg->gyro_config, d);
+ if (result)
+ return result;
+
+ d = INV_MPU6050_FILTER_20HZ;
+ result = regmap_write(st->map, st->reg->lpf, d);
+ if (result)
+ return result;
+
+ d = INV_MPU6050_ONE_K_HZ / INV_MPU6050_INIT_FIFO_RATE - 1;
+ result = regmap_write(st->map, st->reg->sample_rate_div, d);
+ if (result)
+ return result;
+
+ d = (INV_MPU6050_FS_02G << INV_MPU6050_ACCL_CONFIG_FSR_SHIFT);
+ result = regmap_write(st->map, st->reg->accl_config, d);
+ if (result)
+ return result;
+
+ memcpy(&st->chip_config, hw_info[st->chip_type].config,
+ sizeof(struct inv_mpu6050_chip_config));
+ result = inv_mpu6050_set_power_itg(st, false);
+
+ return result;
+}
+
+static int inv_mpu6050_sensor_set(struct inv_mpu6050_state *st, int reg,
+ int axis, int val)
+{
+ int ind, result;
+ __be16 d = cpu_to_be16(val);
+
+ ind = (axis - IIO_MOD_X) * 2;
+ result = regmap_bulk_write(st->map, reg + ind, (u8 *)&d, 2);
+ if (result)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int inv_mpu6050_sensor_show(struct inv_mpu6050_state *st, int reg,
+ int axis, int *val)
+{
+ int ind, result;
+ __be16 d;
+
+ ind = (axis - IIO_MOD_X) * 2;
+ result = regmap_bulk_read(st->map, reg + ind, (u8 *)&d, 2);
+ if (result)
+ return -EINVAL;
+ *val = (short)be16_to_cpup(&d);
+
+ return IIO_VAL_INT;
+}
+
+static int
+inv_mpu6050_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct inv_mpu6050_state *st = iio_priv(indio_dev);
+ int ret = 0;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ {
+ int result;
+
+ ret = IIO_VAL_INT;
+ result = 0;
+ mutex_lock(&indio_dev->mlock);
+ if (!st->chip_config.enable) {
+ result = inv_mpu6050_set_power_itg(st, true);
+ if (result)
+ goto error_read_raw;
+ }
+ /* when enable is on, power is already on */
+ switch (chan->type) {
+ case IIO_ANGL_VEL:
+ if (!st->chip_config.gyro_fifo_enable ||
+ !st->chip_config.enable) {
+ result = inv_mpu6050_switch_engine(st, true,
+ INV_MPU6050_BIT_PWR_GYRO_STBY);
+ if (result)
+ goto error_read_raw;
+ }
+ ret = inv_mpu6050_sensor_show(st, st->reg->raw_gyro,
+ chan->channel2, val);
+ if (!st->chip_config.gyro_fifo_enable ||
+ !st->chip_config.enable) {
+ result = inv_mpu6050_switch_engine(st, false,
+ INV_MPU6050_BIT_PWR_GYRO_STBY);
+ if (result)
+ goto error_read_raw;
+ }
+ break;
+ case IIO_ACCEL:
+ if (!st->chip_config.accl_fifo_enable ||
+ !st->chip_config.enable) {
+ result = inv_mpu6050_switch_engine(st, true,
+ INV_MPU6050_BIT_PWR_ACCL_STBY);
+ if (result)
+ goto error_read_raw;
+ }
+ ret = inv_mpu6050_sensor_show(st, st->reg->raw_accl,
+ chan->channel2, val);
+ if (!st->chip_config.accl_fifo_enable ||
+ !st->chip_config.enable) {
+ result = inv_mpu6050_switch_engine(st, false,
+ INV_MPU6050_BIT_PWR_ACCL_STBY);
+ if (result)
+ goto error_read_raw;
+ }
+ break;
+ case IIO_TEMP:
+ if (!st->chip_config.enable) {
+ result = inv_mpu6050_switch_engine(st, true,
+ INV_MPU6050_BIT_PWR_TEMP_STBY);
+ if (result)
+ goto error_read_raw;
+ }
+ /* wait for stablization */
+ msleep(INV_MPU6050_SENSOR_UP_TIME);
+ ret = inv_mpu6050_sensor_show(st, st->reg->temperature,
+ IIO_MOD_X, val);
+ if (!st->chip_config.enable) {
+ result = inv_mpu6050_switch_engine(st, false,
+ INV_MPU6050_BIT_PWR_TEMP_STBY);
+ if (result)
+ goto error_read_raw;
+ }
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+error_read_raw:
+ if (!st->chip_config.enable)
+ result |= inv_mpu6050_set_power_itg(st, false);
+ mutex_unlock(&indio_dev->mlock);
+ if (result)
+ return result;
+
+ return ret;
+ }
+ case IIO_CHAN_INFO_SCALE:
+ switch (chan->type) {
+ case IIO_ANGL_VEL:
+ *val = 0;
+ *val2 = gyro_scale_6050[st->chip_config.fsr];
+
+ return IIO_VAL_INT_PLUS_NANO;
+ case IIO_ACCEL:
+ *val = 0;
+ *val2 = accel_scale[st->chip_config.accl_fs];
+
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_TEMP:
+ *val = 0;
+ *val2 = INV_MPU6050_TEMP_SCALE;
+
+ return IIO_VAL_INT_PLUS_MICRO;
+ default:
+ return -EINVAL;
+ }
+ case IIO_CHAN_INFO_OFFSET:
+ switch (chan->type) {
+ case IIO_TEMP:
+ *val = INV_MPU6050_TEMP_OFFSET;
+
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+ case IIO_CHAN_INFO_CALIBBIAS:
+ switch (chan->type) {
+ case IIO_ANGL_VEL:
+ ret = inv_mpu6050_sensor_show(st, st->reg->gyro_offset,
+ chan->channel2, val);
+ return IIO_VAL_INT;
+ case IIO_ACCEL:
+ ret = inv_mpu6050_sensor_show(st, st->reg->accl_offset,
+ chan->channel2, val);
+ return IIO_VAL_INT;
+
+ default:
+ return -EINVAL;
+ }
+ default:
+ return -EINVAL;
+ }
+}
+
+static int inv_mpu6050_write_gyro_scale(struct inv_mpu6050_state *st, int val)
+{
+ int result, i;
+ u8 d;
+
+ for (i = 0; i < ARRAY_SIZE(gyro_scale_6050); ++i) {
+ if (gyro_scale_6050[i] == val) {
+ d = (i << INV_MPU6050_GYRO_CONFIG_FSR_SHIFT);
+ result = regmap_write(st->map, st->reg->gyro_config, d);
+ if (result)
+ return result;
+
+ st->chip_config.fsr = i;
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int inv_write_raw_get_fmt(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, long mask)
+{
+ switch (mask) {
+ case IIO_CHAN_INFO_SCALE:
+ switch (chan->type) {
+ case IIO_ANGL_VEL:
+ return IIO_VAL_INT_PLUS_NANO;
+ default:
+ return IIO_VAL_INT_PLUS_MICRO;
+ }
+ default:
+ return IIO_VAL_INT_PLUS_MICRO;
+ }
+
+ return -EINVAL;
+}
+
+static int inv_mpu6050_write_accel_scale(struct inv_mpu6050_state *st, int val)
+{
+ int result, i;
+ u8 d;
+
+ for (i = 0; i < ARRAY_SIZE(accel_scale); ++i) {
+ if (accel_scale[i] == val) {
+ d = (i << INV_MPU6050_ACCL_CONFIG_FSR_SHIFT);
+ result = regmap_write(st->map, st->reg->accl_config, d);
+ if (result)
+ return result;
+
+ st->chip_config.accl_fs = i;
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int inv_mpu6050_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
+{
+ struct inv_mpu6050_state *st = iio_priv(indio_dev);
+ int result;
+
+ mutex_lock(&indio_dev->mlock);
+ /*
+ * we should only update scale when the chip is disabled, i.e.
+ * not running
+ */
+ if (st->chip_config.enable) {
+ result = -EBUSY;
+ goto error_write_raw;
+ }
+ result = inv_mpu6050_set_power_itg(st, true);
+ if (result)
+ goto error_write_raw;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SCALE:
+ switch (chan->type) {
+ case IIO_ANGL_VEL:
+ result = inv_mpu6050_write_gyro_scale(st, val2);
+ break;
+ case IIO_ACCEL:
+ result = inv_mpu6050_write_accel_scale(st, val2);
+ break;
+ default:
+ result = -EINVAL;
+ break;
+ }
+ break;
+ case IIO_CHAN_INFO_CALIBBIAS:
+ switch (chan->type) {
+ case IIO_ANGL_VEL:
+ result = inv_mpu6050_sensor_set(st,
+ st->reg->gyro_offset,
+ chan->channel2, val);
+ break;
+ case IIO_ACCEL:
+ result = inv_mpu6050_sensor_set(st,
+ st->reg->accl_offset,
+ chan->channel2, val);
+ break;
+ default:
+ result = -EINVAL;
+ }
+ default:
+ result = -EINVAL;
+ break;
+ }
+
+error_write_raw:
+ result |= inv_mpu6050_set_power_itg(st, false);
+ mutex_unlock(&indio_dev->mlock);
+
+ return result;
+}
+
+/**
+ * inv_mpu6050_set_lpf() - set low pass filer based on fifo rate.
+ *
+ * Based on the Nyquist principle, the sampling rate must
+ * exceed twice of the bandwidth of the signal, or there
+ * would be alising. This function basically search for the
+ * correct low pass parameters based on the fifo rate, e.g,
+ * sampling frequency.
+ */
+static int inv_mpu6050_set_lpf(struct inv_mpu6050_state *st, int rate)
+{
+ const int hz[] = {188, 98, 42, 20, 10, 5};
+ const int d[] = {INV_MPU6050_FILTER_188HZ, INV_MPU6050_FILTER_98HZ,
+ INV_MPU6050_FILTER_42HZ, INV_MPU6050_FILTER_20HZ,
+ INV_MPU6050_FILTER_10HZ, INV_MPU6050_FILTER_5HZ};
+ int i, h, result;
+ u8 data;
+
+ h = (rate >> 1);
+ i = 0;
+ while ((h < hz[i]) && (i < ARRAY_SIZE(d) - 1))
+ i++;
+ data = d[i];
+ result = regmap_write(st->map, st->reg->lpf, data);
+ if (result)
+ return result;
+ st->chip_config.lpf = data;
+
+ return 0;
+}
+
+/**
+ * inv_mpu6050_fifo_rate_store() - Set fifo rate.
+ */
+static ssize_t
+inv_mpu6050_fifo_rate_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ s32 fifo_rate;
+ u8 d;
+ int result;
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct inv_mpu6050_state *st = iio_priv(indio_dev);
+
+ if (kstrtoint(buf, 10, &fifo_rate))
+ return -EINVAL;
+ if (fifo_rate < INV_MPU6050_MIN_FIFO_RATE ||
+ fifo_rate > INV_MPU6050_MAX_FIFO_RATE)
+ return -EINVAL;
+ if (fifo_rate == st->chip_config.fifo_rate)
+ return count;
+
+ mutex_lock(&indio_dev->mlock);
+ if (st->chip_config.enable) {
+ result = -EBUSY;
+ goto fifo_rate_fail;
+ }
+ result = inv_mpu6050_set_power_itg(st, true);
+ if (result)
+ goto fifo_rate_fail;
+
+ d = INV_MPU6050_ONE_K_HZ / fifo_rate - 1;
+ result = regmap_write(st->map, st->reg->sample_rate_div, d);
+ if (result)
+ goto fifo_rate_fail;
+ st->chip_config.fifo_rate = fifo_rate;
+
+ result = inv_mpu6050_set_lpf(st, fifo_rate);
+ if (result)
+ goto fifo_rate_fail;
+
+fifo_rate_fail:
+ result |= inv_mpu6050_set_power_itg(st, false);
+ mutex_unlock(&indio_dev->mlock);
+ if (result)
+ return result;
+
+ return count;
+}
+
+/**
+ * inv_fifo_rate_show() - Get the current sampling rate.
+ */
+static ssize_t
+inv_fifo_rate_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct inv_mpu6050_state *st = iio_priv(dev_to_iio_dev(dev));
+
+ return sprintf(buf, "%d\n", st->chip_config.fifo_rate);
+}
+
+/**
+ * inv_attr_show() - calling this function will show current
+ * parameters.
+ */
+static ssize_t inv_attr_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct inv_mpu6050_state *st = iio_priv(dev_to_iio_dev(dev));
+ struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+ const char **m;
+
+ switch (this_attr->address) {
+ /*
+ * In MPU6050, the two matrix are the same because gyro and accel
+ * are integrated in one chip
+ */
+ case ATTR_GYRO_MATRIX:
+ case ATTR_ACCL_MATRIX:
+ m = st->orientation.rotation;
+
+ return sprintf(buf, "%s, %s, %s; %s, %s, %s; %s, %s, %s\n",
+ m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8]);
+ default:
+ return -EINVAL;
+ }
+}
+
+/**
+ * inv_mpu6050_validate_trigger() - validate_trigger callback for invensense
+ * MPU6050 device.
+ * @indio_dev: The IIO device
+ * @trig: The new trigger
+ *
+ * Returns: 0 if the 'trig' matches the trigger registered by the MPU6050
+ * device, -EINVAL otherwise.
+ */
+static int inv_mpu6050_validate_trigger(struct iio_dev *indio_dev,
+ struct iio_trigger *trig)
+{
+ struct inv_mpu6050_state *st = iio_priv(indio_dev);
+
+ if (st->trig != trig)
+ return -EINVAL;
+
+ return 0;
+}
+
+#define INV_MPU6050_CHAN(_type, _channel2, _index) \
+ { \
+ .type = _type, \
+ .modified = 1, \
+ .channel2 = _channel2, \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_CALIBBIAS), \
+ .scan_index = _index, \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = 16, \
+ .storagebits = 16, \
+ .shift = 0, \
+ .endianness = IIO_BE, \
+ }, \
+ }
+
+static const struct iio_chan_spec inv_mpu_channels[] = {
+ IIO_CHAN_SOFT_TIMESTAMP(INV_MPU6050_SCAN_TIMESTAMP),
+ /*
+ * Note that temperature should only be via polled reading only,
+ * not the final scan elements output.
+ */
+ {
+ .type = IIO_TEMP,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW)
+ | BIT(IIO_CHAN_INFO_OFFSET)
+ | BIT(IIO_CHAN_INFO_SCALE),
+ .scan_index = -1,
+ },
+ INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_X, INV_MPU6050_SCAN_GYRO_X),
+ INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Y, INV_MPU6050_SCAN_GYRO_Y),
+ INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Z, INV_MPU6050_SCAN_GYRO_Z),
+
+ INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_X, INV_MPU6050_SCAN_ACCL_X),
+ INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Y, INV_MPU6050_SCAN_ACCL_Y),
+ INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_MPU6050_SCAN_ACCL_Z),
+};
+
+/* constant IIO attribute */
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("10 20 50 100 200 500");
+static IIO_CONST_ATTR(in_anglvel_scale_available,
+ "0.000133090 0.000266181 0.000532362 0.001064724");
+static IIO_CONST_ATTR(in_accel_scale_available,
+ "0.000598 0.001196 0.002392 0.004785");
+static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR, inv_fifo_rate_show,
+ inv_mpu6050_fifo_rate_store);
+
+/* Deprecated: kept for userspace backward compatibility. */
+static IIO_DEVICE_ATTR(in_gyro_matrix, S_IRUGO, inv_attr_show, NULL,
+ ATTR_GYRO_MATRIX);
+static IIO_DEVICE_ATTR(in_accel_matrix, S_IRUGO, inv_attr_show, NULL,
+ ATTR_ACCL_MATRIX);
+
+static struct attribute *inv_attributes[] = {
+ &iio_dev_attr_in_gyro_matrix.dev_attr.attr, /* deprecated */
+ &iio_dev_attr_in_accel_matrix.dev_attr.attr, /* deprecated */
+ &iio_dev_attr_sampling_frequency.dev_attr.attr,
+ &iio_const_attr_sampling_frequency_available.dev_attr.attr,
+ &iio_const_attr_in_accel_scale_available.dev_attr.attr,
+ &iio_const_attr_in_anglvel_scale_available.dev_attr.attr,
+ NULL,
+};
+
+static const struct attribute_group inv_attribute_group = {
+ .attrs = inv_attributes
+};
+
+static const struct iio_info mpu_info = {
+ .driver_module = THIS_MODULE,
+ .read_raw = &inv_mpu6050_read_raw,
+ .write_raw = &inv_mpu6050_write_raw,
+ .write_raw_get_fmt = &inv_write_raw_get_fmt,
+ .attrs = &inv_attribute_group,
+ .validate_trigger = inv_mpu6050_validate_trigger,
+};
+
+/**
+ * inv_check_and_setup_chip() - check and setup chip.
+ */
+static int inv_check_and_setup_chip(struct inv_mpu6050_state *st)
+{
+ int result;
+ unsigned int regval;
+
+ st->hw = &hw_info[st->chip_type];
+ st->reg = hw_info[st->chip_type].reg;
+
+ /* reset to make sure previous state are not there */
+ result = regmap_write(st->map, st->reg->pwr_mgmt_1,
+ INV_MPU6050_BIT_H_RESET);
+ if (result)
+ return result;
+ msleep(INV_MPU6050_POWER_UP_TIME);
+
+ /* check chip self-identification */
+ result = regmap_read(st->map, INV_MPU6050_REG_WHOAMI, &regval);
+ if (result)
+ return result;
+ if (regval != st->hw->whoami) {
+ dev_warn(st->dev,
+ "whoami mismatch got %#02x expected %#02hhx for %s\n",
+ regval, st->hw->whoami, st->hw->name);
+ }
+
+ /*
+ * toggle power state. After reset, the sleep bit could be on
+ * or off depending on the OTP settings. Toggling power would
+ * make it in a definite state as well as making the hardware
+ * state align with the software state
+ */
+ result = inv_mpu6050_set_power_itg(st, false);
+ if (result)
+ return result;
+ result = inv_mpu6050_set_power_itg(st, true);
+ if (result)
+ return result;
+
+ result = inv_mpu6050_switch_engine(st, false,
+ INV_MPU6050_BIT_PWR_ACCL_STBY);
+ if (result)
+ return result;
+ result = inv_mpu6050_switch_engine(st, false,
+ INV_MPU6050_BIT_PWR_GYRO_STBY);
+ if (result)
+ return result;
+
+ return 0;
+}
+
+int inv_mpu_core_probe(struct device *dev, struct regmap *regmap, int irq, const char *name,
+ int (*inv_mpu_bus_setup)(struct iio_dev *), int chip_type)
+{
+ struct inv_mpu6050_state *st;
+ struct iio_dev *indio_dev;
+ int result;
+
+ indio_dev = iio_device_alloc(sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ BUILD_BUG_ON(ARRAY_SIZE(hw_info) != INV_NUM_PARTS);
+ if (chip_type < 0 || chip_type >= INV_NUM_PARTS) {
+ dev_err(dev, "Bad invensense chip_type=%d name=%s\n",
+ chip_type, name);
+ return -ENODEV;
+ }
+ st = iio_priv(indio_dev);
+ st->chip_type = chip_type;
+ st->powerup_count = 0;
+ st->irq = irq;
+ st->map = regmap;
+ st->dev = dev;
+
+ result = of_property_read_string_array(dev->of_node,
+ "mount-matrix", st->orientation.rotation,
+ ARRAY_SIZE(st->orientation.rotation));
+
+ if (result != ARRAY_SIZE(st->orientation.rotation)) {
+ dev_err(dev, "Failed to retrieve mounting matrix %d\n", result);
+ return result;
+ }
+
+ /* power is turned on inside check chip type*/
+ result = inv_check_and_setup_chip(st);
+ if (result)
+ return result;
+
+ if (inv_mpu_bus_setup)
+ inv_mpu_bus_setup(indio_dev);
+
+ result = inv_mpu6050_init_config(indio_dev);
+ if (result) {
+ dev_err(dev, "Could not initialize device.\n");
+ return result;
+ }
+
+ dev_set_drvdata(dev, indio_dev);
+ indio_dev->dev.parent = dev;
+ /* name will be NULL when enumerated via ACPI */
+ if (name)
+ indio_dev->name = name;
+ else
+ indio_dev->name = dev_name(dev);
+ indio_dev->channels = inv_mpu_channels;
+ indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels);
+
+ indio_dev->info = &mpu_info;
+ indio_dev->modes = INDIO_BUFFER_TRIGGERED;
+
+ result = iio_triggered_buffer_setup(indio_dev,
+ inv_mpu6050_irq_handler,
+ inv_mpu6050_read_fifo,
+ NULL);
+ if (result) {
+ dev_err(dev, "configure buffer fail %d\n", result);
+ return result;
+ }
+ result = inv_mpu6050_probe_trigger(indio_dev);
+ if (result) {
+ dev_err(dev, "trigger probe fail %d\n", result);
+ goto out_unreg_ring;
+ }
+
+ INIT_KFIFO(st->timestamps);
+ spin_lock_init(&st->time_stamp_lock);
+ result = iio_device_register(indio_dev);
+ if (result) {
+ dev_err(dev, "IIO register fail %d\n", result);
+ goto out_remove_trigger;
+ }
+
+ return 0;
+
+out_remove_trigger:
+ inv_mpu6050_remove_trigger(st);
+out_unreg_ring:
+ iio_triggered_buffer_cleanup(indio_dev);
+ return result;
+}
+EXPORT_SYMBOL_GPL(inv_mpu_core_probe);
+
+int inv_mpu_core_remove(struct device *dev)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+
+ iio_device_unregister(indio_dev);
+ inv_mpu6050_remove_trigger(iio_priv(indio_dev));
+ iio_triggered_buffer_cleanup(indio_dev);
+ iio_device_free(indio_dev);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(inv_mpu_core_remove);
+
+#ifdef CONFIG_PM_SLEEP
+
+static int inv_mpu_resume(struct device *dev)
+{
+ return inv_mpu6050_set_power_itg(iio_priv(dev_get_drvdata(dev)), true);
+}
+
+static int inv_mpu_suspend(struct device *dev)
+{
+ return inv_mpu6050_set_power_itg(iio_priv(dev_get_drvdata(dev)), false);
+}
+#endif /* CONFIG_PM_SLEEP */
+
+SIMPLE_DEV_PM_OPS(inv_mpu_pmops, inv_mpu_suspend, inv_mpu_resume);
+EXPORT_SYMBOL_GPL(inv_mpu_pmops);
+
+MODULE_AUTHOR("Invensense Corporation");
+MODULE_DESCRIPTION("Invensense device MPU6050 driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/imu/inv_mpu9250/inv_mpu_i2c.c b/drivers/iio/imu/inv_mpu9250/inv_mpu_i2c.c
new file mode 100644
index 00000000..6b44d292
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu9250/inv_mpu_i2c.c
@@ -0,0 +1,201 @@
+/*
+* Copyright (C) 2012 Invensense, Inc.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*/
+
+#include <linux/acpi.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/iio/iio.h>
+#include <linux/module.h>
+#include "inv_mpu_iio.h"
+
+static const struct regmap_config inv_mpu_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+};
+
+static int inv_mpu6050_select_bypass(struct i2c_mux_core *muxc, u32 chan_id)
+{
+ struct iio_dev *indio_dev = i2c_mux_priv(muxc);
+ struct inv_mpu6050_state *st = iio_priv(indio_dev);
+ int ret = 0;
+
+ /* Use the same mutex which was used everywhere to protect power-op */
+ mutex_lock(&indio_dev->mlock);
+ if (!st->powerup_count) {
+ ret = regmap_write(st->map, st->reg->pwr_mgmt_1, 0);
+ if (ret)
+ goto write_error;
+
+ usleep_range(INV_MPU6050_REG_UP_TIME_MIN,
+ INV_MPU6050_REG_UP_TIME_MAX);
+ }
+ if (!ret) {
+ st->powerup_count++;
+ ret = regmap_write(st->map, st->reg->int_pin_cfg,
+ INV_MPU6050_INT_PIN_CFG |
+ INV_MPU6050_BIT_BYPASS_EN);
+ }
+write_error:
+ mutex_unlock(&indio_dev->mlock);
+
+ return ret;
+}
+
+static int inv_mpu6050_deselect_bypass(struct i2c_mux_core *muxc, u32 chan_id)
+{
+ struct iio_dev *indio_dev = i2c_mux_priv(muxc);
+ struct inv_mpu6050_state *st = iio_priv(indio_dev);
+
+ mutex_lock(&indio_dev->mlock);
+ /* It doesn't really mattter, if any of the calls fails */
+ regmap_write(st->map, st->reg->int_pin_cfg, INV_MPU6050_INT_PIN_CFG);
+ st->powerup_count--;
+ if (!st->powerup_count)
+ regmap_write(st->map, st->reg->pwr_mgmt_1,
+ INV_MPU6050_BIT_SLEEP);
+ mutex_unlock(&indio_dev->mlock);
+
+ return 0;
+}
+
+static const char *inv_mpu_match_acpi_device(struct device *dev, int *chip_id)
+{
+ const struct acpi_device_id *id;
+
+ id = acpi_match_device(dev->driver->acpi_match_table, dev);
+ if (!id)
+ return NULL;
+
+ *chip_id = (int)id->driver_data;
+
+ return dev_name(dev);
+}
+
+/**
+ * inv_mpu_probe() - probe function.
+ * @client: i2c client.
+ * @id: i2c device id.
+ *
+ * Returns 0 on success, a negative error code otherwise.
+ */
+static int inv_mpu_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct inv_mpu6050_state *st;
+ int result, chip_type;
+ struct regmap *regmap;
+ const char *name;
+
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_I2C_BLOCK))
+ return -EOPNOTSUPP;
+
+ if (id) {
+ chip_type = (int)id->driver_data;
+ name = id->name;
+ } else if (ACPI_HANDLE(&client->dev)) {
+ name = inv_mpu_match_acpi_device(&client->dev, &chip_type);
+ if (!name)
+ return -ENODEV;
+ } else {
+ return -ENOSYS;
+ }
+
+ regmap = devm_regmap_init_i2c(client, &inv_mpu_regmap_config);
+ if (IS_ERR(regmap)) {
+ dev_err(&client->dev, "Failed to register i2c regmap %d\n",
+ (int)PTR_ERR(regmap));
+ return PTR_ERR(regmap);
+ }
+
+ result = inv_mpu_core_probe(&client->dev, regmap, client->irq, name,
+ NULL, chip_type);
+ if (result < 0)
+ return result;
+
+ st = iio_priv(dev_get_drvdata(&client->dev));
+ st->muxc = i2c_mux_alloc(client->adapter, &client->dev,
+ 1, 0, I2C_MUX_LOCKED,
+ inv_mpu6050_select_bypass,
+ inv_mpu6050_deselect_bypass);
+ if (!st->muxc) {
+ result = -ENOMEM;
+ goto out_unreg_device;
+ }
+ st->muxc->priv = dev_get_drvdata(&client->dev);
+ result = i2c_mux_add_adapter(st->muxc, 0, 0, 0);
+ if (result)
+ goto out_unreg_device;
+
+ result = inv_mpu_acpi_create_mux_client(client);
+ if (result)
+ goto out_del_mux;
+
+ return 0;
+
+out_del_mux:
+ i2c_mux_del_adapters(st->muxc);
+out_unreg_device:
+ inv_mpu_core_remove(&client->dev);
+ return result;
+}
+
+static int inv_mpu_remove(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct inv_mpu6050_state *st = iio_priv(indio_dev);
+
+ inv_mpu_acpi_delete_mux_client(client);
+ i2c_mux_del_adapters(st->muxc);
+
+ return inv_mpu_core_remove(&client->dev);
+}
+
+/*
+ * device id table is used to identify what device can be
+ * supported by this driver
+ */
+static const struct i2c_device_id inv_mpu_id[] = {
+ {"mpu6050", INV_MPU6050},
+ {"mpu6500", INV_MPU6500},
+ {"mpu9150", INV_MPU9150},
+ {"mpu9250", INV_MPU9250},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, inv_mpu_id);
+
+static const struct acpi_device_id inv_acpi_match[] = {
+ {"INVN6500", INV_MPU6500},
+ { },
+};
+
+MODULE_DEVICE_TABLE(acpi, inv_acpi_match);
+
+static struct i2c_driver inv_mpu_driver = {
+ .probe = inv_mpu_probe,
+ .remove = inv_mpu_remove,
+ .id_table = inv_mpu_id,
+ .driver = {
+ .acpi_match_table = ACPI_PTR(inv_acpi_match),
+ .name = "inv-mpu6050-i2c",
+ .pm = &inv_mpu_pmops,
+ },
+};
+
+module_i2c_driver(inv_mpu_driver);
+
+MODULE_AUTHOR("Invensense Corporation");
+MODULE_DESCRIPTION("Invensense device MPU6050 driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/imu/inv_mpu9250/inv_mpu_i2cmst.c b/drivers/iio/imu/inv_mpu9250/inv_mpu_i2cmst.c
new file mode 100644
index 00000000..1fa45305
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu9250/inv_mpu_i2cmst.c
@@ -0,0 +1,182 @@
+/*
+* Copyright (C) 2016 Ambarella, Inc.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*/
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/of_i2c.h>
+#include <linux/iio/iio.h>
+#include "inv_mpu_iio.h"
+
+int inv_mpu_i2cmst_read_data(struct inv_mpu6050_state *st,
+ u16 addr, u8 command, int size, union i2c_smbus_data *data)
+{
+ unsigned int d, num;
+ void *buf;
+ int result;
+
+ result = inv_mpu6050_set_power_itg(st, true);
+ if (result)
+ return result;
+
+ switch (size) {
+ case I2C_SMBUS_BYTE_DATA:
+ num = 1;
+ buf = &data->byte;
+ break;
+ case I2C_SMBUS_WORD_DATA:
+ num = 2;
+ buf = &data->word;
+ break;
+ case I2C_SMBUS_I2C_BLOCK_DATA:
+ num = data->block[0];
+ buf = &data->block[1];
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ d = INV_MPU6050_BIT_I2C_SLV0_EN | num;
+ result = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV0_CTRL, d);
+ if (result)
+ return result;
+
+ result = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV0_REG, command);
+ if (result)
+ return result;
+
+ d = INV_MPU6050_BIT_I2C_SLV0_RNW | addr;
+ result = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV0_ADDR, d);
+ if (result)
+ return result;
+
+ d = 1000 / st->chip_config.fifo_rate;
+ msleep(d + d / 2);
+
+ result = regmap_bulk_read(st->map, INV_MPU6050_REG_EXT_SENS_DATA, buf, num);
+ if (result)
+ return result;
+
+ result = inv_mpu6050_set_power_itg(st, false);
+ if (result)
+ return result;
+
+ return 0;
+}
+
+int inv_mpu_i2cmst_write_data(struct inv_mpu6050_state *st,
+ u16 addr, u8 command, int size, union i2c_smbus_data *data)
+{
+ unsigned int d;
+ int result;
+
+ if (size != I2C_SMBUS_BYTE_DATA) {
+ dev_err(&st->adap->dev, "funky write size %d\n", size);
+ return -EINVAL;
+ }
+
+ result = inv_mpu6050_set_power_itg(st, true);
+ if (result)
+ return result;
+
+ d = INV_MPU6050_BIT_I2C_SLV0_EN | 1; /* only one byte allowed to write */
+ result = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV0_CTRL, d);
+ if (result)
+ return result;
+
+ result = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV0_REG, command);
+ if (result)
+ return result;
+
+ result = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV0_DO, data->byte);
+ if (result)
+ return result;
+
+ result = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV0_ADDR, addr);
+ if (result)
+ return result;
+
+ d = 1000 / st->chip_config.fifo_rate;
+ msleep(d + d / 2);
+
+ result = inv_mpu6050_set_power_itg(st, false);
+ if (result)
+ return result;
+
+ return 0;
+}
+
+static int inv_mpu_i2cmst_xfer(struct i2c_adapter *adap, u16 addr,
+ unsigned short flags, char rw, u8 command,
+ int size, union i2c_smbus_data *data)
+{
+ struct inv_mpu6050_state *st = i2c_get_adapdata(adap);
+ int ret = -EINVAL;
+
+ if (rw == I2C_SMBUS_WRITE)
+ ret = inv_mpu_i2cmst_write_data(st, addr, command, size, data);
+ else if (rw == I2C_SMBUS_READ)
+ ret = inv_mpu_i2cmst_read_data(st, addr, command, size, data);
+
+ return ret;
+}
+
+static u32 inv_mpu_i2cmst_func(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_READ_I2C_BLOCK;
+}
+
+static const struct i2c_algorithm inv_mpu_i2cmst_algo = {
+ .smbus_xfer = inv_mpu_i2cmst_xfer,
+ .functionality = inv_mpu_i2cmst_func,
+};
+
+int inv_mpu_i2cmst_probe(struct iio_dev *indio_dev)
+{
+ struct inv_mpu6050_state *st = iio_priv(indio_dev);
+ struct i2c_adapter *adap;
+ int ret;
+
+ adap = devm_kzalloc(&indio_dev->dev, sizeof(*adap), GFP_KERNEL);
+ if (!adap)
+ return -ENOMEM;
+
+ adap->owner = THIS_MODULE;
+ adap->class = I2C_CLASS_HWMON;
+ strlcpy(adap->name, "INV MPU I2CMST adapter", sizeof(adap->name));
+ adap->algo = &inv_mpu_i2cmst_algo;
+ adap->dev.parent = &indio_dev->dev;
+ adap->dev.of_node = indio_dev->dev.of_node;
+
+ i2c_set_adapdata(adap, st);
+ st->adap = adap;
+
+ ret = i2c_add_adapter(adap);
+ if (ret < 0) {
+ dev_err(&indio_dev->dev, "failed to add I2C master: %d\n", ret);
+ return ret;
+ }
+
+ of_i2c_register_devices(adap);
+
+ return 0;
+}
+
+void inv_mpu_i2cmst_remove(struct iio_dev *indio_dev)
+{
+ struct inv_mpu6050_state *st = iio_priv(indio_dev);
+ i2c_del_adapter(st->adap);
+}
+
+MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
+MODULE_DESCRIPTION("Invensense MPU9250 I2C Master driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/imu/inv_mpu9250/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu9250/inv_mpu_iio.h
new file mode 100644
index 00000000..4a6b3602
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu9250/inv_mpu_iio.h
@@ -0,0 +1,315 @@
+/*
+* Copyright (C) 2012 Invensense, Inc.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*/
+#include <linux/i2c.h>
+#include <linux/i2c-mux.h>
+#include <linux/kfifo.h>
+#include <linux/spinlock.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
+#include <linux/regmap.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/kfifo_buf.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/platform_data/invensense_mpu6050.h>
+
+/**
+ * struct inv_mpu6050_reg_map - Notable registers.
+ * @sample_rate_div: Divider applied to gyro output rate.
+ * @lpf: Configures internal low pass filter.
+ * @user_ctrl: Enables/resets the FIFO.
+ * @fifo_en: Determines which data will appear in FIFO.
+ * @gyro_config: gyro config register.
+ * @accl_config: accel config register
+ * @fifo_count_h: Upper byte of FIFO count.
+ * @fifo_r_w: FIFO register.
+ * @raw_gyro: Address of first gyro register.
+ * @raw_accl: Address of first accel register.
+ * @temperature: temperature register
+ * @int_enable: Interrupt enable register.
+ * @pwr_mgmt_1: Controls chip's power state and clock source.
+ * @pwr_mgmt_2: Controls power state of individual sensors.
+ * @int_pin_cfg; Controls interrupt pin configuration.
+ * @accl_offset: Controls the accelerometer calibration offset.
+ * @gyro_offset: Controls the gyroscope calibration offset.
+ */
+struct inv_mpu6050_reg_map {
+ u8 sample_rate_div;
+ u8 lpf;
+ u8 user_ctrl;
+ u8 fifo_en;
+ u8 gyro_config;
+ u8 accl_config;
+ u8 fifo_count_h;
+ u8 fifo_r_w;
+ u8 raw_gyro;
+ u8 raw_accl;
+ u8 temperature;
+ u8 int_enable;
+ u8 pwr_mgmt_1;
+ u8 pwr_mgmt_2;
+ u8 int_pin_cfg;
+ u8 accl_offset;
+ u8 gyro_offset;
+};
+
+/*device enum */
+enum inv_devices {
+ INV_MPU6050,
+ INV_MPU6500,
+ INV_MPU6000,
+ INV_MPU9150,
+ INV_MPU9250,
+ INV_NUM_PARTS
+};
+
+/**
+ * struct inv_mpu6050_chip_config - Cached chip configuration data.
+ * @fsr: Full scale range.
+ * @lpf: Digital low pass filter frequency.
+ * @accl_fs: accel full scale range.
+ * @enable: master enable state.
+ * @accl_fifo_enable: enable accel data output
+ * @gyro_fifo_enable: enable gyro data output
+ * @fifo_rate: FIFO update rate.
+ */
+struct inv_mpu6050_chip_config {
+ unsigned int fsr:2;
+ unsigned int lpf:3;
+ unsigned int accl_fs:2;
+ unsigned int enable:1;
+ unsigned int accl_fifo_enable:1;
+ unsigned int gyro_fifo_enable:1;
+ u16 fifo_rate;
+};
+
+/**
+ * struct inv_mpu6050_hw - Other important hardware information.
+ * @whoami: Self identification byte from WHO_AM_I register
+ * @name: name of the chip.
+ * @reg: register map of the chip.
+ * @config: configuration of the chip.
+ */
+struct inv_mpu6050_hw {
+ u8 whoami;
+ u8 *name;
+ const struct inv_mpu6050_reg_map *reg;
+ const struct inv_mpu6050_chip_config *config;
+};
+
+/*
+ * struct inv_mpu6050_state - Driver state variables.
+ * @TIMESTAMP_FIFO_SIZE: fifo size for timestamp.
+ * @trig: IIO trigger.
+ * @chip_config: Cached attribute information.
+ * @reg: Map of important registers.
+ * @hw: Other hardware-specific information.
+ * @chip_type: chip type.
+ * @time_stamp_lock: spin lock to time stamp.
+ * @orientation: sensor chip orientation relative to main hardware.
+ * @timestamps: kfifo queue to store time stamp.
+ * @map regmap pointer.
+ * @irq interrupt number.
+ */
+struct inv_mpu6050_state {
+#define TIMESTAMP_FIFO_SIZE 16
+ struct iio_trigger *trig;
+ struct inv_mpu6050_chip_config chip_config;
+ const struct inv_mpu6050_reg_map *reg;
+ const struct inv_mpu6050_hw *hw;
+ struct i2c_adapter *adap;
+ enum inv_devices chip_type;
+ spinlock_t time_stamp_lock;
+ struct i2c_mux_core *muxc;
+ struct i2c_client *mux_client;
+ unsigned int powerup_count;
+ struct iio_mount_matrix orientation;
+ DECLARE_KFIFO(timestamps, long long, TIMESTAMP_FIFO_SIZE);
+ struct regmap *map;
+ struct device *dev;
+ int irq;
+};
+
+/*register and associated bit definition*/
+#define INV_MPU6050_REG_ACCEL_OFFSET 0x06
+#define INV_MPU6050_REG_GYRO_OFFSET 0x13
+
+#define INV_MPU6050_REG_SAMPLE_RATE_DIV 0x19
+#define INV_MPU6050_REG_CONFIG 0x1A
+#define INV_MPU6050_REG_GYRO_CONFIG 0x1B
+#define INV_MPU6050_REG_ACCEL_CONFIG 0x1C
+
+#define INV_MPU6050_REG_FIFO_EN 0x23
+#define INV_MPU6050_BIT_ACCEL_OUT 0x08
+#define INV_MPU6050_BITS_GYRO_OUT 0x70
+
+#define INV_MPU6050_REG_I2C_MST_CTRL 0x24
+#define INV_MPU6050_BIT_WAIT_FOR_ES 0x40
+#define INV_MPU6050_BIT_I2C_MST_CLK 0x0d
+
+#define INV_MPU6050_REG_I2C_SLV0_ADDR 0x25
+#define INV_MPU6050_BIT_I2C_SLV0_RNW 0x80
+
+#define INV_MPU6050_REG_I2C_SLV0_REG 0x26
+
+#define INV_MPU6050_REG_I2C_SLV0_CTRL 0x27
+#define INV_MPU6050_BIT_I2C_SLV0_EN 0x80
+
+#define INV_MPU6050_REG_INT_ENABLE 0x38
+#define INV_MPU6050_BIT_DATA_RDY_EN 0x01
+#define INV_MPU6050_BIT_DMP_INT_EN 0x02
+
+#define INV_MPU6050_REG_RAW_ACCEL 0x3B
+#define INV_MPU6050_REG_TEMPERATURE 0x41
+#define INV_MPU6050_REG_RAW_GYRO 0x43
+
+#define INV_MPU6050_REG_EXT_SENS_DATA 0x49
+
+#define INV_MPU6050_REG_I2C_SLV0_DO 0x63
+
+#define INV_MPU6050_REG_USER_CTRL 0x6A
+#define INV_MPU6050_BIT_FIFO_RST 0x04
+#define INV_MPU6050_BIT_DMP_RST 0x08
+#define INV_MPU6050_BIT_I2C_MST_EN 0x20
+#define INV_MPU6050_BIT_FIFO_EN 0x40
+#define INV_MPU6050_BIT_DMP_EN 0x80
+#define INV_MPU6050_BIT_I2C_IF_DIS 0x10
+
+#define INV_MPU6050_REG_PWR_MGMT_1 0x6B
+#define INV_MPU6050_BIT_H_RESET 0x80
+#define INV_MPU6050_BIT_SLEEP 0x40
+#define INV_MPU6050_BIT_CLK_MASK 0x7
+
+#define INV_MPU6050_REG_PWR_MGMT_2 0x6C
+#define INV_MPU6050_BIT_PWR_ACCL_STBY 0x38
+#define INV_MPU6050_BIT_PWR_GYRO_STBY 0x07
+#define INV_MPU6050_BIT_PWR_TEMP_STBY 0x01
+
+#define INV_MPU6050_REG_FIFO_COUNT_H 0x72
+#define INV_MPU6050_REG_FIFO_R_W 0x74
+
+#define INV_MPU6050_BYTES_PER_3AXIS_SENSOR 6
+#define INV_MPU6050_FIFO_COUNT_BYTE 2
+#define INV_MPU6050_FIFO_THRESHOLD 500
+
+/* mpu6500 registers */
+#define INV_MPU6500_REG_ACCEL_OFFSET 0x77
+
+/* delay time in milliseconds */
+#define INV_MPU6050_POWER_UP_TIME 100
+#define INV_MPU6050_TEMP_UP_TIME 100
+#define INV_MPU6050_SENSOR_UP_TIME 30
+
+/* delay time in microseconds */
+#define INV_MPU6050_REG_UP_TIME_MIN 5000
+#define INV_MPU6050_REG_UP_TIME_MAX 10000
+
+#define INV_MPU6050_TEMP_OFFSET 12421
+#define INV_MPU6050_TEMP_SCALE 2941
+#define INV_MPU6050_MAX_GYRO_FS_PARAM 3
+#define INV_MPU6050_MAX_ACCL_FS_PARAM 3
+#define INV_MPU6050_THREE_AXIS 3
+#define INV_MPU6050_GYRO_CONFIG_FSR_SHIFT 3
+#define INV_MPU6050_ACCL_CONFIG_FSR_SHIFT 3
+
+/* 6 + 6 round up and plus 8 */
+#define INV_MPU6050_OUTPUT_DATA_SIZE 24
+
+#define INV_MPU6050_REG_INT_PIN_CFG 0x37
+#define INV_MPU6050_BIT_BYPASS_EN 0x2
+#define INV_MPU6050_INT_PIN_CFG 0
+
+/* init parameters */
+#define INV_MPU6050_INIT_FIFO_RATE 50
+#define INV_MPU6050_TIME_STAMP_TOR 5
+#define INV_MPU6050_MAX_FIFO_RATE 1000
+#define INV_MPU6050_MIN_FIFO_RATE 4
+#define INV_MPU6050_ONE_K_HZ 1000
+
+#define INV_MPU6050_REG_WHOAMI 117
+
+#define INV_MPU6000_WHOAMI_VALUE 0x68
+#define INV_MPU6050_WHOAMI_VALUE 0x68
+#define INV_MPU6500_WHOAMI_VALUE 0x70
+#define INV_MPU9150_WHOAMI_VALUE 0x68
+#define INV_MPU9250_WHOAMI_VALUE 0x71
+
+/* scan element definition */
+enum inv_mpu6050_scan {
+ INV_MPU6050_SCAN_ACCL_X,
+ INV_MPU6050_SCAN_ACCL_Y,
+ INV_MPU6050_SCAN_ACCL_Z,
+ INV_MPU6050_SCAN_GYRO_X,
+ INV_MPU6050_SCAN_GYRO_Y,
+ INV_MPU6050_SCAN_GYRO_Z,
+ INV_MPU6050_SCAN_TIMESTAMP,
+};
+
+enum inv_mpu6050_filter_e {
+ INV_MPU6050_FILTER_256HZ_NOLPF2 = 0,
+ INV_MPU6050_FILTER_188HZ,
+ INV_MPU6050_FILTER_98HZ,
+ INV_MPU6050_FILTER_42HZ,
+ INV_MPU6050_FILTER_20HZ,
+ INV_MPU6050_FILTER_10HZ,
+ INV_MPU6050_FILTER_5HZ,
+ INV_MPU6050_FILTER_2100HZ_NOLPF,
+ NUM_MPU6050_FILTER
+};
+
+/* IIO attribute address */
+enum INV_MPU6050_IIO_ATTR_ADDR {
+ ATTR_GYRO_MATRIX,
+ ATTR_ACCL_MATRIX,
+};
+
+enum inv_mpu6050_accl_fs_e {
+ INV_MPU6050_FS_02G = 0,
+ INV_MPU6050_FS_04G,
+ INV_MPU6050_FS_08G,
+ INV_MPU6050_FS_16G,
+ NUM_ACCL_FSR
+};
+
+enum inv_mpu6050_fsr_e {
+ INV_MPU6050_FSR_250DPS = 0,
+ INV_MPU6050_FSR_500DPS,
+ INV_MPU6050_FSR_1000DPS,
+ INV_MPU6050_FSR_2000DPS,
+ NUM_MPU6050_FSR
+};
+
+enum inv_mpu6050_clock_sel_e {
+ INV_CLK_INTERNAL = 0,
+ INV_CLK_PLL,
+ NUM_CLK
+};
+
+irqreturn_t inv_mpu6050_irq_handler(int irq, void *p);
+irqreturn_t inv_mpu6050_read_fifo(int irq, void *p);
+int inv_mpu6050_probe_trigger(struct iio_dev *indio_dev);
+void inv_mpu6050_remove_trigger(struct inv_mpu6050_state *st);
+int inv_reset_fifo(struct iio_dev *indio_dev);
+int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask);
+int inv_mpu6050_write_reg(struct inv_mpu6050_state *st, int reg, u8 val);
+int inv_mpu6050_set_power_itg(struct inv_mpu6050_state *st, bool power_on);
+int inv_mpu_acpi_create_mux_client(struct i2c_client *client);
+void inv_mpu_acpi_delete_mux_client(struct i2c_client *client);
+int inv_mpu_core_probe(struct device *dev, struct regmap *regmap,
+ int irq, const char *name,
+ int (*inv_mpu_bus_setup)(struct iio_dev *), int chip_type);
+int inv_mpu_core_remove(struct device *dev);
+int inv_mpu_i2cmst_probe(struct iio_dev *indio_dev);
+void inv_mpu_i2cmst_remove(struct iio_dev *indio_dev);
+extern const struct dev_pm_ops inv_mpu_pmops;
diff --git a/drivers/iio/imu/inv_mpu9250/inv_mpu_ring.c b/drivers/iio/imu/inv_mpu9250/inv_mpu_ring.c
new file mode 100644
index 00000000..919662d6
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu9250/inv_mpu_ring.c
@@ -0,0 +1,196 @@
+/*
+* Copyright (C) 2012 Invensense, Inc.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*/
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/sysfs.h>
+#include <linux/jiffies.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/kfifo.h>
+#include <linux/poll.h>
+#include "inv_mpu_iio.h"
+
+static void inv_clear_kfifo(struct inv_mpu6050_state *st)
+{
+ unsigned long flags;
+
+ /* take the spin lock sem to avoid interrupt kick in */
+ spin_lock_irqsave(&st->time_stamp_lock, flags);
+ kfifo_reset(&st->timestamps);
+ spin_unlock_irqrestore(&st->time_stamp_lock, flags);
+}
+
+int inv_reset_fifo(struct iio_dev *indio_dev)
+{
+ int result;
+ u8 d;
+ struct inv_mpu6050_state *st = iio_priv(indio_dev);
+
+ /* disable interrupt */
+ result = regmap_write(st->map, st->reg->int_enable, 0);
+ if (result) {
+ dev_err(st->dev, "int_enable failed %d\n",
+ result);
+ return result;
+ }
+ /* disable the sensor output to FIFO */
+ result = regmap_write(st->map, st->reg->fifo_en, 0);
+ if (result)
+ goto reset_fifo_fail;
+ /* disable fifo reading */
+ result = regmap_update_bits(st->map, st->reg->user_ctrl,
+ INV_MPU6050_BIT_FIFO_EN, 0);
+ if (result)
+ goto reset_fifo_fail;
+
+ /* reset FIFO*/
+ result = regmap_update_bits(st->map, st->reg->user_ctrl,
+ INV_MPU6050_BIT_FIFO_RST, INV_MPU6050_BIT_FIFO_RST);
+ if (result)
+ goto reset_fifo_fail;
+
+ /* clear timestamps fifo */
+ inv_clear_kfifo(st);
+
+ /* enable interrupt */
+ if (st->chip_config.accl_fifo_enable ||
+ st->chip_config.gyro_fifo_enable) {
+ result = regmap_write(st->map, st->reg->int_enable,
+ INV_MPU6050_BIT_DATA_RDY_EN);
+ if (result)
+ return result;
+ }
+ /* enable FIFO reading and I2C master interface*/
+ result = regmap_update_bits(st->map, st->reg->user_ctrl,
+ INV_MPU6050_BIT_FIFO_EN, INV_MPU6050_BIT_FIFO_EN);
+ if (result)
+ goto reset_fifo_fail;
+ /* enable sensor output to FIFO */
+ d = 0;
+ if (st->chip_config.gyro_fifo_enable)
+ d |= INV_MPU6050_BITS_GYRO_OUT;
+ if (st->chip_config.accl_fifo_enable)
+ d |= INV_MPU6050_BIT_ACCEL_OUT;
+ result = regmap_write(st->map, st->reg->fifo_en, d);
+ if (result)
+ goto reset_fifo_fail;
+
+ return 0;
+
+reset_fifo_fail:
+ dev_err(st->dev, "reset fifo failed %d\n", result);
+ result = regmap_write(st->map, st->reg->int_enable,
+ INV_MPU6050_BIT_DATA_RDY_EN);
+
+ return result;
+}
+
+/**
+ * inv_mpu6050_irq_handler() - Cache a timestamp at each data ready interrupt.
+ */
+irqreturn_t inv_mpu6050_irq_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct inv_mpu6050_state *st = iio_priv(indio_dev);
+ s64 timestamp;
+
+ timestamp = iio_get_time_ns();
+ kfifo_in_spinlocked(&st->timestamps, &timestamp, 1,
+ &st->time_stamp_lock);
+
+ return IRQ_WAKE_THREAD;
+}
+
+/**
+ * inv_mpu6050_read_fifo() - Transfer data from hardware FIFO to KFIFO.
+ */
+irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct inv_mpu6050_state *st = iio_priv(indio_dev);
+ size_t bytes_per_datum;
+ int result;
+ u8 data[INV_MPU6050_OUTPUT_DATA_SIZE];
+ u16 fifo_count;
+ s64 timestamp;
+ u64 *tmp;
+
+ mutex_lock(&indio_dev->mlock);
+ if (!(st->chip_config.accl_fifo_enable |
+ st->chip_config.gyro_fifo_enable))
+ goto end_session;
+ bytes_per_datum = 0;
+ if (st->chip_config.accl_fifo_enable)
+ bytes_per_datum += INV_MPU6050_BYTES_PER_3AXIS_SENSOR;
+
+ if (st->chip_config.gyro_fifo_enable)
+ bytes_per_datum += INV_MPU6050_BYTES_PER_3AXIS_SENSOR;
+
+ /*
+ * read fifo_count register to know how many bytes inside FIFO
+ * right now
+ */
+ result = regmap_bulk_read(st->map, st->reg->fifo_count_h, data,
+ INV_MPU6050_FIFO_COUNT_BYTE);
+ if (result)
+ goto end_session;
+ fifo_count = be16_to_cpup((__be16 *)(&data[0]));
+ if (fifo_count < bytes_per_datum)
+ goto end_session;
+ /* fifo count can't be odd number, if it is odd, reset fifo*/
+ if (fifo_count & 1)
+ goto flush_fifo;
+ if (fifo_count > INV_MPU6050_FIFO_THRESHOLD)
+ goto flush_fifo;
+ /* Timestamp mismatch. */
+ if (kfifo_len(&st->timestamps) >
+ fifo_count / bytes_per_datum + INV_MPU6050_TIME_STAMP_TOR)
+ goto flush_fifo;
+ while (fifo_count >= bytes_per_datum) {
+ result = regmap_bulk_read(st->map, st->reg->fifo_r_w,
+ data, bytes_per_datum);
+ if (result)
+ goto flush_fifo;
+
+ result = kfifo_out(&st->timestamps, &timestamp, 1);
+ /* when there is no timestamp, put timestamp as 0 */
+ if (result == 0)
+ timestamp = 0;
+
+ tmp = (u64 *)data;
+ tmp[DIV_ROUND_UP(bytes_per_datum, 8)] = timestamp;
+ result = iio_push_to_buffers(indio_dev, data);
+ if (result)
+ goto flush_fifo;
+ fifo_count -= bytes_per_datum;
+ }
+
+end_session:
+ mutex_unlock(&indio_dev->mlock);
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+
+flush_fifo:
+ /* Flush HW and SW FIFOs. */
+ inv_reset_fifo(indio_dev);
+ mutex_unlock(&indio_dev->mlock);
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
diff --git a/drivers/iio/imu/inv_mpu9250/inv_mpu_spi.c b/drivers/iio/imu/inv_mpu9250/inv_mpu_spi.c
new file mode 100644
index 00000000..1f6b6afd
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu9250/inv_mpu_spi.c
@@ -0,0 +1,132 @@
+/*
+* Copyright (C) 2015 Intel Corporation Inc.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*/
+#include <linux/module.h>
+#include <linux/acpi.h>
+#include <linux/spi/spi.h>
+#include <linux/regmap.h>
+#include <linux/iio/iio.h>
+#include "inv_mpu_iio.h"
+
+static const struct regmap_config inv_mpu_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+};
+
+static int inv_mpu_i2c_disable(struct iio_dev *indio_dev)
+{
+ struct inv_mpu6050_state *st = iio_priv(indio_dev);
+ int ret = 0;
+
+ ret = inv_mpu6050_set_power_itg(st, true);
+ if (ret)
+ return ret;
+
+ ret = regmap_write(st->map, INV_MPU6050_REG_USER_CTRL,
+ INV_MPU6050_BIT_I2C_IF_DIS | INV_MPU6050_BIT_I2C_MST_EN);
+ if (ret) {
+ inv_mpu6050_set_power_itg(st, false);
+ return ret;
+ }
+
+ ret = regmap_write(st->map, INV_MPU6050_REG_I2C_MST_CTRL,
+ INV_MPU6050_BIT_I2C_MST_CLK);
+ if (ret) {
+ inv_mpu6050_set_power_itg(st, false);
+ return ret;
+ }
+
+ return inv_mpu6050_set_power_itg(st, false);
+}
+
+static int inv_mpu_probe(struct spi_device *spi)
+{
+ struct regmap *regmap;
+ const struct spi_device_id *spi_id;
+ const struct acpi_device_id *acpi_id;
+ const char *name = NULL;
+ enum inv_devices chip_type;
+ int ret;
+
+ if ((spi_id = spi_get_device_id(spi))) {
+ chip_type = (enum inv_devices)spi_id->driver_data;
+ name = spi_id->name;
+ } else if ((acpi_id = acpi_match_device(spi->dev.driver->acpi_match_table, &spi->dev))) {
+ chip_type = (enum inv_devices)acpi_id->driver_data;
+ } else {
+ return -ENODEV;
+ }
+
+ regmap = devm_regmap_init_spi(spi, &inv_mpu_regmap_config);
+ if (IS_ERR(regmap)) {
+ dev_err(&spi->dev, "Failed to register spi regmap %d\n",
+ (int)PTR_ERR(regmap));
+ return PTR_ERR(regmap);
+ }
+
+ ret = inv_mpu_core_probe(&spi->dev, regmap, spi->irq, name,
+ inv_mpu_i2c_disable, chip_type);
+ if (ret < 0)
+ return ret;
+
+ ret = inv_mpu_i2cmst_probe(dev_get_drvdata(&spi->dev));
+ if (ret < 0) {
+ dev_err(&spi->dev, "i2c master probe fail %d\n", ret);
+ inv_mpu_core_remove(&spi->dev);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int inv_mpu_remove(struct spi_device *spi)
+{
+ inv_mpu_i2cmst_remove(dev_get_drvdata(&spi->dev));
+ return inv_mpu_core_remove(&spi->dev);
+}
+
+/*
+ * device id table is used to identify what device can be
+ * supported by this driver
+ */
+static const struct spi_device_id inv_mpu_id[] = {
+ {"mpu6000", INV_MPU6000},
+ {"mpu6500", INV_MPU6500},
+ {"mpu9150", INV_MPU9150},
+ {"mpu9250", INV_MPU9250},
+ {}
+};
+
+MODULE_DEVICE_TABLE(spi, inv_mpu_id);
+
+static const struct acpi_device_id inv_acpi_match[] = {
+ {"INVN6000", INV_MPU6000},
+ { },
+};
+MODULE_DEVICE_TABLE(acpi, inv_acpi_match);
+
+static struct spi_driver inv_mpu_driver = {
+ .probe = inv_mpu_probe,
+ .remove = inv_mpu_remove,
+ .id_table = inv_mpu_id,
+ .driver = {
+ .acpi_match_table = ACPI_PTR(inv_acpi_match),
+ .name = "inv-mpu6000-spi",
+ .pm = &inv_mpu_pmops,
+ },
+};
+
+module_spi_driver(inv_mpu_driver);
+
+MODULE_AUTHOR("Adriana Reus <adriana.reus@intel.com>");
+MODULE_DESCRIPTION("Invensense device MPU6000 driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/imu/inv_mpu9250/inv_mpu_trigger.c b/drivers/iio/imu/inv_mpu9250/inv_mpu_trigger.c
new file mode 100644
index 00000000..cca1c242
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu9250/inv_mpu_trigger.c
@@ -0,0 +1,148 @@
+/*
+* Copyright (C) 2012 Invensense, Inc.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*/
+
+#include "inv_mpu_iio.h"
+
+static void inv_scan_query(struct iio_dev *indio_dev)
+{
+ struct inv_mpu6050_state *st = iio_priv(indio_dev);
+
+ st->chip_config.gyro_fifo_enable =
+ test_bit(INV_MPU6050_SCAN_GYRO_X,
+ indio_dev->active_scan_mask) ||
+ test_bit(INV_MPU6050_SCAN_GYRO_Y,
+ indio_dev->active_scan_mask) ||
+ test_bit(INV_MPU6050_SCAN_GYRO_Z,
+ indio_dev->active_scan_mask);
+
+ st->chip_config.accl_fifo_enable =
+ test_bit(INV_MPU6050_SCAN_ACCL_X,
+ indio_dev->active_scan_mask) ||
+ test_bit(INV_MPU6050_SCAN_ACCL_Y,
+ indio_dev->active_scan_mask) ||
+ test_bit(INV_MPU6050_SCAN_ACCL_Z,
+ indio_dev->active_scan_mask);
+}
+
+/**
+ * inv_mpu6050_set_enable() - enable chip functions.
+ * @indio_dev: Device driver instance.
+ * @enable: enable/disable
+ */
+static int inv_mpu6050_set_enable(struct iio_dev *indio_dev, bool enable)
+{
+ struct inv_mpu6050_state *st = iio_priv(indio_dev);
+ int result;
+
+ if (enable) {
+ result = inv_mpu6050_set_power_itg(st, true);
+ if (result)
+ return result;
+ inv_scan_query(indio_dev);
+ if (st->chip_config.gyro_fifo_enable) {
+ result = inv_mpu6050_switch_engine(st, true,
+ INV_MPU6050_BIT_PWR_GYRO_STBY);
+ if (result)
+ return result;
+ }
+ if (st->chip_config.accl_fifo_enable) {
+ result = inv_mpu6050_switch_engine(st, true,
+ INV_MPU6050_BIT_PWR_ACCL_STBY);
+ if (result)
+ return result;
+ }
+ result = inv_reset_fifo(indio_dev);
+ if (result)
+ return result;
+ } else {
+ result = regmap_write(st->map, st->reg->fifo_en, 0);
+ if (result)
+ return result;
+
+ result = regmap_write(st->map, st->reg->int_enable, 0);
+ if (result)
+ return result;
+
+ result = regmap_update_bits(st->map, st->reg->user_ctrl,
+ INV_MPU6050_BIT_FIFO_EN, 0);
+ if (result)
+ return result;
+
+ result = inv_mpu6050_switch_engine(st, false,
+ INV_MPU6050_BIT_PWR_GYRO_STBY);
+ if (result)
+ return result;
+
+ result = inv_mpu6050_switch_engine(st, false,
+ INV_MPU6050_BIT_PWR_ACCL_STBY);
+ if (result)
+ return result;
+ result = inv_mpu6050_set_power_itg(st, false);
+ if (result)
+ return result;
+ }
+ st->chip_config.enable = enable;
+
+ return 0;
+}
+
+/**
+ * inv_mpu_data_rdy_trigger_set_state() - set data ready interrupt state
+ * @trig: Trigger instance
+ * @state: Desired trigger state
+ */
+static int inv_mpu_data_rdy_trigger_set_state(struct iio_trigger *trig,
+ bool state)
+{
+ return inv_mpu6050_set_enable(iio_trigger_get_drvdata(trig), state);
+}
+
+static const struct iio_trigger_ops inv_mpu_trigger_ops = {
+ .owner = THIS_MODULE,
+ .set_trigger_state = &inv_mpu_data_rdy_trigger_set_state,
+};
+
+int inv_mpu6050_probe_trigger(struct iio_dev *indio_dev)
+{
+ int ret;
+ struct inv_mpu6050_state *st = iio_priv(indio_dev);
+
+ st->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name, indio_dev->id);
+ if (!st->trig)
+ return -ENOMEM;
+
+ ret = devm_request_irq(&indio_dev->dev, st->irq,
+ &iio_trigger_generic_data_rdy_poll,
+ IRQF_TRIGGER_RISING,
+ "inv_mpu",
+ st->trig);
+ if (ret)
+ return ret;
+
+ st->trig->dev.parent = st->dev;
+ st->trig->ops = &inv_mpu_trigger_ops;
+ iio_trigger_set_drvdata(st->trig, indio_dev);
+
+ ret = iio_trigger_register(st->trig);
+ if (ret)
+ return ret;
+
+ indio_dev->trig = iio_trigger_get(st->trig);
+
+ return 0;
+}
+
+void inv_mpu6050_remove_trigger(struct inv_mpu6050_state *st)
+{
+ iio_trigger_unregister(st->trig);
+}
diff --git a/drivers/iio/magnetometer/Kconfig b/drivers/iio/magnetometer/Kconfig
index bd1cfb66..6cd03f3a 100644
--- a/drivers/iio/magnetometer/Kconfig
+++ b/drivers/iio/magnetometer/Kconfig
@@ -7,9 +7,11 @@ config AK8975
tristate "Asahi Kasei AK8975 3-Axis Magnetometer"
depends on I2C
depends on GPIOLIB
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
help
- Say yes here to build support for Asahi Kasei AK8975 3-Axis
- Magnetometer.
+ Say yes here to build support for Asahi Kasei AK8975, AK8963,
+ AK09911 or AK09912 3-Axis Magnetometer.
To compile this driver as a module, choose M here: the module
will be called ak8975.
diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c
index 53f82900..1cf7c6e3 100644
--- a/drivers/iio/magnetometer/ak8975.c
+++ b/drivers/iio/magnetometer/ak8975.c
@@ -24,14 +24,23 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/i2c.h>
+#include <linux/interrupt.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/delay.h>
-
+#include <linux/bitops.h>
#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/acpi.h>
+#include <linux/regulator/consumer.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+
/*
* Register definitions, as well as various shifts and masks to get at the
* individual fields of the registers.
@@ -61,10 +70,10 @@
#define AK8975_REG_CNTL 0x0A
#define AK8975_REG_CNTL_MODE_SHIFT 0
#define AK8975_REG_CNTL_MODE_MASK (0xF << AK8975_REG_CNTL_MODE_SHIFT)
-#define AK8975_REG_CNTL_MODE_POWER_DOWN 0
-#define AK8975_REG_CNTL_MODE_ONCE 1
-#define AK8975_REG_CNTL_MODE_SELF_TEST 8
-#define AK8975_REG_CNTL_MODE_FUSE_ROM 0xF
+#define AK8975_REG_CNTL_MODE_POWER_DOWN 0x00
+#define AK8975_REG_CNTL_MODE_ONCE 0x01
+#define AK8975_REG_CNTL_MODE_SELF_TEST 0x08
+#define AK8975_REG_CNTL_MODE_FUSE_ROM 0x0F
#define AK8975_REG_RSVC 0x0B
#define AK8975_REG_ASTC 0x0C
@@ -77,51 +86,443 @@
#define AK8975_MAX_REGS AK8975_REG_ASAZ
+/*
+ * AK09912 Register definitions
+ */
+#define AK09912_REG_WIA1 0x00
+#define AK09912_REG_WIA2 0x01
+#define AK09912_DEVICE_ID 0x04
+#define AK09911_DEVICE_ID 0x05
+
+#define AK09911_REG_INFO1 0x02
+#define AK09911_REG_INFO2 0x03
+
+#define AK09912_REG_ST1 0x10
+
+#define AK09912_REG_ST1_DRDY_SHIFT 0
+#define AK09912_REG_ST1_DRDY_MASK (1 << AK09912_REG_ST1_DRDY_SHIFT)
+
+#define AK09912_REG_HXL 0x11
+#define AK09912_REG_HXH 0x12
+#define AK09912_REG_HYL 0x13
+#define AK09912_REG_HYH 0x14
+#define AK09912_REG_HZL 0x15
+#define AK09912_REG_HZH 0x16
+#define AK09912_REG_TMPS 0x17
+
+#define AK09912_REG_ST2 0x18
+#define AK09912_REG_ST2_HOFL_SHIFT 3
+#define AK09912_REG_ST2_HOFL_MASK (1 << AK09912_REG_ST2_HOFL_SHIFT)
+
+#define AK09912_REG_CNTL1 0x30
+
+#define AK09912_REG_CNTL2 0x31
+#define AK09912_REG_CNTL_MODE_POWER_DOWN 0x00
+#define AK09912_REG_CNTL_MODE_ONCE 0x01
+#define AK09912_REG_CNTL_MODE_SELF_TEST 0x10
+#define AK09912_REG_CNTL_MODE_FUSE_ROM 0x1F
+#define AK09912_REG_CNTL2_MODE_SHIFT 0
+#define AK09912_REG_CNTL2_MODE_MASK (0x1F << AK09912_REG_CNTL2_MODE_SHIFT)
+
+#define AK09912_REG_CNTL3 0x32
+
+#define AK09912_REG_TS1 0x33
+#define AK09912_REG_TS2 0x34
+#define AK09912_REG_TS3 0x35
+#define AK09912_REG_I2CDIS 0x36
+#define AK09912_REG_TS4 0x37
+
+#define AK09912_REG_ASAX 0x60
+#define AK09912_REG_ASAY 0x61
+#define AK09912_REG_ASAZ 0x62
+
+#define AK09912_MAX_REGS AK09912_REG_ASAZ
+
/*
* Miscellaneous values.
*/
#define AK8975_MAX_CONVERSION_TIMEOUT 500
#define AK8975_CONVERSION_DONE_POLL_TIME 10
+#define AK8975_DATA_READY_TIMEOUT ((100*HZ)/1000)
+
+/*
+ * Precalculate scale factor (in Gauss units) for each axis and
+ * store in the device data.
+ *
+ * This scale factor is axis-dependent, and is derived from 3 calibration
+ * factors ASA(x), ASA(y), and ASA(z).
+ *
+ * These ASA values are read from the sensor device at start of day, and
+ * cached in the device context struct.
+ *
+ * Adjusting the flux value with the sensitivity adjustment value should be
+ * done via the following formula:
+ *
+ * Hadj = H * ( ( ( (ASA-128)*0.5 ) / 128 ) + 1 )
+ * where H is the raw value, ASA is the sensitivity adjustment, and Hadj
+ * is the resultant adjusted value.
+ *
+ * We reduce the formula to:
+ *
+ * Hadj = H * (ASA + 128) / 256
+ *
+ * H is in the range of -4096 to 4095. The magnetometer has a range of
+ * +-1229uT. To go from the raw value to uT is:
+ *
+ * HuT = H * 1229/4096, or roughly, 3/10.
+ *
+ * Since 1uT = 0.01 gauss, our final scale factor becomes:
+ *
+ * Hadj = H * ((ASA + 128) / 256) * 3/10 * 1/100
+ * Hadj = H * ((ASA + 128) * 0.003) / 256
+ *
+ * Since ASA doesn't change, we cache the resultant scale factor into the
+ * device context in ak8975_setup().
+ *
+ * Given we use IIO_VAL_INT_PLUS_MICRO bit when displaying the scale, we
+ * multiply the stored scale value by 1e6.
+ */
+static long ak8975_raw_to_gauss(u16 data)
+{
+ return (((long)data + 128) * 3000) / 256;
+}
+
+/*
+ * For AK8963 and AK09911, same calculation, but the device is less sensitive:
+ *
+ * H is in the range of +-8190. The magnetometer has a range of
+ * +-4912uT. To go from the raw value to uT is:
+ *
+ * HuT = H * 4912/8190, or roughly, 6/10, instead of 3/10.
+ */
+
+static long ak8963_09911_raw_to_gauss(u16 data)
+{
+ return (((long)data + 128) * 6000) / 256;
+}
+
+/*
+ * For AK09912, same calculation, except the device is more sensitive:
+ *
+ * H is in the range of -32752 to 32752. The magnetometer has a range of
+ * +-4912uT. To go from the raw value to uT is:
+ *
+ * HuT = H * 4912/32752, or roughly, 3/20, instead of 3/10.
+ */
+static long ak09912_raw_to_gauss(u16 data)
+{
+ return (((long)data + 128) * 1500) / 256;
+}
+
+/* Compatible Asahi Kasei Compass parts */
+enum asahi_compass_chipset {
+ AK8975,
+ AK8963,
+ AK09911,
+ AK09912,
+ AK_MAX_TYPE
+};
+
+enum ak_ctrl_reg_addr {
+ ST1,
+ ST2,
+ CNTL,
+ ASA_BASE,
+ MAX_REGS,
+ REGS_END,
+};
+
+enum ak_ctrl_reg_mask {
+ ST1_DRDY,
+ ST2_HOFL,
+ ST2_DERR,
+ CNTL_MODE,
+ MASK_END,
+};
+
+enum ak_ctrl_mode {
+ POWER_DOWN,
+ MODE_ONCE,
+ SELF_TEST,
+ FUSE_ROM,
+ MODE_END,
+};
+
+struct ak_def {
+ enum asahi_compass_chipset type;
+ long (*raw_to_gauss)(u16 data);
+ u16 range;
+ u8 ctrl_regs[REGS_END];
+ u8 ctrl_masks[MASK_END];
+ u8 ctrl_modes[MODE_END];
+ u8 data_regs[3];
+};
+
+static const struct ak_def ak_def_array[AK_MAX_TYPE] = {
+ {
+ .type = AK8975,
+ .raw_to_gauss = ak8975_raw_to_gauss,
+ .range = 4096,
+ .ctrl_regs = {
+ AK8975_REG_ST1,
+ AK8975_REG_ST2,
+ AK8975_REG_CNTL,
+ AK8975_REG_ASAX,
+ AK8975_MAX_REGS},
+ .ctrl_masks = {
+ AK8975_REG_ST1_DRDY_MASK,
+ AK8975_REG_ST2_HOFL_MASK,
+ AK8975_REG_ST2_DERR_MASK,
+ AK8975_REG_CNTL_MODE_MASK},
+ .ctrl_modes = {
+ AK8975_REG_CNTL_MODE_POWER_DOWN,
+ AK8975_REG_CNTL_MODE_ONCE,
+ AK8975_REG_CNTL_MODE_SELF_TEST,
+ AK8975_REG_CNTL_MODE_FUSE_ROM},
+ .data_regs = {
+ AK8975_REG_HXL,
+ AK8975_REG_HYL,
+ AK8975_REG_HZL},
+ },
+ {
+ .type = AK8963,
+ .raw_to_gauss = ak8963_09911_raw_to_gauss,
+ .range = 8190,
+ .ctrl_regs = {
+ AK8975_REG_ST1,
+ AK8975_REG_ST2,
+ AK8975_REG_CNTL,
+ AK8975_REG_ASAX,
+ AK8975_MAX_REGS},
+ .ctrl_masks = {
+ AK8975_REG_ST1_DRDY_MASK,
+ AK8975_REG_ST2_HOFL_MASK,
+ 0,
+ AK8975_REG_CNTL_MODE_MASK},
+ .ctrl_modes = {
+ AK8975_REG_CNTL_MODE_POWER_DOWN,
+ AK8975_REG_CNTL_MODE_ONCE,
+ AK8975_REG_CNTL_MODE_SELF_TEST,
+ AK8975_REG_CNTL_MODE_FUSE_ROM},
+ .data_regs = {
+ AK8975_REG_HXL,
+ AK8975_REG_HYL,
+ AK8975_REG_HZL},
+ },
+ {
+ .type = AK09911,
+ .raw_to_gauss = ak8963_09911_raw_to_gauss,
+ .range = 8192,
+ .ctrl_regs = {
+ AK09912_REG_ST1,
+ AK09912_REG_ST2,
+ AK09912_REG_CNTL2,
+ AK09912_REG_ASAX,
+ AK09912_MAX_REGS},
+ .ctrl_masks = {
+ AK09912_REG_ST1_DRDY_MASK,
+ AK09912_REG_ST2_HOFL_MASK,
+ 0,
+ AK09912_REG_CNTL2_MODE_MASK},
+ .ctrl_modes = {
+ AK09912_REG_CNTL_MODE_POWER_DOWN,
+ AK09912_REG_CNTL_MODE_ONCE,
+ AK09912_REG_CNTL_MODE_SELF_TEST,
+ AK09912_REG_CNTL_MODE_FUSE_ROM},
+ .data_regs = {
+ AK09912_REG_HXL,
+ AK09912_REG_HYL,
+ AK09912_REG_HZL},
+ },
+ {
+ .type = AK09912,
+ .raw_to_gauss = ak09912_raw_to_gauss,
+ .range = 32752,
+ .ctrl_regs = {
+ AK09912_REG_ST1,
+ AK09912_REG_ST2,
+ AK09912_REG_CNTL2,
+ AK09912_REG_ASAX,
+ AK09912_MAX_REGS},
+ .ctrl_masks = {
+ AK09912_REG_ST1_DRDY_MASK,
+ AK09912_REG_ST2_HOFL_MASK,
+ 0,
+ AK09912_REG_CNTL2_MODE_MASK},
+ .ctrl_modes = {
+ AK09912_REG_CNTL_MODE_POWER_DOWN,
+ AK09912_REG_CNTL_MODE_ONCE,
+ AK09912_REG_CNTL_MODE_SELF_TEST,
+ AK09912_REG_CNTL_MODE_FUSE_ROM},
+ .data_regs = {
+ AK09912_REG_HXL,
+ AK09912_REG_HYL,
+ AK09912_REG_HZL},
+ }
+};
/*
* Per-instance context data for the device.
*/
struct ak8975_data {
struct i2c_client *client;
- struct attribute_group attrs;
+ const struct ak_def *def;
struct mutex lock;
u8 asa[3];
long raw_to_gauss[3];
- u8 reg_cache[AK8975_MAX_REGS];
int eoc_gpio;
+ int eoc_irq;
+ wait_queue_head_t data_ready_queue;
+ unsigned long flags;
+ u8 cntl_cache;
+ struct iio_mount_matrix orientation;
+ struct regulator *vdd;
};
-static const int ak8975_index_to_reg[] = {
- AK8975_REG_HXL, AK8975_REG_HYL, AK8975_REG_HZL,
-};
+/* Enable attached power regulator if any. */
+static int ak8975_power_on(struct i2c_client *client)
+{
+ const struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct ak8975_data *data = iio_priv(indio_dev);
+ int ret;
+
+ data->vdd = devm_regulator_get(&client->dev, "vdd");
+ if (IS_ERR_OR_NULL(data->vdd)) {
+ ret = PTR_ERR(data->vdd);
+ if (ret == -ENODEV)
+ ret = 0;
+ } else {
+ ret = regulator_enable(data->vdd);
+ }
+
+ if (ret)
+ dev_err(&client->dev, "failed to enable Vdd supply: %d\n", ret);
+ return ret;
+}
+
+/* Disable attached power regulator if any. */
+static void ak8975_power_off(const struct i2c_client *client)
+{
+ const struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ const struct ak8975_data *data = iio_priv(indio_dev);
+
+ if (!IS_ERR_OR_NULL(data->vdd))
+ regulator_disable(data->vdd);
+}
/*
- * Helper function to write to the I2C device's registers.
+ * Return 0 if the i2c device is the one we expect.
+ * return a negative error number otherwise
*/
-static int ak8975_write_data(struct i2c_client *client,
- u8 reg, u8 val, u8 mask, u8 shift)
+static int ak8975_who_i_am(struct i2c_client *client,
+ enum asahi_compass_chipset type)
+{
+ u8 wia_val[2];
+ int ret;
+
+ /*
+ * Signature for each device:
+ * Device | WIA1 | WIA2
+ * AK09912 | DEVICE_ID | AK09912_DEVICE_ID
+ * AK09911 | DEVICE_ID | AK09911_DEVICE_ID
+ * AK8975 | DEVICE_ID | NA
+ * AK8963 | DEVICE_ID | NA
+ */
+ ret = i2c_smbus_read_i2c_block_data(client, AK09912_REG_WIA1,
+ 2, wia_val);
+ if (ret < 0) {
+ dev_err(&client->dev, "Error reading WIA\n");
+ return ret;
+ }
+
+ if (wia_val[0] != AK8975_DEVICE_ID)
+ return -ENODEV;
+
+ switch (type) {
+ case AK8975:
+ case AK8963:
+ return 0;
+ case AK09911:
+ if (wia_val[1] == AK09911_DEVICE_ID)
+ return 0;
+ break;
+ case AK09912:
+ if (wia_val[1] == AK09912_DEVICE_ID)
+ return 0;
+ break;
+ default:
+ dev_err(&client->dev, "Type %d unknown\n", type);
+ }
+ return -ENODEV;
+}
+
+/*
+ * Helper function to write to CNTL register.
+ */
+static int ak8975_set_mode(struct ak8975_data *data, enum ak_ctrl_mode mode)
{
- struct iio_dev *indio_dev = i2c_get_clientdata(client);
- struct ak8975_data *data = iio_priv(indio_dev);
u8 regval;
int ret;
- regval = (data->reg_cache[reg] & ~mask) | (val << shift);
- ret = i2c_smbus_write_byte_data(client, reg, regval);
+ regval = (data->cntl_cache & ~data->def->ctrl_masks[CNTL_MODE]) |
+ data->def->ctrl_modes[mode];
+ ret = i2c_smbus_write_byte_data(data->client,
+ data->def->ctrl_regs[CNTL], regval);
if (ret < 0) {
- dev_err(&client->dev, "Write to device fails status %x\n", ret);
return ret;
}
- data->reg_cache[reg] = regval;
+ data->cntl_cache = regval;
+ /* After mode change wait atleast 100us */
+ usleep_range(100, 500);
return 0;
}
+/*
+ * Handle data ready irq
+ */
+static irqreturn_t ak8975_irq_handler(int irq, void *data)
+{
+ struct ak8975_data *ak8975 = data;
+
+ set_bit(0, &ak8975->flags);
+ wake_up(&ak8975->data_ready_queue);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * Install data ready interrupt handler
+ */
+static int ak8975_setup_irq(struct ak8975_data *data)
+{
+ struct i2c_client *client = data->client;
+ int rc;
+ int irq;
+
+ init_waitqueue_head(&data->data_ready_queue);
+ clear_bit(0, &data->flags);
+ if (client->irq)
+ irq = client->irq;
+ else
+ irq = gpio_to_irq(data->eoc_gpio);
+
+ rc = devm_request_irq(&client->dev, irq, ak8975_irq_handler,
+ IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+ dev_name(&client->dev), data);
+ if (rc < 0) {
+ dev_err(&client->dev,
+ "irq %d request failed, (gpio %d): %d\n",
+ irq, data->eoc_gpio, rc);
+ return rc;
+ }
+
+ data->eoc_irq = irq;
+
+ return rc;
+}
+
+
/*
* Perform some start-of-day setup, including reading the asa calibration
* values and caching them.
@@ -130,34 +531,18 @@ static int ak8975_setup(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct ak8975_data *data = iio_priv(indio_dev);
- u8 device_id;
int ret;
- /* Confirm that the device we're talking to is really an AK8975. */
- ret = i2c_smbus_read_byte_data(client, AK8975_REG_WIA);
- if (ret < 0) {
- dev_err(&client->dev, "Error reading WIA\n");
- return ret;
- }
- device_id = ret;
- if (device_id != AK8975_DEVICE_ID) {
- dev_err(&client->dev, "Device ak8975 not found\n");
- return -ENODEV;
- }
-
/* Write the fused rom access mode. */
- ret = ak8975_write_data(client,
- AK8975_REG_CNTL,
- AK8975_REG_CNTL_MODE_FUSE_ROM,
- AK8975_REG_CNTL_MODE_MASK,
- AK8975_REG_CNTL_MODE_SHIFT);
+ ret = ak8975_set_mode(data, FUSE_ROM);
if (ret < 0) {
dev_err(&client->dev, "Error in setting fuse access mode\n");
return ret;
}
/* Get asa data and store in the device data. */
- ret = i2c_smbus_read_i2c_block_data(client, AK8975_REG_ASAX,
+ ret = i2c_smbus_read_i2c_block_data(client,
+ data->def->ctrl_regs[ASA_BASE],
3, data->asa);
if (ret < 0) {
dev_err(&client->dev, "Not able to read asa data\n");
@@ -165,54 +550,24 @@ static int ak8975_setup(struct i2c_client *client)
}
/* After reading fuse ROM data set power-down mode */
- ret = ak8975_write_data(client,
- AK8975_REG_CNTL,
- AK8975_REG_CNTL_MODE_POWER_DOWN,
- AK8975_REG_CNTL_MODE_MASK,
- AK8975_REG_CNTL_MODE_SHIFT);
+ ret = ak8975_set_mode(data, POWER_DOWN);
if (ret < 0) {
dev_err(&client->dev, "Error in setting power-down mode\n");
return ret;
}
-/*
- * Precalculate scale factor (in Gauss units) for each axis and
- * store in the device data.
- *
- * This scale factor is axis-dependent, and is derived from 3 calibration
- * factors ASA(x), ASA(y), and ASA(z).
- *
- * These ASA values are read from the sensor device at start of day, and
- * cached in the device context struct.
- *
- * Adjusting the flux value with the sensitivity adjustment value should be
- * done via the following formula:
- *
- * Hadj = H * ( ( ( (ASA-128)*0.5 ) / 128 ) + 1 )
- *
- * where H is the raw value, ASA is the sensitivity adjustment, and Hadj
- * is the resultant adjusted value.
- *
- * We reduce the formula to:
- *
- * Hadj = H * (ASA + 128) / 256
- *
- * H is in the range of -4096 to 4095. The magnetometer has a range of
- * +-1229uT. To go from the raw value to uT is:
- *
- * HuT = H * 1229/4096, or roughly, 3/10.
- *
- * Since 1uT = 100 gauss, our final scale factor becomes:
- *
- * Hadj = H * ((ASA + 128) / 256) * 3/10 * 100
- * Hadj = H * ((ASA + 128) * 30 / 256
- *
- * Since ASA doesn't change, we cache the resultant scale factor into the
- * device context in ak8975_setup().
- */
- data->raw_to_gauss[0] = ((data->asa[0] + 128) * 30) >> 8;
- data->raw_to_gauss[1] = ((data->asa[1] + 128) * 30) >> 8;
- data->raw_to_gauss[2] = ((data->asa[2] + 128) * 30) >> 8;
+ if (data->eoc_gpio > 0 || client->irq > 0) {
+ ret = ak8975_setup_irq(data);
+ if (ret < 0) {
+ dev_err(&client->dev,
+ "Error setting data ready interrupt\n");
+ return ret;
+ }
+ }
+
+ data->raw_to_gauss[0] = data->def->raw_to_gauss(data->asa[0]);
+ data->raw_to_gauss[1] = data->def->raw_to_gauss(data->asa[1]);
+ data->raw_to_gauss[2] = data->def->raw_to_gauss(data->asa[2]);
return 0;
}
@@ -235,7 +590,7 @@ static int wait_conversion_complete_gpio(struct ak8975_data *data)
return -EINVAL;
}
- ret = i2c_smbus_read_byte_data(client, AK8975_REG_ST1);
+ ret = i2c_smbus_read_byte_data(client, data->def->ctrl_regs[ST1]);
if (ret < 0)
dev_err(&client->dev, "Error in reading ST1\n");
@@ -252,7 +607,8 @@ static int wait_conversion_complete_polled(struct ak8975_data *data)
/* Wait for the conversion to complete. */
while (timeout_ms) {
msleep(AK8975_CONVERSION_DONE_POLL_TIME);
- ret = i2c_smbus_read_byte_data(client, AK8975_REG_ST1);
+ ret = i2c_smbus_read_byte_data(client,
+ data->def->ctrl_regs[ST1]);
if (ret < 0) {
dev_err(&client->dev, "Error in reading ST1\n");
return ret;
@@ -266,69 +622,89 @@ static int wait_conversion_complete_polled(struct ak8975_data *data)
dev_err(&client->dev, "Conversion timeout happened\n");
return -EINVAL;
}
+
return read_status;
}
-/*
- * Emits the raw flux value for the x, y, or z axis.
- */
-static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
+/* Returns 0 if the end of conversion interrupt occured or -ETIME otherwise */
+static int wait_conversion_complete_interrupt(struct ak8975_data *data)
{
- struct ak8975_data *data = iio_priv(indio_dev);
- struct i2c_client *client = data->client;
int ret;
- mutex_lock(&data->lock);
+ ret = wait_event_timeout(data->data_ready_queue,
+ test_bit(0, &data->flags),
+ AK8975_DATA_READY_TIMEOUT);
+ clear_bit(0, &data->flags);
+ return ret > 0 ? 0 : -ETIME;
+}
+
+static int ak8975_start_read_axis(struct ak8975_data *data,
+ const struct i2c_client *client)
+{
/* Set up the device for taking a sample. */
- ret = ak8975_write_data(client,
- AK8975_REG_CNTL,
- AK8975_REG_CNTL_MODE_ONCE,
- AK8975_REG_CNTL_MODE_MASK,
- AK8975_REG_CNTL_MODE_SHIFT);
+ int ret = ak8975_set_mode(data, MODE_ONCE);
+
if (ret < 0) {
dev_err(&client->dev, "Error in setting operating mode\n");
- goto exit;
+ return ret;
}
/* Wait for the conversion to complete. */
- if (gpio_is_valid(data->eoc_gpio))
+ if (data->eoc_irq)
+ ret = wait_conversion_complete_interrupt(data);
+ else if (gpio_is_valid(data->eoc_gpio))
ret = wait_conversion_complete_gpio(data);
else
ret = wait_conversion_complete_polled(data);
if (ret < 0)
- goto exit;
+ return ret;
- if (ret & AK8975_REG_ST1_DRDY_MASK) {
- ret = i2c_smbus_read_byte_data(client, AK8975_REG_ST2);
+ /* This will be executed only for non-interrupt based waiting case */
+ if (ret & data->def->ctrl_masks[ST1_DRDY]) {
+ ret = i2c_smbus_read_byte_data(client,
+ data->def->ctrl_regs[ST2]);
if (ret < 0) {
dev_err(&client->dev, "Error in reading ST2\n");
- goto exit;
+ return ret;
}
- if (ret & (AK8975_REG_ST2_DERR_MASK |
- AK8975_REG_ST2_HOFL_MASK)) {
+ if (ret & (data->def->ctrl_masks[ST2_DERR] |
+ data->def->ctrl_masks[ST2_HOFL])) {
dev_err(&client->dev, "ST2 status error 0x%x\n", ret);
- ret = -EINVAL;
- goto exit;
+ return -EINVAL;
}
}
- /* Read the flux value from the appropriate register
- (the register is specified in the iio device attributes). */
- ret = i2c_smbus_read_word_data(client, ak8975_index_to_reg[index]);
- if (ret < 0) {
- dev_err(&client->dev, "Read axis data fails\n");
+ return 0;
+}
+
+/* Retrieve raw flux value for one of the x, y, or z axis. */
+static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
+{
+ struct ak8975_data *data = iio_priv(indio_dev);
+ const struct i2c_client *client = data->client;
+ const struct ak_def *def = data->def;
+ int ret;
+
+ mutex_lock(&data->lock);
+
+ ret = ak8975_start_read_axis(data, client);
+ if (ret)
+ goto exit;
+
+ ret = i2c_smbus_read_word_data(client, def->data_regs[index]);
+ if (ret < 0)
goto exit;
- }
mutex_unlock(&data->lock);
/* Clamp to valid range. */
- *val = clamp_t(s16, ret, -4096, 4095);
+ *val = clamp_t(s16, ret, -def->range, def->range);
return IIO_VAL_INT;
exit:
mutex_unlock(&data->lock);
+ dev_err(&client->dev, "Error in reading axis\n");
return ret;
}
@@ -343,12 +719,34 @@ static int ak8975_read_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_RAW:
return ak8975_read_axis(indio_dev, chan->address, val);
case IIO_CHAN_INFO_SCALE:
- *val = data->raw_to_gauss[chan->address];
- return IIO_VAL_INT;
+ *val = 0;
+ *val2 = data->raw_to_gauss[chan->address];
+ return IIO_VAL_INT_PLUS_MICRO;
}
return -EINVAL;
}
+static ssize_t ak8975_attr_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct ak8975_data *data = iio_priv(dev_to_iio_dev(dev));
+ const char **m = data->orientation.rotation;
+
+ return sprintf(buf, "%s, %s, %s; %s, %s, %s; %s, %s, %s\n",
+ m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8]);
+}
+
+static IIO_DEVICE_ATTR(in_mount_matrix, S_IRUGO, ak8975_attr_show, NULL, 0);
+
+static struct attribute *ak8975_attributes[] = {
+ &iio_dev_attr_in_mount_matrix.dev_attr.attr,
+ NULL,
+};
+
+static const struct attribute_group ak8975_attribute_group = {
+ .attrs = ak8975_attributes
+};
+
#define AK8975_CHANNEL(axis, index) \
{ \
.type = IIO_MAGN, \
@@ -357,16 +755,104 @@ static int ak8975_read_raw(struct iio_dev *indio_dev,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_SCALE), \
.address = index, \
+ .scan_index = index, \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = 16, \
+ .storagebits = 16, \
+ .endianness = IIO_CPU \
+ }, \
}
static const struct iio_chan_spec ak8975_channels[] = {
AK8975_CHANNEL(X, 0), AK8975_CHANNEL(Y, 1), AK8975_CHANNEL(Z, 2),
+ IIO_CHAN_SOFT_TIMESTAMP(3),
};
+static const unsigned long ak8975_scan_masks[] = { 0x7, 0 };
+
static const struct iio_info ak8975_info = {
.read_raw = &ak8975_read_raw,
.driver_module = THIS_MODULE,
+ .attrs = &ak8975_attribute_group,
+};
+
+static const struct acpi_device_id ak_acpi_match[] = {
+ {"AK8975", AK8975},
+ {"AK8963", AK8963},
+ {"INVN6500", AK8963},
+ {"AK09911", AK09911},
+ {"AK09912", AK09912},
+ { },
};
+MODULE_DEVICE_TABLE(acpi, ak_acpi_match);
+
+static const char *ak8975_match_acpi_device(struct device *dev,
+ enum asahi_compass_chipset *chipset)
+{
+ const struct acpi_device_id *id;
+
+ id = acpi_match_device(dev->driver->acpi_match_table, dev);
+ if (!id)
+ return NULL;
+ *chipset = (int)id->driver_data;
+
+ return dev_name(dev);
+}
+
+static void ak8975_fill_buffer(struct iio_dev *indio_dev)
+{
+ struct ak8975_data *data = iio_priv(indio_dev);
+ const struct i2c_client *client = data->client;
+ const struct ak_def *def = data->def;
+ int ret;
+ s16 buff[8]; /* 3 x 16 bits axis values + 1 aligned 64 bits timestamp */
+ u64 *tmp;
+
+ mutex_lock(&data->lock);
+
+ ret = ak8975_start_read_axis(data, client);
+ if (ret)
+ goto unlock;
+
+ /*
+ * For each axis, read the flux value from the appropriate register
+ * (the register is specified in the iio device attributes).
+ */
+ ret = i2c_smbus_read_i2c_block_data(client,
+ def->data_regs[0],
+ 3 * sizeof(buff[0]),
+ (u8 *)buff);
+ if (ret < 0)
+ goto unlock;
+
+ mutex_unlock(&data->lock);
+
+ /* Clamp to valid range. */
+ buff[0] = clamp_t(s16, le16_to_cpu(buff[0]), -def->range, def->range);
+ buff[1] = clamp_t(s16, le16_to_cpu(buff[1]), -def->range, def->range);
+ buff[2] = clamp_t(s16, le16_to_cpu(buff[2]), -def->range, def->range);
+
+ tmp = (u64 *)buff;
+ tmp[1] = iio_get_time_ns();
+ iio_push_to_buffers(indio_dev, (void *)buff);
+
+ return;
+
+unlock:
+ mutex_unlock(&data->lock);
+ dev_err(&client->dev, "Error in reading axes block\n");
+}
+
+static irqreturn_t ak8975_handle_trigger(int irq, void *p)
+{
+ const struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+
+ ak8975_fill_buffer(indio_dev);
+ iio_trigger_notify_done(indio_dev->trig);
+ return IRQ_HANDLED;
+}
static int ak8975_probe(struct i2c_client *client,
const struct i2c_device_id *id)
@@ -375,81 +861,139 @@ static int ak8975_probe(struct i2c_client *client,
struct iio_dev *indio_dev;
int eoc_gpio;
int err;
+ const char *name = NULL;
+ enum asahi_compass_chipset chipset = AK_MAX_TYPE;
/* Grab and set up the supplied GPIO. */
- if (client->dev.platform_data == NULL)
- eoc_gpio = -1;
+ if (client->dev.of_node)
+ eoc_gpio = of_get_gpio(client->dev.of_node, 0);
else
- eoc_gpio = *(int *)(client->dev.platform_data);
+ eoc_gpio = -1;
+
+ if (eoc_gpio == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
/* We may not have a GPIO based IRQ to scan, that is fine, we will
poll if so */
if (gpio_is_valid(eoc_gpio)) {
- err = gpio_request_one(eoc_gpio, GPIOF_IN, "ak_8975");
+ err = devm_gpio_request_one(&client->dev, eoc_gpio,
+ GPIOF_IN, "ak_8975");
if (err < 0) {
dev_err(&client->dev,
"failed to request GPIO %d, error %d\n",
eoc_gpio, err);
- goto exit;
+ return err;
}
}
/* Register with IIO */
indio_dev = iio_device_alloc(sizeof(*data));
- if (indio_dev == NULL) {
- err = -ENOMEM;
- goto exit_gpio;
- }
+ if (indio_dev == NULL)
+ return -ENOMEM;
+
data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
+
+ data->client = client;
+ data->eoc_gpio = eoc_gpio;
+ data->eoc_irq = 0;
+
+
+ err = of_property_read_string_array(client->dev.of_node,
+ "mount-matrix", data->orientation.rotation,
+ ARRAY_SIZE(data->orientation.rotation));
+
+ if (err != ARRAY_SIZE(data->orientation.rotation)) {
+ dev_err(&client->dev, "Failed to retrieve mounting matrix %d\n", err);
+ return err;
+ }
+
+ /* id will be NULL when enumerated via ACPI */
+ if (id) {
+ chipset = (enum asahi_compass_chipset)(id->driver_data);
+ name = id->name;
+ } else if (ACPI_HANDLE(&client->dev)) {
+ name = ak8975_match_acpi_device(&client->dev, &chipset);
+ if (!name)
+ return -ENODEV;
+ } else
+ return -ENOSYS;
+
+ if (chipset >= AK_MAX_TYPE) {
+ dev_err(&client->dev, "AKM device type unsupported: %d\n",
+ chipset);
+ return -ENODEV;
+ }
+
+ data->def = &ak_def_array[chipset];
+
+ err = ak8975_power_on(client);
+ if (err)
+ return err;
+
+ err = ak8975_who_i_am(client, data->def->type);
+ if (err < 0) {
+ dev_err(&client->dev, "Unexpected device\n");
+ goto power_off;
+ }
+ dev_dbg(&client->dev, "Asahi compass chip %s\n", name);
+
/* Perform some basic start-of-day setup of the device. */
err = ak8975_setup(client);
if (err < 0) {
- dev_err(&client->dev, "AK8975 initialization fails\n");
- goto exit_free_iio;
+ dev_err(&client->dev, "%s initialization fails\n", name);
+ goto power_off;
}
- data->client = client;
mutex_init(&data->lock);
- data->eoc_gpio = eoc_gpio;
indio_dev->dev.parent = &client->dev;
indio_dev->channels = ak8975_channels;
indio_dev->num_channels = ARRAY_SIZE(ak8975_channels);
indio_dev->info = &ak8975_info;
+ indio_dev->available_scan_masks = ak8975_scan_masks;
indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->name = name;
+
+ err = iio_triggered_buffer_setup(indio_dev, NULL, ak8975_handle_trigger,
+ NULL);
+ if (err) {
+ dev_err(&client->dev, "triggered buffer setup failed\n");
+ goto power_off;
+ }
err = iio_device_register(indio_dev);
- if (err < 0)
- goto exit_free_iio;
+ if (err) {
+ dev_err(&client->dev, "device register failed\n");
+ goto cleanup_buffer;
+ }
return 0;
-exit_free_iio:
- iio_device_free(indio_dev);
-exit_gpio:
- if (gpio_is_valid(eoc_gpio))
- gpio_free(eoc_gpio);
-exit:
+cleanup_buffer:
+ iio_triggered_buffer_cleanup(indio_dev);
+power_off:
+ ak8975_power_off(client);
return err;
}
static int ak8975_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
- struct ak8975_data *data = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
-
- if (gpio_is_valid(data->eoc_gpio))
- gpio_free(data->eoc_gpio);
-
+ iio_triggered_buffer_cleanup(indio_dev);
iio_device_free(indio_dev);
+ ak8975_power_off(client);
return 0;
}
static const struct i2c_device_id ak8975_id[] = {
- {"ak8975", 0},
+ {"ak8975", AK8975},
+ {"ak8963", AK8963},
+ {"AK8963", AK8963},
+ {"ak09911", AK09911},
+ {"ak09912", AK09912},
{}
};
@@ -458,14 +1002,21 @@ MODULE_DEVICE_TABLE(i2c, ak8975_id);
static const struct of_device_id ak8975_of_match[] = {
{ .compatible = "asahi-kasei,ak8975", },
{ .compatible = "ak8975", },
- { }
+ { .compatible = "asahi-kasei,ak8963", },
+ { .compatible = "ak8963", },
+ { .compatible = "asahi-kasei,ak09911", },
+ { .compatible = "ak09911", },
+ { .compatible = "asahi-kasei,ak09912", },
+ { .compatible = "ak09912", },
+ {}
};
MODULE_DEVICE_TABLE(of, ak8975_of_match);
static struct i2c_driver ak8975_driver = {
.driver = {
.name = "ak8975",
- .of_match_table = ak8975_of_match,
+ .of_match_table = of_match_ptr(ak8975_of_match),
+ .acpi_match_table = ACPI_PTR(ak_acpi_match),
},
.probe = ak8975_probe,
.remove = ak8975_remove,
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index bb698e1f..5e4807de 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -93,6 +93,18 @@ config INPUT_BMA150
To compile this driver as a module, choose M here: the
module will be called bma150.
+config INPUT_AMBARELLA_IR
+ tristate "Support Ambarella Soc IR"
+ default n
+ help
+ Say Y here if your Ambarella Boards have Keys with IR.
+
+config INPUT_AMBARELLA_ADC
+ tristate "Support Ambarella Soc ADC"
+ default n
+ help
+ Say Y here if your Ambarella Boards have Keys with ADC.
+
config INPUT_PCSPKR
tristate "PC Speaker support"
depends on PCSPKR_PLATFORM
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index d7fc17f1..f05e676e 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -13,6 +13,10 @@ obj-$(CONFIG_INPUT_AD714X_SPI) += ad714x-spi.o
obj-$(CONFIG_INPUT_ADXL34X) += adxl34x.o
obj-$(CONFIG_INPUT_ADXL34X_I2C) += adxl34x-i2c.o
obj-$(CONFIG_INPUT_ADXL34X_SPI) += adxl34x-spi.o
+
+obj-$(CONFIG_INPUT_AMBARELLA_IR) += ambarella_input_ir.o
+obj-$(CONFIG_INPUT_AMBARELLA_ADC) += ambarella_input_adc.o
+
obj-$(CONFIG_INPUT_APANEL) += apanel.o
obj-$(CONFIG_INPUT_ARIZONA_HAPTICS) += arizona-haptics.o
obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o
diff --git a/drivers/input/misc/ambarella_input_adc.c b/drivers/input/misc/ambarella_input_adc.c
new file mode 100644
index 00000000..bd980486
--- /dev/null
+++ b/drivers/input/misc/ambarella_input_adc.c
@@ -0,0 +1,280 @@
+/*
+ * drivers/input/misc/ambarella_input_adc.c
+ *
+ * Author: Qiao Wang <qwang@ambarella.com>
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * @History ::
+ * Date Name Comments
+ * 07/16/2014 Bing-Liang Hu irq or polling depend on adc irq support
+ * 07/21/2014 Cao Rongrong re-design the mechanism with ADC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <plat/adc.h>
+
+struct ambadc_keymap {
+ u32 key_code;
+ u32 channel : 4;
+ u32 low_level : 12;
+ u32 high_level : 12;
+};
+
+struct ambarella_adckey {
+ struct input_dev *input;
+ struct ambadc_client *adc_client;
+
+ struct ambadc_keymap *keymap;
+ u32 key_num;
+ u32 key_saved[ADC_NUM_CHANNELS]; /* save the key currently pressed */
+ u32 print_key : 1;
+};
+
+static void ambarella_adckey_filter_out(struct ambadc_client *client,
+ struct ambadc_keymap *keymap)
+{
+ /* we expect the adc level which is out of current key's range. */
+ ambarella_adc_set_threshold(client,
+ keymap->channel, keymap->low_level, keymap->high_level);
+}
+
+static int ambarella_adckey_callback(struct ambadc_client *client,
+ u32 ch, u32 level)
+{
+ struct ambarella_adckey *adckey;
+ struct ambadc_keymap *keymap;
+ struct input_dev *input;
+ u32 i;
+
+ adckey = dev_get_drvdata(client->dev);
+ if(adckey == NULL)
+ return -EAGAIN;
+
+ keymap = adckey->keymap;
+ input = adckey->input;
+
+ for (i = 0; i < adckey->key_num; i++, keymap++) {
+ if (ch != keymap->channel
+ || level < keymap->low_level
+ || level > keymap->high_level)
+ continue;
+
+ if (adckey->key_saved[ch] == KEY_RESERVED
+ && keymap->key_code != KEY_RESERVED) {
+ input_report_key(input, keymap->key_code, 1);
+ input_sync(input);
+ adckey->key_saved[ch] = keymap->key_code;
+ ambarella_adckey_filter_out(client, keymap);
+
+ if (adckey->print_key) {
+ dev_info(&input->dev, "key[%d:%d] pressed %d\n",
+ ch, adckey->key_saved[ch], level);
+ }
+ break;
+ } else if (adckey->key_saved[ch] != KEY_RESERVED
+ && keymap->key_code == KEY_RESERVED) {
+ input_report_key(input, adckey->key_saved[ch], 0);
+ input_sync(input);
+ adckey->key_saved[ch] = KEY_RESERVED;
+ ambarella_adckey_filter_out(client, keymap);
+
+ if (adckey->print_key) {
+ dev_info(&input->dev, "key[%d:%d] released %d\n",
+ ch, adckey->key_saved[ch], level);
+ }
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int ambarella_adckey_of_parse(struct platform_device *pdev,
+ struct ambarella_adckey *adckey)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct ambadc_keymap *keymap;
+ const __be32 *prop;
+ u32 propval, i, size;
+
+ adckey->print_key = !!of_find_property(np, "amb,print-key", NULL);
+
+ prop = of_get_property(np, "amb,keymap", &size);
+ if (!prop || size % (sizeof(__be32) * 2)) {
+ dev_err(&pdev->dev, "Invalid keymap!\n");
+ return -ENOENT;
+ }
+
+ /* cells is 2 for each keymap */
+ size /= sizeof(__be32) * 2;
+ adckey->key_num = size;
+
+ adckey->keymap = devm_kzalloc(&pdev->dev,
+ sizeof(struct ambadc_keymap) * size, GFP_KERNEL);
+ if (adckey->keymap == NULL){
+ dev_err(&pdev->dev, "No memory for keymap!\n");
+ return -ENOMEM;
+ }
+
+ keymap = adckey->keymap;
+
+ for (i = 0; i < adckey->key_num; i++, keymap++) {
+ propval = be32_to_cpup(prop + i * 2);
+ keymap->low_level = propval & 0xfff;
+ keymap->high_level = (propval >> 16) & 0xfff;
+ keymap->channel = propval >> 28;
+ if (keymap->channel >= ADC_NUM_CHANNELS) {
+ dev_err(&pdev->dev, "Invalid channel: %d\n", keymap->channel);
+ return -EINVAL;
+ }
+
+ propval = be32_to_cpup(prop + i * 2 + 1);
+ keymap->key_code = propval;
+
+ if (keymap->key_code == KEY_RESERVED)
+ ambarella_adckey_filter_out(adckey->adc_client, keymap);
+
+ input_set_capability(adckey->input, EV_KEY, keymap->key_code);
+ }
+
+ for (i = 0; i < ADC_NUM_CHANNELS; i++)
+ adckey->key_saved[i] = KEY_RESERVED;
+
+ return 0;
+}
+
+static int ambarella_adckey_probe(struct platform_device *pdev)
+{
+ struct ambarella_adckey *adckey;
+ struct input_dev *input;
+ int rval = 0;
+
+ adckey = devm_kzalloc(&pdev->dev,
+ sizeof(struct ambarella_adckey),
+ GFP_KERNEL);
+ if (!adckey) {
+ dev_err(&pdev->dev, "Failed to allocate adckey!\n");
+ return -ENOMEM;
+ }
+
+ input = input_allocate_device();
+ if (!input) {
+ dev_err(&pdev->dev, "input_allocate_device fail!\n");
+ return -ENOMEM;
+ }
+
+ input->name = "AmbADCkey";
+ input->phys = "ambadckey/input0";
+ input->id.bustype = BUS_HOST;
+ input->dev.parent = &pdev->dev;
+
+ rval = input_register_device(input);
+ if (rval < 0) {
+ dev_err(&pdev->dev, "Register input_dev failed!\n");
+ goto adckey_probe_err0;
+ }
+
+ adckey->input = input;
+
+ adckey->adc_client = ambarella_adc_register_client(&pdev->dev,
+ AMBADC_CONTINUOUS,
+ ambarella_adckey_callback);
+ if (!adckey->adc_client) {
+ dev_err(&pdev->dev, "Register adc client failed!\n");
+ goto adckey_probe_err1;
+ }
+
+ rval = ambarella_adckey_of_parse(pdev, adckey);
+ if (rval < 0)
+ goto adckey_probe_err2;
+
+ platform_set_drvdata(pdev, adckey);
+
+ dev_info(&pdev->dev, "ADC key input driver probed!\n");
+
+ return 0;
+
+adckey_probe_err2:
+ ambarella_adc_unregister_client(adckey->adc_client);
+adckey_probe_err1:
+ input_unregister_device(adckey->input);
+adckey_probe_err0:
+ input_free_device(input);
+ return rval;
+}
+
+static int ambarella_adckey_remove(struct platform_device *pdev)
+{
+ struct ambarella_adckey *adckey;
+ int rval = 0;
+
+ adckey = platform_get_drvdata(pdev);
+
+ ambarella_adc_unregister_client(adckey->adc_client);
+ input_unregister_device(adckey->input);
+ input_free_device(adckey->input);
+
+ dev_info(&pdev->dev, "Remove Ambarella ADC Key driver.\n");
+
+ return rval;
+}
+
+#ifdef CONFIG_PM
+static int ambarella_adckey_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ return 0;
+}
+
+static int ambarella_adckey_resume(struct platform_device *pdev)
+{
+ return 0;
+}
+#endif
+
+static const struct of_device_id ambarella_adckey_dt_ids[] = {
+ {.compatible = "ambarella,input_adckey", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ambarella_adckey_dt_ids);
+
+static struct platform_driver ambarella_adckey_driver = {
+ .probe = ambarella_adckey_probe,
+ .remove = ambarella_adckey_remove,
+#ifdef CONFIG_PM
+ .suspend = ambarella_adckey_suspend,
+ .resume = ambarella_adckey_resume,
+#endif
+ .driver = {
+ .name = "ambarella-adckey",
+ .owner = THIS_MODULE,
+ .of_match_table = ambarella_adckey_dt_ids,
+ },
+};
+
+module_platform_driver(ambarella_adckey_driver);
+
+MODULE_AUTHOR("Bing-Liang Hu <blhu@ambarella.com>");
+MODULE_DESCRIPTION("Ambarella ADC key Driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/input/misc/ambarella_input_ir.c b/drivers/input/misc/ambarella_input_ir.c
new file mode 100644
index 00000000..966090cc
--- /dev/null
+++ b/drivers/input/misc/ambarella_input_ir.c
@@ -0,0 +1,504 @@
+/*
+ * drivers/input/misc/ambarella_input_ir.c
+ *
+ * Author: Qiao Wang <qwang@ambarella.com>
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <plat/ir.h>
+
+#define MAX_IR_BUFFER 512
+#define HW_FIFO_BUFFER 48
+
+struct ambarella_ir_keymap {
+ u32 key_code;
+ u32 key_raw;
+};
+
+struct ambarella_ir_frame_info {
+ u32 frame_head_size;
+ u32 frame_data_size;
+ u32 frame_end_size;
+ u32 frame_repeat_head_size;
+};
+
+struct ambarella_ir_info {
+ struct input_dev *input;
+ unsigned char __iomem *regbase;
+ unsigned int irq;
+
+ int (*ir_parse)(struct ambarella_ir_info *pirinfo, u32 *uid);
+ int ir_pread;
+ int ir_pwrite;
+ u16 tick_buf[MAX_IR_BUFFER];
+ struct ambarella_ir_frame_info frame_info;
+ u32 frame_data_to_received;
+
+
+ struct ambarella_ir_keymap *keymap;
+ u32 key_num;
+
+ u32 protocol;
+ u32 print_key : 1;
+};
+
+/* ========================================================================= */
+static u16 ambarella_ir_read_data(
+ struct ambarella_ir_info *pirinfo, int pointer)
+{
+ BUG_ON(pointer < 0);
+ BUG_ON(pointer >= MAX_IR_BUFFER);
+ BUG_ON(pointer == pirinfo->ir_pwrite);
+
+ return pirinfo->tick_buf[pointer];
+}
+
+static int ambarella_ir_get_tick_size(struct ambarella_ir_info *pirinfo)
+{
+ int size = 0;
+
+ if (pirinfo->ir_pread > pirinfo->ir_pwrite)
+ size = MAX_IR_BUFFER - pirinfo->ir_pread + pirinfo->ir_pwrite;
+ else
+ size = pirinfo->ir_pwrite - pirinfo->ir_pread;
+
+ return size;
+}
+
+void ambarella_ir_inc_read_ptr(struct ambarella_ir_info *pirinfo)
+{
+ BUG_ON(pirinfo->ir_pread == pirinfo->ir_pwrite);
+
+ pirinfo->ir_pread++;
+ if (pirinfo->ir_pread >= MAX_IR_BUFFER)
+ pirinfo->ir_pread = 0;
+}
+
+void ambarella_ir_move_read_ptr(struct ambarella_ir_info *pirinfo, int offset)
+{
+ for (; offset > 0; offset--) {
+ ambarella_ir_inc_read_ptr(pirinfo);
+ }
+}
+
+/* ========================================================================= */
+#include "ambarella_ir_nec.c"
+#include "ambarella_ir_sony.c"
+#include "ambarella_ir_philips.c"
+#include "ambarella_ir_panasonic.c"
+
+/* ========================================================================= */
+static int ambarella_input_report_ir(struct ambarella_ir_info *pirinfo, u32 uid)
+{
+ struct ambarella_ir_keymap *keymap = pirinfo->keymap;
+ struct input_dev *input = pirinfo->input;
+ int i;
+
+ for (i = 0; i < pirinfo->key_num; i++, keymap++) {
+ if (keymap->key_raw == uid) {
+ input_report_key(input, keymap->key_code, 1);
+ input_sync(input);
+ input_report_key(input, keymap->key_code, 0);
+ input_sync(input);
+ if(pirinfo->print_key)
+ dev_info(&input->dev, "IR_KEY [%d]\n", keymap->key_code);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static inline void ambarella_ir_write_data(struct ambarella_ir_info *pirinfo,
+ u16 val)
+{
+ BUG_ON(pirinfo->ir_pwrite < 0);
+ BUG_ON(pirinfo->ir_pwrite >= MAX_IR_BUFFER);
+
+ pirinfo->tick_buf[pirinfo->ir_pwrite] = val;
+
+ pirinfo->ir_pwrite++;
+
+ if (pirinfo->ir_pwrite >= MAX_IR_BUFFER)
+ pirinfo->ir_pwrite = 0;
+}
+
+static inline int ambarella_ir_update_buffer(struct ambarella_ir_info *pirinfo)
+{
+ int count;
+ int size;
+
+ count = amba_readl(pirinfo->regbase + IR_STATUS_OFFSET);
+ dev_dbg(&pirinfo->input->dev, "size we got is [%d]\n", count);
+ for (; count > 0; count--) {
+ ambarella_ir_write_data(pirinfo,
+ amba_readl(pirinfo->regbase + IR_DATA_OFFSET));
+ }
+ size = ambarella_ir_get_tick_size(pirinfo);
+
+ return size;
+}
+
+static irqreturn_t ambarella_ir_irq(int irq, void *devid)
+{
+ struct ambarella_ir_info *pirinfo;
+ u32 ctrl_val, uid, edges;
+ int rval;
+
+ pirinfo = (struct ambarella_ir_info *)devid;
+
+ BUG_ON(pirinfo->ir_pread < 0);
+ BUG_ON(pirinfo->ir_pread >= MAX_IR_BUFFER);
+
+ ctrl_val = amba_readl(pirinfo->regbase + IR_CONTROL_OFFSET);
+ if (ctrl_val & IR_CONTROL_FIFO_OV) {
+ while (amba_readl(pirinfo->regbase + IR_STATUS_OFFSET) > 0)
+ amba_readl(pirinfo->regbase + IR_DATA_OFFSET);
+
+ amba_setbitsl(pirinfo->regbase + IR_CONTROL_OFFSET,
+ IR_CONTROL_FIFO_OV);
+
+ dev_err(&pirinfo->input->dev,
+ "IR_CONTROL_FIFO_OV overflow\n");
+
+ goto ambarella_ir_irq_exit;
+ }
+
+ ambarella_ir_update_buffer(pirinfo);
+
+ if(!pirinfo->ir_parse)
+ goto ambarella_ir_irq_exit;
+
+ rval = pirinfo->ir_parse(pirinfo, &uid);
+
+ if (rval == 0) {
+ /* yes, we find the key */
+ if(pirinfo->print_key)
+ dev_info(&pirinfo->input->dev, "uid = 0x%08x\n", uid);
+ ambarella_input_report_ir(pirinfo, uid);
+ }
+
+ pirinfo->frame_data_to_received = pirinfo->frame_info.frame_data_size +
+ pirinfo->frame_info.frame_head_size;
+ pirinfo->frame_data_to_received -= ambarella_ir_get_tick_size(pirinfo);
+
+ if (pirinfo->frame_data_to_received <= HW_FIFO_BUFFER) {
+ edges = pirinfo->frame_data_to_received;
+ pirinfo->frame_data_to_received = 0;
+ } else {// > HW_FIFO_BUFFER
+ edges = HW_FIFO_BUFFER;
+ pirinfo->frame_data_to_received -= HW_FIFO_BUFFER;
+ }
+
+ dev_dbg(&pirinfo->input->dev,
+ "line[%d],frame_data_to_received[%d]\n", __LINE__, edges);
+ amba_clrbitsl(pirinfo->regbase + IR_CONTROL_OFFSET,
+ IR_CONTROL_INTLEV(0x3F));
+ amba_setbitsl(pirinfo->regbase + IR_CONTROL_OFFSET,
+ IR_CONTROL_INTLEV(edges));
+
+ambarella_ir_irq_exit:
+ amba_writel(pirinfo->regbase + IR_CONTROL_OFFSET,
+ (amba_readl(pirinfo->regbase + IR_CONTROL_OFFSET) |
+ IR_CONTROL_LEVINT));
+
+ return IRQ_HANDLED;
+}
+
+void ambarella_ir_enable(struct ambarella_ir_info *pirinfo)
+{
+ u32 edges;
+
+ pirinfo->frame_data_to_received = pirinfo->frame_info.frame_head_size
+ + pirinfo->frame_info.frame_data_size;
+
+ BUG_ON(pirinfo->frame_data_to_received > MAX_IR_BUFFER);
+
+ if (pirinfo->frame_data_to_received > HW_FIFO_BUFFER) {
+ edges = HW_FIFO_BUFFER;
+ pirinfo->frame_data_to_received -= HW_FIFO_BUFFER;
+ } else {
+ edges = pirinfo->frame_data_to_received;
+ pirinfo->frame_data_to_received = 0;
+ }
+ amba_writel(pirinfo->regbase + IR_CONTROL_OFFSET, IR_CONTROL_RESET);
+ amba_setbitsl(pirinfo->regbase + IR_CONTROL_OFFSET,
+ IR_CONTROL_ENB | IR_CONTROL_INTLEV(edges) | IR_CONTROL_INTENB);
+
+ enable_irq(pirinfo->irq);
+}
+
+void ambarella_ir_disable(struct ambarella_ir_info *pirinfo)
+{
+ disable_irq(pirinfo->irq);
+}
+
+void ambarella_ir_set_protocol(struct ambarella_ir_info *pirinfo,
+ enum ambarella_ir_protocol protocol_id)
+{
+ memset(pirinfo->tick_buf, 0x0, sizeof(pirinfo->tick_buf));
+ pirinfo->ir_pread = 0;
+ pirinfo->ir_pwrite = 0;
+
+ switch (protocol_id) {
+ case AMBA_IR_PROTOCOL_NEC:
+ dev_notice(&pirinfo->input->dev,
+ "Protocol NEC[%d]\n", protocol_id);
+ pirinfo->ir_parse = ambarella_ir_nec_parse;
+ ambarella_ir_get_nec_info(&pirinfo->frame_info);
+ break;
+ case AMBA_IR_PROTOCOL_PANASONIC:
+ dev_notice(&pirinfo->input->dev,
+ "Protocol PANASONIC[%d]\n", protocol_id);
+ pirinfo->ir_parse = ambarella_ir_panasonic_parse;
+ ambarella_ir_get_panasonic_info(&pirinfo->frame_info);
+ break;
+ case AMBA_IR_PROTOCOL_SONY:
+ dev_notice(&pirinfo->input->dev,
+ "Protocol SONY[%d]\n", protocol_id);
+ pirinfo->ir_parse = ambarella_ir_sony_parse;
+ ambarella_ir_get_sony_info(&pirinfo->frame_info);
+ break;
+ case AMBA_IR_PROTOCOL_PHILIPS:
+ dev_notice(&pirinfo->input->dev,
+ "Protocol PHILIPS[%d]\n", protocol_id);
+ pirinfo->ir_parse = ambarella_ir_philips_parse;
+ ambarella_ir_get_philips_info(&pirinfo->frame_info);
+ break;
+ default:
+ dev_notice(&pirinfo->input->dev,
+ "Protocol default NEC[%d]\n", protocol_id);
+ pirinfo->ir_parse = ambarella_ir_nec_parse;
+ ambarella_ir_get_nec_info(&pirinfo->frame_info);
+ break;
+ }
+}
+
+static void ambarella_ir_init(struct ambarella_ir_info *pirinfo)
+{
+ ambarella_ir_disable(pirinfo);
+
+ clk_set_rate(clk_get(NULL, "gclk_ir"), 13000);
+
+ ambarella_ir_set_protocol(pirinfo, pirinfo->protocol);
+
+ ambarella_ir_enable(pirinfo);
+}
+
+static int ambarella_ir_of_parse(struct platform_device *pdev,
+ struct ambarella_ir_info *pirinfo)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct ambarella_ir_keymap *keymap;
+ const __be32 *prop;
+ int rval, i, size;
+
+ rval = of_property_read_u32(np, "amb,protocol", &pirinfo->protocol);
+ if (rval < 0 || pirinfo->protocol >= AMBA_IR_PROTOCOL_END)
+ pirinfo->protocol = AMBA_IR_PROTOCOL_NEC;
+
+ pirinfo->print_key = !!of_find_property(np, "amb,print-key", NULL);
+
+ prop = of_get_property(np, "amb,keymap", &size);
+ if (!prop || size % (sizeof(__be32) * 2)) {
+ dev_err(&pdev->dev, "Invalid keymap!\n");
+ return -ENOENT;
+ }
+
+ /* cells is 2 for each keymap */
+ size /= sizeof(__be32) * 2;
+
+ pirinfo->key_num = size;
+ pirinfo->keymap = devm_kzalloc(&pdev->dev,
+ sizeof(struct ambarella_ir_keymap) * size, GFP_KERNEL);
+ if (pirinfo->keymap == NULL){
+ dev_err(&pdev->dev, "No memory!\n");
+ return -ENOMEM;
+ }
+
+ keymap = pirinfo->keymap;
+ for (i = 0; i < size; i++) {
+ keymap->key_raw = be32_to_cpup(prop + i * 2);
+ keymap->key_code = be32_to_cpup(prop + i * 2 + 1);
+ input_set_capability(pirinfo->input, EV_KEY, keymap->key_code);
+ keymap++;
+ }
+
+ return 0;
+}
+
+static int ambarella_ir_probe(struct platform_device *pdev)
+{
+ struct ambarella_ir_info *pirinfo;
+ struct input_dev *input;
+ struct resource *mem;
+ int retval;
+
+ pirinfo = devm_kzalloc(&pdev->dev,
+ sizeof(struct ambarella_ir_info), GFP_KERNEL);
+ if (!pirinfo) {
+ dev_err(&pdev->dev, "Failed to allocate pirinfo!\n");
+ return -ENOMEM;
+ }
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (mem == NULL) {
+ dev_err(&pdev->dev, "Get mem resource failed!\n");
+ return -ENXIO;
+ }
+
+ pirinfo->regbase = devm_ioremap(&pdev->dev,
+ mem->start, resource_size(mem));
+ if (!pirinfo->regbase) {
+ dev_err(&pdev->dev, "devm_ioremap() failed\n");
+ return -ENOMEM;
+ }
+
+ pirinfo->irq = platform_get_irq(pdev, 0);
+ if (pirinfo->irq < 0) {
+ dev_err(&pdev->dev, "Get irq failed!\n");
+ return -ENXIO;
+ }
+
+ input = input_allocate_device();
+ if (!input) {
+ dev_err(&pdev->dev, "input_allocate_device fail!\n");
+ return -ENOMEM;
+ }
+
+ input->name = "AmbIR";
+ input->phys = "ambir/input0";
+ input->id.bustype = BUS_HOST;
+
+ retval = input_register_device(input);
+ if (retval) {
+ dev_err(&pdev->dev, "Register input_dev failed!\n");
+ goto ir_err0;
+ }
+
+ pirinfo->input = input;
+
+ retval = ambarella_ir_of_parse(pdev, pirinfo);
+ if (retval)
+ goto ir_err1;
+
+ platform_set_drvdata(pdev, pirinfo);
+
+ retval = devm_request_irq(&pdev->dev, pirinfo->irq,
+ ambarella_ir_irq, IRQF_TRIGGER_HIGH,
+ dev_name(&pdev->dev), pirinfo);
+ if (retval < 0) {
+ dev_err(&pdev->dev, "Request IRQ failed!\n");
+ goto ir_err1;
+ }
+
+ ambarella_ir_init(pirinfo);
+
+ dev_notice(&pdev->dev, "IR Host Controller probed!\n");
+
+ return 0;
+
+ir_err1:
+ input_unregister_device(input);
+ir_err0:
+ input_free_device(input);
+ return retval;
+}
+
+static int ambarella_ir_remove(struct platform_device *pdev)
+{
+ struct ambarella_ir_info *pirinfo;
+ int retval = 0;
+
+ pirinfo = platform_get_drvdata(pdev);
+
+ input_unregister_device(pirinfo->input);
+ input_free_device(pirinfo->input);
+
+ dev_notice(&pdev->dev, "Remove Ambarella IR Host Controller.\n");
+
+ return retval;
+}
+
+#if (defined CONFIG_PM)
+static int ambarella_ir_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ int retval = 0;
+ struct ambarella_ir_info *pirinfo;
+
+ pirinfo = platform_get_drvdata(pdev);
+
+ disable_irq(pirinfo->irq);
+ amba_clrbitsl(pirinfo->regbase + IR_CONTROL_OFFSET, IR_CONTROL_INTENB);
+
+ dev_dbg(&pdev->dev, "%s exit with %d @ %d\n",
+ __func__, retval, state.event);
+ return retval;
+}
+
+static int ambarella_ir_resume(struct platform_device *pdev)
+{
+ int retval = 0;
+ struct ambarella_ir_info *pirinfo;
+
+ pirinfo = platform_get_drvdata(pdev);
+
+ clk_set_rate(clk_get(NULL, "gclk_ir"), 13000);
+ ambarella_ir_enable(pirinfo);
+
+ dev_dbg(&pdev->dev, "%s exit with %d\n", __func__, retval);
+
+ return retval;
+}
+#endif
+
+static const struct of_device_id ambarella_ir_dt_ids[] = {
+ {.compatible = "ambarella,ir", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ambarella_ir_dt_ids);
+
+static struct platform_driver ambarella_ir_driver = {
+ .probe = ambarella_ir_probe,
+ .remove = ambarella_ir_remove,
+#if (defined CONFIG_PM)
+ .suspend = ambarella_ir_suspend,
+ .resume = ambarella_ir_resume,
+#endif
+ .driver = {
+ .name = "ambarella-ir",
+ .owner = THIS_MODULE,
+ .of_match_table = ambarella_ir_dt_ids,
+ },
+};
+
+module_platform_driver(ambarella_ir_driver);
+
+MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
+MODULE_DESCRIPTION("Ambarella IR Input Driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/input/misc/ambarella_ir_nec.c b/drivers/input/misc/ambarella_ir_nec.c
new file mode 100644
index 00000000..937c7b97
--- /dev/null
+++ b/drivers/input/misc/ambarella_ir_nec.c
@@ -0,0 +1,338 @@
+/*
+ * drivers/input/misc/ambarella_ir_nec.c
+ *
+ * History:
+ * 2007/03/28 - [Dragon Chiang] created file
+ * 2009/03/10 - [Anthony Ginger] Port to 2.6.28
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+
+/**
+ * Pulse-Width-Coded Signals vary the length of pulses to code the information.
+ * In this case if the pulse width is short (approximately 550us) it
+ * corresponds to a logical zero or a low. If the pulse width is long
+ * (approximately 2200us) it corresponds to a logical one or a high.
+ *
+ * +--+ +--+ +----+ +----+
+ * | | | | | | | |
+ * ---+ +--+ +--+ +--+ +---
+ * 0 0 1 1
+ */
+
+/* NEC - APEX - HITACHI - PIONEER */
+#define NEC_DEFAULT_FREQUENCY 36000 /* 36KHz */
+#define NEC_DEFAULT_SMALLER_TIME 560 /* T, 560 microseconds. */
+
+/** bit 0 [1120us]
+ * ---+ +----+
+ * | | |
+ * +----+ +---
+ * -T +T
+ */
+
+/** bit 1 [2240us]
+ * ---+ +------------+
+ * | | |
+ * +----+ +---
+ * -T +3T
+ */
+
+/** start [13.3ms]
+ * ---+ +---------------+
+ * | | |
+ * +--------------------------------+ +---
+ * -16T(9ms) +7.5T(4.2ms)
+ */
+
+/** Subsequent Frame [11.3ms]
+ * ---+ +--------+ +---
+ * | | | |
+ * +--------------------------------+ +--+
+ * -16T(9ms) +4T(2.2ms)
+ */
+
+#define NEC_LEADER_LOW_UPBOUND 123 /* default 9ms */
+#define NEC_LEADER_LOW_LOWBOUND 113
+#define NEC_LEADER_HIGH_UPBOUND 63 /* default 4.2ms */
+#define NEC_LEADER_HIGH_LOWBOUND 52
+
+#define SAM_LEADER_LOW_UPBOUND 64 /* default 4.5ms */
+#define SAM_LEADER_LOW_LOWBOUND 50
+#define SAM_LEADER_HIGH_UPBOUND 64 /* default 4.5ms */
+#define SAM_LEADER_HIGH_LOWBOUND 50
+
+#define NEC_REPEAT_LOW_UPBOUND 123 /* default 9ms */
+#define NEC_REPEAT_LOW_LOWBOUND 113
+#define NEC_REPEAT_HIGH_UPBOUND 33 /* default 2.2ms */
+#define NEC_REPEAT_HIGH_LOWBOUND 23
+
+#define NEC_DATA_LOW_UPBOUND 12 /* default 560us */
+#define NEC_DATA_LOW_LOWBOUND 1
+#define NEC_DATA_0_HIGH_UPBOUND 12 /* default 560us */
+#define NEC_DATA_0_HIGH_LOWBOUND 1
+#define NEC_DATA_1_HIGH_UPBOUND 26 /* default 1680us */
+#define NEC_DATA_1_HIGH_LOWBOUND 15
+
+/**
+ * Check the waveform data is leader code or not.
+ */
+static int ambarella_ir_nec_pulse_leader_code(struct ambarella_ir_info *pinfo)
+{
+ int check_sam = 0;
+
+ u16 val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
+
+ if ((val < NEC_LEADER_LOW_UPBOUND) &&
+ (val > NEC_LEADER_LOW_LOWBOUND)) {
+ } else {
+ if ((val < SAM_LEADER_LOW_UPBOUND) &&
+ (val > SAM_LEADER_LOW_LOWBOUND)) {
+ check_sam = 1;
+ } else {
+ return 0;
+ }
+ }
+
+ if ((pinfo->ir_pread + 1) >= MAX_IR_BUFFER) {
+ val = ambarella_ir_read_data(pinfo, 0);
+ } else {
+ val = ambarella_ir_read_data(pinfo, pinfo->ir_pread + 1);
+ }
+
+ if (check_sam) {
+ if ((val < SAM_LEADER_HIGH_UPBOUND) &&
+ (val > SAM_LEADER_HIGH_LOWBOUND) )
+ return 1;
+ else
+ return 0;
+ } else {
+ if ((val < NEC_LEADER_HIGH_UPBOUND) &&
+ (val > NEC_LEADER_HIGH_LOWBOUND) )
+ return 1;
+ else
+ return 0;
+ }
+}
+
+static int ambarella_ir_nec_find_head(struct ambarella_ir_info *pinfo)
+{
+ int i, val = 0;
+
+ i = ambarella_ir_get_tick_size(pinfo) - pinfo->frame_info.frame_head_size + 1;
+
+ while(i--) {
+ if(ambarella_ir_nec_pulse_leader_code(pinfo)) {
+ dev_dbg(&pinfo->input->dev, "find leader code, i [%d]\n", i);
+ val = 1;
+ break;
+ } else {
+ dev_dbg(&pinfo->input->dev, "didn't find leader code, i [%d]\n", i);
+ ambarella_ir_move_read_ptr(pinfo, 1);
+ }
+ }
+
+ return val ;
+}
+/**
+ * Check the waveform data is subsequent code or not.
+ */
+static int ambarella_ir_nec_pulse_subsequent_code(struct ambarella_ir_info *pinfo)
+{
+ u16 val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
+
+ if ((val < NEC_REPEAT_LOW_UPBOUND) &&
+ (val > NEC_REPEAT_LOW_LOWBOUND)) {
+ } else {
+ return 0;
+ }
+
+ if ((pinfo->ir_pread + 1) >= MAX_IR_BUFFER) {
+ val = ambarella_ir_read_data(pinfo, 0);
+ } else {
+ val = ambarella_ir_read_data(pinfo, pinfo->ir_pread + 1);
+ }
+
+ if ((val < NEC_REPEAT_HIGH_UPBOUND) &&
+ (val > NEC_REPEAT_HIGH_LOWBOUND) )
+ return 1;
+ else
+ return 0;
+}
+
+static int ambarella_ir_nec_find_subsequent(struct ambarella_ir_info *pinfo)
+{
+ int i, val = 0;
+
+ i = ambarella_ir_get_tick_size(pinfo) - pinfo->frame_info.frame_head_size + 1;
+
+ while(i--) {
+ if(ambarella_ir_nec_pulse_subsequent_code(pinfo)) {
+ dev_dbg(&pinfo->input->dev, "find leader code, i [%d]\n", i);
+ val = 1;
+ break;
+ } else {
+ dev_dbg(&pinfo->input->dev, "didn't find leader code, i [%d]\n", i);
+ ambarella_ir_move_read_ptr(pinfo, 1);
+ }
+ }
+
+ return val ;
+}
+
+/**
+ * Check the waveform data is 0 bit or not.
+ */
+static int ambarella_ir_nec_pulse_code_0(struct ambarella_ir_info *pinfo)
+{
+ u16 val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
+ if ((val < NEC_DATA_LOW_UPBOUND) &&
+ (val > NEC_DATA_LOW_LOWBOUND)) {
+ } else {
+ return 0;
+ }
+
+ if ((pinfo->ir_pread + 1) >= MAX_IR_BUFFER) {
+ val = ambarella_ir_read_data(pinfo, 0);
+ } else {
+ val = ambarella_ir_read_data(pinfo, pinfo->ir_pread + 1);
+ }
+
+ if ((val < NEC_DATA_0_HIGH_UPBOUND) &&
+ (val > NEC_DATA_0_HIGH_LOWBOUND) )
+ return 1;
+ else
+ return 0;
+}
+
+/**
+ * Check the waveform data is 1 bit or not.
+ */
+static int ambarella_ir_nec_pulse_code_1(struct ambarella_ir_info *pinfo)
+{
+ u16 val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
+
+ if ((val < NEC_DATA_LOW_UPBOUND) &&
+ (val > NEC_DATA_LOW_LOWBOUND)) {
+ } else {
+ return 0;
+ }
+
+ if ((pinfo->ir_pread + 1) >= MAX_IR_BUFFER) {
+ val = ambarella_ir_read_data(pinfo, 0);
+ } else {
+ val = ambarella_ir_read_data(pinfo, pinfo->ir_pread + 1);
+ }
+
+ if ((val < NEC_DATA_1_HIGH_UPBOUND) &&
+ (val > NEC_DATA_1_HIGH_LOWBOUND) )
+ return 1;
+ else
+ return 0;
+}
+
+static int ambarella_ir_nec_pulse_data_translate(struct ambarella_ir_info *pinfo, u8 * data)
+{
+ int i;
+ *data = 0;
+
+ for (i = 7; i >= 0; i--) {
+ if (ambarella_ir_nec_pulse_code_0(pinfo)) {
+
+ } else if (ambarella_ir_nec_pulse_code_1(pinfo)) {
+ *data |= 1 << i;
+ } else {
+ dev_dbg(&pinfo->input->dev, "%d ERROR, the waveform can't match\n", i);
+ return -1;
+ }
+ ambarella_ir_move_read_ptr(pinfo, 2);
+ }
+
+ return 0;
+}
+
+static int ambarella_ir_nec_pulse_decode(struct ambarella_ir_info *pinfo, u32 *uid)
+{
+ u8 addr = 0, inv_addr = 0, data = 0, inv_data = 0;
+ int rval;
+
+ /* Then follows 32 bits of data, broken down in 4 bytes of 8 bits. */
+
+ /* The first 8 bits is the Address. */
+ rval = ambarella_ir_nec_pulse_data_translate(pinfo, &addr);
+ if (rval < 0)
+ return rval;
+
+ /* The second 8 bits is the Address Complement. */
+ rval = ambarella_ir_nec_pulse_data_translate(pinfo, &inv_addr);
+ if (rval < 0)
+ return rval;
+
+ /* The third 8 bits is the data. */
+ rval = ambarella_ir_nec_pulse_data_translate(pinfo, &data);
+ if (rval < 0)
+ return rval;
+
+ /* The fourth 8 bits is the data Complement. */
+ rval = ambarella_ir_nec_pulse_data_translate(pinfo, &inv_data);
+ if (rval < 0)
+ return rval;
+
+ dev_dbg(&pinfo->input->dev, "addr\tinv_addr\tdata\tinv_data\n");
+ dev_dbg(&pinfo->input->dev, "0x%x\t0x%x\t\t0x%x\t0x%x\n", addr, inv_addr, data, inv_data);
+
+ *uid = (addr << 24) | (inv_addr << 16) | (data << 8) | inv_data;
+
+ return 0;
+}
+
+int ambarella_ir_nec_parse(struct ambarella_ir_info *pinfo, u32 *uid)
+{
+ int rval;
+ int cur_ptr = pinfo->ir_pread;
+
+ if ((ambarella_ir_nec_find_head(pinfo) || (ambarella_ir_nec_find_subsequent(pinfo)))
+ && ambarella_ir_get_tick_size(pinfo) >= pinfo->frame_info.frame_data_size
+ + pinfo->frame_info.frame_head_size) {
+
+ dev_dbg(&pinfo->input->dev, "go to decode statge\n");
+ ambarella_ir_move_read_ptr(pinfo, pinfo->frame_info.frame_head_size);//move ptr to data
+ rval = ambarella_ir_nec_pulse_decode(pinfo, uid);
+ } else {
+ return -1;
+ }
+
+ if (rval >= 0) {
+ dev_dbg(&pinfo->input->dev, "buffer[%d]-->mornal key\n", cur_ptr);
+ return 0;
+ }
+
+ return (-1);
+}
+
+void ambarella_ir_get_nec_info(struct ambarella_ir_frame_info *pframe_info)
+{
+ pframe_info->frame_head_size = 2;
+ pframe_info->frame_data_size = 64;
+ pframe_info->frame_end_size = 1;
+ pframe_info->frame_repeat_head_size = 4;
+}
+
diff --git a/drivers/input/misc/ambarella_ir_panasonic.c b/drivers/input/misc/ambarella_ir_panasonic.c
new file mode 100644
index 00000000..0a8aa0fa
--- /dev/null
+++ b/drivers/input/misc/ambarella_ir_panasonic.c
@@ -0,0 +1,267 @@
+/*
+ * drivers/input/misc/ambarella_ir_panasonic.c
+ *
+ * History:
+ * 2007/03/28 - [Dragon Chiang] created file
+ * 2009/03/10 - [Anthony Ginger] Port to 2.6.28
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+
+/**
+ * Pulse-Width-Coded Signals vary the length of pulses to code the information.
+ * In this case if the pulse width is short (approximately 550us) it
+ * corresponds to a logical zero or a low. If the pulse width is long
+ * (approximately 2200us) it corresponds to a logical one or a high.
+ *
+ * +--+ +--+ +----+ +----+
+ * | | | | | | | |
+ * ---+ +--+ +--+ +--+ +---
+ * 0 0 1 1
+ */
+
+#define PANASONIC_DEFAULT_FREQUENCY 38000 /* 38KHz */
+
+/* T = 420 <20>gs to approx 424 <20>gs in the USA and Canada */
+/* T = 454 <20>gs to approx 460 <20>gs in Europe and others */
+#define PANASONIC_DEFAULT_SMALLER_TIME 454 /* T, 450 microseconds. */
+
+/** bit 0
+ * +----+ +---
+ * | | |
+ * ---+ +----+
+ * 2T 2T
+ */
+
+/** bit 1
+ * +----+ +---
+ * | | |
+ * ---+ +------------+
+ * 2T 6T
+ */
+
+/** start
+ * +--------------------------------+ +---
+ * | | |
+ * ---+ +----------------+
+ * 16T 8T
+ */
+
+#define PANASONIC_LEADER_HIGH_UPBOUND 50
+#define PANASONIC_LEADER_HIGH_LOWBOUND 42
+#define PANASONIC_LEADER_LOW_UPBOUND 26
+#define PANASONIC_LEADER_LOW_LOWBOUND 18
+
+#define PANASONIC_DATA_HIGH_UPBOUND 9
+#define PANASONIC_DATA_HIGH_LOWBOUND 1
+#define PANASONIC_DATA_0_LOW_UPBOUND 9
+#define PANASONIC_DATA_0_LOW_LOWBOUND 1
+#define PANASONIC_DATA_1_LOW_UPBOUND 20
+#define PANASONIC_DATA_1_LOW_LOWBOUND 12
+
+static int ambarella_ir_panasonic_pulse_leader_code(struct ambarella_ir_info *pinfo)
+{
+ u16 val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
+
+ if ((val < PANASONIC_LEADER_HIGH_UPBOUND) &&
+ (val > PANASONIC_LEADER_HIGH_LOWBOUND)) {
+ } else {
+ return 0;
+ }
+
+ if ((pinfo->ir_pread + 1) >= MAX_IR_BUFFER) {
+ val = ambarella_ir_read_data(pinfo, 0);
+ } else {
+ val = ambarella_ir_read_data(pinfo, pinfo->ir_pread + 1);
+ }
+
+ if ((val < PANASONIC_LEADER_LOW_UPBOUND) &&
+ (val > PANASONIC_LEADER_LOW_LOWBOUND) )
+ return 1;
+ else
+ return 0;
+}
+
+static int ambarella_ir_panasonic_find_head(struct ambarella_ir_info *pinfo)
+{
+ int i, val = 0;
+
+ i = ambarella_ir_get_tick_size(pinfo) - pinfo->frame_info.frame_head_size + 1;
+
+ while(i--) {
+ if(ambarella_ir_panasonic_pulse_leader_code(pinfo)) {
+ dev_dbg(&pinfo->input->dev, "find leader code, i [%d]\n", i);
+ val = 1;
+ break;
+ } else {
+ dev_dbg(&pinfo->input->dev, "didn't find leader code, i [%d]\n", i);
+ ambarella_ir_move_read_ptr(pinfo, 1);
+ }
+ }
+
+ return val ;
+}
+
+static int ambarella_ir_panasonic_pulse_code_0(struct ambarella_ir_info *pinfo)
+{
+ u16 val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
+ if ((val < PANASONIC_DATA_HIGH_UPBOUND) &&
+ (val > PANASONIC_DATA_HIGH_LOWBOUND)) {
+ } else {
+ return 0;
+ }
+
+ if ((pinfo->ir_pread + 1) >= MAX_IR_BUFFER) {
+ val = ambarella_ir_read_data(pinfo, 0);
+ } else {
+ val = ambarella_ir_read_data(pinfo, pinfo->ir_pread + 1);
+ }
+
+ if ((val < PANASONIC_DATA_0_LOW_UPBOUND) &&
+ (val > PANASONIC_DATA_0_LOW_LOWBOUND) )
+ return 1;
+ else
+ return 0;
+}
+
+static int ambarella_ir_panasonic_pulse_code_1(struct ambarella_ir_info *pinfo)
+{
+ u16 val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
+
+ if ((val < PANASONIC_DATA_HIGH_UPBOUND) &&
+ (val > PANASONIC_DATA_HIGH_LOWBOUND)) {
+ } else {
+ return 0;
+ }
+
+ if ((pinfo->ir_pread + 1) >= MAX_IR_BUFFER) {
+ val = ambarella_ir_read_data(pinfo, 0);
+ } else {
+ val = ambarella_ir_read_data(pinfo, pinfo->ir_pread + 1);
+ }
+
+ if ((val < PANASONIC_DATA_1_LOW_UPBOUND) &&
+ (val > PANASONIC_DATA_1_LOW_LOWBOUND) )
+ return 1;
+ else
+ return 0;
+}
+
+static int ambarella_ir_panasonic_pulse_data_translate(struct ambarella_ir_info *pinfo, u8 * data)
+{
+ int i;
+
+ *data = 0;
+
+ for (i = 7; i >= 0; i--) {
+ if (ambarella_ir_panasonic_pulse_code_0(pinfo)) {
+
+ } else if (ambarella_ir_panasonic_pulse_code_1(pinfo)) {
+ *data |= 1 << i;
+ } else {
+ dev_dbg(&pinfo->input->dev, "%d ERROR, the waveform can't match",
+ pinfo->ir_pread);
+ return -1;
+ }
+ ambarella_ir_move_read_ptr(pinfo, 2);
+ }
+
+ return 0;
+}
+
+static int ambarella_ir_panasonic_pulse_decode(struct ambarella_ir_info *pinfo, u32 *uid)
+{
+ u8 addr0 = 0, addr1 = 0, data0 = 0, data1 = 0, data2 = 0, data3 = 0;
+ int rval;
+
+ /* Then follows 22 bits of data, broken down in 4 bytes of 8 bits. */
+
+ /* The first 8 bits is the Address 0. */
+ rval = ambarella_ir_panasonic_pulse_data_translate(pinfo, &addr0);
+ if (rval < 0)
+ return rval;
+
+ /* The second 8 bits is the Address 1. */
+ rval = ambarella_ir_panasonic_pulse_data_translate(pinfo, &addr1);
+ if (rval < 0)
+ return rval;
+
+ /* The third 8 bits is the data 0. */
+ rval = ambarella_ir_panasonic_pulse_data_translate(pinfo, &data0);
+ if (rval < 0)
+ return rval;
+
+ /* The third 8 bits is the data 1. */
+ rval = ambarella_ir_panasonic_pulse_data_translate(pinfo, &data1);
+ if (rval < 0)
+ return rval;
+
+ /* The third 8 bits is the data 2. */
+ rval = ambarella_ir_panasonic_pulse_data_translate(pinfo, &data2);
+ if (rval < 0)
+ return rval;
+
+ /* The third 8 bits is the data 3. */
+ rval = ambarella_ir_panasonic_pulse_data_translate(pinfo, &data3);
+ if (rval < 0)
+ return rval;
+
+ dev_dbg(&pinfo->input->dev, "\taddr0\taddr1\tdata0\tdata1\tdata2\tdata3");
+ dev_dbg(&pinfo->input->dev, "\t0x%x\t0x%x\t0x%x\t0x%x\t0x%x\t0x%x\n",
+ addr0, addr1, data0, data1, data2, data3);
+
+ *uid = (data0 << 24) | (data1 << 16) | (data2 << 8) | data3;
+
+ return 0;
+}
+
+int ambarella_ir_panasonic_parse(struct ambarella_ir_info *pinfo, u32 *uid)
+{
+ int rval;
+ int cur_ptr = pinfo->ir_pread;
+
+ if (ambarella_ir_panasonic_find_head(pinfo)
+ && ambarella_ir_get_tick_size(pinfo) >= pinfo->frame_info.frame_data_size
+ + pinfo->frame_info.frame_head_size) {
+
+ dev_dbg(&pinfo->input->dev, "go to decode statge\n");
+ ambarella_ir_move_read_ptr(pinfo, pinfo->frame_info.frame_head_size);//move ptr to data
+ rval = ambarella_ir_panasonic_pulse_decode(pinfo, uid);
+ } else {
+ return -1;
+ }
+
+ if (rval >= 0) {
+ dev_dbg(&pinfo->input->dev, "buffer[%d]-->mornal key\n", cur_ptr);
+ return 0;
+ }
+
+ return (-1);
+}
+
+void ambarella_ir_get_panasonic_info(struct ambarella_ir_frame_info *pframe_info)
+{
+ pframe_info->frame_head_size = 2;
+ pframe_info->frame_data_size = 96;
+ pframe_info->frame_end_size = 1;
+ pframe_info->frame_repeat_head_size = 0;
+}
+
diff --git a/drivers/input/misc/ambarella_ir_philips.c b/drivers/input/misc/ambarella_ir_philips.c
new file mode 100644
index 00000000..7d8ccbc9
--- /dev/null
+++ b/drivers/input/misc/ambarella_ir_philips.c
@@ -0,0 +1,238 @@
+/*
+ * drivers/input/misc/ambarella_ir_philips.c
+ *
+ * History:
+ * 2007/03/28 - [Dragon Chiang] created file
+ * 2009/03/10 - [Anthony Ginger] Port to 2.6.28
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+
+/**
+ * Shift-Coded Signals (RC-5)vary the order of pulse space to code the
+ * information. In this case if the space width is short (approximately 550us)
+ * and the pulse width is long (approximately 1100us) the signal corresponds to
+ * a logical one or a high. If the space is long and the pulse is short the
+ * signal corresponds to a logical zero or a low.
+ *
+ * | | |
+ * +--| +--|--+ | +---
+ * | | | | | | |
+ * ---+ |--+ | +--|--+
+ * 1 | 1 | 0 | 1
+ */
+
+/* Philips (RC-5) */
+#define PHILIPS_DEFAULT_FREQUENCY 36000 /* 36KHz */
+#define PHILIPS_DEFAULT_SMALLER_TIME 1728 /* T, 1728 microseconds. */
+
+/** | | | | | | | | | | | | | | |
+ * ---+-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +---
+ * | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+ * | +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+
+ * | | | | | | | | | | | | | | |
+ * | AGC |TOG|< address >|< command >|
+ *
+ * | |
+ */
+#define PHILIPS_LEADER_UPBOUND 0xffff /* default don't care */
+#define PHILIPS_LEADER_LOWBOUND 30
+
+#define PHILIPS_SHC_SIG_CYC_UPBOUND 14 /* default 10~ 12 */
+#define PHILIPS_SHC_SIG_CYC_LOWBOUND 8
+
+#define PHILIPS_SHC_DOB_CYC_UPBOUND 25 /* default 12~ 23 */
+#define PHILIPS_SHC_DOB_CYC_LOWBOUND 20
+
+static int ambarella_ir_philips_shift_leader_code(struct ambarella_ir_info *pinfo)
+{
+/** | | |
+ * ---|--------+ +--------+ |
+ * | | | | |
+ * | +--------+ +--------|---
+ * | | |
+ * | AGC |
+ *
+ * Leader | Leader | Leader |
+ */
+ u16 val_1, val_0 = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
+
+#if 0
+ if ((val_0 <= PHILIPS_LEADER_UPBOUND) &&
+ (val_0 > PHILIPS_LEADER_LOWBOUND)) {
+#else
+ if (val_0 > PHILIPS_LEADER_LOWBOUND) {
+#endif
+ } else {
+ return 0;
+ }
+
+ if ((pinfo->ir_pread + 1) >= MAX_IR_BUFFER) {
+ val_0 = ambarella_ir_read_data(pinfo, 0);
+ val_1 = ambarella_ir_read_data(pinfo, 1);
+ } else if ((pinfo->ir_pread + 2) == MAX_IR_BUFFER) {
+ val_0 = ambarella_ir_read_data(pinfo, pinfo->ir_pread + 1);
+ val_1 = ambarella_ir_read_data(pinfo, 0);
+ } else {
+ val_0 = ambarella_ir_read_data(pinfo, pinfo->ir_pread + 1);
+ val_1 = ambarella_ir_read_data(pinfo, pinfo->ir_pread + 2);
+ }
+
+ if ((val_0 < PHILIPS_SHC_SIG_CYC_UPBOUND) &&
+ (val_0 > PHILIPS_SHC_SIG_CYC_LOWBOUND) &&
+ (val_1 < PHILIPS_SHC_SIG_CYC_UPBOUND) &&
+ (val_1 > PHILIPS_SHC_SIG_CYC_LOWBOUND))
+ return 1;
+ else
+ return 0;
+}
+
+static int ambarella_ir_philips_find_head(struct ambarella_ir_info *pinfo)
+{
+ int i, val = 0;
+
+ i = ambarella_ir_get_tick_size(pinfo) - pinfo->frame_info.frame_head_size + 1;
+
+ while(i--) {
+ if(ambarella_ir_philips_shift_leader_code(pinfo)) {
+ dev_dbg(&pinfo->input->dev, "find leader code, i [%d]\n", i);
+ val = 1;
+ break;
+ } else {
+ dev_dbg(&pinfo->input->dev, "didn't find leader code, i [%d]\n", i);
+ ambarella_ir_move_read_ptr(pinfo, 1);
+ }
+ }
+
+ return val ;
+}
+
+static int ambarella_ir_philips_shift_invert_code(struct ambarella_ir_info *pinfo)
+{
+ u16 val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
+
+ if ((val < PHILIPS_SHC_DOB_CYC_UPBOUND) &&
+ (val > PHILIPS_SHC_DOB_CYC_LOWBOUND))
+ return 1;
+ else
+ return 0;
+}
+
+static int ambarella_ir_philips_shift_repeat_code(struct ambarella_ir_info *pinfo)
+{
+ u16 val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
+
+ if ((val < PHILIPS_SHC_SIG_CYC_UPBOUND) &&
+ (val > PHILIPS_SHC_SIG_CYC_LOWBOUND)) {
+ ambarella_ir_inc_read_ptr(pinfo);
+
+ val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
+ if ((val < PHILIPS_SHC_SIG_CYC_UPBOUND) &&
+ (val > PHILIPS_SHC_SIG_CYC_LOWBOUND))
+ return 1;
+ else
+ return 0;
+ } else
+ return 0;
+}
+
+static int ambarella_ir_philips_shift_decode(struct ambarella_ir_info *pinfo, u32 *uid)
+{
+ int i, val = 0;
+ u8 addr = 0, data = 0;
+
+ ambarella_ir_move_read_ptr(pinfo, 3);
+
+ /* Get toggle code and Initialize start value */
+ if (ambarella_ir_philips_shift_invert_code(pinfo))
+ val = 1;
+ else if (ambarella_ir_philips_shift_repeat_code(pinfo))
+ val = 0;
+ else {
+ dev_dbg(&pinfo->input->dev, "Err->toggle code doesn't match");
+ return (-1);
+ }
+
+ dev_dbg(&pinfo->input->dev, "toggle code:%d", val);
+
+ /* address */
+ for (i = 0; i < 5; i++) {
+ if (ambarella_ir_philips_shift_invert_code(pinfo)) {
+ val = 1 - val;
+ } else if (ambarella_ir_philips_shift_repeat_code(pinfo)) {
+ }else {
+ dev_dbg(&pinfo->input->dev, "Err->addr code(%d) doesn't match", i);
+ return (-1);
+ }
+ addr = (addr << 1) | val;
+ ambarella_ir_inc_read_ptr(pinfo);
+ }
+
+ /* data */
+ for (i = 0; i < 6; i++) {
+ if (ambarella_ir_philips_shift_invert_code(pinfo)) {
+ val = 1 - val;
+ } else if (ambarella_ir_philips_shift_repeat_code(pinfo)) {
+ }else {
+ dev_dbg(&pinfo->input->dev, "Err->data code(%d) doesn't match", i);
+ return (-1);
+ }
+ data = (data << 1) | val;
+ ambarella_ir_inc_read_ptr(pinfo);
+ }
+
+ *uid = (addr << 16) | data;
+
+ return 0;
+}
+
+int ambarella_ir_philips_parse(struct ambarella_ir_info *pinfo, u32 *uid)
+{
+ int rval;
+ int cur_ptr = pinfo->ir_pread;
+
+ if (ambarella_ir_philips_find_head(pinfo)
+ && ambarella_ir_get_tick_size(pinfo) >= pinfo->frame_info.frame_data_size
+ + pinfo->frame_info.frame_head_size) {
+
+ dev_dbg(&pinfo->input->dev, "go to decode statge\n");
+ ambarella_ir_move_read_ptr(pinfo, pinfo->frame_info.frame_head_size);//move ptr to data
+ rval = ambarella_ir_philips_shift_decode(pinfo, uid);
+ } else {
+ return -1;
+ }
+
+ if (rval >= 0) {
+ dev_dbg(&pinfo->input->dev, "buffer[%d]-->mornal key\n", cur_ptr);
+ return 0;
+ }
+
+ return (-1);
+}
+
+void ambarella_ir_get_philips_info(struct ambarella_ir_frame_info *pframe_info)
+{
+ pframe_info->frame_head_size = 6;
+ pframe_info->frame_data_size = 22;
+ pframe_info->frame_end_size = 1;
+ pframe_info->frame_repeat_head_size = 0;
+}
+
diff --git a/drivers/input/misc/ambarella_ir_sony.c b/drivers/input/misc/ambarella_ir_sony.c
new file mode 100644
index 00000000..d7b68c48
--- /dev/null
+++ b/drivers/input/misc/ambarella_ir_sony.c
@@ -0,0 +1,256 @@
+/*
+ * drivers/input/misc/ambarella_ir_sony.c
+ *
+ * History:
+ * 2007/03/28 - [Dragon Chiang] created file
+ * 2009/03/10 - [Anthony Ginger] Port to 2.6.28
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+
+/**
+ * Space-Coded Signals (REC-80) vary the length of the spaces between pulses
+ * to code the information. In this case if the space width is short
+ * (approximately 550us) it corresponds to a logical zero or a low. If the
+ * space width is long (approximately 1650us) it corresponds to a logical one
+ * or a high.
+ *
+ * ---+ +--+ +--+ +--+ +---
+ * | | | | | | | |
+ * +--+ +--+ +----+ +----+
+ * 0 0 1 1
+ */
+
+/* Sony 12-bit, 15-bit and 20-bit versions of the protocol exist (12-bit processed here) */
+#define SONY_DEFAULT_FREQUENCY 36000 /* 36KHz */
+#define SONY_DEFAULT_SMALLER_TIME 600 /* T, 600 microseconds. */
+
+/** bit 0 [1200us]
+ * ---+ +----+
+ * | | |
+ * +----+ +---
+ * -T +T
+ */
+
+/** bit 1 [1800us]
+ * ---+ +--------+
+ * | | |
+ * +----+ +---
+ * -T +2T
+ */
+
+/** start [1800us]
+ * +------------------------------+
+ * | |
+ * ------+ +-----------
+ * -3T(1800us)
+ */
+
+/**
+ * If you hold the remote button pressed, the whole transmited frame
+ * repeats every 25ms.
+ */
+
+#define SONY_LEADER_LOW_UPBOUND 33 /* default 1800us */
+#define SONY_LEADER_LOW_LOWBOUND 28
+
+#define SONY_DATA_LOW_UPBOUND 9 /* default 560us */
+#define SONY_DATA_LOW_LOWBOUND 4
+#define SONY_DATA_0_HIGH_UPBOUND 9 /* default 560us */
+#define SONY_DATA_0_HIGH_LOWBOUND 4
+#define SONY_DATA_1_HIGH_UPBOUND 18 /* default 1680us */
+#define SONY_DATA_1_HIGH_LOWBOUND 12
+
+/**
+ * Check the waveform data is leader code or not.
+ */
+static int ambarella_ir_sony_space_leader_code(struct ambarella_ir_info *pinfo)
+{
+ u16 val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
+
+ if ((val < SONY_LEADER_LOW_UPBOUND) &&
+ (val > SONY_LEADER_LOW_LOWBOUND) )
+ return 1; /* leader code */
+ else
+ return 0;
+}
+
+static int ambarella_ir_sony_find_head(struct ambarella_ir_info *pinfo)
+{
+ int i, val = 0;
+
+ i = ambarella_ir_get_tick_size(pinfo) - pinfo->frame_info.frame_head_size + 1;
+
+ while(i--) {
+ if(ambarella_ir_sony_space_leader_code(pinfo)) {
+ dev_dbg(&pinfo->input->dev, "find leader code, i [%d]\n", i);
+ val = 1;
+ break;
+ } else {
+ dev_dbg(&pinfo->input->dev, "didn't find leader code, i [%d]\n", i);
+ ambarella_ir_move_read_ptr(pinfo, 1);
+ }
+ }
+
+ return val ;
+}
+
+/**
+ * Check the waveform data is 0 bit or not.
+ */
+static int ambarella_ir_sony_space_code_0(struct ambarella_ir_info *pinfo)
+{
+ /* 500us of Silence + 700us of IR for bits ZERO, */
+ u16 val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
+
+ if ((val < SONY_DATA_LOW_UPBOUND) &&
+ (val > SONY_DATA_LOW_LOWBOUND)) {
+ } else {
+ return 0;
+ }
+
+ if ((pinfo->ir_pread + 1) >= MAX_IR_BUFFER) {
+ val = ambarella_ir_read_data(pinfo, 0);
+ if ((val < SONY_DATA_0_HIGH_UPBOUND) &&
+ (val > SONY_DATA_0_HIGH_LOWBOUND) )
+ return 1; /* code 0 */
+ else
+ return 0;
+ } else {
+ val = ambarella_ir_read_data(pinfo, pinfo->ir_pread + 1);
+ if ((val < SONY_DATA_0_HIGH_UPBOUND) &&
+ (val > SONY_DATA_0_HIGH_LOWBOUND) )
+ return 1; /* code 0 */
+ else
+ return 0;
+ }
+}
+
+/**
+ * Check the waveform data is 1 bit or not.
+ */
+static int ambarella_ir_sony_space_code_1(struct ambarella_ir_info *pinfo)
+{
+ /* 500us of Silence + 1300us of IR for bits ONE. */
+ u16 val = ambarella_ir_read_data(pinfo, pinfo->ir_pread);
+
+ if ((val < SONY_DATA_LOW_UPBOUND) &&
+ (val > SONY_DATA_LOW_LOWBOUND)) {
+ } else {
+ return 0;
+ }
+
+ if ((pinfo->ir_pread + 1) >= MAX_IR_BUFFER) {
+ val = ambarella_ir_read_data(pinfo, 0);
+ if ((val < SONY_DATA_1_HIGH_UPBOUND) &&
+ (val > SONY_DATA_1_HIGH_LOWBOUND) )
+ return 1; /* code 1 */
+ else
+ return 0;
+ } else {
+ val = ambarella_ir_read_data(pinfo, pinfo->ir_pread + 1);
+ if ((val < SONY_DATA_1_HIGH_UPBOUND) &&
+ (val > SONY_DATA_1_HIGH_LOWBOUND) )
+ return 1; /* code 1 */
+ else
+ return 0;
+ }
+}
+
+/**
+ * Translate waveform data to useful message.
+ */
+static int ambarella_ir_sony_space_decode(struct ambarella_ir_info *pinfo, u32 *uid)
+{
+ /* Following the header you will find straight 12 bits.
+ The first immediate bit after the START is the LSB of the 12 bits.
+ Lets name this first bit as B0, the Last will be B12.
+ B0 to B6 form the 7 bits for the Command Code.
+ B8 to B11 form the 5 bits for the Device Address.
+ */
+
+ int i;
+
+ u8 addr = 0, data = 0;
+
+ /* command - 7 bits*/
+ for (i = 0; i < 7; i++) {
+ if (ambarella_ir_sony_space_code_0(pinfo)) {
+ }
+ else if (ambarella_ir_sony_space_code_1(pinfo)) {
+ data |= 1 << i;
+ }
+ else {
+ dev_dbg(&pinfo->input->dev, "%d ERROR, the waveform can't match", i);
+ }
+ ambarella_ir_move_read_ptr(pinfo, 2);
+ }
+
+ /* device address - 5 bits */
+ for (i = 0; i < 5; i++) {
+ if (ambarella_ir_sony_space_code_0(pinfo)) {
+ }
+ else if (ambarella_ir_sony_space_code_1(pinfo)) {
+ addr |= 1 << i;
+ }
+ else {
+ dev_dbg(&pinfo->input->dev, "%d ERROR, the waveform can't match", i);
+ }
+ ambarella_ir_move_read_ptr(pinfo, 2);
+ }
+
+ *uid = (addr << 16) | data;
+
+ return 0;
+}
+
+int ambarella_ir_sony_parse(struct ambarella_ir_info *pinfo, u32 *uid)
+{
+ int rval;
+ int cur_ptr = pinfo->ir_pread;
+
+ if (ambarella_ir_sony_find_head(pinfo)
+ && ambarella_ir_get_tick_size(pinfo) >= pinfo->frame_info.frame_data_size
+ + pinfo->frame_info.frame_head_size) {
+
+ dev_dbg(&pinfo->input->dev, "go to decode statge\n");
+ ambarella_ir_move_read_ptr(pinfo, pinfo->frame_info.frame_head_size);//move ptr to data
+ rval = ambarella_ir_sony_space_decode(pinfo, uid);
+ } else {
+ return -1;
+ }
+
+ if (rval >= 0) {
+ dev_dbg(&pinfo->input->dev, "buffer[%d]-->mornal key\n", cur_ptr);
+ return 0;
+ }
+
+ return (-1);
+}
+
+void ambarella_ir_get_sony_info(struct ambarella_ir_frame_info *pframe_info)
+{
+ pframe_info->frame_head_size = 1;
+ pframe_info->frame_data_size = 24;
+ pframe_info->frame_end_size = 1;
+ pframe_info->frame_repeat_head_size = 0;
+}
+
diff --git a/drivers/input/misc/wm831x-on.c b/drivers/input/misc/wm831x-on.c
index caa2c406..702c88d6 100644
--- a/drivers/input/misc/wm831x-on.c
+++ b/drivers/input/misc/wm831x-on.c
@@ -40,16 +40,19 @@ struct wm831x_on {
*/
static void wm831x_poll_on(struct work_struct *work)
{
- struct wm831x_on *wm831x_on = container_of(work, struct wm831x_on,
- work.work);
- struct wm831x *wm831x = wm831x_on->wm831x;
- int poll, ret;
+ int ret;
+ struct wm831x_on *wm831x_on;
+ struct wm831x *wm831x;
+ int key;
+ int poll = 0;
+
+ wm831x_on = container_of(work, struct wm831x_on, work.work);
+ wm831x = wm831x_on->wm831x;
ret = wm831x_reg_read(wm831x, WM831X_ON_PIN_CONTROL);
if (ret >= 0) {
- poll = !(ret & WM831X_ON_PIN_STS);
-
- input_report_key(wm831x_on->dev, KEY_POWER, poll);
+ key = !(ret & WM831X_ON_PIN_STS);
+ input_report_key(wm831x_on->dev, KEY_POWER, key);
input_sync(wm831x_on->dev);
} else {
dev_err(wm831x->dev, "Failed to read ON status: %d\n", ret);
@@ -57,7 +60,7 @@ static void wm831x_poll_on(struct work_struct *work)
}
if (poll)
- schedule_delayed_work(&wm831x_on->work, 100);
+ schedule_delayed_work(&wm831x_on->work, HZ / 10);
}
static irqreturn_t wm831x_on_irq(int irq, void *data)
@@ -100,8 +103,8 @@ static int wm831x_on_probe(struct platform_device *pdev)
wm831x_on->dev->dev.parent = &pdev->dev;
ret = request_threaded_irq(irq, NULL, wm831x_on_irq,
- IRQF_TRIGGER_RISING, "wm831x_on",
- wm831x_on);
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "wm831x_on", wm831x_on);
if (ret < 0) {
dev_err(&pdev->dev, "Unable to request IRQ: %d\n", ret);
goto err_input_dev;
@@ -125,8 +128,11 @@ err:
static int wm831x_on_remove(struct platform_device *pdev)
{
- struct wm831x_on *wm831x_on = platform_get_drvdata(pdev);
- int irq = platform_get_irq(pdev, 0);
+ struct wm831x_on *wm831x_on;
+ int irq;
+
+ wm831x_on = platform_get_drvdata(pdev);
+ irq = platform_get_irq(pdev, 0);
free_irq(irq, wm831x_on);
cancel_delayed_work_sync(&wm831x_on->work);
@@ -134,9 +140,53 @@ static int wm831x_on_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_PM
+static int wm831x_on_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct wm831x_on *wm831x_on;
+ int irq;
+
+ wm831x_on = platform_get_drvdata(pdev);
+ irq = platform_get_irq(pdev, 0);
+
+ disable_irq(irq);
+ cancel_delayed_work_sync(&wm831x_on->work);
+
+ return 0;
+}
+
+static int wm831x_on_resume(struct platform_device *pdev)
+{
+ struct wm831x_on *wm831x_on;
+ struct wm831x *wm831x;
+ int irq;
+ int ret;
+
+ wm831x_on = platform_get_drvdata(pdev);
+ irq = platform_get_irq(pdev, 0);
+
+ wm831x = wm831x_on->wm831x;
+
+ //TBD: Check resumed form self-referesh.
+ ret = wm831x_reg_read(wm831x, WM831X_ON_SOURCE);
+ if (ret & WM831X_ON_SOURCE_ON_PIN) {
+ input_report_key(wm831x_on->dev, KEY_POWER, 1);
+ input_report_key(wm831x_on->dev, KEY_POWER, 0);
+ input_sync(wm831x_on->dev);
+ }
+ enable_irq(irq);
+
+ return 0;
+}
+#endif /* CONFIG_PM */
+
static struct platform_driver wm831x_on_driver = {
.probe = wm831x_on_probe,
.remove = wm831x_on_remove,
+#ifdef CONFIG_PM
+ .suspend = wm831x_on_suspend,
+ .resume = wm831x_on_resume,
+#endif
.driver = {
.name = "wm831x-on",
.owner = THIS_MODULE,
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 4a33351c..0e148121 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -25,6 +25,12 @@ config ARM_VIC_NR
The maximum number of VICs available in the system, for
power management.
+config AMBARELLA_VIC
+ bool
+ depends on PLAT_AMBARELLA
+ select IRQ_DOMAIN
+ select MULTI_IRQ_HANDLER
+
config RENESAS_INTC_IRQPIN
bool
select IRQ_DOMAIN
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index cda4cb5f..c3018a92 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_ARCH_SUNXI) += irq-sun4i.o
obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o
obj-$(CONFIG_ARM_GIC) += irq-gic.o
obj-$(CONFIG_ARM_VIC) += irq-vic.o
+obj-$(CONFIG_AMBARELLA_VIC) += irq-ambarella.o
obj-$(CONFIG_SIRF_IRQ) += irq-sirfsoc.o
obj-$(CONFIG_RENESAS_INTC_IRQPIN) += irq-renesas-intc-irqpin.o
obj-$(CONFIG_RENESAS_IRQC) += irq-renesas-irqc.o
diff --git a/drivers/irqchip/irq-ambarella.c b/drivers/irqchip/irq-ambarella.c
new file mode 100644
index 00000000..b2bbec0d
--- /dev/null
+++ b/drivers/irqchip/irq-ambarella.c
@@ -0,0 +1,657 @@
+/*
+ * drivers/irqchip/irq-ambarella.c
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2013, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/interrupt.h>
+#include <linux/syscore_ops.h>
+#include <asm/exception.h>
+#include "irqchip.h"
+
+#include <plat/rct.h>
+
+#define HWIRQ_TO_BANK(hwirq) ((hwirq) >> 5)
+#define HWIRQ_TO_OFFSET(hwirq) ((hwirq) & 0x1f)
+
+struct ambvic_chip_data {
+ void __iomem *reg_base[VIC_INSTANCES];
+ void __iomem *ipi_reg_base;
+ struct irq_domain *domain;
+};
+
+#ifdef CONFIG_SMP
+
+static DEFINE_RAW_SPINLOCK(irq_controller_lock);
+
+#define IPI0_IRQ_MASK ((1 << (IPI01_IRQ % 32)) | \
+ (1 << (IPI02_IRQ % 32)) | \
+ (1 << (IPI03_IRQ % 32)) | \
+ (1 << (IPI04_IRQ % 32)) | \
+ (1 << (IPI05_IRQ % 32)) | \
+ (1 << (IPI06_IRQ % 32)))
+#define IPI1_IRQ_MASK ((1 << (IPI11_IRQ % 32)) | \
+ (1 << (IPI12_IRQ % 32)) | \
+ (1 << (IPI13_IRQ % 32)) | \
+ (1 << (IPI14_IRQ % 32)) | \
+ (1 << (IPI15_IRQ % 32)) | \
+ (1 << (IPI16_IRQ % 32)))
+#define IPI_IRQ_MASK (IPI0_IRQ_MASK | IPI1_IRQ_MASK)
+
+#define AMBVIC_IRQ_IS_IPI0(irq) (((irq) >= IPI01_IRQ && (irq) <= IPI06_IRQ))
+#define AMBVIC_IRQ_IS_IPI1(irq) (((irq) >= IPI11_IRQ && (irq) <= IPI16_IRQ))
+#define AMBVIC_IRQ_IS_IPI(irq) (AMBVIC_IRQ_IS_IPI0(irq) || AMBVIC_IRQ_IS_IPI1(irq))
+
+#endif
+
+static struct ambvic_chip_data ambvic_data __read_mostly;
+
+/* ==========================================================================*/
+#if (VIC_SUPPORT_CPU_OFFLOAD >= 1)
+
+static void ambvic_ack_irq(struct irq_data *data)
+{
+ void __iomem *reg_base = irq_data_get_irq_chip_data(data);
+ u32 offset = HWIRQ_TO_OFFSET(data->hwirq);
+
+#if (VIC_SUPPORT_CPU_OFFLOAD == 1)
+ amba_writel(reg_base + VIC_EDGE_CLR_OFFSET, 0x1 << offset);
+#else
+ amba_writel(reg_base + VIC_INT_EDGE_CLR_OFFSET, offset);
+#endif
+}
+
+static void ambvic_mask_irq(struct irq_data *data)
+{
+ void __iomem *reg_base = irq_data_get_irq_chip_data(data);
+ u32 offset = HWIRQ_TO_OFFSET(data->hwirq);
+
+ amba_writel(reg_base + VIC_INT_EN_CLR_INT_OFFSET, offset);
+}
+
+static void ambvic_unmask_irq(struct irq_data *data)
+{
+ void __iomem *reg_base = irq_data_get_irq_chip_data(data);
+ u32 offset = HWIRQ_TO_OFFSET(data->hwirq);
+
+ amba_writel(reg_base + VIC_INT_EN_INT_OFFSET, offset);
+}
+
+static void ambvic_mask_ack_irq(struct irq_data *data)
+{
+ void __iomem *reg_base = irq_data_get_irq_chip_data(data);
+ u32 offset = HWIRQ_TO_OFFSET(data->hwirq);
+
+ amba_writel(reg_base + VIC_INT_EN_CLR_INT_OFFSET, offset);
+#if (VIC_SUPPORT_CPU_OFFLOAD == 1)
+ amba_writel(reg_base + VIC_EDGE_CLR_OFFSET, 0x1 << offset);
+#else
+ amba_writel(reg_base + VIC_INT_EDGE_CLR_OFFSET, offset);
+#endif
+}
+
+static int ambvic_set_type_irq(struct irq_data *data, unsigned int type)
+{
+ void __iomem *reg_base = irq_data_get_irq_chip_data(data);
+ struct irq_desc *desc = irq_to_desc(data->irq);
+ u32 offset = HWIRQ_TO_OFFSET(data->hwirq);
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ amba_writel(reg_base + VIC_INT_SENSE_CLR_INT_OFFSET, offset);
+ amba_writel(reg_base + VIC_INT_BOTHEDGE_CLR_INT_OFFSET, offset);
+ amba_writel(reg_base + VIC_INT_EVT_INT_OFFSET, offset);
+ desc->handle_irq = handle_edge_irq;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ amba_writel(reg_base + VIC_INT_SENSE_CLR_INT_OFFSET, offset);
+ amba_writel(reg_base + VIC_INT_BOTHEDGE_CLR_INT_OFFSET, offset);
+ amba_writel(reg_base + VIC_INT_EVT_CLR_INT_OFFSET, offset);
+ desc->handle_irq = handle_edge_irq;
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ amba_writel(reg_base + VIC_INT_SENSE_CLR_INT_OFFSET, offset);
+ amba_writel(reg_base + VIC_INT_BOTHEDGE_INT_OFFSET, offset);
+ amba_writel(reg_base + VIC_INT_EVT_CLR_INT_OFFSET, offset);
+ desc->handle_irq = handle_edge_irq;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ amba_writel(reg_base + VIC_INT_SENSE_INT_OFFSET, offset);
+ amba_writel(reg_base + VIC_INT_BOTHEDGE_CLR_INT_OFFSET, offset);
+ amba_writel(reg_base + VIC_INT_EVT_INT_OFFSET, offset);
+ desc->handle_irq = handle_level_irq;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ amba_writel(reg_base + VIC_INT_SENSE_INT_OFFSET, offset);
+ amba_writel(reg_base + VIC_INT_BOTHEDGE_CLR_INT_OFFSET, offset);
+ amba_writel(reg_base + VIC_INT_EVT_CLR_INT_OFFSET, offset);
+ desc->handle_irq = handle_level_irq;
+ break;
+ default:
+ pr_err("%s: irq[%d] type[%d] fail!\n",
+ __func__, data->irq, type);
+ return -EINVAL;
+ }
+
+ /* clear obsolete irq */
+#if (VIC_SUPPORT_CPU_OFFLOAD == 1)
+ amba_writel(reg_base + VIC_EDGE_CLR_OFFSET, 0x1 << offset);
+#else
+ amba_writel(reg_base + VIC_INT_EDGE_CLR_OFFSET, offset);
+#endif
+
+ return 0;
+}
+
+#else
+static void ambvic_ack_irq(struct irq_data *data)
+{
+ void __iomem *reg_base = irq_data_get_irq_chip_data(data);
+ u32 offset = HWIRQ_TO_OFFSET(data->hwirq);
+
+ amba_writel(reg_base + VIC_EDGE_CLR_OFFSET, 0x1 << offset);
+}
+
+static void ambvic_mask_irq(struct irq_data *data)
+{
+ void __iomem *reg_base = irq_data_get_irq_chip_data(data);
+ u32 offset = HWIRQ_TO_OFFSET(data->hwirq);
+
+ amba_writel(reg_base + VIC_INTEN_CLR_OFFSET, 0x1 << offset);
+}
+
+static void ambvic_unmask_irq(struct irq_data *data)
+{
+ void __iomem *reg_base = irq_data_get_irq_chip_data(data);
+ u32 offset = HWIRQ_TO_OFFSET(data->hwirq);
+
+ amba_writel(reg_base + VIC_INTEN_OFFSET, 0x1 << offset);
+}
+
+static void ambvic_mask_ack_irq(struct irq_data *data)
+{
+ void __iomem *reg_base = irq_data_get_irq_chip_data(data);
+ u32 offset = HWIRQ_TO_OFFSET(data->hwirq);
+
+ amba_writel(reg_base + VIC_INTEN_CLR_OFFSET, 0x1 << offset);
+ amba_writel(reg_base + VIC_EDGE_CLR_OFFSET, 0x1 << offset);
+}
+
+static int ambvic_set_type_irq(struct irq_data *data, unsigned int type)
+{
+ void __iomem *reg_base = irq_data_get_irq_chip_data(data);
+ struct irq_desc *desc = irq_to_desc(data->irq);
+ u32 offset = HWIRQ_TO_OFFSET(data->hwirq);
+ u32 mask, bit, sense, bothedges, event;
+
+ mask = ~(0x1 << offset);
+ bit = (0x1 << offset);
+ sense = amba_readl(reg_base + VIC_SENSE_OFFSET);
+ bothedges = amba_readl(reg_base + VIC_BOTHEDGE_OFFSET);
+ event = amba_readl(reg_base + VIC_EVENT_OFFSET);
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ sense &= mask;
+ bothedges &= mask;
+ event |= bit;
+ desc->handle_irq = handle_edge_irq;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ sense &= mask;
+ bothedges &= mask;
+ event &= mask;
+ desc->handle_irq = handle_edge_irq;
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ sense &= mask;
+ bothedges |= bit;
+ event &= mask;
+ desc->handle_irq = handle_edge_irq;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ sense |= bit;
+ bothedges &= mask;
+ event |= bit;
+ desc->handle_irq = handle_level_irq;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ sense |= bit;
+ bothedges &= mask;
+ event &= mask;
+ desc->handle_irq = handle_level_irq;
+ break;
+ default:
+ pr_err("%s: irq[%d] type[%d] fail!\n",
+ __func__, data->irq, type);
+ return -EINVAL;
+ }
+
+ amba_writel(reg_base + VIC_SENSE_OFFSET, sense);
+ amba_writel(reg_base + VIC_BOTHEDGE_OFFSET, bothedges);
+ amba_writel(reg_base + VIC_EVENT_OFFSET, event);
+ /* clear obsolete irq */
+ amba_writel(reg_base + VIC_EDGE_CLR_OFFSET, 0x1 << offset);
+
+ return 0;
+}
+
+#endif
+
+#ifdef CONFIG_SMP
+static int ambvic_set_affinity(struct irq_data *data,
+ const struct cpumask *mask_val, bool force)
+{
+ void __iomem *reg_base = irq_data_get_irq_chip_data(data);
+ u32 cpu = cpumask_any_and(mask_val, cpu_online_mask);
+ u32 mask = 1 << HWIRQ_TO_OFFSET(data->hwirq);
+ u32 val0, val1;
+
+ if (cpu >= nr_cpu_ids)
+ return -EINVAL;
+
+ raw_spin_lock(&irq_controller_lock);
+
+ val0 = amba_readl(reg_base + VIC_INT_PTR0_OFFSET);
+ val1 = amba_readl(reg_base + VIC_INT_PTR1_OFFSET);
+
+ if (cpu == 0) {
+ val0 |= mask;
+ val1 &= ~mask;
+ } else {
+ val0 &= ~mask;
+ val1 |= mask;
+ }
+
+ amba_writel(reg_base + VIC_INT_PTR0_OFFSET, val0);
+ amba_writel(reg_base + VIC_INT_PTR1_OFFSET, val1);
+
+ raw_spin_unlock(&irq_controller_lock);
+
+ return 0;
+}
+#endif
+
+static struct irq_chip ambvic_chip = {
+ .name = "VIC",
+ .irq_ack = ambvic_ack_irq,
+ .irq_mask = ambvic_mask_irq,
+ .irq_mask_ack = ambvic_mask_ack_irq,
+ .irq_unmask = ambvic_unmask_irq,
+ .irq_set_type = ambvic_set_type_irq,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = ambvic_set_affinity,
+#endif
+ .flags = (IRQCHIP_SET_TYPE_MASKED | IRQCHIP_MASK_ON_SUSPEND |
+ IRQCHIP_SKIP_SET_WAKE),
+};
+
+/* ==========================================================================*/
+#ifdef CONFIG_SMP
+static void ambvic_raise_softirq(const struct cpumask *mask, unsigned int irq)
+{
+ int cpu, softirq;
+
+ /* currently we only support dual cores, so we just pick the
+ * first cpu we find in 'mask'.. */
+ cpu = cpumask_any(mask);
+
+ /*
+ * Ensure that stores to Normal memory are visible to the
+ * other CPUs before issuing the IPI.
+ */
+ dsb();
+
+ /* submit softirq */
+ softirq = irq + ((cpu == 0) ? (IPI01_IRQ % 32) : (IPI11_IRQ % 32));
+ ambvic_sw_set(ambvic_data.ipi_reg_base, softirq);
+}
+
+void ambvic_smp_softirq_init(void)
+{
+ void __iomem *reg_base = ambvic_data.ipi_reg_base;
+ u32 val;
+
+ raw_spin_lock(&irq_controller_lock);
+
+ /* Clear pending IPIs */
+ amba_writel(reg_base + VIC_SOFTEN_CLR_OFFSET, IPI_IRQ_MASK);
+
+ /* Enable all of IPIs */
+ val = amba_readl(reg_base + VIC_INT_PTR0_OFFSET);
+ val |= IPI0_IRQ_MASK;
+ val &= ~IPI1_IRQ_MASK;
+ amba_writel(reg_base + VIC_INT_PTR0_OFFSET, val);
+
+ val = amba_readl(reg_base + VIC_INT_PTR1_OFFSET);
+ val |= IPI1_IRQ_MASK;
+ val &= ~IPI0_IRQ_MASK;
+ amba_writel(reg_base + VIC_INT_PTR1_OFFSET, val);
+
+ amba_writel(reg_base + VIC_SENSE_OFFSET, IPI_IRQ_MASK);
+ amba_writel(reg_base + VIC_EVENT_OFFSET, IPI_IRQ_MASK);
+ amba_writel(reg_base + VIC_INTEN_OFFSET, IPI_IRQ_MASK);
+
+ raw_spin_unlock(&irq_controller_lock);
+}
+#endif
+
+static inline int ambvic_handle_ipi(struct pt_regs *regs,
+ struct irq_domain *domain, u32 hwirq)
+{
+#ifdef CONFIG_SMP
+ /* IPI Handling */
+ if (AMBVIC_IRQ_IS_IPI(hwirq)) {
+ //printk("*********** hwirq = %d\n", hwirq);
+ ambvic_sw_clr(ambvic_data.ipi_reg_base, hwirq % 32);
+ if (AMBVIC_IRQ_IS_IPI0(hwirq))
+ handle_IPI(hwirq - IPI01_IRQ, regs);
+ else
+ handle_IPI(hwirq - IPI11_IRQ, regs);
+
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+#if (VIC_SUPPORT_CPU_OFFLOAD >= 2)
+static int ambvic_handle_scratchpad_vic(struct pt_regs *regs,
+ struct irq_domain *domain)
+{
+ u32 scratchpad, irq_sta, irq, hwirq;
+ int handled = 0;
+
+ if (smp_processor_id())
+ scratchpad = AHBSP_PRI_IRQ_C1_REG;
+ else
+ scratchpad = AHBSP_PRI_IRQ_C0_REG;
+
+ do {
+ hwirq = amba_readl(scratchpad);
+ if (hwirq == VIC_NULL_PRI_IRQ_VAL) {
+#if (VIC_NULL_PRI_IRQ_FIX == 1)
+ irq_sta = amba_readl(ambvic_data.reg_base[2] + VIC_IRQ_STA_OFFSET);
+ if ((irq_sta & 0x1) == 0)
+ break;
+#else
+ break;
+#endif
+ } else if (hwirq == 0) {
+ irq_sta = amba_readl(ambvic_data.reg_base[0] + VIC_IRQ_STA_OFFSET);
+ if ((irq_sta & 0x1) == 0)
+ break;
+ }
+
+#if 0
+ printk("CPU%d_%s: %d_%d\n",
+ smp_processor_id(), __func__,
+ (hwirq >> 5) & 0x3, hwirq & 0x1F);
+#endif
+ if (ambvic_handle_ipi(regs, domain, hwirq)) {
+ handled = 1;
+ continue;
+ }
+
+ irq = irq_find_mapping(domain, hwirq);
+ handle_IRQ(irq, regs);
+ handled = 1;
+ } while (1);
+
+ return handled;
+}
+#else
+static int ambvic_handle_one(struct pt_regs *regs,
+ struct irq_domain *domain, u32 bank)
+{
+ void __iomem *reg_base = ambvic_data.reg_base[bank];
+ u32 hwirq, irq, irq_sta;
+ int handled = 0;
+
+ do {
+#if (VIC_SUPPORT_CPU_OFFLOAD == 1)
+ hwirq = amba_readl(reg_base + VIC_INT_PENDING_OFFSET);
+ if (hwirq == 0) {
+ irq_sta = amba_readl(reg_base + VIC_IRQ_STA_OFFSET);
+ if ((irq_sta & 0x1) == 0) {
+ break;
+ }
+ }
+#else
+ irq_sta = amba_readl(reg_base + VIC_IRQ_STA_OFFSET);
+ if (irq_sta == 0) {
+ break;
+ }
+ hwirq = ffs(irq_sta) - 1;
+#endif
+ hwirq += bank * NR_VIC_IRQ_SIZE;
+
+ if (ambvic_handle_ipi(regs, domain, hwirq)) {
+ handled = 1;
+ continue;
+ }
+
+ irq = irq_find_mapping(domain, hwirq);
+ handle_IRQ(irq, regs);
+ handled = 1;
+ } while (1);
+
+ return handled;
+}
+#endif
+
+static asmlinkage void __exception_irq_entry ambvic_handle_irq(struct pt_regs *regs)
+{
+ int handled;
+
+ do {
+ handled = 0;
+#if (VIC_SUPPORT_CPU_OFFLOAD >= 2)
+ handled = ambvic_handle_scratchpad_vic(regs, ambvic_data.domain);
+#else
+{
+ int i;
+
+ for (i = 0; i < VIC_INSTANCES; i++) {
+ handled |= ambvic_handle_one(regs, ambvic_data.domain, i);
+ }
+}
+#endif
+ } while (handled);
+}
+
+static int ambvic_irq_domain_map(struct irq_domain *d,
+ unsigned int irq, irq_hw_number_t hwirq)
+{
+ if (hwirq > NR_VIC_IRQS)
+ return -EPERM;
+
+ irq_set_chip_and_handler(irq, &ambvic_chip, handle_level_irq);
+ irq_set_chip_data(irq, ambvic_data.reg_base[HWIRQ_TO_BANK(hwirq)]);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+
+ return 0;
+}
+
+static struct irq_domain_ops amb_irq_domain_ops = {
+ .map = ambvic_irq_domain_map,
+ .xlate = irq_domain_xlate_twocell,
+};
+
+
+#if defined(CONFIG_PM)
+
+struct ambvic_pm_reg {
+ u32 int_sel_reg;
+ u32 inten_reg;
+ u32 soften_reg;
+ u32 proten_reg;
+ u32 sense_reg;
+ u32 bothedge_reg;
+ u32 event_reg;
+ u32 int_ptr0_reg;
+ u32 int_ptr1_reg;
+};
+
+static struct ambvic_pm_reg ambvic_pm[VIC_INSTANCES];
+
+static int ambvic_suspend(void)
+{
+ struct ambvic_pm_reg *pm_val;
+ void __iomem *reg_base;
+ int i;
+
+ for (i = 0; i < VIC_INSTANCES; i++) {
+ reg_base = ambvic_data.reg_base[i];
+ pm_val = &ambvic_pm[i];
+
+ pm_val->int_sel_reg = amba_readl(reg_base + VIC_INT_SEL_OFFSET);
+ pm_val->inten_reg = amba_readl(reg_base + VIC_INTEN_OFFSET);
+ pm_val->soften_reg = amba_readl(reg_base + VIC_SOFTEN_OFFSET);
+ pm_val->proten_reg = amba_readl(reg_base + VIC_PROTEN_OFFSET);
+ pm_val->sense_reg = amba_readl(reg_base + VIC_SENSE_OFFSET);
+ pm_val->bothedge_reg = amba_readl(reg_base + VIC_BOTHEDGE_OFFSET);
+ pm_val->event_reg = amba_readl(reg_base + VIC_EVENT_OFFSET);
+ pm_val->int_ptr0_reg = amba_readl(reg_base + VIC_INT_PTR0_OFFSET);
+ pm_val->int_ptr1_reg = amba_readl(reg_base + VIC_INT_PTR1_OFFSET);
+ }
+
+ return 0;
+}
+
+static void ambvic_resume(void)
+{
+ struct ambvic_pm_reg *pm_val;
+ void __iomem *reg_base;
+ int i;
+
+ for (i = VIC_INSTANCES - 1; i >= 0; i--) {
+ reg_base = ambvic_data.reg_base[i];
+ pm_val = &ambvic_pm[i];
+
+ amba_writel(reg_base + VIC_INT_SEL_OFFSET, pm_val->int_sel_reg);
+ amba_writel(reg_base + VIC_INTEN_CLR_OFFSET, 0xffffffff);
+ amba_writel(reg_base + VIC_EDGE_CLR_OFFSET, 0xffffffff);
+ amba_writel(reg_base + VIC_INTEN_OFFSET, pm_val->inten_reg);
+ amba_writel(reg_base + VIC_SOFTEN_CLR_OFFSET, 0xffffffff);
+ amba_writel(reg_base + VIC_SOFTEN_OFFSET, pm_val->soften_reg);
+ amba_writel(reg_base + VIC_PROTEN_OFFSET, pm_val->proten_reg);
+ amba_writel(reg_base + VIC_SENSE_OFFSET, pm_val->sense_reg);
+ amba_writel(reg_base + VIC_BOTHEDGE_OFFSET, pm_val->bothedge_reg);
+ amba_writel(reg_base + VIC_EVENT_OFFSET, pm_val->event_reg);
+ amba_writel(reg_base + VIC_INT_PTR0_OFFSET, pm_val->int_ptr0_reg);
+ amba_writel(reg_base + VIC_INT_PTR1_OFFSET, pm_val->int_ptr1_reg);
+ }
+}
+
+struct syscore_ops ambvic_syscore_ops = {
+ .suspend = ambvic_suspend,
+ .resume = ambvic_resume,
+};
+
+#endif
+
+int __init ambvic_of_init(struct device_node *np, struct device_node *parent)
+{
+ void __iomem *reg_base;
+ int i, irq;
+
+ memset(&ambvic_data, 0, sizeof(struct ambvic_chip_data));
+
+ for (i = 0; i < VIC_INSTANCES; i++) {
+ reg_base = of_iomap(np, i);
+ BUG_ON(!reg_base);
+
+ amba_writel(reg_base + VIC_INT_SEL_OFFSET, 0x00000000);
+ amba_writel(reg_base + VIC_INTEN_OFFSET, 0x00000000);
+ amba_writel(reg_base + VIC_INTEN_CLR_OFFSET, 0xffffffff);
+ amba_writel(reg_base + VIC_EDGE_CLR_OFFSET, 0xffffffff);
+ amba_writel(reg_base + VIC_INT_PTR0_OFFSET, 0xffffffff);
+ amba_writel(reg_base + VIC_INT_PTR1_OFFSET, 0x00000000);
+
+ ambvic_data.reg_base[i] = reg_base;
+ }
+
+ set_handle_irq(ambvic_handle_irq);
+
+ ambvic_data.domain = irq_domain_add_linear(np,
+ NR_VIC_IRQS, &amb_irq_domain_ops, NULL);
+ BUG_ON(!ambvic_data.domain);
+
+ /* create mapping to make hwirq == irq to make life easier */
+ for (i = NR_VIC_IRQS - 1; i >= 0; i--) {
+ irq = irq_create_mapping(ambvic_data.domain, i);
+ irq_set_chip_and_handler(irq, &ambvic_chip, handle_level_irq);
+ irq_set_chip_data(irq, ambvic_data.reg_base[HWIRQ_TO_BANK(i)]);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+
+#ifdef CONFIG_SMP
+ ambvic_data.ipi_reg_base = ambvic_data.reg_base[IPI01_IRQ / 32];
+ ambvic_smp_softirq_init();
+ set_smp_cross_call(ambvic_raise_softirq);
+#if 0
+ /*
+ * Set the default affinity from all CPUs to the boot cpu.
+ * This is required since the MPIC doesn't limit several CPUs
+ * from acknowledging the same interrupt.
+ */
+ cpumask_clear(irq_default_affinity);
+ cpumask_set_cpu(smp_processor_id(), irq_default_affinity);
+#endif
+#endif
+
+#if defined(CONFIG_PM)
+ register_syscore_ops(&ambvic_syscore_ops);
+#endif
+ return 0;
+}
+
+IRQCHIP_DECLARE(ambvic, "ambarella,vic", ambvic_of_init);
+
+/* ==========================================================================*/
+#if (VIC_SUPPORT_CPU_OFFLOAD >= 1)
+void ambvic_sw_set(void __iomem *reg_base, u32 offset)
+{
+ amba_writel(reg_base + VIC_SOFT_INT_INT_OFFSET, offset);
+}
+
+void ambvic_sw_clr(void __iomem *reg_base, u32 offset)
+{
+ amba_writel(reg_base + VIC_SOFT_INT_CLR_INT_OFFSET, offset);
+}
+#else
+void ambvic_sw_set(void __iomem *reg_base, u32 offset)
+{
+ amba_writel(reg_base + VIC_SOFTEN_OFFSET, 0x1 << offset);
+}
+
+void ambvic_sw_clr(void __iomem *reg_base, u32 offset)
+{
+ amba_writel(reg_base + VIC_SOFTEN_CLR_OFFSET, 0x1 << offset);
+}
+#endif
+
+
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
index 521340a7..9ab36620 100644
--- a/drivers/mfd/wm831x-core.c
+++ b/drivers/mfd/wm831x-core.c
@@ -1667,7 +1667,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
switch (ret) {
case WM8310:
parent = WM8310;
- wm831x->num_gpio = 16;
+ wm831x->num_gpio = 12;
wm831x->charger_irq_wake = 1;
if (rev > 0) {
wm831x->has_gpio_ena = 1;
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 3ae6f132..a3fb62ed 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2277,6 +2277,7 @@ static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq)
return 0;
mmc_power_off(host);
+ host->ocr = 0;
return -EIO;
}
@@ -2748,6 +2749,7 @@ int mmc_pm_notify(struct notifier_block *notify_block,
if (!host->bus_ops || host->bus_ops->suspend)
break;
+ mmc_bus_get(host);
/* Calling bus_ops->remove() with a claimed host can deadlock */
if (host->bus_ops->remove)
host->bus_ops->remove(host);
@@ -2757,6 +2759,7 @@ int mmc_pm_notify(struct notifier_block *notify_block,
mmc_power_off(host);
mmc_release_host(host);
host->pm_flags = 0;
+ mmc_bus_put(host);
break;
case PM_POST_SUSPEND:
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index 35c2f85b..759c0dd7 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -126,6 +126,12 @@ static int mmc_ios_show(struct seq_file *s, void *data)
case MMC_TIMING_SD_HS:
str = "sd high-speed";
break;
+ case MMC_TIMING_UHS_SDR12:
+ str = "sd uhs SDR12";
+ break;
+ case MMC_TIMING_UHS_SDR25:
+ str = "sd uhs SDR25";
+ break;
case MMC_TIMING_UHS_SDR50:
str = "sd uhs SDR50";
break;
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index dda1a42a..97e2e287 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -295,13 +295,12 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
}
}
+ /*
+ * The EXT_CSD format is meant to be forward compatible. As long
+ * as CSD_STRUCTURE does not change, all values for EXT_CSD_REV
+ * are authorized, see JEDEC JESD84-B50 section B.8.
+ */
card->ext_csd.rev = ext_csd[EXT_CSD_REV];
- if (card->ext_csd.rev > 6) {
- pr_err("%s: unrecognised EXT_CSD revision %d\n",
- mmc_hostname(card->host), card->ext_csd.rev);
- err = -EINVAL;
- goto out;
- }
card->ext_csd.raw_sectors[0] = ext_csd[EXT_CSD_SEC_CNT + 0];
card->ext_csd.raw_sectors[1] = ext_csd[EXT_CSD_SEC_CNT + 1];
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 6889a821..eab38e78 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -1202,3 +1202,40 @@ err:
return err;
}
+int sdio_reset_comm(struct mmc_card *card)
+{
+ struct mmc_host *host = card->host;
+ u32 ocr;
+ int err;
+
+ //printk("%s():\n", __func__);
+ mmc_claim_host(host);
+
+ mmc_go_idle(host);
+
+ mmc_set_clock(host, host->f_min);
+
+ err = mmc_send_io_op_cond(host, 0, &ocr);
+ if (err)
+ goto err;
+
+ host->ocr = mmc_select_voltage(host, ocr);
+ if (!host->ocr) {
+ err = -EINVAL;
+ goto err;
+ }
+
+ err = mmc_sdio_init_card(host, host->ocr, card, 0);
+ if (err)
+ goto err;
+
+ mmc_release_host(host);
+ return 0;
+ err:
+ //printk("%s: Error resetting SDIO communications (%d)\n",
+ // mmc_hostname(host), err);
+ mmc_release_host(host);
+ return err;
+}
+EXPORT_SYMBOL(sdio_reset_comm);
+
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 9ab8f8de..2e2dcbd8 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -4,6 +4,21 @@
comment "MMC/SD/SDIO Host Controller Drivers"
+config MMC_AMBARELLA
+ tristate "Ambarella Media Processor SD/MMC Host Controller driver"
+ depends on PLAT_AMBARELLA
+ help
+ This selects the Ambarella Media Processor Multimedia Card
+ Interface support. If you have an Ambarella Media Processor
+ platform with a Multimedia Card slot, say Y here.
+
+config AMBARELLA_EMMC_BOOT
+ bool "EMMC Boot for Ambarella Platform"
+ default n
+ help
+ If you want to use ambarella platform to boot from emmc, you must
+ select this item, so it can help emmc reboot.
+
config MMC_ARMMMCI
tristate "ARM AMBA Multimedia Card Interface support"
depends on ARM_AMBA
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index cd322807..a489d093 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -2,6 +2,7 @@
# Makefile for MMC/SD host controller drivers
#
+obj-$(CONFIG_MMC_AMBARELLA) += ambarella_sd.o
obj-$(CONFIG_MMC_ARMMMCI) += mmci.o
obj-$(CONFIG_MMC_PXA) += pxamci.o
obj-$(CONFIG_MMC_MXC) += mxcmmc.o
diff --git a/drivers/mmc/host/ambarella_sd.c b/drivers/mmc/host/ambarella_sd.c
new file mode 100644
index 00000000..dbaba4f3
--- /dev/null
+++ b/drivers/mmc/host/ambarella_sd.c
@@ -0,0 +1,2826 @@
+/*
+ * drivers/mmc/host/ambarella_sd.c
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/of_gpio.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/mmc/slot-gpio.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/blkdev.h>
+#include <linux/scatterlist.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/sd.h>
+#include <linux/debugfs.h>
+#include <asm/dma.h>
+#include <mach/hardware.h>
+#include <plat/fio.h>
+#include <plat/sd.h>
+#include <plat/event.h>
+#include <plat/rct.h>
+
+static struct mmc_host *G_mmc[SD_INSTANCES * AMBA_SD_MAX_SLOT_NUM];
+
+/* ==========================================================================*/
+#define CONFIG_SD_AMBARELLA_TIMEOUT_VAL (0xe)
+#define CONFIG_SD_AMBARELLA_WAIT_TIMEOUT (HZ / 100)
+#define CONFIG_SD_AMBARELLA_WAIT_COUNTER_LIMIT (100000)
+#define CONFIG_SD_AMBARELLA_MAX_TIMEOUT (10 * HZ)
+#define CONFIG_SD_AMBARELLA_VSW_PRE_SPEC (5)
+#define CONFIG_SD_AMBARELLA_VSW_WAIT_LIMIT (1000)
+
+#undef CONFIG_SD_AMBARELLA_DEBUG
+#undef CONFIG_SD_AMBARELLA_DEBUG_VERBOSE
+#undef CONFIG_SD_AMBARELLA_TUNING_DEBUG
+
+#define ambsd_printk(level, phcinfo, format, arg...) \
+ printk(level "%s.%u: " format, dev_name(phcinfo->pinfo->dev), \
+ phcinfo->slot_id, ## arg)
+
+#define ambsd_err(phcinfo, format, arg...) \
+ ambsd_printk(KERN_ERR, phcinfo, format, ## arg)
+#define ambsd_warn(phcinfo, format, arg...) \
+ ambsd_printk(KERN_WARNING, phcinfo, format, ## arg)
+#define ambsd_info(phcinfo, format, arg...) \
+ ambsd_printk(KERN_INFO, phcinfo, format, ## arg)
+#define ambsd_rtdbg(phcinfo, format, arg...) \
+ ambsd_printk(KERN_DEBUG, phcinfo, format, ## arg)
+
+#ifdef CONFIG_SD_AMBARELLA_DEBUG
+#define ambsd_dbg(phcinfo, format, arg...) \
+ ambsd_printk(KERN_DEBUG, phcinfo, format, ## arg)
+#else
+#define ambsd_dbg(phcinfo, format, arg...) \
+ ({ if (0) ambsd_printk(KERN_DEBUG, phcinfo, format, ##arg); 0; })
+#endif
+
+#ifdef CONFIG_SD_AMBARELLA_TUNING_DEBUG
+#define ambsd_tuning_dbg(phcinfo, format, arg...) \
+ ambsd_printk(KERN_DEBUG, phcinfo, format, ## arg)
+#else
+#define ambsd_tuning_dbg(phcinfo, format, arg...) \
+ ({ if (0) ambsd_printk(KERN_DEBUG, phcinfo, format, ##arg); 0; })
+#endif
+
+
+/* ==========================================================================*/
+enum ambarella_sd_state {
+ AMBA_SD_STATE_IDLE,
+ AMBA_SD_STATE_CMD,
+ AMBA_SD_STATE_DATA,
+ AMBA_SD_STATE_RESET,
+ AMBA_SD_STATE_ERR
+};
+
+struct ambarella_sd_phy_timing {
+ u32 mode;
+ u32 val0;
+ u32 val1;
+};
+
+struct ambarella_sd_mmc_info {
+ struct mmc_host *mmc;
+ struct mmc_request *mrq;
+
+ wait_queue_head_t wait;
+
+ enum ambarella_sd_state state;
+
+ struct scatterlist *sg;
+ u32 sg_len;
+ u32 wait_tmo;
+ u16 blk_sz;
+ u16 blk_cnt;
+ u32 arg_reg;
+ u16 xfr_reg;
+ u16 cmd_reg;
+ u16 sta_reg;
+ u8 tmo;
+ u8 use_adma;
+ u32 sta_counter;
+
+ char *buf_vaddress;
+ dma_addr_t buf_paddress;
+ u32 dma_address;
+ u32 dma_size;
+
+ void (*pre_dma)(void *data);
+ void (*post_dma)(void *data);
+
+ u32 slot_id;
+ struct ambarella_sd_controller_info *pinfo;
+ u32 valid;
+ int fixed_cd;
+ int fixed_wp;
+
+ int pwr_gpio;
+ u8 pwr_gpio_active;
+ int v18_gpio;
+ u8 v18_gpio_active;
+ u32 no_1_8_v : 1,
+ caps_ddr : 1,
+ caps_adma : 1,
+ force_gpio : 1;
+
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *state_work;
+ struct pinctrl_state *state_idle;
+
+ struct notifier_block system_event;
+ struct semaphore system_event_sem;
+
+ struct dentry *debugfs;
+
+#ifdef CONFIG_PM
+ u32 sd_nisen;
+ u32 sd_eisen;
+ u32 sd_nixen;
+ u32 sd_eixen;
+#endif
+};
+
+struct ambarella_sd_controller_info {
+ unsigned char __iomem *regbase;
+ unsigned char __iomem *fio_reg;
+ unsigned char __iomem *timing_reg;
+ unsigned char __iomem *sbc_reg;
+ struct device *dev;
+ unsigned int irq;
+ u32 dma_fix;
+ u32 reset_error;
+
+ u32 max_blk_sz;
+ struct kmem_cache *buf_cache;
+
+ struct clk *clk;
+ u32 default_wait_tmo;
+ u32 switch_voltage_tmo;
+ u8 slot_num;
+ u32 phy_type;
+ struct ambarella_sd_phy_timing *phy_timing;
+ u32 phy_timing_num;
+
+ struct ambarella_sd_mmc_info *pslotinfo[AMBA_SD_MAX_SLOT_NUM];
+ struct mmc_ios controller_ios;
+ bool auto_tuning;
+};
+
+static const u8 tuning_blk_pattern_4bit[] = {
+ 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
+ 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
+ 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
+ 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
+ 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
+ 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
+ 0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
+ 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
+};
+
+static const u8 tuning_blk_pattern_8bit[] = {
+ 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
+ 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
+ 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
+ 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
+ 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
+ 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
+ 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
+ 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
+ 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
+ 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
+ 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
+ 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
+ 0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
+ 0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
+ 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
+};
+
+/* ==========================================================================*/
+#ifdef CONFIG_SD_AMBARELLA_DEBUG_VERBOSE
+static void ambarella_sd_show_info(struct ambarella_sd_mmc_info *pslotinfo)
+{
+ ambsd_dbg(pslotinfo, "Enter %s\n", __func__);
+ ambsd_dbg(pslotinfo, "sg = 0x%x.\n", (u32)pslotinfo->sg);
+ ambsd_dbg(pslotinfo, "sg_len = 0x%x.\n", pslotinfo->sg_len);
+ ambsd_dbg(pslotinfo, "tmo = 0x%x.\n", pslotinfo->tmo);
+ ambsd_dbg(pslotinfo, "blk_sz = 0x%x.\n", pslotinfo->blk_sz);
+ ambsd_dbg(pslotinfo, "blk_cnt = 0x%x.\n", pslotinfo->blk_cnt);
+ ambsd_dbg(pslotinfo, "arg_reg = 0x%x.\n", pslotinfo->arg_reg);
+ ambsd_dbg(pslotinfo, "xfr_reg = 0x%x.\n", pslotinfo->xfr_reg);
+ ambsd_dbg(pslotinfo, "cmd_reg = 0x%x.\n", pslotinfo->cmd_reg);
+ ambsd_dbg(pslotinfo, "buf_vaddress = 0x%x.\n",
+ (u32)pslotinfo->buf_vaddress);
+ ambsd_dbg(pslotinfo, "buf_paddress = 0x%x.\n", pslotinfo->buf_paddress);
+ ambsd_dbg(pslotinfo, "dma_address = 0x%x.\n", pslotinfo->dma_address);
+ ambsd_dbg(pslotinfo, "dma_size = 0x%x.\n", pslotinfo->dma_size);
+ ambsd_dbg(pslotinfo, "pre_dma = 0x%x.\n", (u32)pslotinfo->pre_dma);
+ ambsd_dbg(pslotinfo, "post_dma = 0x%x.\n", (u32)pslotinfo->post_dma);
+ ambsd_dbg(pslotinfo, "SD: state = 0x%x.\n", pslotinfo->state);
+ ambsd_dbg(pslotinfo, "Exit %s\n", __func__);
+}
+#endif
+
+void ambarella_detect_sd_slot(int slotid, int fixed_cd)
+{
+ struct mmc_host *mmc;
+ struct ambarella_sd_mmc_info *pslotinfo;
+
+ if (slotid >= SD_INSTANCES * AMBA_SD_MAX_SLOT_NUM) {
+ pr_err("%s: Invalid slotid: %d\n", __func__, slotid);
+ return;
+ }
+
+ mmc = G_mmc[slotid];
+ pslotinfo = mmc_priv(mmc);
+ pslotinfo->fixed_cd = fixed_cd;
+
+ mmc_detect_change(mmc, 0);
+}
+EXPORT_SYMBOL(ambarella_detect_sd_slot);
+
+static ssize_t fixed_cd_get(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = file->private_data;
+ char tmp[4];
+
+ snprintf(tmp, sizeof(tmp), "%d\n", pslotinfo->fixed_cd);
+ tmp[3] = '\n';
+
+ return simple_read_from_buffer(buf, count, ppos, tmp, sizeof(tmp));
+}
+
+static ssize_t fixed_cd_set(struct file *file, const char __user *buf,
+ size_t size, loff_t *ppos)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = file->private_data;
+ char tmp[20];
+ ssize_t len;
+
+ len = simple_write_to_buffer(tmp, sizeof(tmp) - 1, ppos, buf, size);
+ if (len >= 0) {
+ tmp[len] = '\0';
+ pslotinfo->fixed_cd = !!simple_strtoul(tmp, NULL, 0);
+ }
+
+ mmc_detect_change(pslotinfo->mmc, 0);
+
+ return len;
+}
+
+static const struct file_operations fixed_cd_fops = {
+ .read = fixed_cd_get,
+ .write = fixed_cd_set,
+ .open = simple_open,
+ .llseek = default_llseek,
+};
+
+static void ambarella_sd_add_debugfs(struct ambarella_sd_mmc_info *pslotinfo)
+{
+ struct mmc_host *mmc = pslotinfo->mmc;
+ struct dentry *root, *fixed_cd;
+
+ if (!mmc->debugfs_root)
+ return;
+
+ root = debugfs_create_dir("ambhost", mmc->debugfs_root);
+ if (IS_ERR_OR_NULL(root))
+ goto err;
+
+ pslotinfo->debugfs = root;
+
+ fixed_cd = debugfs_create_file("fixed_cd", S_IWUSR | S_IRUGO,
+ pslotinfo->debugfs, pslotinfo, &fixed_cd_fops);
+ if (IS_ERR_OR_NULL(fixed_cd))
+ goto err;
+
+ return;
+
+err:
+ debugfs_remove_recursive(root);
+ pslotinfo->debugfs = NULL;
+ dev_err(pslotinfo->pinfo->dev, "failed to add debugfs\n");
+}
+
+static void ambarella_sd_remove_debugfs(struct ambarella_sd_mmc_info *pslotinfo)
+{
+ debugfs_remove_recursive(pslotinfo->debugfs);
+}
+
+static void ambarella_sd_check_dma_boundary(u32 address, u32 size, u32 max_size)
+{
+ u32 start_512kb, end_512kb;
+
+ start_512kb = (address) & (~(max_size - 1));
+ end_512kb = (address + size - 1) & (~(max_size - 1));
+ BUG_ON(start_512kb != end_512kb);
+}
+
+static void ambarella_sd_pre_sg_to_dma(void *data)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = data;
+ u32 i, offset;
+
+ for (i = 0, offset = 0; i < pslotinfo->sg_len; i++) {
+ memcpy(pslotinfo->buf_vaddress + offset,
+ sg_virt(&pslotinfo->sg[i]),
+ pslotinfo->sg[i].length);
+ offset += pslotinfo->sg[i].length;
+ }
+ BUG_ON(offset != pslotinfo->dma_size);
+ dma_sync_single_for_device(pslotinfo->pinfo->dev, pslotinfo->buf_paddress,
+ pslotinfo->dma_size, DMA_TO_DEVICE);
+ pslotinfo->dma_address = pslotinfo->buf_paddress;
+ pslotinfo->blk_sz |= SD_BLK_SZ_512KB;
+}
+
+static void ambarella_sd_pre_sg_to_adma(void *data)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = data;
+ int i;
+ u32 offset;
+ u32 dma_len;
+ u32 remain_size;
+ u32 current_addr;
+ u32 word_num, byte_num;
+
+ dma_len = dma_map_sg(pslotinfo->pinfo->dev, pslotinfo->sg,
+ pslotinfo->sg_len, DMA_TO_DEVICE);
+ for (i = 0, offset = 0; i < dma_len; i++) {
+ remain_size = sg_dma_len(&pslotinfo->sg[i]);
+ current_addr = sg_dma_address(&pslotinfo->sg[i]);
+ current_addr |= pslotinfo->pinfo->dma_fix;
+ if (sd_addr_is_unlign(current_addr)) {
+ ambsd_err(pslotinfo, "Please disable ADMA\n");
+ BUG();
+ }
+
+ while (unlikely(remain_size > SD_ADMA_TBL_LINE_MAX_LEN)) {
+ *(u32 *)(pslotinfo->buf_vaddress + offset) =
+ (SD_ADMA_TBL_ATTR_TRAN |
+ SD_ADMA_TBL_ATTR_WORD |
+ SD_ADMA_TBL_ATTR_VALID);
+ *(u32 *)(pslotinfo->buf_vaddress + offset + 4) =
+ current_addr;
+ offset += SD_ADMA_TBL_LINE_SIZE;
+ current_addr += SD_ADMA_TBL_LINE_MAX_LEN;
+ remain_size -= SD_ADMA_TBL_LINE_MAX_LEN;
+ }
+ word_num = remain_size >> 2;
+ byte_num = remain_size - (word_num << 2);
+ if (word_num) {
+ *(u32 *)(pslotinfo->buf_vaddress + offset) =
+ (SD_ADMA_TBL_ATTR_TRAN |
+ SD_ADMA_TBL_ATTR_WORD |
+ SD_ADMA_TBL_ATTR_VALID);
+ *(u32 *)(pslotinfo->buf_vaddress + offset) |=
+ (word_num << 16);
+ *(u32 *)(pslotinfo->buf_vaddress + offset + 4) =
+ current_addr;
+ current_addr += (word_num << 2);
+ if (byte_num) {
+ offset += SD_ADMA_TBL_LINE_SIZE;
+ }
+ }
+ if (byte_num) {
+ *(u32 *)(pslotinfo->buf_vaddress + offset) =
+ (SD_ADMA_TBL_ATTR_TRAN |
+ SD_ADMA_TBL_ATTR_VALID);
+ *(u32 *)(pslotinfo->buf_vaddress + offset) |=
+ byte_num << 16;
+ *(u32 *)(pslotinfo->buf_vaddress + offset + 4) =
+ current_addr;
+ }
+ if (unlikely(i == dma_len - 1)) {
+ *(u32 *)(pslotinfo->buf_vaddress + offset) |=
+ SD_ADMA_TBL_ATTR_END;
+ }
+ offset += SD_ADMA_TBL_LINE_SIZE;
+ }
+ dma_sync_single_for_device(pslotinfo->pinfo->dev, pslotinfo->buf_paddress,
+ offset, DMA_TO_DEVICE);
+ pslotinfo->dma_address = pslotinfo->buf_paddress;
+ pslotinfo->blk_sz |= SD_BLK_SZ_512KB;
+}
+
+static void ambarella_sd_post_sg_to_dma(void *data)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = data;
+
+ dma_sync_single_for_cpu(pslotinfo->pinfo->dev,
+ pslotinfo->buf_paddress,
+ pslotinfo->dma_size,
+ DMA_TO_DEVICE);
+}
+
+static void ambarella_sd_post_sg_to_adma(void *data)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = data;
+
+ dma_sync_single_for_cpu(pslotinfo->pinfo->dev,
+ pslotinfo->buf_paddress,
+ pslotinfo->dma_size,
+ DMA_FROM_DEVICE);
+
+ dma_unmap_sg(pslotinfo->pinfo->dev,
+ pslotinfo->sg,
+ pslotinfo->sg_len,
+ DMA_TO_DEVICE);
+}
+
+static void ambarella_sd_pre_dma_to_sg(void *data)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = data;
+
+ dma_sync_single_for_device(pslotinfo->pinfo->dev,
+ pslotinfo->buf_paddress,
+ pslotinfo->dma_size,
+ DMA_FROM_DEVICE);
+
+ pslotinfo->dma_address = pslotinfo->buf_paddress;
+ pslotinfo->blk_sz |= SD_BLK_SZ_512KB;
+}
+
+static void ambarella_sd_pre_adma_to_sg(void *data)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = data;
+ int i;
+ u32 dma_len;
+ u32 offset;
+ u32 remain_size;
+ u32 current_addr;
+ u32 word_num, byte_num;
+
+ dma_len = dma_map_sg(pslotinfo->pinfo->dev, pslotinfo->sg,
+ pslotinfo->sg_len, DMA_FROM_DEVICE);
+ for (i = 0, offset = 0; i < dma_len; i++) {
+ remain_size = sg_dma_len(&pslotinfo->sg[i]);
+ current_addr = sg_dma_address(&pslotinfo->sg[i]);
+ current_addr |= pslotinfo->pinfo->dma_fix;
+ if (sd_addr_is_unlign(current_addr)) {
+ ambsd_err(pslotinfo, "Please disable ADMA\n");
+ BUG();
+ }
+
+ while (unlikely(remain_size > SD_ADMA_TBL_LINE_MAX_LEN)) {
+ *(u32 *)(pslotinfo->buf_vaddress + offset) =
+ (SD_ADMA_TBL_ATTR_TRAN |
+ SD_ADMA_TBL_ATTR_WORD |
+ SD_ADMA_TBL_ATTR_VALID);
+ *(u32 *)(pslotinfo->buf_vaddress + offset + 4) =
+ current_addr;
+ offset += SD_ADMA_TBL_LINE_SIZE;
+ current_addr += SD_ADMA_TBL_LINE_MAX_LEN;
+ remain_size -= SD_ADMA_TBL_LINE_MAX_LEN;
+ }
+ word_num = remain_size >> 2;
+ byte_num = remain_size - (word_num << 2);
+ if (word_num) {
+ *(u32 *)(pslotinfo->buf_vaddress + offset) =
+ (SD_ADMA_TBL_ATTR_TRAN |
+ SD_ADMA_TBL_ATTR_WORD |
+ SD_ADMA_TBL_ATTR_VALID);
+ *(u32 *)(pslotinfo->buf_vaddress + offset) |=
+ (word_num << 16);
+ *(u32 *)(pslotinfo->buf_vaddress + offset + 4) =
+ current_addr;
+ current_addr += (word_num << 2);
+ if (byte_num) {
+ offset += SD_ADMA_TBL_LINE_SIZE;
+ }
+ }
+ if (byte_num) {
+ *(u32 *)(pslotinfo->buf_vaddress + offset) =
+ (SD_ADMA_TBL_ATTR_TRAN |
+ SD_ADMA_TBL_ATTR_VALID);
+ *(u32 *)(pslotinfo->buf_vaddress + offset) |=
+ (byte_num << 16);
+ *(u32 *)(pslotinfo->buf_vaddress + offset + 4) =
+ current_addr;
+ }
+ if (unlikely(i == dma_len - 1)) {
+ *(u32 *)(pslotinfo->buf_vaddress + offset) |=
+ SD_ADMA_TBL_ATTR_END;
+ }
+ offset += SD_ADMA_TBL_LINE_SIZE;
+ }
+ dma_sync_single_for_device(pslotinfo->pinfo->dev,
+ pslotinfo->buf_paddress, offset,
+ DMA_TO_DEVICE);
+ pslotinfo->dma_address = pslotinfo->buf_paddress;
+ pslotinfo->blk_sz |= SD_BLK_SZ_512KB;
+}
+
+static void ambarella_sd_post_dma_to_sg(void *data)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = data;
+ u32 i, offset;
+
+ dma_sync_single_for_cpu(pslotinfo->pinfo->dev,
+ pslotinfo->buf_paddress,
+ pslotinfo->dma_size,
+ DMA_FROM_DEVICE);
+
+ for (i = 0, offset = 0; i < pslotinfo->sg_len; i++) {
+ memcpy(sg_virt(&pslotinfo->sg[i]),
+ pslotinfo->buf_vaddress + offset,
+ pslotinfo->sg[i].length);
+ offset += pslotinfo->sg[i].length;
+ }
+ BUG_ON(offset != pslotinfo->dma_size);
+}
+
+static void ambarella_sd_post_adma_to_sg(void *data)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = data;
+
+ dma_sync_single_for_cpu(pslotinfo->pinfo->dev,
+ pslotinfo->buf_paddress,
+ pslotinfo->dma_size,
+ DMA_FROM_DEVICE);
+
+ dma_unmap_sg(pslotinfo->pinfo->dev,
+ pslotinfo->sg,
+ pslotinfo->sg_len,
+ DMA_FROM_DEVICE);
+}
+
+static void ambarella_sd_request_bus(struct mmc_host *mmc)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
+
+ down(&pslotinfo->system_event_sem);
+
+ if (pslotinfo->slot_id == 0) {
+ fio_select_lock(SELECT_FIO_SD);
+ } else {
+ fio_select_lock(SELECT_FIO_SDIO);
+ if (pslotinfo->force_gpio)
+ pinctrl_select_state(pslotinfo->pinctrl, pslotinfo->state_work);
+ }
+
+}
+
+static void ambarella_sd_release_bus(struct mmc_host *mmc)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
+
+ if (pslotinfo->slot_id == 0) {
+ fio_unlock(SELECT_FIO_SD);
+ } else {
+ if (pslotinfo->force_gpio)
+ pinctrl_select_state(pslotinfo->pinctrl, pslotinfo->state_idle);
+ fio_unlock(SELECT_FIO_SDIO);
+ }
+
+ up(&pslotinfo->system_event_sem);
+}
+
+static void ambarella_sd_enable_int(struct mmc_host *mmc, u32 mask)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
+ struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
+
+ if (pinfo->slot_num > 1) {
+ if (pslotinfo->slot_id == 0)
+ fio_amb_sd0_set_int(mask, 1);
+ else
+ fio_amb_sdio0_set_int(mask, 1);
+ } else {
+ amba_setbitsl(pinfo->regbase + SD_NISEN_OFFSET, mask);
+ amba_setbitsl(pinfo->regbase + SD_NIXEN_OFFSET, mask);
+ }
+
+}
+
+static void ambarella_sd_disable_int(struct mmc_host *mmc, u32 mask)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
+ struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
+
+ if (pinfo->slot_num > 1) {
+ if (pslotinfo->slot_id == 0)
+ fio_amb_sd0_set_int(mask, 0);
+ else
+ fio_amb_sdio0_set_int(mask, 0);
+ } else {
+ amba_clrbitsl(pinfo->regbase + SD_NISEN_OFFSET, mask);
+ amba_clrbitsl(pinfo->regbase + SD_NIXEN_OFFSET, mask);
+ }
+}
+
+static void ambarella_sd_set_iclk(struct mmc_host *mmc, u16 clk_div)
+{
+ u16 clkreg;
+ u32 counter = 0;
+ struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
+ struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
+
+ clk_div <<= 8;
+ clk_div |= SD_CLK_ICLK_EN;
+ amba_writew(pinfo->regbase + SD_CLK_OFFSET, clk_div);
+ while (1) {
+ clkreg = amba_readw(pinfo->regbase + SD_CLK_OFFSET);
+ if (clkreg & SD_CLK_ICLK_STABLE)
+ break;
+ if ((clkreg & ~SD_CLK_ICLK_STABLE) != clk_div) {
+ amba_writew(pinfo->regbase + SD_CLK_OFFSET, clk_div);
+ udelay(1);
+ }
+ counter++;
+ if (counter > CONFIG_SD_AMBARELLA_WAIT_COUNTER_LIMIT) {
+ ambsd_warn(pslotinfo,
+ "Wait SD_CLK_ICLK_STABLE = %d @ 0x%x\n",
+ counter, clkreg);
+ break;
+ }
+ }
+}
+
+static void ambarella_sd_clear_clken(struct mmc_host *mmc)
+{
+ u16 clkreg;
+ u32 counter = 0;
+ struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
+ struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
+
+ while (1) {
+ clkreg = amba_readw(pinfo->regbase + SD_CLK_OFFSET);
+ if (clkreg & SD_CLK_EN) {
+ amba_writew(pinfo->regbase + SD_CLK_OFFSET,
+ (clkreg & ~SD_CLK_EN));
+ udelay(1);
+ } else {
+ break;
+ }
+ counter++;
+ if (counter > CONFIG_SD_AMBARELLA_WAIT_COUNTER_LIMIT) {
+ ambsd_warn(pslotinfo, "%s(%d @ 0x%x)\n",
+ __func__, counter, clkreg);
+ break;
+ }
+ }
+}
+
+static void ambarella_sd_set_clken(struct mmc_host *mmc)
+{
+ u16 clkreg;
+ u32 counter = 0;
+ struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
+ struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
+
+ while (1) {
+ clkreg = amba_readw(pinfo->regbase + SD_CLK_OFFSET);
+ if (clkreg & SD_CLK_EN) {
+ break;
+ } else {
+ amba_writew(pinfo->regbase + SD_CLK_OFFSET,
+ (clkreg | SD_CLK_EN));
+ udelay(1);
+ }
+ counter++;
+ if (counter > CONFIG_SD_AMBARELLA_WAIT_COUNTER_LIMIT) {
+ ambsd_warn(pslotinfo, "%s(%d @ 0x%x)\n",
+ __func__, counter, clkreg);
+ break;
+ }
+ }
+}
+
+static void ambarella_sd_reset_all(struct mmc_host *mmc)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
+ struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
+ u32 nis_flag = 0;
+ u32 eis_flag = 0;
+ u32 counter = 0;
+ u8 reset_reg;
+
+ ambsd_dbg(pslotinfo, "Enter %s with state %u\n",
+ __func__, pslotinfo->state);
+
+ ambarella_sd_disable_int(mmc, 0xFFFFFFFF);
+ amba_write2w(pinfo->regbase + SD_NIS_OFFSET, 0xFFFF, 0xFFFF);
+
+ /*reset sd timing register*/
+ if(pinfo->phy_type == 0 && pinfo->timing_reg) {
+ amba_writel(pinfo->sbc_reg, 0x0);
+ amba_writel(pinfo->timing_reg + 4, 0x0);
+ amba_writel(pinfo->timing_reg, 0x04070000);
+ } else if(pinfo->phy_type == 1) {
+ amba_writel(pinfo->regbase + SD_DELAY_SEL_L, 0x0);
+ amba_writel(pinfo->regbase + SD_DELAY_SEL_H, 0x0);
+ } else if(pinfo->phy_type == 2 && pinfo->timing_reg) {
+ amba_writel(pinfo->timing_reg, amba_rct_readl(pinfo->timing_reg)
+ & 0x1c1f1c1f);
+ }
+
+ amba_writeb(pinfo->regbase + SD_RESET_OFFSET, SD_RESET_ALL);
+ while (1) {
+ reset_reg = amba_readb(pinfo->regbase + SD_RESET_OFFSET);
+ if (!(reset_reg & SD_RESET_ALL))
+ break;
+ counter++;
+ if (counter > CONFIG_SD_AMBARELLA_WAIT_COUNTER_LIMIT) {
+ ambsd_warn(pslotinfo, "Wait SD_RESET_ALL....\n");
+ break;
+ }
+ }
+
+ ambarella_sd_set_iclk(mmc, 0x0000);
+ amba_writeb(pinfo->regbase + SD_TMO_OFFSET,
+ CONFIG_SD_AMBARELLA_TIMEOUT_VAL);
+
+ nis_flag = SD_NISEN_REMOVAL |
+ SD_NISEN_INSERT |
+ SD_NISEN_DMA |
+ SD_NISEN_BLOCK_GAP |
+ SD_NISEN_XFR_DONE |
+ SD_NISEN_CMD_DONE;
+ eis_flag = SD_EISEN_ACMD12_ERR |
+ SD_EISEN_CURRENT_ERR |
+ SD_EISEN_DATA_BIT_ERR |
+ SD_EISEN_DATA_CRC_ERR |
+ SD_EISEN_DATA_TMOUT_ERR |
+ SD_EISEN_CMD_IDX_ERR |
+ SD_EISEN_CMD_BIT_ERR |
+ SD_EISEN_CMD_CRC_ERR |
+ SD_EISEN_CMD_TMOUT_ERR;
+
+ if (pslotinfo->use_adma == 1)
+ eis_flag |= SD_EISEN_ADMA_ERR;
+ else
+ eis_flag &= ~SD_EISEN_ADMA_ERR;
+
+ ambarella_sd_enable_int(mmc, (eis_flag << 16) | nis_flag);
+
+ pslotinfo->state = AMBA_SD_STATE_RESET;
+ pinfo->reset_error = 0;
+
+ ambsd_dbg(pslotinfo, "Exit %s with counter %u\n", __func__, counter);
+}
+
+static void ambarella_sd_reset_cmd_line(struct mmc_host *mmc)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
+ struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
+ u32 counter = 0;
+ u8 reset_reg;
+
+ ambsd_dbg(pslotinfo, "Enter %s with state %u\n",
+ __func__, pslotinfo->state);
+
+ amba_writeb(pinfo->regbase + SD_RESET_OFFSET, SD_RESET_CMD);
+ while (1) {
+ reset_reg = amba_readb(pinfo->regbase + SD_RESET_OFFSET);
+ if (!(reset_reg & SD_RESET_CMD))
+ break;
+ counter++;
+ if (counter > CONFIG_SD_AMBARELLA_WAIT_COUNTER_LIMIT) {
+ ambsd_warn(pslotinfo, "Wait SD_RESET_CMD...\n");
+ pinfo->reset_error = 1;
+ break;
+ }
+ }
+
+ ambsd_dbg(pslotinfo, "Exit %s with counter %u\n", __func__, counter);
+}
+
+static void ambarella_sd_reset_data_line(struct mmc_host *mmc)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
+ struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
+ u32 counter = 0;
+ u8 reset_reg;
+
+ ambsd_dbg(pslotinfo, "Enter %s with state %u\n",
+ __func__, pslotinfo->state);
+
+ amba_writeb(pinfo->regbase + SD_RESET_OFFSET, SD_RESET_DAT);
+ while (1) {
+ reset_reg = amba_readb(pinfo->regbase + SD_RESET_OFFSET);
+ if (!(reset_reg & SD_RESET_DAT))
+ break;
+ counter++;
+ if (counter > CONFIG_SD_AMBARELLA_WAIT_COUNTER_LIMIT) {
+ ambsd_warn(pslotinfo, "Wait SD_RESET_DAT...\n");
+ pinfo->reset_error = 1;
+ break;
+ }
+ }
+
+ ambsd_dbg(pslotinfo, "Exit %s with counter %u\n", __func__, counter);
+}
+
+static inline void ambarella_sd_data_done(
+ struct ambarella_sd_mmc_info *pslotinfo, u16 nis, u16 eis)
+{
+ struct mmc_data *data;
+
+ if ((pslotinfo->state == AMBA_SD_STATE_CMD) &&
+ ((pslotinfo->cmd_reg & 0x3) == SD_CMD_RSP_48BUSY)) {
+ if (eis) {
+ pslotinfo->state = AMBA_SD_STATE_ERR;
+ } else {
+ pslotinfo->state = AMBA_SD_STATE_IDLE;
+ }
+ wake_up(&pslotinfo->wait);
+ return;
+ }
+ if (pslotinfo->mrq == NULL) {
+ ambsd_dbg(pslotinfo, "%s: mrq is NULL, nis[0x%x] eis[0x%x]\n",
+ __func__, nis, eis);
+ return;
+ }
+ if (pslotinfo->mrq->data == NULL) {
+ ambsd_dbg(pslotinfo, "%s: data is NULL, nis[0x%x] eis[0x%x]\n",
+ __func__, nis, eis);
+ return;
+ }
+
+ data = pslotinfo->mrq->data;
+ if (eis) {
+ if (eis & SD_EIS_DATA_BIT_ERR) {
+ data->error = -EILSEQ;
+ } else if (eis & SD_EIS_DATA_CRC_ERR) {
+ data->error = -EILSEQ;
+ } else if (eis & SD_EIS_ADMA_ERR) {
+ data->error = -EILSEQ;
+ } else if (eis & SD_EIS_DATA_TMOUT_ERR) {
+ data->error = -ETIMEDOUT;
+ } else {
+ data->error = -EIO;
+ }
+#ifdef CONFIG_SD_AMBARELLA_DEBUG_VERBOSE
+ ambsd_err(pslotinfo, "%s: CMD[%u] get eis[0x%x]\n", __func__,
+ pslotinfo->mrq->cmd->opcode, eis);
+#endif
+ pslotinfo->state = AMBA_SD_STATE_ERR;
+ wake_up(&pslotinfo->wait);
+ return;
+ } else {
+ data->bytes_xfered = pslotinfo->dma_size;
+ }
+
+ pslotinfo->state = AMBA_SD_STATE_IDLE;
+ wake_up(&pslotinfo->wait);
+}
+
+static inline void ambarella_sd_cmd_done(
+ struct ambarella_sd_mmc_info *pslotinfo, u16 nis, u16 eis)
+{
+ struct mmc_command *cmd;
+ u32 rsp0, rsp1, rsp2, rsp3;
+ struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
+ u16 ac12es;
+
+ if (pslotinfo->mrq == NULL) {
+ ambsd_dbg(pslotinfo, "%s: mrq is NULL, nis[0x%x] eis[0x%x]\n",
+ __func__, nis, eis);
+ return;
+ }
+ if (pslotinfo->mrq->cmd == NULL) {
+ ambsd_dbg(pslotinfo, "%s: cmd is NULL, nis[0x%x] eis[0x%x]\n",
+ __func__, nis, eis);
+ return;
+ }
+
+ cmd = pslotinfo->mrq->cmd;
+ if (eis) {
+ if (eis & SD_EIS_CMD_BIT_ERR) {
+ cmd->error = -EILSEQ;
+ } else if (eis & SD_EIS_CMD_CRC_ERR) {
+ cmd->error = -EILSEQ;
+ } else if (eis & SD_EIS_CMD_TMOUT_ERR) {
+ cmd->error = -ETIMEDOUT;
+ } else if (eis & SD_EIS_ACMD12_ERR) {
+ ac12es = amba_readl(pinfo->regbase + SD_AC12ES_OFFSET);
+ if (ac12es & SD_AC12ES_TMOUT_ERROR) {
+ cmd->error = -ETIMEDOUT;
+ } else if (eis & SD_AC12ES_CRC_ERROR) {
+ cmd->error = -EILSEQ;
+ } else {
+ cmd->error = -EIO;
+ }
+
+ if (pslotinfo->mrq->stop) {
+ pslotinfo->mrq->stop->error = cmd->error;
+ } else {
+ ambsd_err(pslotinfo, "%s NULL stop 0x%x %u\n",
+ __func__, ac12es, cmd->error);
+ }
+ } else {
+ cmd->error = -EIO;
+ }
+#ifdef CONFIG_SD_AMBARELLA_DEBUG_VERBOSE
+ ambsd_err(pslotinfo, "%s: CMD[%u] get eis[0x%x]\n", __func__,
+ pslotinfo->mrq->cmd->opcode, eis);
+#endif
+ pslotinfo->state = AMBA_SD_STATE_ERR;
+ wake_up(&pslotinfo->wait);
+ return;
+ }
+
+ if (cmd->flags & MMC_RSP_136) {
+ rsp0 = amba_readl(pinfo->regbase + SD_RSP0_OFFSET);
+ rsp1 = amba_readl(pinfo->regbase + SD_RSP1_OFFSET);
+ rsp2 = amba_readl(pinfo->regbase + SD_RSP2_OFFSET);
+ rsp3 = amba_readl(pinfo->regbase + SD_RSP3_OFFSET);
+ cmd->resp[0] = ((rsp3 << 8) | (rsp2 >> 24));
+ cmd->resp[1] = ((rsp2 << 8) | (rsp1 >> 24));
+ cmd->resp[2] = ((rsp1 << 8) | (rsp0 >> 24));
+ cmd->resp[3] = (rsp0 << 8);
+ } else {
+ cmd->resp[0] = amba_readl(pinfo->regbase + SD_RSP0_OFFSET);
+ }
+
+ if ((pslotinfo->state == AMBA_SD_STATE_CMD) &&
+ ((pslotinfo->cmd_reg & 0x3) != SD_CMD_RSP_48BUSY)) {
+ pslotinfo->state = AMBA_SD_STATE_IDLE;
+ wake_up(&pslotinfo->wait);
+ }
+}
+
+static void ambarella_sd_set_clk(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
+ struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
+ u32 sd_clk, desired_clk, actual_clk, bneed_div = 1;
+ u16 clk_div = 0x0000;
+
+ ambarella_sd_clear_clken(mmc);
+ if (ios->clock != 0) {
+ desired_clk = ios->clock;
+ if (desired_clk > mmc->f_max)
+ desired_clk = mmc->f_max;
+
+ if (desired_clk < 10000000) {
+ /* Below 10Mhz, divide by sd controller */
+ clk_set_rate(pinfo->clk, mmc->f_max);
+ } else {
+ clk_set_rate(pinfo->clk, desired_clk);
+ actual_clk = clk_get_rate(pinfo->clk);
+ bneed_div = 0;
+ }
+
+ if (bneed_div) {
+ sd_clk = clk_get_rate(pinfo->clk);
+ for (clk_div = 0x0; clk_div <= 0x80;) {
+ if (clk_div == 0)
+ actual_clk = sd_clk;
+ else
+ actual_clk = sd_clk / (clk_div << 1);
+
+ if (actual_clk <= desired_clk)
+ break;
+
+ if (clk_div >= 0x80)
+ break;
+
+ if (clk_div == 0x0)
+ clk_div = 0x1;
+ else
+ clk_div <<= 1;
+ }
+ }
+ ambsd_dbg(pslotinfo, "sd_pll = %lu.\n", clk_get_rate(pinfo->clk));
+ ambsd_dbg(pslotinfo, "desired_clk = %u.\n", desired_clk);
+ ambsd_dbg(pslotinfo, "actual_clk = %u.\n", actual_clk);
+ ambsd_dbg(pslotinfo, "clk_div = %u.\n", clk_div);
+ ambarella_sd_set_iclk(mmc, clk_div);
+ ambarella_sd_set_clken(mmc);
+ }
+}
+
+static void ambarella_sd_set_pwr(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
+ struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
+
+ if (ios->power_mode == MMC_POWER_OFF) {
+ ambarella_sd_reset_all(pslotinfo->mmc);
+ amba_writeb(pinfo->regbase + SD_PWR_OFFSET, SD_PWR_OFF);
+
+ if (gpio_is_valid(pslotinfo->pwr_gpio)) {
+ gpio_set_value_cansleep(pslotinfo->pwr_gpio,
+ !pslotinfo->pwr_gpio_active);
+ msleep(300);
+ }
+
+ if (gpio_is_valid(pslotinfo->v18_gpio)) {
+ gpio_set_value_cansleep(pslotinfo->v18_gpio,
+ !pslotinfo->v18_gpio_active);
+ msleep(10);
+ }
+ } else if (ios->power_mode == MMC_POWER_UP) {
+ if (gpio_is_valid(pslotinfo->v18_gpio)) {
+ gpio_set_value_cansleep(pslotinfo->v18_gpio,
+ !pslotinfo->v18_gpio_active);
+ msleep(10);
+ }
+
+ if (gpio_is_valid(pslotinfo->pwr_gpio)) {
+ gpio_set_value_cansleep(pslotinfo->pwr_gpio,
+ pslotinfo->pwr_gpio_active);
+ msleep(300);
+ }
+
+ amba_writeb(pinfo->regbase + SD_PWR_OFFSET,
+ (SD_PWR_ON | SD_PWR_3_3V));
+ } else if (ios->power_mode == MMC_POWER_ON) {
+ switch (1 << ios->vdd) {
+ case MMC_VDD_165_195:
+ case MMC_VDD_32_33:
+ case MMC_VDD_33_34:
+ break;
+ default:
+ ambsd_err(pslotinfo, "%s Wrong voltage[%u]!\n",
+ __func__, ios->vdd);
+ break;
+ }
+ }
+ msleep(1);
+ ambsd_dbg(pslotinfo, "pwr = 0x%x.\n",
+ amba_readb(pinfo->regbase + SD_PWR_OFFSET));
+}
+
+static void ambarella_sd_set_phy_timing(
+ struct ambarella_sd_controller_info *pinfo, int mode)
+{
+ u32 i, val0, val1;
+
+ if (pinfo->phy_type < 0 || !pinfo->phy_timing || pinfo->phy_timing_num == 0)
+ return;
+
+ for (i = 0; i < pinfo->phy_timing_num; i++) {
+ if (pinfo->phy_timing[i].mode & (0x1 << mode))
+ break;
+ }
+
+ /* phy setting is not defined in DTS for this mode, so we use the
+ * default phy setting defined for DS mode. */
+ if (i >= pinfo->phy_timing_num)
+ i = 0;
+
+ val0 = pinfo->phy_timing[i].val0;
+ val1 = pinfo->phy_timing[i].val1;
+
+ if (pinfo->phy_type == 0) {
+ /*using rct sd phy*/
+ amba_writel(pinfo->timing_reg, val0 | 0x02000000);
+ amba_writel(pinfo->timing_reg, val0);
+ amba_writel(pinfo->regbase + SD_LAT_CTRL_OFFSET, val1);
+ } else if(pinfo->phy_type == 1) {
+ /*using sd controller as sd phy*/
+ amba_writel(pinfo->regbase + SD_DELAY_SEL_L, val0);
+ amba_writel(pinfo->regbase + SD_DELAY_SEL_H, val1);
+ } else {
+ u32 ms_delay = amba_rct_readl(pinfo->timing_reg);
+ ms_delay &= val0;
+ ms_delay |= val1;
+ amba_rct_writel(pinfo->timing_reg, ms_delay);
+ }
+}
+
+static void ambarella_sd_set_bus(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
+ struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
+ u8 hostr = 0;
+
+ hostr = amba_readb(pinfo->regbase + SD_HOST_OFFSET);
+ if (ios->bus_width == MMC_BUS_WIDTH_8) {
+ hostr |= SD_HOST_8BIT;
+ hostr &= ~(SD_HOST_4BIT);
+ } else if (ios->bus_width == MMC_BUS_WIDTH_4) {
+ hostr &= ~(SD_HOST_8BIT);
+ hostr |= SD_HOST_4BIT;
+ } else if (ios->bus_width == MMC_BUS_WIDTH_1) {
+ hostr &= ~(SD_HOST_8BIT);
+ hostr &= ~(SD_HOST_4BIT);
+ } else {
+ ambsd_err(pslotinfo, "Unknown bus_width[%u], assume 1bit.\n",
+ ios->bus_width);
+ hostr &= ~(SD_HOST_8BIT);
+ hostr &= ~(SD_HOST_4BIT);
+ }
+
+ hostr &= ~SD_HOST_HIGH_SPEED;
+ switch (ios->timing) {
+ case MMC_TIMING_LEGACY:
+ case MMC_TIMING_MMC_HS:
+ case MMC_TIMING_MMC_HS200:
+ case MMC_TIMING_SD_HS:
+ case MMC_TIMING_UHS_SDR12:
+ case MMC_TIMING_UHS_SDR25:
+ case MMC_TIMING_UHS_SDR50:
+ case MMC_TIMING_UHS_SDR104:
+ amba_clrbitsl(pinfo->regbase + SD_XC_CTR_OFFSET,
+ SD_XC_CTR_DDR_EN);
+ amba_clrbitsw(pinfo->regbase + SD_HOST2_OFFSET, 0x0004);
+ break;
+ case MMC_TIMING_UHS_DDR50:
+ hostr |= SD_HOST_HIGH_SPEED;
+ amba_setbitsl(pinfo->regbase + SD_XC_CTR_OFFSET,
+ SD_XC_CTR_DDR_EN);
+ amba_setbitsw(pinfo->regbase + SD_HOST2_OFFSET, 0x0004);
+ break;
+ default:
+ amba_clrbitsl(pinfo->regbase + SD_XC_CTR_OFFSET,
+ SD_XC_CTR_DDR_EN);
+ amba_clrbitsw(pinfo->regbase + SD_HOST2_OFFSET, 0x0004);
+ ambsd_err(pslotinfo, "Unknown timing[%d], assume legacy.\n",
+ ios->timing);
+ break;
+ }
+
+ amba_writeb(pinfo->regbase + SD_HOST_OFFSET, hostr);
+ ambsd_dbg(pslotinfo, "hostr = 0x%x.\n", hostr);
+
+ if(!pinfo->auto_tuning || ios->timing == MMC_TIMING_LEGACY
+ || ios->timing == MMC_TIMING_MMC_HS || ios->timing == MMC_TIMING_SD_HS)
+ ambarella_sd_set_phy_timing(pinfo, ios->timing);
+
+}
+
+static void ambarella_sd_check_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
+ struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
+
+ if ((pinfo->controller_ios.power_mode != ios->power_mode) ||
+ (pinfo->controller_ios.vdd != ios->vdd) ||
+ (pslotinfo->state == AMBA_SD_STATE_RESET)) {
+ ambarella_sd_set_pwr(mmc, ios);
+ pinfo->controller_ios.power_mode = ios->power_mode;
+ pinfo->controller_ios.vdd = ios->vdd;
+ }
+
+ if ((pinfo->controller_ios.clock != ios->clock) ||
+ (pslotinfo->state == AMBA_SD_STATE_RESET)) {
+ ambarella_sd_set_clk(mmc, ios);
+ pinfo->controller_ios.clock = ios->clock;
+ }
+
+ if ((pinfo->controller_ios.bus_width != ios->bus_width) ||
+ (pinfo->controller_ios.timing != ios->timing) ||
+ (pslotinfo->state == AMBA_SD_STATE_RESET)) {
+ ambarella_sd_set_bus(mmc, ios);
+ pinfo->controller_ios.bus_width = ios->bus_width;
+ pinfo->controller_ios.timing = ios->timing;
+ }
+
+ if (pslotinfo->state == AMBA_SD_STATE_RESET) {
+ pslotinfo->state = AMBA_SD_STATE_IDLE;
+ }
+}
+
+static void ambarella_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ ambarella_sd_request_bus(mmc);
+ ambarella_sd_check_ios(mmc, ios);
+ ambarella_sd_release_bus(mmc);
+}
+
+static void ambarella_sd_recovery(struct mmc_host *mmc)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
+ struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
+ u32 latency = 0, sbc_reg = 0, timing_reg0 = 0, timing_reg1 = 0;
+ u32 sd_delay_sel0 = 0, sd_delay_sel1 = 0, divisor = 0;
+
+ /*save the sd timing register*/
+ if(pinfo->phy_type == 0 && pinfo->timing_reg) {
+ latency = amba_readl(pinfo->regbase + SD_LAT_CTRL_OFFSET);
+ timing_reg0 = amba_readl(pinfo->timing_reg);
+ timing_reg1 = amba_readl(pinfo->timing_reg + 4);
+ sbc_reg = amba_readl(pinfo->sbc_reg);
+ } else if(pinfo->phy_type == 1) {
+ sd_delay_sel0 = amba_readl(pinfo->regbase + SD_DELAY_SEL_L);
+ sd_delay_sel1 = amba_readl(pinfo->regbase + SD_DELAY_SEL_H);
+ } else if(pinfo->phy_type == 2 && pinfo->timing_reg) {
+ timing_reg0 = amba_readl(pinfo->timing_reg);
+ }
+
+ divisor = (amba_readw(pinfo->regbase + SD_CLK_OFFSET) & 0xff00) >> 8;
+
+ ambarella_sd_reset_all(mmc);
+
+ /*restore clk*/
+ ambarella_sd_clear_clken(mmc);
+ ambarella_sd_set_iclk(mmc, divisor);
+ ambarella_sd_set_clken(mmc);
+ ambarella_sd_set_bus(mmc, &pinfo->controller_ios);
+
+ /*restore the sd timing register*/
+ if(pinfo->phy_type == 0 && pinfo->timing_reg) {
+ amba_writel(pinfo->regbase + SD_LAT_CTRL_OFFSET, latency);
+ amba_writel(pinfo->timing_reg, timing_reg0);
+ amba_writel(pinfo->timing_reg + 4, timing_reg1);
+ amba_writel(pinfo->sbc_reg, sbc_reg);
+ } else if(pinfo->phy_type == 1) {
+ amba_writel(pinfo->regbase + SD_DELAY_SEL_L, sd_delay_sel0);
+ amba_writel(pinfo->regbase + SD_DELAY_SEL_H, sd_delay_sel1);
+ } else if(pinfo->phy_type == 2 && pinfo->timing_reg) {
+ amba_writel(pinfo->timing_reg, timing_reg0);
+ }
+
+}
+
+static u32 ambarella_sd_check_cd(struct mmc_host *mmc)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
+ struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
+ int cdpin;
+
+ if (pslotinfo->fixed_cd != -1) {
+ cdpin = !!pslotinfo->fixed_cd;
+ } else {
+ cdpin = mmc_gpio_get_cd(mmc);
+ if (cdpin < 0) {
+ cdpin = amba_readl(pinfo->regbase + SD_STA_OFFSET);
+ cdpin &= SD_STA_CARD_INSERTED;
+ }
+ }
+
+ return !!cdpin;
+}
+
+static inline void ambarella_sd_prepare_tmo(
+ struct ambarella_sd_mmc_info *pslotinfo,
+ struct mmc_data *pmmcdata)
+{
+ struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
+
+ pslotinfo->tmo = CONFIG_SD_AMBARELLA_TIMEOUT_VAL;
+ pslotinfo->wait_tmo = min_t(u32, pinfo->default_wait_tmo, CONFIG_SD_AMBARELLA_MAX_TIMEOUT);
+ pslotinfo->sta_counter = pinfo->default_wait_tmo / CONFIG_SD_AMBARELLA_MAX_TIMEOUT + 1;
+
+ ambsd_dbg(pslotinfo, "timeout_ns = %u, timeout_clks = %u, "
+ "wait_tmo = %u, tmo = %u, sta_counter = %u.\n",
+ pmmcdata->timeout_ns, pmmcdata->timeout_clks,
+ pslotinfo->wait_tmo, pslotinfo->tmo, pslotinfo->sta_counter);
+}
+
+static inline void ambarella_sd_pre_cmd(struct ambarella_sd_mmc_info *pslotinfo)
+{
+ struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
+
+ pslotinfo->state = AMBA_SD_STATE_CMD;
+ pslotinfo->sg_len = 0;
+ pslotinfo->sg = NULL;
+ pslotinfo->blk_sz = 0;
+ pslotinfo->blk_cnt = 0;
+ pslotinfo->arg_reg = 0;
+ pslotinfo->cmd_reg = 0;
+ pslotinfo->sta_reg = 0;
+ pslotinfo->tmo = CONFIG_SD_AMBARELLA_TIMEOUT_VAL;
+ pslotinfo->wait_tmo = (1 * HZ);
+ pslotinfo->xfr_reg = 0;
+ pslotinfo->dma_address = 0;
+ pslotinfo->dma_size = 0;
+
+ if (pslotinfo->mrq->stop) {
+ if (likely(pslotinfo->mrq->stop->opcode ==
+ MMC_STOP_TRANSMISSION)) {
+ pslotinfo->xfr_reg = SD_XFR_AC12_EN;
+ } else {
+ ambsd_err(pslotinfo, "%s strange stop cmd%u\n",
+ __func__, pslotinfo->mrq->stop->opcode);
+ }
+ }
+
+ if (!(pslotinfo->mrq->cmd->flags & MMC_RSP_PRESENT))
+ pslotinfo->cmd_reg = SD_CMD_RSP_NONE;
+ else if (pslotinfo->mrq->cmd->flags & MMC_RSP_136)
+ pslotinfo->cmd_reg = SD_CMD_RSP_136;
+ else if (pslotinfo->mrq->cmd->flags & MMC_RSP_BUSY)
+ pslotinfo->cmd_reg = SD_CMD_RSP_48BUSY;
+ else
+ pslotinfo->cmd_reg = SD_CMD_RSP_48;
+ if (pslotinfo->mrq->cmd->flags & MMC_RSP_CRC)
+ pslotinfo->cmd_reg |= SD_CMD_CHKCRC;
+ if (pslotinfo->mrq->cmd->flags & MMC_RSP_OPCODE)
+ pslotinfo->cmd_reg |= SD_CMD_CHKIDX;
+ pslotinfo->cmd_reg |= SD_CMD_IDX(pslotinfo->mrq->cmd->opcode);
+ pslotinfo->arg_reg = pslotinfo->mrq->cmd->arg;
+
+ if (pslotinfo->mrq->data) {
+ pslotinfo->state = AMBA_SD_STATE_DATA;
+ ambarella_sd_prepare_tmo(pslotinfo, pslotinfo->mrq->data);
+ pslotinfo->blk_sz = (pslotinfo->mrq->data->blksz & 0xFFF);
+ pslotinfo->dma_size = pslotinfo->mrq->data->blksz *
+ pslotinfo->mrq->data->blocks;
+ pslotinfo->sg_len = pslotinfo->mrq->data->sg_len;
+ pslotinfo->sg = pslotinfo->mrq->data->sg;
+ pslotinfo->xfr_reg |= SD_XFR_DMA_EN;
+ pslotinfo->cmd_reg |= SD_CMD_DATA;
+ pslotinfo->blk_cnt = pslotinfo->mrq->data->blocks;
+ if (pslotinfo->blk_cnt > 1) {
+ pslotinfo->xfr_reg |= SD_XFR_MUL_SEL;
+ pslotinfo->xfr_reg |= SD_XFR_BLKCNT_EN;
+ }
+ if (pslotinfo->mrq->data->flags & MMC_DATA_STREAM) {
+ pslotinfo->xfr_reg |= SD_XFR_MUL_SEL;
+ pslotinfo->xfr_reg &= ~SD_XFR_BLKCNT_EN;
+ }
+ if (pslotinfo->mrq->data->flags & MMC_DATA_WRITE) {
+ pslotinfo->xfr_reg &= ~SD_XFR_CTH_SEL;
+ pslotinfo->sta_reg = (SD_STA_WRITE_XFR_ACTIVE |
+ SD_STA_DAT_ACTIVE);
+ if (pslotinfo->use_adma == 1) {
+ pslotinfo->pre_dma = &ambarella_sd_pre_sg_to_adma;
+ pslotinfo->post_dma = &ambarella_sd_post_sg_to_adma;
+ } else {
+ pslotinfo->pre_dma = &ambarella_sd_pre_sg_to_dma;
+ pslotinfo->post_dma = &ambarella_sd_post_sg_to_dma;
+ }
+ } else {
+ pslotinfo->xfr_reg |= SD_XFR_CTH_SEL;
+ pslotinfo->sta_reg = (SD_STA_READ_XFR_ACTIVE |
+ SD_STA_DAT_ACTIVE);
+ if (pslotinfo->use_adma == 1) {
+ pslotinfo->pre_dma = &ambarella_sd_pre_adma_to_sg;
+ pslotinfo->post_dma = &ambarella_sd_post_adma_to_sg;
+ } else {
+ pslotinfo->pre_dma = &ambarella_sd_pre_dma_to_sg;
+ pslotinfo->post_dma = &ambarella_sd_post_dma_to_sg;
+ }
+ }
+ pslotinfo->pre_dma(pslotinfo);
+ if (pinfo->dma_fix) {
+ pslotinfo->dma_address |= pinfo->dma_fix;
+ }
+ }
+}
+
+static inline void ambarella_sd_send_cmd(struct ambarella_sd_mmc_info *pslotinfo)
+{
+ struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
+ u32 valid_request, sta_reg, tmpreg, counter = 0;
+ long timeout;
+
+ ambarella_sd_request_bus(pslotinfo->mmc);
+
+ valid_request = ambarella_sd_check_cd(pslotinfo->mmc);
+ ambsd_dbg(pslotinfo, "cmd = %u valid_request = %u.\n",
+ pslotinfo->mrq->cmd->opcode, valid_request);
+ if (!valid_request) {
+ pslotinfo->mrq->cmd->error = -ENOMEDIUM;
+ pslotinfo->state = AMBA_SD_STATE_ERR;
+ goto ambarella_sd_send_cmd_exit;
+ }
+
+ ambarella_sd_check_ios(pslotinfo->mmc, &pslotinfo->mmc->ios);
+ if (pslotinfo->mrq->data) {
+ while (1) {
+ sta_reg = amba_readl(pinfo->regbase + SD_STA_OFFSET);
+ if ((sta_reg & SD_STA_CMD_INHIBIT_DAT) == 0) {
+ break;
+ }
+ counter++;
+ if (counter > CONFIG_SD_AMBARELLA_WAIT_COUNTER_LIMIT) {
+ if(pslotinfo->mrq->cmd->opcode != MMC_SEND_TUNING_BLOCK)
+ ambsd_warn(pslotinfo,
+ "Wait SD_STA_CMD_INHIBIT_DAT...\n");
+ pslotinfo->state = AMBA_SD_STATE_ERR;
+ pslotinfo->mrq->data->error = -EILSEQ;
+ pinfo->reset_error = 1;
+ goto ambarella_sd_send_cmd_exit;
+ }
+ }
+
+ amba_writeb(pinfo->regbase + SD_TMO_OFFSET, pslotinfo->tmo);
+ if (pslotinfo->use_adma == 1) {
+ amba_setbitsb(pinfo->regbase + SD_HOST_OFFSET,
+ SD_HOST_ADMA);
+ amba_writel(pinfo->regbase + SD_ADMA_ADDR_OFFSET,
+ pslotinfo->dma_address);
+ } else {
+ amba_clrbitsb(pinfo->regbase + SD_HOST_OFFSET,
+ SD_HOST_ADMA);
+ amba_writel(pinfo->regbase + SD_DMA_ADDR_OFFSET,
+ pslotinfo->dma_address);
+ }
+ amba_write2w(pinfo->regbase + SD_BLK_SZ_OFFSET,
+ pslotinfo->blk_sz, pslotinfo->blk_cnt);
+ amba_writel(pinfo->regbase + SD_ARG_OFFSET, pslotinfo->arg_reg);
+ amba_write2w(pinfo->regbase + SD_XFR_OFFSET,
+ pslotinfo->xfr_reg, pslotinfo->cmd_reg);
+ } else {
+ while (1) {
+ sta_reg = amba_readl(pinfo->regbase + SD_STA_OFFSET);
+ if ((sta_reg & SD_STA_CMD_INHIBIT_CMD) == 0) {
+ break;
+ }
+ counter++;
+ if (counter > CONFIG_SD_AMBARELLA_WAIT_COUNTER_LIMIT) {
+ ambsd_warn(pslotinfo,
+ "Wait SD_STA_CMD_INHIBIT_CMD...\n");
+ pslotinfo->state = AMBA_SD_STATE_ERR;
+ pslotinfo->mrq->cmd->error = -EILSEQ;
+ pinfo->reset_error = 1;
+ goto ambarella_sd_send_cmd_exit;
+ }
+ }
+
+ amba_writel(pinfo->regbase + SD_ARG_OFFSET, pslotinfo->arg_reg);
+ amba_write2w(pinfo->regbase + SD_XFR_OFFSET,
+ 0x00, pslotinfo->cmd_reg);
+ }
+
+ambarella_sd_send_cmd_exit:
+ if (pslotinfo->state == AMBA_SD_STATE_CMD) {
+ timeout = wait_event_timeout(pslotinfo->wait,
+ (pslotinfo->state != AMBA_SD_STATE_CMD),
+ pslotinfo->wait_tmo);
+ if (pslotinfo->state == AMBA_SD_STATE_CMD) {
+ ambsd_err(pslotinfo,
+ "cmd%u %u@[%ld:%u], sta=0x%04x\n",
+ pslotinfo->mrq->cmd->opcode,
+ pslotinfo->state, timeout, pslotinfo->wait_tmo,
+ amba_readl(pinfo->regbase + SD_STA_OFFSET));
+ pslotinfo->mrq->cmd->error = -ETIMEDOUT;
+ }
+ } else if (pslotinfo->state == AMBA_SD_STATE_DATA) {
+ do {
+ timeout = wait_event_timeout(pslotinfo->wait,
+ (pslotinfo->state != AMBA_SD_STATE_DATA),
+ pslotinfo->wait_tmo);
+ sta_reg = amba_readl(pinfo->regbase + SD_STA_OFFSET);
+ if ((pslotinfo->state == AMBA_SD_STATE_DATA) &&
+ (sta_reg & pslotinfo->sta_reg)) {
+ ambsd_rtdbg(pslotinfo, "data%u %u@"
+ "[%ld:%u:%u:%u], sta=0x%04x:0x%04x\n",
+ pslotinfo->mrq->cmd->opcode,
+ pslotinfo->state, timeout,
+ pslotinfo->wait_tmo,
+ pslotinfo->mrq->data->timeout_ns,
+ pslotinfo->mrq->data->timeout_clks,
+ sta_reg, pslotinfo->sta_reg);
+ ambsd_rtdbg(pslotinfo,
+ "DMA %u in %u sg [0x%08x:0x%08x]\n",
+ pslotinfo->dma_size,
+ pslotinfo->sg_len,
+ pslotinfo->dma_address,
+ pslotinfo->dma_size);
+ tmpreg = amba_readw(pinfo->regbase +
+ SD_BLK_CNT_OFFSET);
+ if (tmpreg) {
+ ambsd_rtdbg(pslotinfo,
+ "SD_DMA_ADDR_OFFSET[0x%08X]\n",
+ amba_readl(pinfo->regbase +
+ SD_DMA_ADDR_OFFSET));
+ amba_writel((pinfo->regbase +
+ SD_DMA_ADDR_OFFSET),
+ amba_readl(pinfo->regbase +
+ SD_DMA_ADDR_OFFSET));
+ } else {
+ ambsd_rtdbg(pslotinfo,
+ "SD_DATA_OFFSET[0x%08X]\n",
+ amba_readl(pinfo->regbase +
+ SD_DATA_OFFSET));
+ ambsd_rtdbg(pslotinfo,
+ "SD_STA_OFFSET[0x%08X]\n",
+ amba_readl(pinfo->regbase +
+ SD_STA_OFFSET));
+ }
+ } else {
+ break;
+ }
+ } while (pslotinfo->sta_counter--);
+ if (pslotinfo->state == AMBA_SD_STATE_DATA) {
+ ambsd_err(pslotinfo,
+ "data%u %u@%u, sta=0x%04x:0x%04x\n",
+ pslotinfo->mrq->cmd->opcode,
+ pslotinfo->state,
+ pslotinfo->wait_tmo,
+ sta_reg, pslotinfo->sta_reg);
+ pslotinfo->mrq->data->error = -ETIMEDOUT;
+ }
+ }
+}
+
+static inline void ambarella_sd_post_cmd(struct ambarella_sd_mmc_info *pslotinfo)
+{
+ struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
+
+ if (pslotinfo->state == AMBA_SD_STATE_IDLE) {
+ ambarella_sd_release_bus(pslotinfo->mmc);
+ if (pslotinfo->mrq->data) {
+ pslotinfo->post_dma(pslotinfo);
+ }
+ } else {
+#ifdef CONFIG_SD_AMBARELLA_DEBUG_VERBOSE
+ u32 counter = 0;
+
+ ambsd_err(pslotinfo, "CMD%u retries[%u] state[%u].\n",
+ pslotinfo->mrq->cmd->opcode,
+ pslotinfo->mrq->cmd->retries,
+ pslotinfo->state);
+ for (counter = 0; counter < 0x100; counter += 4) {
+ ambsd_err(pslotinfo, "0x%04x: 0x%08x\n",
+ counter, amba_readl(pinfo->regbase + counter));
+ }
+ ambarella_sd_show_info(pslotinfo);
+#endif
+ if (pinfo->reset_error) {
+ ambarella_sd_recovery(pslotinfo->mmc);
+ //ambarella_sd_reset_all(pslotinfo->mmc);
+ }
+ ambarella_sd_release_bus(pslotinfo->mmc);
+ }
+}
+
+static void ambarella_sd_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
+
+ pslotinfo->mrq = mrq;
+ ambarella_sd_pre_cmd(pslotinfo);
+ ambarella_sd_send_cmd(pslotinfo);
+ ambarella_sd_post_cmd(pslotinfo);
+ pslotinfo->mrq = NULL;
+ mmc_request_done(mmc, mrq);
+}
+
+static int ambarella_sd_get_ro(struct mmc_host *mmc)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
+ struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
+ int wpspl;
+
+ ambarella_sd_request_bus(mmc);
+
+ if (pslotinfo->fixed_wp != -1) {
+ wpspl = !!pslotinfo->fixed_wp;
+ } else {
+ wpspl = mmc_gpio_get_ro(mmc);
+ if (wpspl < 0) {
+ wpspl = amba_readl(pinfo->regbase + SD_STA_OFFSET);
+ wpspl &= SD_STA_WPS_PL;
+ }
+ }
+
+ ambarella_sd_release_bus(mmc);
+
+ ambsd_dbg(pslotinfo, "RO[%u].\n", wpspl);
+ return !!wpspl;
+}
+
+static int ambarella_sd_get_cd(struct mmc_host *mmc)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
+ u32 cdpin;
+
+ ambarella_sd_request_bus(mmc);
+ cdpin = ambarella_sd_check_cd(mmc);
+ ambarella_sd_release_bus(mmc);
+
+ ambsd_dbg(pslotinfo, "CD[%u].\n", cdpin);
+ return cdpin ? 1 : 0;
+}
+
+static void ambarella_sd_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{
+ if (enable)
+ ambarella_sd_enable_int(mmc, SD_NISEN_CARD);
+ else
+ ambarella_sd_disable_int(mmc, SD_NISEN_CARD);
+}
+
+static int ambarella_sd_ssvs(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ int retval = 0;
+ struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
+ struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
+
+ ambarella_sd_request_bus(mmc);
+ if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
+ amba_writeb(pinfo->regbase + SD_PWR_OFFSET,
+ (SD_PWR_ON | SD_PWR_3_3V));
+
+ if (gpio_is_valid(pslotinfo->v18_gpio)) {
+ gpio_set_value_cansleep(pslotinfo->v18_gpio,
+ !pslotinfo->v18_gpio_active);
+ msleep(10);
+ }
+ } else if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
+ ambarella_sd_clear_clken(mmc);
+ msleep(CONFIG_SD_AMBARELLA_VSW_PRE_SPEC);
+ amba_writeb(pinfo->regbase + SD_PWR_OFFSET,
+ (SD_PWR_ON | SD_PWR_1_8V));
+
+ if (gpio_is_valid(pslotinfo->v18_gpio)) {
+ gpio_set_value_cansleep(pslotinfo->v18_gpio,
+ pslotinfo->v18_gpio_active);
+ msleep(pinfo->switch_voltage_tmo);
+ }
+ ambarella_sd_set_clken(mmc);
+ }
+ ambarella_sd_release_bus(mmc);
+
+ return retval;
+}
+
+static int ambarella_sd_card_busy(struct mmc_host *mmc)
+{
+ int retval = 0;
+ struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
+ struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
+ u32 sta_reg;
+
+ ambarella_sd_request_bus(mmc);
+ sta_reg = amba_readl(pinfo->regbase + SD_STA_OFFSET);
+ ambsd_dbg(pslotinfo, "SD_STA_OFFSET = 0x%08X.\n", sta_reg);
+ retval = !(sta_reg & 0x1F00000);
+ ambarella_sd_release_bus(mmc);
+
+ return retval;
+}
+
+static int ambarella_send_tuning_cmd(struct mmc_host *host, u32 opcode, int *cmd_error)
+{
+ struct mmc_request mrq = {NULL};
+ struct mmc_command cmd = {0};
+ struct mmc_data data = {0};
+ struct scatterlist sg;
+ struct mmc_ios *ios = &host->ios;
+ const u8 *tuning_block_pattern;
+ int size, err = 0;
+ u8 *data_buf;
+
+ if (ios->bus_width == MMC_BUS_WIDTH_8) {
+ tuning_block_pattern = tuning_blk_pattern_8bit;
+ size = sizeof(tuning_blk_pattern_8bit);
+ } else if (ios->bus_width == MMC_BUS_WIDTH_4) {
+ tuning_block_pattern = tuning_blk_pattern_4bit;
+ size = sizeof(tuning_blk_pattern_4bit);
+ } else
+ return -EINVAL;
+
+ data_buf = kzalloc(size, GFP_KERNEL);
+ if (!data_buf)
+ return -ENOMEM;
+
+ mrq.cmd = &cmd;
+ mrq.data = &data;
+
+ cmd.opcode = opcode;
+ cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+
+ data.blksz = size;
+ data.blocks = 1;
+ data.flags = MMC_DATA_READ;
+
+ /*
+ * According to the tuning specs, Tuning process
+ * is normally shorter 40 executions of CMD19,
+ * and timeout value should be shorter than 150 ms
+ */
+ data.timeout_ns = 150 * NSEC_PER_MSEC;
+
+ data.sg = &sg;
+ data.sg_len = 1;
+ sg_init_one(&sg, data_buf, size);
+
+ mmc_wait_for_req(host, &mrq);
+
+ if (cmd_error)
+ *cmd_error = cmd.error;
+
+ if (cmd.error) {
+ err = cmd.error;
+ goto out;
+ }
+
+ if (data.error) {
+ err = data.error;
+ goto out;
+ }
+
+ if (memcmp(data_buf, tuning_block_pattern, size))
+ err = -EIO;
+
+out:
+ kfree(data_buf);
+ return err;
+
+}
+
+static int ambarella_sd_execute_tuning(struct mmc_host *mmc, u32 opcode)
+{
+ struct ambarella_sd_mmc_info *pslotinfo = mmc_priv(mmc);
+ struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
+ u32 tmp, misc, lat, s = -1, e = 0, middle;
+ u32 best_misc = 0, best_s = -1, best_e = 0, doing_retune = 0;
+ int dly, longest_range = 0, range = 0;
+ u32 clock = pinfo->controller_ios.clock;
+
+ if(!pinfo->auto_tuning || !pinfo->timing_reg)
+ return 0;
+
+retry:
+ if (doing_retune) {
+ clock -= 10000000;
+ if (clock <= 50000000) {
+ ambsd_tuning_dbg(pslotinfo,
+ "tuning: can't find any valid timing\n");
+ return -ECANCELED;
+ }
+
+ pinfo->controller_ios.clock = clock;
+ ambarella_sd_set_clk(mmc, &pinfo->controller_ios);
+ }
+
+ if(pinfo->phy_type == 0)
+ goto phy_type_0;
+ else if (pinfo->phy_type == 1)
+ goto phy_type_1;
+ else if (pinfo->phy_type == 2)
+ goto phy_type_2;
+
+phy_type_0:
+ for (misc = 0; misc < 4; misc++) {
+ writel_relaxed(0x8001, pinfo->sbc_reg);
+
+ tmp = readl_relaxed(pinfo->timing_reg);
+ tmp &= 0x0000ffff;
+ tmp |= ((misc >> 1) & 0x1) << 19;
+ writel_relaxed(tmp | (1 << 25), pinfo->timing_reg);
+ usleep_range(5, 10);
+ writel_relaxed(tmp, pinfo->timing_reg);
+ usleep_range(5, 10);
+ lat = ((misc >> 0) & 0x1) + 1;
+ tmp = (lat << 12) | (lat << 8) | (lat << 4) | (lat << 0);
+ writel_relaxed(tmp, pinfo->regbase + SD_LAT_CTRL_OFFSET);
+
+ for (dly = 0; dly < 4; dly++) {
+ tmp = readl_relaxed(pinfo->sbc_reg);
+ tmp &= 0xfffffff9;
+// tmp |= (((dly >> 6) & 0x3) << 1);
+ tmp |= dly;
+ writel_relaxed(tmp, pinfo->sbc_reg);
+/*
+ sel = dly % 64;
+ if (sel < 0x20)
+ sel = 63 - sel;
+ else
+ sel = sel - 32;
+
+ tmp = (sel << 16) | (sel << 8) | (sel << 0);
+ writel_relaxed(tmp, pinfo->timing_reg + 4);
+*/
+ if (ambarella_send_tuning_cmd(mmc, opcode, NULL) == 0) {
+ /* Tuning is successful at this tuning point */
+ if (s == -1)
+ s = dly;
+ e = dly;
+ range++;
+ } else {
+ if (range > 0) {
+ ambsd_tuning_dbg(pslotinfo,
+ "tuning: misc[0x%x], count[%d](%d - %d)\n",
+ misc, e - s + 1, s, e);
+ }
+
+ if (range > longest_range) {
+ best_misc = misc;
+ best_s = s;
+ best_e = e;
+ longest_range = range;
+ }
+ s = -1;
+ e = range = 0;
+ }
+ }
+
+ /* in case the last timings are all working */
+ if (range > longest_range) {
+ if (range > 0) {
+ ambsd_tuning_dbg(pslotinfo,
+ "tuning last: misc[0x%x], count[%d](%d - %d)\n",
+ misc, e - s + 1, s, e);
+ }
+ best_misc = misc;
+ best_s = s;
+ best_e = e;
+ longest_range = range;
+ }
+ s = -1;
+ e = range = 0;
+ }
+
+ if (longest_range == 0) {
+ if (clock > 50000000) {
+ doing_retune = 1;
+ goto retry;
+ }
+
+ return -EIO;
+ }
+
+ middle = (best_s + best_e) / 2;
+
+// tmp = (((middle >> 6) & 0x3) << 1) | 0x8001;
+ tmp = (middle << 1) | 0x8001;
+ writel_relaxed(tmp, pinfo->sbc_reg);
+/*
+ sel = middle % 64;
+ if (sel < 0x20)
+ sel = 63 - sel;
+ else
+ sel = sel - 32;
+
+ tmp = (sel << 16) | (sel << 8) | (sel << 0);
+ writel_relaxed(tmp, pinfo->timing_reg + 4);
+*/
+ tmp = readl_relaxed(pinfo->timing_reg);
+ tmp &= 0x0000ffff;
+ tmp |= ((best_misc >> 1) & 0x1) << 19;
+ writel_relaxed(tmp | (1 << 25), pinfo->timing_reg);
+ usleep_range(5, 10);
+ writel_relaxed(tmp, pinfo->timing_reg);
+ usleep_range(5, 10);
+
+ lat = ((best_misc >> 0) & 0x1) + 1;
+ tmp = (lat << 12) | (lat << 8) | (lat << 4) | (lat << 0);
+ writel_relaxed(tmp, pinfo->regbase + SD_LAT_CTRL_OFFSET);
+
+ ambarella_sd_recovery(mmc);
+
+ return 0;
+
+phy_type_1:
+
+ /* misc: 3 bits data out delay
+ * dly: 2 bits clk mode and 3 bits clk out delay, total 5 bits;
+ */
+
+ for(misc = 0; misc < 8; misc++) {
+ for(dly = 0; dly < 32; dly++) {
+ tmp = (misc << 9) | (misc << 15) | (misc << 21) | (misc << 27);
+ amba_writel(pinfo->regbase + SD_DELAY_SEL_L, tmp);
+ tmp = ((dly >> 3) << 25) | ((dly & 0x07) << 22) | (misc << 1)
+ | (misc << 7) | (misc << 13) | (misc << 19);
+ amba_writel(pinfo->regbase + SD_DELAY_SEL_H, tmp);
+
+ if (ambarella_send_tuning_cmd(mmc, opcode, NULL) == 0) {
+ /* Tuning is successful at this tuning point */
+ if (s == -1)
+ s = dly;
+ e = dly;
+ range++;
+ } else {
+ if (range > 0) {
+ ambsd_tuning_dbg(pslotinfo,
+ "tuning last: misc[0x%x], count[%d](%d - %d)\n",
+ misc, e - s + 1, s, e);
+ }
+
+ if (range > longest_range) {
+ best_misc = misc;
+ best_s = s;
+ best_e = e;
+ longest_range = range;
+ }
+ s = -1;
+ e = range = 0;
+ }
+ }
+
+ /* in case the last timings are all working */
+ if (range > longest_range) {
+ if (range > 0) {
+ ambsd_tuning_dbg(pslotinfo,
+ "tuning last: misc[0x%x], count[%d](%d - %d)\n",
+ misc, e - s + 1, s, e);
+ }
+ best_misc = misc;
+ best_s = s;
+ best_e = e;
+ longest_range = range;
+ }
+ s = -1;
+ e = range = 0;
+ }
+
+ if (longest_range == 0) {
+ if (clock > 50000000) {
+ doing_retune = 1;
+ goto retry;
+ }
+
+ return -EIO;
+ }
+
+ middle = (best_s + best_e) / 2;
+
+ tmp = (best_misc << 9) | (best_misc << 15) | (best_misc << 21) | (best_misc << 27);
+ amba_writel(pinfo->regbase + SD_DELAY_SEL_L, tmp);
+ tmp = ((middle >> 3) << 25) | ((middle & 0x07) << 22) | (best_misc << 1)
+ | (best_misc << 7) | (best_misc << 13) | (best_misc << 19);
+ amba_writel(pinfo->regbase + SD_DELAY_SEL_H, tmp);
+
+ ambarella_sd_recovery(mmc);
+
+ return 0;
+
+phy_type_2:
+
+ /* misc: 5 bits out clock delay
+ * dly: 2 bits out data delay and 3 bits input data delay, total 5 bits;
+ */
+
+ /*This is only used for s2e sdio slot*/
+ lat = amba_readl(pinfo->timing_reg);
+ lat &= ~0xC3E0E000;
+
+ for(misc = 0; misc < 32; misc++) {
+ for(dly = 0; dly < 32; dly++) {
+ tmp = lat | ((dly >> 3) << 30) | ((dly & 0x07) << 13) | (misc << 21);
+ amba_writel(pinfo->timing_reg, tmp);
+ if (ambarella_send_tuning_cmd(mmc, opcode, NULL) == 0) {
+ /* Tuning is successful at this tuning point */
+ if (s == -1)
+ s = dly;
+ e = dly;
+ range++;
+ } else {
+ if (range > 0) {
+ ambsd_tuning_dbg(pslotinfo,
+ "tuning last: misc[0x%x], count[%d](%d - %d)\n",
+ misc, e - s + 1, s, e);
+ }
+
+ if (range > longest_range) {
+ best_misc = misc;
+ best_s = s;
+ best_e = e;
+ longest_range = range;
+ }
+ s = -1;
+ e = range = 0;
+ }
+ }
+
+ /* in case the last timings are all working */
+ if (range > longest_range) {
+ if (range > 0) {
+ ambsd_tuning_dbg(pslotinfo,
+ "tuning last: misc[0x%x], count[%d](%d - %d)\n",
+ misc, e - s + 1, s, e);
+ }
+ best_misc = misc;
+ best_s = s;
+ best_e = e;
+ longest_range = range;
+ }
+ s = -1;
+ e = range = 0;
+ }
+
+ if (longest_range == 0) {
+ if (clock > 50000000) {
+ doing_retune = 1;
+ goto retry;
+ }
+
+ return -EIO;
+ }
+
+ middle = (best_s + best_e) / 2;
+ tmp = lat | ((middle >> 3) << 30) | ((middle & 0x07) << 13) | (best_misc << 21);
+ amba_writel(pinfo->timing_reg, tmp);
+
+ ambarella_sd_recovery(mmc);
+
+ return 0;
+}
+
+static const struct mmc_host_ops ambarella_sd_host_ops = {
+ .request = ambarella_sd_request,
+ .set_ios = ambarella_sd_ios,
+ .get_ro = ambarella_sd_get_ro,
+ .get_cd = ambarella_sd_get_cd,
+ .enable_sdio_irq = ambarella_sd_enable_sdio_irq,
+ .start_signal_voltage_switch = ambarella_sd_ssvs,
+ .card_busy = ambarella_sd_card_busy,
+ .execute_tuning = ambarella_sd_execute_tuning,
+};
+
+static int ambarella_sd_system_event(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ struct ambarella_sd_mmc_info *pslotinfo;
+ struct ambarella_sd_controller_info *pinfo;
+
+ pslotinfo = container_of(nb, struct ambarella_sd_mmc_info, system_event);
+ pinfo = (struct ambarella_sd_controller_info *)pslotinfo->pinfo;
+
+ switch (val) {
+ case AMBA_EVENT_PRE_CPUFREQ:
+ pr_debug("%s[%u]: Pre Change\n", __func__, pslotinfo->slot_id);
+ down(&pslotinfo->system_event_sem);
+ break;
+
+ case AMBA_EVENT_POST_CPUFREQ:
+ pr_debug("%s[%u]: Post Change\n", __func__, pslotinfo->slot_id);
+ ambarella_sd_set_clk(pslotinfo->mmc, &pinfo->controller_ios);
+ up(&pslotinfo->system_event_sem);
+ break;
+
+ default:
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static irqreturn_t ambarella_sd_irq(int irq, void *devid)
+{
+ struct ambarella_sd_controller_info *pinfo = devid;
+ struct ambarella_sd_mmc_info *pslotinfo = NULL;
+ u16 nis, eis, slot_id;
+
+ /* Read and clear the interrupt registers */
+ amba_read2w(pinfo->regbase + SD_NIS_OFFSET, &nis, &eis);
+ amba_write2w(pinfo->regbase + SD_NIS_OFFSET, nis, eis);
+
+ if (pinfo->slot_num > 1) {
+ u32 fio_ctrl = amba_readl(pinfo->fio_reg + FIO_CTR_OFFSET);
+ slot_id = (fio_ctrl & FIO_CTR_XD) ? 1 : 0;
+ } else
+ slot_id = 0;
+
+ pslotinfo = pinfo->pslotinfo[slot_id];
+
+ ambsd_dbg(pslotinfo, "%s nis = 0x%x, eis = 0x%x & %u\n",
+ __func__, nis, eis, pslotinfo->state);
+
+ if (nis & SD_NIS_CARD) {
+ ambsd_dbg(pslotinfo, "SD_NIS_CARD\n");
+ mmc_signal_sdio_irq(pslotinfo->mmc);
+ }
+
+ if(pslotinfo->fixed_cd == -1) {
+ if (nis & SD_NIS_REMOVAL) {
+ ambsd_dbg(pslotinfo, "SD_NIS_REMOVAL\n");
+ mmc_detect_change(pslotinfo->mmc, msecs_to_jiffies(1000));
+ } else if (nis & SD_NIS_INSERT) {
+ ambsd_dbg(pslotinfo, "SD_NIS_INSERT\n");
+ mmc_detect_change(pslotinfo->mmc, msecs_to_jiffies(1000));
+ }
+ }
+
+ if (eis) {
+ if (eis & (SD_EIS_CMD_TMOUT_ERR | SD_EIS_CMD_CRC_ERR |
+ SD_EIS_CMD_BIT_ERR | SD_EIS_CMD_IDX_ERR |
+ SD_EIS_ACMD12_ERR)) {
+ ambarella_sd_reset_cmd_line(pslotinfo->mmc);
+ }
+ if (eis & (SD_EIS_DATA_TMOUT_ERR | SD_EIS_DATA_CRC_ERR)) {
+ ambarella_sd_reset_data_line(pslotinfo->mmc);
+ }
+ if (eis & (SD_EIS_DATA_BIT_ERR | SD_EIS_CURRENT_ERR)) {
+ //ambarella_sd_reset_all(pslotinfo->mmc);
+ ambarella_sd_recovery(pslotinfo->mmc);
+ }
+ if (pslotinfo->state == AMBA_SD_STATE_CMD) {
+ ambarella_sd_cmd_done(pslotinfo, nis, eis);
+ } else if (pslotinfo->state == AMBA_SD_STATE_DATA) {
+ ambarella_sd_data_done(pslotinfo, nis, eis);
+ }
+ } else {
+ if (nis & SD_NIS_CMD_DONE) {
+ ambarella_sd_cmd_done(pslotinfo, nis, eis);
+ }
+ if (nis & SD_NIS_XFR_DONE) {
+ ambarella_sd_data_done(pslotinfo, nis, eis);
+ }
+#if 0
+ if (nis & SD_NIS_DMA) {
+ amba_writel(pinfo->regbase + SD_DMA_ADDR_OFFSET,
+ amba_readl(pinfo->regbase + SD_DMA_ADDR_OFFSET));
+ }
+#endif
+ }
+
+ return IRQ_HANDLED;
+}
+
+
+/* ==========================================================================*/
+
+static int ambarella_sd_init_slot(struct device_node *np, int id,
+ struct ambarella_sd_controller_info *pinfo)
+{
+ struct device_node *save_np;
+ struct ambarella_sd_mmc_info *pslotinfo = NULL;
+ struct mmc_host *mmc;
+ enum of_gpio_flags flags;
+ u32 gpio_init_flag, hc_cap, hc_timeout_clk;
+ int global_id, retval = 0;
+
+ mmc = mmc_alloc_host(sizeof(*pslotinfo), pinfo->dev);
+ if (!mmc) {
+ dev_err(pinfo->dev, "Failed to alloc mmc host %u!\n", id);
+ return -ENOMEM;
+ }
+ pslotinfo = mmc_priv(mmc);
+ pslotinfo->mmc = mmc;
+
+ /* in order to use mmc_of_parse(), we reassign the parent
+ * of_node, this should be a workaroud. */
+ save_np = mmc->parent->of_node;
+ mmc->parent->of_node = np;
+ mmc_of_parse(mmc);
+ mmc->parent->of_node = save_np;
+
+ /* our own extra property */
+ if (of_property_read_u32(np, "amb,fixed-wp", &pslotinfo->fixed_wp) < 0)
+ pslotinfo->fixed_wp = -1;
+ if (of_property_read_u32(np, "amb,fixed-cd", &pslotinfo->fixed_cd) < 0)
+ pslotinfo->fixed_cd = -1;
+ pslotinfo->no_1_8_v = !!of_find_property(np, "no-1-8-v", NULL);
+ pslotinfo->caps_ddr = !!of_find_property(np, "amb,caps-ddr", NULL);
+ pslotinfo->caps_adma = !!of_find_property(np, "amb,caps-adma", NULL);
+ pslotinfo->force_gpio = !!of_find_property(np, "amb,force-gpio", NULL);
+ if (pslotinfo->force_gpio) {
+ pslotinfo->pinctrl = devm_pinctrl_get(pinfo->dev);
+ if (IS_ERR(pslotinfo->pinctrl)) {
+ retval = PTR_ERR(pslotinfo->pinctrl);
+ dev_err(pinfo->dev, "Can't get pinctrl: %d\n", retval);
+ goto init_slot_err1;
+ }
+
+ pslotinfo->state_work =
+ pinctrl_lookup_state(pslotinfo->pinctrl, "work");
+ if (IS_ERR(pslotinfo->state_work)) {
+ retval = PTR_ERR(pslotinfo->state_work);
+ dev_err(pinfo->dev, "Can't get pinctrl state: work\n");
+ goto init_slot_err1;
+ }
+
+ pslotinfo->state_idle =
+ pinctrl_lookup_state(pslotinfo->pinctrl, "idle");
+ if (IS_ERR(pslotinfo->state_idle)) {
+ retval = PTR_ERR(pslotinfo->state_idle);
+ dev_err(pinfo->dev, "Can't get pinctrl state: idle\n");
+ goto init_slot_err1;
+ }
+ }
+
+ /* request gpio for external power control */
+ pslotinfo->pwr_gpio = of_get_named_gpio_flags(np, "pwr-gpios", 0, &flags);
+ pslotinfo->pwr_gpio_active = !!(flags & OF_GPIO_ACTIVE_LOW);
+
+ if (gpio_is_valid(pslotinfo->pwr_gpio)) {
+ if (pslotinfo->pwr_gpio_active)
+ gpio_init_flag = GPIOF_OUT_INIT_LOW;
+ else
+ gpio_init_flag = GPIOF_OUT_INIT_HIGH;
+
+ retval = devm_gpio_request_one(pinfo->dev, pslotinfo->pwr_gpio,
+ gpio_init_flag, "sd ext power");
+ if (retval < 0) {
+ dev_err(pinfo->dev, "Failed to request pwr-gpios!\n");
+ goto init_slot_err1;
+ }
+ }
+
+ /* request gpio for 3.3v/1.8v switch */
+ pslotinfo->v18_gpio = of_get_named_gpio_flags(np, "v18-gpios", 0, &flags);
+ pslotinfo->v18_gpio_active = !!(flags & OF_GPIO_ACTIVE_LOW);
+
+ if (gpio_is_valid(pslotinfo->v18_gpio)) {
+ if (pslotinfo->v18_gpio_active)
+ gpio_init_flag = GPIOF_OUT_INIT_LOW;
+ else
+ gpio_init_flag = GPIOF_OUT_INIT_HIGH;
+
+ retval = devm_gpio_request_one(pinfo->dev, pslotinfo->v18_gpio,
+ gpio_init_flag, "sd ext power");
+ if (retval < 0) {
+ dev_err(pinfo->dev, "Failed to request v18-gpios!\n");
+ goto init_slot_err1;
+ }
+ }
+
+ mmc->f_min = mmc->f_max >> 8;
+ mmc->ops = &ambarella_sd_host_ops;
+
+ init_waitqueue_head(&pslotinfo->wait);
+ pslotinfo->state = AMBA_SD_STATE_ERR;
+ pslotinfo->slot_id = id;
+ pslotinfo->pinfo = pinfo;
+ pinfo->pslotinfo[id] = pslotinfo;
+ sema_init(&pslotinfo->system_event_sem, 1);
+
+ ambarella_sd_request_bus(mmc);
+
+ ambarella_sd_reset_all(mmc);
+
+ hc_cap = amba_readl(pinfo->regbase + SD_CAP_OFFSET);
+
+ dev_dbg(pinfo->dev,
+ "SD Clock: base[%uMHz], min[%uHz], max[%uHz].\n",
+ SD_CAP_BASE_FREQ(hc_cap), mmc->f_min, mmc->f_max);
+
+ hc_timeout_clk = mmc->f_max / 1000;
+ if (hc_timeout_clk == 0)
+ hc_timeout_clk = 24000;
+
+ mmc->max_discard_to = (1 << 27) / hc_timeout_clk;
+
+ if (hc_cap & SD_CAP_MAX_2KB_BLK)
+ mmc->max_blk_size = 2048;
+ else if (hc_cap & SD_CAP_MAX_1KB_BLK)
+ mmc->max_blk_size = 1024;
+ else if (hc_cap & SD_CAP_MAX_512B_BLK)
+ mmc->max_blk_size = 512;
+
+ dev_dbg(pinfo->dev, "SD max_blk_size: %u.\n", mmc->max_blk_size);
+
+ mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ |
+ MMC_CAP_ERASE | MMC_CAP_BUS_WIDTH_TEST;
+
+ mmc->caps2 |= MMC_CAP2_HS200 | MMC_CAP2_HS200_1_8V_SDR;
+
+ if (mmc->f_max > 25000000) {
+ mmc->caps |= MMC_CAP_SD_HIGHSPEED;
+ mmc->caps |= MMC_CAP_MMC_HIGHSPEED;
+ }
+
+ if (!(hc_cap & SD_CAP_DMA)) {
+ ambsd_err(pslotinfo, "HW do not support DMA!\n");
+ retval = -ENODEV;
+ goto init_slot_err1;
+ }
+
+ if (hc_cap & SD_CAP_ADMA_SUPPORT) {
+ dev_dbg(pinfo->dev, "HW support ADMA!\n");
+ pslotinfo->use_adma = pslotinfo->caps_adma ? 1 : 0;
+ }
+
+ dev_dbg(pinfo->dev, "HW%s support Suspend/Resume!\n",
+ (hc_cap & SD_CAP_SUS_RES) ? "" : " do not");
+
+ mmc->ocr_avail = 0;
+ if (hc_cap & SD_CAP_VOL_3_3V)
+ mmc->ocr_avail |= MMC_VDD_32_33 | MMC_VDD_33_34;
+
+ if ((hc_cap & SD_CAP_VOL_1_8V) && !pslotinfo->no_1_8_v) {
+ mmc->ocr_avail |= MMC_VDD_165_195;
+ if (hc_cap & SD_CAP_HIGH_SPEED)
+ mmc->caps |= MMC_CAP_1_8V_DDR;
+
+ mmc->caps |= MMC_CAP_UHS_SDR12;
+ if (mmc->f_max > 25000000) {
+ mmc->caps |= MMC_CAP_UHS_SDR25;
+ if (pslotinfo->caps_ddr)
+ mmc->caps |= MMC_CAP_UHS_DDR50;
+ }
+
+ if (mmc->f_max > 50000000)
+ mmc->caps |= MMC_CAP_UHS_SDR50;
+
+ if (mmc->f_max > 100000000)
+ mmc->caps |= MMC_CAP_UHS_SDR104;
+ }
+
+ if (mmc->ocr_avail == 0) {
+ ambsd_err(pslotinfo, "HW report wrong voltages[0x%x]!\n", hc_cap);
+ retval = -ENODEV;
+ goto init_slot_err1;
+ }
+
+ if (!(hc_cap & SD_CAP_INTMODE)) {
+ ambsd_err(pslotinfo, "HW do not support Interrupt mode!\n");
+ retval = -ENODEV;
+ goto init_slot_err1;
+ }
+
+ dev_dbg(pinfo->dev, "SD caps: 0x%x.\n", mmc->caps);
+ dev_dbg(pinfo->dev, "SD ocr: 0x%x.\n", mmc->ocr_avail);
+
+ mmc->max_blk_count = 0xFFFF;
+ mmc->max_seg_size = pinfo->max_blk_sz;
+ mmc->max_segs = mmc->max_seg_size / PAGE_SIZE;
+ mmc->max_req_size =
+ min(mmc->max_seg_size, mmc->max_blk_size * mmc->max_blk_count);
+
+ pslotinfo->buf_vaddress = kmem_cache_alloc(pinfo->buf_cache, GFP_KERNEL);
+ if (!pslotinfo->buf_vaddress) {
+ ambsd_err(pslotinfo, "Can't alloc DMA memory");
+ retval = -ENOMEM;
+ goto init_slot_err1;
+ }
+ pslotinfo->buf_paddress = dma_map_single(pinfo->dev,
+ pslotinfo->buf_vaddress,
+ mmc->max_req_size,
+ DMA_BIDIRECTIONAL);
+ ambarella_sd_check_dma_boundary(pslotinfo->buf_paddress,
+ mmc->max_req_size, pinfo->max_blk_sz);
+
+ dev_notice(pinfo->dev, "Slot%u use bounce buffer[0x%p<->0x%08x]\n",
+ pslotinfo->slot_id, pslotinfo->buf_vaddress,
+ pslotinfo->buf_paddress);
+
+ dev_notice(pinfo->dev, "Slot%u req_size=0x%08X, "
+ "segs=%u, seg_size=0x%08X\n",
+ pslotinfo->slot_id, mmc->max_req_size,
+ mmc->max_segs, mmc->max_seg_size);
+
+ dev_notice(pinfo->dev, "Slot%u use %sDMA\n", pslotinfo->slot_id,
+ pslotinfo->use_adma ? "A" :"");
+
+ ambarella_sd_release_bus(mmc);
+
+ retval = mmc_add_host(pslotinfo->mmc);
+ if (retval < 0) {
+ ambsd_err(pslotinfo, "Can't add mmc host!\n");
+ goto init_slot_err2;
+ }
+
+ ambarella_sd_add_debugfs(pslotinfo);
+
+ pslotinfo->system_event.notifier_call = ambarella_sd_system_event;
+ ambarella_register_event_notifier(&pslotinfo->system_event);
+
+ retval = of_property_read_u32(np, "global-id", &global_id);
+ if (retval < 0 || global_id >= SD_INSTANCES * AMBA_SD_MAX_SLOT_NUM)
+ global_id = 0;
+ G_mmc[global_id] = mmc;
+
+ return 0;
+
+init_slot_err2:
+ dma_unmap_single(pinfo->dev, pslotinfo->buf_paddress,
+ pslotinfo->mmc->max_req_size, DMA_BIDIRECTIONAL);
+ kmem_cache_free(pinfo->buf_cache, pslotinfo->buf_vaddress);
+
+init_slot_err1:
+ mmc_free_host(mmc);
+ return retval;
+}
+
+static int ambarella_sd_free_slot(struct ambarella_sd_mmc_info *pslotinfo)
+{
+ struct ambarella_sd_controller_info *pinfo = pslotinfo->pinfo;
+ int retval = 0;
+
+ ambarella_unregister_event_notifier(&pslotinfo->system_event);
+
+ ambarella_sd_remove_debugfs(pslotinfo);
+
+ mmc_remove_host(pslotinfo->mmc);
+
+ if (pslotinfo->buf_paddress) {
+ dma_unmap_single(pinfo->dev, pslotinfo->buf_paddress,
+ pslotinfo->mmc->max_req_size, DMA_BIDIRECTIONAL);
+ pslotinfo->buf_paddress = (dma_addr_t)NULL;
+ }
+
+ if (pslotinfo->buf_vaddress) {
+ kmem_cache_free(pinfo->buf_cache, pslotinfo->buf_vaddress);
+ pslotinfo->buf_vaddress = NULL;
+ }
+
+ mmc_free_host(pslotinfo->mmc);
+
+ return retval;
+}
+
+static int ambarella_sd_of_parse(struct ambarella_sd_controller_info *pinfo)
+{
+ struct device_node *np = pinfo->dev->of_node;
+ const __be32 *prop;
+ const char *clk_name;
+ int psize, tmo, switch_vol_tmo, retval = 0;
+
+ retval = of_property_read_string(np, "amb,clk-name", &clk_name);
+ if (retval < 0) {
+ dev_err(pinfo->dev, "Get pll-name failed! %d\n", retval);
+ goto pasre_err;
+ }
+
+ pinfo->clk = clk_get(NULL, clk_name);
+ if (IS_ERR(pinfo->clk)) {
+ dev_err(pinfo->dev, "Get PLL failed!\n");
+ retval = PTR_ERR(pinfo->clk);
+ goto pasre_err;
+ }
+
+ if (of_find_property(np, "amb,dma-addr-fix", NULL))
+ pinfo->dma_fix = 0xc0000000;
+
+ retval = of_property_read_u32(np, "amb,wait-tmo", &tmo);
+ if (retval < 0)
+ tmo = 0x10000;
+
+ pinfo->default_wait_tmo = msecs_to_jiffies(tmo);
+
+ if (pinfo->default_wait_tmo < CONFIG_SD_AMBARELLA_WAIT_TIMEOUT)
+ pinfo->default_wait_tmo = CONFIG_SD_AMBARELLA_WAIT_TIMEOUT;
+
+ retval = of_property_read_u32(np, "amb,switch-vol-tmo", &switch_vol_tmo);
+ if (retval < 0)
+ switch_vol_tmo = 100;
+
+ pinfo->switch_voltage_tmo = switch_vol_tmo;
+
+ retval = of_property_read_u32(np, "amb,max-blk-size", &pinfo->max_blk_sz);
+ if (retval < 0)
+ pinfo->max_blk_sz = 0x20000;
+
+ pinfo->auto_tuning = !!of_find_property(np, "amb,auto-tuning", NULL);
+ retval = of_property_read_u32(np, "amb,phy-type", &pinfo->phy_type);
+ if(retval) {
+ /*this controller don't support sd phy*/
+ pinfo->phy_type = -1;
+ retval = 0;
+ } else {
+ /* amb,phy-timing must be provided when timing_reg is given */
+ prop = of_get_property(np, "amb,phy-timing", &psize);
+ if (!prop) {
+ retval = -EINVAL;
+ goto pasre_err;
+ }
+
+ psize /= sizeof(u32);
+ BUG_ON(psize % 3);
+ pinfo->phy_timing_num = psize / 3;
+ pinfo->phy_timing = devm_kzalloc(pinfo->dev, psize, GFP_KERNEL);
+ if (pinfo->phy_timing == NULL) {
+ retval = -ENOMEM;
+ goto pasre_err;
+ }
+
+ retval = of_property_read_u32_array(np, "amb,phy-timing",
+ (u32 *)pinfo->phy_timing, psize);
+
+ /* bit0 of mode must be set, and the phy setting in first row with
+ * bit0 set is the default one. */
+ BUG_ON(!(pinfo->phy_timing[0].mode & 0x1));
+ }
+
+pasre_err:
+ return retval;
+}
+
+static int ambarella_sd_get_resource(struct platform_device *pdev,
+ struct ambarella_sd_controller_info *pinfo)
+{
+ struct resource *mem;
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (mem == NULL) {
+ dev_err(&pdev->dev, "Get SD/MMC mem resource failed!\n");
+ return -ENXIO;
+ }
+
+ pinfo->regbase = devm_ioremap(&pdev->dev,
+ mem->start, resource_size(mem));
+ if (pinfo->regbase == NULL) {
+ dev_err(&pdev->dev, "devm_ioremap() failed\n");
+ return -ENOMEM;
+ }
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (mem == NULL) {
+ dev_err(&pdev->dev, "Get FIO mem resource failed!\n");
+ return -ENXIO;
+ }
+
+ pinfo->fio_reg = devm_ioremap(&pdev->dev,
+ mem->start, resource_size(mem));
+ if (pinfo->fio_reg == NULL) {
+ dev_err(&pdev->dev, "devm_ioremap() failed\n");
+ return -ENOMEM;
+ }
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+ if (mem == NULL) {
+ pinfo->timing_reg = NULL;
+ pinfo->auto_tuning = false;
+ } else {
+ pinfo->timing_reg = devm_ioremap(&pdev->dev,
+ mem->start, resource_size(mem));
+ if (pinfo->timing_reg == NULL) {
+ dev_err(&pdev->dev, "devm_ioremap() failed\n");
+ return -ENOMEM;
+ }
+ }
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 3);
+ if (mem == NULL) {
+ pinfo->sbc_reg = pinfo->timing_reg;
+ } else {
+ pinfo->sbc_reg = devm_ioremap(&pdev->dev,
+ mem->start, resource_size(mem));
+ if (pinfo->sbc_reg == NULL) {
+ dev_err(&pdev->dev, "devm_ioremap() failed for sbc_reg\n");
+ return -ENOMEM;
+ }
+ }
+
+ pinfo->irq = platform_get_irq(pdev, 0);
+ if (pinfo->irq < 0) {
+ dev_err(&pdev->dev, "Get SD/MMC irq resource failed!\n");
+ return -ENXIO;
+ }
+
+ return 0;
+}
+
+static int ambarella_sd_probe(struct platform_device *pdev)
+{
+ struct ambarella_sd_controller_info *pinfo;
+ struct device_node *slot_np;
+ int retval, i, slot_id = -1;
+
+ pinfo = devm_kzalloc(&pdev->dev, sizeof(*pinfo), GFP_KERNEL);
+ if (pinfo == NULL) {
+ dev_err(&pdev->dev, "Out of memory!\n");
+ return -ENOMEM;
+ }
+ pinfo->dev = &pdev->dev;
+
+ retval = ambarella_sd_get_resource(pdev, pinfo);
+ if (retval < 0)
+ return retval;
+
+ retval = ambarella_sd_of_parse(pinfo);
+ if (retval < 0)
+ return retval;
+
+ pinfo->buf_cache = kmem_cache_create(dev_name(&pdev->dev),
+ pinfo->max_blk_sz, pinfo->max_blk_sz, 0, NULL);
+ if (!pinfo->buf_cache) {
+ dev_err(&pdev->dev, "Can't alloc DMA Cache");
+ return -ENOMEM;
+ }
+
+ pinfo->slot_num = 0;
+ for_each_child_of_node(pdev->dev.of_node, slot_np) {
+ if (!slot_np->name || of_node_cmp(slot_np->name, "slot"))
+ continue;
+
+ retval = of_property_read_u32(slot_np, "reg", &slot_id);
+ if (retval < 0 || slot_id >= AMBA_SD_MAX_SLOT_NUM)
+ goto ambarella_sd_probe_free_host;
+
+ retval = ambarella_sd_init_slot(slot_np, slot_id, pinfo);
+ if (retval < 0)
+ goto ambarella_sd_probe_free_host;
+
+ pinfo->slot_num++;
+ }
+
+ platform_set_drvdata(pdev, pinfo);
+
+ retval = devm_request_irq(&pdev->dev, pinfo->irq, ambarella_sd_irq,
+ IRQF_SHARED | IRQF_TRIGGER_HIGH,
+ dev_name(&pdev->dev), pinfo);
+ if (retval < 0) {
+ dev_err(&pdev->dev, "Can't Request IRQ%u!\n", pinfo->irq);
+ goto ambarella_sd_probe_free_host;
+ }
+
+ dev_info(&pdev->dev, "%u slots @ %luHz\n",
+ pinfo->slot_num, clk_get_rate(pinfo->clk));
+
+ return 0;
+
+ambarella_sd_probe_free_host:
+ for (i = pinfo->slot_num - 1; i >= 0; i--)
+ ambarella_sd_free_slot(pinfo->pslotinfo[i]);
+
+ if (pinfo->buf_cache) {
+ kmem_cache_destroy(pinfo->buf_cache);
+ pinfo->buf_cache = NULL;
+ }
+
+ return retval;
+}
+
+static int ambarella_sd_remove(struct platform_device *pdev)
+{
+ struct ambarella_sd_controller_info *pinfo;
+ int retval = 0, i;
+
+ pinfo = platform_get_drvdata(pdev);
+
+ for (i = 0; i < pinfo->slot_num; i++)
+ ambarella_sd_free_slot(pinfo->pslotinfo[i]);
+
+ if (pinfo->buf_cache)
+ kmem_cache_destroy(pinfo->buf_cache);
+
+ dev_notice(&pdev->dev,
+ "Remove Ambarella Media Processor SD/MMC Host Controller.\n");
+
+ return retval;
+}
+
+#ifdef CONFIG_PM
+static int ambarella_sd_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ struct ambarella_sd_controller_info *pinfo;
+ struct ambarella_sd_mmc_info *pslotinfo;
+
+ int retval = 0, i;
+
+ pinfo = platform_get_drvdata(pdev);
+
+ for (i = 0; i < pinfo->slot_num; i++) {
+ pslotinfo = pinfo->pslotinfo[i];
+
+ if (pslotinfo->mmc) {
+ if (pslotinfo->mmc->pm_caps & MMC_PM_KEEP_POWER) {
+ pslotinfo->mmc->pm_flags = MMC_PM_KEEP_POWER;
+ }
+ retval = mmc_suspend_host(pslotinfo->mmc);
+ if (retval) {
+ ambsd_err(pslotinfo,
+ "mmc_suspend_host[%d] failed[%d]!\n", i, retval);
+ return retval;
+ }
+ }
+ if (pslotinfo->mmc->pm_caps & MMC_PM_KEEP_POWER) {
+ ambarella_sd_disable_int(pslotinfo->mmc, SD_NISEN_CARD);
+ pslotinfo->sd_nisen = amba_readw(pinfo->regbase + SD_NISEN_OFFSET);
+ pslotinfo->sd_eisen = amba_readw(pinfo->regbase + SD_EISEN_OFFSET);
+ pslotinfo->sd_nixen = amba_readw(pinfo->regbase + SD_NIXEN_OFFSET);
+ pslotinfo->sd_eixen = amba_readw(pinfo->regbase + SD_EIXEN_OFFSET);
+ }
+ }
+
+ disable_irq(pinfo->irq);
+ dev_dbg(&pdev->dev, "%s exit with %d @ %d\n", __func__,
+ retval, state.event);
+
+ return retval;
+
+}
+
+static int ambarella_sd_resume(struct platform_device *pdev)
+{
+ struct ambarella_sd_controller_info *pinfo;
+ struct ambarella_sd_mmc_info *pslotinfo;
+ int retval = 0, i;
+
+ pinfo = platform_get_drvdata(pdev);
+
+ enable_irq(pinfo->irq);
+
+ for (i = 0; i < pinfo->slot_num; i++) {
+ pslotinfo = pinfo->pslotinfo[i];
+ if (gpio_is_valid(pslotinfo->pwr_gpio)){
+ gpio_direction_output(pslotinfo->pwr_gpio, pslotinfo->pwr_gpio_active);
+ }
+ if (pslotinfo->mmc->pm_caps & MMC_PM_KEEP_POWER) {
+ amba_writew(pinfo->regbase + SD_NISEN_OFFSET, pslotinfo->sd_nisen);
+ amba_writew(pinfo->regbase + SD_EISEN_OFFSET, pslotinfo->sd_eisen);
+ amba_writew(pinfo->regbase + SD_NIXEN_OFFSET, pslotinfo->sd_nixen);
+ amba_writew(pinfo->regbase + SD_EIXEN_OFFSET, pslotinfo->sd_eixen);
+ pslotinfo->mmc->caps |= MMC_CAP_NONREMOVABLE;
+ mdelay(10);
+ ambarella_sd_set_clk(pslotinfo->mmc, &pinfo->controller_ios);
+ ambarella_sd_set_bus(pslotinfo->mmc, &pinfo->controller_ios);
+ mdelay(10);
+ ambarella_sd_enable_int(pslotinfo->mmc, SD_NISEN_CARD);
+ } else {
+ clk_set_rate(pinfo->clk, pslotinfo->mmc->f_max);
+ ambarella_sd_reset_all(pslotinfo->mmc);
+ }
+ }
+
+ for (i = 0; i < pinfo->slot_num; i++) {
+ pslotinfo = pinfo->pslotinfo[i];
+ if (pslotinfo->mmc) {
+ retval = mmc_resume_host(pslotinfo->mmc);
+ if (retval) {
+ ambsd_err(pslotinfo,
+ "mmc_resume_host[%d] failed[%d]!\n", i, retval);
+ }
+ }
+ }
+
+ dev_dbg(&pdev->dev, "%s exit with %d\n", __func__, retval);
+
+ return retval;
+}
+#endif
+
+#ifdef CONFIG_AMBARELLA_EMMC_BOOT
+void ambarella_sd_shutdown (struct platform_device *pdev)
+{
+ struct ambarella_sd_controller_info *pinfo;
+ struct ambarella_sd_mmc_info *pslotinfo;
+ struct mmc_host *host;
+ struct mmc_command cmd = {0};
+ int i;
+
+ pinfo = platform_get_drvdata(pdev);
+
+ for (i = 0; i < pinfo->slot_num; i++) {
+ pslotinfo = pinfo->pslotinfo[i];
+ host = pslotinfo->mmc;
+ if((host == G_mmc[0]) && ((system_state == SYSTEM_RESTART) ||
+ (system_state == SYSTEM_HALT))) {
+ if (mmc_try_claim_host(pslotinfo->mmc)) {
+ cmd.opcode = 0;
+ cmd.arg = 0xf0f0f0f0;
+ cmd.flags = MMC_RSP_NONE;
+
+ mmc_wait_for_cmd(pslotinfo->mmc, &cmd, 0);
+ } else {
+ dev_err(&pdev->dev, "Unable to claim host!\n");
+ }
+ }
+ }
+
+}
+#endif
+
+static const struct of_device_id ambarella_mmc_dt_ids[] = {
+ { .compatible = "ambarella,sdmmc", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, ambarella_mmc_dt_ids);
+
+static struct platform_driver ambarella_sd_driver = {
+ .probe = ambarella_sd_probe,
+ .remove = ambarella_sd_remove,
+#ifdef CONFIG_PM
+ .suspend = ambarella_sd_suspend,
+ .resume = ambarella_sd_resume,
+#endif
+
+#ifdef CONFIG_AMBARELLA_EMMC_BOOT
+ .shutdown = ambarella_sd_shutdown,
+#endif
+ .driver = {
+ .name = "ambarella-sd",
+ .owner = THIS_MODULE,
+ .of_match_table = ambarella_mmc_dt_ids,
+ },
+};
+
+static int __init ambarella_sd_init(void)
+{
+ int retval = 0;
+
+ retval = platform_driver_register(&ambarella_sd_driver);
+ if (retval) {
+ printk(KERN_ERR "%s: Register failed %d!\n",
+ __func__, retval);
+ }
+
+ return retval;
+}
+
+static void __exit ambarella_sd_exit(void)
+{
+ platform_driver_unregister(&ambarella_sd_driver);
+}
+
+fs_initcall(ambarella_sd_init);
+module_exit(ambarella_sd_exit);
+
+MODULE_DESCRIPTION("Ambarella Media Processor SD/MMC Host Controller");
+MODULE_AUTHOR("Anthony Ginger, <hfjiang@ambarella.com>");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 5fab4e6e..14cb18d4 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -197,6 +197,17 @@ config MTD_BLOCK_RO
You do not need this option for use with the DiskOnChip devices. For
those, enable NFTL support (CONFIG_NFTL) instead.
+config MTD_BLOCK_AMBRO
+ tristate "Ambarella Readonly block device access to MTD devices"
+ depends on MTD_BLOCK!=y && MTD_BLOCK_RO!=y && MTD_UBI_GLUEBI!=y && BLOCK
+ select MTD_BLKDEVS
+ help
+ This allows you to mount read-only file systems (such as cramfs/squashfs)
+ from an MTD device, without the overhead (and danger) of the caching
+ driver, but with the bad block skipped.
+
+ Note: This is mutually exclusive with UBI gluebi.
+
config FTL
tristate "FTL (Flash Translation Layer) support"
depends on BLOCK
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index 4cfb31e6..28471dc3 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o
obj-$(CONFIG_MTD_BLKDEVS) += mtd_blkdevs.o
obj-$(CONFIG_MTD_BLOCK) += mtdblock.o
obj-$(CONFIG_MTD_BLOCK_RO) += mtdblock_ro.o
+obj-$(CONFIG_MTD_BLOCK_AMBRO) += mtdblock_ambro.o
obj-$(CONFIG_FTL) += ftl.o
obj-$(CONFIG_NFTL) += nftl.o
obj-$(CONFIG_INFTL) += inftl.o
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 2a4d55e4..53ee819e 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -2,6 +2,11 @@ menu "Self-contained MTD device drivers"
depends on MTD!=n
depends on HAS_IOMEM
+config MTD_AMBARELLA_SPI_NOR
+ tristate "Ambarella Support SPI Nor Flash chips"
+ help
+ Support Ambarella SPI NOR controler
+
config MTD_PMC551
tristate "Ramix PMC551 PCI Mezzanine RAM card support"
depends on PCI
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index d83bd730..e8f64af0 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -16,6 +16,6 @@ obj-$(CONFIG_MTD_NAND_OMAP_BCH) += elm.o
obj-$(CONFIG_MTD_SPEAR_SMI) += spear_smi.o
obj-$(CONFIG_MTD_SST25L) += sst25l.o
obj-$(CONFIG_MTD_BCM47XXSFLASH) += bcm47xxsflash.o
-
+obj-$(CONFIG_MTD_AMBARELLA_SPI_NOR) += ambarella_spinor.o spinor.o
CFLAGS_docg3.o += -I$(src)
diff --git a/drivers/mtd/devices/ambarella_spinor.c b/drivers/mtd/devices/ambarella_spinor.c
new file mode 100644
index 00000000..81b056a0
--- /dev/null
+++ b/drivers/mtd/devices/ambarella_spinor.c
@@ -0,0 +1,786 @@
+/*
+ * drivers/mtd/ambarella_spinor.c
+ *
+ * History:
+ * 2014/03/10 - [cddiao] created file
+ *
+ * Copyright (C) 2014-2019, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "spinor.h"
+
+/* Flash opcodes. */
+#define OPCODE_WREN 0x06 /* Write enable */
+#define OPCODE_RDSR 0x05 /* Read status register */
+#define OPCODE_WRSR 0x01 /* Write status register 1 byte */
+#define OPCODE_NORM_READ 0x03 /* Read data bytes (low frequency) */
+#define OPCODE_FAST_READ 0x0b /* Read data bytes (high frequency) */
+#define OPCODE_PP 0x02 /* Page program (up to 256 bytes) */
+#define OPCODE_BE_4K 0x20 /* Erase 4KiB block */
+#define OPCODE_BE_32K 0x52 /* Erase 32KiB block */
+#define OPCODE_CHIP_ERASE 0xc7 /* Erase whole flash chip */
+#define OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */
+#define OPCODE_RDID 0x9f /* Read JEDEC ID */
+
+/* Used for SST flashes only. */
+#define OPCODE_BP 0x02 /* Byte program */
+#define OPCODE_WRDI 0x04 /* Write disable */
+#define OPCODE_AAI_WP 0xad /* Auto address increment word program */
+
+/* Used for Macronix flashes only. */
+#define OPCODE_EN4B 0xb7 /* Enter 4-byte mode */
+#define OPCODE_EX4B 0xe9 /* Exit 4-byte mode */
+
+/* Used for Spansion flashes only. */
+#define OPCODE_BRWR 0x17 /* Bank register write */
+
+/* Status Register bits. */
+#define SR_WIP 1 /* Write in progress */
+#define SR_WEL 2 /* Write enable latch */
+/* meaning of other SR_* bits may differ between vendors */
+#define SR_BP0 4 /* Block protect 0 */
+#define SR_BP1 8 /* Block protect 1 */
+#define SR_BP2 0x10 /* Block protect 2 */
+#define SR_SRWD 0x80 /* SR write protect */
+
+/* Define max times to check status register before we give up. */
+#define MAX_READY_WAIT_JIFFIES (400 * HZ) /* 40s max chip erase */
+#define MAX_CMD_SIZE 5
+
+#define JEDEC_MFR(_jedec_id) ((_jedec_id) >> 16)
+
+#define PART_DEV_SPINOR (0x08)
+static u16 spi_addr_mode = 3;
+
+/****************************************************************************/
+
+static inline struct amb_norflash *mtd_to_amb(struct mtd_info *mtd)
+{
+ return container_of(mtd, struct amb_norflash, mtd);
+}
+
+/****************************************************************************/
+
+static int read_sr(struct amb_norflash *flash)
+{
+ ssize_t retval = 0;
+ u8 code = OPCODE_RDSR;
+ u8 val;
+ retval = ambspi_read_reg(flash, 1, code, &val);
+
+ if (retval < 0) {
+ dev_err((const struct device *)&flash->dev, "error %d reading SR\n",
+ (int) retval);
+ return retval;
+ }
+
+ return val;
+}
+
+/*
+ * Set write enable latch with Write Enable command.
+ * Returns negative if error occurred.
+ */
+int write_enable(struct amb_norflash *flash)
+{
+ u8 code = OPCODE_WREN;
+ return ambspi_send_cmd(flash, code, 0, 0, 0);
+}
+
+/*
+ * Send write disble instruction to the chip.
+ */
+static inline int write_disable(struct amb_norflash *flash)
+{
+ u8 code = OPCODE_WRDI;
+ return ambspi_send_cmd(flash, code, 0, 0, 0);
+}
+
+/*
+ * Enable/disable 4-byte addressing mode.
+ */
+static inline int set_4byte(struct amb_norflash *flash, u32 jedec_id, int enable)
+{
+ int ret = 0;
+
+ switch (JEDEC_MFR(jedec_id)) {
+ case CFI_MFR_MACRONIX:
+ case 0xEF: /* winbond */
+ case 0xC8: /* GD */
+ flash->command[0] = enable ? OPCODE_EN4B : OPCODE_EX4B;
+ return ambspi_send_cmd(flash, flash->command[0], 0, 0, 0);
+ case CFI_MFR_ST: /*Micron*/
+ write_enable(flash);
+ flash->command[0] = enable ? OPCODE_EN4B : OPCODE_EX4B;
+ ret = ambspi_send_cmd(flash, flash->command[0], 0, 0, 0);
+ write_disable(flash);
+ return ret;
+ default:
+ /* Spansion style */
+ flash->command[0] = OPCODE_BRWR;
+ flash->command[1] = enable << 7;
+ return ambspi_send_cmd(flash, flash->command[0], 0, flash->command[1], 1);
+ }
+}
+/*
+mode 1 - enter 4 byte spi addr mode
+ 0 - exit 4 byte spi addr mode
+*/
+static void check_set_spinor_addr_mode(struct amb_norflash *flash, int mode)
+{
+ if (flash->addr_width == 4) {
+ if (spi_addr_mode == 3 && mode){
+ set_4byte(flash, flash->jedec_id, 1);
+ spi_addr_mode = 4;
+ } else if (spi_addr_mode == 4 && mode == 0){
+ set_4byte(flash, flash->jedec_id, 0);
+ spi_addr_mode = 3;
+ }
+ }
+}
+/*
+ * Service routine to read status register until ready, or timeout occurs.
+ * Returns non-zero if error.
+ */
+int wait_till_ready(struct amb_norflash *flash)
+{
+ unsigned long deadline;
+ int sr;
+
+ deadline = jiffies + MAX_READY_WAIT_JIFFIES;
+
+ do {
+ if ((sr = read_sr(flash)) < 0)
+ break;
+ else if (!(sr & SR_WIP))
+ return 0;
+
+ cond_resched();
+
+ } while (!time_after_eq(jiffies, deadline));
+
+ return 1;
+}
+
+/*
+ * Erase the whole flash memory
+ *
+ * Returns 0 if successful, non-zero otherwise.
+ */
+static int erase_chip(struct amb_norflash *flash)
+{
+ /* Wait until finished previous write command. */
+ if (wait_till_ready(flash))
+ return 1;
+
+ /* Send write enable, then erase commands. */
+ write_enable(flash);
+
+ /* Set up command buffer. */
+ flash->command[0] = OPCODE_CHIP_ERASE;
+ ambspi_send_cmd(flash, flash->command[0], 0, 0, 0);
+
+ return 0;
+}
+
+
+/*
+ * Erase one sector of flash memory at offset ``offset'' which is any
+ * address within the sector which should be erased.
+ *
+ * Returns 0 if successful, non-zero otherwise.
+ */
+static int erase_sector(struct amb_norflash *flash, u32 offset)
+{
+
+ /* Wait until finished previous write command. */
+ if (wait_till_ready(flash))
+ return 1;
+
+ /* Send write enable, then erase commands. */
+ write_enable(flash);
+
+ /* Set up command buffer. */
+ flash->command[0] = flash->erase_opcode;
+ ambspi_send_cmd(flash, flash->command[0], 0, offset, flash->addr_width);
+
+ return 0;
+}
+
+/****************************************************************************/
+
+/*
+ * MTD implementation
+ */
+
+/*
+ * Erase an address range on the flash chip. The address range may extend
+ * one or more erase sectors. Return an error is there is a problem erasing.
+ */
+static int amba_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+ struct amb_norflash *flash = mtd_to_amb(mtd);
+ u32 addr, len;
+ uint32_t rem;
+
+ div_u64_rem(instr->len, mtd->erasesize, &rem);
+ if (rem)
+ return -EINVAL;
+
+ addr = instr->addr;
+ len = instr->len;
+
+ mutex_lock(&flash->lock);
+ check_set_spinor_addr_mode(flash, 1);
+ /* whole-chip erase? */
+ if (len == flash->mtd.size) {
+ if (erase_chip(flash)) {
+ instr->state = MTD_ERASE_FAILED;
+ check_set_spinor_addr_mode(flash, 0);
+ mutex_unlock(&flash->lock);
+ return -EIO;
+ }
+
+ /* REVISIT in some cases we could speed up erasing large regions
+ * by using OPCODE_SE instead of OPCODE_BE_4K. We may have set up
+ * to use "small sector erase", but that's not always optimal.
+ */
+
+ /* "sector"-at-a-time erase */
+ } else {
+ while (len) {
+ if (erase_sector(flash, addr)) {
+ instr->state = MTD_ERASE_FAILED;
+ check_set_spinor_addr_mode(flash, 0);
+ mutex_unlock(&flash->lock);
+ return -EIO;
+ }
+
+ addr += mtd->erasesize;
+ len -= mtd->erasesize;
+ }
+ }
+ check_set_spinor_addr_mode(flash, 0);
+ mutex_unlock(&flash->lock);
+
+ instr->state = MTD_ERASE_DONE;
+ mtd_erase_callback(instr);
+
+ return 0;
+}
+
+/*
+ * Read an address range from the flash chip. The address range
+ * may be any size provided it is within the physical boundaries.
+ */
+ static int amba_read(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *buf)
+{
+ struct amb_norflash *flash = mtd_to_amb(mtd);
+ uint8_t opcode;
+ int offset;
+ int needread = 0;
+ int ret=0;
+
+ mutex_lock(&flash->lock);
+
+ /* Wait till previous write/erase is done. */
+ if (wait_till_ready(flash)) {
+ /* REVISIT status return?? */
+ mutex_unlock(&flash->lock);
+ return 1;
+ }
+ check_set_spinor_addr_mode(flash, 1);
+ /* Set up the write data buffer. */
+ opcode = flash->fast_read ? OPCODE_FAST_READ : OPCODE_NORM_READ;
+ flash->command[0] = opcode;
+ flash->dummy = 0;
+
+ for (offset = 0; offset < len; ) {
+ needread = len - offset;
+ if (needread >= AMBA_SPINOR_DMA_BUFF_SIZE) {
+ ret = ambspi_read_data(flash, from+offset, AMBA_SPINOR_DMA_BUFF_SIZE);
+ if(ret) {
+ dev_err((const struct device *)&flash->dev,
+ "SPI NOR read error from=%x len=%d\r\n", (u32)(from+offset), AMBA_SPINOR_DMA_BUFF_SIZE);
+ check_set_spinor_addr_mode(flash, 0);
+ mutex_unlock(&flash->lock);
+ return -1;
+ }
+ memcpy(buf+offset, flash->dmabuf, AMBA_SPINOR_DMA_BUFF_SIZE);
+ offset += AMBA_SPINOR_DMA_BUFF_SIZE;
+ }else{
+ ret = ambspi_read_data(flash, from+offset, needread);
+ if(ret) {
+ dev_err((const struct device *)&flash->dev,
+ "SPI NOR read error from=%x len=%d\r\n", (u32)(from+offset), needread);
+ check_set_spinor_addr_mode(flash, 0);
+ mutex_unlock(&flash->lock);
+ return -1;
+ }
+ memcpy(buf+offset, flash->dmabuf, needread);
+ offset += needread;
+ }
+ }
+ *retlen = offset;
+ check_set_spinor_addr_mode(flash, 0);
+ mutex_unlock(&flash->lock);
+ return 0;
+}
+
+/*
+ * Write an address range to the flash chip. Data must be written in
+ * FLASH_PAGESIZE chunks. The address range may be any size provided
+ * it is within the physical boundaries.
+ */
+static int amba_write(struct mtd_info *mtd, loff_t to, size_t len,
+ size_t *retlen, const u_char *buf)
+{
+ struct amb_norflash *flash = mtd_to_amb(mtd);
+ u32 page_offset, needwrite, needcopy, page_write;
+ mutex_lock(&flash->lock);
+
+ /* Wait until finished previous write command. */
+ if (wait_till_ready(flash)) {
+ mutex_unlock(&flash->lock);
+ return 1;
+ }
+ check_set_spinor_addr_mode(flash, 1);
+ write_enable(flash);
+
+ /* Set up the opcode in the write buffer. */
+ flash->command[0] = OPCODE_PP;
+ flash->dummy = 0;
+ page_offset = to & (flash->page_size - 1);
+ /* do all the bytes fit onto one page? */
+ if (page_offset + len <= flash->page_size) {
+ memcpy(flash->dmabuf, buf, len);
+ ambspi_prog_data(flash, 0, to, len);
+ *retlen = len;
+ } else {
+ u32 i;
+ u32 j;
+
+ /* the size of data remaining on the first page */
+ needwrite = flash->page_size - page_offset;
+ memcpy(flash->dmabuf, buf, needwrite);
+ ambspi_prog_data(flash, 0, to, needwrite);
+ *retlen = needwrite;
+ for (j=needwrite; j < len; j += needcopy) {
+ if (len-j < AMBA_SPINOR_DMA_BUFF_SIZE) {
+ needcopy = len-j;
+ }else{
+ needcopy = AMBA_SPINOR_DMA_BUFF_SIZE;
+ }
+ memcpy(flash->dmabuf, buf+j, needcopy);
+
+ for (i = 0; i < needcopy; i += page_write) {
+ page_write = needcopy - i;
+ if (page_write > flash->page_size) {
+ page_write = flash->page_size;
+ }
+ /* write the next page to flash */
+ if (wait_till_ready(flash)) {
+ check_set_spinor_addr_mode(flash, 0);
+ mutex_unlock(&flash->lock);
+ return 1;
+ }
+ write_enable(flash);
+ ambspi_prog_data(flash, i, to+i+j, page_write);
+ *retlen += page_write;
+ }
+ }
+ }
+ check_set_spinor_addr_mode(flash, 0);
+ mutex_unlock(&flash->lock);
+ return 0;
+}
+
+
+/****************************************************************************/
+struct flash_info {
+ /* JEDEC id zero means "no ID" (most older chips);otherwise it has
+ * a high byte of zero plus three data bytes: the manufacturer id,
+ * then a two byte device id.
+ */
+ u32 jedec_id;
+ u16 ext_id;
+
+ /* The size listed here is what works with OPCODE_SE, which isn't
+ * necessarily called a "sector" by the vendor.
+ */
+ unsigned sector_size;
+ u16 n_sectors;
+
+ u16 page_size;
+ u16 addr_width;
+
+ u32 max_clk_hz;
+ u16 flags;
+#define SECT_4K 0x01 /* OPCODE_BE_4K works uniformly */
+};
+
+
+#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _page_size, _max_clk_hz, _flags) \
+ { \
+ .jedec_id = (_jedec_id), \
+ .ext_id = (_ext_id), \
+ .sector_size = (_sector_size), \
+ .n_sectors = (_n_sectors), \
+ .page_size = (_page_size), \
+ .max_clk_hz = (_max_clk_hz), \
+ .flags = (_flags), }
+
+
+struct ambid_t {
+ char name[32];
+ struct flash_info driver_data;
+};
+
+static const struct ambid_t amb_ids[] = {
+ { "s70fl01gs", INFO(0x010220, 0x4d00, 256 * 1024, 256, 512, 50000000, 0) },
+ { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, 256, 50000000, 0) },
+ { "mx25l25645g", INFO(0xc22019, 0, 64 * 1024, 512, 256, 50000000, 0) },
+ { "mx66l51235f", INFO(0xc2201a, 0, 64 * 1024, 1024, 256, 50000000, 0) },
+ { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, 256, 50000000, 0) },
+ { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, 256, 50000000, 0) },
+ { "gd25q128", INFO(0xc84018, 0, 64 * 1024, 256, 256, 50000000, 0) },
+ { "gd25q256c", INFO(0xc84019, 0, 64 * 1024, 512, 256, 50000000, 0) },
+ { "gd25q512", INFO(0xc84020, 0, 64 * 1024, 1024, 256, 50000000, 0) },
+ { },
+};
+
+static const struct ambid_t *jedec_probe(struct amb_norflash *flash)
+{
+ int retval;
+ u8 code = OPCODE_RDID;
+ u8 id[5];
+ u32 jedec;
+ u16 ext_jedec;
+ struct flash_info *info;
+ int tmp;
+
+ /* JEDEC also defines an optional "extended device information"
+ * string for after vendor-specific data, after the three bytes
+ * we use here. Supporting some chips might require using it.
+ */
+ retval = ambspi_read_reg(flash, 5, code, id);
+ if (retval < 0) {
+ dev_err((const struct device *)&flash->dev, "error %d reading id\n",
+ (int) retval);
+ return ERR_PTR(retval);
+ }
+ jedec = id[0];
+ jedec = jedec << 8;
+ jedec |= id[1];
+ jedec = jedec << 8;
+ jedec |= id[2];
+
+ ext_jedec = id[3] << 8 | id[4];
+
+ for (tmp = 0; tmp < ARRAY_SIZE(amb_ids) - 1; tmp++) {
+ info = (void *)&amb_ids[tmp].driver_data;
+ if (info->jedec_id == jedec) {
+ if (info->ext_id != 0 && info->ext_id != ext_jedec)
+ continue;
+ return &amb_ids[tmp];
+ }
+ }
+ dev_err((const struct device *)&flash->dev, "unrecognized JEDEC id %06x\n", jedec);
+ return ERR_PTR(-ENODEV);
+}
+
+static int amb_get_resource(struct amb_norflash *flash, struct platform_device *pdev)
+{
+ struct resource *res;
+ int errorCode = 0;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "No mem resource for spinor_reg!\n");
+ errorCode = -ENXIO;
+ goto spinor_get_resource_err_exit;
+ }
+
+ flash->regbase =
+ devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!flash->regbase) {
+ dev_err(&pdev->dev, "devm_ioremap() failed\n");
+ errorCode = -ENOMEM;
+ goto spinor_get_resource_err_exit;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res) {
+ dev_err(&pdev->dev, "No mem resource for spinor_reg!\n");
+ errorCode = -ENXIO;
+ goto spinor_get_resource_err_exit;
+ }
+
+ flash->dmaregbase =
+ devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!flash->dmaregbase) {
+ dev_err(&pdev->dev, "devm_ioremap() failed\n");
+ errorCode = -ENOMEM;
+ goto spinor_get_resource_err_exit;
+ }
+
+ return 0;
+
+spinor_get_resource_err_exit:
+ return errorCode;
+}
+
+
+static int amb_spi_nor_probe(struct platform_device *pdev)
+{
+ struct mtd_part_parser_data ppdata;
+ struct flash_platform_data data;
+ struct amb_norflash *flash;
+ struct flash_info *info;
+ unsigned i;
+ int errCode = 0;
+ const struct ambid_t *ambid = NULL;;
+
+ flash = kzalloc(sizeof(struct amb_norflash), GFP_KERNEL);
+ if (!flash) {
+ errCode = -ENOMEM;
+ goto amb_spi_nor_probe_exit;
+ }
+
+ mutex_init(&flash->lock);
+ platform_set_drvdata(pdev, flash);
+ flash->dev = &pdev->dev;
+
+ /* set 50Mhz as default spi clock */
+ flash->clk = 50000000;
+ amb_get_resource(flash, pdev);
+ ambspi_init(flash);
+
+ ambid = jedec_probe(flash);
+ if (IS_ERR(ambid))
+ return PTR_ERR(ambid);
+ else {
+ info = (void *)&ambid->driver_data;
+ }
+ data.type = kzalloc(sizeof(32), GFP_KERNEL);
+ strcpy(data.type, ambid->name);
+
+ flash->mtd.name = "amba_spinor";
+ flash->mtd.type = MTD_NORFLASH;
+ flash->mtd.writesize = 1;
+ flash->mtd.flags = MTD_CAP_NORFLASH;
+ flash->mtd.size = info->sector_size * info->n_sectors;
+ flash->mtd._erase = amba_erase;
+ flash->mtd._read = amba_read;
+ flash->mtd._write = amba_write;
+ flash->write_enable = write_enable;
+ flash->wait_till_ready = wait_till_ready;
+
+ /* prefer "small sector" erase if possible */
+ if (info->flags & SECT_4K) {
+ flash->erase_opcode = OPCODE_BE_4K;
+ flash->mtd.erasesize = 4096;
+ } else {
+ flash->erase_opcode = OPCODE_SE;
+ flash->mtd.erasesize = info->sector_size;
+ }
+
+ flash->mtd.flags |= MTD_NO_ERASE;
+
+ flash->page_size = info->page_size;
+ flash->mtd.writebufsize = flash->page_size;
+
+ flash->fast_read = false;
+ flash->command = kzalloc(5, GFP_KERNEL);
+ if(!flash->command) {
+ dev_err((const struct device *)&flash->dev,
+ "SPI NOR driver malloc command error\r\n");
+ errCode = -ENOMEM;
+ goto amb_spi_nor_probe_free_flash;
+ }
+ if (flash->page_size > AMBA_SPINOR_DMA_BUFF_SIZE) {
+ dev_err((const struct device *)&flash->dev,
+ "SPI NOR driver buff size should bigger than nor flash page size \r\n");
+ errCode = -EINVAL;
+ goto amb_spi_nor_probe_free_command;
+ }
+ flash->clk = info->max_clk_hz;
+ ambspi_init(flash);
+
+ if (info->addr_width)
+ flash->addr_width = info->addr_width;
+ else {
+ /* enable 4-byte addressing if the device exceeds 16MiB */
+ if (flash->mtd.size > 0x1000000) {
+ flash->addr_width = 4;
+ /* We have set 4-bytes mode in bootloader */
+ //set_4byte(flash, info->jedec_id, 1);
+ spi_addr_mode = 4;
+ } else {
+ flash->addr_width = 3;
+ spi_addr_mode = 3;
+ }
+ }
+
+ flash->jedec_id = info->jedec_id;
+ pr_debug("mtd .name = %s, .size = 0x%llx (%lldMiB) "
+ ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n",
+ flash->mtd.name,
+ (long long)flash->mtd.size, (long long)(flash->mtd.size >> 20),
+ flash->mtd.erasesize, flash->mtd.erasesize / 1024,
+ flash->mtd.numeraseregions);
+
+ if (flash->mtd.numeraseregions)
+ for (i = 0; i < flash->mtd.numeraseregions; i++)
+ pr_debug("mtd.eraseregions[%d] = { .offset = 0x%llx, "
+ ".erasesize = 0x%.8x (%uKiB), "
+ ".numblocks = %d }\n",
+ i, (long long)flash->mtd.eraseregions[i].offset,
+ flash->mtd.eraseregions[i].erasesize,
+ flash->mtd.eraseregions[i].erasesize / 1024,
+ flash->mtd.eraseregions[i].numblocks);
+
+ ambspi_dma_config(flash);
+ ppdata.of_node = pdev->dev.of_node;
+ errCode = mtd_device_parse_register(&flash->mtd, NULL, &ppdata, NULL, 0);
+ if (errCode < 0)
+ goto amb_spi_nor_probe_free_command;
+
+ check_set_spinor_addr_mode(flash, 0);
+ printk("SPI NOR Controller probed\r\n");
+ return 0;
+
+amb_spi_nor_probe_free_command:
+ kfree(flash->command);
+amb_spi_nor_probe_free_flash:
+ kfree(flash);
+amb_spi_nor_probe_exit:
+ return errCode;
+}
+
+
+static int amb_spi_nor_remove(struct platform_device *pdev)
+{
+
+ struct amb_norflash *flash = platform_get_drvdata(pdev);
+ int status;
+
+ /* Clean up MTD stuff. */
+ status = mtd_device_unregister(&flash->mtd);
+ if (status == 0) {
+ kfree(flash->command);
+ dma_free_coherent(flash->dev,
+ AMBA_SPINOR_DMA_BUFF_SIZE,
+ flash->dmabuf, flash->dmaaddr);
+ kfree(flash);
+ }
+ return 0;
+}
+
+static void amb_spi_nor_shutdown(struct platform_device *pdev)
+{
+ struct amb_norflash *flash = platform_get_drvdata(pdev);
+
+ /* Wait until finished previous write command. */
+ if (wait_till_ready(flash))
+ return;
+
+ /* Send write enable, then erase commands. */
+ //write_enable(flash);
+ switch (JEDEC_MFR(flash->jedec_id)) {
+ case CFI_MFR_MACRONIX:
+ case 0xEF: /* winbond */
+ case 0xC8: /* GD */
+ case CFI_MFR_ST: /*Micron*/
+ flash->command[0] = 0x66;
+ ambspi_send_cmd(flash, flash->command[0], 0, 0, 0);
+ flash->command[0] = 0x99;
+ ambspi_send_cmd(flash, flash->command[0], 0, 0, 0);
+ return;
+ default:
+ /* Spansion style */
+ /* Set up command buffer. */
+ /* FL01GS use 0xF0 as reset enable command */
+ flash->command[0] = 0xF0;
+ ambspi_send_cmd(flash, flash->command[0], 0, 0, 0);
+ }
+}
+
+#ifdef CONFIG_PM
+static int amb_spi_nor_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ int errorCode = 0;
+ struct amb_norflash *flash;
+
+ flash = platform_get_drvdata(pdev);
+
+ dev_dbg(&pdev->dev, "%s exit with %d @ %d\n",
+ __func__, errorCode, state.event);
+
+ return errorCode;
+}
+
+static int amb_spi_nor_resume(struct platform_device *pdev)
+{
+ int errorCode = 0;
+ struct amb_norflash *flash;
+
+ flash = platform_get_drvdata(pdev);
+ ambspi_init(flash);
+ if (flash->addr_width == 4)
+ set_4byte(flash, flash->jedec_id, 1);
+
+ dev_dbg(&pdev->dev, "%s exit with %d\n", __func__, errorCode);
+
+ return errorCode;
+}
+#endif
+
+static const struct of_device_id ambarella_spi_nor_of_match[] = {
+ {.compatible = "ambarella,spinor", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ambarella_spi_nor_of_match);
+
+static struct platform_driver amb_spi_nor_driver = {
+ .driver = {
+ .name = "ambarella-spinor",
+ .owner = THIS_MODULE,
+ .of_match_table = ambarella_spi_nor_of_match,
+ },
+ .probe = amb_spi_nor_probe,
+ .remove = amb_spi_nor_remove,
+ .shutdown = amb_spi_nor_shutdown,
+#ifdef CONFIG_PM
+ .suspend = amb_spi_nor_suspend,
+ .resume = amb_spi_nor_resume,
+#endif
+ /* REVISIT: many of these chips have deep power-down modes, which
+ * should clearly be entered on suspend() to minimize power use.
+ * And also when they're otherwise idle...
+ */
+};
+
+module_platform_driver(amb_spi_nor_driver);
+
+MODULE_AUTHOR("Johnson Diao");
+MODULE_DESCRIPTION("Ambarella Media processor SPI NOR Flash Controller Driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/mtd/devices/spinor.c b/drivers/mtd/devices/spinor.c
new file mode 100644
index 00000000..b1af28cf
--- /dev/null
+++ b/drivers/mtd/devices/spinor.c
@@ -0,0 +1,494 @@
+/**
+ * system/src/bld/spi_nor.c
+ *
+ * Flash controller functions with spi nor chips.
+ *
+ * History:
+ * 2013/10/12 - [cddiao] creat
+ *
+ * Copyright 2008-2015 Ambarella Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include "spinor.h"
+
+struct spinorcmd_s{
+ int (*init)(void);
+ int (*erase_sector)(u32 sector);
+ int (*write_sector)(u32 sector, u8 *src);
+ int (*write_bst)(u32 sector, u8 *src, u32 *page_size);
+ int (*read)(u32 addr, u32 data_len, const u8 *dst);
+}spinorcmd;
+
+int ambspi_send_cmd(struct amb_norflash *flash, u32 cmd, u32 dummy_len, u32 data, u32 len)
+{
+ u32 tmp = 0;
+
+ tmp = amba_readl(flash->regbase + REG00);
+ REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, 0);
+ REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, dummy_len);
+ REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, len);
+ REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
+ amba_writel(flash->regbase + REG00, tmp);
+
+ tmp = amba_readl(flash->regbase + REG04);
+ REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 1);
+ REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 0);
+ REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 0);
+ REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
+ REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
+ amba_writel(flash->regbase + REG04, tmp);
+
+ tmp = amba_readl(flash->regbase + REG0C);
+ REGPREP(tmp, REG0C_CMD0_MASK, REG0C_CMD0_SHIFT, cmd);
+ amba_writel(flash->regbase + REG0C, tmp);
+
+ if(len){
+ tmp = data;
+ amba_writel(flash->regbase + REG14, tmp);
+ }
+
+ tmp = 0x0;
+ amba_writel(flash->regbase + REG30, tmp);
+
+ tmp = 0x20;
+ amba_writel(flash->regbase + REG3C, tmp);
+
+ tmp = amba_readl(flash->regbase + REG50);
+ REGPREP(tmp, REG50_STRTRX_MASK, REG50_STRTRX_SHIFT, 1);
+ amba_writel(flash->regbase + REG50, tmp);
+
+ for (;;){
+ tmp = amba_readl(flash->regbase + REG38);
+ if (REGDUMP(tmp, REG38_DATALENREACHINTR_MASK, REG38_DATALENREACHINTR_SHIFT) == 1){
+ return 0;
+ }
+ }
+ return -1;
+}
+EXPORT_SYMBOL_GPL(ambspi_send_cmd);
+
+int ambspi_read_reg(struct amb_norflash *flash, u32 datalen, u32 reg, u8 *value)
+{
+ u32 tmp = 0;
+ int i;
+
+ tmp = amba_readl(flash->regbase + REG28);
+ for (;REGDUMP(tmp, REG28_RXFIFOLV_MASK, REG28_RXFIFOLV_SHIFT)!= 0;){
+ amba_readb(flash->regbase + REG200);
+ tmp = amba_readl(flash->regbase + REG28);
+ }
+
+ tmp = amba_readl(flash->regbase + REG00);
+ REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
+ REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, 0);
+ REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, 0);
+ REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, datalen);
+ amba_writel(flash->regbase + REG00, tmp);
+
+ tmp = amba_readl(flash->regbase + REG04);
+ REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 1);
+ REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 0);
+ REGPREP(tmp, REG04_RXLANE_MASK, REG04_RXLANE_SHIFT, 1);
+ REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 1);
+ REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
+ amba_writel(flash->regbase + REG04, tmp);
+
+ tmp = reg;
+ amba_writel(flash->regbase + REG0C, tmp);
+
+ tmp = 0x0;
+ amba_writel(flash->regbase + REG10, tmp);
+ tmp = 0x0;
+ amba_writel(flash->regbase + REG14, tmp);
+
+ tmp = 0;
+ REGPREP(tmp, REG50_STRTRX_MASK, REG50_STRTRX_SHIFT, 1);
+ amba_writel(flash->regbase + REG50, tmp);
+
+ for (;;){
+ tmp = amba_readl(flash->regbase + REG28);
+ if(REGDUMP(tmp, REG28_RXFIFOLV_MASK, REG28_RXFIFOLV_SHIFT) == datalen){
+ break;
+ }
+ }
+
+ for (i = 0; i < datalen; i++){
+ *(value+i) = amba_readb(flash->regbase + REG200);
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(ambspi_read_reg);
+
+int ambspi_dma_config(struct amb_norflash *flash)
+{
+ flash->dmabuf = dma_alloc_coherent(flash->dev, AMBA_SPINOR_DMA_BUFF_SIZE,
+ &flash->dmaaddr, GFP_KERNEL);
+ if (flash->dmabuf == NULL){
+ dev_err(flash->dev, "dma_alloc_coherent failed!\n");
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+int ambspi_progdata_dma(struct amb_norflash *flash, u32 srcoffset, u32 dst, u32 len)
+{
+ int done;
+ u32 tmp = 0;
+
+ amba_writel(flash->dmaregbase + 0x00, 0x1a800000);// DMA_ch0_control
+ amba_writel(flash->dmaregbase + 0x0c, 0x0);
+ amba_writel(flash->dmaregbase + 0x04, flash->dmaaddr + srcoffset);// DMA_ch0_src_addr
+ amba_writel(flash->dmaregbase + 0x08, (u32)(flash->regbase + REG100));// DMA_ch0_dest_addr
+ amba_writel(flash->dmaregbase + 0x00, 0x9a800000|len);// DMA_ch0_control
+
+ tmp = amba_readl(flash->regbase + REG00);
+ REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, len);
+ REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, flash->dummy);
+ REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, flash->addr_width);
+ REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
+ amba_writel(flash->regbase + REG00, tmp);
+
+ tmp = amba_readl(flash->regbase + REG04);
+ REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 1);
+ REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 0);
+ REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 0);
+ REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
+ amba_writel(flash->regbase + REG04, tmp);
+
+ tmp = flash->command[0];
+ amba_writel(flash->regbase + REG0C, tmp);
+
+ tmp = 0;
+ REGPREP(tmp, REG30_DATAREACH_MASK, REG30_DATAREACH_SHIFT, 1);
+ amba_writel(flash->regbase + REG30, tmp);
+
+ tmp = dst;
+ amba_writel(flash->regbase + REG14, tmp);
+
+ tmp = 0;
+ REGPREP(tmp, REG1C_TXFIFOLV_MASK, REG1C_TXFIFOLV_SHIFT, (256-32));
+ amba_writel(flash->regbase + REG1C, tmp);
+
+ tmp = amba_readl(flash->regbase + REG18);
+ REGPREP(tmp, REG18_TXDMAEN_MASK, REG18_TXDMAEN_SHIFT, 1);
+ REGPREP(tmp, REG18_RXDMAEN_MASK, REG18_RXDMAEN_SHIFT, 0);
+ amba_writel(flash->regbase + REG18, tmp);
+
+ do {
+ tmp = amba_readl(flash->regbase + REG2C);
+ done = REGDUMP(tmp, REG2C_TXFIFOEMP_MASK, REG2C_TXFIFOEMP_SHIFT);
+ }while (done != 0x0);
+
+ tmp = 0x20;
+ amba_writel(flash->regbase + REG3C, tmp);
+
+ tmp = amba_readl(flash->regbase + REG50);
+ REGPREP(tmp, REG50_STRTRX_MASK, REG50_STRTRX_SHIFT, 1);
+ amba_writel(flash->regbase + REG50, tmp);
+ for (;;){
+ tmp = amba_readl(flash->regbase + REG38);
+ if (REGDUMP(tmp,
+ REG38_DATALENREACHINTR_MASK,
+ REG38_DATALENREACHINTR_SHIFT) == 1){
+ return 0;
+ }
+ }
+ return -1;
+}
+
+int ambspi_prog_data(struct amb_norflash *flash, u32 srcoffset, u32 dst, u32 len)
+{
+ u32 tmp = 0;
+ int ret = 0;
+ u32 tail = 0, bulk = 0, i = 0;
+
+ tail = len % 32;
+ bulk = len / 32;
+
+ if (bulk >= 1 ){
+ ret = ambspi_progdata_dma(flash, srcoffset, dst, len-tail);
+ }
+ if (ret){
+ return ret;
+ }
+ if (tail){
+ if(bulk >= 1){
+ flash->wait_till_ready(flash);
+ flash->write_enable(flash);
+ }
+
+ tmp = amba_readl(flash->regbase + REG00);
+ REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, tail);
+ REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, flash->dummy);
+ REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, flash->addr_width);
+ REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
+ amba_writel(flash->regbase + REG00, tmp);
+
+ tmp = amba_readl(flash->regbase + REG04);
+ REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 1);
+ REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 0);
+ REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 0);
+ REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
+ amba_writel(flash->regbase + REG04, tmp);
+
+ tmp = flash->command[0];
+ amba_writel(flash->regbase + REG0C, tmp);
+
+ tmp = 0;
+ REGPREP(tmp, REG30_DATAREACH_MASK, REG30_DATAREACH_SHIFT, 1);
+ amba_writel(flash->regbase + REG30, tmp);
+
+ tmp = dst + bulk*32;
+ amba_writel(flash->regbase + REG14, tmp);
+
+ tmp = 0;
+ REGPREP(tmp, REG1C_TXFIFOLV_MASK, REG1C_TXFIFOLV_SHIFT, (256-32));
+ amba_writel(flash->regbase + REG1C, tmp);
+
+ tmp = amba_readl(flash->regbase + REG18);
+ REGPREP(tmp, REG18_TXDMAEN_MASK, REG18_TXDMAEN_SHIFT, 0);
+ REGPREP(tmp, REG18_RXDMAEN_MASK, REG18_RXDMAEN_SHIFT, 0);
+ amba_writel(flash->regbase + REG18, tmp);
+ for (i = 0; i < tail; i++){
+ amba_writeb(flash->regbase + REG100,
+ *(flash->dmabuf + srcoffset + bulk*32 + i));
+ }
+ tmp = 0x20;
+ amba_writel(flash->regbase + REG3C, tmp);
+
+ tmp = amba_readl(flash->regbase + REG50);
+ REGPREP(tmp, REG50_STRTRX_MASK, REG50_STRTRX_SHIFT, 1);
+ amba_writel(flash->regbase + REG50, tmp);
+ for (;;){
+ tmp = amba_readl(flash->regbase + REG24);
+ if(REGDUMP(tmp, REG24_TXFIFOLV_MASK, REG24_TXFIFOLV_SHIFT) == 0){
+ return 0;
+ }
+ udelay(100);//must delay
+ }
+ }
+ return -1;
+}
+EXPORT_SYMBOL_GPL(ambspi_prog_data);
+
+int ambspi_readdata_dma(struct amb_norflash *flash, u32 from,
+ u32 len)
+{
+ u32 tmp = 0;
+
+ amba_writel(flash->dmaregbase + 0x10, 0x2a800000);// DMA_ch1_control
+ amba_writel(flash->dmaregbase + 0x1c, 0x0);
+ amba_writel(flash->dmaregbase + 0x14, (u32)(flash->regbase + REG200));// DMA_ch1_src_addr
+ amba_writel(flash->dmaregbase + 0x18, flash->dmaaddr);// DMA_ch1_dest_addr
+ amba_writel(flash->dmaregbase + 0x10, 0xaa800000 | len);// DMA_ch1_control
+
+ tmp = amba_readl(flash->regbase + REG00);
+ REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, len);
+ REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, flash->dummy);
+ REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, flash->addr_width);
+ REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
+ amba_writel(flash->regbase + REG00, tmp);
+
+ tmp = amba_readl(flash->regbase + REG04);
+ REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 1);
+ REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 0);
+ REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 1);
+ REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
+ amba_writel(flash->regbase + REG04, tmp);
+
+ tmp = flash->command[0];
+ amba_writel(flash->regbase + REG0C, tmp);
+
+ tmp = from;
+ amba_writel(flash->regbase + REG14, tmp);
+
+ tmp = 0x20;
+ amba_writel(flash->regbase + REG3C, tmp);
+
+ tmp = (32-1); // must use word.can't use rxfifothlv
+ amba_writel(flash->regbase + REG20, tmp);
+
+ tmp = amba_readl(flash->regbase + REG18);
+ REGPREP(tmp, REG18_RXDMAEN_MASK, REG18_RXDMAEN_SHIFT, 1);
+ REGPREP(tmp, REG18_TXDMAEN_MASK, REG18_TXDMAEN_SHIFT, 0);
+ amba_writel(flash->regbase + REG18, tmp);
+
+ tmp = amba_readl(flash->regbase + REG50);
+ REGPREP(tmp, REG50_STRTRX_MASK, REG50_STRTRX_SHIFT, 1);
+ amba_writel(flash->regbase + REG50, tmp);
+
+ for (;;){
+ tmp = amba_readl(flash->regbase + REG38);
+ if(REGDUMP(tmp,
+ REG38_DATALENREACHINTR_MASK,
+ REG38_DATALENREACHINTR_SHIFT) == 1){
+ return 0;
+ }
+ udelay(10);
+ }
+ return -1;
+}
+int ambspi_read_data(struct amb_norflash *flash, u32 from, u32 len)
+{
+ u32 tmp = 0;
+ int ret = 0;
+ u32 tail = 0, bulk = 0, i = 0;
+ tail = len % 32;
+ bulk = len / 32;
+ if (bulk >= 1){
+ ret = ambspi_readdata_dma(flash, from, len-tail);
+ }
+ if (ret){
+ return ret;
+ }
+ if (tail){
+ tmp = amba_readl(flash->regbase + REG00);
+ REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, tail);
+ REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, flash->dummy);
+ REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, flash->addr_width);
+ REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
+ amba_writel(flash->regbase + REG00, tmp);
+
+ tmp = amba_readl(flash->regbase + REG04);
+ REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 1);
+ REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 0);
+ REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 1);
+ REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
+ amba_writel(flash->regbase + REG04, tmp);
+
+ tmp = flash->command[0];
+ amba_writel(flash->regbase + REG0C, tmp);
+
+ tmp = from+bulk*32;
+ amba_writel(flash->regbase + REG14, tmp);
+
+ tmp = 0x20;
+ amba_writel(flash->regbase + REG3C, tmp);
+
+ tmp = 31; // the reserved bits must set 0
+ amba_writel(flash->regbase + REG20, tmp);
+
+ tmp = amba_readl(flash->regbase + REG18);
+ REGPREP(tmp, REG18_RXDMAEN_MASK, REG18_RXDMAEN_SHIFT, 0);
+ REGPREP(tmp, REG18_TXDMAEN_MASK, REG18_TXDMAEN_SHIFT, 0);
+ amba_writel(flash->regbase + REG18, tmp);
+
+ tmp = amba_readl(flash->regbase + REG50);
+ REGPREP(tmp, REG50_STRTRX_MASK, REG50_STRTRX_SHIFT, 1);
+ amba_writel(flash->regbase + REG50, tmp);
+
+ for (;;){
+ tmp = amba_readl(flash->regbase + REG28);
+ if(REGDUMP(tmp,
+ REG28_RXFIFOLV_MASK,
+ REG28_RXFIFOLV_SHIFT) == tail){
+ break;
+ }
+ }
+ for (i = 0; i < tail; i++){
+ *(flash->dmabuf+bulk*32+i) = amba_readb(flash->regbase + REG200);
+ }
+ ret = 0;
+ }
+ return ret;
+}
+EXPORT_SYMBOL_GPL(ambspi_read_data);
+
+static u32 get_ssi3_freq_hz(void)
+{
+#define PLL_OUT_ENET 300000000
+ u32 val;
+
+ val = amba_rct_readl(CG_SSI3_REG);
+ if (val & 0x01000000)
+ return 0;
+
+ if (val == 0)
+ val = 1;
+
+ //return (clk_get_rate(clk_get(NULL, "gclk_core")) << 1) / val;
+ return (PLL_OUT_ENET) / val;
+}
+
+int ambspi_init(struct amb_norflash *flash)
+{
+ u32 divider, tmp = 0;
+
+ divider = get_ssi3_freq_hz() / flash->clk;
+ tmp = amba_readl(flash->regbase + REG08);
+ REGPREP(tmp, REG08_CHIPSEL_MASK, REG08_CHIPSEL_SHIFT, ~(1 << SPINOR_DEV));
+ REGPREP(tmp, REG08_CLKDIV_MASK, REG08_CLKDIV_SHIFT, divider);
+ REGPREP(tmp, REG08_FLOWCON_MASK, REG08_FLOWCON_SHIFT, 1);
+ REGPREP(tmp, REG08_HOLDPIN_MASK, REG08_HOLDPIN_SHIFT, 3);
+ amba_writel(flash->regbase + REG08, tmp);
+
+ tmp = amba_readl(flash->regbase + REG00);
+ REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, 0);
+ REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, 0);
+ REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, 0);
+ REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
+ amba_writel(flash->regbase + REG00, tmp);
+
+ tmp = amba_readl(flash->regbase + REG04);
+ REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 0);
+ REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 0);
+ REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 0);
+ REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
+ amba_writel(flash->regbase + REG04, tmp);
+
+ tmp = 0x20;
+ amba_writel(flash->regbase + REG30, tmp);
+
+ tmp = 0;
+ REGPREP(tmp, REG40_TXFIFORESET_MASK, REG40_TXFIFORESET_SHIFT, 1);
+ amba_writel(flash->regbase + REG40, tmp);
+ tmp = 0;
+ REGPREP(tmp, REG44_RXFIFORESET_MASK, REG44_RXFIFORESET_SHIFT, 1);
+ amba_writel(flash->regbase + REG44, tmp);
+
+ /* after reset fifo, the 0x28 will become 0x10,
+ *so , read REG200 times to clear the 0x28, this is a bug in hardware
+ */
+ while (amba_readl(flash->regbase + REG28) != 0) {
+ tmp = amba_readl(flash->regbase + REG200);
+ }
+
+ tmp = 0;
+ REGPREP(tmp, REG1C_TXFIFOLV_MASK, REG1C_TXFIFOLV_SHIFT, 0x7f);
+ amba_writel(flash->regbase + REG1C, tmp);
+
+ tmp = 0;
+ REGPREP(tmp, REG20_RXFIFOLV_MASK, REG20_RXFIFOLV_SHIFT, 0x7f);
+ amba_writel(flash->regbase + REG20, tmp);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(ambspi_init);
diff --git a/drivers/mtd/devices/spinor.h b/drivers/mtd/devices/spinor.h
new file mode 100644
index 00000000..53257016
--- /dev/null
+++ b/drivers/mtd/devices/spinor.h
@@ -0,0 +1,235 @@
+/**
+ * system/include/flash/spinor.h
+ *
+ * History:
+ * 2013/10/15 - [Johnson Diao] created file
+ *
+ * Copyright 2008-2015 Ambarella Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/mutex.h>
+#include <linux/math64.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/mod_devicetable.h>
+
+#include <linux/mtd/cfi.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/of_platform.h>
+
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <plat/dma.h>
+#include <plat/rct.h>
+
+#include <plat/ptb.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/delay.h>
+
+#define REGPREP(reg,mask,shift,value) (reg=((~mask)&reg)|(value << shift))
+#define REGDUMP(reg,mask,shift) ((reg&mask)>>shift)
+
+#define REG00_DATALEN_SHIFT 0 /*[21:0] data access length*/
+#define REG00_DATALEN_MASK 0x003fffff
+#define REG00_DUMMYLEN_SHIFT 22 /*[26:22] dummy cycle length*/
+#define REG00_DUMMYLEN_MASK 0x07c00000
+#define REG00_ADDRLEN_SHIFT 27 /*[29:27] address length*/
+#define REG00_ADDRLEN_MASK 0x38000000
+#define REG00_CMDLEN_SHIFT 30 /*[31:30] command length*/
+#define REG00_CMDLEN_MASK 0xc0000000
+
+#define REG04_READEN_SHIFT 0 /*[0] data part read mode*/
+#define REG04_READEN_MASK 0x00000001
+#define REG04_WRITEEN_SHIFT 1 /*[1] data part write mode*/
+#define REG04_WRITEEN_MASK 0x00000002
+#define REG04_RXLANE_SHIFT 9 /*[9] rx lane config*/
+#define REG04_RXLANE_MASK 0x00000200
+#define REG04_DATALANE_SHIFT 10 /*[11:10] number of data lane*/
+#define REG04_DATALANE_MASK 0x00000c00
+#define REG04_ADDRLANE_SHIFT 12 /*[13:12] number of addr lane*/
+#define REG04_ADDRLANE_MASK 0x00003000
+#define REG04_CMDLANE_SHIFT 14 /*[15:14] number of command lane */
+#define REG04_CMDLANE_MASK 0x0000c000
+#define REG04_LSBFRT_SHIFT 24 /*[24] 0-msb first 1-lsb first*/
+#define REG04_LSBFRT_MASK 0x01000000
+#define REG04_DATADTR_SHIFT 28 /*[28] data double transfer rate*/
+#define REG04_DATADTR_MASK 0x10000000
+#define REG04_DUMMYDTR_SHIFT 29 /*[29] dummy double transfer rate*/
+#define REG04_DUMMYDTR_MASK 0x20000000
+#define REG04_ADDRDTR_SHIFT 30 /*[30] address double transfer rate*/
+#define REG04_ADDRDTR_MASK 0x40000000
+#define REG04_CMDDTR_SHIFT 31/*[31] command dtr,only reg_clk divider>2*/
+#define REG04_CMDDTR_MASK 0x80000000
+
+#define REG08_RXSPLDELAY_SHIFT 0 /*[4:0] adjust rx sampling data phase*/
+#define REG08_RXSPLDELAY_MASK 0x0000001f
+#define REG08_CLKDIV_SHIFT 10 /*[17:10] divide reference clock*/
+#define REG08_CLKDIV_MASK 0x0003fc00
+#define REG08_CHIPSEL_SHIFT 18 /*[25:18] cen for multiple device 0 for select and vice versa*/
+#define REG08_CHIPSEL_MASK 0x03fc0000
+#define REG08_HOLDSWITCH_SHIFT 26 /*[26]0 for hold switching on switch one ref clock cycle before negative edge*/
+#define REG08_HOLDSWITCH_MASK 0x04000000
+#define REG08_SPICLKPOL_SHIFT 27 /*[27] clock will remain 1 or 0 in standby mode*/
+#define REG08_SPICLKPOL_MASK 0x08000000
+#define REG08_HOLDPIN_SHIFT 28 /*[30:28] for flow control purpose*/
+#define REG08_HOLDPIN_MASK 0x70000000
+#define REG08_FLOWCON_SHIFT 31 /*[31] flow control enable*/
+#define REG08_FLOWCON_MASK 0x80000000
+
+#define REG0C_CMD0_SHIFT 0 /*[7:0] command for SPI device*/
+#define REG0C_CMD0_MASK 0x000000ff
+#define REG0C_CMD1_SHIFT 8 /*[15:8]*/
+#define REG0C_CMD1_MASK 0x0000ff00
+#define REG0C_CMD2_SHIFT 16 /*[23:16]*/
+#define REG0C_CMD2_MASK 0x00ff0000
+
+#define REG18_RXDMAEN_SHIFT 0 /*[0] rx dma enable*/
+#define REG18_RXDMAEN_MASK 0x00000001
+#define REG18_TXDMAEN_SHIFT 1 /*[1] tx dma enable*/
+#define REG18_TXDMAEN_MASK 0x00000002
+
+#define REG1C_TXFIFOLV_SHIFT 0 /*[8:0] tx fifo threshold level*/
+#define REG1C_TXFIFOLV_MASK 0x000000ff
+
+#define REG20_RXFIFOLV_SHIFT 0
+#define REG20_RXFIFOLV_MASK 0x000000ff
+
+#define REG24_TXFIFOLV_SHIFT 0
+#define REG24_TXFIFOLV_MASK 0x000000ff
+
+#define REG28_RXFIFOLV_SHIFT 0
+#define REG28_RXFIFOLV_MASK 0x000000ff
+
+#define REG2C_TXFIFONOTFULL_SHIFT 1 /*[1]*/
+#define REG2C_TXFIFONOTFULL_MASK 0x00000002
+#define REG2C_TXFIFOEMP_SHIFT 2 /*[2] tx fifo empty*/
+#define REG2C_TXFIFOEMP_MASK 0x00000004
+#define REG2C_RXFIFONOTEMP_SHIFT 3 /*[3] */
+#define REG2C_RXFIFONOTEMP_MASK 0x00000008
+#define REG2C_RXFIFOFULL_SHIFT 4 /*[4] rx fifo full*/
+#define REG2C_RXFIFOFULL_MASK 0x00000010
+
+#define REG30_TXEMP_SHIFT 0/*[0] tx fifo almost empty*/
+#define REG30_TXEMP_MASK 0x00000001
+#define REG30_TXOVER_SHIFT 1 /*[1]*/
+#define REG30_TXOVER_MASK 0x00000002
+#define REG30_RXUNDER_SHIFT 2/*[2]*/
+#define REG30_RXUNDER_MASK 0x00000004
+#define REG30_RXOVER_SHIFT 3/*[3]*/
+#define REG30_RXOVER_MASK 0x00000008
+#define REG30_RXFULL_SHIFT 4 /*[4]*/
+#define REG30_RXFULL_MASK 0x00000010
+#define REG30_DATAREACH_SHIFT 5 /*[5]*/
+#define REG30_DATAREACH_MASK 0x00000020
+#define REG30_TXUNDER_SHIFT 6/*[6]*/
+#define REG30_TXUNDER_MASK 0x00000040
+
+#define REG38_TXEMPTYINTR_SHIFT 0 /*[0] tx almost empty*/
+#define REG38_TXEMPTYINTR_MASK 0x00000001
+#define REG38_TXOVERFLOWINTR_SHIFT 1 /*[1] */
+#define REG38_TXOVERFLOWINTR_MASK 0x00000002
+#define REG38_RXUNDERFLOWINTR_SHIFT 2 /*[2]*/
+#define REG38_RXUNDERFLOWINTR_MASK 0x00000004
+#define REG38_RXOVERFLOWINTR_SHIFT 3 /*[3]*/
+#define REG38_RXOVERFLOWINTR_MASK 0x00000008
+#define REG38_RXFULLINTR_SHIFT 4 /*[4] rx fifo almost full*/
+#define REG38_RXFULLINTR_MASK 0x00000010
+#define REG38_DATALENREACHINTR_SHIFT 5 /*[5] transaction done interrupt*/
+#define REG38_DATALENREACHINTR_MASK 0x00000020
+#define REG38_TXUNDERFLOWINTR_SHIFT 6 /*[6] */
+#define REG38_TXUNDERFLOWINTR_MASK 0x00000040
+
+#define REG40_TXFIFORESET_SHIFT 0 /*[0] software reset the tx fifo*/
+#define REG40_TXFIFORESET_MASK 0x00000001
+
+#define REG44_RXFIFORESET_SHIFT 0 /*[0] software reset the rx fifo*/
+#define REG44_RXFIFORESET_MASK 0x00000001
+
+#define REG50_STRTRX_SHIFT 0 /*[0] start tx or rx*/
+#define REG50_STRTRX_MASK 0x00000001
+
+#define HAS_IMG_PARTS 15
+#define TOTAL_FW_PARTS (HAS_IMG_PARTS + HAS_NO_IMG_PARTS)
+
+#define REG00 0x00
+#define REG04 0x04
+#define REG08 0x08
+#define REG0C 0x0c
+#define REG10 0x10
+#define REG14 0x14
+#define REG18 0x18
+#define REG1C 0x1c
+#define REG20 0x20
+#define REG24 0x24
+#define REG28 0x28
+#define REG2C 0x2c
+#define REG30 0x30
+#define REG34 0x34
+#define REG38 0x38
+#define REG3C 0x3C
+#define REG40 0x40
+#define REG44 0x44
+#define REG50 0x50
+#define REG100 0x100
+#define REG200 0x200
+#define DMA_CONTROLLER_OFFSET (0xe0005000)
+
+#if defined(CONFIG_SPI_NOR_CHIP_0)
+#define SPINOR_DEV 0
+#elif defined(CONFIG_SPI_NOR_CHIP_1)
+#define SPINOR_DEV 1
+#elif defined(CONFIG_SPI_NOR_CHIP_2)
+#define SPINOR_DEV 2
+#elif defined(CONFIG_SPI_NOR_CHIP_3)
+#define SPINOR_DEV 3
+#else
+#define SPINOR_DEV 0
+#endif
+
+struct amb_norflash {
+ struct device *dev;
+ unsigned char __iomem *regbase;
+ unsigned char __iomem *dmaregbase;
+ dma_addr_t dmaaddr;
+ u8 *dmabuf;
+ int (*write_enable)(struct amb_norflash *flash);
+ int (*wait_till_ready)(struct amb_norflash *flash);
+ struct mutex lock;
+ struct mtd_info mtd;
+ u16 page_size;
+ u16 addr_width;
+ u8 erase_opcode;
+ u8 *command;
+ u8 dummy;
+ u32 addr;
+ u32 clk;
+ bool fast_read;
+ u32 jedec_id;
+};
+//the buffer size must align to 32 and smaller than the max size of DMA
+#define AMBA_SPINOR_DMA_BUFF_SIZE 4096
+
+extern int ambspi_init(struct amb_norflash *flash);
+extern int ambspi_read_data(struct amb_norflash *flash,u32 from,u32 len);
+extern int ambspi_send_cmd(struct amb_norflash *flash,u32 cmd,u32 dummy_len,u32 data,u32 len);
+extern int ambspi_prog_data(struct amb_norflash *flash,u32 srcoffset,u32 dst,u32 len);
+extern int ambspi_read_reg(struct amb_norflash *flash,u32 datalen,u32 reg,u8 *value);
+extern int ambspi_dma_config(struct amb_norflash *flash);
diff --git a/drivers/mtd/mtdblock_ambro.c b/drivers/mtd/mtdblock_ambro.c
new file mode 100644
index 00000000..8a506228
--- /dev/null
+++ b/drivers/mtd/mtdblock_ambro.c
@@ -0,0 +1,134 @@
+/*
+ * drivers/mtd/mtdblock_ambro.c
+ *
+ * History:
+ * 2014/08/15 - [Cao Rongrong] created file
+ *
+ * Copyright (C) 2012-2016, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/blktrans.h>
+#include <linux/module.h>
+
+struct mtdblk_ambdev {
+ struct mtd_blktrans_dev mbd;
+ unsigned int *block_map;
+ unsigned int blocks;
+};
+
+static int mtdblock_readsect(struct mtd_blktrans_dev *dev,
+ unsigned long sector, char *buf)
+{
+ struct mtdblk_ambdev *ambdev = container_of(dev, struct mtdblk_ambdev, mbd);
+ unsigned int logic_b, phys_b;
+ loff_t from;
+ size_t retlen;
+
+ logic_b = mtd_div_by_eb(sector * 512, dev->mtd);
+ phys_b = ambdev->block_map[logic_b];
+ from = phys_b * dev->mtd->erasesize + mtd_mod_by_eb(sector * 512, dev->mtd);
+
+ if (mtd_read(dev->mtd, from, 512, &retlen, buf))
+ return 1;
+
+ return 0;
+}
+
+static int mtdblock_writesect(struct mtd_blktrans_dev *dev,
+ unsigned long sector, char *buf)
+{
+ BUG();
+ return 0;
+}
+
+static void mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
+{
+ struct mtdblk_ambdev *ambdev;
+ unsigned int blocks, logic_b, phys_b;
+
+ ambdev = kzalloc(sizeof(struct mtdblk_ambdev), GFP_KERNEL);
+ if (!ambdev)
+ return;
+
+ ambdev->mbd.mtd = mtd;
+ ambdev->mbd.devnum = mtd->index;
+
+ ambdev->mbd.size = mtd->size / 512;
+ ambdev->mbd.tr = tr;
+ ambdev->mbd.readonly = 1;
+
+ blocks = mtd_div_by_eb(mtd->size, mtd);
+ ambdev->block_map = kzalloc(blocks * sizeof(unsigned int), GFP_KERNEL);
+ if (!ambdev->block_map) {
+ kfree(ambdev);
+ return;
+ }
+
+ for (logic_b = 0, phys_b = 0; phys_b < blocks; phys_b++) {
+ if (mtd_block_isbad(mtd, phys_b * mtd->erasesize))
+ continue;
+ ambdev->block_map[logic_b] = phys_b;
+ logic_b++;
+ }
+
+ ambdev->blocks = logic_b;
+
+ if (add_mtd_blktrans_dev(&ambdev->mbd)) {
+ kfree(ambdev->block_map);
+ kfree(ambdev);
+ }
+}
+
+static void mtdblock_remove_dev(struct mtd_blktrans_dev *dev)
+{
+ del_mtd_blktrans_dev(dev);
+}
+
+static struct mtd_blktrans_ops mtdblock_tr = {
+ .name = "mtdblock",
+ .major = 31,
+ .part_bits = 0,
+ .blksize = 512,
+ .readsect = mtdblock_readsect,
+ .writesect = mtdblock_writesect,
+ .add_mtd = mtdblock_add_mtd,
+ .remove_dev = mtdblock_remove_dev,
+ .owner = THIS_MODULE,
+};
+
+static int __init mtdblock_init(void)
+{
+ pr_info("Ambarella read-only mtdblock\n");
+ return register_mtd_blktrans(&mtdblock_tr);
+}
+
+static void __exit mtdblock_exit(void)
+{
+ deregister_mtd_blktrans(&mtdblock_tr);
+}
+
+module_init(mtdblock_init);
+module_exit(mtdblock_exit);
+
+MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
+MODULE_DESCRIPTION("Simple read-only block device emulation, with bad block skipped");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 50543f16..f1f18940 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -41,6 +41,20 @@ config MTD_SM_COMMON
tristate
default n
+config MTD_NAND_AMBARELLA
+ tristate "Ambarella Media Soc NAND support"
+ depends on PLAT_AMBARELLA
+ help
+ This enables the SLC NAND flash controller on the Ambarella
+ Media SoC.
+
+config MTD_SPINAND_AMBARELLA
+ tristate "Ambarella Media Soc SPI NAND support"
+ depends on PLAT_AMBARELLA
+ help
+ This enables the SPI NAND flash controller on the Ambarella
+ Media SoC.
+
config MTD_NAND_DENALI
tristate "Support Denali NAND controller"
help
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index bb818917..d60ff878 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -8,6 +8,8 @@ obj-$(CONFIG_MTD_NAND_BCH) += nand_bch.o
obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o
obj-$(CONFIG_MTD_SM_COMMON) += sm_common.o
+obj-$(CONFIG_MTD_NAND_AMBARELLA) += ambarella_nand.o
+
obj-$(CONFIG_MTD_NAND_CAFE) += cafe_nand.o
obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-delta.o
obj-$(CONFIG_MTD_NAND_DENALI) += denali.o
@@ -50,5 +52,6 @@ obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o
obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi-nand/
obj-$(CONFIG_MTD_NAND_XWAY) += xway_nand.o
obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) += bcm47xxnflash/
+obj-$(CONFIG_MTD_SPINAND_AMBARELLA) += ambarella_spinand.o
nand-objs := nand_base.o nand_bbt.o
diff --git a/drivers/mtd/nand/ambarella_nand.c b/drivers/mtd/nand/ambarella_nand.c
new file mode 100644
index 00000000..28f4c5f5
--- /dev/null
+++ b/drivers/mtd/nand/ambarella_nand.c
@@ -0,0 +1,2092 @@
+/*
+ * drivers/mtd/ambarella_nand.c
+ *
+ * History:
+ * 2008/04/11 - [Cao Rongrong & Chien-Yang Chen] created file
+ * 2009/01/04 - [Anthony Ginger] Port to 2.6.28
+ * 2012/05/23 - [Ken He] Add the dma engine driver method support
+ * 2012/07/03 - [Ken He] use the individual FDMA for nand
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/semaphore.h>
+#include <linux/slab.h>
+#include <linux/bitrev.h>
+#include <linux/bch.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_mtd.h>
+#include <linux/clk.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+#include <plat/dma.h>
+#include <plat/nand.h>
+#include <plat/fio.h>
+#include <plat/rct.h>
+#include <plat/event.h>
+
+#define AMBARELLA_NAND_DMA_BUFFER_SIZE 4096
+
+
+struct ambarella_nand_info {
+ struct nand_chip chip;
+ struct mtd_info mtd;
+ struct nand_hw_control controller;
+
+ struct device *dev;
+ wait_queue_head_t wq;
+
+ unsigned char __iomem *regbase;
+ unsigned char __iomem *fdmaregbase;
+ u32 dmabase;
+ int suspend;
+ /* dma irq for transferring data between Nand and FIFO */
+ int dma_irq;
+ int cmd_irq;
+ /* fdma irq for transferring data between FIFO and Dram */
+ int fdma_irq;
+ u32 ecc_bits;
+ /* if or not support to read id in 5 cycles */
+ bool id_cycles_5;
+ bool pllx2;
+ bool soft_ecc;
+ bool nand_wp;
+
+ /* used for software BCH */
+ struct bch_control *bch;
+ u32 *errloc;
+ u8 *bch_data;
+ u8 read_ecc_rev[13];
+ u8 calc_ecc_rev[13];
+ u8 soft_bch_extra_size;
+
+ dma_addr_t dmaaddr;
+ u8 *dmabuf;
+ int dma_bufpos;
+ u32 dma_status;
+ u32 fio_dma_sta;
+ u32 fio_ecc_sta;
+ atomic_t irq_flag;
+
+ /* saved column/page_addr during CMD_SEQIN */
+ int seqin_column;
+ int seqin_page_addr;
+
+ /* Operation parameters for nand controller register */
+ int err_code;
+ u32 cmd;
+ u32 control_reg;
+ u32 addr_hi;
+ u32 addr;
+ u32 dst;
+ dma_addr_t buf_phys;
+ dma_addr_t spare_buf_phys;
+ u32 len;
+ u32 slen;
+ u32 area;
+ u32 ecc;
+ u32 timing[6];
+
+ struct notifier_block system_event;
+ struct semaphore system_event_sem;
+
+};
+
+static struct nand_ecclayout amb_oobinfo_512 = {
+ .eccbytes = 5,
+ .eccpos = {6, 7, 8, 9, 10},
+ .oobfree = {{0, 5}, {11, 5}}
+};
+
+static struct nand_ecclayout amb_oobinfo_2048 = {
+ .eccbytes = 20,
+ .eccpos = {8, 9, 10,11, 12,
+ 24, 25, 26, 27, 28,
+ 40, 41, 42, 43, 44,
+ 56, 57, 58, 59, 60},
+ .oobfree = {{1, 7}, {13, 3},
+ {17, 7}, {29, 3},
+ {33, 7}, {45, 3},
+ {49, 7}, {61, 3}}
+};
+
+static struct nand_ecclayout amb_oobinfo_2048_dsm_ecc6 = {
+ .eccbytes = 40,
+ .eccpos = {6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63},
+ .oobfree = {{1, 5}, {17, 5},
+ {33, 5}, {49, 5}}
+};
+
+static struct nand_ecclayout amb_oobinfo_2048_dsm_ecc8 = {
+ .eccbytes = 52,
+ .eccpos = {19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127},
+ .oobfree = {{2, 17}, {34, 17},
+ {66, 17}, {98, 17}}
+};
+
+/* ==========================================================================*/
+#define NAND_TIMING_RSHIFT24BIT(x) (((x) & 0xff000000) >> 24)
+#define NAND_TIMING_RSHIFT16BIT(x) (((x) & 0x00ff0000) >> 16)
+#define NAND_TIMING_RSHIFT8BIT(x) (((x) & 0x0000ff00) >> 8)
+#define NAND_TIMING_RSHIFT0BIT(x) (((x) & 0x000000ff) >> 0)
+
+#define NAND_TIMING_LSHIFT24BIT(x) ((x) << 24)
+#define NAND_TIMING_LSHIFT16BIT(x) ((x) << 16)
+#define NAND_TIMING_LSHIFT8BIT(x) ((x) << 8)
+#define NAND_TIMING_LSHIFT0BIT(x) ((x) << 0)
+
+static int nand_timing_calc(u32 clk, int minmax, int val)
+{
+ u32 x;
+ int n,r;
+
+ x = val * clk;
+ n = x / 1000;
+ r = x % 1000;
+
+ if (r != 0)
+ n++;
+
+ if (minmax)
+ n--;
+ return n < 1 ? 1 : n;
+}
+
+static inline int nand_amb_is_hw_bch(struct ambarella_nand_info *nand_info)
+{
+ return !nand_info->soft_ecc && nand_info->ecc_bits > 1;
+}
+
+static inline int nand_amb_is_sw_bch(struct ambarella_nand_info *nand_info)
+{
+ return nand_info->soft_ecc && nand_info->ecc_bits > 1;
+}
+
+static void nand_amb_corrected_recovery(struct ambarella_nand_info *nand_info)
+{
+ u32 fio_ctr_reg, fio_dmactr_reg;
+
+ /* FIO reset will just reset FIO registers, but will not affect
+ * Nand controller. */
+ fio_ctr_reg = amba_readl(nand_info->regbase + FIO_CTR_OFFSET);
+ fio_dmactr_reg = amba_readl(nand_info->regbase + FIO_DMACTR_OFFSET);
+ ambarella_fio_rct_reset();
+ amba_writel(nand_info->regbase + FIO_CTR_OFFSET, fio_ctr_reg);
+ amba_writel(nand_info->regbase + FIO_DMACTR_OFFSET, fio_dmactr_reg);
+}
+
+static void nand_amb_enable_dsm(struct ambarella_nand_info *nand_info)
+{
+ u32 fio_dsm_ctr = 0, fio_ctr_reg = 0, dma_dsm_ctr = 0;
+ fio_ctr_reg = amba_readl(nand_info->regbase + FIO_CTR_OFFSET);
+
+ fio_dsm_ctr |= (FIO_DSM_EN | FIO_DSM_MAJP_2KB);
+ dma_dsm_ctr |= (DMA_DSM_EN | DMA_DSM_MAJP_2KB);
+ fio_ctr_reg |= FIO_CTR_RS;
+ fio_ctr_reg &= ~(FIO_CTR_CO | FIO_CTR_SE | FIO_CTR_ECC_6BIT
+ | FIO_CTR_ECC_8BIT);
+
+ if (nand_info->ecc_bits == 6) {
+ fio_dsm_ctr |= FIO_DSM_SPJP_64B;
+ dma_dsm_ctr |= DMA_DSM_SPJP_64B;
+ } else {
+ u32 nand_ext_ctr_reg = 0;
+ fio_dsm_ctr |= FIO_DSM_SPJP_128B;
+ dma_dsm_ctr |= DMA_DSM_SPJP_128B;
+
+ nand_ext_ctr_reg = amba_readl(nand_info->regbase +
+ FLASH_EX_CTR_OFFSET);
+ nand_ext_ctr_reg |= NAND_EXT_CTR_SP_2X;
+ amba_writel(nand_info->regbase + FLASH_EX_CTR_OFFSET,
+ nand_ext_ctr_reg);
+ }
+
+ amba_writel(nand_info->regbase + FIO_CTR_OFFSET, fio_ctr_reg | FIO_CTR_RR);
+ amba_writel(nand_info->regbase + FIO_DSM_CTR_OFFSET, fio_dsm_ctr);
+ amba_writel(nand_info->regbase + FIO_CTR_OFFSET, fio_ctr_reg);
+ amba_writel(nand_info->fdmaregbase + FDMA_DSM_CTR_OFFSET, dma_dsm_ctr);
+
+}
+
+static void nand_amb_enable_bch(struct ambarella_nand_info *nand_info)
+{
+ u32 fio_dsm_ctr = 0, fio_ctr_reg = 0, dma_dsm_ctr = 0;
+ fio_ctr_reg = amba_readl(nand_info->regbase + FIO_CTR_OFFSET);
+
+ fio_dsm_ctr |= (FIO_DSM_EN | FIO_DSM_MAJP_2KB);
+ dma_dsm_ctr |= (DMA_DSM_EN | DMA_DSM_MAJP_2KB);
+ fio_ctr_reg |= (FIO_CTR_RS | FIO_CTR_CO | FIO_CTR_SKIP_BLANK);
+
+ if (nand_info->ecc_bits == 6) {
+ fio_dsm_ctr |= FIO_DSM_SPJP_64B;
+ dma_dsm_ctr |= DMA_DSM_SPJP_64B;
+ fio_ctr_reg |= FIO_CTR_ECC_6BIT;
+ } else {
+ u32 nand_ext_ctr_reg = 0;
+ fio_dsm_ctr |= FIO_DSM_SPJP_128B;
+ dma_dsm_ctr |= DMA_DSM_SPJP_128B;
+ fio_ctr_reg |= FIO_CTR_ECC_8BIT;
+ nand_ext_ctr_reg = amba_readl(nand_info->regbase +
+ FLASH_EX_CTR_OFFSET);
+ nand_ext_ctr_reg |= NAND_EXT_CTR_SP_2X;
+ amba_writel(nand_info->regbase + FLASH_EX_CTR_OFFSET,
+ nand_ext_ctr_reg);
+ }
+
+ amba_writel(nand_info->regbase + FIO_CTR_OFFSET, fio_ctr_reg | FIO_CTR_RR);
+ amba_writel(nand_info->regbase + FIO_DSM_CTR_OFFSET, fio_dsm_ctr);
+ amba_writel(nand_info->regbase + FIO_CTR_OFFSET, fio_ctr_reg);
+ amba_writel(nand_info->fdmaregbase + FDMA_DSM_CTR_OFFSET, dma_dsm_ctr);
+
+}
+
+static void nand_amb_disable_bch(struct ambarella_nand_info *nand_info)
+{
+ u32 fio_ctr_reg = 0;
+
+ fio_ctr_reg = amba_readl(nand_info->regbase + FIO_CTR_OFFSET);
+ /* Setup FIO Dual Space Mode Control Register */
+ fio_ctr_reg |= FIO_CTR_RS;
+ fio_ctr_reg &= ~(FIO_CTR_CO |
+ FIO_CTR_ECC_6BIT |
+ FIO_CTR_ECC_8BIT);
+
+ if (nand_info->ecc_bits == 8) {
+ u32 nand_ext_ctr_reg = 0;
+ nand_ext_ctr_reg = amba_readl(nand_info->regbase +
+ FLASH_EX_CTR_OFFSET);
+ nand_ext_ctr_reg &= ~NAND_EXT_CTR_SP_2X;
+ amba_writel(nand_info->regbase + FLASH_EX_CTR_OFFSET,
+ nand_ext_ctr_reg);
+ }
+ amba_writel(nand_info->regbase + FIO_CTR_OFFSET, fio_ctr_reg);
+
+ amba_writel(nand_info->regbase + FIO_DSM_CTR_OFFSET, 0);
+ amba_writel(nand_info->fdmaregbase + FDMA_DSM_CTR_OFFSET, 0);
+}
+
+static int count_zero_bits(u8 *buf, int size, int max_bits)
+{
+ int i, zero_bits = 0;
+
+ for (i = 0; i < size; i++) {
+ zero_bits += hweight8(~buf[i]);
+ if (zero_bits > max_bits)
+ break;
+ }
+ return zero_bits;
+}
+
+static int nand_bch_check_blank_page(struct ambarella_nand_info *nand_info, int needset)
+{
+ struct nand_chip *chip = &nand_info->chip;
+ int eccsteps = chip->ecc.steps;
+ int zeroflip = 0;
+ int oob_subset;
+ int zero_bits = 0;
+ u32 i;
+ u8 *bufpos;
+ u8 *bsp;
+
+ bufpos = nand_info->dmabuf;
+ bsp = nand_info->dmabuf + nand_info->mtd.writesize;
+ oob_subset = nand_info->mtd.oobsize / eccsteps;
+
+ for (i = 0; i < eccsteps; i++) {
+ zero_bits = count_zero_bits(bufpos, chip->ecc.size,
+ chip->ecc.strength);
+ if (zero_bits > chip->ecc.strength)
+ return -1;
+
+ if (zero_bits)
+ zeroflip = 1;
+
+ zero_bits += count_zero_bits(bsp, oob_subset,
+ chip->ecc.strength);
+ if (zero_bits > chip->ecc.strength)
+ return -1;
+
+ bufpos += chip->ecc.size;
+ bsp += oob_subset;
+ }
+
+ if (needset && zeroflip)
+ memset(nand_info->dmabuf, 0xff, nand_info->mtd.writesize);
+
+ return zeroflip;
+}
+static void amb_nand_set_timing(struct ambarella_nand_info *nand_info)
+{
+ u8 tcls, tals, tcs, tds;
+ u8 tclh, talh, tch, tdh;
+ u8 twp, twh, twb, trr;
+ u8 trp, treh, trb, tceh;
+ u8 trdelay, tclr, twhr, tir;
+ u8 tww, trhz, tar;
+ u32 i, t, clk, val;
+
+ for (i = 0; i < ARRAY_SIZE(nand_info->timing); i++) {
+ if (nand_info->timing[i] != 0x0)
+ break;
+ }
+ /* if the timing is not setup by Amboot, we leave the timing unchanged */
+ if (i == ARRAY_SIZE(nand_info->timing))
+ return;
+
+ clk = (clk_get_rate(clk_get(NULL, "gclk_core")) / 1000000);
+ if (nand_info->pllx2)
+ clk <<= 1;
+
+ /* timing 0 */
+ t = nand_info->timing[0];
+ tcls = NAND_TIMING_RSHIFT24BIT(t);
+ tals = NAND_TIMING_RSHIFT16BIT(t);
+ tcs = NAND_TIMING_RSHIFT8BIT(t);
+ tds = NAND_TIMING_RSHIFT0BIT(t);
+
+ tcls = nand_timing_calc(clk, 0, tcls);
+ tals = nand_timing_calc(clk, 0, tals);
+ tcs = nand_timing_calc(clk, 0, tcs);
+ tds = nand_timing_calc(clk, 0, tds);
+
+ val = NAND_TIMING_LSHIFT24BIT(tcls) |
+ NAND_TIMING_LSHIFT16BIT(tals) |
+ NAND_TIMING_LSHIFT8BIT(tcs) |
+ NAND_TIMING_LSHIFT0BIT(tds);
+
+ /* use default timing if gclk_core <= 96MHz */
+ if (clk <= 96)
+ val = 0x20202020;
+
+ amba_writel(nand_info->regbase + FLASH_TIM0_OFFSET, val);
+
+ /* timing 1 */
+ t = nand_info->timing[1];
+ tclh = NAND_TIMING_RSHIFT24BIT(t);
+ talh = NAND_TIMING_RSHIFT16BIT(t);
+ tch = NAND_TIMING_RSHIFT8BIT(t);
+ tdh = NAND_TIMING_RSHIFT0BIT(t);
+
+ tclh = nand_timing_calc(clk, 0, tclh);
+ talh = nand_timing_calc(clk, 0, talh);
+ tch = nand_timing_calc(clk, 0, tch);
+ tdh = nand_timing_calc(clk, 0, tdh);
+
+ val = NAND_TIMING_LSHIFT24BIT(tclh) |
+ NAND_TIMING_LSHIFT16BIT(talh) |
+ NAND_TIMING_LSHIFT8BIT(tch) |
+ NAND_TIMING_LSHIFT0BIT(tdh);
+
+ /* use default timing if gclk_core <= 96MHz */
+ if (clk <= 96)
+ val = 0x20202020;
+
+ amba_writel(nand_info->regbase + FLASH_TIM1_OFFSET, val);
+
+ /* timing 2 */
+ t = nand_info->timing[2];
+ twp = NAND_TIMING_RSHIFT24BIT(t);
+ twh = NAND_TIMING_RSHIFT16BIT(t);
+ twb = NAND_TIMING_RSHIFT8BIT(t);
+ trr = NAND_TIMING_RSHIFT0BIT(t);
+
+ twp = nand_timing_calc(clk, 0, twp);
+ twh = nand_timing_calc(clk, 0, twh);
+ twb = nand_timing_calc(clk, 1, twb);
+ trr = nand_timing_calc(clk, 0, trr);
+
+ val = NAND_TIMING_LSHIFT24BIT(twp) |
+ NAND_TIMING_LSHIFT16BIT(twh) |
+ NAND_TIMING_LSHIFT8BIT(twb) |
+ NAND_TIMING_LSHIFT0BIT(trr);
+
+ /* use default timing if gclk_core <= 96MHz */
+ if (clk <= 96)
+ val = 0x20204020;
+
+ amba_writel(nand_info->regbase + FLASH_TIM2_OFFSET, val);
+
+ /* timing 3 */
+ t = nand_info->timing[3];
+ trp = NAND_TIMING_RSHIFT24BIT(t);
+ treh = NAND_TIMING_RSHIFT16BIT(t);
+ trb = NAND_TIMING_RSHIFT8BIT(t);
+ tceh = NAND_TIMING_RSHIFT0BIT(t);
+
+ trp = nand_timing_calc(clk, 0, trp);
+ treh = nand_timing_calc(clk, 0, treh);
+ trb = nand_timing_calc(clk, 1, trb);
+ tceh = nand_timing_calc(clk, 1, tceh);
+
+ val = NAND_TIMING_LSHIFT24BIT(trp) |
+ NAND_TIMING_LSHIFT16BIT(treh) |
+ NAND_TIMING_LSHIFT8BIT(trb) |
+ NAND_TIMING_LSHIFT0BIT(tceh);
+
+ /* use default timing if gclk_core <= 96MHz */
+ if (clk <= 96)
+ val = 0x20202020;
+
+ amba_writel(nand_info->regbase + FLASH_TIM3_OFFSET, val);
+
+ /* timing 4 */
+ t = nand_info->timing[4];
+ trdelay = NAND_TIMING_RSHIFT24BIT(t);
+ tclr = NAND_TIMING_RSHIFT16BIT(t);
+ twhr = NAND_TIMING_RSHIFT8BIT(t);
+ tir = NAND_TIMING_RSHIFT0BIT(t);
+
+ trdelay = trp + treh;
+ tclr = nand_timing_calc(clk, 0, tclr);
+ twhr = nand_timing_calc(clk, 0, twhr);
+ tir = nand_timing_calc(clk, 0, tir);
+
+ val = NAND_TIMING_LSHIFT24BIT(trdelay) |
+ NAND_TIMING_LSHIFT16BIT(tclr) |
+ NAND_TIMING_LSHIFT8BIT(twhr) |
+ NAND_TIMING_LSHIFT0BIT(tir);
+
+ /* use default timing if gclk_core <= 96MHz */
+ if (clk <= 96)
+ val = 0x20202020;
+
+ amba_writel(nand_info->regbase + FLASH_TIM4_OFFSET, val);
+
+ /* timing 5 */
+ t = nand_info->timing[5];
+ tww = NAND_TIMING_RSHIFT16BIT(t);
+ trhz = NAND_TIMING_RSHIFT8BIT(t);
+ tar = NAND_TIMING_RSHIFT0BIT(t);
+
+ tww = nand_timing_calc(clk, 0, tww);
+ trhz = nand_timing_calc(clk, 1, trhz);
+ tar = nand_timing_calc(clk, 0, tar);
+
+
+ val = NAND_TIMING_LSHIFT16BIT(tww) |
+ NAND_TIMING_LSHIFT8BIT(trhz) |
+ NAND_TIMING_LSHIFT0BIT(tar);
+
+ /* use default timing if gclk_core <= 96MHz */
+ if (clk <= 96)
+ val = 0x20202020;
+
+ amba_writel(nand_info->regbase + FLASH_TIM5_OFFSET, val);
+}
+
+static int ambarella_nand_system_event(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ int errorCode = NOTIFY_OK;
+ struct ambarella_nand_info *nand_info;
+
+ nand_info = container_of(nb, struct ambarella_nand_info, system_event);
+
+ switch (val) {
+ case AMBA_EVENT_PRE_CPUFREQ:
+ pr_debug("%s: Pre Change\n", __func__);
+ down(&nand_info->system_event_sem);
+ break;
+
+ case AMBA_EVENT_POST_CPUFREQ:
+ pr_debug("%s: Post Change\n", __func__);
+ amb_nand_set_timing(nand_info);
+ up(&nand_info->system_event_sem);
+ break;
+
+ default:
+ break;
+ }
+
+ return errorCode;
+}
+
+static irqreturn_t nand_fiocmd_isr_handler(int irq, void *dev_id)
+{
+ irqreturn_t rval = IRQ_NONE;
+ struct ambarella_nand_info *nand_info;
+ u32 val;
+
+ nand_info = (struct ambarella_nand_info *)dev_id;
+
+ val = amba_readl(nand_info->regbase + FIO_STA_OFFSET);
+
+ if (val & FIO_STA_FI) {
+ amba_writel(nand_info->regbase + FLASH_INT_OFFSET, 0x0);
+
+ atomic_clear_mask(0x1, (unsigned long *)&nand_info->irq_flag);
+ wake_up(&nand_info->wq);
+
+ rval = IRQ_HANDLED;
+ }
+
+ return rval;
+}
+
+/* this dma is used to transfer data between Nand and FIO FIFO. */
+static irqreturn_t nand_fiodma_isr_handler(int irq, void *dev_id)
+{
+ struct ambarella_nand_info *nand_info;
+ u32 val, fio_dma_sta;
+
+ nand_info = (struct ambarella_nand_info *)dev_id;
+
+ val = amba_readl(nand_info->regbase + FIO_DMACTR_OFFSET);
+
+ if ((val & (FIO_DMACTR_SD | FIO_DMACTR_CF |
+ FIO_DMACTR_XD | FIO_DMACTR_FL)) == FIO_DMACTR_FL) {
+ fio_dma_sta = amba_readl(nand_info->regbase + FIO_DMASTA_OFFSET);
+ /* dummy IRQ by S2 chip */
+ if (fio_dma_sta == 0x0)
+ return IRQ_HANDLED;
+
+ nand_info->fio_dma_sta = fio_dma_sta;
+
+ amba_writel(nand_info->regbase + FIO_DMASTA_OFFSET, 0x0);
+
+ if (nand_amb_is_hw_bch(nand_info)) {
+ nand_info->fio_ecc_sta =
+ amba_readl(nand_info->regbase + FIO_ECC_RPT_STA_OFFSET);
+ amba_writel(nand_info->regbase + FIO_ECC_RPT_STA_OFFSET, 0x0);
+ }
+ atomic_clear_mask(0x2, (unsigned long *)&nand_info->irq_flag);
+ wake_up(&nand_info->wq);
+ }
+
+ return IRQ_HANDLED;
+}
+
+/* this dma is used to transfer data between FIO FIFO and Memory. */
+static irqreturn_t ambarella_fdma_isr_handler(int irq, void *dev_id)
+{
+ irqreturn_t rval = IRQ_NONE;
+ struct ambarella_nand_info *nand_info;
+ u32 int_src;
+
+ nand_info = (struct ambarella_nand_info *)dev_id;
+
+ int_src = amba_readl(nand_info->fdmaregbase + FDMA_INT_OFFSET);
+
+ if (int_src & (1 << FIO_DMA_CHAN)) {
+ nand_info->dma_status =
+ amba_readl(nand_info->fdmaregbase + FDMA_STA_OFFSET);
+ amba_writel(nand_info->fdmaregbase + FDMA_STA_OFFSET, 0);
+ amba_writel(nand_info->fdmaregbase + FDMA_SPR_STA_OFFSET, 0);
+
+ atomic_clear_mask(0x4, (unsigned long *)&nand_info->irq_flag);
+ wake_up(&nand_info->wq);
+
+ rval = IRQ_HANDLED;
+ }
+
+ return rval;
+}
+
+static void nand_amb_setup_dma_devmem(struct ambarella_nand_info *nand_info)
+{
+ u32 ctrl_val;
+ u32 size = 0;
+
+ /* init and enable fdma to transfer data betwee FIFO and Memory */
+ if (nand_info->len > 16)
+ ctrl_val = DMA_CHANX_CTR_WM | DMA_CHANX_CTR_NI | DMA_NODC_MN_BURST_SIZE;
+ else
+ ctrl_val = DMA_CHANX_CTR_WM | DMA_CHANX_CTR_NI | DMA_NODC_SP_BURST_SIZE;
+
+ ctrl_val |= nand_info->len | DMA_CHANX_CTR_EN;
+ ctrl_val &= ~DMA_CHANX_CTR_D;
+
+ /* Setup main external DMA engine transfer */
+ amba_writel(nand_info->fdmaregbase + FDMA_STA_OFFSET, 0);
+
+ amba_writel(nand_info->fdmaregbase + FDMA_SRC_OFFSET, nand_info->dmabase);
+ amba_writel(nand_info->fdmaregbase + FDMA_DST_OFFSET, nand_info->buf_phys);
+
+ if (nand_info->ecc_bits > 1) {
+ /* Setup spare external DMA engine transfer */
+ amba_writel(nand_info->fdmaregbase + FDMA_SPR_STA_OFFSET, 0x0);
+ amba_writel(nand_info->fdmaregbase + FDMA_SPR_SRC_OFFSET, nand_info->dmabase);
+ amba_writel(nand_info->fdmaregbase + FDMA_SPR_DST_OFFSET, nand_info->spare_buf_phys);
+ amba_writel(nand_info->fdmaregbase + FDMA_SPR_CNT_OFFSET, nand_info->slen);
+ }
+
+ amba_writel(nand_info->fdmaregbase + FDMA_CTR_OFFSET, ctrl_val);
+
+ /* init and enable fio-dma to transfer data between Nand and FIFO */
+ amba_writel(nand_info->regbase + FIO_DMAADR_OFFSET, nand_info->addr);
+
+ size = nand_info->len + nand_info->slen;
+ if (size > 16) {
+ ctrl_val = FIO_DMACTR_EN |
+ FIO_DMACTR_FL |
+ FIO_MN_BURST_SIZE |
+ size;
+ } else {
+ ctrl_val = FIO_DMACTR_EN |
+ FIO_DMACTR_FL |
+ FIO_SP_BURST_SIZE |
+ size;
+ }
+ amba_writel(nand_info->regbase + FIO_DMACTR_OFFSET, ctrl_val);
+}
+
+static void nand_amb_setup_dma_memdev(struct ambarella_nand_info *nand_info)
+{
+ u32 ctrl_val, dma_burst_val, fio_burst_val;
+ u32 size = 0;
+
+ if (nand_info->ecc_bits > 1) {
+ dma_burst_val = DMA_NODC_MN_BURST_SIZE8;
+ fio_burst_val = FIO_MN_BURST_SIZE8;
+ } else {
+ dma_burst_val = DMA_NODC_MN_BURST_SIZE;
+ fio_burst_val = FIO_MN_BURST_SIZE;
+ }
+
+ /* init and enable fdma to transfer data betwee FIFO and Memory */
+ if (nand_info->len > 16)
+ ctrl_val = DMA_CHANX_CTR_RM | DMA_CHANX_CTR_NI | dma_burst_val;
+ else
+ ctrl_val = DMA_CHANX_CTR_RM | DMA_CHANX_CTR_NI | DMA_NODC_SP_BURST_SIZE;
+
+ ctrl_val |= nand_info->len | DMA_CHANX_CTR_EN;
+ ctrl_val &= ~DMA_CHANX_CTR_D;
+
+ /* Setup main external DMA engine transfer */
+ amba_writel(nand_info->fdmaregbase + FDMA_STA_OFFSET, 0);
+
+ amba_writel(nand_info->fdmaregbase + FDMA_SRC_OFFSET, nand_info->buf_phys);
+ amba_writel(nand_info->fdmaregbase + FDMA_DST_OFFSET, nand_info->dmabase);
+
+ if (nand_info->ecc_bits > 1) {
+ /* Setup spare external DMA engine transfer */
+ amba_writel(nand_info->fdmaregbase + FDMA_SPR_STA_OFFSET, 0x0);
+ amba_writel(nand_info->fdmaregbase + FDMA_SPR_SRC_OFFSET, nand_info->spare_buf_phys);
+ amba_writel(nand_info->fdmaregbase + FDMA_SPR_DST_OFFSET, nand_info->dmabase);
+ amba_writel(nand_info->fdmaregbase + FDMA_SPR_CNT_OFFSET, nand_info->slen);
+ }
+
+ amba_writel(nand_info->fdmaregbase + FDMA_CTR_OFFSET, ctrl_val);
+
+ /* init and enable fio-dma to transfer data between Nand and FIFO */
+ amba_writel(nand_info->regbase + FIO_DMAADR_OFFSET, nand_info->addr);
+
+ size = nand_info->len + nand_info->slen;
+ if (size > 16) {
+ ctrl_val = FIO_DMACTR_EN | FIO_DMACTR_FL | fio_burst_val |
+ FIO_DMACTR_RM | size;
+ } else {
+ ctrl_val = FIO_DMACTR_EN | FIO_DMACTR_FL | FIO_SP_BURST_SIZE |
+ FIO_DMACTR_RM | size;
+ }
+ amba_writel(nand_info->regbase + FIO_DMACTR_OFFSET, ctrl_val);
+}
+
+static int nand_amb_request(struct ambarella_nand_info *nand_info)
+{
+ int errorCode = 0;
+ u32 cmd;
+ u32 nand_ctr_reg = 0;
+ u32 nand_cmd_reg = 0;
+ u32 fio_ctr_reg = 0;
+ long timeout;
+
+ if (unlikely(nand_info->suspend == 1)) {
+ dev_err(nand_info->dev, "%s: suspend!\n", __func__);
+ errorCode = -EPERM;
+ goto nand_amb_request_exit;
+ }
+
+ cmd = nand_info->cmd;
+
+ nand_ctr_reg = nand_info->control_reg | NAND_CTR_WAS;
+
+ fio_select_lock(SELECT_FIO_FL);
+
+ if ((nand_info->nand_wp) &&
+ (cmd == NAND_AMB_CMD_ERASE || cmd == NAND_AMB_CMD_COPYBACK ||
+ cmd == NAND_AMB_CMD_PROGRAM || cmd == NAND_AMB_CMD_READSTATUS))
+ nand_ctr_reg &= ~NAND_CTR_WP;
+
+ switch (cmd) {
+ case NAND_AMB_CMD_RESET:
+ nand_cmd_reg = NAND_AMB_CMD_RESET;
+ amba_writel(nand_info->regbase + FLASH_CMD_OFFSET,
+ nand_cmd_reg);
+ break;
+
+ case NAND_AMB_CMD_READID:
+ nand_ctr_reg |= NAND_CTR_A(nand_info->addr_hi);
+ nand_cmd_reg = nand_info->addr | NAND_AMB_CMD_READID;
+
+ if (nand_info->id_cycles_5) {
+ u32 nand_ext_ctr_reg = 0;
+
+ nand_ext_ctr_reg = amba_readl(nand_info->regbase + FLASH_EX_CTR_OFFSET);
+ nand_ext_ctr_reg |= NAND_EXT_CTR_I5;
+ nand_ctr_reg &= ~(NAND_CTR_I4);
+ amba_writel(nand_info->regbase + FLASH_EX_CTR_OFFSET,
+ nand_ext_ctr_reg);
+ }
+
+ amba_writel(nand_info->regbase + FLASH_CTR_OFFSET,
+ nand_ctr_reg);
+ amba_writel(nand_info->regbase + FLASH_CMD_OFFSET,
+ nand_cmd_reg);
+ break;
+
+ case NAND_AMB_CMD_READSTATUS:
+ nand_ctr_reg |= NAND_CTR_A(nand_info->addr_hi);
+ nand_cmd_reg = nand_info->addr | NAND_AMB_CMD_READSTATUS;
+ amba_writel(nand_info->regbase + FLASH_CTR_OFFSET,
+ nand_ctr_reg);
+ amba_writel(nand_info->regbase + FLASH_CMD_OFFSET,
+ nand_cmd_reg);
+ break;
+
+ case NAND_AMB_CMD_ERASE:
+ nand_ctr_reg |= NAND_CTR_A(nand_info->addr_hi);
+ nand_cmd_reg = nand_info->addr | NAND_AMB_CMD_ERASE;
+ amba_writel(nand_info->regbase + FLASH_CTR_OFFSET,
+ nand_ctr_reg);
+ amba_writel(nand_info->regbase + FLASH_CMD_OFFSET,
+ nand_cmd_reg);
+ break;
+
+ case NAND_AMB_CMD_COPYBACK:
+ nand_ctr_reg |= NAND_CTR_A(nand_info->addr_hi);
+ nand_ctr_reg |= NAND_CTR_CE;
+ nand_cmd_reg = nand_info->addr | NAND_AMB_CMD_COPYBACK;
+ amba_writel(nand_info->regbase + FLASH_CFI_OFFSET,
+ nand_info->dst);
+ amba_writel(nand_info->regbase + FLASH_CTR_OFFSET,
+ nand_ctr_reg);
+ amba_writel(nand_info->regbase + FLASH_CMD_OFFSET,
+ nand_cmd_reg);
+ break;
+
+ case NAND_AMB_CMD_READ:
+ nand_ctr_reg |= NAND_CTR_A(nand_info->addr_hi);
+
+ if (nand_amb_is_hw_bch(nand_info)) {
+ /* Setup FIO DMA Control Register */
+ nand_amb_enable_bch(nand_info);
+ /* in dual space mode,enable the SE bit */
+ nand_ctr_reg |= NAND_CTR_SE;
+
+ /* Clean Flash_IO_ecc_rpt_status Register */
+ amba_writel(nand_info->regbase + FIO_ECC_RPT_STA_OFFSET, 0x0);
+ } else if (nand_amb_is_sw_bch(nand_info)) {
+ /* Setup FIO DMA Control Register */
+ nand_amb_enable_dsm(nand_info);
+ /* in dual space mode,enable the SE bit */
+ nand_ctr_reg |= NAND_CTR_SE;
+ } else {
+ if (nand_info->area == MAIN_ECC)
+ nand_ctr_reg |= (NAND_CTR_SE);
+ else if (nand_info->area == SPARE_ONLY ||
+ nand_info->area == SPARE_ECC)
+ nand_ctr_reg |= (NAND_CTR_SE | NAND_CTR_SA);
+
+ fio_ctr_reg = amba_readl(nand_info->regbase + FIO_CTR_OFFSET);
+ fio_ctr_reg &= ~(FIO_CTR_CO | FIO_CTR_RS);
+
+ if (nand_info->area == SPARE_ONLY ||
+ nand_info->area == SPARE_ECC ||
+ nand_info->area == MAIN_ECC)
+ fio_ctr_reg |= (FIO_CTR_RS);
+
+ switch (nand_info->ecc) {
+ case EC_MDSE:
+ nand_ctr_reg |= NAND_CTR_EC_SPARE;
+ fio_ctr_reg |= FIO_CTR_CO;
+ break;
+ case EC_MESD:
+ nand_ctr_reg |= NAND_CTR_EC_MAIN;
+ fio_ctr_reg |= FIO_CTR_CO;
+ break;
+ case EC_MESE:
+ nand_ctr_reg |= (NAND_CTR_EC_MAIN | NAND_CTR_EC_SPARE);
+ fio_ctr_reg |= FIO_CTR_CO;
+ break;
+ case EC_MDSD:
+ default:
+ break;
+ }
+
+ amba_writel(nand_info->regbase + FIO_CTR_OFFSET,
+ fio_ctr_reg);
+ }
+
+ amba_writel(nand_info->regbase + FLASH_CTR_OFFSET, nand_ctr_reg);
+ nand_amb_setup_dma_devmem(nand_info);
+
+ break;
+
+ case NAND_AMB_CMD_PROGRAM:
+ nand_ctr_reg |= NAND_CTR_A(nand_info->addr_hi);
+
+ if (nand_amb_is_hw_bch(nand_info)) {
+ /* Setup FIO DMA Control Register */
+ nand_amb_enable_bch(nand_info);
+ /* in dual space mode,enable the SE bit */
+ nand_ctr_reg |= NAND_CTR_SE;
+
+ /* Clean Flash_IO_ecc_rpt_status Register */
+ amba_writel(nand_info->regbase + FIO_ECC_RPT_STA_OFFSET, 0x0);
+ } else if (nand_amb_is_sw_bch(nand_info)) {
+ /* Setup FIO DMA Control Register */
+ nand_amb_enable_dsm(nand_info);
+ /* in dual space mode,enable the SE bit */
+ nand_ctr_reg |= NAND_CTR_SE;
+ } else {
+ if (nand_info->area == MAIN_ECC)
+ nand_ctr_reg |= (NAND_CTR_SE);
+ else if (nand_info->area == SPARE_ONLY ||
+ nand_info->area == SPARE_ECC)
+ nand_ctr_reg |= (NAND_CTR_SE | NAND_CTR_SA);
+
+ fio_ctr_reg = amba_readl(nand_info->regbase + FIO_CTR_OFFSET);
+ fio_ctr_reg &= ~(FIO_CTR_CO | FIO_CTR_RS);
+
+ if (nand_info->area == SPARE_ONLY ||
+ nand_info->area == SPARE_ECC ||
+ nand_info->area == MAIN_ECC)
+ fio_ctr_reg |= (FIO_CTR_RS);
+
+ switch (nand_info->ecc) {
+ case EG_MDSE :
+ nand_ctr_reg |= NAND_CTR_EG_SPARE;
+ break;
+ case EG_MESD :
+ nand_ctr_reg |= NAND_CTR_EG_MAIN;
+ break;
+ case EG_MESE :
+ nand_ctr_reg |= (NAND_CTR_EG_MAIN | NAND_CTR_EG_SPARE);
+ break;
+ case EG_MDSD:
+ default:
+ break;
+ }
+
+ amba_writel(nand_info->regbase + FIO_CTR_OFFSET,
+ fio_ctr_reg);
+ }
+ amba_writel(nand_info->regbase + FLASH_CTR_OFFSET, nand_ctr_reg);
+ nand_amb_setup_dma_memdev(nand_info);
+
+ break;
+
+ default:
+ dev_warn(nand_info->dev,
+ "%s: wrong command %d!\n", __func__, cmd);
+ errorCode = -EINVAL;
+ goto nand_amb_request_done;
+ break;
+ }
+
+ if (cmd == NAND_AMB_CMD_READ || cmd == NAND_AMB_CMD_PROGRAM) {
+ timeout = wait_event_timeout(nand_info->wq,
+ atomic_read(&nand_info->irq_flag) == 0x0, 1 * HZ);
+ if (timeout <= 0) {
+ errorCode = -EBUSY;
+ dev_err(nand_info->dev, "%s: cmd=0x%x timeout 0x%08x\n",
+ __func__, cmd, atomic_read(&nand_info->irq_flag));
+ } else {
+ dev_dbg(nand_info->dev, "%ld jiffies left.\n", timeout);
+ }
+
+ if (nand_info->dma_status & (DMA_CHANX_STA_OE | DMA_CHANX_STA_ME |
+ DMA_CHANX_STA_BE | DMA_CHANX_STA_RWE |
+ DMA_CHANX_STA_AE)) {
+ dev_err(nand_info->dev,
+ "%s: Errors happend in DMA transaction %d!\n",
+ __func__, nand_info->dma_status);
+ errorCode = -EIO;
+ goto nand_amb_request_done;
+ }
+
+ if (nand_amb_is_hw_bch(nand_info)) {
+ if (cmd == NAND_AMB_CMD_READ) {
+ if (nand_info->fio_ecc_sta & FIO_ECC_RPT_FAIL) {
+ int ret;
+
+ /* Workaround for some chips which will
+ * report ECC failed for blank page. */
+ if (FIO_SUPPORT_SKIP_BLANK_ECC)
+ ret = -1;
+ else
+ ret = nand_bch_check_blank_page(nand_info, 1);
+
+ if (ret < 0) {
+ nand_info->mtd.ecc_stats.failed++;
+ dev_err(nand_info->dev,
+ "BCH corrected failed (0x%08x), addr is 0x[%x]!\n",
+ nand_info->fio_ecc_sta, nand_info->addr);
+ }
+ } else if (nand_info->fio_ecc_sta & FIO_ECC_RPT_ERR) {
+ unsigned int corrected;
+ corrected = 1;
+ if (NAND_ECC_RPT_NUM_SUPPORT) {
+ corrected = (nand_info->fio_ecc_sta >> 16) & 0x000F;
+ dev_info(nand_info->dev, "BCH correct [%d]bit in block[%d]\n",
+ corrected, (nand_info->fio_ecc_sta & 0x00007FFF));
+ } else {
+ /* once bitflip and data corrected happened, BCH will keep on
+ * to report bitflip in following read operations, even though
+ * there is no bitflip happened really. So this is a workaround
+ * to get it back. */
+ nand_amb_corrected_recovery(nand_info);
+ }
+ nand_info->mtd.ecc_stats.corrected += corrected;
+ }
+ } else if (cmd == NAND_AMB_CMD_PROGRAM) {
+ if (nand_info->fio_ecc_sta & FIO_ECC_RPT_FAIL) {
+ dev_err(nand_info->dev,
+ "BCH program program failed (0x%08x)!\n",
+ nand_info->fio_ecc_sta);
+ }
+ }
+ }
+
+ if ((nand_info->fio_dma_sta & FIO_DMASTA_RE)
+ || (nand_info->fio_dma_sta & FIO_DMASTA_AE)
+ || !(nand_info->fio_dma_sta & FIO_DMASTA_DN)) {
+ u32 block_addr;
+ block_addr = nand_info->addr /
+ nand_info->mtd.erasesize *
+ nand_info->mtd.erasesize;
+ dev_err(nand_info->dev,
+ "%s: dma_status=0x%08x, cmd=0x%x, addr_hi=0x%x, "
+ "addr=0x%x, dst=0x%x, buf=0x%x, "
+ "len=0x%x, area=0x%x, ecc=0x%x, "
+ "block addr=0x%x!\n",
+ __func__,
+ nand_info->fio_dma_sta,
+ cmd,
+ nand_info->addr_hi,
+ nand_info->addr,
+ nand_info->dst,
+ nand_info->buf_phys,
+ nand_info->len,
+ nand_info->area,
+ nand_info->ecc,
+ block_addr);
+ errorCode = -EIO;
+ goto nand_amb_request_done;
+ }
+ } else {
+ /* just wait cmd irq, no care about both DMA irqs */
+ timeout = wait_event_timeout(nand_info->wq,
+ (atomic_read(&nand_info->irq_flag) & 0x1) == 0x0, 1 * HZ);
+ if (timeout <= 0) {
+ errorCode = -EBUSY;
+ dev_err(nand_info->dev, "%s: cmd=0x%x timeout 0x%08x\n",
+ __func__, cmd, atomic_read(&nand_info->irq_flag));
+ goto nand_amb_request_done;
+ } else {
+ dev_dbg(nand_info->dev, "%ld jiffies left.\n", timeout);
+
+ if (cmd == NAND_AMB_CMD_READID) {
+ u32 id = amba_readl(nand_info->regbase +
+ FLASH_ID_OFFSET);
+ if (nand_info->id_cycles_5) {
+ u32 id_5 = amba_readl(nand_info->regbase +
+ FLASH_EX_ID_OFFSET);
+ nand_info->dmabuf[4] = (unsigned char) (id_5 & 0xFF);
+ }
+ nand_info->dmabuf[0] = (unsigned char) (id >> 24);
+ nand_info->dmabuf[1] = (unsigned char) (id >> 16);
+ nand_info->dmabuf[2] = (unsigned char) (id >> 8);
+ nand_info->dmabuf[3] = (unsigned char) id;
+ } else if (cmd == NAND_AMB_CMD_READSTATUS) {
+ *nand_info->dmabuf = amba_readl(nand_info->regbase +
+ FLASH_STA_OFFSET);
+ }
+ }
+ }
+
+nand_amb_request_done:
+ atomic_set(&nand_info->irq_flag, 0x7);
+ nand_info->dma_status = 0;
+ /* Avoid to flush previous error info */
+ if (nand_info->err_code == 0)
+ nand_info->err_code = errorCode;
+
+ if ((nand_info->nand_wp) &&
+ (cmd == NAND_AMB_CMD_ERASE || cmd == NAND_AMB_CMD_COPYBACK ||
+ cmd == NAND_AMB_CMD_PROGRAM || cmd == NAND_AMB_CMD_READSTATUS)) {
+ nand_ctr_reg |= NAND_CTR_WP;
+ amba_writel(nand_info->regbase + FLASH_CTR_OFFSET, nand_ctr_reg);
+ }
+
+ if ((cmd == NAND_AMB_CMD_READ || cmd == NAND_AMB_CMD_PROGRAM)
+ && nand_amb_is_hw_bch(nand_info))
+ nand_amb_disable_bch(nand_info);
+
+ fio_unlock(SELECT_FIO_FL);
+
+nand_amb_request_exit:
+ return errorCode;
+}
+
+int nand_amb_reset(struct ambarella_nand_info *nand_info)
+{
+ nand_info->cmd = NAND_AMB_CMD_RESET;
+
+ return nand_amb_request(nand_info);
+}
+
+int nand_amb_read_id(struct ambarella_nand_info *nand_info)
+{
+ nand_info->cmd = NAND_AMB_CMD_READID;
+ nand_info->addr_hi = 0;
+ nand_info->addr = 0;
+
+ return nand_amb_request(nand_info);
+}
+
+int nand_amb_read_status(struct ambarella_nand_info *nand_info)
+{
+ nand_info->cmd = NAND_AMB_CMD_READSTATUS;
+ nand_info->addr_hi = 0;
+ nand_info->addr = 0;
+
+ return nand_amb_request(nand_info);
+}
+
+int nand_amb_erase(struct ambarella_nand_info *nand_info, u32 page_addr)
+{
+ int errorCode = 0;
+ u32 addr_hi;
+ u32 addr;
+ u64 addr64;
+
+ addr64 = (u64)(page_addr * nand_info->mtd.writesize);
+ addr_hi = (u32)(addr64 >> 32);
+ addr = (u32)addr64;
+
+ nand_info->cmd = NAND_AMB_CMD_ERASE;
+ nand_info->addr_hi = addr_hi;
+ nand_info->addr = addr;
+
+ /* Fix dual space mode bug */
+ if (nand_info->ecc_bits > 1)
+ amba_writel(nand_info->regbase + FIO_DMAADR_OFFSET, nand_info->addr);
+
+ errorCode = nand_amb_request(nand_info);
+
+ return errorCode;
+}
+
+int nand_amb_read_data(struct ambarella_nand_info *nand_info,
+ u32 page_addr, dma_addr_t buf_dma, u8 area)
+{
+ int errorCode = 0;
+ u32 addr_hi;
+ u32 addr;
+ u32 len;
+ u64 addr64;
+ u8 ecc = 0;
+
+ addr64 = (u64)(page_addr * nand_info->mtd.writesize);
+ addr_hi = (u32)(addr64 >> 32);
+ addr = (u32)addr64;
+
+ switch (area) {
+ case MAIN_ONLY:
+ ecc = EC_MDSD;
+ len = nand_info->mtd.writesize;
+ break;
+ case MAIN_ECC:
+ ecc = EC_MESD;
+ len = nand_info->mtd.writesize;
+ break;
+ case SPARE_ONLY:
+ ecc = EC_MDSD;
+ len = nand_info->mtd.oobsize;
+ break;
+ case SPARE_ECC:
+ ecc = EC_MDSE;
+ len = nand_info->mtd.oobsize;
+ break;
+ default:
+ dev_err(nand_info->dev, "%s: Wrong area.\n", __func__);
+ errorCode = -EINVAL;
+ goto nand_amb_read_page_exit;
+ break;
+ }
+
+ nand_info->slen = 0;
+ if (nand_info->ecc_bits > 1) {
+ /* when use BCH, the EG and EC should be 0 */
+ ecc = 0;
+ len = nand_info->mtd.writesize;
+ nand_info->slen = nand_info->mtd.oobsize;
+ nand_info->spare_buf_phys = buf_dma + len;
+ }
+
+ nand_info->cmd = NAND_AMB_CMD_READ;
+ nand_info->addr_hi = addr_hi;
+ nand_info->addr = addr;
+ nand_info->buf_phys = buf_dma;
+ nand_info->len = len;
+ nand_info->area = area;
+ nand_info->ecc = ecc;
+
+ errorCode = nand_amb_request(nand_info);
+
+nand_amb_read_page_exit:
+ return errorCode;
+}
+
+int nand_amb_write_data(struct ambarella_nand_info *nand_info,
+ u32 page_addr, dma_addr_t buf_dma, u8 area)
+{
+ int errorCode = 0;
+ u32 addr_hi;
+ u32 addr;
+ u32 len;
+ u64 addr64;
+ u8 ecc;
+
+ addr64 = (u64)(page_addr * nand_info->mtd.writesize);
+ addr_hi = (u32)(addr64 >> 32);
+ addr = (u32)addr64;
+
+ switch (area) {
+ case MAIN_ONLY:
+ ecc = EG_MDSD;
+ len = nand_info->mtd.writesize;
+ break;
+ case MAIN_ECC:
+ ecc = EG_MESD;
+ len = nand_info->mtd.writesize;
+ break;
+ case SPARE_ONLY:
+ ecc = EG_MDSD;
+ len = nand_info->mtd.oobsize;
+ break;
+ case SPARE_ECC:
+ ecc = EG_MDSE;
+ len = nand_info->mtd.oobsize;
+ break;
+ default:
+ dev_err(nand_info->dev, "%s: Wrong area.\n", __func__);
+ errorCode = -EINVAL;
+ goto nand_amb_write_page_exit;
+ break;
+ }
+
+ nand_info->slen = 0;
+ if (nand_info->ecc_bits > 1) {
+ /* when use BCH, the EG and EC should be 0 */
+ ecc = 0;
+ len = nand_info->mtd.writesize;
+ nand_info->slen = nand_info->mtd.oobsize;
+ nand_info->spare_buf_phys = buf_dma + len;
+ }
+ nand_info->cmd = NAND_AMB_CMD_PROGRAM;
+ nand_info->addr_hi = addr_hi;
+ nand_info->addr = addr;
+ nand_info->buf_phys = buf_dma;
+ nand_info->len = len;
+ nand_info->area = area;
+ nand_info->ecc = ecc;
+
+ errorCode = nand_amb_request(nand_info);
+
+nand_amb_write_page_exit:
+ return errorCode;
+}
+
+
+/* ==========================================================================*/
+static uint8_t amb_nand_read_byte(struct mtd_info *mtd)
+{
+ struct ambarella_nand_info *nand_info;
+ uint8_t *data;
+
+ nand_info = (struct ambarella_nand_info *)mtd->priv;
+
+ data = nand_info->dmabuf + nand_info->dma_bufpos;
+ nand_info->dma_bufpos++;
+
+ return *data;
+}
+
+static u16 amb_nand_read_word(struct mtd_info *mtd)
+{
+ struct ambarella_nand_info *nand_info;
+ u16 *data;
+
+ nand_info = (struct ambarella_nand_info *)mtd->priv;
+
+ data = (u16 *)(nand_info->dmabuf + nand_info->dma_bufpos);
+ nand_info->dma_bufpos += 2;
+
+ return *data;
+}
+
+static void amb_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+ struct ambarella_nand_info *nand_info;
+
+ nand_info = (struct ambarella_nand_info *)mtd->priv;
+
+ BUG_ON((nand_info->dma_bufpos + len) > AMBARELLA_NAND_DMA_BUFFER_SIZE);
+
+ memcpy(buf, nand_info->dmabuf + nand_info->dma_bufpos, len);
+ nand_info->dma_bufpos += len;
+}
+
+static void amb_nand_write_buf(struct mtd_info *mtd,
+ const uint8_t *buf, int len)
+{
+ struct ambarella_nand_info *nand_info;
+
+ nand_info = (struct ambarella_nand_info *)mtd->priv;
+
+ BUG_ON((nand_info->dma_bufpos + len) > AMBARELLA_NAND_DMA_BUFFER_SIZE);
+
+ memcpy(nand_info->dmabuf + nand_info->dma_bufpos, buf, len);
+ nand_info->dma_bufpos += len;
+}
+
+static void amb_nand_select_chip(struct mtd_info *mtd, int chip)
+{
+ struct ambarella_nand_info *nand_info;
+
+ nand_info = (struct ambarella_nand_info *)mtd->priv;
+
+ if (chip > 0) {
+ dev_err(nand_info->dev,
+ "%s: Multi-Chip isn't supported yet.\n", __func__);
+ }
+}
+
+static void amb_nand_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl)
+{
+
+}
+
+static int amb_nand_dev_ready(struct mtd_info *mtd)
+{
+ struct nand_chip *chip = mtd->priv;
+
+ chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
+
+ return (chip->read_byte(mtd) & NAND_STATUS_READY) ? 1 : 0;
+}
+
+static int amb_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *chip)
+{
+ int status = 0;
+ struct ambarella_nand_info *nand_info;
+
+ nand_info = (struct ambarella_nand_info *)mtd->priv;
+
+ /* ambarella nand controller has waited for the command completion,
+ * but still need to check the nand chip's status
+ */
+ if (nand_info->err_code)
+ status = NAND_STATUS_FAIL;
+ else {
+ chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
+ status = chip->read_byte(mtd);
+ }
+
+ return status;
+}
+
+static void amb_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
+ int column, int page_addr)
+{
+ struct ambarella_nand_info *nand_info;
+
+ nand_info = (struct ambarella_nand_info *)mtd->priv;
+ nand_info->err_code = 0;
+
+ switch(command) {
+ case NAND_CMD_RESET:
+ nand_amb_reset(nand_info);
+ break;
+ case NAND_CMD_READID:
+ nand_info->dma_bufpos = 0;
+ nand_amb_read_id(nand_info);
+ break;
+ case NAND_CMD_STATUS:
+ nand_info->dma_bufpos = 0;
+ nand_amb_read_status(nand_info);
+ break;
+ case NAND_CMD_ERASE1:
+ nand_amb_erase(nand_info, page_addr);
+ break;
+ case NAND_CMD_ERASE2:
+ break;
+ case NAND_CMD_READOOB:
+ nand_info->dma_bufpos = column;
+ if (nand_info->ecc_bits > 1) {
+ u8 area = nand_info->soft_ecc ? MAIN_ONLY : MAIN_ECC;
+ nand_info->dma_bufpos = mtd->writesize;
+ nand_amb_read_data(nand_info, page_addr,
+ nand_info->dmaaddr, area);
+ } else {
+ nand_amb_read_data(nand_info, page_addr,
+ nand_info->dmaaddr, SPARE_ONLY);
+ }
+ break;
+ case NAND_CMD_READ0:
+ {
+ u8 area = nand_info->soft_ecc ? MAIN_ONLY : MAIN_ECC;
+
+ nand_info->dma_bufpos = column;
+ nand_amb_read_data(nand_info, page_addr, nand_info->dmaaddr, area);
+ if (nand_info->ecc_bits == 1)
+ nand_amb_read_data(nand_info, page_addr,
+ nand_info->dmaaddr + mtd->writesize, SPARE_ONLY);
+
+ break;
+ }
+ case NAND_CMD_SEQIN:
+ nand_info->dma_bufpos = column;
+ nand_info->seqin_column = column;
+ nand_info->seqin_page_addr = page_addr;
+ break;
+ case NAND_CMD_PAGEPROG:
+ {
+ u32 mn_area, sp_area, offset;
+
+ mn_area = nand_info->soft_ecc ? MAIN_ONLY : MAIN_ECC;
+ sp_area = nand_amb_is_hw_bch(nand_info) ? SPARE_ECC : SPARE_ONLY;
+ offset = (nand_info->ecc_bits > 1) ? 0 : mtd->writesize;
+
+ if (nand_info->seqin_column < mtd->writesize) {
+ nand_amb_write_data(nand_info,
+ nand_info->seqin_page_addr,
+ nand_info->dmaaddr, mn_area);
+ if (nand_info->soft_ecc && nand_info->ecc_bits == 1) {
+ nand_amb_write_data(nand_info,
+ nand_info->seqin_page_addr,
+ nand_info->dmaaddr + mtd->writesize,
+ sp_area);
+ }
+ } else {
+ nand_amb_write_data(nand_info,
+ nand_info->seqin_page_addr,
+ nand_info->dmaaddr + offset,
+ sp_area);
+ }
+ break;
+ }
+ default:
+ dev_err(nand_info->dev, "%s: 0x%x, %d, %d\n",
+ __func__, command, column, page_addr);
+ BUG();
+ break;
+ }
+}
+
+static void amb_nand_hwctl(struct mtd_info *mtd, int mode)
+{
+}
+
+static int amb_nand_calculate_ecc(struct mtd_info *mtd,
+ const u_char *buf, u_char *code)
+{
+ struct ambarella_nand_info *nand_info;
+
+ nand_info = (struct ambarella_nand_info *)mtd->priv;
+
+ if (!nand_info->soft_ecc) {
+ memset(code, 0xff, nand_info->chip.ecc.bytes);
+ } else if (nand_info->ecc_bits == 1) {
+ nand_calculate_ecc(mtd, buf, code);
+ /* FIXME: the first two bytes ecc codes are swaped comparing
+ * to the ecc codes generated by our hardware, so we swap them
+ * here manually. But I don't know why they were swapped. */
+ swap(code[0], code[1]);
+ } else {
+ u32 i, amb_eccsize;
+
+ /* make it be compatible with hw bch */
+ for (i = 0; i < nand_info->chip.ecc.size; i++)
+ nand_info->bch_data[i] = bitrev8(buf[i]);
+
+ memset(code, 0, nand_info->chip.ecc.bytes);
+
+ amb_eccsize = nand_info->chip.ecc.size + nand_info->soft_bch_extra_size;
+ encode_bch(nand_info->bch, nand_info->bch_data, amb_eccsize, code);
+
+ /* make it be compatible with hw bch */
+ for (i = 0; i < nand_info->chip.ecc.bytes; i++)
+ code[i] = bitrev8(code[i]);
+ }
+
+ return 0;
+}
+
+static int amb_nand_correct_data(struct mtd_info *mtd, u_char *buf,
+ u_char *read_ecc, u_char *calc_ecc)
+{
+ struct ambarella_nand_info *nand_info;
+ int errorCode = 0;
+
+ nand_info = (struct ambarella_nand_info *)mtd->priv;
+
+ /* if we use hardware ecc, any errors include DMA error and
+ * FIO DMA error, we consider it as a ecc error which will tell
+ * the caller the read fail. We have distinguish all the errors,
+ * but the nand_read_ecc only check the return value by this
+ * function. */
+ if (!nand_info->soft_ecc)
+ errorCode = nand_info->err_code;
+ else if (nand_info->ecc_bits == 1)
+ errorCode = nand_correct_data(mtd, buf, read_ecc, calc_ecc);
+ else {
+ struct nand_chip *chip = &nand_info->chip;
+ u32 *errloc = nand_info->errloc;
+ int amb_eccsize, i, count;
+
+ for (i = 0; i < chip->ecc.bytes; i++) {
+ nand_info->read_ecc_rev[i] = bitrev8(read_ecc[i]);
+ nand_info->calc_ecc_rev[i] = bitrev8(calc_ecc[i]);
+ }
+
+ amb_eccsize = chip->ecc.size + nand_info->soft_bch_extra_size;
+ count = decode_bch(nand_info->bch, NULL,
+ amb_eccsize,
+ nand_info->read_ecc_rev,
+ nand_info->calc_ecc_rev,
+ NULL, errloc);
+ if (count > 0) {
+ for (i = 0; i < count; i++) {
+ if (errloc[i] < (amb_eccsize * 8)) {
+ /* error is located in data, correct it */
+ buf[errloc[i] >> 3] ^= (128 >> (errloc[i] & 7));
+ }
+ /* else error in ecc, no action needed */
+
+ dev_dbg(nand_info->dev,
+ "corrected bitflip %u\n", errloc[i]);
+ }
+ } else if (count < 0) {
+ count = nand_bch_check_blank_page(nand_info , 0);
+ if (count < 0)
+ dev_err(nand_info->dev, "ecc unrecoverable error\n");
+ else if (count > 0)
+ memset(buf, 0xff, chip->ecc.size);
+ }
+
+ errorCode = count;
+ }
+
+ return errorCode;
+}
+
+static int amb_nand_write_oob_std(struct mtd_info *mtd,
+ struct nand_chip *chip, int page)
+{
+ struct ambarella_nand_info *nand_info;
+ int i, status;
+
+ nand_info = (struct ambarella_nand_info *)mtd->priv;
+
+ /* Our nand controller will write the generated ECC code into spare
+ * area automatically, so we should mark the ECC code which located
+ * in the eccpos.
+ */
+ if (!nand_info->soft_ecc) {
+ for (i = 0; i < chip->ecc.total; i++)
+ chip->oob_poi[chip->ecc.layout->eccpos[i]] = 0xFF;
+ }
+
+ chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page);
+ chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+ chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
+ status = chip->waitfunc(mtd, chip);
+
+ return status & NAND_STATUS_FAIL ? -EIO : 0;
+}
+
+/*
+ * The encoding sequence in a byte is "LSB first".
+ *
+ * For each 2K page, there will be 2048 byte main data (B0 ~ B2047) and 64 byte
+ * spare data (B2048 ~ B2111). Thus, each page is divided into 4 BCH blocks.
+ * For example, B0~B511 and B2048~B2063 are grouped as the first BCH block.
+ * B0 will be encoded first and B2053 will be encoded last.
+ *
+ * B2054 ~B2063 are used to store 10B parity data (precisely to say, 78 bits)
+ * The 2 dummy bits are filled as 0 and located at the msb of B2063.
+*/
+static int ambarella_nand_init_soft_bch(struct ambarella_nand_info *nand_info)
+{
+ struct nand_chip *chip = &nand_info->chip;
+ u32 amb_eccsize, eccbytes, m, t;
+
+ amb_eccsize = chip->ecc.size + nand_info->soft_bch_extra_size;
+ eccbytes = chip->ecc.bytes;
+
+ m = fls(1 + 8 * amb_eccsize);
+ t = (eccbytes * 8) / m;
+
+ nand_info->bch = init_bch(m, t, 0);
+ if (!nand_info->bch)
+ return -EINVAL;
+
+ nand_info->errloc = devm_kzalloc(nand_info->dev,
+ t * sizeof(*nand_info->errloc), GFP_KERNEL);
+ if (!nand_info->errloc)
+ return -ENOMEM;
+
+ nand_info->bch_data = devm_kzalloc(nand_info->dev,
+ amb_eccsize, GFP_KERNEL);
+ if (nand_info->bch_data == NULL)
+ return -ENOMEM;
+
+ /* asumming the 6 bytes data in spare area are all 0xff, in other
+ * words, we don't support to write anything except for ECC code
+ * into spare are. */
+ memset(nand_info->bch_data + chip->ecc.size,
+ 0xff, nand_info->soft_bch_extra_size);
+
+ return 0;
+}
+
+static void ambarella_fio_nand_rct_reset(void)
+{
+ amba_rct_writel(FIO_RESET_REG, FIO_RESET_FIO_RST | FIO_RESET_FLASH_RST);
+ mdelay(5);
+ amba_rct_writel(FIO_RESET_REG, 0x0);
+ mdelay(5);
+}
+
+static void ambarella_nand_init_hw(struct ambarella_nand_info *nand_info)
+{
+ /* reset FIO by RCT */
+ fio_select_lock(SELECT_FIO_FL);
+ ambarella_fio_nand_rct_reset();
+ fio_unlock(SELECT_FIO_FL);
+
+ /* When suspend/resume mode, before exit random read mode,
+ * we take time for make sure FIO reset well and
+ * some dma req finished.
+ */
+ if (nand_info->suspend == 1)
+ mdelay(2);
+ /* Exit random read mode */
+ amba_clrbitsl(nand_info->regbase + FIO_CTR_OFFSET, FIO_CTR_RR);
+ mdelay(1);
+ nand_info->fio_dma_sta = 0;
+
+ /* init fdma to avoid dummy irq */
+ amba_writel(nand_info->fdmaregbase + FDMA_STA_OFFSET, 0);
+ amba_writel(nand_info->fdmaregbase + FDMA_SPR_STA_OFFSET, 0);
+ amba_writel(nand_info->fdmaregbase + FDMA_CTR_OFFSET,
+ DMA_CHANX_CTR_WM | DMA_CHANX_CTR_RM | DMA_CHANX_CTR_NI);
+
+ if (nand_info->suspend == 1)
+ amba_writel(nand_info->regbase + FLASH_CTR_OFFSET,
+ nand_info->control_reg);
+
+ amb_nand_set_timing(nand_info);
+}
+
+static int ambarella_nand_config_flash(struct ambarella_nand_info *nand_info)
+{
+ int errorCode = 0;
+
+ /* control_reg will be uesd when real operation to NAND is performed */
+
+ /* Calculate row address cycyle according to whether the page number
+ * of the nand is greater than 65536 */
+ if ((nand_info->chip.chip_shift - nand_info->chip.page_shift) > 16)
+ nand_info->control_reg |= NAND_CTR_P3;
+ else
+ nand_info->control_reg &= ~NAND_CTR_P3;
+
+ nand_info->control_reg &= ~NAND_CTR_SZ_8G;
+ switch (nand_info->chip.chipsize) {
+ case 8 * 1024 * 1024:
+ nand_info->control_reg |= NAND_CTR_SZ_64M;
+ break;
+ case 16 * 1024 * 1024:
+ nand_info->control_reg |= NAND_CTR_SZ_128M;
+ break;
+ case 32 * 1024 * 1024:
+ nand_info->control_reg |= NAND_CTR_SZ_256M;
+ break;
+ case 64 * 1024 * 1024:
+ nand_info->control_reg |= NAND_CTR_SZ_512M;
+ break;
+ case 128 * 1024 * 1024:
+ nand_info->control_reg |= NAND_CTR_SZ_1G;
+ break;
+ case 256 * 1024 * 1024:
+ nand_info->control_reg |= NAND_CTR_SZ_2G;
+ break;
+ case 512 * 1024 * 1024:
+ nand_info->control_reg |= NAND_CTR_SZ_4G;
+ break;
+ case 1024 * 1024 * 1024:
+ nand_info->control_reg |= NAND_CTR_SZ_8G;
+ break;
+ default:
+ dev_err(nand_info->dev,
+ "Unexpected NAND flash chipsize %lld. Aborting\n",
+ nand_info->chip.chipsize);
+ errorCode = -ENXIO;
+ break;
+ }
+
+ return errorCode;
+}
+
+static int ambarella_nand_init_chip(struct ambarella_nand_info *nand_info,
+ struct device_node *np)
+{
+ struct nand_chip *chip = &nand_info->chip;
+ u32 poc = ambarella_get_poc();
+
+ /* if ecc is generated by software, the ecc bits num will
+ * be defined in FDT. */
+ if (!nand_info->soft_ecc) {
+ if (of_find_property(np, "amb,no-bch", NULL)) {
+ nand_info->ecc_bits = 1;
+ } else if (poc & SYS_CONFIG_NAND_ECC_BCH_EN) {
+ if (poc & SYS_CONFIG_NAND_ECC_SPARE_2X)
+ nand_info->ecc_bits = 8;
+ else
+ nand_info->ecc_bits = 6;
+ } else {
+ nand_info->ecc_bits = 1;
+ }
+ }
+
+ dev_info(nand_info->dev, "in %secc-[%d]bit mode\n",
+ nand_info->soft_ecc ? "soft " : "", nand_info->ecc_bits);
+
+ nand_info->control_reg = 0;
+ if (poc & SYS_CONFIG_NAND_READ_CONFIRM)
+ nand_info->control_reg |= NAND_CTR_RC;
+ if (poc & SYS_CONFIG_NAND_PAGE_SIZE)
+ nand_info->control_reg |= (NAND_CTR_C2 | NAND_CTR_SZ_8G);
+ /*
+ * Always use P3 and I4 to support all NAND,
+ * but we will adjust them after read ID from NAND. */
+ nand_info->control_reg |= (NAND_CTR_P3 | NAND_CTR_I4 | NAND_CTR_IE);
+ nand_info->id_cycles_5 = NAND_READ_ID5;
+
+ if(nand_info->nand_wp)
+ nand_info->control_reg |= NAND_CTR_WP;
+
+ chip->chip_delay = 0;
+ chip->controller = &nand_info->controller;
+ chip->read_byte = amb_nand_read_byte;
+ chip->read_word = amb_nand_read_word;
+ chip->write_buf = amb_nand_write_buf;
+ chip->read_buf = amb_nand_read_buf;
+ chip->select_chip = amb_nand_select_chip;
+ chip->cmd_ctrl = amb_nand_cmd_ctrl;
+ chip->dev_ready = amb_nand_dev_ready;
+ chip->waitfunc = amb_nand_waitfunc;
+ chip->cmdfunc = amb_nand_cmdfunc;
+ chip->options |= NAND_NO_SUBPAGE_WRITE;
+ if (of_get_nand_on_flash_bbt(np)) {
+ printk(KERN_INFO "ambarella_nand: Use On Flash BBT\n");
+ chip->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
+ }
+
+ nand_info->mtd.priv = chip;
+ nand_info->mtd.owner = THIS_MODULE;
+
+ return 0;
+}
+
+static int ambarella_nand_init_chipecc(struct ambarella_nand_info *nand_info)
+{
+ struct nand_chip *chip = &nand_info->chip;
+ struct mtd_info *mtd = &nand_info->mtd;
+ int errorCode = 0;
+
+ /* sanity check */
+ BUG_ON(nand_info->ecc_bits != 1
+ && nand_info->ecc_bits != 6
+ && nand_info->ecc_bits != 8);
+ BUG_ON(mtd->writesize != 2048 && mtd->writesize != 512);
+ BUG_ON(nand_info->ecc_bits == 8 && mtd->oobsize < 128);
+
+ chip->ecc.mode = NAND_ECC_HW;
+ chip->ecc.strength = nand_info->ecc_bits;
+
+ switch (nand_info->ecc_bits) {
+ case 8:
+ chip->ecc.size = 512;
+ chip->ecc.bytes = 13;
+ chip->ecc.layout = &amb_oobinfo_2048_dsm_ecc8;
+ nand_info->soft_bch_extra_size = 19;
+ break;
+ case 6:
+ chip->ecc.size = 512;
+ chip->ecc.bytes = 10;
+ chip->ecc.layout = &amb_oobinfo_2048_dsm_ecc6;
+ nand_info->soft_bch_extra_size = 6;
+ break;
+ case 1:
+ chip->ecc.size = 512;
+ chip->ecc.bytes = 5;
+ if (mtd->writesize == 2048)
+ chip->ecc.layout = &amb_oobinfo_2048;
+ else
+ chip->ecc.layout = &amb_oobinfo_512;
+ break;
+ }
+
+ if (nand_amb_is_sw_bch(nand_info)) {
+ errorCode = ambarella_nand_init_soft_bch(nand_info);
+ if (errorCode < 0)
+ return errorCode;
+ /* bootloader may have enabled hw BCH, we must disable it here */
+ nand_amb_enable_dsm(nand_info);
+ }
+
+ chip->ecc.hwctl = amb_nand_hwctl;
+ chip->ecc.calculate = amb_nand_calculate_ecc;
+ chip->ecc.correct = amb_nand_correct_data;
+ chip->ecc.write_oob = amb_nand_write_oob_std;
+
+ return 0;
+}
+
+static int ambarella_nand_get_resource(
+ struct ambarella_nand_info *nand_info, struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct resource *res;
+ int errorCode = 0;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "No mem resource for fio_reg!\n");
+ errorCode = -ENXIO;
+ goto nand_get_resource_err_exit;
+ }
+
+ nand_info->regbase =
+ devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!nand_info->regbase) {
+ dev_err(&pdev->dev, "devm_ioremap() failed\n");
+ errorCode = -ENOMEM;
+ goto nand_get_resource_err_exit;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res) {
+ dev_err(&pdev->dev, "No mem resource for fdma_reg!\n");
+ errorCode = -ENXIO;
+ goto nand_get_resource_err_exit;
+ }
+
+ nand_info->fdmaregbase =
+ devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!nand_info->fdmaregbase) {
+ dev_err(&pdev->dev, "devm_ioremap() failed\n");
+ errorCode = -ENOMEM;
+ goto nand_get_resource_err_exit;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+ if (!res) {
+ dev_err(&pdev->dev, "No mem resource for fifo base!\n");
+ errorCode = -ENXIO;
+ goto nand_get_resource_err_exit;
+ }
+ nand_info->dmabase = res->start;
+
+ nand_info->cmd_irq = platform_get_irq(pdev, 0);
+ if (nand_info->cmd_irq < 0) {
+ dev_err(&pdev->dev, "no irq for cmd_irq!\n");
+ errorCode = -ENODEV;
+ goto nand_get_resource_err_exit;
+ }
+
+ nand_info->dma_irq = platform_get_irq(pdev, 1);
+ if (nand_info->dma_irq < 0) {
+ dev_err(&pdev->dev, "no irq for dma_irq!\n");
+ errorCode = -ENODEV;
+ goto nand_get_resource_err_exit;
+ }
+
+ nand_info->fdma_irq = platform_get_irq(pdev, 2);
+ if (nand_info->fdma_irq < 0) {
+ dev_err(&pdev->dev, "no irq for fdma_irq!\n");
+ errorCode = -ENODEV;
+ goto nand_get_resource_err_exit;
+ }
+
+ nand_info->nand_wp = !!of_find_property(np, "amb,enable-wp", NULL);
+
+ errorCode = of_property_read_u32_array(np, "amb,timing",
+ nand_info->timing, 6);
+ if (errorCode < 0) {
+ dev_dbg(&pdev->dev, "No timing defined!\n");
+ memset(nand_info->timing, 0x0, sizeof(nand_info->timing));
+ }
+
+ nand_info->pllx2 = !!of_find_property(np, "amb,use-2x-pll", NULL);
+
+ nand_info->ecc_bits = 0;
+ of_property_read_u32(np, "amb,soft-ecc", &nand_info->ecc_bits);
+ if (nand_info->ecc_bits > 0)
+ nand_info->soft_ecc = true;
+
+ ambarella_nand_init_hw(nand_info);
+
+ errorCode = request_irq(nand_info->cmd_irq, nand_fiocmd_isr_handler,
+ IRQF_SHARED | IRQF_TRIGGER_HIGH,
+ "fio_cmd_irq", nand_info);
+ if (errorCode < 0) {
+ dev_err(&pdev->dev, "Could not register fio_cmd_irq %d!\n",
+ nand_info->cmd_irq);
+ goto nand_get_resource_err_exit;
+ }
+
+ errorCode = request_irq(nand_info->dma_irq, nand_fiodma_isr_handler,
+ IRQF_SHARED | IRQF_TRIGGER_HIGH,
+ "fio_dma_irq", nand_info);
+ if (errorCode < 0) {
+ dev_err(&pdev->dev, "Could not register fio_dma_irq %d!\n",
+ nand_info->dma_irq);
+ goto nand_get_resource_free_fiocmd_irq;
+ }
+
+ errorCode = request_irq(nand_info->fdma_irq, ambarella_fdma_isr_handler,
+ IRQF_SHARED | IRQF_TRIGGER_HIGH,
+ "fdma_irq", nand_info);
+ if (errorCode < 0) {
+ dev_err(&pdev->dev, "Could not register fdma_irq %d!\n",
+ nand_info->dma_irq);
+ goto nand_get_resource_free_fiodma_irq;
+ }
+
+ return 0;
+
+nand_get_resource_free_fiodma_irq:
+ free_irq(nand_info->dma_irq, nand_info);
+
+nand_get_resource_free_fiocmd_irq:
+ free_irq(nand_info->cmd_irq, nand_info);
+
+nand_get_resource_err_exit:
+ return errorCode;
+}
+
+static void ambarella_nand_put_resource(struct ambarella_nand_info *nand_info)
+{
+ free_irq(nand_info->fdma_irq, nand_info);
+ free_irq(nand_info->dma_irq, nand_info);
+ free_irq(nand_info->cmd_irq, nand_info);
+}
+
+static int ambarella_nand_probe(struct platform_device *pdev)
+{
+ int errorCode = 0;
+ struct ambarella_nand_info *nand_info;
+ struct mtd_info *mtd;
+ struct mtd_part_parser_data ppdata = {};
+
+ nand_info = kzalloc(sizeof(struct ambarella_nand_info), GFP_KERNEL);
+ if (nand_info == NULL) {
+ dev_err(&pdev->dev, "kzalloc for nand nand_info failed!\n");
+ errorCode = - ENOMEM;
+ goto ambarella_nand_probe_exit;
+ }
+
+ nand_info->dev = &pdev->dev;
+ spin_lock_init(&nand_info->controller.lock);
+ init_waitqueue_head(&nand_info->controller.wq);
+ init_waitqueue_head(&nand_info->wq);
+ sema_init(&nand_info->system_event_sem, 1);
+ atomic_set(&nand_info->irq_flag, 0x7);
+
+ nand_info->dmabuf = dma_alloc_coherent(nand_info->dev,
+ AMBARELLA_NAND_DMA_BUFFER_SIZE,
+ &nand_info->dmaaddr, GFP_KERNEL);
+ if (nand_info->dmabuf == NULL) {
+ dev_err(&pdev->dev, "dma_alloc_coherent failed!\n");
+ errorCode = -ENOMEM;
+ goto ambarella_nand_probe_free_info;
+ }
+ BUG_ON(nand_info->dmaaddr & 0x7);
+
+ errorCode = ambarella_nand_get_resource(nand_info, pdev);
+ if (errorCode < 0)
+ goto ambarella_nand_probe_free_dma;
+
+ ambarella_nand_init_chip(nand_info, pdev->dev.of_node);
+
+ mtd = &nand_info->mtd;
+ errorCode = nand_scan_ident(mtd, 1, NULL);
+ if (errorCode)
+ goto ambarella_nand_probe_mtd_error;
+
+ errorCode = ambarella_nand_init_chipecc(nand_info);
+ if (errorCode)
+ goto ambarella_nand_probe_mtd_error;
+
+ errorCode = ambarella_nand_config_flash(nand_info);
+ if (errorCode)
+ goto ambarella_nand_probe_mtd_error;
+
+ errorCode = nand_scan_tail(mtd);
+ if (errorCode)
+ goto ambarella_nand_probe_mtd_error;
+
+ mtd->name = "amba_nand";
+
+ ppdata.of_node = pdev->dev.of_node;
+ errorCode = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
+ if (errorCode < 0)
+ goto ambarella_nand_probe_mtd_error;
+
+ platform_set_drvdata(pdev, nand_info);
+
+ nand_info->system_event.notifier_call = ambarella_nand_system_event;
+ ambarella_register_event_notifier(&nand_info->system_event);
+
+ return 0;
+
+ambarella_nand_probe_mtd_error:
+ ambarella_nand_put_resource(nand_info);
+
+ambarella_nand_probe_free_dma:
+ dma_free_coherent(nand_info->dev,
+ AMBARELLA_NAND_DMA_BUFFER_SIZE,
+ nand_info->dmabuf, nand_info->dmaaddr);
+
+ambarella_nand_probe_free_info:
+ kfree(nand_info);
+
+ambarella_nand_probe_exit:
+
+ return errorCode;
+}
+
+static int ambarella_nand_remove(struct platform_device *pdev)
+{
+ int errorCode = 0;
+ struct ambarella_nand_info *nand_info;
+
+ nand_info = (struct ambarella_nand_info *)platform_get_drvdata(pdev);
+
+ if (nand_info) {
+ ambarella_unregister_event_notifier(&nand_info->system_event);
+
+ nand_release(&nand_info->mtd);
+
+ ambarella_nand_put_resource(nand_info);
+
+ dma_free_coherent(nand_info->dev,
+ AMBARELLA_NAND_DMA_BUFFER_SIZE,
+ nand_info->dmabuf, nand_info->dmaaddr);
+
+ kfree(nand_info);
+ }
+
+ return errorCode;
+}
+
+#ifdef CONFIG_PM
+static int ambarella_nand_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ int errorCode = 0;
+ struct ambarella_nand_info *nand_info;
+
+ nand_info = platform_get_drvdata(pdev);
+ nand_info->suspend = 1;
+ disable_irq(nand_info->dma_irq);
+ disable_irq(nand_info->cmd_irq);
+
+ dev_dbg(&pdev->dev, "%s exit with %d @ %d\n",
+ __func__, errorCode, state.event);
+
+ return errorCode;
+}
+
+static int ambarella_nand_resume(struct platform_device *pdev)
+{
+ int errorCode = 0;
+ struct ambarella_nand_info *nand_info;
+ struct mtd_info *mtd;
+
+ nand_info = platform_get_drvdata(pdev);
+ ambarella_nand_init_hw(nand_info);
+ nand_info->suspend = 0;
+ enable_irq(nand_info->dma_irq);
+ enable_irq(nand_info->cmd_irq);
+ mtd = &nand_info->mtd;
+ errorCode = nand_scan_tail(mtd);
+
+ dev_dbg(&pdev->dev, "%s exit with %d\n", __func__, errorCode);
+
+ return errorCode;
+}
+#endif
+
+static const struct of_device_id ambarella_nand_of_match[] = {
+ {.compatible = "ambarella,nand", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ambarella_nand_of_match);
+
+static struct platform_driver amb_nand_driver = {
+ .probe = ambarella_nand_probe,
+ .remove = ambarella_nand_remove,
+#ifdef CONFIG_PM
+ .suspend = ambarella_nand_suspend,
+ .resume = ambarella_nand_resume,
+#endif
+ .driver = {
+ .name = "ambarella-nand",
+ .owner = THIS_MODULE,
+ .of_match_table = ambarella_nand_of_match,
+ },
+};
+module_platform_driver(amb_nand_driver);
+
+MODULE_AUTHOR("Cao Rongrong & Chien-Yang Chen");
+MODULE_DESCRIPTION("Ambarella Media processor NAND Controller Driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/mtd/nand/ambarella_spinand.c b/drivers/mtd/nand/ambarella_spinand.c
new file mode 100644
index 00000000..a7c5f654
--- /dev/null
+++ b/drivers/mtd/nand/ambarella_spinand.c
@@ -0,0 +1,1414 @@
+/*
+ * drivers/mtd/ambarella_spinand.c
+ *
+ * History:
+ * 2015/10/26 - [Ken He] created file
+ *
+ * Copyright (C) 2014-2018, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include "ambarella_spinand.h"
+
+#define MAX_WAIT_JIFFIES (40 * HZ)
+#define MAX_WAIT_ERASE_JIFFIES ((HZ * 400)/1000)
+#define AVERAGE_WAIT_JIFFIES ((HZ * 20)/1000)
+
+#define CACHE_BUF (2176)
+
+static struct nand_ecclayout ecc_layout_2KB_8bit = {
+ .eccbytes = 64,
+ .eccpos = {
+ 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103,
+ 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127
+ },
+ .oobfree = { {1, 63} }
+};
+
+/****************************************************************************/
+static inline struct amb_spinand *mtd_to_amb(struct mtd_info *mtd)
+{
+ return container_of(mtd, struct amb_spinand, mtd);
+}
+
+/* mtd_to_state - obtain the spinand state from the mtd info provided */
+static inline struct spinand_state *mtd_to_state(struct mtd_info *mtd)
+{
+ struct nand_chip *chip = (struct nand_chip *)mtd->priv;
+ struct amb_spinand *flash = (struct amb_spinand *)chip->priv;
+ struct spinand_state *state = (struct spinand_state *)flash->priv;
+
+ return state;
+}
+/****************************************************************************/
+
+static int ambspinand_send_cmd(struct amb_spinand *flash, u32 cmd, u32 dummy_len, u32 data, u32 len)
+{
+ u32 tmp = 0;
+
+ tmp = amba_readl(flash->regbase + REG00);
+ REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, 0);
+ REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, dummy_len);
+ REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, len);
+ REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
+ amba_writel(flash->regbase + REG00, tmp);
+
+ tmp = amba_readl(flash->regbase + REG04);
+ REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 1);
+ REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 0);
+ REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 0);
+ REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
+ REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
+ amba_writel(flash->regbase + REG04, tmp);
+
+ tmp = amba_readl(flash->regbase + REG0C);
+ REGPREP(tmp, REG0C_CMD0_MASK, REG0C_CMD0_SHIFT, cmd);
+ amba_writel(flash->regbase + REG0C, tmp);
+
+ if(len){
+ tmp = data;
+ amba_writel(flash->regbase + REG14, tmp);
+ }
+
+ tmp = 0x0;
+ amba_writel(flash->regbase + REG30, tmp);
+
+ tmp = 0x20;
+ amba_writel(flash->regbase + REG3C, tmp);
+
+ tmp = amba_readl(flash->regbase + REG50);
+ REGPREP(tmp, REG50_STRTRX_MASK, REG50_STRTRX_SHIFT, 1);
+ amba_writel(flash->regbase + REG50, tmp);
+
+ for (;;){
+ tmp = amba_readl(flash->regbase + REG38);
+ if (REGDUMP(tmp, REG38_DATALENREACHINTR_MASK, REG38_DATALENREACHINTR_SHIFT) == 1){
+ return 0;
+ }
+ }
+ return -1;
+}
+
+static int ambspinand_read_reg(struct amb_spinand *flash, u32 datalen, u32 reg, u8 *value)
+{
+ u32 tmp = 0;
+ int i;
+
+ tmp = amba_readl(flash->regbase + REG28);
+ for (;REGDUMP(tmp, REG28_RXFIFOLV_MASK, REG28_RXFIFOLV_SHIFT)!= 0;){
+ amba_readb(flash->regbase + REG200);
+ tmp = amba_readl(flash->regbase + REG28);
+ }
+
+ tmp = amba_readl(flash->regbase + REG00);
+ REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
+ REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, 0);
+ REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, 0);
+ REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, datalen);
+ amba_writel(flash->regbase + REG00, tmp);
+
+ tmp = amba_readl(flash->regbase + REG04);
+ REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 1);
+ REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 0);
+ REGPREP(tmp, REG04_RXLANE_MASK, REG04_RXLANE_SHIFT, 1);
+ REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 1);
+ REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
+ amba_writel(flash->regbase + REG04, tmp);
+
+ tmp = reg;
+ amba_writel(flash->regbase + REG0C, tmp);
+
+ tmp = 0x0;
+ amba_writel(flash->regbase + REG10, tmp);
+ tmp = 0x0;
+ amba_writel(flash->regbase + REG14, tmp);
+
+ tmp = 0;
+ REGPREP(tmp, REG50_STRTRX_MASK, REG50_STRTRX_SHIFT, 1);
+ amba_writel(flash->regbase + REG50, tmp);
+
+ for (;;){
+ tmp = amba_readl(flash->regbase + REG28);
+ if(REGDUMP(tmp, REG28_RXFIFOLV_MASK, REG28_RXFIFOLV_SHIFT) == datalen){
+ break;
+ }
+ }
+
+ for (i = 0; i < datalen; i++){
+ *(value+i) = amba_readb(flash->regbase + REG200);
+ }
+ return 0;
+}
+
+static int ambspinand_read_feature(struct amb_spinand *flash, u32 cmd, u32 datalen, u32 reg, u8 *value)
+{
+ u32 tmp = 0;
+ int i;
+
+ tmp = amba_readl(flash->regbase + REG28);
+ for (;REGDUMP(tmp, REG28_RXFIFOLV_MASK, REG28_RXFIFOLV_SHIFT)!= 0;){
+ amba_readb(flash->regbase + REG200);
+ tmp = amba_readl(flash->regbase + REG28);
+ }
+
+ tmp = amba_readl(flash->regbase + REG00);
+ REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
+ REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, 0);
+ REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, 1);
+ REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, datalen);
+ amba_writel(flash->regbase + REG00, tmp);
+
+ tmp = amba_readl(flash->regbase + REG04);
+ REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 1);
+ REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 0);
+ REGPREP(tmp, REG04_RXLANE_MASK, REG04_RXLANE_SHIFT, 1);
+ REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 1);
+ REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
+ amba_writel(flash->regbase + REG04, tmp);
+
+ tmp = cmd;
+ amba_writel(flash->regbase + REG0C, tmp);
+
+ tmp = 0x0;
+ amba_writel(flash->regbase + REG10, tmp);
+ tmp = reg;
+ amba_writel(flash->regbase + REG14, tmp);
+
+ tmp = 0;
+ REGPREP(tmp, REG50_STRTRX_MASK, REG50_STRTRX_SHIFT, 1);
+ amba_writel(flash->regbase + REG50, tmp);
+
+ for (;;){
+ tmp = amba_readl(flash->regbase + REG28);
+ if(REGDUMP(tmp, REG28_RXFIFOLV_MASK, REG28_RXFIFOLV_SHIFT) == datalen){
+ break;
+ }
+ }
+
+ for (i = 0; i < datalen; i++){
+ *(value+i) = amba_readb(flash->regbase + REG200);
+ }
+ return 0;
+}
+
+static int ambspinand_set_feature(struct amb_spinand *flash, u32 cmd, u32 datalen, u32 reg, u8 value)
+{
+ u32 tmp = 0;
+/*
+ tmp = amba_readl(flash->regbase + REG28);
+ for (;REGDUMP(tmp, REG28_RXFIFOLV_MASK, REG28_RXFIFOLV_SHIFT)!= 0;){
+ amba_readb(flash->regbase + REG200);
+ tmp = amba_readl(flash->regbase + REG28);
+ }
+*/
+ tmp = amba_readl(flash->regbase + REG00);
+ REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
+ REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, 0);
+ REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, 1);
+ REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, datalen);
+ amba_writel(flash->regbase + REG00, tmp);
+
+ tmp = amba_readl(flash->regbase + REG04);
+ REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 0);
+ REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 1);
+ REGPREP(tmp, REG04_RXLANE_MASK, REG04_RXLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 0);
+ REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
+ amba_writel(flash->regbase + REG04, tmp);
+
+ tmp = cmd;
+ amba_writel(flash->regbase + REG0C, tmp);
+
+ tmp = 0x0;
+ amba_writel(flash->regbase + REG10, tmp);
+ tmp = reg;
+ amba_writel(flash->regbase + REG14, tmp);
+
+ amba_writeb(flash->regbase + REG100, value);
+ tmp = 0;
+ REGPREP(tmp, REG50_STRTRX_MASK, REG50_STRTRX_SHIFT, 1);
+ amba_writel(flash->regbase + REG50, tmp);
+
+ for (;;){
+ tmp = amba_readl(flash->regbase + REG24);
+ if(REGDUMP(tmp, REG24_TXFIFOLV_MASK, REG24_TXFIFOLV_SHIFT) == 0){
+ return 0;
+ }
+ udelay(100);//must delay
+ }
+
+ return 0;
+}
+
+static int ambspi_dma_config(struct amb_spinand *flash)
+{
+ flash->dmabuf = dma_alloc_coherent(flash->dev, AMBA_SPINOR_DMA_BUFF_SIZE,
+ &flash->dmaaddr, GFP_KERNEL);
+ if (flash->dmabuf == NULL){
+ dev_err(flash->dev, "dma_alloc_coherent failed!\n");
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static int ambspinand_prog_page(struct amb_spinand *flash, u16 byte_id, u8 *buf, u32 len)
+{
+ int done;
+ u32 tmp = 0;
+
+ amba_writel(flash->dmaregbase + 0x00, 0x1a800000);// DMA_ch0_control
+ amba_writel(flash->dmaregbase + 0x0c, 0x0);
+ amba_writel(flash->dmaregbase + 0x04, flash->dmaaddr + byte_id);// DMA_ch0_src_addr
+ amba_writel(flash->dmaregbase + 0x08, (u32)(flash->regbase + REG100));// DMA_ch0_dest_addr
+ amba_writel(flash->dmaregbase + 0x00, 0x9a800000|len);// DMA_ch0_control
+
+ tmp = amba_readl(flash->regbase + REG00);
+ REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, len);
+ //REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, flash->dummy);
+ //REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, flash->addr_width);
+ REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, 0);
+ REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, 2);
+ REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
+ amba_writel(flash->regbase + REG00, tmp);
+
+ tmp = amba_readl(flash->regbase + REG04);
+ REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 1);
+ REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 0);
+ REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 0);
+ REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
+ amba_writel(flash->regbase + REG04, tmp);
+
+ tmp = flash->command[0];
+ amba_writel(flash->regbase + REG0C, tmp);
+
+ tmp = 0;
+ REGPREP(tmp, REG30_DATAREACH_MASK, REG30_DATAREACH_SHIFT, 1);
+ amba_writel(flash->regbase + REG30, tmp);
+
+ tmp = byte_id;
+ amba_writel(flash->regbase + REG14, tmp);
+
+ tmp = 0;
+ REGPREP(tmp, REG1C_TXFIFOLV_MASK, REG1C_TXFIFOLV_SHIFT, (256-32));
+ amba_writel(flash->regbase + REG1C, tmp);
+
+ tmp = amba_readl(flash->regbase + REG18);
+ REGPREP(tmp, REG18_TXDMAEN_MASK, REG18_TXDMAEN_SHIFT, 1);
+ REGPREP(tmp, REG18_RXDMAEN_MASK, REG18_RXDMAEN_SHIFT, 0);
+ amba_writel(flash->regbase + REG18, tmp);
+
+ do {
+ tmp = amba_readl(flash->regbase + REG2C);
+ done = REGDUMP(tmp, REG2C_TXFIFOEMP_MASK, REG2C_TXFIFOEMP_SHIFT);
+ }while (done != 0x0);
+
+ tmp = 0x20;
+ amba_writel(flash->regbase + REG3C, tmp);
+
+ tmp = amba_readl(flash->regbase + REG50);
+ REGPREP(tmp, REG50_STRTRX_MASK, REG50_STRTRX_SHIFT, 1);
+ amba_writel(flash->regbase + REG50, tmp);
+ for (;;){
+ tmp = amba_readl(flash->regbase + REG38);
+ if (REGDUMP(tmp,
+ REG38_DATALENREACHINTR_MASK,
+ REG38_DATALENREACHINTR_SHIFT) == 1){
+ return 0;
+ }
+ }
+ return -1;
+}
+
+static int ambspinand_read_page(struct amb_spinand *flash, u32 offset, u8 *rbuf,
+ u32 len)
+{
+ u32 tmp = 0;
+
+ amba_writel(flash->dmaregbase + 0x10, 0x2a800000);// DMA_ch1_control
+ amba_writel(flash->dmaregbase + 0x1c, 0x0);
+ amba_writel(flash->dmaregbase + 0x14, (u32)(flash->regbase + REG200));// DMA_ch1_src_addr
+ amba_writel(flash->dmaregbase + 0x18, flash->dmaaddr);// DMA_ch1_dest_addr
+ amba_writel(flash->dmaregbase + 0x10, 0xaa800000 | len);// DMA_ch1_control
+
+ tmp = amba_readl(flash->regbase + REG00);
+ REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, len);
+ //REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, flash->dummy);
+ //REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, flash->addr_width);
+ REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, 0);
+ REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, 3);
+ REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
+ amba_writel(flash->regbase + REG00, tmp);
+
+ tmp = amba_readl(flash->regbase + REG04);
+ REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 1);
+ REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 0);
+ REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 1);
+ REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
+ amba_writel(flash->regbase + REG04, tmp);
+
+ tmp = flash->command[0];
+ amba_writel(flash->regbase + REG0C, tmp);
+
+ tmp = offset;
+ amba_writel(flash->regbase + REG14, tmp);
+
+ tmp = 0x20;
+ amba_writel(flash->regbase + REG3C, tmp);
+
+ tmp = (32-1); // must use word.can't use rxfifothlv
+ amba_writel(flash->regbase + REG20, tmp);
+
+ tmp = amba_readl(flash->regbase + REG18);
+ REGPREP(tmp, REG18_RXDMAEN_MASK, REG18_RXDMAEN_SHIFT, 1);
+ REGPREP(tmp, REG18_TXDMAEN_MASK, REG18_TXDMAEN_SHIFT, 0);
+ amba_writel(flash->regbase + REG18, tmp);
+
+ tmp = amba_readl(flash->regbase + REG50);
+ REGPREP(tmp, REG50_STRTRX_MASK, REG50_STRTRX_SHIFT, 1);
+ amba_writel(flash->regbase + REG50, tmp);
+
+ for (;;){
+ tmp = amba_readl(flash->regbase + REG38);
+ if(REGDUMP(tmp,
+ REG38_DATALENREACHINTR_MASK,
+ REG38_DATALENREACHINTR_SHIFT) == 1){
+ return 0;
+ }
+ udelay(10);
+ }
+ return -1;
+}
+#if 0
+static u32 get_ssi3_freq_hz(void)
+{
+ #define PLL_OUT_ENET 300000000
+ u32 val;
+
+ val = amba_rct_readl(CG_SSI3_REG);
+ if (val & 0x01000000)
+ return 0;
+
+ if (val == 0)
+ val = 1;
+
+ //return (clk_get_rate(clk_get(NULL, "gclk_core")) << 1) / val;
+ return (PLL_OUT_ENET) / val;
+}
+#endif
+static int ambspinand_init(struct amb_spinand *flash)
+{
+ u32 tmp = 0;
+#if 0
+ u32 divider;
+ divider = get_ssi3_freq_hz() / flash->clk;
+ tmp = amba_readl(flash->regbase + REG08);
+ REGPREP(tmp, REG08_CHIPSEL_MASK, REG08_CHIPSEL_SHIFT, ~(1 << SPINOR_DEV));
+ REGPREP(tmp, REG08_CLKDIV_MASK, REG08_CLKDIV_SHIFT, divider);
+ REGPREP(tmp, REG08_FLOWCON_MASK, REG08_FLOWCON_SHIFT, 1);
+ REGPREP(tmp, REG08_HOLDPIN_MASK, REG08_HOLDPIN_SHIFT, 3);
+ amba_writel(flash->regbase + REG08, tmp);
+
+ tmp = amba_readl(flash->regbase + REG00);
+ REGPREP(tmp, REG00_DATALEN_MASK, REG00_DATALEN_SHIFT, 0);
+ REGPREP(tmp, REG00_DUMMYLEN_MASK, REG00_DUMMYLEN_SHIFT, 0);
+ REGPREP(tmp, REG00_ADDRLEN_MASK, REG00_ADDRLEN_SHIFT, 0);
+ REGPREP(tmp, REG00_CMDLEN_MASK, REG00_CMDLEN_SHIFT, 1);
+ amba_writel(flash->regbase + REG00, tmp);
+
+ tmp = amba_readl(flash->regbase + REG04);
+ REGPREP(tmp, REG04_WRITEEN_MASK, REG04_WRITEEN_SHIFT, 0);
+ REGPREP(tmp, REG04_READEN_MASK, REG04_READEN_SHIFT, 0);
+ REGPREP(tmp, REG04_DATALANE_MASK, REG04_DATALANE_SHIFT, 0);
+ REGPREP(tmp, REG04_ADDRLANE_MASK, REG04_ADDRLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDLANE_MASK, REG04_CMDLANE_SHIFT, 0);
+ REGPREP(tmp, REG04_LSBFRT_MASK, REG04_LSBFRT_SHIFT, 0);
+ REGPREP(tmp, REG04_CMDDTR_MASK, REG04_CMDDTR_SHIFT, 0);
+ amba_writel(flash->regbase + REG04, tmp);
+#endif
+ tmp = 0x20;
+ amba_writel(flash->regbase + REG30, tmp);
+
+ tmp = 0;
+ REGPREP(tmp, REG40_TXFIFORESET_MASK, REG40_TXFIFORESET_SHIFT, 1);
+ amba_writel(flash->regbase + REG40, tmp);
+ tmp = 0;
+ REGPREP(tmp, REG44_RXFIFORESET_MASK, REG44_RXFIFORESET_SHIFT, 1);
+ amba_writel(flash->regbase + REG44, tmp);
+
+ /* after reset fifo, the 0x28 will become 0x10,
+ *so , read REG200 times to clear the 0x28, this is a bug in hardware
+ */
+ while (amba_readl(flash->regbase + REG28) != 0) {
+ tmp = amba_readl(flash->regbase + REG200);
+ }
+
+ tmp = 0;
+ REGPREP(tmp, REG1C_TXFIFOLV_MASK, REG1C_TXFIFOLV_SHIFT, 0x7f);
+ amba_writel(flash->regbase + REG1C, tmp);
+
+ tmp = 0;
+ REGPREP(tmp, REG20_RXFIFOLV_MASK, REG20_RXFIFOLV_SHIFT, 0x7f);
+ amba_writel(flash->regbase + REG20, tmp);
+
+ return 0;
+}
+/* spi nand function end */
+
+/****************************************************************************/
+/*
+ * spinand_write_enable - send command to enable write or erase of
+ * the nand cells.
+ * Before one can write or erase the nand cells, the write enable
+ * has to be set. After write or erase, the write enable bit is
+ * automatically cleared.
+ */
+static int spinand_write_enable(struct amb_spinand *flash)
+{
+ int ret;
+
+ flash->command[0] = SPI_NAND_WRITE_ENABLE;
+ ret = ambspinand_send_cmd(flash, flash->command[0], 0, 0, 0);
+ if (ret < 0) {
+ dev_err(flash->dev, "Write Enable SPI NAND failed!\n");
+ }
+ return ret;
+}
+
+/*
+ * spinand_get_feature - send command to get feature register
+ * spinand_set_feature - send command to set feature register
+ *
+ * The GET FEATURES (0Fh) and SET FEATURES (1Fh) commands are used to
+ * alter the device behavior from the default power-on behavior.
+ * These commands use a 1-byte feature address to determine which feature
+ * is to be read or modified
+ */
+static int spinand_get_feature(struct amb_spinand *flash, u8 feature_reg,
+ u8 *value)
+{
+ u32 cmd;
+ int ret;
+
+ cmd = SPI_NAND_GET_FEATURE_INS;
+
+ /* Check the register address */
+ if (feature_reg != SPI_NAND_PROTECTION_REG_ADDR &&
+ feature_reg != SPI_NAND_FEATURE_EN_REG_ADDR &&
+ feature_reg != SPI_NAND_STATUS_REG_ADDR &&
+ feature_reg != SPI_NAND_DS_REG_ADDR)
+ return -1;
+
+ ret = ambspinand_read_feature(flash, cmd, 1, feature_reg, value);
+ if (ret < 0)
+ dev_err(flash->dev, "Error %d read feature reg.\n", ret);
+ return ret;
+}
+
+static int spinand_set_feature(struct amb_spinand *flash, u8 feature_reg,
+ u8 value)
+{
+ int ret;
+ u32 cmd;
+
+ cmd = SPI_NAND_SET_FEATURE;
+
+ /* Check the register address */
+ if (feature_reg != SPI_NAND_PROTECTION_REG_ADDR &&
+ feature_reg != SPI_NAND_FEATURE_EN_REG_ADDR &&
+ feature_reg != SPI_NAND_STATUS_REG_ADDR &&
+ feature_reg != SPI_NAND_DS_REG_ADDR)
+ return -1;
+
+ ret = ambspinand_set_feature(flash, cmd, 1, feature_reg, value);
+ if (ret < 0)
+ dev_err(flash->dev, "Error %d set feture reg.\n", ret);
+
+ return ret;
+}
+/*
+ * spinand_get_status
+ * spinand_get_protection
+ * spinand_get_feature_en
+ * spinand_get_driver_strength
+ *
+ * Read the specific feature register using spinand_get_feature
+ */
+static inline int
+spinand_get_status(struct amb_spinand *flash, u8 *value)
+{
+ return
+ spinand_get_feature(flash, SPI_NAND_STATUS_REG_ADDR, value);
+}
+static inline int
+spinand_get_protection(struct amb_spinand *flash, u8 *value)
+{
+ return
+ spinand_get_feature(flash, SPI_NAND_PROTECTION_REG_ADDR, value);
+}
+static inline int
+spinand_get_feature_en(struct amb_spinand *flash, u8 *value)
+{
+ return
+ spinand_get_feature(flash, SPI_NAND_FEATURE_EN_REG_ADDR, value);
+}
+static inline int
+spinand_get_driver_strength(struct amb_spinand *flash, u8 *value)
+{
+ return
+ spinand_get_feature(flash, SPI_NAND_DS_REG_ADDR, value);
+}
+/*
+ * spinand_set_status
+ * spinand_set_protection
+ * spinand_set_feature_en
+ *
+ * Set the specific feature register using spinand_set_feature
+ */
+static inline int
+spinand_set_status(struct amb_spinand *flash, u8 value)
+{
+ return
+ spinand_set_feature(flash, SPI_NAND_STATUS_REG_ADDR, value);
+}
+static inline int
+spinand_set_protection(struct amb_spinand *flash, u8 value)
+{
+ return
+ spinand_set_feature(flash, SPI_NAND_PROTECTION_REG_ADDR, value);
+}
+static inline int
+spinand_set_feature_en(struct amb_spinand *flash, u8 value)
+{
+ return
+ spinand_set_feature(flash, SPI_NAND_FEATURE_EN_REG_ADDR, value);
+}
+static inline int
+spinand_set_driver_strength(struct amb_spinand *flash, u8 value)
+{
+ return
+ spinand_set_feature(flash, SPI_NAND_DS_REG_ADDR, value);
+}
+/*
+ * is_spinand_busy - check the operation in progress bit and return
+ * if NAND chip is busy or not.
+ * This function checks the Operation In Progress (OIP) bit to
+ * determine whether the NAND memory is busy with a program execute,
+ * page read, block erase or reset command.
+ */
+static inline int is_spinand_busy(struct amb_spinand *flash)
+{
+ u8 status;
+ int ret;
+
+ /* Read the status register and check the OIP bit */
+ ret = spinand_get_status(flash, &status);
+ if (ret)
+ return ret;
+
+ if (status & SPI_NAND_OIP)
+ return 1;
+ else
+ return 0;
+}
+
+/* wait_execution_complete - wait for the current operation to finish */
+static inline int wait_execution_complete(struct amb_spinand *flash,
+ u32 timeout)
+{
+ int ret;
+ unsigned long deadline = jiffies + timeout;
+
+ do {
+ ret = is_spinand_busy(flash);
+ if (!ret)
+ return 0;
+ if (ret < 0)
+ return ret;
+ } while (!time_after_eq(jiffies, deadline));
+
+ return -1;
+}
+
+static int spinand_enable_ecc(struct amb_spinand *flash)
+{
+ uint8_t feature_reg = 0;
+ int ret = 0;
+
+ ret = spinand_get_feature_en(flash, &feature_reg);
+ if (ret < 0)
+ return ret;
+ return spinand_set_feature_en(flash, feature_reg | SPI_NAND_ECC_EN);
+}
+#if 0
+static int spinand_disable_ecc(struct amb_spinand *flash)
+{
+ uint8_t feature_reg = 0;
+ int ret = 0;
+
+ ret = spinand_get_feature_en(flash, &feature_reg);
+ if (ret < 0)
+ return ret;
+ return spinand_set_feature_en(flash, feature_reg & (~SPI_NAND_ECC_EN));
+}
+#endif
+/*
+ * spinand_read_id - Read SPI nand ID
+ * Byte 0: Manufacture ID
+ * Byte 1: Device ID 1
+ * Byte 2: Device ID 2
+ */
+static int spinand_read_id(struct amb_spinand *flash, u8 *id)
+{
+ int ret;
+ u8 nand_id[3];
+ u32 cmd;
+
+ cmd = SPI_NAND_READ_ID;
+ ret = ambspinand_read_reg(flash,3, cmd, nand_id);
+ if (ret < 0) {
+ dev_err(flash->dev, "Error %d reading id\n", ret);
+ return ret;
+ }
+ id[0] = nand_id[0];
+ id[1] = nand_id[1];
+ id[2] = nand_id[2];
+
+ return ret;
+}
+
+/* spinand_reset - send RESET command to NAND device */
+static void spinand_reset(struct amb_spinand *flash)
+{
+ int ret;
+
+ flash->command[0] = SPI_NAND_RESET;
+ ret = ambspinand_send_cmd(flash, flash->command[0], 0, 0, 0);
+ if (ret < 0) {
+ dev_err(flash->dev, "Reset SPI NAND failed!\n");
+ return;
+ }
+
+ /* OIP status can be read from 300ns after reset*/
+ udelay(1);
+ /* Wait for execution to complete */
+ ret = wait_execution_complete(flash, MAX_WAIT_JIFFIES);
+ if (ret) {
+ if (ret < 0)
+ dev_err(flash->dev, "%s: Wait execution complete failed!\n",
+ __func__);
+ else
+ dev_err(flash->dev, "%s: Wait execution complete timedout!\n",
+ __func__);
+ }
+}
+
+/*
+ * spinand_erase_block - erase a block
+ * The erase can specify the block to be erased
+ * (block_id >= 0, block_id < no_blocks)
+ * no_blocks depends on the size of the flash
+ * Command sequence: WRITE ENBALE, BLOCK ERASE,
+ * GET FEATURES command to read the status register
+ */
+static int spinand_erase_block(struct amb_spinand *flash, u32 page)
+{
+ int ret;
+ u8 status;
+
+ /* Enable capability of erasing NAND cells */
+ ret = spinand_write_enable(flash);
+ if (ret < 0) {
+ dev_err(flash->dev, "Error %d on write enable.\n",
+ (int) ret);
+ return ret;
+ }
+
+ /* Set up command buffer. */
+ flash->command[0] = SPI_NAND_BLOCK_ERASE_INS;
+ ambspinand_send_cmd(flash, flash->command[0], 0, page, 3);
+
+ if (ret < 0) {
+ dev_err(flash->dev, "Error %d when erasing block.\n",
+ (int) ret);
+ return ret;
+ }
+
+ ret = wait_execution_complete(flash, MAX_WAIT_JIFFIES);
+ if (ret) {
+ if (ret < 0) {
+ dev_err(flash->dev, "%s: Wait execution complete failed!\n",
+ __func__);
+ return ret;
+ } else {
+ dev_err(flash->dev, "%s: Wait execution complete timedout!\n",
+ __func__);
+ return -1;
+ }
+ }
+
+ /* Check status register for erase fail bit */
+ ret = spinand_get_status(flash, &status);
+ if (ret < 0) {
+ dev_err(flash->dev, "Error %d reading status register.\n",
+ (int) ret);
+ return ret;
+ }
+ if (status & SPI_NAND_EF) {
+ dev_err(flash->dev, "Erase fail on block %d\n", (page/64));
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * spinand_read_page_to_cache - send command to read data from the device and
+ * into the internal cache
+ * The read can specify the page to be read into cache
+ * (page_id >= 0, page_id < no_pages, no_pages=no_blocks*no_pages_per_block)
+ * no_blocks and no_pages_per_block depend on the size of the flash
+ */
+static int spinand_read_page_to_cache(struct amb_spinand *flash, u32 page_id)
+{
+ int ret = 0;
+ /* Set up command buffer. */
+ flash->command[0] = SPI_NAND_PAGE_READ_INS;
+ ret = ambspinand_send_cmd(flash, flash->command[0], 0, page_id, 3);
+ if (ret < 0) {
+ dev_err(flash->dev, "Error %d when read page 0x%x to cache.\n",
+ page_id, (int) ret);
+ }
+ return ret;
+}
+
+/*
+ * spinand_read_from_cache - send command to read out the data from the
+ * cache register
+ * The read can specify a byte offset within the page
+ * (byte_id >= 0, byte_id < size_of_page)
+ * The read can specify a length to be read (len > 0 && len < size_of_page)
+ * size_of_page depends on the size of the flash
+ */
+static int spinand_read_from_cache(struct amb_spinand *flash,
+ u32 byte_id, int len, u8 *rbuf)
+{
+ int ret;
+
+ flash->command[0] = SPI_NAND_READ_CACHE_INS;
+ ret = ambspinand_read_page(flash, byte_id, rbuf, len);
+ if (ret < 0) {
+ dev_err(flash->dev, "Error %d when read from cache.\n",
+ (int) ret);
+ }
+ return ret;
+}
+
+/*
+ * spinand_read_page - read data from the flash by first reading the
+ * corresponding page into the internal cache and after reading out the
+ * data from it.
+ * The read can specify the page to be read into cache
+ * (page_id >= 0, page_id < no_pages, no_pages=no_blocks*no_pages_per_block)
+ * no_blocks and no_pages_per_block depend on the size of the flash
+ * The read can specify a byte offset within the page
+ * (byte_id >= 0, byte_id < size_of_page)
+ * The read can specify a length to be read (len > 0 && len < size_of_page)
+ * size_of_page depends on the size of the flash
+ */
+static int spinand_read_page(struct amb_spinand *flash, u32 page_id,
+ u32 offset, int len, u8 *rbuf)
+{
+ int ret;
+ u8 status;
+
+ /* Read page from device to internal cache */
+ ret = spinand_read_page_to_cache(flash, page_id);
+ if (ret < 0) {
+ dev_err(flash->dev, "Error %d reading page to cache.\n",
+ ret);
+ return ret;
+ }
+
+ /* Wait until the operation completes or a timeout occurs. */
+ ret = wait_execution_complete(flash, MAX_WAIT_JIFFIES);
+ if (ret) {
+ if (ret < 0) {
+ dev_err(flash->dev, "%s: Wait execution complete failed!\n",
+ __func__);
+ return ret;
+ } else {
+ dev_err(flash->dev, "%s: Wait execution complete timedout!\n",
+ __func__);
+ return -1;
+ }
+ }
+
+ /* Check status register for uncorrectable errors */
+ ret = spinand_get_status(flash, &status);
+ if (ret < 0) {
+ dev_err(flash->dev, "Error %d reading status register.\n",
+ (int) ret);
+ return ret;
+ }
+ status &= SPI_NAND_ECC_UNABLE_TO_CORRECT;
+ if (status == SPI_NAND_ECC_UNABLE_TO_CORRECT) {
+ dev_err(flash->dev, "ECC error reading page %d.\n",
+ page_id);
+ return -1;
+ }
+
+ /* Read page from internal cache to our buffers */
+ ret = spinand_read_from_cache(flash, offset, len, rbuf);
+ if (ret < 0) {
+ dev_err(flash->dev, "Error %d reading from cache.\n",
+ (int) ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+/*
+ * spinand_program_data_to_cache - send command to program data to cache
+ * The write can specify a byte offset within the page
+ * (byte_id >= 0, byte_id < size_of_page)
+ * The write can specify a length to be written
+ * (len > 0 && len < size_of_page)
+ * size_of_page depends on the size of the flash
+ */
+static int spinand_program_data_to_cache(struct amb_spinand *flash,
+ u16 byte_id, int len, u8 *wbuf)
+{
+ int ret = 0;
+
+ flash->command[0] = SPI_NAND_PROGRAM_LOAD_INS;
+ ret = ambspinand_prog_page(flash, byte_id, wbuf, len);
+ if (ret < 0) {
+ dev_err(flash->dev, "Error %d when program to cache.\n",
+ (int) ret);
+ }
+ return ret;
+}
+
+/*
+ * spinand_program_execute - writes a page from cache to NAND array
+ * The write can specify the page to be programmed
+ * (page_id >= 0, page_id < no_pages, no_pages=no_blocks*no_pages_per_block)
+ * no_blocks and no_pages_per_block depend on the size of the flash
+ */
+static int spinand_program_execute(struct amb_spinand *flash, u32 page_id)
+{
+ int ret;
+
+ flash->command[0] = SPI_NAND_PROGRAM_EXEC_INS;
+ ret = ambspinand_send_cmd(flash, flash->command[0], 0, page_id, 3);
+ if (ret < 0) {
+ dev_err(flash->dev, "Error %d when read page 0x%x to cache.\n",
+ page_id, (int) ret);
+ }
+ return ret;
+}
+
+/*
+ * spinand_program_page - secquence to program a page
+ * The write can specify the page to be programmed
+ * (page_id >= 0, page_id < no_pages, no_pages=no_blocks*no_pages_per_block)
+ * no_blocks and no_pages_per_block depend on the size of the flash
+ * The write can specify a byte offset within the page
+ * (byte_id >= 0, byte_id < size_of_page)
+ * The write can specify a length to be written
+ * (len > 0 && len < size_of_page)
+ * size_of_page depends on the size of the flash
+ * Command sequence: WRITE ENABLE, PROGRAM LOAD, PROGRAM EXECUTE,
+ * GET FEATURE command to read the status
+ */
+static int spinand_program_page(struct amb_spinand *flash,
+ u32 page_id, u16 offset, int len, u8 *buf)
+{
+ int ret;
+ u8 status;
+ uint8_t *wbuf;
+
+ wbuf = buf;
+
+ /* Issue program cache command */
+ ret = spinand_program_data_to_cache(flash, offset, len, wbuf);
+ if (ret < 0) {
+ dev_err(flash->dev, "Error %d when programming cache.\n",
+ (int) ret);
+ return ret;
+ }
+
+ /* Enable capability of programming NAND cells */
+ ret = spinand_write_enable(flash);
+ if (ret < 0) {
+ dev_err(flash->dev, "Error %d on write enable.\n",
+ (int) ret);
+ return ret;
+ }
+
+ /* Issue program execute command */
+ ret = spinand_program_execute(flash, page_id);
+ if (ret < 0) {
+ dev_err(flash->dev, "Error %d when programming NAND cells.\n",
+ (int) ret);
+ return ret;
+ }
+
+ /* Wait until the operation completes or a timeout occurs. */
+ ret = wait_execution_complete(flash, MAX_WAIT_JIFFIES);
+ if (ret) {
+ if (ret < 0) {
+ dev_err(flash->dev, "%s: Wait execution complete failed!\n",
+ __func__);
+ return ret;
+ } else {
+ dev_err(flash->dev, "%s Wait execution complete timedout!\n",
+ __func__);
+ return -1;
+ }
+ }
+
+ /* Check status register for program fail bit */
+ ret = spinand_get_status(flash, &status);
+ if (ret < 0) {
+ dev_err(flash->dev, "Error %d reading status register.\n",
+ (int) ret);
+ return ret;
+ }
+ if (status & SPI_NAND_PF) {
+ dev_err(flash->dev, "Program failed on page %d\n", page_id);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int spinand_write_page_hwecc(struct mtd_info *mtd,
+ struct nand_chip *chip, const uint8_t *buf, int oob_required)
+{
+ chip->write_buf(mtd, buf, chip->ecc.size * chip->ecc.steps);
+ return 0;
+}
+
+static int spinand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+ uint8_t *buf, int oob_required, int page)
+{
+ u8 status;
+ int ret;
+ struct amb_spinand *flash = (struct amb_spinand *)chip->priv;
+
+ /* Read data and OOB area */
+ chip->read_buf(mtd, buf, chip->ecc.size * chip->ecc.steps);
+ if (oob_required)
+ chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+ /* Wait until the operation completes or a timeout occurs. */
+ ret = wait_execution_complete(flash, MAX_WAIT_JIFFIES);
+ if (ret) {
+ if (ret < 0) {
+ pr_err("%s: Wait execution complete failed!\n",
+ __func__);
+ return ret;
+ } else {
+ pr_err("%s: Wait execution complete timedout!\n",
+ __func__);
+ return -1;
+ }
+ }
+
+ /* Check status register for uncorrectable errors */
+ ret = spinand_get_status(flash, &status);
+ if (ret < 0) {
+ pr_err("Error %d reading status register.\n", ret);
+ return ret;
+ }
+ status &= SPI_NAND_ECC_UNABLE_TO_CORRECT;
+ if (status == SPI_NAND_ECC_UNABLE_TO_CORRECT) {
+ pr_info("ECC error reading page.\n");
+ mtd->ecc_stats.failed++;
+ }
+ if (status && (status != SPI_NAND_ECC_UNABLE_TO_CORRECT))
+ mtd->ecc_stats.corrected++;
+ return 0;
+}
+
+static void amb_spinand_cmdfunc(struct mtd_info *mtd, unsigned int command,
+ int column, int page)
+{
+ struct nand_chip *chip = (struct nand_chip *)mtd->priv;
+ struct amb_spinand *flash = (struct amb_spinand *)chip->priv;
+ struct spinand_state *state = (struct spinand_state *)flash->priv;
+
+ switch (command) {
+ case NAND_CMD_READ1:
+ case NAND_CMD_READ0:
+ state->buf_ptr = 0;
+ spinand_read_page(flash, page, 0, mtd->writesize,
+ flash->dmabuf);
+ break;
+ case NAND_CMD_READOOB:
+ state->buf_ptr = 0;
+ spinand_read_page(flash, page, mtd->writesize, mtd->oobsize,
+ flash->dmabuf);
+ break;
+ case NAND_CMD_RNDOUT:
+ state->buf_ptr = column;
+ break;
+ case NAND_CMD_READID:
+ state->buf_ptr = 0;
+ spinand_read_id(flash, (u8 *)flash->dmabuf);
+ break;
+ case NAND_CMD_PARAM:
+ state->buf_ptr = 0;
+ break;
+ /* ERASE1 performs the entire erase operation*/
+ case NAND_CMD_ERASE1:
+ //printk("spinand erase 1 command page 0x%x \n", page);
+ spinand_erase_block(flash, page);
+ break;
+ case NAND_CMD_ERASE2:
+ //printk("spinand erase 2 command page 0x%x \n", page);
+ break;
+ /* SEQIN sets up the addr buffer and all registers except the length */
+ case NAND_CMD_SEQIN:
+ state->col = column;
+ state->row = page;
+ state->buf_ptr = 0;
+ break;
+ /* PAGEPROG reuses all of the setup from SEQIN and adds the length */
+ case NAND_CMD_PAGEPROG:
+ spinand_program_page(flash, state->row, state->col,
+ state->buf_ptr, flash->dmabuf);
+ break;
+ case NAND_CMD_STATUS:
+ spinand_get_status(flash, flash->dmabuf);
+ if (!(flash->dmabuf[0] & 0x80))
+ flash->dmabuf[0] = 0x80;
+ state->buf_ptr = 0;
+ break;
+ /* RESET command */
+ case NAND_CMD_RESET:
+ spinand_reset(flash);
+ break;
+ default:
+ dev_err(flash->dev, "Command 0x%x not implementd or unknown.\n",
+ command);
+ }
+}
+
+static int ambarella_spinand_get_resource(struct amb_spinand *flash,
+ struct platform_device *pdev)
+{
+ struct resource *res;
+ int errorCode = 0;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "No mem resource for spinor_reg!\n");
+ errorCode = -ENXIO;
+ goto spinand_get_resource_err_exit;
+ }
+
+ flash->regbase =
+ devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!flash->regbase) {
+ dev_err(&pdev->dev, "devm_ioremap() failed\n");
+ errorCode = -ENOMEM;
+ goto spinand_get_resource_err_exit;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res) {
+ dev_err(&pdev->dev, "No mem resource for spinor_reg!\n");
+ errorCode = -ENXIO;
+ goto spinand_get_resource_err_exit;
+ }
+
+ flash->dmaregbase =
+ devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!flash->dmaregbase) {
+ dev_err(&pdev->dev, "devm_ioremap() failed\n");
+ errorCode = -ENOMEM;
+ goto spinand_get_resource_err_exit;
+ }
+
+ return 0;
+
+spinand_get_resource_err_exit:
+ return errorCode;
+}
+
+static int amb_spinand_waitfunc(struct mtd_info *mtd, struct nand_chip *chip)
+{
+ struct amb_spinand *flash = (struct amb_spinand *)chip->priv;
+ int state = chip->state;
+ u32 timeout;
+
+ if (state == FL_ERASING)
+ timeout = MAX_WAIT_ERASE_JIFFIES;
+ else
+ timeout = AVERAGE_WAIT_JIFFIES;
+ return wait_execution_complete(flash, timeout);
+}
+
+static void amb_spinand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
+{
+ struct nand_chip *chip = (struct nand_chip *)mtd->priv;
+ struct amb_spinand *flash = (struct amb_spinand *)chip->priv;
+ struct spinand_state *state = (struct spinand_state *)flash->priv;
+
+ memcpy(flash->dmabuf + state->buf_ptr, buf, len);
+ state->buf_ptr += len;
+}
+
+static void amb_spinand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+ struct nand_chip *chip = (struct nand_chip *)mtd->priv;
+ struct amb_spinand *flash = (struct amb_spinand *)chip->priv;
+ struct spinand_state *state = (struct spinand_state *)flash->priv;
+
+ memcpy(buf, flash->dmabuf + state->buf_ptr, len);
+ state->buf_ptr += len;
+}
+
+static uint8_t amb_spinand_read_byte(struct mtd_info *mtd)
+{
+ struct nand_chip *chip = (struct nand_chip *)mtd->priv;
+ struct amb_spinand *flash = (struct amb_spinand *)chip->priv;
+ struct spinand_state *state = (struct spinand_state *)flash->priv;
+ u8 data;
+
+ data = flash->dmabuf[state->buf_ptr];
+ state->buf_ptr++;
+ return data;
+}
+
+static void amb_spinand_select_chip(struct mtd_info *mtd, int dev)
+{
+}
+
+static int ambarella_spinand_init_chip(struct amb_spinand *flash,
+ struct device_node *np)
+{
+ struct nand_chip *chip = &flash->chip;
+
+ chip->read_byte = amb_spinand_read_byte;
+ chip->write_buf = amb_spinand_write_buf;
+ chip->read_buf = amb_spinand_read_buf;
+ chip->select_chip = amb_spinand_select_chip;
+ chip->waitfunc = amb_spinand_waitfunc;
+ chip->cmdfunc = amb_spinand_cmdfunc;
+ chip->options |= (NAND_CACHEPRG | NAND_NO_SUBPAGE_WRITE);
+ //chip->options |= NAND_CACHEPRG;
+ chip->priv = flash;
+ chip->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
+
+ flash->mtd.priv = chip;
+ flash->mtd.name = "amba_spinand";
+ flash->mtd.owner = THIS_MODULE;
+ flash->mtd.writebufsize = flash->mtd.writesize;
+ flash->mtd.type = MTD_NANDFLASH;
+
+ return 0;
+}
+
+static int ambarella_spinand_init_chipecc(struct amb_spinand *flash)
+{
+ int ret = 0;
+
+ struct nand_chip *chip = &flash->chip;
+
+ chip->ecc.mode = NAND_ECC_HW;
+ chip->ecc.size = 0x200;
+ chip->ecc.bytes = 16;
+ chip->ecc.steps = 0x4;
+
+ chip->ecc.strength = 8;
+ chip->ecc.total = chip->ecc.steps * chip->ecc.bytes;
+ chip->ecc.layout = &ecc_layout_2KB_8bit;
+ chip->ecc.read_page = spinand_read_page_hwecc;
+ chip->ecc.write_page = spinand_write_page_hwecc;
+ ret = spinand_enable_ecc(flash);
+
+ return ret;
+}
+
+static int ambarella_spinand_probe(struct platform_device *pdev)
+{
+ struct mtd_info *mtd;
+ struct mtd_part_parser_data ppdata;
+ struct amb_spinand *flash;
+ struct spinand_state *state;
+ int errCode = 0;
+
+ flash = kzalloc(sizeof(struct amb_spinand), GFP_KERNEL);
+ if (!flash) {
+ errCode = -ENOMEM;
+ goto ambarella_spinand_probe_exit;
+ }
+
+ state = kzalloc(sizeof(struct spinand_state), GFP_KERNEL);
+ if (!state) {
+ errCode = -ENOMEM;
+ goto ambarella_spinand_probe_free_flash;
+ }
+ flash->priv = state;
+ state->buf_ptr = 0;
+
+ mutex_init(&flash->lock);
+ platform_set_drvdata(pdev, flash);
+ flash->dev = &pdev->dev;
+
+ /* set 50Mhz as default spi clock */
+ flash->clk = 50000000;
+ ambarella_spinand_get_resource(flash, pdev);
+ ambspinand_init(flash);
+
+ ambarella_spinand_init_chipecc(flash);
+ ambarella_spinand_init_chip(flash, pdev->dev.of_node);
+
+ mtd = &flash->mtd;
+
+ flash->command = kzalloc(5, GFP_KERNEL);
+ if(!flash->command) {
+ dev_err((const struct device *)&flash->dev,
+ "SPI NAND driver malloc command error\r\n");
+ errCode = -ENOMEM;
+ goto ambarella_spinand_probe_free_state;
+ }
+ //flash->clk = info->max_clk_hz;
+ ambspinand_init(flash);
+ ambspi_dma_config(flash);
+
+ spinand_set_protection(flash, SPI_NAND_PROTECTED_ALL_UNLOCKED);
+
+ if (nand_scan(mtd, 1))
+ return -ENXIO;
+
+ ppdata.of_node = pdev->dev.of_node;
+ errCode = mtd_device_parse_register(&flash->mtd, NULL, &ppdata, NULL, 0);
+ if (errCode < 0)
+ goto ambarella_spinand_probe_free_command;
+
+ printk("AMBARELLA SPINAND probed \n");
+ return 0;
+
+ambarella_spinand_probe_free_command:
+ kfree(flash->command);
+ambarella_spinand_probe_free_state:
+ kfree(state);
+ambarella_spinand_probe_free_flash:
+ kfree(flash);
+ambarella_spinand_probe_exit:
+ return errCode;
+}
+
+
+static int ambarella_spinand_remove(struct platform_device *pdev)
+{
+ struct amb_spinand *flash = platform_get_drvdata(pdev);
+ int status;
+
+ if (flash) {
+ /* Clean up MTD stuff. */
+ status = mtd_device_unregister(&flash->mtd);
+ if (status == 0) {
+ kfree(flash->command);
+ dma_free_coherent(flash->dev,
+ AMBA_SPINOR_DMA_BUFF_SIZE,
+ flash->dmabuf, flash->dmaaddr);
+ kfree(flash);
+ }
+ }
+ return 0;
+}
+
+static void ambarella_spinand_shutdown(struct platform_device *pdev)
+{
+ int ret;
+ struct amb_spinand *flash = platform_get_drvdata(pdev);
+
+ /* Wait until finished previous write command. */
+ ret = wait_execution_complete(flash, MAX_WAIT_JIFFIES);
+ if (ret) {
+ if (ret < 0) {
+ dev_err(flash->dev, "%s: Wait execution complete failed!\n",
+ __func__);
+ return;
+ } else
+ dev_err(flash->dev, "%s: Wait execution complete timedout!\n",
+ __func__);
+ }
+ /* Workaround for the spinand software reboot */
+ spinand_read_page_to_cache(flash, 0);
+ ret = wait_execution_complete(flash, MAX_WAIT_JIFFIES);
+ if (ret) {
+ if (ret < 0)
+ dev_err(flash->dev, "%s: Wait execution complete failed!\n",
+ __func__);
+ else
+ dev_err(flash->dev, "%s: Wait execution complete timedout!\n",
+ __func__);
+ }
+ return;
+}
+
+static const struct of_device_id ambarella_spinand_of_match[] = {
+ {.compatible = "ambarella,spinand", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ambarella_spinand_of_match);
+
+static struct platform_driver amb_spinand_driver = {
+ .probe = ambarella_spinand_probe,
+ .remove = ambarella_spinand_remove,
+ .driver = {
+ .name = "ambarella-spinand",
+ .owner = THIS_MODULE,
+ .of_match_table = ambarella_spinand_of_match,
+ },
+ .shutdown = ambarella_spinand_shutdown,
+};
+
+module_platform_driver(amb_spinand_driver);
+
+MODULE_AUTHOR("Ken He");
+MODULE_DESCRIPTION("Ambarella Media processor SPI NAND Flash Controller Driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/mtd/nand/ambarella_spinand.h b/drivers/mtd/nand/ambarella_spinand.h
new file mode 100644
index 00000000..d00bb4d9
--- /dev/null
+++ b/drivers/mtd/nand/ambarella_spinand.h
@@ -0,0 +1,386 @@
+/**
+ * ambarella_spinand.h
+ *
+ * History:
+ * 2015/10/26 - [Ken He] created file
+ *
+ * Copyright 2014-2018 Ambarella Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __LINUX_AMBARELLA_SPINAND_H__
+#define __LINUX_AMBARELLA_SPINAND_H__
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/mutex.h>
+#include <linux/math64.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/mod_devicetable.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/of_platform.h>
+
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <plat/dma.h>
+#include <plat/rct.h>
+
+#include <plat/ptb.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/delay.h>
+
+#define REGPREP(reg,mask,shift,value) (reg=((~mask)&reg)|(value << shift))
+#define REGDUMP(reg,mask,shift) ((reg&mask)>>shift)
+
+#define REG00_DATALEN_SHIFT 0 /*[21:0] data access length*/
+#define REG00_DATALEN_MASK 0x003fffff
+#define REG00_DUMMYLEN_SHIFT 22 /*[26:22] dummy cycle length*/
+#define REG00_DUMMYLEN_MASK 0x07c00000
+#define REG00_ADDRLEN_SHIFT 27 /*[29:27] address length*/
+#define REG00_ADDRLEN_MASK 0x38000000
+#define REG00_CMDLEN_SHIFT 30 /*[31:30] command length*/
+#define REG00_CMDLEN_MASK 0xc0000000
+
+#define REG04_READEN_SHIFT 0 /*[0] data part read mode*/
+#define REG04_READEN_MASK 0x00000001
+#define REG04_WRITEEN_SHIFT 1 /*[1] data part write mode*/
+#define REG04_WRITEEN_MASK 0x00000002
+#define REG04_RXLANE_SHIFT 9 /*[9] rx lane config*/
+#define REG04_RXLANE_MASK 0x00000200
+#define REG04_DATALANE_SHIFT 10 /*[11:10] number of data lane*/
+#define REG04_DATALANE_MASK 0x00000c00
+#define REG04_ADDRLANE_SHIFT 12 /*[13:12] number of addr lane*/
+#define REG04_ADDRLANE_MASK 0x00003000
+#define REG04_CMDLANE_SHIFT 14 /*[15:14] number of command lane */
+#define REG04_CMDLANE_MASK 0x0000c000
+#define REG04_LSBFRT_SHIFT 24 /*[24] 0-msb first 1-lsb first*/
+#define REG04_LSBFRT_MASK 0x01000000
+#define REG04_DATADTR_SHIFT 28 /*[28] data double transfer rate*/
+#define REG04_DATADTR_MASK 0x10000000
+#define REG04_DUMMYDTR_SHIFT 29 /*[29] dummy double transfer rate*/
+#define REG04_DUMMYDTR_MASK 0x20000000
+#define REG04_ADDRDTR_SHIFT 30 /*[30] address double transfer rate*/
+#define REG04_ADDRDTR_MASK 0x40000000
+#define REG04_CMDDTR_SHIFT 31/*[31] command dtr,only reg_clk divider>2*/
+#define REG04_CMDDTR_MASK 0x80000000
+
+#define REG08_RXSPLDELAY_SHIFT 0 /*[4:0] adjust rx sampling data phase*/
+#define REG08_RXSPLDELAY_MASK 0x0000001f
+#define REG08_CLKDIV_SHIFT 10 /*[17:10] divide reference clock*/
+#define REG08_CLKDIV_MASK 0x0003fc00
+#define REG08_CHIPSEL_SHIFT 18 /*[25:18] cen for multiple device 0 for select and vice versa*/
+#define REG08_CHIPSEL_MASK 0x03fc0000
+#define REG08_HOLDSWITCH_SHIFT 26 /*[26]0 for hold switching on switch one ref clock cycle before negative edge*/
+#define REG08_HOLDSWITCH_MASK 0x04000000
+#define REG08_SPICLKPOL_SHIFT 27 /*[27] clock will remain 1 or 0 in standby mode*/
+#define REG08_SPICLKPOL_MASK 0x08000000
+#define REG08_HOLDPIN_SHIFT 28 /*[30:28] for flow control purpose*/
+#define REG08_HOLDPIN_MASK 0x70000000
+#define REG08_FLOWCON_SHIFT 31 /*[31] flow control enable*/
+#define REG08_FLOWCON_MASK 0x80000000
+
+#define REG0C_CMD0_SHIFT 0 /*[7:0] command for SPI device*/
+#define REG0C_CMD0_MASK 0x000000ff
+#define REG0C_CMD1_SHIFT 8 /*[15:8]*/
+#define REG0C_CMD1_MASK 0x0000ff00
+#define REG0C_CMD2_SHIFT 16 /*[23:16]*/
+#define REG0C_CMD2_MASK 0x00ff0000
+
+#define REG18_RXDMAEN_SHIFT 0 /*[0] rx dma enable*/
+#define REG18_RXDMAEN_MASK 0x00000001
+#define REG18_TXDMAEN_SHIFT 1 /*[1] tx dma enable*/
+#define REG18_TXDMAEN_MASK 0x00000002
+
+#define REG1C_TXFIFOLV_SHIFT 0 /*[8:0] tx fifo threshold level*/
+#define REG1C_TXFIFOLV_MASK 0x000000ff
+
+#define REG20_RXFIFOLV_SHIFT 0
+#define REG20_RXFIFOLV_MASK 0x000000ff
+
+#define REG24_TXFIFOLV_SHIFT 0
+#define REG24_TXFIFOLV_MASK 0x000000ff
+
+#define REG28_RXFIFOLV_SHIFT 0
+#define REG28_RXFIFOLV_MASK 0x000000ff
+
+#define REG2C_TXFIFONOTFULL_SHIFT 1 /*[1]*/
+#define REG2C_TXFIFONOTFULL_MASK 0x00000002
+#define REG2C_TXFIFOEMP_SHIFT 2 /*[2] tx fifo empty*/
+#define REG2C_TXFIFOEMP_MASK 0x00000004
+#define REG2C_RXFIFONOTEMP_SHIFT 3 /*[3] */
+#define REG2C_RXFIFONOTEMP_MASK 0x00000008
+#define REG2C_RXFIFOFULL_SHIFT 4 /*[4] rx fifo full*/
+#define REG2C_RXFIFOFULL_MASK 0x00000010
+
+#define REG30_TXEMP_SHIFT 0/*[0] tx fifo almost empty*/
+#define REG30_TXEMP_MASK 0x00000001
+#define REG30_TXOVER_SHIFT 1 /*[1]*/
+#define REG30_TXOVER_MASK 0x00000002
+#define REG30_RXUNDER_SHIFT 2/*[2]*/
+#define REG30_RXUNDER_MASK 0x00000004
+#define REG30_RXOVER_SHIFT 3/*[3]*/
+#define REG30_RXOVER_MASK 0x00000008
+#define REG30_RXFULL_SHIFT 4 /*[4]*/
+#define REG30_RXFULL_MASK 0x00000010
+#define REG30_DATAREACH_SHIFT 5 /*[5]*/
+#define REG30_DATAREACH_MASK 0x00000020
+#define REG30_TXUNDER_SHIFT 6/*[6]*/
+#define REG30_TXUNDER_MASK 0x00000040
+
+#define REG38_TXEMPTYINTR_SHIFT 0 /*[0] tx almost empty*/
+#define REG38_TXEMPTYINTR_MASK 0x00000001
+#define REG38_TXOVERFLOWINTR_SHIFT 1 /*[1] */
+#define REG38_TXOVERFLOWINTR_MASK 0x00000002
+#define REG38_RXUNDERFLOWINTR_SHIFT 2 /*[2]*/
+#define REG38_RXUNDERFLOWINTR_MASK 0x00000004
+#define REG38_RXOVERFLOWINTR_SHIFT 3 /*[3]*/
+#define REG38_RXOVERFLOWINTR_MASK 0x00000008
+#define REG38_RXFULLINTR_SHIFT 4 /*[4] rx fifo almost full*/
+#define REG38_RXFULLINTR_MASK 0x00000010
+#define REG38_DATALENREACHINTR_SHIFT 5 /*[5] transaction done interrupt*/
+#define REG38_DATALENREACHINTR_MASK 0x00000020
+#define REG38_TXUNDERFLOWINTR_SHIFT 6 /*[6] */
+#define REG38_TXUNDERFLOWINTR_MASK 0x00000040
+
+#define REG40_TXFIFORESET_SHIFT 0 /*[0] software reset the tx fifo*/
+#define REG40_TXFIFORESET_MASK 0x00000001
+
+#define REG44_RXFIFORESET_SHIFT 0 /*[0] software reset the rx fifo*/
+#define REG44_RXFIFORESET_MASK 0x00000001
+
+#define REG50_STRTRX_SHIFT 0 /*[0] start tx or rx*/
+#define REG50_STRTRX_MASK 0x00000001
+
+#define HAS_IMG_PARTS 15
+#define TOTAL_FW_PARTS (HAS_IMG_PARTS + HAS_NO_IMG_PARTS)
+
+#define REG00 0x00
+#define REG04 0x04
+#define REG08 0x08
+#define REG0C 0x0c
+#define REG10 0x10
+#define REG14 0x14
+#define REG18 0x18
+#define REG1C 0x1c
+#define REG20 0x20
+#define REG24 0x24
+#define REG28 0x28
+#define REG2C 0x2c
+#define REG30 0x30
+#define REG34 0x34
+#define REG38 0x38
+#define REG3C 0x3C
+#define REG40 0x40
+#define REG44 0x44
+#define REG50 0x50
+#define REG100 0x100
+#define REG200 0x200
+#define DMA_CONTROLLER_OFFSET (0xe0005000)
+
+#if defined(CONFIG_SPI_NOR_CHIP_0)
+#define SPINOR_DEV 0
+#elif defined(CONFIG_SPI_NOR_CHIP_1)
+#define SPINOR_DEV 1
+#elif defined(CONFIG_SPI_NOR_CHIP_2)
+#define SPINOR_DEV 2
+#elif defined(CONFIG_SPI_NOR_CHIP_3)
+#define SPINOR_DEV 3
+#else
+#define SPINOR_DEV 0
+#endif
+
+struct amb_spinand {
+ struct device *dev;
+ unsigned char __iomem *regbase;
+ unsigned char __iomem *dmaregbase;
+ dma_addr_t dmaaddr;
+ u8 *dmabuf;
+ int (*write_enable)(struct amb_spinand *flash);
+ int (*wait_till_ready)(struct amb_spinand *flash);
+ struct mutex lock;
+ struct mtd_info mtd;
+ u16 page_size;
+ u16 addr_width;
+ u8 erase_opcode;
+ u8 *command;
+ u8 dummy;
+ u32 addr;
+ u32 clk;
+ bool fast_read;
+ u32 jedec_id;
+ struct nand_chip chip;
+ void *priv;
+};
+//the buffer size must align to 32 and smaller than the max size of DMA
+#define AMBA_SPINOR_DMA_BUFF_SIZE 4096
+
+/* SPI NAND Command Set Definitions */
+enum {
+ SPI_NAND_WRITE_ENABLE = 0x06,
+ SPI_NAND_WRITE_DISABLE = 0x04,
+ SPI_NAND_GET_FEATURE_INS = 0x0F,
+ SPI_NAND_SET_FEATURE = 0x1F,
+ SPI_NAND_PAGE_READ_INS = 0x13,
+ SPI_NAND_READ_CACHE_INS = 0x03,
+ SPI_NAND_FAST_READ_CACHE_INS = 0x0B,
+ SPI_NAND_READ_CACHE_X2_INS = 0x3B,
+ SPI_NAND_READ_CACHE_X4_INS = 0x6B,
+ SPI_NAND_READ_CACHE_DUAL_IO_INS = 0xBB,
+ SPI_NAND_READ_CACHE_QUAD_IO_INS = 0xEB,
+ SPI_NAND_READ_ID = 0x9F,
+ SPI_NAND_PROGRAM_LOAD_INS = 0x02,
+ SPI_NAND_PROGRAM_LOAD4_INS = 0x32,
+ SPI_NAND_PROGRAM_EXEC_INS = 0x10,
+ SPI_NAND_PROGRAM_LOAD_RANDOM_INS = 0x84,
+ SPI_NAND_PROGRAM_LOAD_RANDOM4_INS = 0xC4,
+ SPI_NAND_BLOCK_ERASE_INS = 0xD8,
+ SPI_NAND_RESET = 0xFF
+};
+
+/* Feature registers */
+enum feature_register {
+ SPI_NAND_PROTECTION_REG_ADDR = 0xA0,
+ SPI_NAND_FEATURE_EN_REG_ADDR = 0xB0,
+ SPI_NAND_STATUS_REG_ADDR = 0xC0,
+ SPI_NAND_DS_REG_ADDR = 0xD0,
+};
+/*
+ * SR7 - reserved
+ * SR6 - ECC status 2
+ * SR5 - ECC status 1
+ * SR4 - ECC status 0
+ *
+ * ECCS provides ECC status as follows:
+ * 000b = No bit errors were detected during the previous read algorithm.
+ * 001b = bit error was detected and corrected, error bit number < 3.
+ * 010b = bit error was detected and corrected, error bit number = 4.
+ * 011b = bit error was detected and corrected, error bit number = 5.
+ * 100b = bit error was detected and corrected, error bit number = 6.
+ * 101b = bit error was detected and corrected, error bit number = 7.
+ * 110b = bit error was detected and corrected, error bit number = 8.
+ * 111b = bit error was detected and not corrected.
+ *
+ * SR3 - P_Fail Program fail
+ * SR2 - E_Fail Erase fail
+ * SR1 - WEL - Write enable latch
+ * SR0 - OIP - Operation in progress
+ */
+enum {
+ SPI_NAND_ECCS2 = 0x40,
+ SPI_NAND_ECCS1 = 0x20,
+ SPI_NAND_ECCS0 = 0x10,
+ SPI_NAND_PF = 0x08,
+ SPI_NAND_EF = 0x04,
+ SPI_NAND_WEL = 0x02,
+ SPI_NAND_OIP = 0x01
+};
+
+enum {
+ SPI_NAND_ECC_NO_ERRORS = 0x00,
+ SPI_NAND_ECC_UNABLE_TO_CORRECT =
+ SPI_NAND_ECCS0 | SPI_NAND_ECCS1 | SPI_NAND_ECCS2
+};
+
+/*
+ * Feature enable register description: SPI_NAND_FEATURE_EN_REG_ADDR
+ *
+ * FR7 - OTP protect
+ * FR6 - OTP enable
+ * FR5 - reserved
+ * FR4 - ECC enable
+ * FR3 - reserved
+ * FR2 - reserved
+ * FR1 - reserved
+ * FR0 - Quad operation enable
+ */
+enum {
+ SPI_NAND_QUAD_EN = 0x01,
+ SPI_NAND_ECC_EN = 0x10,
+ SPI_NAND_OTP_EN = 0x40,
+ SPI_NAND_OTP_PRT = 0x80
+};
+
+/*
+ * Protection register description: SPI_NAND_PROTECTION_REG_ADDR
+ *
+ * BL7 - BRWD
+ * BL6 - reserved
+ * BL5 - Block protect 2
+ * BL4 - Block protect 1
+ * BL3 - Block protect 0
+ * BL2 - INV
+ * BL1 - CMP
+ * BL0 - reserved
+ */
+enum {
+ SPI_NAND_BRWD = 0x80,
+ SPI_NAND_BP2 = 0x20,
+ SPI_NAND_BP1 = 0x10,
+ SPI_NAND_BP0 = 0x08,
+ SPI_NAND_INV = 0x04,
+ SPI_NAND_CMP = 0x02
+};
+
+enum protected_rows {
+ /* All unlocked : 000xx */
+ SPI_NAND_PROTECTED_ALL_UNLOCKED = 0x00,
+ SPI_NAND_UPPER_1_64_LOCKED = 0x04,
+ SPI_NAND_LOWER_63_64_LOCKED = 0x05,
+ SPI_NAND_LOWER_1_64_LOCKED = 0x06,
+ SPI_NAND_UPPER_63_64_LOCKED = 0x07,
+ SPI_NAND_UPPER_1_32_LOCKED = 0x08,
+ SPI_NAND_LOWER_31_32_LOCKED = 0x09,
+ SPI_NAND_LOWER_1_32_LOCKED = 0x0A,
+ SPI_NAND_UPPER_31_32_LOCKED = 0x0B,
+ SPI_NAND_UPPER_1_16_LOCKED = 0x0C,
+ SPI_NAND_LOWER_15_16_LOCKED = 0x0D,
+ SPI_NAND_LOWER_1_16_LOCKED = 0x0E,
+ SPI_NAND_UPPER_15_16_LOCKED = 0x0F,
+ SPI_NAND_UPPER_1_8_LOCKED = 0x10,
+ SPI_NAND_LOWER_7_8_LOCKED = 0x11,
+ SPI_NAND_LOWER_1_8_LOCKED = 0x12,
+ SPI_NAND_UPPER_7_8_LOCKED = 0x13,
+ SPI_NAND_UPPER_1_4_LOCKED = 0x14,
+ SPI_NAND_LOWER_3_4_LOCKED = 0x15,
+ SPI_NAND_LOWER_1_4_LOCKED = 0x16,
+ SPI_NAND_UPPER_3_4_LOCKED = 0x17,
+ SPI_NAND_UPPER_1_2_LOCKED = 0x18,
+ SPI_NAND_BLOCK_0_LOCKED = 0x19,
+ SPI_NAND_LOWER_1_2_LOCKED = 0x1A,
+ SPI_NAND_BLOCK_0_LOCKED1 = 0x1B,
+ /* All locked (default) : 111xx */
+ SPI_NAND_PROTECTED_ALL_LOCKED = 0x1C,
+
+};
+
+struct spinand_info{
+ struct nand_ecclayout *ecclayout;
+ void *priv;
+};
+
+struct spinand_state{
+ u32 col; /* offset in page */
+ u32 row; /* page number */
+ int buf_ptr;
+};
+
+#endif /* __LINUX_AMBARELLA_SPINAND_H__ */
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c
index 683813a4..201808cf 100644
--- a/drivers/mtd/nand/nand_ids.c
+++ b/drivers/mtd/nand/nand_ids.c
@@ -44,6 +44,66 @@ struct nand_flash_dev nand_flash_ids[] = {
{ .id = {0x98, 0xde, 0x94, 0x82, 0x76, 0x56, 0x04, 0x20} },
SZ_8K, SZ_8K, SZ_2M, 0, 8, 640},
+ {"TC58NVG0S3H 1G 3.3V 8-bit",
+ { .id = {0x98, 0xf1, 0x80, 0x15, 0x72} },
+ SZ_2K, SZ_128, SZ_128K, 0, 5, 128},
+
+ {"TC58NVG1S3H 2G 3.3V 8-bit",
+ { .id = {0x98, 0xda, 0x90, 0x15, 0x76} },
+ SZ_2K, SZ_256, SZ_128K, 0, 5, 128},
+
+ {"S34ML02G2 2G 3.3V 8-bit",
+ { .id = {0x01, 0xda, 0x90, 0x95, 0x46} },
+ SZ_2K, SZ_256, SZ_128K, 0, 5, 128},
+
+ {"S34ML04G2 4G 3.3V 8-bit",
+ { .id = {0x01, 0xdc, 0x90, 0x95, 0x56} },
+ SZ_2K, SZ_512, SZ_128K, 0, 5, 128},
+
+ {"S34MS02G2 2G 1.8V 8-bit",
+ { .id = {0x01, 0xaa, 0x90, 0x15, 0x46} },
+ SZ_2K, SZ_256, SZ_128K, 0, 5, 128},
+
+ {"MT29F2G08ABAFA 2G 3.3V 8-bit",
+ { .id = {0x2c, 0xda, 0x90, 0x95, 0x04} },
+ SZ_2K, SZ_256, SZ_128K, 0, 5, 128},
+
+ {"MT29F2G08ABAGA 2G 3.3V 8-bit",
+ { .id = {0x2c, 0xda, 0x90, 0x95, 0x06} },
+ SZ_2K, SZ_256, SZ_128K, 0, 5, 128},
+
+ {"H27U2G8F2D 2G 3.3V 8-bit",
+ { .id = {0xad, 0xda, 0x90, 0x95, 0x46} },
+ SZ_2K, SZ_256, SZ_128K, 0, 5, 128},
+
+ {"W29N02KV 2G 3.3V 8-bit",
+ { .id = {0xef, 0xda, 0x10, 0x95, 0x06} },
+ SZ_2K, SZ_256, SZ_128K, 0, 5, 128},
+
+ {"GD9FU1G8F2A 1G 3.3V 8-bit",
+ { .id = {0xc8, 0xf1, 0x80, 0x1d, 0x42} },
+ SZ_2K, SZ_128, SZ_128K, 0, 5, 128},
+
+ {"GD9FS1G8F2A 1G 1.8V 8-bit",
+ { .id = {0xc8, 0xa1, 0x80, 0x15, 0x42} },
+ SZ_2K, SZ_128, SZ_128K, 0, 5, 128},
+
+ {"GD5F1GQ4UCY1G SPINAND 1Gb 3.3V 8-bit",
+ { .id = {0xc8, 0xb1, 0x48} },
+ SZ_2K, SZ_128, SZ_128K, LP_OPTIONS, 3, 128},
+
+ {"GD5F1GQ4UFY1G SPINAND 1Gb 3.3V 8-bit",
+ { .id = {0xc8, 0xb3, 0x48} },
+ SZ_2K, SZ_128, SZ_128K, LP_OPTIONS, 3, 128},
+
+ {"GD5F2GQ4UCY1G SPINAND 2Gb 3.3V 8-bit",
+ { .id = {0xc8, 0xb2, 0x48} },
+ SZ_2K, SZ_256, SZ_128K, LP_OPTIONS, 3, 128},
+
+ {"HYF1GQ4UBACAE SPINAND 1Gb 3.3V 8-bit",
+ { .id = {0xc9, 0x59, 0x1b} },
+ SZ_2K, SZ_128, SZ_128K, LP_OPTIONS, 3, 128},
+
LEGACY_ID_NAND("NAND 4MiB 5V 8-bit", 0x6B, 4, SZ_8K, SP_OPTIONS),
LEGACY_ID_NAND("NAND 4MiB 3,3V 8-bit", 0xE3, 4, SZ_8K, SP_OPTIONS),
LEGACY_ID_NAND("NAND 4MiB 3,3V 8-bit", 0xE5, 4, SZ_8K, SP_OPTIONS),
@@ -169,6 +229,7 @@ struct nand_manufacturers nand_manuf_ids[] = {
{NAND_MFR_AMD, "AMD/Spansion"},
{NAND_MFR_MACRONIX, "Macronix"},
{NAND_MFR_EON, "Eon"},
+ {NAND_MFR_GD,"GigdDevice"},
{0x0, "Unknown"}
};
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index ed956e08..f03fcaa1 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -21,6 +21,7 @@ source "drivers/net/ethernet/3com/Kconfig"
source "drivers/net/ethernet/adaptec/Kconfig"
source "drivers/net/ethernet/aeroflex/Kconfig"
source "drivers/net/ethernet/alteon/Kconfig"
+source "drivers/net/ethernet/ambarella/Kconfig"
source "drivers/net/ethernet/amd/Kconfig"
source "drivers/net/ethernet/apple/Kconfig"
source "drivers/net/ethernet/atheros/Kconfig"
diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile
index 8268d85f..834537fb 100644
--- a/drivers/net/ethernet/Makefile
+++ b/drivers/net/ethernet/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_NET_VENDOR_8390) += 8390/
obj-$(CONFIG_NET_VENDOR_ADAPTEC) += adaptec/
obj-$(CONFIG_GRETH) += aeroflex/
obj-$(CONFIG_NET_VENDOR_ALTEON) += alteon/
+obj-$(CONFIG_NET_VENDOR_AMBARELLA) += ambarella/
obj-$(CONFIG_NET_VENDOR_AMD) += amd/
obj-$(CONFIG_NET_VENDOR_APPLE) += apple/
obj-$(CONFIG_NET_VENDOR_ATHEROS) += atheros/
diff --git a/drivers/net/ethernet/ambarella/Kconfig b/drivers/net/ethernet/ambarella/Kconfig
new file mode 100644
index 00000000..2a0c0b72
--- /dev/null
+++ b/drivers/net/ethernet/ambarella/Kconfig
@@ -0,0 +1,23 @@
+#
+# AMBARELLA network device configuration
+#
+
+config NET_VENDOR_AMBARELLA
+ tristate "Ambarella 10/100/1000 GMAC Ethernet support"
+ depends on PLAT_AMBARELLA
+ select CRC32
+ select PHYLIB
+ select MII
+ help
+ This driver supports Ambarella 10/100/1000 GMAC Ethernet.
+
+config NET_VENDOR_AMBARELLA_INTEN_TUE
+ bool "Enable Transmit Buffer Unavailable Interrupt"
+ default n
+ depends on NET_VENDOR_AMBARELLA
+ help
+ Enable ETH_DMA_INTEN_TUE will downgrade the performance in most case,
+ but you will get a quick response especially in GMII mode.
+
+ If you are not sure, say N here.
+
diff --git a/drivers/net/ethernet/ambarella/Makefile b/drivers/net/ethernet/ambarella/Makefile
new file mode 100644
index 00000000..e2e9c09e
--- /dev/null
+++ b/drivers/net/ethernet/ambarella/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the Ambarella network device drivers
+#
+
+obj-$(CONFIG_NET_VENDOR_AMBARELLA) += ambarella_eth.o
diff --git a/drivers/net/ethernet/ambarella/ambarella_eth.c b/drivers/net/ethernet/ambarella/ambarella_eth.c
new file mode 100644
index 00000000..a081bd33
--- /dev/null
+++ b/drivers/net/ethernet/ambarella/ambarella_eth.c
@@ -0,0 +1,2597 @@
+/*
+ * /drivers/net/ethernet/ambarella/ambarella_eth_normal.c
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ * Copyright (C) 2004-2011, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/of.h>
+#include <linux/of_net.h>
+#include <linux/of_mdio.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/crc32.h>
+#include <linux/time.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+#include <linux/ethtool.h>
+
+#include <asm/dma.h>
+
+#include <mach/hardware.h>
+#include <plat/eth.h>
+#include <plat/rct.h>
+/* ==========================================================================*/
+#define AMBETH_NAPI_WEIGHT 32
+#define AMBETH_TX_WATCHDOG (2 * HZ)
+#define AMBETH_MII_RETRY_CNT 200
+#define AMBETH_FC_PAUSE_TIME 1954
+
+#define AMBETH_PACKET_MAXFRAME (1536)
+#define AMBETH_RX_COPYBREAK (1518)
+#define AMBETH_RX_RNG_MIN (8)
+#define AMBETH_TX_RNG_MIN (4)
+#define AMBETH_PHY_REG_SIZE (32)
+
+#define AMBETH_RXDMA_STATUS (ETH_DMA_STATUS_OVF | ETH_DMA_STATUS_RI | \
+ ETH_DMA_STATUS_RU | ETH_DMA_STATUS_RPS | \
+ ETH_DMA_STATUS_RWT)
+#define AMBETH_RXDMA_INTEN (ETH_DMA_INTEN_OVE | ETH_DMA_INTEN_RIE | \
+ ETH_DMA_INTEN_RUE | ETH_DMA_INTEN_RSE | \
+ ETH_DMA_INTEN_RWE)
+#define AMBETH_TXDMA_STATUS (ETH_DMA_STATUS_TI | ETH_DMA_STATUS_TPS | \
+ ETH_DMA_STATUS_TU | ETH_DMA_STATUS_TJT | \
+ ETH_DMA_STATUS_UNF)
+#if defined(CONFIG_NET_VENDOR_AMBARELLA_INTEN_TUE)
+#define AMBETH_TXDMA_INTEN (ETH_DMA_INTEN_TIE | ETH_DMA_INTEN_TSE | \
+ ETH_DMA_INTEN_TUE | ETH_DMA_INTEN_TJE | \
+ ETH_DMA_INTEN_UNE)
+#else
+#define AMBETH_TXDMA_INTEN (ETH_DMA_INTEN_TIE | ETH_DMA_INTEN_TSE | \
+ ETH_DMA_INTEN_TJE | ETH_DMA_INTEN_UNE)
+#endif
+#define AMBETH_DMA_INTEN (ETH_DMA_INTEN_NIE | ETH_DMA_INTEN_AIE | \
+ ETH_DMA_INTEN_FBE | AMBETH_RXDMA_INTEN | \
+ AMBETH_TXDMA_INTEN)
+
+/* ==========================================================================*/
+struct ambeth_rng_info {
+ struct sk_buff *skb;
+ dma_addr_t mapping;
+};
+
+struct ambeth_tx_rngmng {
+ unsigned int cur_tx;
+ unsigned int dirty_tx;
+ struct ambeth_rng_info *rng_tx;
+ struct ambeth_desc *desc_tx;
+};
+
+struct ambeth_rx_rngmng {
+ unsigned int cur_rx;
+ unsigned int dirty_rx;
+ struct ambeth_rng_info *rng_rx;
+ struct ambeth_desc *desc_rx;
+};
+
+struct ambeth_info {
+ unsigned int rx_count;
+ struct ambeth_rx_rngmng rx;
+ unsigned int tx_count;
+ unsigned int tx_irq_low;
+ unsigned int tx_irq_high;
+ struct ambeth_tx_rngmng tx;
+ dma_addr_t rx_dma_desc;
+ dma_addr_t tx_dma_desc;
+ spinlock_t lock;
+ int oldspeed;
+ int oldduplex;
+ int oldlink;
+ int oldpause;
+ int oldasym_pause;
+ u32 flow_ctr;
+
+ struct net_device_stats stats;
+ struct napi_struct napi;
+ struct net_device *ndev;
+
+ struct mii_bus new_bus;
+ struct phy_device *phydev;
+ int pwr_gpio;
+ u8 pwr_gpio_active;
+ int rst_gpio;
+ u8 rst_gpio_active;
+ u32 phy_supported;
+ u32 fixed_speed; /* only for phy-less */
+
+ unsigned char __iomem *regbase;
+ u32 msg_enable;
+
+ u32 mdio_gpio : 1,
+ phy_enabled : 1,
+ ipc_tx : 1,
+ ipc_rx : 1,
+ dump_tx : 1,
+ dump_rx : 1,
+ dump_rx_free : 1,
+ dump_rx_all : 1;
+ int clk_direction;
+};
+
+/* ==========================================================================*/
+static int msg_level = -1;
+module_param (msg_level, int, 0);
+MODULE_PARM_DESC (msg_level, "Override default message level");
+
+/* ==========================================================================*/
+static void amba_set_eth_desc(struct ambeth_desc *desc, u32 val) {
+ u32 status = 0, length = 0;
+
+ if(ETH_ENHANCED) {
+ if(val & ETH_TDES_IC)
+ status |= ETH_ENHANCED_TDES0_IC;
+ if(val & ETH_TDES_LS)
+ status |= ETH_ENHANCED_TDES0_LS;
+ if(val & ETH_TDES_FS)
+ status |= ETH_ENHANCED_TDES0_FS;
+ if(val & ETH_TDES_TCH)
+ status |= ETH_ENHANCED_TDES0_TCH;
+ if(val & ETH_TDES_CIC)
+ status |= ETH_ENHANCED_TDES0_CIC_V2;
+
+ desc->status |= status;
+ } else {
+ if(val & ETH_TDES_IC)
+ length |= ETH_TDES1_IC;
+ if(val & ETH_TDES_LS)
+ length |= ETH_TDES1_LS;
+ if(val & ETH_TDES_FS)
+ length |= ETH_TDES1_FS;
+ if(val & ETH_TDES_TCH)
+ length |= ETH_TDES1_TCH;
+ if(val & ETH_TDES_CIC)
+ length |= ETH_TDES1_CIC_TUI | ETH_TDES1_CIC_HDR;
+
+ desc->length |= length;
+ }
+
+}
+
+static void ambhw_dump(struct ambeth_info *lp)
+{
+ u32 i;
+ unsigned int dirty_diff;
+ u32 entry;
+
+ dirty_diff = (lp->rx.cur_rx - lp->rx.dirty_rx);
+ entry = (lp->rx.cur_rx % lp->rx_count);
+ dev_info(&lp->ndev->dev, "RX Info: cur_rx[%u], dirty_rx[%u],"
+ " diff[%u], entry[%u].\n", lp->rx.cur_rx, lp->rx.dirty_rx,
+ dirty_diff, entry);
+ for (i = 0; i < lp->rx_count; i++) {
+ dev_info(&lp->ndev->dev, "RX Info: RX descriptor[%u] "
+ "0x%08x 0x%08x 0x%08x 0x%08x.\n", i,
+ lp->rx.desc_rx[i].status, lp->rx.desc_rx[i].length,
+ lp->rx.desc_rx[i].buffer1, lp->rx.desc_rx[i].buffer2);
+ }
+ dirty_diff = (lp->tx.cur_tx - lp->tx.dirty_tx);
+ entry = (lp->tx.cur_tx % lp->tx_count);
+ dev_info(&lp->ndev->dev, "TX Info: cur_tx[%u], dirty_tx[%u],"
+ " diff[%u], entry[%u].\n", lp->tx.cur_tx, lp->tx.dirty_tx,
+ dirty_diff, entry);
+ for (i = 0; i < lp->tx_count; i++) {
+ dev_info(&lp->ndev->dev, "TX Info: TX descriptor[%u] "
+ "0x%08x 0x%08x 0x%08x 0x%08x.\n", i,
+ lp->tx.desc_tx[i].status, lp->tx.desc_tx[i].length,
+ lp->tx.desc_tx[i].buffer1, lp->tx.desc_tx[i].buffer2);
+ }
+ for (i = 0; i <= 21; i++) {
+ dev_dbg(&lp->ndev->dev, "GMAC[%d]: 0x%08x.\n", i,
+ amba_readl(lp->regbase + ETH_MAC_CFG_OFFSET + (i << 2)));
+ }
+ for (i = 0; i <= 54; i++) {
+ dev_dbg(&lp->ndev->dev, "GDMA[%d]: 0x%08x.\n", i,
+ amba_readl(lp->regbase + ETH_DMA_BUS_MODE_OFFSET + (i << 2)));
+ }
+}
+
+static inline int ambhw_dma_reset(struct ambeth_info *lp)
+{
+ int ret_val = 0;
+ u32 counter = 0;
+
+ amba_setbitsl(lp->regbase + ETH_DMA_BUS_MODE_OFFSET,
+ ETH_DMA_BUS_MODE_SWR);
+ do {
+ if (counter++ > 100) {
+ ret_val = -EIO;
+ break;
+ }
+ mdelay(1);
+ } while (amba_tstbitsl(lp->regbase + ETH_DMA_BUS_MODE_OFFSET,
+ ETH_DMA_BUS_MODE_SWR));
+
+ if (ret_val && netif_msg_drv(lp))
+ dev_err(&lp->ndev->dev, "DMA Error: Check PHY.\n");
+
+ return ret_val;
+}
+
+static inline void ambhw_dma_int_enable(struct ambeth_info *lp)
+{
+ amba_writel(lp->regbase + ETH_DMA_INTEN_OFFSET, AMBETH_DMA_INTEN);
+}
+
+static inline void ambhw_dma_int_disable(struct ambeth_info *lp)
+{
+ amba_writel(lp->regbase + ETH_DMA_INTEN_OFFSET, 0);
+}
+
+static inline void ambhw_dma_rx_start(struct ambeth_info *lp)
+{
+ amba_setbitsl(lp->regbase + ETH_DMA_OPMODE_OFFSET, ETH_DMA_OPMODE_SR);
+}
+
+static inline void ambhw_dma_rx_stop(struct ambeth_info *lp)
+{
+ unsigned int irq_status;
+ int i = 1300;
+
+ amba_clrbitsl(lp->regbase + ETH_DMA_OPMODE_OFFSET, ETH_DMA_OPMODE_SR);
+ do {
+ udelay(1);
+ irq_status = amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET);
+ } while ((irq_status & ETH_DMA_STATUS_RS_MASK) && --i);
+ if ((i <= 0) && netif_msg_drv(lp)) {
+ dev_err(&lp->ndev->dev,
+ "DMA Error: Stop RX status=0x%x, opmode=0x%x.\n",
+ amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET),
+ amba_readl(lp->regbase + ETH_DMA_OPMODE_OFFSET));
+ }
+}
+
+static inline void ambhw_dma_tx_start(struct ambeth_info *lp)
+{
+ amba_setbitsl(lp->regbase + ETH_DMA_OPMODE_OFFSET, ETH_DMA_OPMODE_ST);
+}
+
+static inline void ambhw_dma_tx_stop(struct ambeth_info *lp)
+{
+ unsigned int irq_status;
+ int i = 1300;
+
+ amba_clrbitsl(lp->regbase + ETH_DMA_OPMODE_OFFSET, ETH_DMA_OPMODE_ST);
+ do {
+ udelay(1);
+ irq_status = amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET);
+ } while ((irq_status & ETH_DMA_STATUS_TS_MASK) && --i);
+ if ((i <= 0) && netif_msg_drv(lp)) {
+ dev_err(&lp->ndev->dev,
+ "DMA Error: Stop TX status=0x%x, opmode=0x%x.\n",
+ amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET),
+ amba_readl(lp->regbase + ETH_DMA_OPMODE_OFFSET));
+ }
+ amba_setbitsl(lp->regbase + ETH_DMA_OPMODE_OFFSET, ETH_DMA_OPMODE_FTF);
+}
+
+static inline void ambhw_dma_tx_restart(struct ambeth_info *lp, u32 entry)
+{
+ lp->tx.desc_tx[entry].status = 0;
+ amba_set_eth_desc(&lp->tx.desc_tx[entry], ETH_TDES_IC);
+ lp->tx.desc_tx[entry].status |= ETH_TDES0_OWN;
+ amba_writel(lp->regbase + ETH_DMA_TX_DESC_LIST_OFFSET,
+ (u32)lp->tx_dma_desc + (entry * sizeof(struct ambeth_desc)));
+ if (netif_msg_tx_err(lp)) {
+ dev_err(&lp->ndev->dev, "TX Error: restart %u.\n", entry);
+ ambhw_dump(lp);
+ }
+ ambhw_dma_tx_start(lp);
+}
+
+static inline void ambhw_dma_tx_poll(struct ambeth_info *lp)
+{
+ amba_writel(lp->regbase + ETH_DMA_TX_POLL_DMD_OFFSET, 0x01);
+}
+
+static inline void ambhw_stop_tx_rx(struct ambeth_info *lp)
+{
+ unsigned int irq_status;
+ int i = 1300;
+
+ amba_clrbitsl(lp->regbase + ETH_MAC_CFG_OFFSET, ETH_MAC_CFG_RE);
+ amba_clrbitsl(lp->regbase + ETH_DMA_OPMODE_OFFSET,
+ (ETH_DMA_OPMODE_SR | ETH_DMA_OPMODE_ST));
+ do {
+ udelay(1);
+ irq_status = amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET);
+ } while ((irq_status & (ETH_DMA_STATUS_TS_MASK |
+ ETH_DMA_STATUS_RS_MASK)) && --i);
+ if ((i <= 0) && netif_msg_drv(lp)) {
+ dev_err(&lp->ndev->dev,
+ "DMA Error: Stop TX/RX status=0x%x, opmode=0x%x.\n",
+ amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET),
+ amba_readl(lp->regbase + ETH_DMA_OPMODE_OFFSET));
+ }
+ amba_clrbitsl(lp->regbase + ETH_MAC_CFG_OFFSET, ETH_MAC_CFG_TE);
+}
+
+static inline void ambhw_set_dma_desc(struct ambeth_info *lp)
+{
+ amba_writel(lp->regbase + ETH_DMA_RX_DESC_LIST_OFFSET,
+ lp->rx_dma_desc);
+ amba_writel(lp->regbase + ETH_DMA_TX_DESC_LIST_OFFSET,
+ lp->tx_dma_desc);
+}
+
+static inline phy_interface_t ambhw_get_interface(struct ambeth_info *lp)
+{
+ return amba_tstbitsl(lp->regbase + ETH_MAC_CFG_OFFSET,
+ ETH_MAC_CFG_PS) ? PHY_INTERFACE_MODE_MII :
+ PHY_INTERFACE_MODE_GMII;
+}
+
+static inline void ambhw_set_hwaddr(struct ambeth_info *lp, u8 *hwaddr)
+{
+ u32 val;
+
+ val = (hwaddr[5] << 8) | hwaddr[4];
+ amba_writel(lp->regbase + ETH_MAC_MAC0_HI_OFFSET, val);
+ udelay(4);
+ val = (hwaddr[3] << 24) | (hwaddr[2] << 16) |
+ (hwaddr[1] << 8) | hwaddr[0];
+ amba_writel(lp->regbase + ETH_MAC_MAC0_LO_OFFSET, val);
+}
+
+static inline void ambhw_get_hwaddr(struct ambeth_info *lp, u8 *hwaddr)
+{
+ u32 hval;
+ u32 lval;
+
+ hval = amba_readl(lp->regbase + ETH_MAC_MAC0_HI_OFFSET);
+ lval = amba_readl(lp->regbase + ETH_MAC_MAC0_LO_OFFSET);
+ hwaddr[5] = ((hval >> 8) & 0xff);
+ hwaddr[4] = ((hval >> 0) & 0xff);
+ hwaddr[3] = ((lval >> 24) & 0xff);
+ hwaddr[2] = ((lval >> 16) & 0xff);
+ hwaddr[1] = ((lval >> 8) & 0xff);
+ hwaddr[0] = ((lval >> 0) & 0xff);
+}
+
+static void ambeth_fc_resolve(struct ambeth_info *lp);
+
+static inline void ambhw_set_link_mode_speed(struct ambeth_info *lp)
+{
+ u32 val;
+
+ val = amba_readl(lp->regbase + ETH_MAC_CFG_OFFSET);
+ switch (lp->oldspeed) {
+ case SPEED_1000:
+ val &= ~(ETH_MAC_CFG_PS);
+ break;
+ case SPEED_100:
+ val |= ETH_MAC_CFG_PS;
+ val |= ETH_MAC_CFG_FES;
+ break;
+ case SPEED_10:
+ val |= ETH_MAC_CFG_PS;
+ val &= ~(ETH_MAC_CFG_FES);
+ break;
+ default:
+ break;
+ }
+ if (lp->oldduplex) {
+ val &= ~(ETH_MAC_CFG_DO);
+ val |= ETH_MAC_CFG_DM;
+ } else {
+ val &= ~(ETH_MAC_CFG_DM);
+ val |= ETH_MAC_CFG_DO;
+ }
+ amba_writel(lp->regbase + ETH_MAC_CFG_OFFSET, val);
+ ambeth_fc_resolve(lp);
+}
+
+static inline int ambhw_enable(struct ambeth_info *lp)
+{
+ int ret_val = 0;
+ u32 val;
+
+ ret_val = ambhw_dma_reset(lp);
+ if (ret_val)
+ goto ambhw_init_exit;
+
+ ambhw_set_hwaddr(lp, lp->ndev->dev_addr);
+
+ val = ETH_DMA_BUS_MODE_FB | ETH_DMA_BUS_MODE_PBL_32 |
+ ETH_DMA_BUS_MODE_DA_RX;
+
+ if(ETH_ENHANCED)
+ val |= ETH_DMA_BUS_MODE_ATDS;
+
+ amba_writel(lp->regbase + ETH_DMA_BUS_MODE_OFFSET, val);
+ amba_writel(lp->regbase + ETH_MAC_FRAME_FILTER_OFFSET, 0);
+
+ val = ETH_DMA_OPMODE_TTC_256 | ETH_DMA_OPMODE_RTC_64 |
+ ETH_DMA_OPMODE_FUF | ETH_DMA_OPMODE_TSF;
+ amba_writel(lp->regbase + ETH_DMA_OPMODE_OFFSET, val);
+ amba_writel(lp->regbase + ETH_MAC_CFG_OFFSET,
+ (ETH_MAC_CFG_TE | ETH_MAC_CFG_RE));
+
+ /*
+ * (512 bits / N) * pause_time = actual pause time
+ * ex:
+ * 512 bits / 1 Gbps * 1954 = ~0.0010 sec = 1 ms
+ * 512 bits / 100 Mbps * 1954 = ~0.010 sec = 10 ms
+ */
+ amba_writel(lp->regbase + ETH_MAC_FLOW_CTR_OFFSET,
+ ETH_MAC_FLOW_CTR_PLT_256 |
+ ETH_MAC_FLOW_CTR_PT(AMBETH_FC_PAUSE_TIME));
+
+ if (lp->ipc_rx) {
+ amba_setbitsl(lp->regbase + ETH_DMA_OPMODE_OFFSET,
+ ETH_DMA_OPMODE_RSF);
+ amba_setbitsl(lp->regbase + ETH_MAC_CFG_OFFSET,
+ ETH_MAC_CFG_IPC);
+ }
+
+ if (lp->dump_rx_all) {
+ amba_setbitsl(lp->regbase + ETH_MAC_FRAME_FILTER_OFFSET,
+ ETH_MAC_FRAME_FILTER_RA);
+ }
+
+ if(ETH_ENHANCED)
+ amba_writel(lp->regbase + ETH_MAC_INTERRUPT_MASK_OFFSET,0xFFFFFFFF);
+
+ amba_writel(lp->regbase + ETH_DMA_STATUS_OFFSET,
+ amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET));
+
+ambhw_init_exit:
+ return ret_val;
+}
+
+static inline void ambhw_disable(struct ambeth_info *lp)
+{
+ ambhw_stop_tx_rx(lp);
+ ambhw_dma_int_disable(lp);
+}
+
+static void ambhw_dump_buffer(const char *msg,
+ unsigned char *data, unsigned int length)
+{
+ unsigned int i;
+
+ if (msg)
+ printk("%s", msg);
+ for (i = 0; i < length; i++) {
+ if (i % 16 == 0) {
+ printk("\n%03X:", i);
+ }
+ printk(" %02x", data[i]);
+ }
+ printk("\n");
+}
+
+/* ==========================================================================*/
+static int ambhw_mdio_read(struct mii_bus *bus,
+ int mii_id, int regnum)
+{
+ struct ambeth_info *lp = bus->priv;
+ int val, cnt;
+
+ for (cnt = AMBETH_MII_RETRY_CNT; cnt > 0; cnt--) {
+ if (!amba_tstbitsl(lp->regbase + ETH_MAC_GMII_ADDR_OFFSET,
+ ETH_MAC_GMII_ADDR_GB))
+ break;
+ udelay(10);
+ }
+ if ((cnt <= 0) && netif_msg_hw(lp)) {
+ dev_err(&lp->ndev->dev, "MII Error: Preread tmo!\n");
+ val = 0xFFFFFFFF;
+ goto ambhw_mdio_read_exit;
+ }
+
+ val = ETH_MAC_GMII_ADDR_PA(mii_id) | ETH_MAC_GMII_ADDR_GR(regnum);
+ val |= ETH_MAC_GMII_ADDR_CR_250_300MHZ | ETH_MAC_GMII_ADDR_GB;
+ amba_writel(lp->regbase + ETH_MAC_GMII_ADDR_OFFSET, val);
+
+ for (cnt = AMBETH_MII_RETRY_CNT; cnt > 0; cnt--) {
+ if (!amba_tstbitsl(lp->regbase + ETH_MAC_GMII_ADDR_OFFSET,
+ ETH_MAC_GMII_ADDR_GB))
+ break;
+ udelay(10);
+ }
+ if ((cnt <= 0) && netif_msg_hw(lp)) {
+ dev_err(&lp->ndev->dev, "MII Error: Postread tmo!\n");
+ val = 0xFFFFFFFF;
+ goto ambhw_mdio_read_exit;
+ }
+
+ val = amba_readl(lp->regbase + ETH_MAC_GMII_DATA_OFFSET);
+
+ambhw_mdio_read_exit:
+ if (netif_msg_hw(lp))
+ dev_info(&lp->ndev->dev,
+ "MII Read: addr[0x%02x], reg[0x%02x], val[0x%04x].\n",
+ mii_id, regnum, val);
+
+ return val;
+}
+
+static int ambhw_mdio_write(struct mii_bus *bus,
+ int mii_id, int regnum, u16 value)
+{
+ int ret_val = 0;
+ struct ambeth_info *lp;
+ int val;
+ int cnt = 0;
+
+ lp = (struct ambeth_info *)bus->priv;
+
+ if (netif_msg_hw(lp))
+ dev_info(&lp->ndev->dev,
+ "MII Write: id[0x%02x], add[0x%02x], val[0x%04x].\n",
+ mii_id, regnum, value);
+
+ for (cnt = AMBETH_MII_RETRY_CNT; cnt > 0; cnt--) {
+ if (!amba_tstbitsl(lp->regbase + ETH_MAC_GMII_ADDR_OFFSET,
+ ETH_MAC_GMII_ADDR_GB))
+ break;
+ udelay(10);
+ }
+ if ((cnt <= 0) && netif_msg_hw(lp)) {
+ dev_err(&lp->ndev->dev, "MII Error: Prewrite tmo!\n");
+ ret_val = -EIO;
+ goto ambhw_mdio_write_exit;
+ }
+
+ val = value;
+ amba_writel(lp->regbase + ETH_MAC_GMII_DATA_OFFSET, val);
+ val = ETH_MAC_GMII_ADDR_PA(mii_id) | ETH_MAC_GMII_ADDR_GR(regnum);
+ val |= ETH_MAC_GMII_ADDR_CR_250_300MHZ | ETH_MAC_GMII_ADDR_GW |
+ ETH_MAC_GMII_ADDR_GB;
+ amba_writel(lp->regbase + ETH_MAC_GMII_ADDR_OFFSET, val);
+
+ for (cnt = AMBETH_MII_RETRY_CNT; cnt > 0; cnt--) {
+ if (!amba_tstbitsl(lp->regbase + ETH_MAC_GMII_ADDR_OFFSET,
+ ETH_MAC_GMII_ADDR_GB))
+ break;
+ udelay(10);
+ }
+ if ((cnt <= 0) && netif_msg_hw(lp)) {
+ dev_err(&lp->ndev->dev, "MII Error: Postwrite tmo!\n");
+ ret_val = -EIO;
+ goto ambhw_mdio_write_exit;
+ }
+
+ambhw_mdio_write_exit:
+ return ret_val;
+}
+
+static int ambhw_mdio_reset(struct mii_bus *bus)
+{
+ struct ambeth_info *lp = bus->priv;
+ int ret_val = 0;
+
+ if (netif_msg_hw(lp)) {
+ dev_info(&lp->ndev->dev, "MII Info: Power gpio = %d, "
+ "Reset gpio = %d.\n", lp->pwr_gpio, lp->rst_gpio);
+ }
+
+ if (gpio_is_valid(lp->pwr_gpio))
+ gpio_set_value_cansleep(lp->pwr_gpio, !lp->pwr_gpio_active);
+ if (gpio_is_valid(lp->rst_gpio))
+ gpio_set_value_cansleep(lp->rst_gpio, lp->rst_gpio_active);
+ if (gpio_is_valid(lp->pwr_gpio))
+ gpio_set_value_cansleep(lp->pwr_gpio, lp->pwr_gpio_active);
+ if (gpio_is_valid(lp->rst_gpio))
+ gpio_set_value_cansleep(lp->rst_gpio, !lp->rst_gpio_active);
+
+ /* waiting for PHY working stable, this delay is a must */
+ msleep(50);
+
+ return ret_val;
+}
+
+/* ==========================================================================*/
+static void ambeth_adjust_link(struct net_device *ndev)
+{
+ struct ambeth_info *lp = netdev_priv(ndev);
+ struct phy_device *phydev = lp->phydev;
+ int need_update = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&lp->lock, flags);
+
+ if (phydev->link) {
+ if (phydev->duplex != lp->oldduplex) {
+ need_update = 1;
+ lp->oldduplex = phydev->duplex;
+ }
+ if (phydev->speed != lp->oldspeed) {
+ switch (phydev->speed) {
+ case SPEED_1000:
+ case SPEED_100:
+ case SPEED_10:
+ need_update = 1;
+ lp->oldspeed = phydev->speed;
+ break;
+ default:
+ if (netif_msg_link(lp))
+ dev_warn(&lp->ndev->dev,
+ "Unknown Speed(%d).\n",
+ phydev->speed);
+ break;
+ }
+ }
+ if (phydev->pause != lp->oldpause ||
+ phydev->asym_pause != lp->oldasym_pause) {
+ lp->oldpause = phydev->pause;
+ lp->oldasym_pause = phydev->asym_pause;
+ need_update = 1;
+ }
+ if (lp->oldlink != phydev->link) {
+ need_update = 1;
+ lp->oldlink = phydev->link;
+ }
+ } else if (lp->oldlink) {
+ need_update = 1;
+ lp->oldlink = PHY_DOWN;
+ lp->oldspeed = 0;
+ lp->oldduplex = -1;
+ }
+
+ if (need_update) {
+ ambhw_set_link_mode_speed(lp);
+ if (netif_msg_link(lp))
+ phy_print_status(phydev);
+ }
+ spin_unlock_irqrestore(&lp->lock, flags);
+}
+
+static void ambeth_fc_config(struct ambeth_info *lp)
+{
+ u32 sup, adv, flow_ctr;
+
+ sup = lp->phydev->supported;
+ adv = lp->phydev->advertising;
+ flow_ctr = lp->flow_ctr;
+
+ sup |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
+ adv &= ~(ADVERTISED_Pause | ADVERTISED_Asym_Pause);
+
+ sup &= lp->phy_supported;
+
+ if (!(sup & (SUPPORTED_Pause | SUPPORTED_Asym_Pause)))
+ goto unsupported;
+
+ if (lp->fixed_speed != SPEED_UNKNOWN)
+ goto autoneg_unsupported;
+
+ if (!(sup & SUPPORTED_Autoneg) ||
+ !(flow_ctr & AMBARELLA_ETH_FC_AUTONEG))
+ goto autoneg_unsupported;
+
+ if (flow_ctr & AMBARELLA_ETH_FC_RX) {
+ /*
+ * Being able to decode pause frames is sufficently to
+ * advertise that we support both sym. and asym. pause.
+ * It doesn't matter if send pause frame or not.
+ */
+ adv |= (ADVERTISED_Pause | ADVERTISED_Asym_Pause);
+ goto done;
+ }
+
+ if (flow_ctr & AMBARELLA_ETH_FC_TX) {
+ /* Tell the link parter that we do send the pause frame. */
+ adv |= ADVERTISED_Asym_Pause;
+ goto done;
+ }
+ goto done;
+
+autoneg_unsupported:
+ /* Sanitize the config value */
+ lp->flow_ctr &= ~AMBARELLA_ETH_FC_AUTONEG;
+
+ /* Advertise nothing about pause frame */
+ adv &= ~(ADVERTISED_Pause | ADVERTISED_Asym_Pause);
+ goto done;
+
+unsupported:
+ /* Sanitize the config value */
+ lp->flow_ctr &= ~(AMBARELLA_ETH_FC_AUTONEG |
+ AMBARELLA_ETH_FC_RX |
+ AMBARELLA_ETH_FC_TX);
+done:
+ lp->phydev->advertising = adv;
+ lp->phydev->supported = sup;
+ dev_info(&lp->ndev->dev, "adv: sym %d, asym: %d\n",
+ !!(adv & ADVERTISED_Pause),
+ !!(adv & ADVERTISED_Asym_Pause));
+}
+
+static void ambeth_fc_resolve(struct ambeth_info *lp)
+{
+ u32 flow_ctr, fc, old_fc;
+
+ flow_ctr = lp->flow_ctr;
+
+ if (!(flow_ctr & AMBARELLA_ETH_FC_AUTONEG))
+ goto force_setting;
+
+ fc = old_fc = amba_readl(lp->regbase + ETH_MAC_FLOW_CTR_OFFSET);
+
+ dev_info(&lp->ndev->dev, "lp: sym: %d, asym: %d\n",
+ lp->phydev->pause, lp->phydev->asym_pause);
+ /*
+ * Decode pause frames only if user specified, and the link
+ * partner could send them on the same time.
+ */
+ if ((flow_ctr & AMBARELLA_ETH_FC_RX) &&
+ (lp->phydev->pause || lp->phydev->asym_pause))
+ fc |= ETH_MAC_FLOW_CTR_RFE;
+ else
+ fc &= ~ETH_MAC_FLOW_CTR_RFE;
+
+ /*
+ * Send pause frames only if user specified, and the link
+ * partner can resopnds to them on the same time.
+ */
+ if ((flow_ctr & AMBARELLA_ETH_FC_TX) && lp->phydev->pause)
+ fc |= ETH_MAC_FLOW_CTR_TFE;
+ else
+ fc &= ~ETH_MAC_FLOW_CTR_TFE;
+
+ if (fc != old_fc)
+ amba_writel(lp->regbase + ETH_MAC_FLOW_CTR_OFFSET, fc);
+
+ return;
+
+force_setting:
+
+ if (flow_ctr & AMBARELLA_ETH_FC_TX)
+ amba_setbitsl(lp->regbase + ETH_MAC_FLOW_CTR_OFFSET,
+ ETH_MAC_FLOW_CTR_TFE);
+
+ if (flow_ctr & AMBARELLA_ETH_FC_RX)
+ amba_setbitsl(lp->regbase + ETH_MAC_FLOW_CTR_OFFSET,
+ ETH_MAC_FLOW_CTR_RFE);
+}
+
+static int ambeth_phy_start(struct ambeth_info *lp)
+{
+ struct net_device *ndev = lp->ndev;
+ struct phy_device *phydev = lp->phydev;
+ phy_interface_t intf;
+ int ret_val = 0;
+ unsigned long flags;
+
+ if (lp->phy_enabled)
+ return 0;
+
+ lp->oldlink = PHY_DOWN;
+ lp->oldspeed = 0;
+ lp->oldduplex = -1;
+
+ /* Fixed Link mode: we allow all valid fixed_speed,
+ even HW can not support the speed. */
+ switch (lp->fixed_speed) {
+ case SPEED_1000:
+ case SPEED_100:
+ case SPEED_10:
+ lp->oldlink = PHY_RUNNING;
+ lp->oldspeed = lp->fixed_speed;
+ lp->oldduplex = DUPLEX_FULL;
+ ambhw_set_link_mode_speed(lp);
+ dev_notice(&lp->ndev->dev, "Fixed Link - %d/%s\n", lp->oldspeed,
+ ((lp->oldduplex == DUPLEX_FULL) ? "Full" : "Half"));
+ netif_carrier_on(ndev);
+ goto ambeth_init_phy_exit;
+ break;
+ default:
+ break;
+ }
+
+ intf = ambhw_get_interface(lp);
+ ret_val = phy_connect_direct(ndev, phydev, &ambeth_adjust_link, intf);
+ if (ret_val) {
+ dev_err(&lp->ndev->dev, "Could not attach to PHY!\n");
+ goto ambeth_init_phy_exit;
+ }
+
+ phydev->supported &= lp->phy_supported;
+ phydev->advertising = phydev->supported;
+
+ spin_lock_irqsave(&lp->lock, flags);
+ lp->phy_enabled = 1;
+ spin_unlock_irqrestore(&lp->lock, flags);
+
+ ambeth_fc_config(lp);
+ ret_val = phy_start_aneg(phydev);
+
+ ambeth_fc_resolve(lp);
+
+ambeth_init_phy_exit:
+ return ret_val;
+}
+
+static void ambeth_phy_stop(struct ambeth_info *lp)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&lp->lock, flags);
+ lp->phy_enabled = 0;
+ lp->oldlink = PHY_DOWN;
+ spin_unlock_irqrestore(&lp->lock, flags);
+
+ phy_disconnect(lp->phydev);
+}
+
+static inline int ambeth_rx_rngmng_check_skb(struct ambeth_info *lp, u32 entry)
+{
+ int ret_val = 0;
+ dma_addr_t mapping;
+ struct sk_buff *skb;
+
+ if (lp->rx.rng_rx[entry].skb == NULL) {
+ skb = netdev_alloc_skb(lp->ndev, AMBETH_PACKET_MAXFRAME);
+ if (skb == NULL) {
+ if (netif_msg_drv(lp))
+ dev_err(&lp->ndev->dev,
+ "RX Error: netdev_alloc_skb.\n");
+ ret_val = -ENOMEM;
+ goto ambeth_rx_rngmng_skb_exit;
+ }
+ mapping = dma_map_single(&lp->ndev->dev, skb->data,
+ AMBETH_PACKET_MAXFRAME, DMA_FROM_DEVICE);
+ lp->rx.rng_rx[entry].skb = skb;
+ lp->rx.rng_rx[entry].mapping = mapping;
+ lp->rx.desc_rx[entry].buffer1 = mapping;
+ }
+
+ambeth_rx_rngmng_skb_exit:
+ return ret_val;
+}
+
+static inline void ambeth_rx_rngmng_init(struct ambeth_info *lp)
+{
+ int i;
+
+ lp->rx.cur_rx = 0;
+ lp->rx.dirty_rx = 0;
+ for (i = 0; i < lp->rx_count; i++) {
+ if (ambeth_rx_rngmng_check_skb(lp, i))
+ break;
+ lp->rx.desc_rx[i].status = ETH_RDES0_OWN;
+ lp->rx.desc_rx[i].length = (ETH_RDES1_RCH |
+ ETH_RDES1_RBS1x(AMBETH_PACKET_MAXFRAME));
+ lp->rx.desc_rx[i].buffer2 = (u32)lp->rx_dma_desc +
+ ((i + 1) * sizeof(struct ambeth_desc));
+ }
+ lp->rx.desc_rx[lp->rx_count - 1].buffer2 = (u32)lp->rx_dma_desc;
+}
+
+static inline void ambeth_rx_rngmng_refill(struct ambeth_info *lp)
+{
+ u32 i;
+ unsigned int dirty_diff;
+ u32 entry;
+
+ dirty_diff = (lp->rx.cur_rx - lp->rx.dirty_rx);
+ for (i = 0; i < dirty_diff; i++) {
+ entry = lp->rx.dirty_rx % lp->rx_count;
+ if (ambeth_rx_rngmng_check_skb(lp, entry))
+ break;
+ lp->rx.desc_rx[entry].status = ETH_RDES0_OWN;
+ lp->rx.dirty_rx++;
+ }
+}
+
+static inline void ambeth_rx_rngmng_del(struct ambeth_info *lp)
+{
+ int i;
+ dma_addr_t mapping;
+ struct sk_buff *skb;
+
+ for (i = 0; i < lp->rx_count; i++) {
+ if (lp->rx.rng_rx) {
+ skb = lp->rx.rng_rx[i].skb;
+ mapping = lp->rx.rng_rx[i].mapping;
+ lp->rx.rng_rx[i].skb = NULL;
+ lp->rx.rng_rx[i].mapping = 0;
+ if (mapping) {
+ dma_unmap_single(&lp->ndev->dev, mapping,
+ AMBETH_PACKET_MAXFRAME,
+ DMA_FROM_DEVICE);
+ }
+ if (skb) {
+ dev_kfree_skb(skb);
+ }
+ }
+ if (lp->rx.desc_rx) {
+ lp->rx.desc_rx[i].status = 0;
+ lp->rx.desc_rx[i].length = 0;
+ lp->rx.desc_rx[i].buffer1 = 0xBADF00D0;
+ lp->rx.desc_rx[i].buffer2 = 0xBADF00D0;
+ }
+ }
+}
+
+static inline void ambeth_tx_rngmng_init(struct ambeth_info *lp)
+{
+ u32 i;
+
+ lp->tx.cur_tx = 0;
+ lp->tx.dirty_tx = 0;
+ for (i = 0; i < lp->tx_count; i++) {
+ lp->tx.rng_tx[i].mapping = 0;
+ lp->tx.desc_tx[i].length = 0;
+ amba_set_eth_desc(&lp->tx.desc_tx[i], ETH_TDES_LS | ETH_TDES_FS
+ | ETH_TDES_TCH);
+ lp->tx.desc_tx[i].buffer1 = 0;
+ lp->tx.desc_tx[i].buffer2 = (u32)lp->tx_dma_desc +
+ ((i + 1) * sizeof(struct ambeth_desc));
+ }
+ lp->tx.desc_tx[lp->tx_count - 1].buffer2 = (u32)lp->tx_dma_desc;
+}
+
+static inline void ambeth_tx_rngmng_del(struct ambeth_info *lp)
+{
+ u32 i;
+ dma_addr_t mapping;
+ struct sk_buff *skb;
+
+ for (i = 0; i < lp->tx_count; i++) {
+ if (lp->tx.rng_tx) {
+ skb = lp->tx.rng_tx[i].skb;
+ mapping = lp->tx.rng_tx[i].mapping;
+ lp->tx.rng_tx[i].skb = NULL;
+ lp->tx.rng_tx[i].mapping = 0;
+ if (skb) {
+ dma_unmap_single(&lp->ndev->dev, mapping,
+ skb->len, DMA_TO_DEVICE);
+ dev_kfree_skb(skb);
+ }
+ }
+ if (lp->tx.desc_tx) {
+ lp->tx.desc_tx[i].status = 0;
+ lp->tx.desc_tx[i].length = 0;
+ lp->tx.desc_tx[i].buffer1 = 0xBADF00D0;
+ lp->tx.desc_tx[i].buffer2 = 0xBADF00D0;
+ }
+ }
+}
+
+static inline void ambeth_check_dma_error(struct ambeth_info *lp,
+ u32 irq_status)
+{
+ u32 miss_ov = 0;
+
+ if (unlikely(irq_status & ETH_DMA_STATUS_AIS)) {
+ if (irq_status & (ETH_DMA_STATUS_RU | ETH_DMA_STATUS_OVF))
+ miss_ov = amba_readl(lp->regbase +
+ ETH_DMA_MISS_FRAME_BOCNT_OFFSET);
+
+ if (irq_status & ETH_DMA_STATUS_FBI) {
+ if (netif_msg_drv(lp))
+ dev_err(&lp->ndev->dev,
+ "DMA Error: Fatal Bus Error 0x%x.\n",
+ (irq_status & ETH_DMA_STATUS_EB_MASK));
+ }
+ if (irq_status & ETH_DMA_STATUS_ETI) {
+ if (netif_msg_tx_err(lp))
+ dev_err(&lp->ndev->dev,
+ "DMA Error: Early Transmit.\n");
+ }
+ if (irq_status & ETH_DMA_STATUS_RWT) {
+ if (netif_msg_rx_err(lp))
+ dev_err(&lp->ndev->dev,
+ "DMA Error: Receive Watchdog Timeout.\n");
+ }
+ if (irq_status & ETH_DMA_STATUS_RPS) {
+ if (netif_msg_rx_err(lp))
+ dev_err(&lp->ndev->dev,
+ "DMA Error: Receive Process Stopped.\n");
+ }
+ if (irq_status & ETH_DMA_STATUS_RU) {
+ if (miss_ov & ETH_DMA_MISS_FRAME_BOCNT_FRAME) {
+ lp->stats.rx_dropped +=
+ ETH_DMA_MISS_FRAME_BOCNT_HOST(miss_ov);
+ }
+ if (netif_msg_rx_err(lp))
+ dev_err(&lp->ndev->dev,
+ "DMA Error: Receive Buffer Unavailable, %u.\n",
+ ETH_DMA_MISS_FRAME_BOCNT_HOST(miss_ov));
+ }
+ if (irq_status & ETH_DMA_STATUS_UNF) {
+ if (netif_msg_tx_err(lp))
+ dev_err(&lp->ndev->dev,
+ "DMA Error: Transmit Underflow.\n");
+ }
+ if (irq_status & ETH_DMA_STATUS_OVF) {
+ if (miss_ov & ETH_DMA_MISS_FRAME_BOCNT_FIFO) {
+ lp->stats.rx_fifo_errors +=
+ ETH_DMA_MISS_FRAME_BOCNT_APP(miss_ov);
+ }
+ if (netif_msg_rx_err(lp))
+ dev_err(&lp->ndev->dev,
+ "DMA Error: Receive FIFO Overflow, %u.\n",
+ ETH_DMA_MISS_FRAME_BOCNT_APP(miss_ov));
+ }
+ if (irq_status & ETH_DMA_STATUS_TJT) {
+ lp->stats.tx_errors++;
+ if (netif_msg_drv(lp))
+ dev_err(&lp->ndev->dev,
+ "DMA Error: Transmit Jabber Timeout.\n");
+ }
+ if (irq_status & ETH_DMA_STATUS_TPS) {
+ if (netif_msg_tx_err(lp))
+ dev_err(&lp->ndev->dev,
+ "DMA Error: Transmit Process Stopped.\n");
+ }
+ if (netif_msg_tx_err(lp) || netif_msg_rx_err(lp)) {
+ dev_err(&lp->ndev->dev, "DMA Error: Abnormal: 0x%x.\n",
+ irq_status);
+ ambhw_dump(lp);
+ }
+ }
+}
+
+static inline void ambeth_pause_frame(struct ambeth_info *lp)
+{
+ u32 fc;
+
+ fc = amba_readl(lp->regbase + ETH_MAC_FLOW_CTR_OFFSET);
+ if (!(fc & ETH_MAC_FLOW_CTR_TFE))
+ return;
+
+ fc |= ETH_MAC_FLOW_CTR_FCBBPA;
+
+ amba_writel(lp->regbase + ETH_MAC_FLOW_CTR_OFFSET, fc);
+}
+
+static inline void ambeth_interrupt_rx(struct ambeth_info *lp, u32 irq_status)
+{
+ if (irq_status & AMBETH_RXDMA_STATUS) {
+ amba_clrbitsl(lp->regbase + ETH_DMA_INTEN_OFFSET,
+ AMBETH_RXDMA_INTEN);
+ napi_schedule(&lp->napi);
+ }
+}
+
+static inline void ambeth_interrupt_gmac(struct ambeth_info *lp, u32 irq_status)
+{
+ if(ETH_ENHANCED) {
+ u32 tmp_reg;
+
+ if (irq_status & ETH_DMA_STATUS_GPI) {
+ dev_vdbg(&lp->ndev->dev, "ETH_DMA_STATUS_GPI\n");
+ }
+ if (irq_status & ETH_DMA_STATUS_GMI) {
+ dev_vdbg(&lp->ndev->dev, "ETH_DMA_STATUS_GMI\n");
+ }
+ if (irq_status & ETH_DMA_STATUS_GLI) {
+ dev_vdbg(&lp->ndev->dev, "ETH_DMA_STATUS_GLI\n");
+ tmp_reg = amba_readl(lp->regbase +
+ ETH_MAC_INTERRUPT_STATUS_OFFSET);
+ dev_vdbg(&lp->ndev->dev,
+ "ETH_MAC_INTERRUPT_STATUS_OFFSET = 0x%08X\n",tmp_reg);
+ tmp_reg = amba_readl(lp->regbase +
+ ETH_MAC_INTERRUPT_MASK_OFFSET);
+ dev_vdbg(&lp->ndev->dev,
+ "ETH_MAC_INTERRUPT_MASK_OFFSET = 0x%08X\n",tmp_reg);
+ tmp_reg = amba_readl(lp->regbase +
+ ETH_MAC_AN_STATUS_OFFSET);
+ dev_vdbg(&lp->ndev->dev,
+ "ETH_MAC_AN_STATUS_OFFSET = 0x%08X\n",tmp_reg);
+ tmp_reg = amba_readl(lp->regbase +
+ ETH_MAC_RGMII_CS_OFFSET);
+ dev_vdbg(&lp->ndev->dev,
+ "ETH_MAC_RGMII_CS_OFFSET = 0x%08X\n",tmp_reg);
+ tmp_reg = amba_readl(lp->regbase +
+ ETH_MAC_GPIO_OFFSET);
+ dev_vdbg(&lp->ndev->dev,
+ "ETH_MAC_GPIO_OFFSET = 0x%08X\n",tmp_reg);
+ }
+
+ }
+}
+
+static inline u32 ambeth_check_tdes0_status(struct ambeth_info *lp,
+ unsigned int status)
+{
+ u32 tx_retry = 0;
+
+ if (status & ETH_TDES0_JT) {
+ lp->stats.tx_heartbeat_errors++;
+ if (netif_msg_drv(lp))
+ dev_err(&lp->ndev->dev, "TX Error: Jabber Timeout.\n");
+ }
+ if (status & ETH_TDES0_FF) {
+ lp->stats.tx_dropped++;
+ if (netif_msg_drv(lp))
+ dev_err(&lp->ndev->dev, "TX Error: Frame Flushed.\n");
+ }
+ if (status & ETH_TDES0_PCE) {
+ lp->stats.tx_fifo_errors++;
+ if (netif_msg_drv(lp))
+ dev_err(&lp->ndev->dev,
+ "TX Error: Payload Checksum Error.\n");
+ }
+ if (status & ETH_TDES0_LCA) {
+ lp->stats.tx_carrier_errors++;
+ dev_err(&lp->ndev->dev, "TX Error: Loss of Carrier.\n");
+ }
+ if (status & ETH_TDES0_NC) {
+ lp->stats.tx_carrier_errors++;
+ if (netif_msg_drv(lp))
+ dev_err(&lp->ndev->dev, "TX Error: No Carrier.\n");
+ }
+ if (status & ETH_TDES0_LCO) {
+ lp->stats.tx_aborted_errors++;
+ lp->stats.collisions++;
+ if (netif_msg_drv(lp))
+ dev_err(&lp->ndev->dev, "TX Error: Late Collision.\n");
+ }
+ if (status & ETH_TDES0_EC) {
+ lp->stats.tx_aborted_errors++;
+ lp->stats.collisions += ETH_TDES0_CC(status);
+ if (netif_msg_drv(lp))
+ dev_err(&lp->ndev->dev,
+ "TX Error: Excessive Collision %u.\n",
+ ETH_TDES0_CC(status));
+ }
+ if (status & ETH_TDES0_VF) {
+ if (netif_msg_drv(lp))
+ dev_info(&lp->ndev->dev, "TX Info: VLAN Frame.\n");
+ }
+ if (status & ETH_TDES0_ED) {
+ lp->stats.tx_fifo_errors++;
+ if (netif_msg_drv(lp))
+ dev_err(&lp->ndev->dev,
+ "TX Error: Excessive Deferral.\n");
+ }
+ if (status & ETH_TDES0_UF) {
+ tx_retry = 1;
+ if (netif_msg_tx_err(lp)) {
+ dev_err(&lp->ndev->dev, "TX Error: Underflow Error.\n");
+ ambhw_dump(lp);
+ }
+ }
+ if (status & ETH_TDES0_DB) {
+ lp->stats.tx_fifo_errors++;
+ if (netif_msg_drv(lp))
+ dev_err(&lp->ndev->dev, "TX Error: Deferred Bit.\n");
+ }
+
+ return tx_retry;
+}
+
+static inline void ambeth_interrupt_tx(struct ambeth_info *lp, u32 irq_status)
+{
+ u32 i;
+ unsigned int dirty_diff;
+ u32 entry;
+ u32 status;
+
+ if (irq_status & AMBETH_TXDMA_STATUS) {
+ dev_vdbg(&lp->ndev->dev, "cur_tx[%u], dirty_tx[%u], 0x%x.\n",
+ lp->tx.cur_tx, lp->tx.dirty_tx, irq_status);
+ dirty_diff = (lp->tx.cur_tx - lp->tx.dirty_tx);
+ for (i = 0; i < dirty_diff; i++) {
+ entry = (lp->tx.dirty_tx % lp->tx_count);
+ status = lp->tx.desc_tx[entry].status;
+
+ if (status & ETH_TDES0_OWN)
+ break;
+
+ if (unlikely(status & ETH_TDES0_ES)) {
+ if ((status & ETH_TDES0_ES_MASK) ==
+ ETH_TDES0_ES) {
+ break;
+ }
+ if (ambeth_check_tdes0_status(lp, status)) {
+ ambhw_dma_tx_stop(lp);
+ ambhw_dma_tx_restart(lp, entry);
+ ambhw_dma_tx_poll(lp);
+ break;
+ } else {
+ lp->stats.tx_errors++;
+ }
+ } else {
+ if (unlikely(status & ETH_TDES0_IHE)) {
+ if (netif_msg_drv(lp))
+ dev_err(&lp->ndev->dev,
+ "TX Error: IP Header Error.\n");
+ }
+ lp->stats.tx_bytes +=
+ lp->tx.rng_tx[entry].skb->len;
+ lp->stats.tx_packets++;
+ }
+
+ dma_unmap_single(&lp->ndev->dev,
+ lp->tx.rng_tx[entry].mapping,
+ lp->tx.rng_tx[entry].skb->len,
+ DMA_TO_DEVICE);
+ dev_kfree_skb_irq(lp->tx.rng_tx[entry].skb);
+ lp->tx.rng_tx[entry].skb = NULL;
+ lp->tx.rng_tx[entry].mapping = 0;
+ lp->tx.dirty_tx++;
+ }
+ dirty_diff = (lp->tx.cur_tx - lp->tx.dirty_tx);
+ if (dirty_diff && (irq_status & ETH_DMA_STATUS_TU)) {
+ ambhw_dma_tx_poll(lp);
+ }
+ if (likely(dirty_diff < lp->tx_irq_low)) {
+ netif_wake_queue(lp->ndev);
+ }
+ dev_vdbg(&lp->ndev->dev, "cur_tx[%u], dirty_tx[%u], 0x%x.\n",
+ lp->tx.cur_tx, lp->tx.dirty_tx, irq_status);
+ }
+}
+
+static irqreturn_t ambeth_interrupt(int irq, void *dev_id)
+{
+ struct net_device *ndev;
+ struct ambeth_info *lp;
+ u32 irq_status;
+ unsigned long flags;
+
+ ndev = (struct net_device *)dev_id;
+ lp = netdev_priv(ndev);
+
+ spin_lock_irqsave(&lp->lock, flags);
+ irq_status = amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET);
+ ambeth_check_dma_error(lp, irq_status);
+ ambeth_interrupt_gmac(lp, irq_status);
+ ambeth_interrupt_rx(lp, irq_status);
+ ambeth_interrupt_tx(lp, irq_status);
+ amba_writel(lp->regbase + ETH_DMA_STATUS_OFFSET, irq_status);
+ spin_unlock_irqrestore(&lp->lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+static int ambeth_start_hw(struct net_device *ndev)
+{
+ int ret_val = 0;
+ struct ambeth_info *lp;
+ unsigned long flags;
+
+ lp = (struct ambeth_info *)netdev_priv(ndev);
+
+ if (gpio_is_valid(lp->pwr_gpio))
+ gpio_set_value_cansleep(lp->pwr_gpio, lp->pwr_gpio_active);
+ if (gpio_is_valid(lp->rst_gpio)) {
+ gpio_set_value_cansleep(lp->rst_gpio, lp->rst_gpio_active);
+ msleep(200);
+ gpio_set_value_cansleep(lp->rst_gpio, !lp->rst_gpio_active);
+ }
+
+ spin_lock_irqsave(&lp->lock, flags);
+ ret_val = ambhw_enable(lp);
+ spin_unlock_irqrestore(&lp->lock, flags);
+ if (ret_val)
+ goto ambeth_start_hw_exit;
+
+ lp->rx.rng_rx = kmalloc((sizeof(struct ambeth_rng_info) *
+ lp->rx_count), GFP_KERNEL);
+ if (lp->rx.rng_rx == NULL) {
+ if (netif_msg_drv(lp))
+ dev_err(&lp->ndev->dev, "alloc rng_rx fail.\n");
+ ret_val = -ENOMEM;
+ goto ambeth_start_hw_exit;
+ }
+ lp->rx.desc_rx = dma_alloc_coherent(&lp->ndev->dev,
+ (sizeof(struct ambeth_desc) * lp->rx_count),
+ &lp->rx_dma_desc, GFP_KERNEL);
+ if (lp->rx.desc_rx == NULL) {
+ if (netif_msg_drv(lp))
+ dev_err(&lp->ndev->dev,
+ "dma_alloc_coherent desc_rx fail.\n");
+ ret_val = -ENOMEM;
+ goto ambeth_start_hw_exit;
+ }
+ memset(lp->rx.rng_rx, 0,
+ (sizeof(struct ambeth_rng_info) * lp->rx_count));
+ memset(lp->rx.desc_rx, 0,
+ (sizeof(struct ambeth_desc) * lp->rx_count));
+ ambeth_rx_rngmng_init(lp);
+
+ lp->tx.rng_tx = kmalloc((sizeof(struct ambeth_rng_info) *
+ lp->tx_count), GFP_KERNEL);
+ if (lp->tx.rng_tx == NULL) {
+ if (netif_msg_drv(lp))
+ dev_err(&lp->ndev->dev, "alloc rng_tx fail.\n");
+ ret_val = -ENOMEM;
+ goto ambeth_start_hw_exit;
+ }
+ lp->tx.desc_tx = dma_alloc_coherent(&lp->ndev->dev,
+ (sizeof(struct ambeth_desc) * lp->tx_count),
+ &lp->tx_dma_desc, GFP_KERNEL);
+ if (lp->tx.desc_tx == NULL) {
+ if (netif_msg_drv(lp))
+ dev_err(&lp->ndev->dev,
+ "dma_alloc_coherent desc_tx fail.\n");
+ ret_val = -ENOMEM;
+ goto ambeth_start_hw_exit;
+ }
+ memset(lp->tx.rng_tx, 0,
+ (sizeof(struct ambeth_rng_info) * lp->tx_count));
+ memset(lp->tx.desc_tx, 0,
+ (sizeof(struct ambeth_desc) * lp->tx_count));
+ ambeth_tx_rngmng_init(lp);
+
+ spin_lock_irqsave(&lp->lock, flags);
+ ambhw_set_dma_desc(lp);
+ ambhw_dma_rx_start(lp);
+ ambhw_dma_tx_start(lp);
+ spin_unlock_irqrestore(&lp->lock, flags);
+
+ambeth_start_hw_exit:
+ return ret_val;
+}
+
+static void ambeth_stop_hw(struct net_device *ndev)
+{
+ struct ambeth_info *lp;
+ unsigned long flags;
+
+ lp = (struct ambeth_info *)netdev_priv(ndev);
+
+ spin_lock_irqsave(&lp->lock, flags);
+ ambhw_disable(lp);
+ spin_unlock_irqrestore(&lp->lock, flags);
+
+ ambeth_tx_rngmng_del(lp);
+ if (lp->tx.desc_tx) {
+ dma_free_coherent(&lp->ndev->dev,
+ (sizeof(struct ambeth_desc) * lp->tx_count),
+ lp->tx.desc_tx, lp->tx_dma_desc);
+ lp->tx.desc_tx = NULL;
+ }
+ if (lp->tx.rng_tx) {
+ kfree(lp->tx.rng_tx);
+ lp->tx.rng_tx = NULL;
+ }
+
+ ambeth_rx_rngmng_del(lp);
+ if (lp->rx.desc_rx) {
+ dma_free_coherent(&lp->ndev->dev,
+ (sizeof(struct ambeth_desc) * lp->rx_count),
+ lp->rx.desc_rx, lp->rx_dma_desc);
+ lp->rx.desc_rx = NULL;
+ }
+ if (lp->rx.rng_rx) {
+ kfree(lp->rx.rng_rx);
+ lp->rx.rng_rx = NULL;
+ }
+
+ if (gpio_is_valid(lp->pwr_gpio))
+ gpio_set_value_cansleep(lp->pwr_gpio, !lp->pwr_gpio_active);
+ if (gpio_is_valid(lp->rst_gpio))
+ gpio_set_value_cansleep(lp->rst_gpio, lp->rst_gpio_active);
+}
+
+static int ambeth_open(struct net_device *ndev)
+{
+ int ret_val = 0;
+ struct ambeth_info *lp;
+
+ lp = (struct ambeth_info *)netdev_priv(ndev);
+
+ ret_val = ambeth_start_hw(ndev);
+ if (ret_val)
+ goto ambeth_open_exit;
+
+ ret_val = request_irq(ndev->irq, ambeth_interrupt,
+ IRQF_SHARED | IRQF_TRIGGER_HIGH, ndev->name, ndev);
+ if (ret_val) {
+ if (netif_msg_drv(lp))
+ dev_err(&lp->ndev->dev,
+ "Request_irq[%d] fail.\n", ndev->irq);
+ goto ambeth_open_exit;
+ }
+
+ napi_enable(&lp->napi);
+ netif_start_queue(ndev);
+ ambhw_dma_int_enable(lp);
+
+ netif_carrier_off(ndev);
+ ret_val = ambeth_phy_start(lp);
+ if (ret_val) {
+ netif_stop_queue(ndev);
+ napi_disable(&lp->napi);
+ free_irq(ndev->irq, ndev);
+ }
+
+ambeth_open_exit:
+ if (ret_val) {
+ ambeth_stop_hw(ndev);
+ }
+
+ return ret_val;
+}
+
+static int ambeth_stop(struct net_device *ndev)
+{
+ struct ambeth_info *lp = netdev_priv(ndev);
+ int ret_val = 0;
+
+ netif_stop_queue(ndev);
+ napi_disable(&lp->napi);
+ free_irq(ndev->irq, ndev);
+ ambeth_phy_stop(lp);
+ netif_carrier_off(ndev);
+ ambeth_stop_hw(ndev);
+
+ return ret_val;
+}
+
+static int ambeth_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+ int ret_val = 0;
+ struct ambeth_info *lp;
+ dma_addr_t mapping;
+ u32 entry;
+ unsigned int dirty_diff;
+ u32 tx_flag;
+ unsigned long flags;
+
+ lp = (struct ambeth_info *)netdev_priv(ndev);
+ tx_flag = ETH_TDES_LS | ETH_TDES_FS | ETH_TDES_TCH;
+
+ spin_lock_irqsave(&lp->lock, flags);
+ dirty_diff = (lp->tx.cur_tx - lp->tx.dirty_tx);
+ entry = (lp->tx.cur_tx % lp->tx_count);
+ if (dirty_diff == lp->tx_irq_high) {
+ tx_flag |= ETH_TDES_IC;
+ } else if (dirty_diff == (lp->tx_count - 1)) {
+ netif_stop_queue(ndev);
+ tx_flag |= ETH_TDES_IC;
+ } else if (dirty_diff >= lp->tx_count) {
+ netif_stop_queue(ndev);
+ ret_val = -ENOMEM;
+ ambhw_dma_tx_poll(lp);
+ spin_unlock_irqrestore(&lp->lock, flags);
+ dev_err(&lp->ndev->dev, "TX Error: TX OV.\n");
+ goto ambeth_hard_start_xmit_exit;
+ }
+ if (unlikely(lp->dump_tx))
+ ambhw_dump_buffer(__func__, skb->data, skb->len);
+
+ mapping = dma_map_single(&lp->ndev->dev,
+ skb->data, skb->len, DMA_TO_DEVICE);
+ if (lp->ipc_tx && (skb->ip_summed == CHECKSUM_PARTIAL)) {
+ tx_flag |= ETH_TDES_CIC;
+ }
+
+ lp->tx.rng_tx[entry].skb = skb;
+ lp->tx.rng_tx[entry].mapping = mapping;
+ lp->tx.desc_tx[entry].buffer1 = mapping;
+ lp->tx.desc_tx[entry].length = ETH_TDES1_TBS1x(skb->len);
+ lp->tx.desc_tx[entry].status = 0;
+ amba_set_eth_desc(&lp->tx.desc_tx[entry], tx_flag);
+ lp->tx.desc_tx[entry].status |= ETH_TDES0_OWN;
+
+ lp->tx.cur_tx++;
+ ambhw_dma_tx_poll(lp);
+ spin_unlock_irqrestore(&lp->lock, flags);
+
+ ndev->trans_start = jiffies;
+ dev_vdbg(&lp->ndev->dev, "TX Info: cur_tx[%u], dirty_tx[%u], "
+ "entry[%u], len[%u], data_len[%u], ip_summed[%u], "
+ "csum_start[%u], csum_offset[%u].\n",
+ lp->tx.cur_tx, lp->tx.dirty_tx, entry, skb->len, skb->data_len,
+ skb->ip_summed, skb->csum_start, skb->csum_offset);
+
+ambeth_hard_start_xmit_exit:
+ return ret_val;
+}
+
+static void ambeth_timeout(struct net_device *ndev)
+{
+ struct ambeth_info *lp;
+ unsigned long flags;
+ u32 irq_status;
+
+ lp = (struct ambeth_info *)netdev_priv(ndev);
+
+ dev_info(&lp->ndev->dev, "OOM Info:...\n");
+ spin_lock_irqsave(&lp->lock, flags);
+ irq_status = amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET);
+ ambeth_interrupt_tx(lp, irq_status | AMBETH_TXDMA_STATUS);
+ ambhw_dump(lp);
+ spin_unlock_irqrestore(&lp->lock, flags);
+
+ netif_wake_queue(ndev);
+}
+
+static struct net_device_stats *ambeth_get_stats(struct net_device *ndev)
+{
+ struct ambeth_info *lp = netdev_priv(ndev);
+
+ return &lp->stats;
+}
+
+static void ambhw_dump_rx(struct ambeth_info *lp, u32 status, u32 entry)
+{
+ short pkt_len;
+ struct sk_buff *skb;
+ dma_addr_t mapping;
+
+ pkt_len = ETH_RDES0_FL(status) - 4;
+ if (unlikely(pkt_len > AMBETH_RX_COPYBREAK)) {
+ dev_warn(&lp->ndev->dev, "Bogus packet size %u.\n", pkt_len);
+ pkt_len = AMBETH_RX_COPYBREAK;
+ }
+
+ skb = lp->rx.rng_rx[entry].skb;
+ mapping = lp->rx.rng_rx[entry].mapping;
+ if (likely(skb && mapping)) {
+ dma_unmap_single(&lp->ndev->dev, mapping,
+ AMBETH_PACKET_MAXFRAME, DMA_FROM_DEVICE);
+ skb_put(skb, pkt_len);
+ lp->rx.rng_rx[entry].skb = NULL;
+ lp->rx.rng_rx[entry].mapping = 0;
+ ambhw_dump_buffer(__func__, skb->data, skb->len);
+ dev_kfree_skb(skb);
+ }
+}
+
+static inline void ambeth_check_rdes0_status(struct ambeth_info *lp,
+ u32 status, u32 entry)
+{
+ if (status & ETH_RDES0_DE) {
+ lp->stats.rx_frame_errors++;
+ if (netif_msg_drv(lp))
+ dev_err(&lp->ndev->dev,
+ "RX Error: Descriptor Error.\n");
+ }
+ if (status & ETH_RDES0_SAF) {
+ if (netif_msg_drv(lp))
+ dev_err(&lp->ndev->dev,
+ "RX Error: Source Address Filter Fail.\n");
+ }
+ if (status & ETH_RDES0_LE) {
+ lp->stats.rx_length_errors++;
+ if (netif_msg_drv(lp))
+ dev_err(&lp->ndev->dev, "RX Error: Length Error.\n");
+ }
+ if (status & ETH_RDES0_OE) {
+ lp->stats.rx_over_errors++;
+ if (netif_msg_rx_err(lp))
+ dev_err(&lp->ndev->dev, "RX Error: Overflow Error.\n");
+ }
+ if (status & ETH_RDES0_VLAN) {
+ if (netif_msg_drv(lp))
+ dev_info(&lp->ndev->dev, "RX Info: VLAN.\n");
+ }
+ if (status & ETH_RDES0_IPC) {
+ if (netif_msg_drv(lp))
+ dev_err(&lp->ndev->dev,
+ "RX Error: IPC Checksum/Giant Frame.\n");
+ }
+ if (status & ETH_RDES0_LC) {
+ lp->stats.collisions++;
+ if (netif_msg_drv(lp))
+ dev_err(&lp->ndev->dev, "RX Error: Late Collision.\n");
+ }
+ if (status & ETH_RDES0_FT) {
+ if (netif_msg_rx_err(lp))
+ dev_info(&lp->ndev->dev,
+ "RX Info: Ethernet-type frame.\n");
+ }
+ if (status & ETH_RDES0_RWT) {
+ if (netif_msg_drv(lp))
+ dev_err(&lp->ndev->dev,
+ "RX Error: Watchdog Timeout.\n");
+ }
+ if (status & ETH_RDES0_RE) {
+ lp->stats.rx_errors++;
+ if (netif_msg_rx_err(lp))
+ dev_err(&lp->ndev->dev, "RX Error: Receive.\n");
+ }
+ if (status & ETH_RDES0_DBE) {
+ if (amba_tstbitsl(lp->regbase + ETH_MAC_CFG_OFFSET,
+ ETH_MAC_CFG_PS)) {
+ lp->stats.rx_length_errors++;
+ if (netif_msg_drv(lp))
+ dev_err(&lp->ndev->dev,
+ "RX Error: Dribble Bit.\n");
+ }
+ }
+ if (status & ETH_RDES0_CE) {
+ lp->stats.rx_crc_errors++;
+ if (netif_msg_rx_err(lp)) {
+ dev_err(&lp->ndev->dev, "RX Error: CRC.\n");
+ }
+ }
+ if (status & ETH_RDES0_RX) {
+ if (netif_msg_drv(lp)) {
+ dev_err(&lp->ndev->dev,
+ "RX Error: Rx MAC Address/Payload Checksum.\n");
+ if (lp->dump_rx)
+ ambhw_dump_rx(lp, status, entry);
+ }
+ }
+}
+
+static inline void ambeth_napi_rx(struct ambeth_info *lp, u32 status, u32 entry)
+{
+ short pkt_len;
+ struct sk_buff *skb;
+ dma_addr_t mapping;
+
+ pkt_len = ETH_RDES0_FL(status) - 4;
+ skb = lp->rx.rng_rx[entry].skb;
+ mapping = lp->rx.rng_rx[entry].mapping;
+ if (likely(skb && mapping)) {
+ dma_unmap_single(&lp->ndev->dev, mapping,
+ AMBETH_PACKET_MAXFRAME, DMA_FROM_DEVICE);
+ skb_put(skb, pkt_len);
+ skb->protocol = eth_type_trans(skb, lp->ndev);
+ if(ETH_ENHANCED == 0) {
+ if (lp->ipc_rx) {
+ if ((status & ETH_RDES0_COE_MASK) ==
+ ETH_RDES0_COE_NOCHKERROR) {
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ } else {
+ skb->ip_summed = CHECKSUM_NONE;
+ if (netif_msg_rx_err(lp)) {
+ dev_err(&lp->ndev->dev,
+ "RX Error: RDES0_COE[0x%x].\n", status);
+ }
+ }
+ }
+
+ }
+
+ if (unlikely(lp->dump_rx)) {
+ ambhw_dump_buffer(__func__, (skb->data - 14),
+ (skb->len + 14));
+ }
+ if (unlikely(lp->dump_rx_free))
+ kfree_skb(skb);
+ else
+ netif_receive_skb(skb);
+
+ lp->rx.rng_rx[entry].skb = NULL;
+ lp->rx.rng_rx[entry].mapping = 0;
+ lp->ndev->last_rx = jiffies;
+ lp->stats.rx_packets++;
+ lp->stats.rx_bytes += pkt_len;
+ lp->rx.cur_rx++;
+ } else {
+ if (netif_msg_drv(lp)) {
+ dev_err(&lp->ndev->dev,
+ "RX Error: %u skb[%p], map[0x%08X].\n",
+ entry, skb, mapping);
+ }
+ }
+}
+
+int ambeth_napi(struct napi_struct *napi, int budget)
+{
+ int rx_budget = budget;
+ struct ambeth_info *lp;
+ u32 entry;
+ u32 status;
+ unsigned long flags;
+ unsigned int dirty_diff;
+ short pkt_len;
+
+ lp = container_of(napi, struct ambeth_info, napi);
+ dev_vdbg(&lp->ndev->dev, "cur_rx[%u], dirty_rx[%u]\n",
+ lp->rx.cur_rx, lp->rx.dirty_rx);
+
+ if (unlikely(!netif_carrier_ok(lp->ndev)))
+ goto ambeth_poll_complete;
+
+ while (rx_budget > 0) {
+ entry = lp->rx.cur_rx % lp->rx_count;
+ status = lp->rx.desc_rx[entry].status;
+ if (status & ETH_RDES0_OWN)
+ break;
+
+ pkt_len = ETH_RDES0_FL(status) - 4;
+ if (unlikely(pkt_len > AMBETH_RX_COPYBREAK)) {
+ dev_err(&lp->ndev->dev, "ambarella eth: jumbo frame[size:%d] received drop\n",
+ pkt_len);
+ ambhw_dma_rx_stop(lp);
+ ambeth_check_rdes0_status(lp, status, entry);
+ lp->rx.cur_rx++;
+ break;
+ }
+
+ if (unlikely((status & (ETH_RDES0_FS | ETH_RDES0_LS)) !=
+ (ETH_RDES0_FS | ETH_RDES0_LS))) {
+ break;
+ }
+ if (likely((status & ETH_RDES0_ES) != ETH_RDES0_ES)) {
+ ambeth_napi_rx(lp, status, entry);
+ } else {
+ ambhw_dma_rx_stop(lp);
+ ambeth_check_rdes0_status(lp, status, entry);
+ rx_budget += lp->rx_count;
+ lp->rx.cur_rx++;
+ }
+ rx_budget--;
+
+ dirty_diff = (lp->rx.cur_rx - lp->rx.dirty_rx);
+ if (dirty_diff > (lp->rx_count / 4)) {
+ ambeth_rx_rngmng_refill(lp);
+ }
+ }
+
+ambeth_poll_complete:
+ if (rx_budget > 0) {
+ ambeth_rx_rngmng_refill(lp);
+ spin_lock_irqsave(&lp->lock, flags);
+ napi_complete(&lp->napi);
+ amba_setbitsl(lp->regbase + ETH_DMA_INTEN_OFFSET,
+ AMBETH_RXDMA_INTEN);
+ ambhw_dma_rx_start(lp);
+ spin_unlock_irqrestore(&lp->lock, flags);
+ }
+
+ dev_vdbg(&lp->ndev->dev, "cur_rx[%u], dirty_rx[%u], rx_budget[%u]\n",
+ lp->rx.cur_rx, lp->rx.dirty_rx, rx_budget);
+ return (budget - rx_budget);
+}
+
+static inline u32 ambhw_hashtable_crc(unsigned char *mac)
+{
+ unsigned char tmpbuf[ETH_ALEN];
+ int i;
+ u32 crc;
+
+ for (i = 0; i < ETH_ALEN; i++)
+ tmpbuf[i] = bitrev8(mac[i]);
+ crc = crc32_be(~0, tmpbuf, ETH_ALEN);
+
+ return (crc ^ ~0);
+}
+
+static inline void ambhw_hashtable_get(struct net_device *ndev, u32 *hat)
+{
+ struct netdev_hw_addr *ha;
+ unsigned int bitnr;
+#if 0
+ unsigned char test1[] = {0x1F,0x52,0x41,0x9C,0xB6,0xAF};
+ unsigned char test2[] = {0xA0,0x0A,0x98,0x00,0x00,0x45};
+ dev_info(&ndev->dev,
+ "Test1: 0x%08X.\n", ambhw_hashtable_crc(test1));
+ dev_info(&ndev->dev,
+ "Test2: 0x%08X.\n", ambhw_hashtable_crc(test2));
+#endif
+
+ hat[0] = hat[1] = 0;
+ netdev_for_each_mc_addr(ha, ndev) {
+ if (!(ha->addr[0] & 1))
+ continue;
+ bitnr = ambhw_hashtable_crc(ha->addr);
+ bitnr >>= 26;
+ bitnr &= 0x3F;
+ hat[bitnr >> 5] |= 1 << (bitnr & 31);
+ }
+}
+
+static void ambeth_set_multicast_list(struct net_device *ndev)
+{
+ struct ambeth_info *lp;
+ unsigned int mac_filter;
+ u32 hat[2];
+ unsigned long flags;
+
+ lp = (struct ambeth_info *)netdev_priv(ndev);
+ spin_lock_irqsave(&lp->lock, flags);
+
+ mac_filter = amba_readl(lp->regbase + ETH_MAC_FRAME_FILTER_OFFSET);
+ hat[0] = 0;
+ hat[1] = 0;
+
+ if (ndev->flags & IFF_PROMISC) {
+ mac_filter |= ETH_MAC_FRAME_FILTER_PR;
+ } else if (ndev->flags & (~IFF_PROMISC)) {
+ mac_filter &= ~ETH_MAC_FRAME_FILTER_PR;
+ }
+
+ if (ndev->flags & IFF_ALLMULTI) {
+ hat[0] = 0xFFFFFFFF;
+ hat[1] = 0xFFFFFFFF;
+ mac_filter |= ETH_MAC_FRAME_FILTER_PM;
+ } else if (!netdev_mc_empty(ndev)) {
+ ambhw_hashtable_get(ndev, hat);
+ mac_filter &= ~ETH_MAC_FRAME_FILTER_PM;
+ mac_filter |= ETH_MAC_FRAME_FILTER_HMC;
+ } else if (ndev->flags & (~IFF_ALLMULTI)) {
+ mac_filter &= ~ETH_MAC_FRAME_FILTER_PM;
+ mac_filter |= ETH_MAC_FRAME_FILTER_HMC;
+ }
+
+ if (netif_msg_hw(lp)) {
+ dev_info(&lp->ndev->dev, "MC Info: flags 0x%x.\n", ndev->flags);
+ dev_info(&lp->ndev->dev, "MC Info: mc_count 0x%x.\n",
+ netdev_mc_count(ndev));
+ dev_info(&lp->ndev->dev, "MC Info: mac_filter 0x%x.\n",
+ mac_filter);
+ dev_info(&lp->ndev->dev, "MC Info: hat[0x%x:0x%x].\n",
+ hat[1], hat[0]);
+ }
+
+ amba_writel(lp->regbase + ETH_MAC_HASH_HI_OFFSET, hat[1]);
+ amba_writel(lp->regbase + ETH_MAC_HASH_LO_OFFSET, hat[0]);
+ amba_writel(lp->regbase + ETH_MAC_FRAME_FILTER_OFFSET, mac_filter);
+
+ spin_unlock_irqrestore(&lp->lock, flags);
+}
+
+static int ambeth_set_mac_address(struct net_device *ndev, void *addr)
+{
+ struct ambeth_info *lp = (struct ambeth_info *)netdev_priv(ndev);
+ struct sockaddr *saddr = addr;
+ unsigned long flags;
+
+ if (!is_valid_ether_addr(saddr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ spin_lock_irqsave(&lp->lock, flags);
+
+ if (netif_running(ndev)) {
+ spin_unlock_irqrestore(&lp->lock, flags);
+ return -EBUSY;
+ }
+
+ dev_dbg(&lp->ndev->dev, "MAC address[%pM].\n", saddr->sa_data);
+
+ memcpy(ndev->dev_addr, saddr->sa_data, ndev->addr_len);
+ ambhw_set_hwaddr(lp, ndev->dev_addr);
+ ambhw_get_hwaddr(lp, ndev->dev_addr);
+
+ spin_unlock_irqrestore(&lp->lock, flags);
+
+ return 0;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void ambeth_poll_controller(struct net_device *ndev)
+{
+ ambeth_interrupt(ndev->irq, ndev);
+}
+#endif
+
+static int ambeth_ioctl(struct net_device *ndev, struct ifreq *ifr, int ecmd)
+{
+ struct ambeth_info *lp = netdev_priv(ndev);
+
+ if (!netif_running(ndev))
+ return -EINVAL;
+
+ if (!lp->phydev)
+ return -ENODEV;
+
+ return phy_mii_ioctl(lp->phydev, ifr, ecmd);
+}
+
+static const struct net_device_ops ambeth_netdev_ops = {
+ .ndo_open = ambeth_open,
+ .ndo_stop = ambeth_stop,
+ .ndo_start_xmit = ambeth_hard_start_xmit,
+ .ndo_set_rx_mode = ambeth_set_multicast_list,
+ .ndo_set_mac_address = ambeth_set_mac_address,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_do_ioctl = ambeth_ioctl,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_tx_timeout = ambeth_timeout,
+ .ndo_get_stats = ambeth_get_stats,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = ambeth_poll_controller,
+#endif
+};
+
+/* ==========================================================================*/
+static int ambeth_get_settings(struct net_device *ndev,
+ struct ethtool_cmd *ecmd)
+{
+ struct ambeth_info *lp = netdev_priv(ndev);
+ int ret_val = 0;
+
+ if (!netif_running(ndev))
+ return -EINVAL;
+
+ if (lp->phy_enabled) {
+ ret_val = phy_ethtool_gset(lp->phydev, ecmd);
+ } else {
+ ret_val = -EINVAL;
+ if (lp->oldlink == PHY_RUNNING) {
+ ethtool_cmd_speed_set(ecmd, lp->oldspeed);
+ ecmd->duplex = lp->oldduplex;
+ ecmd->port = PORT_MII;
+ ecmd->phy_address = 0xFF;
+ ecmd->transceiver = XCVR_EXTERNAL;
+ ecmd->autoneg = AUTONEG_DISABLE;
+ ecmd->supported = SUPPORTED_MII;
+ switch (lp->oldspeed) {
+ case SPEED_1000:
+ if (lp->oldduplex == DUPLEX_FULL) {
+ ecmd->supported |=
+ SUPPORTED_1000baseT_Full;
+ } else {
+ ecmd->supported |=
+ SUPPORTED_1000baseT_Half;
+ }
+ ret_val = 0;
+ break;
+ case SPEED_100:
+ if (lp->oldduplex == DUPLEX_FULL) {
+ ecmd->supported |=
+ SUPPORTED_100baseT_Full;
+ } else {
+ ecmd->supported |=
+ SUPPORTED_100baseT_Half;
+ }
+ ret_val = 0;
+ break;
+ case SPEED_10:
+ if (lp->oldduplex == DUPLEX_FULL) {
+ ecmd->supported |=
+ SUPPORTED_10baseT_Full;
+ } else {
+ ecmd->supported |=
+ SUPPORTED_10baseT_Half;
+ }
+ ret_val = 0;
+ break;
+ default:
+ break;
+ }
+ ecmd->advertising = ecmd->supported;
+ }
+ }
+
+ return ret_val;
+}
+
+static int ambeth_set_settings(struct net_device *ndev,
+ struct ethtool_cmd *ecmd)
+{
+ struct ambeth_info *lp = netdev_priv(ndev);
+
+ if (!netif_running(ndev) || !lp->phy_enabled)
+ return -EINVAL;
+
+ return phy_ethtool_sset(lp->phydev, ecmd);
+}
+
+static int ambeth_get_dump_flag(struct net_device *ndev,
+ struct ethtool_dump *ed)
+{
+ ed->len = (AMBETH_PHY_REG_SIZE * sizeof(u16));
+ ed->flag = 0;
+ pr_debug("%s: cmd[0x%08X], version[0x%08X], "
+ "flag[0x%08X], len[0x%08X]\n",
+ __func__, ed->cmd, ed->version,
+ ed->flag, ed->len);
+
+ return 0;
+}
+
+static int ambeth_get_dump_data(struct net_device *ndev,
+ struct ethtool_dump *ed, void *pdata)
+{
+ struct ambeth_info *lp = netdev_priv(ndev);
+ int i;
+ u16 *regbuf;
+
+ pr_debug("%s: cmd[0x%08X], version[0x%08X], "
+ "flag[0x%08X], len[0x%08X]\n",
+ __func__, ed->cmd, ed->version,
+ ed->flag, ed->len);
+
+ if (!lp->phy_enabled) {
+ return -EINVAL;
+ }
+ regbuf = (u16 *)pdata;
+ for (i = 0; i < (ed->len / 2); i++) {
+ regbuf[i] = mdiobus_read(lp->phydev->bus,
+ lp->phydev->addr, i);
+ }
+
+ return 0;
+}
+
+static int ambeth_set_dump(struct net_device *ndev, struct ethtool_dump *ed)
+{
+ struct ambeth_info *lp = netdev_priv(ndev);
+ u16 dbg_address;
+ u16 dbg_value;
+
+ pr_debug("%s: cmd[0x%08X], version[0x%08X], "
+ "flag[0x%08X], len[0x%08X]\n",
+ __func__, ed->cmd, ed->version,
+ ed->flag, ed->len);
+
+ if (!lp->phy_enabled) {
+ return -EINVAL;
+ }
+ dbg_address = ((ed->flag & 0xFFFF0000) >> 16);
+ dbg_value = (ed->flag & 0x0000FFFF);
+ mdiobus_write(lp->phydev->bus, lp->phydev->addr,
+ dbg_address, dbg_value);
+
+ return 0;
+}
+
+static u32 ambeth_get_msglevel(struct net_device *ndev)
+{
+ struct ambeth_info *lp;
+
+ lp = (struct ambeth_info *)netdev_priv(ndev);
+
+ return lp->msg_enable;
+}
+
+static void ambeth_set_msglevel(struct net_device *ndev, u32 value)
+{
+ struct ambeth_info *lp;
+
+ lp = (struct ambeth_info *)netdev_priv(ndev);
+
+ lp->msg_enable = value;
+}
+
+static void ambeth_get_pauseparam(struct net_device *ndev,
+ struct ethtool_pauseparam *pause)
+{
+ struct ambeth_info *lp;
+ u32 flow_ctr;
+
+ lp = (struct ambeth_info *)netdev_priv(ndev);
+ flow_ctr = lp->flow_ctr;
+
+ pause->autoneg = (flow_ctr & AMBARELLA_ETH_FC_AUTONEG) ?
+ AUTONEG_ENABLE : AUTONEG_DISABLE;
+
+ pause->rx_pause = (flow_ctr & AMBARELLA_ETH_FC_RX) ? 1 : 0;
+ pause->tx_pause = (flow_ctr & AMBARELLA_ETH_FC_TX) ? 1 : 0;
+}
+
+static int ambeth_set_pauseparam(struct net_device *ndev,
+ struct ethtool_pauseparam *pause)
+{
+ struct ambeth_info *lp = netdev_priv(ndev);
+ u32 flow_ctr;
+ int ret_val = 0;
+
+ /*
+ * Symmeteric pause can respond to recieved pause frames, and
+ * send pause frames to the link partner.
+ *
+ * Asymmetric pause can send pause frames, but can't respond to
+ * pause frames from the link partner.
+ *
+ * Autoneg only advertises and reports the 'cap (or will)' of
+ * the link partner. The final resolution still has to be done in
+ * MAC / Driver.
+ *
+ * Since our MAC can support both directions independently, we
+ * advertise our 'cap' to the link partner based on the
+ * pauseparam specified by the user (ethtool). And take the
+ * 'cap' of the link partner reported into consideration for
+ * makeing the final resolution.
+ */
+
+ flow_ctr = lp->flow_ctr;
+
+ if (pause->autoneg)
+ flow_ctr |= AMBARELLA_ETH_FC_AUTONEG;
+ else
+ flow_ctr &= ~AMBARELLA_ETH_FC_AUTONEG;
+
+ if (pause->rx_pause)
+ flow_ctr |= AMBARELLA_ETH_FC_RX;
+ else
+ flow_ctr &= ~AMBARELLA_ETH_FC_RX;
+
+ if (pause->tx_pause)
+ flow_ctr |= AMBARELLA_ETH_FC_TX;
+ else
+ flow_ctr &= ~AMBARELLA_ETH_FC_TX;
+
+ lp->flow_ctr = flow_ctr;
+ if(lp->flow_ctr & (AMBARELLA_ETH_FC_TX | AMBARELLA_ETH_FC_RX))
+ lp->phy_supported |= SUPPORTED_Pause;
+ else
+ lp->phy_supported &= ~SUPPORTED_Pause;
+
+
+ ambeth_fc_config(lp);
+
+ if (pause->autoneg && lp->phydev->autoneg) {
+
+ ret_val = phy_start_aneg(lp->phydev);
+ if (ret_val)
+ goto done;
+ }
+ else {
+ ambeth_fc_resolve(lp);
+ }
+done:
+ return ret_val;
+}
+
+static int ambeth_get_eee(struct net_device *ndev, struct ethtool_eee *e)
+{
+ struct ambeth_info *lp = netdev_priv(ndev);
+
+ /*now our chip don't support EEE*/
+ e->eee_enabled = false;
+ e->eee_active = false;
+ e->tx_lpi_enabled = false;
+ e->tx_lpi_timer = 0;
+
+ return phy_ethtool_get_eee(lp->phydev, e);
+}
+
+static int ambeth_set_eee(struct net_device *ndev, struct ethtool_eee *e)
+{
+ struct ambeth_info *lp = netdev_priv(ndev);
+ int ret = 0;
+
+ if(e->eee_enabled || e->tx_lpi_enabled) {
+ dev_err(&lp->ndev->dev, "eth don't support EEE.\n");
+ return -EOPNOTSUPP;
+ }
+
+ ret = phy_init_eee(lp->phydev, 0);
+ if (ret) {
+ dev_err(&lp->ndev->dev, "phy don't support EEE.\n");
+ return ret;
+ }
+
+ return phy_ethtool_set_eee(lp->phydev, e);
+}
+
+static const struct ethtool_ops ambeth_ethtool_ops = {
+ .get_settings = ambeth_get_settings,
+ .set_settings = ambeth_set_settings,
+ .get_link = ethtool_op_get_link,
+ .get_dump_flag = ambeth_get_dump_flag,
+ .get_dump_data = ambeth_get_dump_data,
+ .set_dump = ambeth_set_dump,
+ .get_msglevel = ambeth_get_msglevel,
+ .set_msglevel = ambeth_set_msglevel,
+ .get_pauseparam = ambeth_get_pauseparam,
+ .set_pauseparam = ambeth_set_pauseparam,
+ .get_eee = ambeth_get_eee,
+ .set_eee = ambeth_set_eee,
+};
+
+/* ==========================================================================*/
+static int ambeth_of_parse(struct device_node *np, struct ambeth_info *lp)
+{
+ struct device_node *phy_np;
+ enum of_gpio_flags flags;
+ int gmii, ret_val, clk_src, clk_direction, clk_pl;
+
+ ret_val = of_property_read_u32(np, "amb,fixed-speed", &lp->fixed_speed);
+ if (ret_val < 0)
+ lp->fixed_speed = SPEED_UNKNOWN;
+
+ gmii = !!of_find_property(np, "amb,support-gmii", NULL);
+ if (gmii) {
+ lp->phy_supported = ( SUPPORTED_10baseT_Half | \
+ SUPPORTED_10baseT_Full | \
+ SUPPORTED_100baseT_Half | \
+ SUPPORTED_100baseT_Full | \
+ SUPPORTED_1000baseT_Half | \
+ SUPPORTED_1000baseT_Full | \
+ SUPPORTED_Autoneg | \
+ SUPPORTED_MII);
+ } else {
+ lp->phy_supported = ( SUPPORTED_10baseT_Half | \
+ SUPPORTED_10baseT_Full | \
+ SUPPORTED_100baseT_Half | \
+ SUPPORTED_100baseT_Full | \
+ SUPPORTED_Autoneg | \
+ SUPPORTED_MII);
+ }
+
+ /*enable flow control*/
+ lp->phy_supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
+
+ ret_val = of_property_read_u32(np, "amb,tx-ring-size", &lp->tx_count);
+ if (ret_val < 0 || lp->tx_count < AMBETH_TX_RNG_MIN)
+ lp->tx_count = AMBETH_TX_RNG_MIN;
+
+ ret_val = of_property_read_u32(np, "amb,rx-ring-size", &lp->rx_count);
+ if (ret_val < 0 || lp->rx_count < AMBETH_RX_RNG_MIN)
+ lp->rx_count = AMBETH_RX_RNG_MIN;
+
+ lp->tx_irq_low = ((lp->tx_count * 1) / 4);
+ lp->tx_irq_high = ((lp->tx_count * 3) / 4);
+
+ lp->ipc_tx = !!of_find_property(np, "amb,ipc-tx", NULL);
+ lp->ipc_rx = !!of_find_property(np, "amb,ipc-rx", NULL);
+ lp->dump_tx = !!of_find_property(np, "amb,dump-tx", NULL);
+ lp->dump_rx = !!of_find_property(np, "amb,dump-rx", NULL);
+ lp->dump_rx_free = !!of_find_property(np, "amb,dump-rx-free", NULL);
+ lp->dump_rx_all = !!of_find_property(np, "amb,dump-rx-all", NULL);
+ lp->mdio_gpio = !!of_find_property(np, "amb,mdio-gpio", NULL);
+
+ for_each_child_of_node(np, phy_np) {
+ if (!phy_np->name || of_node_cmp(phy_np->name, "phy"))
+ continue;
+
+ lp->pwr_gpio = of_get_named_gpio_flags(phy_np, "pwr-gpios", 0, &flags);
+ lp->pwr_gpio_active = !!(flags & OF_GPIO_ACTIVE_LOW);
+
+ lp->rst_gpio = of_get_named_gpio_flags(phy_np, "rst-gpios", 0, &flags);
+ lp->rst_gpio_active = !!(flags & OF_GPIO_ACTIVE_LOW);
+
+ ret_val = of_property_read_u32(phy_np, "amb,clk-src", &clk_src);
+ if (ret_val == 0 && clk_src == 0) {
+ /*clk_src == 0 represent the clk is external*/
+ amba_writel(ENET_CLK_SRC_SEL_REG, 0x00);
+ } else if(ret_val == 0 && clk_src == 1) {
+ /*clk_src == 1 and default represent the clk is internal*/
+ amba_writel(ENET_CLK_SRC_SEL_REG, 0x01);
+ } else {
+ /*default value for clk source*/
+ }
+
+ ret_val = of_property_read_u32(phy_np, "amb,clk-invert", &clk_pl);
+ if(ret_val == 0 && clk_pl == 1) {
+ amba_setbitsl(AHB_SCRATCHPAD_REG(0xc), 0x80000000);
+ } else if(ret_val == 0 && clk_pl == 0) {
+ amba_clrbitsl(AHB_SCRATCHPAD_REG(0xc), 0x80000000);
+ }
+
+ ret_val = of_property_read_u32(phy_np, "amb,clk-dir", &clk_direction);
+ if(ret_val == 0 && clk_direction == 1) {
+ /*set direction of xx_enet_clk_rx as output from ambarella chip*/
+ lp->clk_direction = 1;
+ ret_val = amba_readl(AHB_MISC_EN_REG);
+ ret_val |= (1 << 5);
+ amba_writel(AHB_MISC_EN_REG, ret_val);
+ } else if(ret_val == 0 && clk_direction == 0) {
+ /*set direction of xx_enet_clk_rx as output from external phy*/
+ lp->clk_direction = 0;
+ ret_val = amba_readl(AHB_MISC_EN_REG);
+ ret_val &= ~(1 << 5);
+ amba_writel(AHB_MISC_EN_REG, ret_val);
+ } else
+ lp->clk_direction = -1;
+ }
+
+ return 0;
+}
+
+static int ambeth_drv_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node, *mdio_np = NULL;
+ struct net_device *ndev;
+ struct ambeth_info *lp;
+ struct resource *res;
+ const char *macaddr;
+ int ret_val = 0;
+
+ if (!(ambarella_get_poc() & SYS_CONFIG_ETH_ENABLE)) {
+ dev_err(&pdev->dev, "Not enabled, check HW config!\n");
+ return -EPERM;
+ }
+
+ ndev = alloc_etherdev(sizeof(struct ambeth_info));
+ if (ndev == NULL) {
+ dev_err(&pdev->dev, "alloc_etherdev fail.\n");
+ return -ENOMEM;
+ }
+ lp = netdev_priv(ndev);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "No mem resource for fio_reg!\n");
+ ret_val = -ENXIO;
+ goto ambeth_drv_probe_free_netdev;
+ }
+
+ lp->regbase = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!lp->regbase) {
+ dev_err(&pdev->dev, "devm_ioremap() failed\n");
+ ret_val = -ENOMEM;
+ goto ambeth_drv_probe_free_netdev;
+ }
+
+ ndev->irq = platform_get_irq(pdev, 0);
+ if (ndev->irq < 0) {
+ dev_err(&pdev->dev, "no irq for ethernet!\n");
+ ret_val = -ENODEV;
+ goto ambeth_drv_probe_free_netdev;
+ }
+
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+ ndev->dev.dma_mask = pdev->dev.dma_mask;
+ ndev->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask;
+
+ spin_lock_init(&lp->lock);
+ lp->ndev = ndev;
+ lp->msg_enable = netif_msg_init(msg_level, NETIF_MSG_DRV);
+
+ ambeth_of_parse(np, lp);
+
+ if (lp->ipc_tx)
+ ndev->features |= NETIF_F_HW_CSUM;
+
+ /* request gpio for PHY power control */
+ if (gpio_is_valid(lp->pwr_gpio)) {
+ ret_val = devm_gpio_request(&pdev->dev,
+ lp->pwr_gpio, "phy power");
+ if (ret_val < 0) {
+ dev_err(&pdev->dev, "Failed to request pwr-gpios!\n");
+ goto ambeth_drv_probe_free_netdev;
+ }
+ gpio_direction_output(lp->pwr_gpio, lp->pwr_gpio_active);
+ }
+
+ /* request gpio for PHY reset control */
+ if (gpio_is_valid(lp->rst_gpio)) {
+ ret_val = devm_gpio_request(&pdev->dev,
+ lp->rst_gpio, "phy reset");
+ if (ret_val < 0) {
+ dev_err(&pdev->dev, "Failed to request rst-gpios!\n");
+ goto ambeth_drv_probe_free_netdev;
+ }
+ gpio_direction_output(lp->rst_gpio, !lp->rst_gpio_active);
+ }
+
+ if(lp->mdio_gpio) {
+ mdio_np = of_find_compatible_node(NULL, NULL, "virtual,mdio-gpio");
+
+ if(mdio_np == NULL) {
+ dev_err(&pdev->dev, "Failed to get mdio_gpio device node\n");
+ goto ambeth_drv_probe_free_netdev;
+ }
+
+ lp->phydev = of_phy_find_device(mdio_np->child);
+
+ if(!lp->phydev) {
+ dev_err(&pdev->dev, "Failed to get phydev from mdio_gpio device node\n");
+ goto ambeth_drv_probe_free_netdev;
+ }
+
+ lp->new_bus = *lp->phydev->bus;
+ } else {
+ lp->new_bus.name = "Ambarella MII Bus",
+ lp->new_bus.read = &ambhw_mdio_read,
+ lp->new_bus.write = &ambhw_mdio_write,
+ lp->new_bus.reset = &ambhw_mdio_reset,
+ snprintf(lp->new_bus.id, MII_BUS_ID_SIZE, "%s", pdev->name);
+ lp->new_bus.priv = lp;
+ lp->new_bus.irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
+ if (lp->new_bus.irq == NULL) {
+ dev_err(&pdev->dev, "alloc new_bus.irq fail.\n");
+ ret_val = -ENOMEM;
+ goto ambeth_drv_probe_free_netdev;
+ }
+
+ lp->new_bus.parent = &pdev->dev;
+ lp->new_bus.state = MDIOBUS_ALLOCATED;
+
+ ret_val = of_mdiobus_register(&lp->new_bus, pdev->dev.of_node);
+ if (ret_val < 0) {
+ dev_err(&pdev->dev, "mdiobus_register fail%d.\n", ret_val);
+ goto ambeth_drv_probe_kfree_mdiobus;
+ }
+
+ lp->phydev = phy_find_first(&lp->new_bus);
+ if (lp->phydev == NULL) {
+ dev_err(&pdev->dev, "No PHY device.\n");
+ ret_val = -ENODEV;
+ goto ambeth_drv_probe_kfree_mdiobus;
+ }
+ }
+
+ if (netif_msg_drv(lp)) {
+ dev_info(&pdev->dev, "Ethernet PHY[%d]: 0x%08x!\n",
+ lp->phydev->addr, lp->phydev->phy_id);
+ }
+
+ ether_setup(ndev);
+ ndev->netdev_ops = &ambeth_netdev_ops;
+ ndev->watchdog_timeo = AMBETH_TX_WATCHDOG;
+ netif_napi_add(ndev, &lp->napi, ambeth_napi, AMBETH_NAPI_WEIGHT);
+
+ macaddr = of_get_mac_address(pdev->dev.of_node);
+ if (macaddr)
+ memcpy(ndev->dev_addr, macaddr, ETH_ALEN);
+
+ if (!is_valid_ether_addr(ndev->dev_addr))
+ eth_hw_addr_random(ndev);
+
+ ambhw_disable(lp);
+
+ if (gpio_is_valid(lp->pwr_gpio))
+ gpio_set_value_cansleep(lp->pwr_gpio, !lp->pwr_gpio_active);
+ if (gpio_is_valid(lp->rst_gpio))
+ gpio_set_value_cansleep(lp->rst_gpio, lp->rst_gpio_active);
+
+ SET_ETHTOOL_OPS(ndev, &ambeth_ethtool_ops);
+ ret_val = register_netdev(ndev);
+ if (ret_val) {
+ dev_err(&pdev->dev, " register_netdev fail%d.\n", ret_val);
+ goto ambeth_drv_probe_netif_napi_del;
+ }
+
+ platform_set_drvdata(pdev, ndev);
+ dev_notice(&pdev->dev, "MAC Address[%pM].\n", ndev->dev_addr);
+
+ return 0;
+
+ambeth_drv_probe_netif_napi_del:
+ netif_napi_del(&lp->napi);
+ mdiobus_unregister(&lp->new_bus);
+
+ambeth_drv_probe_kfree_mdiobus:
+ kfree(lp->new_bus.irq);
+
+ambeth_drv_probe_free_netdev:
+ free_netdev(ndev);
+ return ret_val;
+}
+
+static int ambeth_drv_remove(struct platform_device *pdev)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct ambeth_info *lp = netdev_priv(ndev);
+
+ unregister_netdev(ndev);
+ netif_napi_del(&lp->napi);
+ mdiobus_unregister(&lp->new_bus);
+ kfree(lp->new_bus.irq);
+ platform_set_drvdata(pdev, NULL);
+ free_netdev(ndev);
+ dev_notice(&pdev->dev, "Removed.\n");
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int ambeth_drv_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct ambeth_info *lp = netdev_priv(ndev);
+ int ret_val = 0;
+ unsigned long flags;
+
+ if (!netif_running(ndev))
+ goto ambeth_drv_suspend_exit;
+
+ napi_disable(&lp->napi);
+ netif_device_detach(ndev);
+ disable_irq(ndev->irq);
+
+ ambeth_phy_stop(lp);
+
+ spin_lock_irqsave(&lp->lock, flags);
+ ambhw_disable(lp);
+ spin_unlock_irqrestore(&lp->lock, flags);
+
+ if (gpio_is_valid(lp->pwr_gpio))
+ gpio_set_value_cansleep(lp->pwr_gpio, !lp->pwr_gpio_active);
+ if (gpio_is_valid(lp->rst_gpio))
+ gpio_set_value_cansleep(lp->rst_gpio, lp->rst_gpio_active);
+
+ambeth_drv_suspend_exit:
+ dev_dbg(&pdev->dev, "%s exit with %d @ %d\n",
+ __func__, ret_val, state.event);
+
+ return ret_val;
+}
+
+static int ambeth_drv_resume(struct platform_device *pdev)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct ambeth_info *lp = netdev_priv(ndev);
+ int ret_val = 0;
+ unsigned long flags;
+
+ if (!netif_running(ndev))
+ goto ambeth_drv_resume_exit;
+
+ if(lp->clk_direction == 1) {
+ ret_val = amba_readl(AHB_MISC_EN_REG);
+ ret_val |= (1 << 5);
+ amba_writel(AHB_MISC_EN_REG, ret_val);
+ } else if(lp->clk_direction == 0) {
+ ret_val = amba_readl(AHB_MISC_EN_REG);
+ ret_val &= ~(1 << 5);
+ amba_writel(AHB_MISC_EN_REG, ret_val);
+ }
+
+ if (gpio_is_valid(lp->pwr_gpio))
+ gpio_set_value_cansleep(lp->pwr_gpio, lp->pwr_gpio_active);
+ if (gpio_is_valid(lp->rst_gpio)) {
+ gpio_set_value_cansleep(lp->rst_gpio, lp->rst_gpio_active);
+ msleep(10);
+ gpio_set_value_cansleep(lp->rst_gpio, !lp->rst_gpio_active);
+ }
+
+ spin_lock_irqsave(&lp->lock, flags);
+ ret_val = ambhw_enable(lp);
+ ambhw_set_link_mode_speed(lp);
+ ambeth_rx_rngmng_init(lp);
+ ambeth_tx_rngmng_init(lp);
+ ambhw_set_dma_desc(lp);
+ ambhw_dma_rx_start(lp);
+ ambhw_dma_tx_start(lp);
+ ambhw_dma_int_enable(lp);
+ spin_unlock_irqrestore(&lp->lock, flags);
+
+ if (ret_val) {
+ dev_err(&pdev->dev, "ambhw_enable.\n");
+ } else {
+ ambeth_set_multicast_list(ndev);
+ netif_carrier_off(ndev);
+ ret_val = ambeth_phy_start(lp);
+ enable_irq(ndev->irq);
+ netif_device_attach(ndev);
+ napi_enable(&lp->napi);
+ }
+ambeth_drv_resume_exit:
+ dev_dbg(&pdev->dev, "%s exit with %d\n", __func__, ret_val);
+ return ret_val;
+}
+#endif
+
+static const struct of_device_id ambarella_eth_dt_ids[] = {
+ { .compatible = "ambarella,eth" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, ambarella_eth_dt_ids);
+
+static struct platform_driver ambeth_driver = {
+ .probe = ambeth_drv_probe,
+ .remove = ambeth_drv_remove,
+#ifdef CONFIG_PM
+ .suspend = ambeth_drv_suspend,
+ .resume = ambeth_drv_resume,
+#endif
+ .driver = {
+ .name = "ambarella-eth",
+ .owner = THIS_MODULE,
+ .of_match_table = ambarella_eth_dt_ids,
+ },
+};
+
+module_platform_driver(ambeth_driver);
+
+MODULE_DESCRIPTION("Ambarella Media Processor Ethernet Driver");
+MODULE_AUTHOR("Anthony Ginger, <hfjiang@ambarella.com>");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 1e11f2bf..b29a0f6b 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -106,6 +106,13 @@ config MICREL_PHY
---help---
Supports the KSZ9021, VSC8201, KS8001 PHYs.
+config MICREL_PHY_KSZ80X1R
+ tristate "Driver for Micrel PHYs KSZ80X1R"
+ depends on PLAT_AMBARELLA=y
+ depends on MICREL_PHY=n
+ ---help---
+ Supports the KSZ80X1R PHYs.
+
config FIXED_PHY
bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
depends on PHYLIB=y
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 9645e389..04c9ddc7 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_NATIONAL_PHY) += national.o
obj-$(CONFIG_DP83640_PHY) += dp83640.o
obj-$(CONFIG_STE10XP) += ste10Xp.o
obj-$(CONFIG_MICREL_PHY) += micrel.o
+obj-$(CONFIG_MICREL_PHY_KSZ80X1R) += ksz80x1r.o
obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o
obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o
obj-$(CONFIG_AT803X_PHY) += at803x.o
diff --git a/drivers/net/phy/ksz80x1r.c b/drivers/net/phy/ksz80x1r.c
new file mode 100644
index 00000000..64372e8a
--- /dev/null
+++ b/drivers/net/phy/ksz80x1r.c
@@ -0,0 +1,150 @@
+/*
+ * drivers/net/phy/ksz80x1r.c
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2014, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/phy.h>
+#include <linux/micrel_phy.h>
+
+/* ==========================================================================*/
+#define MII_KSZ80X1R_INTCS 0x1B
+#define KSZ80X1R_INTCS_JABBER (1 << 15)
+#define KSZ80X1R_INTCS_RECEIVE_ERR (1 << 14)
+#define KSZ80X1R_INTCS_PAGE_RECEIVE (1 << 13)
+#define KSZ80X1R_INTCS_PARELLEL (1 << 12)
+#define KSZ80X1R_INTCS_LINK_PARTNER_ACK (1 << 11)
+#define KSZ80X1R_INTCS_LINK_DOWN (1 << 10)
+#define KSZ80X1R_INTCS_REMOTE_FAULT (1 << 9)
+#define KSZ80X1R_INTCS_LINK_UP (1 << 8)
+#define KSZ80X1R_INTCS_ALL (KSZ80X1R_INTCS_LINK_UP |\
+ KSZ80X1R_INTCS_LINK_DOWN)
+
+#define MII_KSZ80X1R_CTRL 0x1F
+#define KSZ80X1R_CTRL_INT_ACTIVE_HIGH (1 << 9)
+#define KSZ80X1R_RMII_50MHZ_CLK (1 << 7)
+
+/* ==========================================================================*/
+MODULE_DESCRIPTION("Micrel KSZ8081R");
+MODULE_AUTHOR("Anthony Ginger <hfjiang@ambarella.com>");
+MODULE_LICENSE("GPL");
+
+/* ==========================================================================*/
+static int ksz80x1r_config_init(struct phy_device *phydev)
+{
+ int regval;
+
+ pr_debug("Set KSZ80X1R 50MHz Clock Mode...");
+ regval = phy_read(phydev, MII_KSZ80X1R_CTRL);
+ regval |= KSZ80X1R_RMII_50MHZ_CLK;
+ return phy_write(phydev, MII_KSZ80X1R_CTRL, regval);
+}
+
+void ksz80x1r_prevent_loss(struct phy_device *phydev) {
+ phy_write(phydev, 0x0d, 0x001c);
+ phy_write(phydev, 0x0e, 0x0008);
+ phy_write(phydev, 0x0d, 0x401c);
+ phy_write(phydev, 0x0e, 0x0067);
+ phy_write(phydev, 0x0d, 0x001c);
+ phy_write(phydev, 0x0e, 0x0009);
+ phy_write(phydev, 0x0d, 0x401c);
+ phy_write(phydev, 0x0e, 0xffff);
+ phy_write(phydev, 0x0d, 0x001c);
+ phy_write(phydev, 0x0e, 0x000a);
+ phy_write(phydev, 0x0d, 0x401c);
+ phy_write(phydev, 0x0e, 0xffff);
+}
+
+int ksz80x1r_config_aneg(struct phy_device *phydev)
+{
+ int result;
+
+ result = genphy_config_aneg(phydev);
+ if(result > 0)
+ ksz80x1r_prevent_loss(phydev);
+
+ return result;
+}
+
+static int ksz80x1r_ack_interrupt(struct phy_device *phydev)
+{
+ int rc;
+
+ rc = phy_read(phydev, MII_KSZ80X1R_INTCS);
+
+ return (rc < 0) ? rc : 0;
+}
+
+static int ksz80x1r_set_interrupt(struct phy_device *phydev)
+{
+ int temp;
+ temp = (PHY_INTERRUPT_ENABLED == phydev->interrupts) ?
+ KSZ80X1R_INTCS_ALL : 0;
+ return phy_write(phydev, MII_KSZ80X1R_INTCS, temp);
+}
+
+static int ksz80x1r_config_intr(struct phy_device *phydev)
+{
+ int temp, rc;
+
+ /* set the interrupt pin active low */
+ temp = phy_read(phydev, MII_KSZ80X1R_CTRL);
+ temp &= ~KSZ80X1R_CTRL_INT_ACTIVE_HIGH;
+ phy_write(phydev, MII_KSZ80X1R_CTRL, temp);
+ rc = ksz80x1r_set_interrupt(phydev);
+ return rc < 0 ? rc : 0;
+}
+
+static struct phy_driver ksz80x1r_driver = {
+ .phy_id = PHY_ID_KSZ8081,
+ .name = "Micrel KSZ8081 or KSZ8091",
+ .phy_id_mask = 0x00fffff0,
+ .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
+ .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
+ .config_init = ksz80x1r_config_init,
+ .config_aneg = ksz80x1r_config_aneg,
+ .read_status = genphy_read_status,
+ .ack_interrupt = ksz80x1r_ack_interrupt,
+ .config_intr = ksz80x1r_config_intr,
+ .driver = { .owner = THIS_MODULE,},
+};
+
+static int __init ksz80x1r_init(void)
+{
+ return phy_driver_register(&ksz80x1r_driver);
+}
+
+static void __exit ksz80x1r_exit(void)
+{
+ phy_driver_unregister(&ksz80x1r_driver);
+}
+
+/* ==========================================================================*/
+module_init(ksz80x1r_init);
+module_exit(ksz80x1r_exit);
+
+static struct mdio_device_id __maybe_unused ksz80x1r_tbl[] = {
+ { PHY_ID_KSZ8081, 0x0000fff0 },
+ { }
+};
+MODULE_DEVICE_TABLE(mdio, ksz80x1r_tbl);
+
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c
index a47f9236..a64ad54b 100644
--- a/drivers/net/phy/mdio-gpio.c
+++ b/drivers/net/phy/mdio-gpio.c
@@ -30,16 +30,32 @@
#include <linux/of_gpio.h>
#include <linux/of_mdio.h>
+#include <linux/delay.h>
struct mdio_gpio_info {
struct mdiobb_ctrl ctrl;
- int mdc, mdio;
+ int mdc, mdio, rst;
+ int rst_active_low;
};
+static int mdio_gpio_reset(struct mii_bus *bus)
+{
+ struct mdiobb_ctrl *bb_ctrl = bus->priv;
+ struct mdio_gpio_info *mdio_info = container_of(bb_ctrl, struct mdio_gpio_info, ctrl);
+
+ gpio_direction_output(mdio_info->rst, mdio_info->rst_active_low);
+ msleep(50);
+ gpio_direction_output(mdio_info->rst, !mdio_info->rst_active_low);
+ msleep(50);
+
+ return 0;
+}
+
static void *mdio_gpio_of_get_data(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct mdio_gpio_platform_data *pdata;
+ enum of_gpio_flags flags;
int ret;
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
@@ -57,6 +73,18 @@ static void *mdio_gpio_of_get_data(struct platform_device *pdev)
return NULL;
pdata->mdio = ret;
+ pdata->rst = of_get_named_gpio_flags(np->child, "rst-gpios", 0, &flags);
+ if (gpio_is_valid(pdata->rst)) {
+ ret = devm_gpio_request(&pdev->dev,
+ pdata->rst, "phy reset");
+ if(ret < 0)
+ dev_err(&pdev->dev, "Failed to request rst-gpios!\n");
+ else {
+ pdata->rst_active_low = flags & OF_GPIO_ACTIVE_LOW;
+ pdata->reset = mdio_gpio_reset;
+ }
+ }
+
return pdata;
}
@@ -119,6 +147,8 @@ static struct mii_bus *mdio_gpio_bus_init(struct device *dev,
bitbang->ctrl.reset = pdata->reset;
bitbang->mdc = pdata->mdc;
bitbang->mdio = pdata->mdio;
+ bitbang->rst = pdata->rst;
+ bitbang->rst_active_low = pdata->rst_active_low;
new_bus = alloc_mdio_bitbang(&bitbang->ctrl);
if (!new_bus)
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 299d3555..48f8d581 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -588,7 +588,7 @@ int phy_start_interrupts(struct phy_device *phydev)
atomic_set(&phydev->irq_disable, 0);
if (request_irq(phydev->irq, phy_interrupt,
- IRQF_SHARED,
+ IRQF_SHARED | phydev->irq_flags,
"phy_interrupt",
phydev) < 0) {
pr_warn("%s: Can't get IRQ %d (PHY)\n",
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 3657b4a2..2b764d61 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -917,6 +917,9 @@ static int genphy_config_init(struct phy_device *phydev)
int val;
u32 features;
+ /* Make sure PHY is ON */
+ genphy_resume(phydev);
+
/* For now, I'll claim that the generic driver supports
* all possible port types */
features = (SUPPORTED_TP | SUPPORTED_MII
@@ -958,6 +961,7 @@ static int genphy_config_init(struct phy_device *phydev)
return 0;
}
+
int genphy_suspend(struct phy_device *phydev)
{
int value;
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 8f669243..ff7a6f6f 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -221,6 +221,12 @@ config PINCTRL_S3C64XX
depends on ARCH_S3C64XX
select PINCTRL_SAMSUNG
+config PINCTRL_AMB
+ bool
+ depends on PLAT_AMBARELLA
+ select PINMUX
+ select PINCONF
+
source "drivers/pinctrl/mvebu/Kconfig"
source "drivers/pinctrl/sh-pfc/Kconfig"
source "drivers/pinctrl/spear/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 9bdaeb87..cbbe9aaf 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -45,9 +45,11 @@ obj-$(CONFIG_PINCTRL_EXYNOS5440) += pinctrl-exynos5440.o
obj-$(CONFIG_PINCTRL_S3C64XX) += pinctrl-s3c64xx.o
obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o
obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o
+obj-$(CONFIG_PINCTRL_AMB) += pinctrl-ambarella.o
obj-$(CONFIG_PLAT_ORION) += mvebu/
obj-$(CONFIG_ARCH_SHMOBILE) += sh-pfc/
obj-$(CONFIG_SUPERH) += sh-pfc/
obj-$(CONFIG_PLAT_SPEAR) += spear/
obj-$(CONFIG_ARCH_VT8500) += vt8500/
+
diff --git a/drivers/pinctrl/pinctrl-ambarella.c b/drivers/pinctrl/pinctrl-ambarella.c
new file mode 100644
index 00000000..28c33a88
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-ambarella.c
@@ -0,0 +1,856 @@
+/*
+ * drivers/pinctrl/ambarella/pinctrl-amb.c
+ *
+ * History:
+ * 2013/12/18 - [Cao Rongrong] created file
+ *
+ * Copyright (C) 2012-2016, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/syscore_ops.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <plat/rct.h>
+#include <plat/pinctrl.h>
+#include "core.h"
+
+#define PIN_NAME_LENGTH 8
+#define SUFFIX_LENGTH 4
+
+#define MUXIDS_TO_PINID(m) ((m) & 0xfff)
+#define MUXIDS_TO_ALT(m) (((m) >> 12) & 0xf)
+
+#define CONFIDS_TO_PINID(c) ((c) & 0xfff)
+#define CONFIDS_TO_CONF(c) (((c) >> 16) & 0xffff)
+
+/*
+ * bit1~0: 00: pull down, 01: pull up, 1x: clear pull up/down
+ * bit2: reserved
+ * bit3: 1: config pull up/down, 0: leave pull up/down as default value
+ * bit5~4: drive strength value
+ * bit6: reserved
+ * bit7: 1: config drive strength, 0: leave drive strength as default value
+ */
+#define CONF_TO_PULL_VAL(c) (((c) >> 0) & 0x1)
+#define CONF_TO_PULL_CLR(c) (((c) >> 1) & 0x1)
+#define CFG_PULL_PRESENT(c) (((c) >> 3) & 0x1)
+#define CONF_TO_DS_VAL(c) (((c) >> 4) & 0x3)
+#define CFG_DS_PRESENT(c) (((c) >> 7) & 0x1)
+
+struct ambpin_group {
+ const char *name;
+ unsigned int *pins;
+ unsigned num_pins;
+ u8 *alt;
+ unsigned int *conf_pins;
+ unsigned num_conf_pins;
+ unsigned long *conf;
+};
+
+struct ambpin_function {
+ const char *name;
+ const char **groups;
+ unsigned num_groups;
+ unsigned long function;
+};
+
+struct amb_pinctrl_soc_data {
+ struct device *dev;
+ struct pinctrl_dev *pctl;
+ void __iomem *regbase[GPIO_INSTANCES];
+ void __iomem *iomux_base;
+ unsigned long used[BITS_TO_LONGS(AMBGPIO_SIZE)];
+
+ struct ambpin_function *functions;
+ unsigned int nr_functions;
+ struct ambpin_group *groups;
+ unsigned int nr_groups;
+};
+
+void __iomem *amb_iomux_base = NULL;
+
+/* check if the selector is a valid pin group selector */
+static int amb_get_group_count(struct pinctrl_dev *pctldev)
+{
+ struct amb_pinctrl_soc_data *soc;
+
+ soc = pinctrl_dev_get_drvdata(pctldev);
+ return soc->nr_groups;
+}
+
+/* return the name of the group selected by the group selector */
+static const char *amb_get_group_name(struct pinctrl_dev *pctldev,
+ unsigned selector)
+{
+ struct amb_pinctrl_soc_data *soc;
+
+ soc = pinctrl_dev_get_drvdata(pctldev);
+ return soc->groups[selector].name;
+}
+
+/* return the pin numbers associated with the specified group */
+static int amb_get_group_pins(struct pinctrl_dev *pctldev,
+ unsigned selector, const unsigned **pins, unsigned *num_pins)
+{
+ struct amb_pinctrl_soc_data *soc;
+
+ soc = pinctrl_dev_get_drvdata(pctldev);
+ *pins = soc->groups[selector].pins;
+ *num_pins = soc->groups[selector].num_pins;
+ return 0;
+}
+
+static void amb_pin_dbg_show(struct pinctrl_dev *pctldev,
+ struct seq_file *s, unsigned pin)
+{
+ struct pin_desc *desc;
+
+ seq_printf(s, " %s", dev_name(pctldev->dev));
+
+ desc = pin_desc_get(pctldev, pin);
+ if (desc) {
+ seq_printf(s, " owner: %s%s%s%s",
+ desc->mux_owner ? desc->mux_owner : "",
+ desc->mux_owner && desc->gpio_owner ? " " : "",
+ desc->gpio_owner ? desc->gpio_owner : "",
+ !desc->mux_owner && !desc->gpio_owner ? "NULL" : "");
+ } else {
+ seq_printf(s, " not registered");
+ }
+}
+
+static int amb_dt_node_to_map(struct pinctrl_dev *pctldev,
+ struct device_node *np,
+ struct pinctrl_map **map, unsigned *num_maps)
+{
+ struct amb_pinctrl_soc_data *soc = pinctrl_dev_get_drvdata(pctldev);
+ struct ambpin_group *grp = NULL;
+ struct pinctrl_map *new_map;
+ char *grp_name = NULL;
+ int length = strlen(np->name) + SUFFIX_LENGTH;
+ u32 i, reg, new_num;
+
+ if (of_property_read_u32(np, "reg", &reg))
+ return -EINVAL;
+
+ /* Compose group name */
+ grp_name = devm_kzalloc(soc->dev, length, GFP_KERNEL);
+ if (!grp_name)
+ return -ENOMEM;
+
+ snprintf(grp_name, length, "%s.%d", np->name, reg);
+
+ /* find the group of this node by name */
+ for (i = 0; i < soc->nr_groups; i++) {
+ if (!strcmp(soc->groups[i].name, grp_name)) {
+ grp = &soc->groups[i];
+ break;
+ }
+ }
+ if (grp == NULL){
+ dev_err(soc->dev, "unable to find group for node %s\n", np->name);
+ return -EINVAL;
+ }
+
+ new_num = !!grp->num_pins + grp->num_conf_pins;
+ new_map = devm_kzalloc(soc->dev,
+ sizeof(struct pinctrl_map) * new_num, GFP_KERNEL);
+ if (!new_map)
+ return -ENOMEM;
+
+ *map = new_map;
+ *num_maps = new_num;
+
+ /* create mux map */
+ if (grp->num_pins) {
+ new_map[0].type = PIN_MAP_TYPE_MUX_GROUP;
+ new_map[0].data.mux.group = grp_name;
+ new_map[0].data.mux.function = np->name;
+ new_map++;
+ }
+
+ /* create config map */
+ for (i = 0; i < grp->num_conf_pins; i++) {
+ new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN;
+ new_map[i].data.configs.group_or_pin =
+ pin_get_name(pctldev, grp->conf_pins[i]);
+ new_map[i].data.configs.configs = &grp->conf[i];
+ new_map[i].data.configs.num_configs = 1;
+ }
+
+ return 0;
+}
+
+static void amb_dt_free_map(struct pinctrl_dev *pctldev,
+ struct pinctrl_map *map, unsigned num_maps)
+{
+}
+
+/* list of pinctrl callbacks for the pinctrl core */
+static const struct pinctrl_ops amb_pctrl_ops = {
+ .get_groups_count = amb_get_group_count,
+ .get_group_name = amb_get_group_name,
+ .get_group_pins = amb_get_group_pins,
+ .pin_dbg_show = amb_pin_dbg_show,
+ .dt_node_to_map = amb_dt_node_to_map,
+ .dt_free_map = amb_dt_free_map,
+};
+
+/* check if the selector is a valid pin function selector */
+static int amb_pinmux_request(struct pinctrl_dev *pctldev, unsigned pin)
+{
+ struct amb_pinctrl_soc_data *soc;
+ int rval = 0;
+
+ soc = pinctrl_dev_get_drvdata(pctldev);
+
+ if (test_and_set_bit(pin, soc->used))
+ rval = -EBUSY;
+
+ return rval;
+}
+
+/* check if the selector is a valid pin function selector */
+static int amb_pinmux_free(struct pinctrl_dev *pctldev, unsigned pin)
+{
+ struct amb_pinctrl_soc_data *soc;
+
+ soc = pinctrl_dev_get_drvdata(pctldev);
+ clear_bit(pin, soc->used);
+
+ return 0;
+}
+
+/* check if the selector is a valid pin function selector */
+static int amb_pinmux_get_fcount(struct pinctrl_dev *pctldev)
+{
+ struct amb_pinctrl_soc_data *soc;
+
+ soc = pinctrl_dev_get_drvdata(pctldev);
+ return soc->nr_functions;
+}
+
+/* return the name of the pin function specified */
+static const char *amb_pinmux_get_fname(struct pinctrl_dev *pctldev,
+ unsigned selector)
+{
+ struct amb_pinctrl_soc_data *soc;
+
+ soc = pinctrl_dev_get_drvdata(pctldev);
+ return soc->functions[selector].name;
+}
+
+/* return the groups associated for the specified function selector */
+static int amb_pinmux_get_groups(struct pinctrl_dev *pctldev,
+ unsigned selector, const char * const **groups,
+ unsigned * const num_groups)
+{
+ struct amb_pinctrl_soc_data *soc;
+
+ soc = pinctrl_dev_get_drvdata(pctldev);
+ *groups = soc->functions[selector].groups;
+ *num_groups = soc->functions[selector].num_groups;
+ return 0;
+}
+
+static void amb_pinmux_set_altfunc(struct amb_pinctrl_soc_data *soc,
+ u32 bank, u32 offset, enum amb_pin_altfunc altfunc)
+{
+ void __iomem *regbase = soc->regbase[bank];
+ void __iomem *iomux_reg;
+ u32 i, data;
+
+ if (altfunc == AMB_ALTFUNC_GPIO) {
+ amba_clrbitsl(regbase + GPIO_AFSEL_OFFSET, 0x1 << offset);
+ amba_clrbitsl(regbase + GPIO_DIR_OFFSET, 0x1 << offset);
+ } else {
+ amba_setbitsl(regbase + GPIO_AFSEL_OFFSET, 0x1 << offset);
+ amba_clrbitsl(regbase + GPIO_MASK_OFFSET, 0x1 << offset);
+ }
+
+ if (soc->iomux_base) {
+ for (i = 0; i < 3; i++) {
+ iomux_reg = soc->iomux_base + IOMUX_REG_OFFSET(bank, i);
+ data = amba_readl(iomux_reg);
+ data &= (~(0x1 << offset));
+ data |= (((altfunc >> i) & 0x1) << offset);
+ amba_writel(iomux_reg, data);
+ }
+ iomux_reg = soc->iomux_base + IOMUX_CTRL_SET_OFFSET;
+ amba_writel(iomux_reg, 0x1);
+ amba_writel(iomux_reg, 0x0);
+ }
+}
+
+/* enable a specified pinmux by writing to registers */
+static int amb_pinmux_enable(struct pinctrl_dev *pctldev,
+ unsigned selector, unsigned group)
+{
+ struct amb_pinctrl_soc_data *soc;
+ const struct ambpin_group *grp;
+ u32 i, bank, offset;
+
+ soc = pinctrl_dev_get_drvdata(pctldev);
+ grp = &soc->groups[group];
+
+ for (i = 0; i < grp->num_pins; i++) {
+ bank = PINID_TO_BANK(grp->pins[i]);
+ offset = PINID_TO_OFFSET(grp->pins[i]);
+ amb_pinmux_set_altfunc(soc, bank, offset, grp->alt[i]);
+ }
+
+ return 0;
+}
+
+/* disable a specified pinmux by writing to registers */
+static void amb_pinmux_disable(struct pinctrl_dev *pctldev,
+ unsigned selector, unsigned group)
+{
+ struct amb_pinctrl_soc_data *soc;
+ const struct ambpin_group *grp;
+
+ soc = pinctrl_dev_get_drvdata(pctldev);
+ grp = &soc->groups[group];
+
+ /* FIXME: poke out the mux, set the pin to some default state? */
+ dev_dbg(soc->dev,
+ "disable group %s, %u pins\n", grp->name, grp->num_pins);
+}
+
+static int amb_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range, unsigned pin)
+{
+ struct amb_pinctrl_soc_data *soc;
+ u32 bank, offset;
+
+ soc = pinctrl_dev_get_drvdata(pctldev);
+
+ if (!range || !range->gc) {
+ dev_err(soc->dev, "invalid range: %p\n", range);
+ return -EINVAL;
+ }
+
+ if (test_and_set_bit(pin, soc->used))
+ return -EBUSY;
+
+ bank = PINID_TO_BANK(pin);
+ offset = PINID_TO_OFFSET(pin);
+ amb_pinmux_set_altfunc(soc, bank, offset, AMB_ALTFUNC_GPIO);
+
+ return 0;
+}
+
+static void amb_pinmux_gpio_disable_free(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned pin)
+{
+ struct amb_pinctrl_soc_data *soc;
+
+ soc = pinctrl_dev_get_drvdata(pctldev);
+ dev_dbg(soc->dev, "disable pin %u as GPIO\n", pin);
+ /* Set the pin to some default state, GPIO is usually default */
+
+ clear_bit(pin, soc->used);
+}
+
+/*
+ * The calls to gpio_direction_output() and gpio_direction_input()
+ * leads to this function call (via the pinctrl_gpio_direction_{input|output}()
+ * function called from the gpiolib interface).
+ */
+static int amb_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned pin, bool input)
+{
+ struct amb_pinctrl_soc_data *soc;
+ void __iomem *regbase;
+ u32 bank, offset, mask;
+
+ soc = pinctrl_dev_get_drvdata(pctldev);
+
+ bank = PINID_TO_BANK(pin);
+ offset = PINID_TO_OFFSET(pin);
+ regbase = soc->regbase[bank];
+ mask = (0x1 << offset);
+
+ amba_clrbitsl(regbase + GPIO_AFSEL_OFFSET, mask);
+ if (input)
+ amba_clrbitsl(regbase + GPIO_DIR_OFFSET, mask);
+ else
+ amba_setbitsl(regbase + GPIO_DIR_OFFSET, mask);
+
+ return 0;
+}
+
+/* list of pinmux callbacks for the pinmux vertical in pinctrl core */
+static const struct pinmux_ops amb_pinmux_ops = {
+ .request = amb_pinmux_request,
+ .free = amb_pinmux_free,
+ .get_functions_count = amb_pinmux_get_fcount,
+ .get_function_name = amb_pinmux_get_fname,
+ .get_function_groups = amb_pinmux_get_groups,
+ .enable = amb_pinmux_enable,
+ .disable = amb_pinmux_disable,
+ .gpio_request_enable = amb_pinmux_gpio_request_enable,
+ .gpio_disable_free = amb_pinmux_gpio_disable_free,
+ .gpio_set_direction = amb_pinmux_gpio_set_direction,
+};
+
+/* set the pin config settings for a specified pin */
+static int amb_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+ unsigned long config)
+{
+ struct amb_pinctrl_soc_data *soc;
+ u32 bank, offset, reg, val;
+
+ soc = pinctrl_dev_get_drvdata(pctldev);
+ bank = PINID_TO_BANK(pin);
+ offset = PINID_TO_OFFSET(pin);
+
+ if (CFG_PULL_PRESENT(config)) {
+ reg = GPIO_PAD_PULL_REG(GPIO_PAD_PULL_DIR_OFFSET(bank));
+ amba_clrbitsl(reg, 1 << offset);
+ amba_setbitsl(reg, CONF_TO_PULL_VAL(config) << offset);
+
+ reg = GPIO_PAD_PULL_REG(GPIO_PAD_PULL_EN_OFFSET(bank));
+ if (CONF_TO_PULL_CLR(config))
+ amba_clrbitsl(reg, 1 << offset);
+ else
+ amba_setbitsl(reg, 1 << offset);
+ }
+
+ if (CFG_DS_PRESENT(config)) {
+ amba_clrbitsl(RCT_REG(GPIO_DS0_OFFSET(bank)), 1 << offset);
+ amba_clrbitsl(RCT_REG(GPIO_DS1_OFFSET(bank)), 1 << offset);
+ /* set bit1 of DS value to DS0 reg, and set bit0 of DS value to DS1 reg,
+ * because bit[1:0] = 00 is 2mA, 10 is 4mA, 01 is 8mA, 11 is 12mA */
+ val = (CONF_TO_DS_VAL(config) >> 1) & 0x1;
+ amba_setbitsl(RCT_REG(GPIO_DS0_OFFSET(bank)), val << offset);
+ val = CONF_TO_DS_VAL(config) & 0x1;
+ amba_setbitsl(RCT_REG(GPIO_DS1_OFFSET(bank)), val << offset);
+ }
+
+ return 0;
+}
+
+/* get the pin config settings for a specified pin */
+static int amb_pinconf_get(struct pinctrl_dev *pctldev,
+ unsigned int pin, unsigned long *config)
+{
+ dev_WARN_ONCE(pctldev->dev, true, "NOT Implemented.\n");
+ return -ENOTSUPP;
+}
+
+static void amb_pinconf_dbg_show(struct pinctrl_dev *pctldev,
+ struct seq_file *s, unsigned pin)
+{
+ struct amb_pinctrl_soc_data *soc;
+ u32 bank, offset, reg;
+ u32 pull_en, pull_dir, drv_strength;
+
+ soc = pinctrl_dev_get_drvdata(pctldev);
+ bank = PINID_TO_BANK(pin);
+ offset = PINID_TO_OFFSET(pin);
+
+ reg = GPIO_PAD_PULL_REG(GPIO_PAD_PULL_EN_OFFSET(bank));
+ pull_en = (amba_readl(reg) >> offset) & 0x1;
+
+ reg = GPIO_PAD_PULL_REG(GPIO_PAD_PULL_DIR_OFFSET(bank));
+ pull_dir = (amba_readl(reg) >> offset) & 0x1;
+
+ seq_printf(s, " pull: %s, ", pull_en ? pull_dir ? "up" : "down" : "disable");
+
+ reg = RCT_REG(GPIO_DS0_OFFSET(bank));
+ drv_strength = ((amba_readl(reg) >> offset) & 0x1) << 1;
+ reg = RCT_REG(GPIO_DS1_OFFSET(bank));
+ drv_strength |= (amba_readl(reg) >> offset) & 0x1;
+
+ seq_printf(s, "drive-strength: %s",
+ drv_strength == 3 ? "12mA" : drv_strength == 2 ? "8mA" :
+ drv_strength == 1 ? "4mA" : "2mA");
+}
+
+/* list of pinconfig callbacks for pinconfig vertical in the pinctrl code */
+static const struct pinconf_ops amb_pinconf_ops = {
+ .pin_config_get = amb_pinconf_get,
+ .pin_config_set = amb_pinconf_set,
+ .pin_config_dbg_show = amb_pinconf_dbg_show,
+};
+
+static struct pinctrl_desc amb_pinctrl_desc = {
+ .pctlops = &amb_pctrl_ops,
+ .pmxops = &amb_pinmux_ops,
+ .confops = &amb_pinconf_ops,
+ .owner = THIS_MODULE,
+};
+
+static int amb_pinctrl_parse_group(struct amb_pinctrl_soc_data *soc,
+ struct device_node *np, int idx, const char **out_name)
+{
+ struct ambpin_group *grp = &soc->groups[idx];
+ struct property *prop;
+ const char *prop_name;
+ char *grp_name;
+ int length = strlen(np->name) + SUFFIX_LENGTH;
+ u32 reg, i;
+
+ grp_name = devm_kzalloc(soc->dev, length, GFP_KERNEL);
+ if (!grp_name)
+ return -ENOMEM;
+
+ if (of_property_read_u32(np, "reg", &reg))
+ return -EINVAL;
+
+ snprintf(grp_name, length, "%s.%d", np->name, reg);
+
+ grp->name = grp_name;
+
+ prop_name = "amb,pinmux-ids";
+ prop = of_find_property(np, prop_name, &length);
+ if (prop) {
+ grp->num_pins = length / sizeof(u32);
+
+ grp->pins = devm_kzalloc(soc->dev,
+ grp->num_pins * sizeof(u32), GFP_KERNEL);
+ if (!grp->pins)
+ return -ENOMEM;
+
+ grp->alt = devm_kzalloc(soc->dev,
+ grp->num_pins * sizeof(u8), GFP_KERNEL);
+ if (!grp->alt)
+ return -ENOMEM;
+
+ of_property_read_u32_array(np, prop_name, grp->pins, grp->num_pins);
+
+ for (i = 0; i < grp->num_pins; i++) {
+ grp->alt[i] = MUXIDS_TO_ALT(grp->pins[i]);
+ grp->pins[i] = MUXIDS_TO_PINID(grp->pins[i]);
+ }
+ }
+
+ /* parse pinconf */
+ prop_name = "amb,pinconf-ids";
+ prop = of_find_property(np, prop_name, &length);
+ if (prop) {
+ grp->num_conf_pins = length / sizeof(u32);
+
+ grp->conf_pins = devm_kzalloc(soc->dev,
+ grp->num_conf_pins * sizeof(u32), GFP_KERNEL);
+ if (!grp->conf_pins)
+ return -ENOMEM;
+
+ grp->conf = devm_kzalloc(soc->dev,
+ grp->num_conf_pins * sizeof(unsigned long), GFP_KERNEL);
+ if (!grp->conf)
+ return -ENOMEM;
+
+ of_property_read_u32_array(np, prop_name, grp->conf_pins, grp->num_conf_pins);
+
+ for (i = 0; i < grp->num_conf_pins; i++) {
+ grp->conf[i] = CONFIDS_TO_CONF(grp->conf_pins[i]);
+ grp->conf_pins[i] = CONFIDS_TO_PINID(grp->conf_pins[i]);
+ }
+ }
+
+ if (out_name)
+ *out_name = grp->name;
+
+ return 0;
+}
+
+static int amb_pinctrl_parse_dt(struct amb_pinctrl_soc_data *soc)
+{
+ struct device_node *np = soc->dev->of_node;
+ struct device_node *child;
+ struct ambpin_function *f;
+ const char *gpio_compat = "ambarella,gpio";
+ const char *fn;
+ int i = 0, idxf = 0, idxg = 0;
+ int ret;
+
+ child = of_get_next_child(np, NULL);
+ if (!child) {
+ dev_err(soc->dev, "no group is defined\n");
+ return -ENOENT;
+ }
+
+ /* Count total functions and groups */
+ fn = "";
+ for_each_child_of_node(np, child) {
+ if (of_device_is_compatible(child, gpio_compat))
+ continue;
+ soc->nr_groups++;
+ if (strcmp(fn, child->name)) {
+ fn = child->name;
+ soc->nr_functions++;
+ }
+ }
+
+ soc->functions = devm_kzalloc(soc->dev, soc->nr_functions *
+ sizeof(struct ambpin_function), GFP_KERNEL);
+ if (!soc->functions)
+ return -ENOMEM;
+
+ soc->groups = devm_kzalloc(soc->dev, soc->nr_groups *
+ sizeof(struct ambpin_group), GFP_KERNEL);
+ if (!soc->groups)
+ return -ENOMEM;
+
+ /* Count groups for each function */
+ fn = "";
+ f = &soc->functions[idxf];
+ for_each_child_of_node(np, child) {
+ if (of_device_is_compatible(child, gpio_compat))
+ continue;
+ if (strcmp(fn, child->name)) {
+ f = &soc->functions[idxf++];
+ f->name = fn = child->name;
+ }
+ f->num_groups++;
+ };
+
+ /* Get groups for each function */
+ fn = "";
+ idxf = 0;
+ for_each_child_of_node(np, child) {
+ if (of_device_is_compatible(child, gpio_compat))
+ continue;
+
+ if (strcmp(fn, child->name)) {
+ f = &soc->functions[idxf++];
+ f->groups = devm_kzalloc(soc->dev,
+ f->num_groups * sizeof(*f->groups),
+ GFP_KERNEL);
+ if (!f->groups)
+ return -ENOMEM;
+ fn = child->name;
+ i = 0;
+ }
+
+ ret = amb_pinctrl_parse_group(soc, child,
+ idxg++, &f->groups[i++]);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+/* register the pinctrl interface with the pinctrl subsystem */
+static int amb_pinctrl_register(struct amb_pinctrl_soc_data *soc)
+{
+ struct pinctrl_pin_desc *pindesc;
+ char *pin_names;
+ int pin, rval;
+
+ /* dynamically populate the pin number and pin name for pindesc */
+ pindesc = devm_kzalloc(soc->dev,
+ sizeof(*pindesc) * AMBGPIO_SIZE, GFP_KERNEL);
+ if (!pindesc) {
+ dev_err(soc->dev, "No memory for pin desc\n");
+ return -ENOMEM;
+ }
+
+ pin_names = devm_kzalloc(soc->dev,
+ PIN_NAME_LENGTH * AMBGPIO_SIZE, GFP_KERNEL);
+ if (!pin_names) {
+ dev_err(soc->dev, "No memory for pin names\n");
+ return -ENOMEM;
+ }
+
+ for (pin = 0; pin < AMBGPIO_SIZE; pin++) {
+ pindesc[pin].number = pin;
+ sprintf(pin_names, "io%d", pin);
+ pindesc[pin].name = pin_names;
+ pin_names += PIN_NAME_LENGTH;
+ }
+
+ amb_pinctrl_desc.name = dev_name(soc->dev);
+ amb_pinctrl_desc.pins = pindesc;
+ amb_pinctrl_desc.npins = AMBGPIO_SIZE;
+
+ rval = amb_pinctrl_parse_dt(soc);
+ if (rval)
+ return rval;
+
+ soc->pctl = pinctrl_register(&amb_pinctrl_desc, soc->dev, soc);
+ if (!soc->pctl) {
+ dev_err(soc->dev, "could not register pinctrl driver\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int amb_pinctrl_probe(struct platform_device *pdev)
+{
+ struct amb_pinctrl_soc_data *soc;
+ struct resource *res;
+ int i, rval;
+
+ soc = devm_kzalloc(&pdev->dev, sizeof(*soc), GFP_KERNEL);
+ if (!soc) {
+ dev_err(&pdev->dev, "failed to allocate memory for private data\n");
+ return -ENOMEM;
+ }
+ soc->dev = &pdev->dev;
+
+ for (i = 0; i < GPIO_INSTANCES; i++) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "no mem resource for gpio[%d]!\n", i);
+ return -ENXIO;
+ }
+
+ soc->regbase[i] = devm_ioremap(&pdev->dev,
+ res->start, resource_size(res));
+ if (soc->regbase[i] == 0) {
+ dev_err(&pdev->dev, "devm_ioremap() failed\n");
+ return -ENOMEM;
+ }
+ }
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iomux");
+ if (res != NULL) {
+ soc->iomux_base = devm_ioremap(&pdev->dev,
+ res->start, resource_size(res));
+ if (soc->iomux_base == 0) {
+ dev_err(&pdev->dev, "devm_ioremap() failed\n");
+ return -ENOMEM;
+ }
+
+ amb_iomux_base = soc->iomux_base;
+ }
+
+ rval = amb_pinctrl_register(soc);
+ if (rval)
+ return rval;
+
+ platform_set_drvdata(pdev, soc);
+ dev_info(&pdev->dev, "Ambarella pinctrl driver registered\n");
+
+ return 0;
+}
+
+#if defined(CONFIG_PM)
+
+static u32 amb_iomux_pm_reg[GPIO_INSTANCES][3];
+static u32 amb_pull_pm_reg[2][GPIO_INSTANCES];
+static u32 amb_ds_pm_reg[GPIO_INSTANCES][2];
+
+static int amb_pinctrl_suspend(void)
+{
+ u32 i, j, reg;
+
+ for (i = 0; i < GPIO_INSTANCES; i++) {
+ reg = GPIO_PAD_PULL_REG(GPIO_PAD_PULL_EN_OFFSET(i));
+ amb_pull_pm_reg[0][i] = amba_readl(reg);
+ reg = GPIO_PAD_PULL_REG(GPIO_PAD_PULL_DIR_OFFSET(i));
+ amb_pull_pm_reg[1][i] = amba_readl(reg);
+ }
+
+ for (i = 0; i < GPIO_INSTANCES; i++) {
+ amb_ds_pm_reg[i][0] = amba_readl(RCT_REG(GPIO_DS0_OFFSET(i)));
+ amb_ds_pm_reg[i][1] = amba_readl(RCT_REG(GPIO_DS1_OFFSET(i)));
+ }
+
+ if (amb_iomux_base == NULL)
+ return 0;
+
+ for (i = 0; i < GPIO_INSTANCES; i++) {
+ for (j = 0; j < 3; j++) {
+ reg = (u32)amb_iomux_base + IOMUX_REG_OFFSET(i, j);
+ amb_iomux_pm_reg[i][j] = amba_readl(reg);
+ }
+ }
+
+ return 0;
+}
+
+static void amb_pinctrl_resume(void)
+{
+ u32 i, j, reg;
+
+ for (i = 0; i < GPIO_INSTANCES; i++) {
+ reg = GPIO_PAD_PULL_REG(GPIO_PAD_PULL_EN_OFFSET(i));
+ amba_writel(reg, amb_pull_pm_reg[0][i]);
+ reg = GPIO_PAD_PULL_REG(GPIO_PAD_PULL_DIR_OFFSET(i));
+ amba_writel(reg, amb_pull_pm_reg[1][i]);
+ }
+
+ for (i = 0; i < GPIO_INSTANCES; i++) {
+ amba_writel(RCT_REG(GPIO_DS0_OFFSET(i)), amb_ds_pm_reg[i][0]);
+ amba_writel(RCT_REG(GPIO_DS1_OFFSET(i)), amb_ds_pm_reg[i][1]);
+ }
+
+ if (amb_iomux_base == NULL)
+ return;
+
+ for (i = 0; i < GPIO_INSTANCES; i++) {
+ for (j = 0; j < 3; j++) {
+ reg = (u32)amb_iomux_base + IOMUX_REG_OFFSET(i, j);
+ amba_writel(reg, amb_iomux_pm_reg[i][j]);
+ }
+ }
+
+ amba_writel(amb_iomux_base + IOMUX_CTRL_SET_OFFSET, 0x1);
+ amba_writel(amb_iomux_base + IOMUX_CTRL_SET_OFFSET, 0x0);
+}
+
+static struct syscore_ops amb_pinctrl_syscore_ops = {
+ .suspend = amb_pinctrl_suspend,
+ .resume = amb_pinctrl_resume,
+};
+
+#endif /* CONFIG_PM */
+
+static const struct of_device_id amb_pinctrl_dt_match[] = {
+ { .compatible = "ambarella,pinctrl" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, amb_pinctrl_dt_match);
+
+static struct platform_driver amb_pinctrl_driver = {
+ .probe = amb_pinctrl_probe,
+ .driver = {
+ .name = "ambarella-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(amb_pinctrl_dt_match),
+ },
+};
+
+static int __init amb_pinctrl_drv_register(void)
+{
+#ifdef CONFIG_PM
+ register_syscore_ops(&amb_pinctrl_syscore_ops);
+#endif
+ return platform_driver_register(&amb_pinctrl_driver);
+}
+postcore_initcall(amb_pinctrl_drv_register);
+
+MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
+MODULE_DESCRIPTION("Ambarella SoC pinctrl driver");
+MODULE_LICENSE("GPL v2");
+
+
diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c
index 3ccadf63..7b1ec8b0 100644
--- a/drivers/power/wm831x_power.c
+++ b/drivers/power/wm831x_power.c
@@ -18,6 +18,7 @@
#include <linux/mfd/wm831x/auxadc.h>
#include <linux/mfd/wm831x/pmu.h>
#include <linux/mfd/wm831x/pdata.h>
+#include <linux/mfd/wm831x/irq.h>
struct wm831x_power {
struct wm831x *wm831x;
@@ -649,8 +650,66 @@ static int wm831x_power_remove(struct platform_device *pdev)
power_supply_unregister(&wm831x_power->wall);
power_supply_unregister(&wm831x_power->usb);
kfree(wm831x_power);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int wm831x_power_suppend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ int irq, i;
+
+ for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
+ irq = platform_get_irq_byname(pdev, wm831x_bat_irqs[i]);
+ disable_irq(irq);
+ }
+
+ irq = platform_get_irq_byname(pdev, "PWR SRC");
+ disable_irq(irq);
+
+ irq = platform_get_irq_byname(pdev, "SYSLO");
+ disable_irq(irq);
+
+ return 0;
+}
+
+static int wm831x_power_resume(struct platform_device *pdev)
+{
+ struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
+ struct wm831x_pdata *wm831x_pdata = wm831x->dev->platform_data;
+ int irq, i;
+
+ for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
+ irq = platform_get_irq_byname(pdev, wm831x_bat_irqs[i]);
+ enable_irq(irq);
+ }
+
+ irq = platform_get_irq_byname(pdev, "PWR SRC");
+ enable_irq(irq);
+
+ irq = platform_get_irq_byname(pdev, "SYSLO");
+ enable_irq(irq);
+
+ if (wm831x_pdata && wm831x_pdata->irq_cmos)
+ i = 0;
+ else
+ i = WM831X_IRQ_OD;
+
+ wm831x_set_bits(wm831x, WM831X_IRQ_CONFIG,
+ WM831X_IRQ_OD, i);
+
+ wm831x_reg_write(wm831x, WM831X_SYSTEM_INTERRUPTS_MASK, 0);
+
+ for(i=0;i<ARRAY_SIZE(wm831x->irq_masks_cur);i++){
+ wm831x_reg_write(wm831x,
+ WM831X_INTERRUPT_STATUS_1_MASK + i,
+ wm831x->irq_masks_cache[i]);
+ }
+
return 0;
}
+#endif
static struct platform_driver wm831x_power_driver = {
.probe = wm831x_power_probe,
@@ -658,6 +717,10 @@ static struct platform_driver wm831x_power_driver = {
.driver = {
.name = "wm831x-power",
},
+#ifdef CONFIG_PM
+ .suspend = wm831x_power_suppend,
+ .resume = wm831x_power_resume,
+#endif
};
module_platform_driver(wm831x_power_driver);
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 115b6445..24a11249 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -28,6 +28,15 @@ menuconfig PWM
if PWM
+config PWM_AMBARELLA
+ tristate "Ambarella PWM support"
+ depends on ARCH_AMBARELLA && OF
+ help
+ Generic PWM framework driver for Ambarella chips.
+
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-ambarella.
+
config PWM_AB8500
tristate "AB8500 PWM support"
depends on AB8500_CORE && ARCH_U8500
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 94ba21e2..db8a9978 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -1,4 +1,5 @@
obj-$(CONFIG_PWM) += core.o
+obj-$(CONFIG_PWM_AMBARELLA) += pwm-ambarella.o
obj-$(CONFIG_PWM_AB8500) += pwm-ab8500.o
obj-$(CONFIG_PWM_ATMEL_TCB) += pwm-atmel-tcb.o
obj-$(CONFIG_PWM_BFIN) += pwm-bfin.o
diff --git a/drivers/pwm/pwm-ambarella.c b/drivers/pwm/pwm-ambarella.c
new file mode 100644
index 00000000..d5995bf3
--- /dev/null
+++ b/drivers/pwm/pwm-ambarella.c
@@ -0,0 +1,270 @@
+/*
+ * drivers/pwm/pwm-ambarella.c
+ *
+ * History:
+ * 2014/03/19 - [Cao Rongrong] Created
+ *
+ * Copyright (C) 2012-2016, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/slab.h>
+#include <plat/pwm.h>
+
+#define PWM_DEFAULT_FREQUENCY 2200000
+
+struct ambarella_pwm_chip {
+ struct pwm_chip chip;
+ void __iomem *base;
+ void __iomem *base2; /* for the individual pwm controller if existed */
+ struct clk *clk;
+ enum pwm_polarity polarity[PWM_INSTANCES];
+};
+
+#define to_ambarella_pwm_chip(_chip) container_of(_chip, struct ambarella_pwm_chip, chip)
+
+static u32 ambpwm_enable_offset[] = {
+ PWM_B0_ENABLE_OFFSET,
+ PWM_B1_ENABLE_OFFSET,
+ PWM_C0_ENABLE_OFFSET,
+ PWM_C1_ENABLE_OFFSET,
+ PWM_ENABLE_OFFSET,
+};
+
+static u32 ambpwm_divider_offset[] = {
+ PWM_B0_ENABLE_OFFSET,
+ PWM_B1_ENABLE_OFFSET,
+ PWM_C0_ENABLE_OFFSET,
+ PWM_C1_ENABLE_OFFSET,
+ PWM_MODE_OFFSET,
+};
+
+static u32 ambpwm_data_offset[] = {
+ PWM_B0_DATA1_OFFSET,
+ PWM_B1_DATA1_OFFSET,
+ PWM_C0_DATA1_OFFSET,
+ PWM_C1_DATA1_OFFSET,
+ PWM_CONTROL_OFFSET,
+};
+
+static bool ambpwm_is_chief[] = {true, false, true, false, false};
+
+static int ambarella_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+ int duty_ns, int period_ns)
+{
+ struct ambarella_pwm_chip *ambpwm = to_ambarella_pwm_chip(chip);
+ void __iomem *base;
+ void __iomem *reg;
+ u32 tick_bits, clock, total, on, off, div;
+
+ /* we arrange the id of the individual pwm to the last one */
+ if (ambpwm->base2 && pwm->hwpwm == PWM_INSTANCES - 1) {
+ base = ambpwm->base2;
+ tick_bits = PWM_PWM_TICKS_MAX_BITS;
+ } else {
+ base = ambpwm->base;
+ tick_bits = PWM_ST_TICKS_MAX_BITS;
+ }
+
+ reg = base + ambpwm_enable_offset[pwm->hwpwm];
+ if (ambpwm_is_chief[pwm->hwpwm])
+ amba_setbitsl(reg, PWM_CLK_SRC_BIT);
+ else
+ amba_clrbitsl(reg, PWM_INV_EN_BIT);
+
+ clock = (clk_get_rate(clk_get(NULL, "gclk_pwm")) + 50000) / 100000;
+ total = (clock * period_ns + 5000) / 10000;
+ div = total >> tick_bits;
+ clock /= (div + 1);
+ reg = base + ambpwm_divider_offset[pwm->hwpwm];
+ amba_clrbitsl(reg, PWM_DIVIDER_MASK);
+ amba_setbitsl(reg, div << 1);
+
+ total = (clock * period_ns + 5000) / 10000;
+ on = (clock * duty_ns + 5000) / 10000;
+ off = total - on;
+ if (on == 0)
+ on = 1;
+ if (off == 0)
+ off = 1;
+
+ reg = base + ambpwm_data_offset[pwm->hwpwm];
+ if (ambpwm->polarity[pwm->hwpwm] == PWM_POLARITY_NORMAL)
+ amba_writel(reg, (on - 1) << tick_bits | (off - 1));
+ else
+ amba_writel(reg, (off - 1) << tick_bits | (on - 1));
+
+ return 0;
+}
+
+static int ambarella_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct ambarella_pwm_chip *ambpwm = to_ambarella_pwm_chip(chip);
+ void __iomem *reg;
+
+ /* we arrange the id of the individual pwm to the last one */
+ if (ambpwm->base2 && pwm->hwpwm == PWM_INSTANCES - 1)
+ reg = ambpwm->base2 + ambpwm_enable_offset[pwm->hwpwm];
+ else
+ reg = ambpwm->base + ambpwm_enable_offset[pwm->hwpwm];
+
+ amba_setbitsl(reg, PWM_PWM_EN_BIT);
+
+ return 0;
+}
+
+static void ambarella_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct ambarella_pwm_chip *ambpwm = to_ambarella_pwm_chip(chip);
+ void __iomem *reg;
+
+ /* we arrange the id of the individual pwm to the last one */
+ if (ambpwm->base2 && pwm->hwpwm == PWM_INSTANCES - 1)
+ reg = ambpwm->base2 + ambpwm_enable_offset[pwm->hwpwm];
+ else
+ reg = ambpwm->base + ambpwm_enable_offset[pwm->hwpwm];
+
+ amba_clrbitsl(reg, PWM_PWM_EN_BIT);
+}
+
+static int ambarella_pwm_set_polarity(struct pwm_chip *chip,
+ struct pwm_device *pwm, enum pwm_polarity polarity)
+{
+ struct ambarella_pwm_chip *ambpwm = to_ambarella_pwm_chip(chip);
+
+ ambpwm->polarity[pwm->hwpwm] = polarity;
+
+ return 0;
+}
+
+static const struct pwm_ops ambarella_pwm_ops = {
+ .config = ambarella_pwm_config,
+ .enable = ambarella_pwm_enable,
+ .disable = ambarella_pwm_disable,
+ .set_polarity = ambarella_pwm_set_polarity,
+ .owner = THIS_MODULE,
+};
+
+static int ambarella_pwm_probe(struct platform_device *pdev)
+{
+ struct ambarella_pwm_chip *ambpwm;
+ struct resource *res;
+ int ret;
+
+ BUG_ON(ARRAY_SIZE(ambpwm_enable_offset) < PWM_INSTANCES);
+
+ ambpwm = devm_kzalloc(&pdev->dev, sizeof(*ambpwm), GFP_KERNEL);
+ if (!ambpwm)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL)
+ return -ENXIO;
+
+ ambpwm->base = devm_ioremap(&pdev->dev,
+ res->start, resource_size(res));
+ if (IS_ERR(ambpwm->base))
+ return PTR_ERR(ambpwm->base);
+
+ ambpwm->base2 = NULL;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (res != NULL) {
+ ambpwm->base2 = devm_ioremap(&pdev->dev,
+ res->start, resource_size(res));
+ if (IS_ERR(ambpwm->base2))
+ return PTR_ERR(ambpwm->base);
+ }
+
+ ambpwm->clk = clk_get(NULL, "gclk_pwm");
+ if (IS_ERR(ambpwm->clk))
+ return PTR_ERR(ambpwm->clk);
+
+ clk_set_rate(clk_get(NULL, "gclk_pwm"), PWM_DEFAULT_FREQUENCY);
+
+ ambpwm->chip.dev = &pdev->dev;
+ ambpwm->chip.ops = &ambarella_pwm_ops;
+ ambpwm->chip.of_xlate = of_pwm_xlate_with_flags;
+ ambpwm->chip.of_pwm_n_cells = 3;
+ ambpwm->chip.base = -1;
+ ambpwm->chip.npwm = PWM_INSTANCES;
+
+ ret = pwmchip_add(&ambpwm->chip);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to add pwm chip %d\n", ret);
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, ambpwm);
+
+ return 0;
+}
+
+static int ambarella_pwm_remove(struct platform_device *pdev)
+{
+ struct ambarella_pwm_chip *ambpwm = platform_get_drvdata(pdev);
+
+ return pwmchip_remove(&ambpwm->chip);
+}
+
+#ifdef CONFIG_PM
+static int ambarella_pwm_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ return 0;
+}
+
+static int ambarella_pwm_resume(struct platform_device *pdev)
+{
+ clk_set_rate(clk_get(NULL, "gclk_pwm"), PWM_DEFAULT_FREQUENCY);
+ return 0;
+}
+#endif
+
+static const struct of_device_id ambarella_pwm_dt_ids[] = {
+ { .compatible = "ambarella,pwm", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, ambarella_pwm_dt_ids);
+
+static struct platform_driver ambarella_pwm_driver = {
+ .driver = {
+ .name = "ambarella-pwm",
+ .of_match_table = of_match_ptr(ambarella_pwm_dt_ids),
+ },
+ .probe = ambarella_pwm_probe,
+ .remove = ambarella_pwm_remove,
+#ifdef CONFIG_PM
+ .suspend = ambarella_pwm_suspend,
+ .resume = ambarella_pwm_resume,
+#endif
+};
+module_platform_driver(ambarella_pwm_driver);
+
+MODULE_ALIAS("platform:ambarella-pwm");
+MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
+MODULE_DESCRIPTION("Ambarella PWM Driver");
+MODULE_LICENSE("GPL v2");
+
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 70ccc201..1d7a283c 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -312,7 +312,49 @@ static ssize_t regulator_uV_show(struct device *dev,
return ret;
}
-static DEVICE_ATTR(microvolts, 0444, regulator_uV_show, NULL);
+
+static ssize_t regulator_uV_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct regulator_dev *rdev = dev_get_drvdata(dev);
+ ssize_t status;
+ long value;
+ int ret;
+ int min_uV, max_uV ;
+
+ mutex_lock(&rdev->mutex);
+ status = strict_strtol(buf, 0, &value);
+ if (status != 0)
+ goto out;
+
+ /* sanity check */
+ if (!rdev->desc->ops->set_voltage &&
+ !rdev->desc->ops->set_voltage_sel)
+ goto out;
+
+ min_uV = max_uV = value;
+ /* constraints check */
+ ret = regulator_check_voltage(rdev, &min_uV, &max_uV);
+ if (ret < 0)
+ goto out;
+
+ ret = regulator_check_consumers(rdev, &min_uV, &max_uV);
+ if (ret < 0)
+ goto out;
+
+ ret = _regulator_do_set_voltage(rdev, min_uV, max_uV);
+ if (ret < 0)
+ goto out;
+
+out:
+ mutex_unlock(&rdev->mutex);
+
+ return count;
+}
+
+
+static DEVICE_ATTR(microvolts, 0644, regulator_uV_show, regulator_uV_store);
static ssize_t regulator_uA_show(struct device *dev,
struct device_attribute *attr, char *buf)
diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c
index 0af6898b..40964a3d 100644
--- a/drivers/regulator/wm831x-dcdc.c
+++ b/drivers/regulator/wm831x-dcdc.c
@@ -365,6 +365,16 @@ static int wm831x_buckv_get_current_limit(struct regulator_dev *rdev)
return wm831x_dcdc_ilim[val];
}
+static int wm831x_buckv_set_suspend_enable(struct regulator_dev *rdev)
+{
+ return 0;
+}
+
+static int wm831x_buckv_set_suspend_disable(struct regulator_dev *rdev)
+{
+ return 0;
+}
+
static struct regulator_ops wm831x_buckv_ops = {
.set_voltage_sel = wm831x_buckv_set_voltage_sel,
.get_voltage_sel = wm831x_buckv_get_voltage_sel,
@@ -381,6 +391,8 @@ static struct regulator_ops wm831x_buckv_ops = {
.get_mode = wm831x_dcdc_get_mode,
.set_mode = wm831x_dcdc_set_mode,
.set_suspend_mode = wm831x_dcdc_set_suspend_mode,
+ .set_suspend_enable = wm831x_buckv_set_suspend_enable,
+ .set_suspend_disable = wm831x_buckv_set_suspend_disable,
};
/*
@@ -607,6 +619,16 @@ static int wm831x_buckp_set_suspend_voltage(struct regulator_dev *rdev, int uV)
return wm831x_set_bits(wm831x, reg, WM831X_DC3_ON_VSEL_MASK, sel);
}
+static int wm831x_buckp_set_suspend_enable(struct regulator_dev *rdev)
+{
+ return 0;
+}
+
+static int wm831x_buckp_set_suspend_disable(struct regulator_dev *rdev)
+{
+ return 0;
+}
+
static struct regulator_ops wm831x_buckp_ops = {
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
@@ -621,6 +643,8 @@ static struct regulator_ops wm831x_buckp_ops = {
.get_mode = wm831x_dcdc_get_mode,
.set_mode = wm831x_dcdc_set_mode,
.set_suspend_mode = wm831x_dcdc_set_suspend_mode,
+ .set_suspend_enable = wm831x_buckp_set_suspend_enable,
+ .set_suspend_disable = wm831x_buckp_set_suspend_disable,
};
static int wm831x_buckp_probe(struct platform_device *pdev)
diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c
index 1ec379a9..747daef0 100644
--- a/drivers/regulator/wm831x-ldo.c
+++ b/drivers/regulator/wm831x-ldo.c
@@ -228,6 +228,15 @@ static unsigned int wm831x_gp_ldo_get_optimum_mode(struct regulator_dev *rdev,
return REGULATOR_MODE_NORMAL;
}
+static int wm831x_gp_ldo_set_suspend_enable(struct regulator_dev *rdev)
+{
+ return 0;
+}
+
+static int wm831x_gp_ldo_set_suspend_disable(struct regulator_dev *rdev)
+{
+ return 0;
+}
static struct regulator_ops wm831x_gp_ldo_ops = {
.list_voltage = wm831x_gp_ldo_list_voltage,
@@ -245,6 +254,8 @@ static struct regulator_ops wm831x_gp_ldo_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
+ .set_suspend_enable = wm831x_gp_ldo_set_suspend_enable,
+ .set_suspend_disable = wm831x_gp_ldo_set_suspend_disable,
};
static int wm831x_gp_ldo_probe(struct platform_device *pdev)
@@ -487,6 +498,16 @@ static int wm831x_aldo_get_status(struct regulator_dev *rdev)
return regulator_mode_to_status(ret);
}
+static int wm831x_aldo_set_suspend_enable(struct regulator_dev *rdev)
+{
+ return 0;
+}
+
+static int wm831x_aldo_set_suspend_disable(struct regulator_dev *rdev)
+{
+ return 0;
+}
+
static struct regulator_ops wm831x_aldo_ops = {
.list_voltage = wm831x_aldo_list_voltage,
.map_voltage = wm831x_aldo_map_voltage,
@@ -502,6 +523,8 @@ static struct regulator_ops wm831x_aldo_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
+ .set_suspend_enable = wm831x_aldo_set_suspend_enable,
+ .set_suspend_disable = wm831x_aldo_set_suspend_disable,
};
static int wm831x_aldo_probe(struct platform_device *pdev)
diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index d4d377c4..2c7a43a9 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -63,4 +63,5 @@ config DA8XX_REMOTEPROC
It's safe to say n here if you're not interested in multimedia
offloading.
+source "drivers/remoteproc/ambarella/Kconfig"
endmenu
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index ac2ff756..d6b8ce6a 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -7,6 +7,8 @@ remoteproc-y := remoteproc_core.o
remoteproc-y += remoteproc_debugfs.o
remoteproc-y += remoteproc_virtio.o
remoteproc-y += remoteproc_elf_loader.o
+remoteproc-y += remoteproc_dummy_loader.o
obj-$(CONFIG_OMAP_REMOTEPROC) += omap_remoteproc.o
obj-$(CONFIG_STE_MODEM_RPROC) += ste_modem_rproc.o
obj-$(CONFIG_DA8XX_REMOTEPROC) += da8xx_remoteproc.o
+obj-$(CONFIG_PLAT_AMBARELLA_SUPPORT_RPROC) += ambarella/
diff --git a/drivers/remoteproc/ambarella/Kconfig b/drivers/remoteproc/ambarella/Kconfig
new file mode 100644
index 00000000..87935c29
--- /dev/null
+++ b/drivers/remoteproc/ambarella/Kconfig
@@ -0,0 +1,63 @@
+config RPROC_SUPPORT
+ bool
+ select REMOTEPROC
+ select RPMSG
+ default n
+
+config RPROC_CA9_A
+ tristate "Enable RPROC Host on CA9-A"
+ depends on MACH_HYACINTH_0
+ select RPROC_SUPPORT
+ help
+ TBD:
+
+config RPROC_CA9_B
+ tristate "Enable RPROC Host on CA9-B"
+ depends on MACH_HYACINTH_1
+ select RPROC_SUPPORT
+ help
+ TBD:
+
+config RPROC_S2
+ tristate "Enable RPROC Host on S2"
+ depends on MACH_GINKGO
+ select RPROC_SUPPORT
+ help
+ TBD:
+ default n
+
+config RPCLNT_SUPPORT
+ bool
+ select REMOTEPROC
+ select RPMSG
+ default n
+
+config RPCLNT_CA9_B
+ tristate "Enable RPROC Clnt on CA9-B"
+ depends on MACH_HYACINTH_1
+ select RPCLNT_SUPPORT
+ help
+ TODO:
+
+config RPMSG_VRING_BASE
+ hex "Base address (Physical) used for the rpmsg & remoteproc"
+ depends on REMOTEPROC
+ default 0x5C000000 if MACH_HYACINTH_0 || MACH_HYACINTH_1
+ default 0x20000000 if MACH_GINKO
+
+config RPMSG_NUM_BUFS
+ int "Number of buffers for each RPMSG bus"
+ depends on REMOTEPROC
+ default 4096
+ help
+ The buffers are partitioned into dedicated halves for TX
+ and RX.
+
+config RPMSG_BUF_SIZE
+ int "Buffer size (in bytes) for each RPMSG message"
+ depends on REMOTEPROC
+ default 4096
+ help
+ The first 16 bytes are used by the rpmsg header internally.
+ So only N - 16 bytes is available for the message payload.
+
diff --git a/drivers/remoteproc/ambarella/Makefile b/drivers/remoteproc/ambarella/Makefile
new file mode 100644
index 00000000..2cb554c8
--- /dev/null
+++ b/drivers/remoteproc/ambarella/Makefile
@@ -0,0 +1,8 @@
+obj-$(CONFIG_RPROC_SUPPORT) += host/rproc_ambarella.o
+obj-$(CONFIG_RPROC_CA9_A) += host/rproc_ca9_a.o
+obj-$(CONFIG_RPROC_CA9_B) += host/rproc_ca9_b.o
+obj-$(CONFIG_RPROC_S2) += host/rproc_s2.o
+
+obj-$(CONFIG_RPCLNT_SUPPORT) += clnt/vq.o
+obj-$(CONFIG_RPCLNT_SUPPORT) += clnt/rpdev.o
+obj-$(CONFIG_RPCLNT_CA9_B) += clnt/rpclnt_ca9_b.o
diff --git a/drivers/remoteproc/ambarella/clnt/rpclnt.h b/drivers/remoteproc/ambarella/clnt/rpclnt.h
new file mode 100644
index 00000000..bbc69536
--- /dev/null
+++ b/drivers/remoteproc/ambarella/clnt/rpclnt.h
@@ -0,0 +1,49 @@
+/**
+ * system/src/rpclnt/rpclnt.h
+ *
+ * History:
+ * 2012/08/15 - [Tzu-Jung Lee] created file
+ *
+ * Copyright 2008-2015 Ambarella Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __RPCLNT_H__
+#define __RPCLNT_H__
+
+struct rpclnt
+{
+ struct work_struct svq_work;
+ struct work_struct rvq_work;
+
+ int inited;
+ char *name;
+
+ void *svq;
+ int svq_tx_irq;
+ int svq_rx_irq;
+ int svq_num_bufs;
+ u32 svq_buf_phys;
+ u32 svq_vring_phys;
+ int svq_vring_algn;
+
+ void *rvq;
+ int rvq_tx_irq;
+ int rvq_rx_irq;
+ int rvq_num_bufs;
+ u32 rvq_buf_phys;
+ u32 rvq_vring_phys;
+ int rvq_vring_algn;
+};
+
+extern struct rpclnt *rpclnt_sync(const char *bus_name);
+
+#endif /* __RPCLNT_H__ */
diff --git a/drivers/remoteproc/ambarella/clnt/rpclnt_ca9_b.c b/drivers/remoteproc/ambarella/clnt/rpclnt_ca9_b.c
new file mode 100644
index 00000000..9520d01f
--- /dev/null
+++ b/drivers/remoteproc/ambarella/clnt/rpclnt_ca9_b.c
@@ -0,0 +1,202 @@
+/**
+ * system/src/rpclnt/rpclnt.h
+ *
+ * History:
+ * 2012/08/15 - [Tzu-Jung Lee] created file
+ *
+ * Copyright 2008-2015 Ambarella Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/kthread.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+#include <plat/remoteproc_cfg.h>
+#include <plat/rpdev.h>
+#include <plat/rct.h>
+
+#include "rpclnt.h"
+#include "vq.h"
+
+extern void rpdev_svq_cb(struct vq *vq);
+extern void rpdev_rvq_cb(struct vq *vq);
+
+DECLARE_COMPLETION(rpclnt_comp);
+
+static struct rpclnt G_rproc_ca9_b = {
+
+ .name = "rpclnt_ca9_a_and_b",
+ .inited = 0,
+
+ .svq_tx_irq = VRING_CA9_B_TO_A_HOST_IRQ,
+ .svq_rx_irq = VRING_CA9_B_TO_A_CLNT_IRQ,
+ .svq_num_bufs = RPMSG_NUM_BUFS >> 1,
+ .svq_buf_phys = VRING_BUF_CA9_A_AND_B,
+ .svq_vring_phys = VRING_CA9_B_TO_A,
+ .svq_vring_algn = RPMSG_VRING_ALIGN,
+
+ .rvq_tx_irq = VRING_CA9_A_TO_B_HOST_IRQ,
+ .rvq_rx_irq = VRING_CA9_A_TO_B_CLNT_IRQ,
+ .rvq_num_bufs = RPMSG_NUM_BUFS >> 1,
+ .rvq_buf_phys = VRING_BUF_CA9_A_AND_B + (RPMSG_TOTAL_BUF_SPACE >> 1),
+ .rvq_vring_phys = VRING_CA9_A_TO_B,
+ .rvq_vring_algn = RPMSG_VRING_ALIGN,
+};
+
+struct rpclnt *rpclnt_sync(const char *bus_name)
+{
+ struct rpclnt *rpclnt = &G_rproc_ca9_b;
+
+ if (strcmp(bus_name, "ca9_a_and_b"))
+ return NULL;
+
+ if (!rpclnt->inited)
+ wait_for_completion(&rpclnt_comp);
+
+ return &G_rproc_ca9_b;
+}
+
+static void rpclnt_complete_registration(struct rpclnt *rpclnt)
+{
+ u32 buf = rpclnt->rvq_buf_phys;
+
+ vq_init_unused_bufs(rpclnt->rvq, (void*)buf, RPMSG_BUF_SIZE);
+
+ rpclnt->inited = 1;
+ complete_all(&rpclnt_comp);
+}
+
+static irqreturn_t rpclnt_isr(int irq, void *dev_id)
+{
+ struct rpclnt *rpclnt = dev_id;
+
+ if (!rpclnt->inited && irq == rpclnt->svq_rx_irq) {
+
+ rpclnt_complete_registration(rpclnt);
+
+ amba_writel(AHB_SCRATCHPAD_REG(0x14),
+ 0x1 << (irq - AXI_SOFT_IRQ(0)));
+
+ return IRQ_HANDLED;
+ }
+
+ /*
+ * Before scheduling the bottom half for processing the messages,
+ * we tell the remote host not to notify us (generate interrupts) when
+ * subsequent messages are enqueued. The bottom half will pull out
+ * this message and the pending ones. Once it processed all the messages
+ * in the queue, it will re-enable remote host for the notification.
+ */
+ if (irq == rpclnt->rvq_rx_irq) {
+
+ vq_disable_used_notify(rpclnt->rvq);
+ schedule_work(&rpclnt->rvq_work);
+
+ } else if (irq == rpclnt->svq_rx_irq) {
+
+ vq_disable_used_notify(rpclnt->svq);
+ schedule_work(&rpclnt->svq_work);
+ }
+
+ amba_writel(AHB_SCRATCHPAD_REG(0x14),
+ 0x1 << (irq - AXI_SOFT_IRQ(0)));
+
+ return IRQ_HANDLED;
+}
+
+static void rpclnt_rvq_worker(struct work_struct *work)
+{
+ struct rpclnt *rpclnt = container_of(work, struct rpclnt, rvq_work);
+ struct vq *vq = rpclnt->rvq;
+
+ if (vq->cb)
+ vq->cb(vq);
+}
+
+static void rpclnt_svq_worker(struct work_struct *work)
+{
+ struct rpclnt *rpclnt = container_of(work, struct rpclnt, svq_work);
+ struct vq *vq = rpclnt->svq;
+
+ if (vq->cb)
+ vq->cb(vq);
+}
+
+static void rpclnt_kick_rvq(struct vq *vq)
+{
+ /*
+ * Honor the flag set by the remote host.
+ *
+ * Most of the time, the remote host want to supress their
+ * tx-complete interrupts. In this case, we don't bother it.
+ */
+ if (vq_kick_prepare(vq)) {
+
+ amba_writel(AHB_SCRATCHPAD_REG(0x10),
+ 0x1 << (107 - AXI_SOFT_IRQ(0)));
+ }
+}
+
+static void rpclnt_kick_svq(struct vq *vq)
+{
+ /*
+ * Honor the flag set by the remote host.
+ *
+ * When the remote host is already busy enough processing the
+ * messages, it might suppress the interrupt and work in polling
+ * mode.
+ */
+ if (vq_kick_prepare(vq)) {
+
+ amba_writel(AHB_SCRATCHPAD_REG(0x10),
+ 0x1 << (109 - AXI_SOFT_IRQ(0)));
+ }
+}
+
+static int rpclnt_drv_init(void)
+{
+ int ret;
+ struct rpclnt *rpclnt = &G_rproc_ca9_b;
+
+ rpclnt->svq = vq_create(rpdev_svq_cb,
+ rpclnt_kick_svq,
+ rpclnt->svq_num_bufs,
+ ambarella_phys_to_virt(rpclnt->svq_vring_phys),
+ rpclnt->svq_vring_algn);
+
+ rpclnt->rvq = vq_create(rpdev_rvq_cb,
+ rpclnt_kick_rvq,
+ rpclnt->rvq_num_bufs,
+ ambarella_phys_to_virt(rpclnt->rvq_vring_phys),
+ rpclnt->rvq_vring_algn);
+
+ INIT_WORK(&rpclnt->svq_work, rpclnt_svq_worker);
+ INIT_WORK(&rpclnt->rvq_work, rpclnt_rvq_worker);
+
+ ret = request_irq(rpclnt->svq_rx_irq, rpclnt_isr,
+ IRQF_SHARED, "rpclnt_svq_rx", rpclnt);
+ if (ret)
+ printk("Error: failed to request svq_rx_irq: %d, err: %d\n",
+ rpclnt->svq_rx_irq, ret);
+
+ ret = request_irq(rpclnt->rvq_rx_irq, rpclnt_isr,
+ IRQF_SHARED, "rpclnt_rvq_rx", rpclnt);
+
+ if (ret)
+ printk("Error: failed to request rvq_rx_irq: %d, err: %d\n",
+ rpclnt->rvq_rx_irq, ret);
+
+ return 0;
+}
+
+module_init(rpclnt_drv_init);
diff --git a/drivers/remoteproc/ambarella/clnt/rpdev.c b/drivers/remoteproc/ambarella/clnt/rpdev.c
new file mode 100644
index 00000000..854e8446
--- /dev/null
+++ b/drivers/remoteproc/ambarella/clnt/rpdev.c
@@ -0,0 +1,223 @@
+/**
+ * system/src/rpclnt/rpdev.c
+ *
+ * History:
+ * 2012/08/15 - [Tzu-Jung Lee] created file
+ *
+ * Copyright 2008-2015 Ambarella Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/rpmsg.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <plat/rpdev.h>
+
+#include "rpclnt.h"
+#include "vq.h"
+
+static struct rpdev *g_registered_rpdev[64];
+static int g_registered_cnt;
+DEFINE_SPINLOCK(spinlock_rpdev_tbl);
+
+static struct rpdev *rpdev_lookup(int src, int dst)
+{
+ struct rpdev *rpdev = NULL;
+ unsigned long flag;
+ int i;
+
+ spin_lock_irqsave(&spinlock_rpdev_tbl, flag);
+
+ for (i = 0; i < g_registered_cnt; i++) {
+
+ rpdev = g_registered_rpdev[i];
+
+ if (rpdev->src == src && rpdev->dst == dst) {
+ spin_unlock_irqrestore(&spinlock_rpdev_tbl, flag);
+ return rpdev;
+ }
+
+ }
+
+ spin_unlock_irqrestore(&spinlock_rpdev_tbl, flag);
+
+ return NULL;
+}
+
+void rpdev_rvq_cb(struct vq *vq)
+{
+ struct rpmsg_hdr *hdr;
+ struct rpdev *rpdev;
+ int len;
+ int idx;
+
+ while (1) {
+
+ idx = vq_get_avail_buf(vq, (void**)&hdr, &len);
+ if (idx < 0) {
+
+ vq_enable_used_notify(vq);
+
+ /*
+ * In case any message slipped in the window, check
+ * again. Otherwise, it will be delayed until next
+ * interrupt.
+ */
+ idx = vq_get_avail_buf(vq, (void**)&hdr, &len);
+ if (idx < 0)
+ break;
+
+ /* Disable the intruupt, and continue to poll */
+ vq_disable_used_notify(vq);
+ }
+
+ rpdev = rpdev_lookup(hdr->dst, hdr->src);
+ if (rpdev) {
+
+ rpdev->cb(rpdev, &hdr->data, hdr->len, rpdev->priv, hdr->src);
+ vq_add_used_buf(vq, idx, RPMSG_BUF_SIZE);
+
+ continue;
+ }
+
+ rpdev = rpdev_lookup(hdr->dst, RPMSG_NS_ADDR);
+ if (rpdev) {
+
+ if (hdr->len == sizeof(struct rpmsg_ns_msg)) {
+
+ rpdev->dst = hdr->src;
+ complete(&rpdev->comp);
+ vq_add_used_buf(vq, idx, RPMSG_BUF_SIZE);
+ }
+ }
+ }
+
+ vq->kick(vq);
+
+}
+
+void rpdev_svq_cb(struct vq *vq)
+{
+ vq_complete(vq);
+ vq_enable_used_notify(vq);
+}
+
+int rpdev_send_offchannel(struct rpdev *rpdev, u32 src, u32 dst, void *data, int len)
+{
+ int idx = 0;
+ int buf_len = 0;
+ struct rpmsg_hdr *hdr = NULL;
+ struct vq *vq;
+
+ vq = rpdev->rpclnt->svq;
+
+ idx = vq_get_avail_buf(vq, (void**)&hdr, &buf_len);
+ if (idx < 0)
+ return -1;
+
+ hdr->src = src;
+ hdr->dst = dst;
+ hdr->reserved = 0;
+ hdr->len = len;
+ hdr->flags = 0;
+
+ memcpy(hdr->data, data, len);
+
+ vq_add_used_buf(vq, idx, buf_len);
+
+ vq->kick(vq);
+
+ return 0;
+}
+
+int rpdev_send(struct rpdev *rpdev, void *data, int len)
+{
+ struct vq *vq;
+
+ while (rpdev_send_offchannel(rpdev, rpdev->src, rpdev->dst, data, len)) {
+
+ vq = rpdev->rpclnt->svq;
+
+ vq_enable_used_notify(vq);
+ vq_wait_for_completion(vq);
+ vq_disable_used_notify(vq);
+ }
+
+ return 0;
+}
+
+int rpdev_trysend(struct rpdev *rpdev, void *data, int len)
+{
+ return rpdev_send_offchannel(rpdev, rpdev->src, rpdev->dst,
+ data, len);
+}
+
+int rpdev_register(struct rpdev *rpdev, const char *bus_name)
+{
+ struct rpmsg_ns_msg nsm;
+ struct rpclnt *rpclnt;
+ unsigned long flag;
+
+ rpclnt = rpclnt_sync(bus_name);
+ rpdev->rpclnt = rpclnt;
+
+ memcpy(&nsm.name, rpdev->name, RPMSG_NAME_LEN);
+ nsm.addr = rpdev->src;
+ nsm.flags = rpdev->flags;
+
+ rpdev_send_offchannel(rpdev, rpdev->src, RPMSG_NS_ADDR,
+ &nsm, sizeof(nsm));
+
+ wait_for_completion(&rpdev->comp);
+
+ /*
+ * Supress the tx-complete interrupt by default.
+ *
+ * This interuupt will be re-enabled when necessary.
+ * When all available tx buffers are used up, users may
+ * be blocked if they were calling rpdev_send() API.
+ *
+ * In this case, we'd like to recieve interrupt when any
+ * tx-buffer is available so we can waken up the blocked
+ * users.
+ */
+ vq_disable_used_notify(rpclnt->svq);
+
+ return 0;
+}
+
+struct rpdev *rpdev_alloc(const char *name, int flags, rpdev_cb cb, void *priv)
+{
+ struct rpdev *rpdev;
+ unsigned long flag;
+
+ rpdev = kmalloc(sizeof(*rpdev), GFP_KERNEL);
+
+ strcpy(rpdev->name, name);
+
+ spin_lock_irqsave(&spinlock_rpdev_tbl, flag);
+ g_registered_rpdev[g_registered_cnt] = rpdev;
+
+ rpdev->src = RPMSG_RESERVED_ADDRESSES + g_registered_cnt++;
+ spin_unlock_irqrestore(&spinlock_rpdev_tbl, flag);
+
+ rpdev->dst = RPMSG_NS_ADDR;
+ rpdev->flags = flags;
+ rpdev->cb = cb;
+ rpdev->priv = priv;
+
+ init_completion(&rpdev->comp);
+
+ return rpdev;
+}
diff --git a/drivers/remoteproc/ambarella/clnt/vq.c b/drivers/remoteproc/ambarella/clnt/vq.c
new file mode 100644
index 00000000..7d224529
--- /dev/null
+++ b/drivers/remoteproc/ambarella/clnt/vq.c
@@ -0,0 +1,382 @@
+/**
+ * system/src/rpclnt/vq.c
+ *
+ * History:
+ * 2012/08/15 - [Tzu-Jung Lee] created file
+ *
+ * Copyright 2008-2015 Ambarella Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#if defined(__KERNEL__)
+#include <linux/slab.h>
+#else
+#include <itron.h>
+#include <kutil.h>
+extern void clean_d_cache_region(void *addr, unsigned int size);
+extern void flush_d_cache_region(void *addr, unsigned int size);
+#endif
+
+#include "vq.h"
+
+/******************************************************************************
+ * OS dependent utility functions
+ *****************************************************************************/
+
+#if defined(__KERNEL__)
+
+static inline struct vq *vq_alloc(void)
+{
+ return kmalloc(sizeof(struct vq), GFP_KERNEL);
+}
+
+static inline void vq_init_completion(struct vq *vq)
+{
+ init_completion(&vq->comp);
+}
+
+inline void vq_wait_for_completion(struct vq *vq)
+{
+ wait_for_completion(&vq->comp);
+}
+
+inline void vq_complete(struct vq *vq)
+{
+ complete(&vq->comp);
+}
+
+/*
+ * For Linux, we map the whole PPM region as non-cached.
+ * So no cache operation needed.
+ *
+ */
+static inline void vq_clean_d_cache_region(void *addr, unsigned int size)
+{
+}
+
+static inline void vq_flush_d_cache_region(void *addr, unsigned int size)
+{
+}
+
+static inline void vq_lock_init(struct vq *vq)
+{
+ spin_lock_init(&vq->lock);
+}
+
+#define vq_lock(vq, flag) spin_lock_irqsave(&vq->lock, flag)
+#define vq_unlock(vq, flag) spin_unlock_irqrestore(&vq->lock, flag)
+
+#else /* ITRON */
+
+static inline struct vq *vq_alloc(void)
+{
+ struct vq *vq;
+
+ pget_mpl(HEAP_MPLID, sizeof(*vq), (VP *)&vq);
+ return vq;
+}
+
+static inline void vq_init_completion(struct vq *vq)
+{
+ T_CFLG pk_cflg;
+
+ pk_cflg.flgatr = (TA_TFIFO | TA_WMUL | TA_CLR);
+ pk_cflg.iflgptn = 0x0;
+ vq->flgid = acre_flg(&pk_cflg);
+
+ K_ASSERT(vq->flgid > 0);
+}
+
+void vq_wait_for_completion(struct vq *vq)
+{
+ ER ercd;
+ FLGPTN flgptn;
+
+ ercd = wai_flg(vq->flgid, 0x1, TWF_ANDW, &flgptn);
+ K_ASSERT(ercd == E_OK);
+}
+
+void vq_complete(struct vq *vq)
+{
+ ER ercd;
+
+ ercd = set_flg(vq->flgid, 0x1);
+ K_ASSERT(ercd == E_OK);
+}
+
+static inline void vq_clean_d_cache_region(void *addr, unsigned int size)
+{
+ u32 mask = (1 << CLINE) - 1;
+
+ addr = (u32)addr &~ mask;
+ size = (size + mask) &~ mask;
+
+ clean_d_cache_region(addr, size);
+}
+
+static inline void vq_flush_d_cache_region(void *addr, unsigned int size)
+{
+ u32 mask = (1 << CLINE) - 1;
+
+ addr = (u32)addr &~ mask;
+ size = (size + mask) &~ mask;
+
+ flush_d_cache_region(addr, size);
+}
+
+static inline void vq_lock_init(struct vq *vq)
+{
+ T_CMTX pk_cmtx;
+
+ pk_cmtx.mtxatr = TA_TFIFO;
+ pk_cmtx.ceilpri = 0;
+ vq->mtxid = acre_mtx(&pk_cmtx);
+ K_ASSERT(vq->mtxid > 0);
+}
+
+static inline void vq_lock(struct vq *vq)
+{
+ ER er;
+
+ er = loc_mtx(vq->mtxid);
+ K_ASSERT (er == E_OK);
+}
+
+static inline void vq_unlock(struct vq *vq)
+{
+ ER er;
+
+ er = unl_mtx(vq->mtxid);
+ K_ASSERT (er == E_OK);
+}
+#endif /* __KERNEL__ */
+
+/******************************************************************************/
+
+int vq_kick_prepare(struct vq *vq)
+{
+ vq_flush_d_cache_region(&vq->vring.avail->flags,
+ sizeof(vq->vring.avail->flags));
+
+ return !(vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT);
+}
+void vq_enable_used_notify(struct vq *vq)
+{
+ vq_flush_d_cache_region(&vq->vring.used->flags,
+ sizeof(vq->vring.used->flags));
+
+ vq->vring.used->flags &= ~VRING_USED_F_NO_NOTIFY;
+
+ vq_clean_d_cache_region(&vq->vring.used->flags,
+ sizeof(vq->vring.used->flags));
+}
+
+void vq_disable_used_notify(struct vq *vq)
+{
+ vq_flush_d_cache_region(&vq->vring.used->flags,
+ sizeof(vq->vring.used->flags));
+
+ vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY;
+
+ vq_clean_d_cache_region(&vq->vring.used->flags,
+ sizeof(vq->vring.used->flags));
+}
+
+int vq_more_avail_buf(struct vq *vq)
+{
+ struct vring_avail *avail = vq->vring.avail;
+
+ vq_flush_d_cache_region(avail, sizeof(*avail));
+
+ return vq->last_avail_idx != avail->idx;
+}
+
+struct vq *vq_create(void (*cb)(struct vq *vq),
+ void (*kick)(struct vq *vq),
+ int num_bufs,
+ u32 vring_addr, int vring_algn)
+{
+ struct vq *vq = vq_alloc();
+
+ vq_init_completion(vq);
+ vq_lock_init(vq);
+
+ vq->cb = cb;
+ vq->kick = kick;
+ vq->last_avail_idx = 0;
+ vq->last_used_idx = 0;
+
+ vring_init(&vq->vring, num_bufs, (void*)vring_addr, vring_algn);
+ printk("vring size: 0x%x\n", vring_size(num_bufs, vring_algn));
+
+ return vq;
+}
+
+/*
+ * vq_get_avail_buf and vq_add_used_buf usually used in pairs to
+ * grab a "available" buffer, use it, and then tell the HOST, we
+ * finish our usage.
+ */
+int vq_get_avail_buf(struct vq *vq, void **buf, int *len)
+{
+ int idx;
+ u16 last_avail_idx;
+ struct vring_avail *avail;
+ struct vring_desc *desc;
+ unsigned long flag;
+
+ vq_lock(vq, flag);
+
+ if (!vq_more_avail_buf(vq)) {
+ vq_unlock(vq, flag);
+ return -1;
+ }
+
+ last_avail_idx = vq->last_avail_idx++ % vq->vring.num;
+ avail = vq->vring.avail;
+
+ vq_flush_d_cache_region(avail, sizeof(*avail));
+ vq_flush_d_cache_region(&avail->ring[last_avail_idx], sizeof(*avail->ring));
+
+ idx = avail->ring[last_avail_idx];
+ desc = &vq->vring.desc[idx];
+ vq_flush_d_cache_region(desc, sizeof(*desc));
+
+ *buf = (void*)ambarella_phys_to_virt(desc->addr);
+ *len = desc->len;
+
+ vq_flush_d_cache_region(*buf, *len);
+
+ vq_unlock(vq, flag);
+
+ return idx;
+}
+
+int vq_add_used_buf(struct vq *vq, int idx, int len)
+{
+ struct vring_used_elem *used_elem;
+ struct vring_used *used;
+ unsigned long flag;
+
+ vq_lock(vq, flag);
+
+ /* Clean the cache of buffer of the used buffer */
+ vq_clean_d_cache_region((void*)(unsigned long)vq->vring.desc[idx].addr, len);
+
+ /* Update the used descriptor and clean its cache region */
+ used = vq->vring.used;
+ used_elem = &used->ring[used->idx % vq->vring.num];
+ used_elem->id = idx;
+ used_elem->len = len;
+ vq_clean_d_cache_region(used_elem, sizeof(*used_elem));
+
+ /*
+ * Update the used descriptor index and clean its cache region.
+ * This step has to be done as the last step. The order matters.
+ */
+ used->idx++;
+ vq_clean_d_cache_region(used, sizeof(*used));
+
+ vq_unlock(vq, flag);
+
+ return 0;
+}
+
+/*
+ * Linux HOST rpmsg implementation only setup the RX buffer descriptors on HOST.
+ * Buffer descriptors for HOST TX (CLIENT RX) are left for CLIENT to setup.
+ *
+ * A very IMPORTANT thing should be noted: Though the Linux HOST does not setup
+ * the HOST TX descriptors, it "zeros out" them during vring initialization.
+ * So this API should be synchronized and called only after the Linux HOST has
+ * finished their initialization.
+ */
+int vq_init_unused_bufs(struct vq *vq, void *buf, int len)
+{
+ struct vring_desc *desc;
+ unsigned long flag;
+ int i;
+
+ vq_lock(vq, flag);
+
+ for (i = 0; i < vq->vring.num; i++) {
+
+ desc = &vq->vring.desc[i];
+ desc->addr = ambarella_virt_to_phys((u32)buf);
+ desc->len = len;
+ vq_clean_d_cache_region(desc, sizeof(*desc));
+
+ buf += len;
+ }
+
+ vq_unlock(vq, flag);
+
+ return 0;
+}
+
+#if 0
+/*
+ * Normally, this API should not be used for now. We just keep it in case the
+ * API expansion or more comprehensive bits are added in the future.
+ */
+
+int vq_add_avail_buf(struct vq *vq, void *buf, int len)
+{
+ struct vring_avail *avail;
+ struct vring_desc *desc;
+ unsigned long flag;
+
+ vq_lock(vq, flag);
+ vq->num_free--;
+
+ avail = vq->vring.avail;
+ desc = &vq->vring.desc[avail->idx % vq->vring.num];
+ desc->addr = ambarella_virt_to_phys((u32)buf);
+ desc->len = len;
+ vq_clean_d_cache_region(desc, sizeof(*desc));
+
+ /*
+ * Update the avail descriptor index and clean its cache region.
+ * This step has to be done as the last step. The order matters.
+ */
+ avail->idx++;
+ vq_clean_d_cache_region(avail, sizeof(*avail));
+
+ vq_unlock(vq, flag);
+
+ return vq->num_free;
+}
+
+void *vq_get_used_buf(struct vq *vq)
+{
+ int last_used_idx;
+ struct vring_used_elem *used_elem;
+ struct vring_desc *desc;
+ void *buf;
+ unsigned long flag;
+
+ vq_lock(vq, flag);
+
+ last_used_idx = vq->last_used_idx++ % vq->vring.num;
+ used_elem = &vq->vring.used->ring[last_used_idx];
+ vq_flush_d_cache_region(used_elem, sizeof(*used_elem));
+
+ desc = &vq->vring.desc[used_elem->id];
+ vq_flush_d_cache_region(desc, sizeof(*desc));
+
+ buf = (void*)ambarella_phys_to_virt(desc->addr);
+ vq_flush_d_cache_region(buf, desc->len);
+
+ vq_unlock(vq, flag);
+
+ return buf;
+}
+#endif
diff --git a/drivers/remoteproc/ambarella/clnt/vq.h b/drivers/remoteproc/ambarella/clnt/vq.h
new file mode 100644
index 00000000..725d5990
--- /dev/null
+++ b/drivers/remoteproc/ambarella/clnt/vq.h
@@ -0,0 +1,71 @@
+/**
+ * system/src/rpclnt/vq.h
+ *
+ * History:
+ * 2012/08/15 - [Tzu-Jung Lee] created file
+ *
+ * Copyright 2008-2015 Ambarella Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __VQ_H__
+#define __VQ_H__
+
+#if defined(__KERNEL__)
+#include <linux/virtio_ring.h>
+#include <linux/sched.h>
+#else
+#include <itron.h>
+#include "virtio_ring.h"
+
+static inline void *ambarella_virt_to_phys(void *addr)
+{
+ return addr;
+}
+
+static inline void *ambarella_phys_to_virt(void *addr)
+{
+ return addr;
+}
+#endif
+
+struct vq {
+#if defined(__KERNEL__)
+ spinlock_t lock;
+ struct completion comp;
+#else
+ ID mtxid;
+ ID flgid;
+#endif
+ void (*cb)(struct vq *vq);
+ void (*kick)(struct vq *vq);
+ struct vring vring;
+ u16 last_avail_idx;
+ u16 last_used_idx;
+};
+
+extern struct vq *vq_create(void (*cb)(struct vq *vq),
+ void (*kick)(struct vq *vq),
+ int num_bufs,
+ u32 vring_virt, int vring_algn);
+
+extern void vq_wait_for_completion(struct vq *vq);
+extern void vq_complete(struct vq *vq);
+
+extern int vq_kick_prepare(struct vq *vq);
+extern void vq_enable_used_notify(struct vq *vq);
+extern void vq_disable_used_notify(struct vq *vq);
+extern int vq_more_avail_buf(struct vq *vq);
+extern int vq_get_avail_buf(struct vq *vq, void **buf, int *len);
+extern int vq_add_used_buf(struct vq *vq, int idx, int len);
+extern int vq_init_unused_bufs(struct vq *vq, void *buf, int len);
+
+#endif /* __VQ_H__ */
diff --git a/drivers/remoteproc/ambarella/host/rproc_ambarella.c b/drivers/remoteproc/ambarella/host/rproc_ambarella.c
new file mode 100644
index 00000000..721ec6c2
--- /dev/null
+++ b/drivers/remoteproc/ambarella/host/rproc_ambarella.c
@@ -0,0 +1,208 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/remoteproc.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+
+#include <plat/remoteproc.h>
+#include <plat/rct.h>
+
+#include "../../remoteproc_internal.h"
+
+static void rpmsg_send_irq(int irq)
+{
+ if (irq > 0) {
+ amba_writel(AHB_SCRATCHPAD_REG(0x10), 0x1 << (irq - AXI_SOFT_IRQ(0)));
+ }
+ else {
+ irq = -irq;
+ amba_writel(VIC3_REG(0x18), 0x1 << (irq - 96));
+ }
+}
+
+static void rpmsg_ack_irq(int irq)
+{
+ amba_writel(AHB_SCRATCHPAD_REG(0x14), 0x1 << (irq - AXI_SOFT_IRQ(0)));
+}
+
+static void ambarella_rproc_kick(struct rproc *rproc, int vqid)
+{
+ struct ambarella_rproc_pdata *pdata = rproc->priv;
+
+ if (vqid == 0)
+ rpmsg_send_irq(pdata->rvq_tx_irq);
+ else
+ rpmsg_send_irq(pdata->svq_tx_irq);
+}
+
+static void rproc_svq_worker(struct work_struct *work)
+{
+ struct ambarella_rproc_pdata *pdata;
+ struct rproc *rproc;
+
+ pdata = container_of(work, struct ambarella_rproc_pdata, svq_work);
+ rproc = pdata->rproc;
+
+ rproc_vq_interrupt(rproc, 1);
+}
+
+static void rproc_rvq_worker(struct work_struct *work)
+{
+ struct ambarella_rproc_pdata *pdata;
+ struct rproc *rproc;
+ struct rproc_vring *rvring;
+
+ pdata = container_of(work, struct ambarella_rproc_pdata, rvq_work);
+ rproc = pdata->rproc;
+ rvring = idr_find(&pdata->rproc->notifyids, 0);
+
+ while (1) {
+
+ if (rproc_vq_interrupt(rproc, 0) == IRQ_HANDLED)
+ continue;
+
+ virtqueue_enable_cb(rvring->vq);
+
+ if (rproc_vq_interrupt(rproc, 0) == IRQ_HANDLED) {
+
+ virtqueue_disable_cb(rvring->vq);
+ continue;
+ }
+
+ break;
+ }
+}
+
+static irqreturn_t rproc_ambarella_isr(int irq, void *dev_id)
+{
+ struct ambarella_rproc_pdata *pdata = dev_id;
+ struct rproc_vring *rvring;
+
+ if (irq == pdata->rvq_rx_irq) {
+ rvring = idr_find(&pdata->rproc->notifyids, 0);
+ virtqueue_disable_cb(rvring->vq);
+ schedule_work(&pdata->rvq_work);
+ }
+ else if (irq == pdata->svq_rx_irq) {
+ schedule_work(&pdata->svq_work);
+ }
+
+ rpmsg_ack_irq(irq);
+
+ return IRQ_HANDLED;
+}
+
+static int ambarella_rproc_start(struct rproc *rproc)
+{
+ return 0;
+}
+
+static int ambarella_rproc_stop(struct rproc *rproc)
+{
+ return 0;
+}
+
+static struct rproc_ops ambarella_rproc_ops = {
+ .start = ambarella_rproc_start,
+ .stop = ambarella_rproc_stop,
+ .kick = ambarella_rproc_kick,
+};
+
+extern const struct rproc_fw_ops rproc_dummy_fw_ops;
+
+static int ambarella_rproc_probe(struct platform_device *pdev)
+{
+ struct ambarella_rproc_pdata *pdata = pdev->dev.platform_data;
+ struct rproc *rproc;
+ int ret;
+
+ ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
+ if (ret) {
+ dev_err(pdev->dev.parent, "dma_set_coherent_mask: %d\n", ret);
+ return ret;
+ }
+
+ rproc = rproc_alloc(&pdev->dev, pdata->name, &ambarella_rproc_ops,
+ pdata->firmware, 8192);
+ if (!rproc) {
+ ret = -ENOMEM;
+ goto free_rproc;
+ }
+
+ ret = request_irq(pdata->svq_rx_irq, rproc_ambarella_isr, IRQF_SHARED,
+ "rproc-svq_rx", pdata);
+ if (ret)
+ goto free_rproc;
+
+ ret = request_irq(pdata->rvq_rx_irq, rproc_ambarella_isr, IRQF_SHARED,
+ "rproc-rvq_rx", pdata);
+ if (ret)
+ goto free_rproc;
+
+ INIT_WORK(&pdata->svq_work, rproc_svq_worker);
+ INIT_WORK(&pdata->rvq_work, rproc_rvq_worker);
+
+ mutex_init(&rproc->lock);
+
+ rproc->priv = pdata;
+ pdata->rproc = rproc;
+
+ platform_set_drvdata(pdev, rproc);
+
+ rproc->fw_ops = &rproc_dummy_fw_ops;
+ ret = rproc_add(rproc);
+ if (ret)
+ goto free_rproc;
+
+ return 0;
+
+free_rproc:
+ rproc_put(rproc);
+ return ret;
+}
+
+static int ambarella_rproc_remove(struct platform_device *pdev)
+{
+ struct rproc *rproc = platform_get_drvdata(pdev);
+
+ rproc_del(rproc);
+ rproc_put(rproc);
+ return 0;
+}
+
+static struct platform_device_id id_table[] = {
+ { "ca9_a_and_b", 0},
+ { "ca9_a_and_arm11", 0},
+ { "ca9_b_and_arm11", 0},
+ { "c0_and_c1", 0},
+ { /* sentinel */ }
+};
+
+static struct platform_driver ambarella_rproc_driver = {
+ .probe = ambarella_rproc_probe,
+ .remove = ambarella_rproc_remove,
+ .driver = {
+ .name = "ambarella-rproc",
+ .owner = THIS_MODULE,
+ },
+ .id_table = id_table,
+};
+
+static int ambarella_rproc_driver_init(void)
+{
+ platform_driver_register(&ambarella_rproc_driver);
+ return 0;
+}
+
+static void ambarella_rproc_driver_fini(void)
+{
+ platform_driver_unregister(&ambarella_rproc_driver);
+}
+
+module_init(ambarella_rproc_driver_init);
+module_exit(ambarella_rproc_driver_fini);
+
+MODULE_DESCRIPTION("Ambarella Remote Processor control driver");
diff --git a/drivers/remoteproc/ambarella/host/rproc_ca9_a.c b/drivers/remoteproc/ambarella/host/rproc_ca9_a.c
new file mode 100644
index 00000000..04646a4b
--- /dev/null
+++ b/drivers/remoteproc/ambarella/host/rproc_ca9_a.c
@@ -0,0 +1,193 @@
+/*
+ * Author: Tzu-Jung Lee <tjlee@ambarella.com>
+ *
+ * Copyright (C) 2012-2012, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/platform_device.h>
+
+#include <linux/slab.h>
+#include <linux/virtio_ids.h>
+#include <linux/rpmsg.h>
+#include <linux/dma-mapping.h>
+
+#include <plat/remoteproc.h>
+#include <plat/remoteproc_cfg.h>
+
+/*
+ * The gen_rsc_table_* functions below fabricate the "resource table", which is
+ * used to initialize the vring configurations by the RPROC subsystem.
+ *
+ * The tables were originally meant to be loaded from ELF files on filesystem.
+ * It's a flexible and generic design, but requires extra maintenance out side
+ * the kernel space. So we currently code it plainly and directly here.
+ *
+ * The following illustrate the layout and structure of the table we use.
+ * Watch out the "sizeof()", since most of the structures here are embedded with
+ * variable-length array.
+ *
+ * 0x0000 &table
+ *
+ * < sizeof(*table) >
+ * < sizeof(u32) * table->num >
+ *
+ * 0x0014 &hdr (&table->offset)
+ *
+ * < sizeof(*hdr) >
+ *
+ * 0x0018 &vdev (&hdr->data)
+ *
+ * < sizeof(*vdev) >
+ *
+ * 0x0030 &vdev->ring[0] (&hdr->data)
+ *
+ * < sizeof(*vring) >
+ *
+ * 0x0044 &vdev->ring[1];
+ *
+ * < sizeof(*vring) >
+ * 0x0058
+ */
+
+static struct resource_table *gen_rsc_table_ca9_b(int *tablesz)
+{
+ struct resource_table *table;
+ struct fw_rsc_hdr *hdr;
+ struct fw_rsc_vdev *vdev;
+ struct fw_rsc_vdev_vring *vring;
+
+ *tablesz = sizeof(*table) + sizeof(u32) * 1
+ + sizeof(*hdr) + sizeof(*vdev)
+ + sizeof(*vring) * 2;
+
+ table = kzalloc((*tablesz), GFP_KERNEL);
+ table->ver = 1;
+ table->num = 1;
+ table->offset[0] = sizeof(*table) + sizeof(u32) * table->num;
+
+ hdr = (void*)table + table->offset[0];
+ hdr->type = RSC_VDEV;
+ vdev = (void*)&hdr->data;
+ vdev->id = VIRTIO_ID_RPMSG;
+ vdev->notifyid = 123;
+ vdev->dfeatures = (1 << VIRTIO_RPMSG_F_NS);
+ vdev->config_len = 0;
+ vdev->num_of_vrings = 2;
+
+ vring = (void*)&vdev->vring[0];
+ vring->da = VRING_CA9_B_TO_A;
+ vring->align = PAGE_SIZE;
+ vring->num = RPMSG_NUM_BUFS >> 1;
+ vring->notifyid = 111;
+
+ vring = (void*)&vdev->vring[1];
+ vring->da = VRING_CA9_A_TO_B;
+ vring->align = PAGE_SIZE;
+ vring->num = RPMSG_NUM_BUFS >> 1;
+ vring->notifyid = 112;
+
+ return table;
+}
+
+static struct resource_table *gen_rsc_table_arm11(int *tablesz)
+{
+ struct resource_table *table;
+ struct fw_rsc_hdr *hdr;
+ struct fw_rsc_vdev *vdev;
+ struct fw_rsc_vdev_vring *vring;
+
+ *tablesz = sizeof(*table) + sizeof(u32) * 1
+ + sizeof(*hdr) + sizeof(*vdev)
+ + sizeof(*vring) * 2;
+
+ table = kzalloc((*tablesz), GFP_KERNEL);
+ table->ver = 1;
+ table->num = 1;
+ table->offset[0] = sizeof(*table) + sizeof(u32) * table->num;
+
+ hdr = (void*)table + table->offset[0];
+ hdr->type = RSC_VDEV;
+ vdev = (void*)&hdr->data;
+ vdev->id = VIRTIO_ID_RPMSG;
+ vdev->notifyid = 124;
+ vdev->dfeatures = (1 << VIRTIO_RPMSG_F_NS);
+ vdev->config_len = 0;
+ vdev->num_of_vrings = 2;
+
+ vring = (void*)&vdev->vring[0];
+ vring->da = VRING_ARM11_TO_CA9_A;
+ vring->align = PAGE_SIZE;
+ vring->num = RPMSG_NUM_BUFS >> 1;
+ vring->notifyid = 111;
+
+ vring = (void*)&vdev->vring[1];
+ vring->da = VRING_CA9_A_TO_ARM11;
+ vring->align = PAGE_SIZE;
+ vring->num = RPMSG_NUM_BUFS >> 1;
+ vring->notifyid = 112;
+
+ return table;
+}
+
+static struct ambarella_rproc_pdata pdata_ca9_b = {
+ .name = "ca9_a_and_b",
+ .firmware = "dummy",
+ .svq_tx_irq = VRING_CA9_A_TO_B_CLNT_IRQ,
+ .svq_rx_irq = VRING_CA9_A_TO_B_HOST_IRQ,
+ .rvq_tx_irq = VRING_CA9_B_TO_A_CLNT_IRQ,
+ .rvq_rx_irq = VRING_CA9_B_TO_A_HOST_IRQ,
+ .ops = NULL,
+ .buf_addr_pa = VRING_BUF_CA9_A_AND_B,
+ .gen_rsc_table = gen_rsc_table_ca9_b,
+};
+
+struct platform_device ambarella_rproc_ca9_a_and_b_dev = {
+ .name = "ca9_a_and_b",
+ .id = VIRTIO_ID_RPMSG,
+ .resource = NULL,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &pdata_ca9_b,
+ .dma_mask = &ambarella_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct ambarella_rproc_pdata pdata_arm11 = {
+ .name = "ca9_a_and_arm11",
+ .firmware = "dummy",
+ .svq_tx_irq = -VRING_CA9_A_TO_ARM11_CLNT_IRQ,
+ .svq_rx_irq = VRING_CA9_A_TO_ARM11_HOST_IRQ,
+ .rvq_tx_irq = -VRING_ARM11_TO_CA9_A_CLNT_IRQ,
+ .rvq_rx_irq = VRING_ARM11_TO_CA9_A_HOST_IRQ,
+ .ops = NULL,
+ .buf_addr_pa = VRING_BUF_CA9_A_AND_ARM11,
+ .gen_rsc_table = gen_rsc_table_arm11,
+};
+
+struct platform_device ambarella_rproc_ca9_a_and_arm11_dev = {
+ .name = "ca9_a_and_arm11",
+ .id = VIRTIO_ID_RPMSG,
+ .resource = NULL,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &pdata_arm11,
+ .dma_mask = &ambarella_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
diff --git a/drivers/remoteproc/ambarella/host/rproc_ca9_b.c b/drivers/remoteproc/ambarella/host/rproc_ca9_b.c
new file mode 100644
index 00000000..f519ef0e
--- /dev/null
+++ b/drivers/remoteproc/ambarella/host/rproc_ca9_b.c
@@ -0,0 +1,129 @@
+/*
+ * Author: Tzu-Jung Lee <tjlee@ambarella.com>
+ *
+ * Copyright (C) 2012-2012, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/platform_device.h>
+
+#include <linux/slab.h>
+#include <linux/virtio_ids.h>
+#include <linux/rpmsg.h>
+#include <linux/dma-mapping.h>
+
+#include <plat/remoteproc.h>
+#include <plat/remoteproc_cfg.h>
+
+/*
+ * The gen_rsc_table_* functions below fabricate the "resource table", which is
+ * used to initialize the vring configurations by the RPROC subsystem.
+ *
+ * The tables were originally meant to be loaded from ELF files on filesystem.
+ * It's a flexible and generic design, but requires extra maintenance out side
+ * the kernel space. So we currently code it plainly and directly here.
+ *
+ * The following illustrate the layout and structure of the table we use.
+ * Watch out the "sizeof()", since most of the structures here are embedded with
+ * variable-length array.
+ *
+ * 0x0000 &table
+ *
+ * < sizeof(*table) >
+ * < sizeof(u32) * table->num >
+ *
+ * 0x0014 &hdr (&table->offset)
+ *
+ * < sizeof(*hdr) >
+ *
+ * 0x0018 &vdev (&hdr->data)
+ *
+ * < sizeof(*vdev) >
+ *
+ * 0x0030 &vdev->ring[0] (&hdr->data)
+ *
+ * < sizeof(*vring) >
+ *
+ * 0x0044 &vdev->ring[1];
+ *
+ * < sizeof(*vring) >
+ * 0x0058
+ */
+
+static struct resource_table *gen_rsc_table_arm11(int *tablesz)
+{
+ struct resource_table *table;
+ struct fw_rsc_hdr *hdr;
+ struct fw_rsc_vdev *vdev;
+ struct fw_rsc_vdev_vring *vring;
+
+ *tablesz = sizeof(*table) + sizeof(u32) * 1
+ + sizeof(*hdr) + sizeof(*vdev)
+ + sizeof(*vring) * 2;
+
+ table = kzalloc((*tablesz), GFP_KERNEL);
+ table->ver = 1;
+ table->num = 1;
+ table->offset[0] = sizeof(*table) + sizeof(u32) * table->num;
+
+ hdr = (void*)table + table->offset[0];
+ hdr->type = RSC_VDEV;
+ vdev = (void*)&hdr->data;
+ vdev->id = VIRTIO_ID_RPMSG;
+ vdev->notifyid = 124;
+ vdev->dfeatures = (1 << VIRTIO_RPMSG_F_NS);
+ vdev->config_len = 0;
+ vdev->num_of_vrings = 2;
+
+ vring = (void*)&vdev->vring[0];
+ vring->da = VRING_ARM11_TO_CA9_B;
+ vring->align = PAGE_SIZE;
+ vring->num = RPMSG_NUM_BUFS >> 1;
+ vring->notifyid = 111;
+
+ vring = (void*)&vdev->vring[1];
+ vring->da = VRING_CA9_B_TO_ARM11;
+ vring->align = PAGE_SIZE;
+ vring->num = RPMSG_NUM_BUFS >> 1;
+ vring->notifyid = 112;
+
+ return table;
+}
+
+static struct ambarella_rproc_pdata pdata_arm11 = {
+ .name = "ca9_b_and_arm11",
+ .firmware = "dummy",
+ .svq_tx_irq = -VRING_CA9_B_TO_ARM11_CLNT_IRQ,
+ .svq_rx_irq = VRING_CA9_B_TO_ARM11_HOST_IRQ,
+ .rvq_tx_irq = -VRING_ARM11_TO_CA9_B_CLNT_IRQ,
+ .rvq_rx_irq = VRING_ARM11_TO_CA9_B_HOST_IRQ,
+ .ops = NULL,
+ .buf_addr_pa = VRING_BUF_CA9_B_AND_ARM11,
+ .gen_rsc_table = gen_rsc_table_arm11,
+};
+
+struct platform_device ambarella_rproc_ca9_b_and_arm11_dev = {
+ .name = "ca9_b_and_arm11",
+ .id = VIRTIO_ID_RPMSG,
+ .resource = NULL,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &pdata_arm11,
+ .dma_mask = &ambarella_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
diff --git a/drivers/remoteproc/ambarella/host/rproc_s2.c b/drivers/remoteproc/ambarella/host/rproc_s2.c
new file mode 100644
index 00000000..dde36747
--- /dev/null
+++ b/drivers/remoteproc/ambarella/host/rproc_s2.c
@@ -0,0 +1,129 @@
+/*
+ * Author: Tzu-Jung Lee <tjlee@ambarella.com>
+ *
+ * Copyright (C) 2012-2012, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/platform_device.h>
+
+#include <linux/slab.h>
+#include <linux/virtio_ids.h>
+#include <linux/rpmsg.h>
+#include <linux/dma-mapping.h>
+
+#include <plat/remoteproc.h>
+#include <plat/remoteproc_cfg.h>
+
+/*
+ * The gen_rsc_table_* functions below fabricate the "resource table", which is
+ * used to initialize the vring configurations by the RPROC subsystem.
+ *
+ * The tables were originally meant to be loaded from ELF files on filesystem.
+ * It's a flexible and generic design, but requires extra maintenance out side
+ * the kernel space. So we currently code it plainly and directly here.
+ *
+ * The following illustrate the layout and structure of the table we use.
+ * Watch out the "sizeof()", since most of the structures here are embedded with
+ * variable-length array.
+ *
+ * 0x0000 &table
+ *
+ * < sizeof(*table) >
+ * < sizeof(u32) * table->num >
+ *
+ * 0x0014 &hdr (&table->offset)
+ *
+ * < sizeof(*hdr) >
+ *
+ * 0x0018 &vdev (&hdr->data)
+ *
+ * < sizeof(*vdev) >
+ *
+ * 0x0030 &vdev->ring[0] (&hdr->data)
+ *
+ * < sizeof(*vring) >
+ *
+ * 0x0044 &vdev->ring[1];
+ *
+ * < sizeof(*vring) >
+ * 0x0058
+ */
+
+static struct resource_table *gen_rsc_table_cortex(int *tablesz)
+{
+ struct resource_table *table;
+ struct fw_rsc_hdr *hdr;
+ struct fw_rsc_vdev *vdev;
+ struct fw_rsc_vdev_vring *vring;
+
+ *tablesz = sizeof(*table) + sizeof(u32) * 1
+ + sizeof(*hdr) + sizeof(*vdev)
+ + sizeof(*vring) * 2;
+
+ table = kzalloc((*tablesz), GFP_KERNEL);
+ table->ver = 1;
+ table->num = 1;
+ table->offset[0] = sizeof(*table) + sizeof(u32) * table->num;
+
+ hdr = (void*)table + table->offset[0];
+ hdr->type = RSC_VDEV;
+ vdev = (void*)&hdr->data;
+ vdev->id = VIRTIO_ID_RPMSG;
+ vdev->notifyid = 124;
+ vdev->dfeatures = (1 << VIRTIO_RPMSG_F_NS);
+ vdev->config_len = 0;
+ vdev->num_of_vrings = 2;
+
+ vring = (void*)&vdev->vring[0];
+ vring->da = VRING_C0_TO_C1;
+ vring->align = PAGE_SIZE;
+ vring->num = RPMSG_NUM_BUFS >> 1;
+ vring->notifyid = 111;
+
+ vring = (void*)&vdev->vring[1];
+ vring->da = VRING_C1_TO_C0;
+ vring->align = PAGE_SIZE;
+ vring->num = RPMSG_NUM_BUFS >> 1;
+ vring->notifyid = 112;
+
+ return table;
+}
+
+static struct ambarella_rproc_pdata pdata_cortex = {
+ .name = "c0_and_c1",
+ .firmware = "dummy",
+ .svq_tx_irq = VRING_IRQ_C1_TO_C0_KICK, //108
+ .svq_rx_irq = VRING_IRQ_C0_TO_C1_ACK, //107
+ .rvq_tx_irq = VRING_IRQ_C1_TO_C0_ACK, //109
+ .rvq_rx_irq = VRING_IRQ_C0_TO_C1_KICK, //106
+ .ops = NULL,
+ .buf_addr_pa = VRING_C0_AND_C1_BUF,
+ .gen_rsc_table = gen_rsc_table_cortex,
+};
+
+struct platform_device ambarella_rproc_cortex_dev = {
+ .name = "c0_and_c1",
+ .id = VIRTIO_ID_RPMSG,
+ .resource = NULL,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &pdata_cortex,
+ .dma_mask = &ambarella_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 022dc635..30072a83 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -206,7 +206,12 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i)
* Allocate non-cacheable memory for the vring. In the future
* this call will also configure the IOMMU for us
*/
+#if 0
va = dma_alloc_coherent(dev->parent, size, &dma, GFP_KERNEL);
+#else
+ va = (void*)ambarella_phys_to_virt(rvring->da);
+ dma = rvring->da;
+#endif
if (!va) {
dev_err(dev->parent, "dma_alloc_coherent failed\n");
return -EINVAL;
@@ -271,6 +276,7 @@ rproc_parse_vring(struct rproc_vdev *rvdev, struct fw_rsc_vdev *rsc, int i)
rvring->len = vring->num;
rvring->align = vring->align;
rvring->rvdev = rvdev;
+ rvring->da = vring->da;
return 0;
}
@@ -930,7 +936,8 @@ static void rproc_fw_config_virtio(const struct firmware *fw, void *context)
ret = rproc_handle_resources(rproc, tablesz, rproc_vdev_handler);
out:
- release_firmware(fw);
+ rproc_fw_release_firmware(rproc, fw);
+
/* allow rproc_del() contexts, if any, to proceed */
complete_all(&rproc->firmware_loading_complete);
}
@@ -950,9 +957,13 @@ static int rproc_add_virtio_devices(struct rproc *rproc)
* We're initiating an asynchronous firmware loading, so we can
* be built-in kernel code, without hanging the boot process.
*/
+#if 1
+ ret = rproc_fw_request_firmware_nowait(rproc, rproc_fw_config_virtio);
+#else
ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
rproc->firmware, &rproc->dev, GFP_KERNEL,
rproc, rproc_fw_config_virtio);
+#endif
if (ret < 0) {
dev_err(&rproc->dev, "request_firmware_nowait err: %d\n", ret);
complete_all(&rproc->firmware_loading_complete);
@@ -1076,7 +1087,7 @@ int rproc_boot(struct rproc *rproc)
dev_info(dev, "powering up %s\n", rproc->name);
/* load firmware */
- ret = request_firmware(&firmware_p, rproc->firmware, dev);
+ ret = rproc_fw_request_firmware(rproc, &firmware_p);
if (ret < 0) {
dev_err(dev, "request_firmware failed: %d\n", ret);
goto downref_rproc;
@@ -1084,7 +1095,7 @@ int rproc_boot(struct rproc *rproc)
ret = rproc_fw_boot(rproc, firmware_p);
- release_firmware(firmware_p);
+ rproc_fw_release_firmware(rproc, firmware_p);
downref_rproc:
if (ret) {
diff --git a/drivers/remoteproc/remoteproc_dummy_loader.c b/drivers/remoteproc/remoteproc_dummy_loader.c
new file mode 100644
index 00000000..90c53aad
--- /dev/null
+++ b/drivers/remoteproc/remoteproc_dummy_loader.c
@@ -0,0 +1,81 @@
+/*
+ * Remote Processor Framework Elf loader
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Ohad Ben-Cohen <ohad@wizery.com>
+ * Brian Swetland <swetland@google.com>
+ * Mark Grosen <mgrosen@ti.com>
+ * Fernando Guzman Lugo <fernando.lugo@ti.com>
+ * Suman Anna <s-anna@ti.com>
+ * Robert Tivy <rtivy@ti.com>
+ * Armando Uribe De Leon <x0095078@ti.com>
+ * Sjur Brændeland <sjur.brandeland@stericsson.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/firmware.h>
+#include <linux/remoteproc.h>
+#include <linux/slab.h>
+#include <linux/virtio_ids.h>
+
+#include <plat/remoteproc.h>
+
+#include "remoteproc_internal.h"
+
+static struct resource_table *
+rproc_dummy_find_rsc_table(struct rproc *rproc, const struct firmware *fw,
+ int *tablesz)
+{
+ struct ambarella_rproc_pdata *pdata = rproc->priv;
+
+ return pdata->gen_rsc_table(tablesz);
+}
+
+static int rproc_dummy_load_segments(struct rproc *rproc,
+ const struct firmware *fw)
+{
+ return 0;
+}
+
+static int rproc_dummy_request_firmware_nowait( struct module *module, bool uevent,
+ const char *name, struct device *device, gfp_t gfp, void *context,
+ void (*cont)(const struct firmware *fw, void *context))
+{
+ cont(NULL, context);
+
+ return 0;
+}
+
+static int rproc_dummy_request_firmware(const struct firmware **firmware_p,
+ const char *name, struct device *device)
+{
+ *firmware_p = kzalloc(sizeof(**firmware_p), GFP_KERNEL);
+
+ return 0;
+}
+
+static void rproc_dummy_release_firmware(const struct firmware *fw)
+{
+ kfree(fw);
+}
+
+const struct rproc_fw_ops rproc_dummy_fw_ops = {
+ .request_firmware = rproc_dummy_request_firmware,
+ .request_firmware_nowait = rproc_dummy_request_firmware_nowait,
+ .release_firmware = rproc_dummy_release_firmware,
+ .load = rproc_dummy_load_segments,
+ .find_rsc_table = rproc_dummy_find_rsc_table,
+ .sanity_check = NULL,
+ .get_boot_addr = NULL
+};
diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c
index ce283a5b..250dfc99 100644
--- a/drivers/remoteproc/remoteproc_elf_loader.c
+++ b/drivers/remoteproc/remoteproc_elf_loader.c
@@ -329,6 +329,10 @@ rproc_elf_find_loaded_rsc_table(struct rproc *rproc, const struct firmware *fw)
}
const struct rproc_fw_ops rproc_elf_fw_ops = {
+ .request_firmware = request_firmware,
+ .get_boot_addr = rproc_elf_get_boot_addr,
+ .request_firmware_nowait = request_firmware_nowait,
+ .release_firmware = release_firmware,
.load = rproc_elf_load_segments,
.find_rsc_table = rproc_elf_find_rsc_table,
.find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table,
diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h
index 157e762c..b5f9d09c 100644
--- a/drivers/remoteproc/remoteproc_internal.h
+++ b/drivers/remoteproc/remoteproc_internal.h
@@ -22,6 +22,7 @@
#include <linux/irqreturn.h>
#include <linux/firmware.h>
+#include <linux/module.h>
struct rproc;
@@ -40,6 +41,12 @@ struct rproc_fw_ops {
int *tablesz);
struct resource_table *(*find_loaded_rsc_table)(struct rproc *rproc,
const struct firmware *fw);
+ int (*request_firmware)(const struct firmware **firmware_p,
+ const char *name, struct device *device);
+ int (*request_firmware_nowait)(struct module *module, bool uevent,
+ const char *name, struct device *device, gfp_t gfp, void *context,
+ void (*cont)(const struct firmware *fw, void *context));
+ void (*release_firmware)(const struct firmware *fw);
int (*load)(struct rproc *rproc, const struct firmware *fw);
int (*sanity_check)(struct rproc *rproc, const struct firmware *fw);
u32 (*get_boot_addr)(struct rproc *rproc, const struct firmware *fw);
@@ -68,6 +75,38 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i);
void *rproc_da_to_va(struct rproc *rproc, u64 da, int len);
int rproc_trigger_recovery(struct rproc *rproc);
+static inline
+int rproc_fw_request_firmware(struct rproc *rproc, const struct firmware **fw)
+{
+ if (rproc->fw_ops->request_firmware)
+ return rproc->fw_ops->request_firmware(fw,
+ rproc->firmware,
+ &rproc->dev);
+
+ return 0;
+}
+
+static inline
+int rproc_fw_request_firmware_nowait(struct rproc *rproc,
+ void (*cont)(const struct firmware *fw, void *context))
+{
+ if (rproc->fw_ops->request_firmware_nowait) {
+ return rproc->fw_ops->request_firmware_nowait(THIS_MODULE,
+ FW_ACTION_HOTPLUG, rproc->firmware,
+ &rproc->dev, GFP_KERNEL, rproc,
+ cont);
+ }
+
+ return 0;
+}
+
+static inline
+void rproc_fw_release_firmware(struct rproc *rproc, const struct firmware *fw)
+{
+ if (rproc->fw_ops->release_firmware)
+ rproc->fw_ops->release_firmware(fw);
+}
+
static inline
int rproc_fw_sanity_check(struct rproc *rproc, const struct firmware *fw)
{
diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig
index 69a21938..93205bd6 100644
--- a/drivers/rpmsg/Kconfig
+++ b/drivers/rpmsg/Kconfig
@@ -6,4 +6,11 @@ config RPMSG
select VIRTIO
select VIRTUALIZATION
+config RPMSG_TX_SPINLOCK
+ bool "Support non-blocking TX in interrupt context"
+ default y
+ depends on RPMSG
+
+source "drivers/rpmsg/ambarella/Kconfig"
+
endmenu
diff --git a/drivers/rpmsg/Makefile b/drivers/rpmsg/Makefile
index 7617fcb8..a6e02158 100644
--- a/drivers/rpmsg/Makefile
+++ b/drivers/rpmsg/Makefile
@@ -1 +1,2 @@
obj-$(CONFIG_RPMSG) += virtio_rpmsg_bus.o
+obj-$(CONFIG_PLAT_AMBARELLA_SUPPORT_RPROC) += ambarella/
diff --git a/drivers/rpmsg/ambarella/Kconfig b/drivers/rpmsg/ambarella/Kconfig
new file mode 100644
index 00000000..47f518db
--- /dev/null
+++ b/drivers/rpmsg/ambarella/Kconfig
@@ -0,0 +1,24 @@
+menu "RPMSG Host Programs"
+depends on RPROC_SUPPORT
+source "drivers/rpmsg/ambarella/host/ambxc/Kconfig"
+source "drivers/rpmsg/ambarella/host/aservice/Kconfig"
+source "drivers/rpmsg/ambarella/host/echo/Kconfig"
+source "drivers/rpmsg/ambarella/host/rsh/Kconfig"
+source "drivers/rpmsg/ambarella/host/veth/Kconfig"
+source "drivers/rpmsg/ambarella/host/wnfs/Kconfig"
+source "drivers/rpmsg/ambarella/host/rnfs/Kconfig"
+source "drivers/rpmsg/ambarella/host/vgpio/Kconfig"
+
+endmenu
+
+menu "RPMSG Client Programs"
+depends on RPCLNT_SUPPORT
+
+source "drivers/rpmsg/ambarella/clnt/rsh/Kconfig"
+source "drivers/rpmsg/ambarella/clnt/echo/Kconfig"
+source "drivers/rpmsg/ambarella/clnt/veth/Kconfig"
+
+endmenu
+
+source "drivers/rpmsg/ambarella/common/rsh/Kconfig"
+source "drivers/rpmsg/ambarella/common/veth/Kconfig"
diff --git a/drivers/rpmsg/ambarella/Makefile b/drivers/rpmsg/ambarella/Makefile
new file mode 100644
index 00000000..023530aa
--- /dev/null
+++ b/drivers/rpmsg/ambarella/Makefile
@@ -0,0 +1,15 @@
+obj-$(CONFIG_RPROC_SUPPORT) += host/ambxc/
+obj-$(CONFIG_RPROC_SUPPORT) += host/aservice/
+obj-$(CONFIG_RPROC_SUPPORT) += host/rsh/
+obj-$(CONFIG_RPROC_SUPPORT) += host/echo/
+obj-$(CONFIG_RPROC_SUPPORT) += host/veth/
+obj-$(CONFIG_RPROC_SUPPORT) += host/wnfs/
+obj-$(CONFIG_RPROC_SUPPORT) += host/rnfs/
+obj-$(CONFIG_RPROC_SUPPORT) += host/vgpio/
+
+obj-$(CONFIG_RPCLNT_SUPPORT) += clnt/rsh/
+obj-$(CONFIG_RPCLNT_SUPPORT) += clnt/echo/
+obj-$(CONFIG_RPCLNT_SUPPORT) += clnt/veth/
+
+obj-y += common/rsh/
+obj-y += common/veth/
diff --git a/drivers/rpmsg/ambarella/clnt/echo/Kconfig b/drivers/rpmsg/ambarella/clnt/echo/Kconfig
new file mode 100644
index 00000000..8df1983b
--- /dev/null
+++ b/drivers/rpmsg/ambarella/clnt/echo/Kconfig
@@ -0,0 +1,4 @@
+config RPDEV_ECHO
+ tristate "Echo"
+ help
+ A sample of rpmsg program which implement an "echo client".
diff --git a/drivers/rpmsg/ambarella/clnt/echo/Makefile b/drivers/rpmsg/ambarella/clnt/echo/Makefile
new file mode 100644
index 00000000..c91826f4
--- /dev/null
+++ b/drivers/rpmsg/ambarella/clnt/echo/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_RPDEV_ECHO) += rpdev_echo.o
diff --git a/drivers/rpmsg/ambarella/clnt/echo/rpdev_echo.c b/drivers/rpmsg/ambarella/clnt/echo/rpdev_echo.c
new file mode 100644
index 00000000..9a021986
--- /dev/null
+++ b/drivers/rpmsg/ambarella/clnt/echo/rpdev_echo.c
@@ -0,0 +1,77 @@
+/**
+ * History:
+ * 2012/07/30 - [Tzu-Jung Lee] created file
+ *
+ * Copyright 2008-2015 Ambarella Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/rpmsg.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/remoteproc.h>
+
+#include <plat/rpdev.h>
+
+static void rpdev_echo_cb(struct rpdev *rpdev, void *data, int len,
+ void *priv, u32 src)
+{
+ printk("[ %20s ] recv message: [%s]\n", __func__, (char *)data);
+}
+
+static void rpdev_echo_init_work(struct work_struct *work)
+{
+ struct rpdev *rpdev;
+ char *str = "Hello from CA9-B";
+ char buf[64];
+ int i;
+
+ rpdev = rpdev_alloc("echo_ca9_b", 0, rpdev_echo_cb, NULL);
+
+ rpdev_register(rpdev, "ca9_a_and_b");
+
+ printk("[ %20s ] send message: [%s]\n", __func__, str);
+
+ for (i = 0; i < 512; i++) {
+ sprintf(buf, "%s %d", str, i);
+ printk("try sending: %s OK\n", buf);
+ while (rpdev_trysend(rpdev, buf, strlen(buf) + 1) != 0) {
+ printk("retry sending: %s\n", buf);
+ msleep(10);
+ }
+ }
+
+ for (i = 0; i < 512; i++) {
+ sprintf(buf, "%s %d (wait)", str, i);
+ printk("sending: %s OK\n", buf);
+ rpdev_send(rpdev, buf, strlen(buf) + 1);
+ }
+}
+
+static struct work_struct work;
+
+static int rpdev_echo_init(void)
+{
+ INIT_WORK(&work, rpdev_echo_init_work);
+ schedule_work(&work);
+ return 0;
+}
+
+static void rpdev_echo_fini(void)
+{
+}
+
+module_init(rpdev_echo_init);
+module_exit(rpdev_echo_fini);
diff --git a/drivers/rpmsg/ambarella/clnt/rsh/Kconfig b/drivers/rpmsg/ambarella/clnt/rsh/Kconfig
new file mode 100644
index 00000000..4be32a86
--- /dev/null
+++ b/drivers/rpmsg/ambarella/clnt/rsh/Kconfig
@@ -0,0 +1,6 @@
+config RPDEV_RSH
+ tristate "Remote Shell"
+ select AMBARELLA_RSH
+ help
+ A Remote shell server for CA9-B to accept remote
+ connection from CA9-A
diff --git a/drivers/rpmsg/ambarella/clnt/rsh/Makefile b/drivers/rpmsg/ambarella/clnt/rsh/Makefile
new file mode 100644
index 00000000..9045f8ec
--- /dev/null
+++ b/drivers/rpmsg/ambarella/clnt/rsh/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_RPDEV_RSH) += rpdev_rsh.o
+
diff --git a/drivers/rpmsg/ambarella/clnt/rsh/rpdev_rsh.c b/drivers/rpmsg/ambarella/clnt/rsh/rpdev_rsh.c
new file mode 100644
index 00000000..cfeb8632
--- /dev/null
+++ b/drivers/rpmsg/ambarella/clnt/rsh/rpdev_rsh.c
@@ -0,0 +1,75 @@
+/**
+ * History:
+ * 2012/09/15 - [Tzu-Jung Lee] created file
+ *
+ * Copyright 2008-2015 Ambarella Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/tty.h>
+#include <linux/remoteproc.h>
+
+#include <plat/rpdev.h>
+
+extern int rsh_init_driver(void);
+extern int rsh_init_device(int index, void *rpdev);
+
+extern void rsh_cb(int index, void *data, int len);
+
+int do_rsh_write(void *rpdev, const unsigned char *buf, int count)
+{
+ while (rpdev_trysend(rpdev, (char*)buf, count))
+ ;
+
+ return count;
+}
+
+static void rpdev_rsh_cb(struct rpdev *rpdev, void *data, int len,
+ void *priv, u32 src)
+{
+ rsh_cb((int)priv, data, len);
+}
+
+static void rpdev_rsh_init_work(struct work_struct *work)
+{
+ struct rpdev *rpdev;
+ int index = 0;
+
+ rpdev = rpdev_alloc("rsh_ca9_b", 0, rpdev_rsh_cb, NULL);
+
+ rsh_init_driver();
+ rpdev->priv = (void*)index;
+
+ rpdev_register(rpdev, "ca9_a_and_b");
+
+ rsh_init_device(index, rpdev);
+}
+
+static struct work_struct work;
+
+static int rpdev_rsh_init(void)
+{
+ INIT_WORK(&work, rpdev_rsh_init_work);
+ schedule_work(&work);
+
+ return 0;
+}
+
+static void rpdev_rsh_fini(void)
+{
+}
+
+module_init(rpdev_rsh_init);
+module_exit(rpdev_rsh_fini);
+
+MODULE_DESCRIPTION("RPMSG Remote Shell");
diff --git a/drivers/rpmsg/ambarella/clnt/veth/Kconfig b/drivers/rpmsg/ambarella/clnt/veth/Kconfig
new file mode 100644
index 00000000..37930a41
--- /dev/null
+++ b/drivers/rpmsg/ambarella/clnt/veth/Kconfig
@@ -0,0 +1,5 @@
+config RPDEV_VETH
+ tristate "Virtual Ethernet"
+ select AMBARELLA_VETH
+ help
+ A virtualized ethernet device over RPMSG bus.
diff --git a/drivers/rpmsg/ambarella/clnt/veth/Makefile b/drivers/rpmsg/ambarella/clnt/veth/Makefile
new file mode 100644
index 00000000..1bcbdc7d
--- /dev/null
+++ b/drivers/rpmsg/ambarella/clnt/veth/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_RPDEV_VETH) += rpdev_veth.o
diff --git a/drivers/rpmsg/ambarella/clnt/veth/rpdev_veth.c b/drivers/rpmsg/ambarella/clnt/veth/rpdev_veth.c
new file mode 100644
index 00000000..d99f888b
--- /dev/null
+++ b/drivers/rpmsg/ambarella/clnt/veth/rpdev_veth.c
@@ -0,0 +1,50 @@
+#include <plat/rpdev.h>
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+extern struct platform_device ambveth_device;
+extern void ambveth_enqueue(void *priv, void *data, int len);
+
+struct rpdev *g_rpdev;
+
+int ambveth_do_send(void *data, int len)
+{
+ return rpdev_trysend(g_rpdev, data, len);
+}
+
+static void rpdev_veth_client_cb(struct rpdev *rpdev, void *data, int len,
+ void *priv, u32 src)
+{
+ ambveth_enqueue(priv, data, len);
+}
+
+static void rpdev_veth_client_init_work(struct work_struct *work)
+{
+ struct rpdev *rpdev;
+
+ platform_device_register(&ambveth_device);
+
+ rpdev = rpdev_alloc("veth_ca9_b", 0, rpdev_veth_client_cb, &ambveth_device);
+
+ rpdev_register(rpdev, "ca9_a_and_b");
+ g_rpdev = rpdev;
+}
+
+static struct work_struct work;
+
+static int rpdev_veth_client_init(void)
+{
+ INIT_WORK(&work, rpdev_veth_client_init_work);
+ schedule_work(&work);
+ return 0;
+}
+
+static void rpdev_veth_client_fini(void)
+{
+}
+
+module_init(rpdev_veth_client_init);
+module_exit(rpdev_veth_client_fini);
+
+MODULE_DESCRIPTION("RPMSG VETH");
diff --git a/drivers/rpmsg/ambarella/common/rsh/Kconfig b/drivers/rpmsg/ambarella/common/rsh/Kconfig
new file mode 100644
index 00000000..c24abd26
--- /dev/null
+++ b/drivers/rpmsg/ambarella/common/rsh/Kconfig
@@ -0,0 +1,4 @@
+config AMBARELLA_RSH
+ bool
+ default n
+ depends on RPDEV_RSH || RPMSG_RSH
diff --git a/drivers/rpmsg/ambarella/common/rsh/Makefile b/drivers/rpmsg/ambarella/common/rsh/Makefile
new file mode 100644
index 00000000..553391aa
--- /dev/null
+++ b/drivers/rpmsg/ambarella/common/rsh/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_AMBARELLA_RSH) += rsh.o
diff --git a/drivers/rpmsg/ambarella/common/rsh/rsh.c b/drivers/rpmsg/ambarella/common/rsh/rsh.c
new file mode 100644
index 00000000..54cc5f27
--- /dev/null
+++ b/drivers/rpmsg/ambarella/common/rsh/rsh.c
@@ -0,0 +1,160 @@
+#include <linux/err.h>
+#include <linux/kfifo.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+
+extern int do_rsh_write(void *rpdev,
+ const unsigned char *buf,
+ int count);
+
+struct rsh_struct
+{
+ struct tty_port port;
+ struct timer_list timer;
+ struct kfifo fifo;
+ void *rpdev;
+
+ spinlock_t lock;
+};
+
+static struct rsh_struct g_rsh[3];
+static struct tty_driver *g_driver;
+
+void rsh_cb(int index, void *data, int len)
+{
+ struct rsh_struct *rsh = &g_rsh[index];
+
+ kfifo_in_locked(&rsh->fifo, (char *)data, len, &rsh->lock);
+}
+
+static void rsh_receive_chars(unsigned long data)
+{
+ struct rsh_struct *rsh = (struct rsh_struct *)data;
+ struct tty_port *port = &rsh->port;
+ char c;
+
+ while (kfifo_out_locked(&rsh->fifo, &c, sizeof(c), &rsh->lock))
+ tty_insert_flip_char(port, c, 0);
+
+ tty_schedule_flip(port);
+
+ spin_lock(&port->lock);
+ if (port->tty)
+ mod_timer(&rsh->timer, jiffies + 50);
+ spin_unlock(&port->lock);
+}
+
+static int rsh_write(struct tty_struct *tty, const unsigned char *buf,
+ int count)
+{
+ struct rsh_struct *rsh = &g_rsh[tty->index];
+
+ return do_rsh_write(rsh->rpdev, buf, count);
+}
+
+static int rsh_write_room(struct tty_struct *tty)
+{
+ return INT_MAX;
+}
+
+static int rsh_chars_in_buffer(struct tty_struct *tty)
+{
+ return 0;
+}
+
+static int rsh_open(struct tty_struct *tty, struct file *filp)
+{
+ struct rsh_struct *rsh = &g_rsh[tty->index];
+ struct tty_port *port = &rsh->port;
+
+ if (!port->tty) {
+ tty->driver_data = rsh;
+ tty->port = port;
+ port->tty = tty;
+ mod_timer(&rsh->timer, jiffies + 10);
+ }
+
+ return 0;
+}
+
+static void rsh_close(struct tty_struct *tty, struct file *filp)
+{
+ struct rsh_struct *rsh = &g_rsh[tty->index];
+ struct tty_port *port = &rsh->port;
+
+ if (tty->count == 1) {
+ port->tty = NULL;
+ del_timer(&rsh->timer);
+ }
+}
+
+static const struct tty_operations rsh_ops =
+{
+ .open = rsh_open,
+ .close = rsh_close,
+ .write = rsh_write,
+ .write_room = rsh_write_room,
+ .chars_in_buffer = rsh_chars_in_buffer,
+};
+
+extern int rsh_init_device(int index, void *rpdev)
+{
+ struct rsh_struct *rsh = &g_rsh[index];
+ struct tty_port *port;
+ int ret;
+ const char *name[3] = {
+ "CA9-A <-> CA9-B",
+ "CA9-A <-> ARM11",
+ "CA9-B <-> ARM11",
+ };
+
+ rsh = &g_rsh[index];
+ rsh->rpdev = rpdev;
+ port = &rsh->port;
+
+ tty_port_init(port);
+
+ setup_timer(&rsh->timer, rsh_receive_chars, (unsigned long)rsh);
+
+ spin_lock_init(&rsh->lock);
+
+ ret = kfifo_alloc(&rsh->fifo, 1024 * 64, GFP_KERNEL);
+ if (ret)
+ return ret;
+
+ tty_port_register_device(port, g_driver, index, NULL);
+
+ printk("RPMSG: Remote Shell /dev/ttyRSH%d (%s)\n", index, name[index]);
+
+ return 0;
+}
+
+int rsh_init_driver(void)
+{
+ struct tty_driver *driver;
+ int ret;
+
+ driver = tty_alloc_driver(3, 0);
+ if (!driver)
+ return -ENOMEM;
+
+ driver->driver_name = "ttyRSH";
+ driver->name = "ttyRSH";
+ driver->major = 0;
+ driver->minor_start = 0;
+ driver->type = TTY_DRIVER_TYPE_SYSTEM;
+ driver->subtype = SYSTEM_TYPE_SYSCONS;
+ driver->init_termios = tty_std_termios;
+ driver->flags = TTY_DRIVER_DYNAMIC_DEV;
+
+ tty_set_operations(driver, &rsh_ops);
+ ret = tty_register_driver(driver);
+ if (ret) {
+ put_tty_driver(driver);
+ return ret;
+ }
+
+ g_driver = driver;
+
+ return 0;
+}
diff --git a/drivers/rpmsg/ambarella/common/veth/Kconfig b/drivers/rpmsg/ambarella/common/veth/Kconfig
new file mode 100644
index 00000000..52ca6906
--- /dev/null
+++ b/drivers/rpmsg/ambarella/common/veth/Kconfig
@@ -0,0 +1,4 @@
+config AMBARELLA_VETH
+ bool
+ default n
+ depends on RPDEV_VETH || RPMSG_VETH
diff --git a/drivers/rpmsg/ambarella/common/veth/Makefile b/drivers/rpmsg/ambarella/common/veth/Makefile
new file mode 100644
index 00000000..e5d33873
--- /dev/null
+++ b/drivers/rpmsg/ambarella/common/veth/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_AMBARELLA_VETH) += veth.o
diff --git a/drivers/rpmsg/ambarella/common/veth/veth.c b/drivers/rpmsg/ambarella/common/veth/veth.c
new file mode 100644
index 00000000..a7c2125e
--- /dev/null
+++ b/drivers/rpmsg/ambarella/common/veth/veth.c
@@ -0,0 +1,237 @@
+/*
+ * Author: Tzu-Jung Lee <tjlee@ambarella.com>
+ * Copyright (C) 2012-2013, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/err.h>
+
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/time.h>
+#include <linux/crc16.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/rpmsg.h>
+
+#include <plat/ambcache.h>
+
+#define MIN_MTU 68
+#define MAX_MTU (4096 - ETH_HLEN - sizeof(struct rpmsg_hdr))
+#define DEF_MTU MAX_MTU
+
+extern int ambveth_do_send(void *data, int len);
+
+struct ambveth
+{
+ spinlock_t lock;
+
+ struct net_device_stats stats;
+ struct net_device *ndev;
+};
+
+void ambveth_enqueue(void *priv, void *data, int len)
+{
+ struct ambveth *lp;
+ struct sk_buff *skb;
+
+ lp = ((struct platform_device*)priv)->dev.platform_data;
+
+ skb = dev_alloc_skb(len + NET_IP_ALIGN);
+ if (!skb) {
+ lp->stats.rx_dropped++;
+ return;
+ }
+ skb_put(skb, len);
+
+ memcpy(skb->data, data, len);
+
+ lp->stats.rx_packets++;
+ lp->stats.rx_bytes += len;
+
+ skb->dev = lp->ndev;
+ skb->protocol = eth_type_trans(skb, skb->dev);
+
+ netif_rx_ni(skb);
+}
+
+static int ambveth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+ struct ambveth *lp;
+ int ret;
+
+ lp = netdev_priv(ndev);
+
+ ret = ambveth_do_send(skb->data, skb->len);
+ if (ret) {
+ lp->stats.tx_dropped++;
+
+ return NETDEV_TX_BUSY;
+ }
+
+ lp->stats.tx_packets++;
+ lp->stats.tx_bytes += skb->len;
+
+ dev_kfree_skb(skb);
+
+ return NETDEV_TX_OK;
+}
+
+static int ambveth_open(struct net_device *ndev)
+{
+ struct ambveth *lp;
+
+ lp = netdev_priv(ndev);
+
+ netif_start_queue(ndev);
+
+ return 0;
+}
+
+static int ambveth_stop(struct net_device *ndev)
+{
+ struct ambveth *lp;
+
+ lp = netdev_priv(ndev);
+
+ netif_stop_queue(ndev);
+ flush_scheduled_work();
+
+ return 0;
+}
+
+static void ambveth_timeout(struct net_device *ndev)
+{
+ netif_wake_queue(ndev);
+}
+
+static struct net_device_stats *ambveth_get_stats(struct net_device *ndev)
+{
+ struct ambveth *lp;
+
+ lp = netdev_priv(ndev);
+
+ return &lp->stats;
+}
+
+static int ambveth_change_mtu(struct net_device *dev, int mtu)
+{
+ if (mtu < MIN_MTU || mtu + dev->hard_header_len > MAX_MTU)
+
+ return -EINVAL;
+
+ dev->mtu = mtu;
+
+ return 0;
+}
+
+static int ambveth_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd)
+{
+ int ret = 0;
+
+ if (!netif_running(ndev)) {
+ ret = -EINVAL;
+ goto ambveth_get_settings_exit;
+ }
+
+ambveth_get_settings_exit:
+ return ret;
+}
+
+/* ==========================================================================*/
+static const struct net_device_ops ambveth_netdev_ops = {
+ .ndo_open = ambveth_open,
+ .ndo_stop = ambveth_stop,
+ .ndo_start_xmit = ambveth_start_xmit,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_do_ioctl = ambveth_ioctl,
+ .ndo_tx_timeout = ambveth_timeout,
+ .ndo_get_stats = ambveth_get_stats,
+ .ndo_change_mtu = ambveth_change_mtu,
+};
+
+struct platform_device ambveth_device = {
+ .name = "ambveth",
+ .id = 0,
+ .resource = NULL,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = NULL,
+ }
+};
+
+static int ambveth_drv_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct net_device *ndev;
+ struct ambveth *lp;
+ char mac_addr[6];
+
+ ndev = alloc_etherdev(sizeof(struct ambveth));
+ if (!ndev)
+ ret = -ENOMEM;
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+
+ lp = netdev_priv(ndev);
+ lp->ndev = ndev;
+ spin_lock_init(&lp->lock);
+ pdev->dev.platform_data = lp;
+
+ ndev->netdev_ops = &ambveth_netdev_ops;
+ ndev->mtu = DEF_MTU;
+ sprintf(ndev->name, "veth0");
+
+ if (!is_valid_ether_addr(mac_addr))
+ random_ether_addr(mac_addr);
+
+ memcpy(ndev->dev_addr, mac_addr, 6);
+
+ ret = register_netdev(ndev);
+ if (ret)
+ dev_err(&pdev->dev, " register_netdev fail%d.\n", ret);
+
+ return ret;
+}
+
+static struct platform_driver ambveth_driver = {
+ .probe = ambveth_drv_probe,
+ .driver = {
+ .name = "ambveth",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init ambveth_init(void)
+{
+ return platform_driver_register(&ambveth_driver);
+}
+
+static void __exit ambveth_fini(void)
+{
+}
+
+module_init(ambveth_init);
+module_exit(ambveth_fini);
+
+MODULE_DESCRIPTION("Ambarella veth driver");
diff --git a/drivers/rpmsg/ambarella/host/ambxc/Kconfig b/drivers/rpmsg/ambarella/host/ambxc/Kconfig
new file mode 100644
index 00000000..f3940fba
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/ambxc/Kconfig
@@ -0,0 +1,11 @@
+config RPMSG_AMBXC
+ tristate "Ambarella A8 Codec driver"
+ depends on RPMSG
+ select VIDEO_V4L2
+ select V4L2_MEM2MEM_DEV
+ select VIDEOBUF2_CORE
+ select VIDEOBUF2_MEMOPS
+ select VIDEOBUF2_VMALLOC
+ default n
+ ---help---
+ V4L2 Display driver support for Ambarella A8.
diff --git a/drivers/rpmsg/ambarella/host/ambxc/Makefile b/drivers/rpmsg/ambarella/host/ambxc/Makefile
new file mode 100644
index 00000000..448c987e
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/ambxc/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for the ambarella video device drivers.
+#
+
+# Ambarella A8 CODEC driver
+rpmsg_ambxc-y += ambxc_vdev.o \
+ ambxc_ioctl.o \
+ ambxc_ctrls.o \
+ ambxc_ctl.o \
+ ambxc_rpmsg.o
+
+obj-$(CONFIG_RPMSG_AMBXC) += rpmsg_ambxc.o
diff --git a/drivers/rpmsg/ambarella/host/ambxc/ambxc.h b/drivers/rpmsg/ambarella/host/ambxc/ambxc.h
new file mode 100644
index 00000000..312d5a03
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/ambxc/ambxc.h
@@ -0,0 +1,80 @@
+#ifndef __AMBXC_H__
+#define __AMBXC_H__
+
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/kthread.h>
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+#include <media/videobuf2-vmalloc.h>
+
+#define AMBXC_NAME "ambxc"
+
+#define MEM2MEM_DEF_NUM_BUFS VIDEO_MAX_FRAME
+#define MEM2MEM_VID_MEM_LIMIT (16 * 1024 * 1024)
+
+#define dprintk(dev, fmt, arg...) \
+ v4l2_dbg(1, 1, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg)
+
+#define BUF_SIZE (0x80000)
+
+struct ambxc_fmt {
+ char *name;
+ u32 fourcc;
+ u32 types;
+ int field;
+};
+
+#define NUM_FORMATS ARRAY_SIZE(formats)
+
+/* Per-queue, driver-specific private data */
+struct ambxc_q_data {
+ unsigned int width;
+ unsigned int height;
+ unsigned int sizeimage;
+ struct ambxc_fmt *fmt;
+};
+
+enum {
+ V4L2_M2M_SRC = 0,
+ V4L2_M2M_DST = 1,
+};
+
+struct ambxc_dev {
+ struct v4l2_device v4l2_dev;
+ struct video_device *vfd;
+
+ atomic_t inst;
+ atomic_t ref_cnt;
+ struct ambxc_ctx *ctx;
+ struct mutex dev_mutex;
+ spinlock_t irqlock;
+ struct task_struct *kthread_capture;
+ struct task_struct *kthread_feed;
+ wait_queue_head_t queue_capture;
+ wait_queue_head_t queue_feed;
+
+ struct v4l2_m2m_dev *m2m_dev;
+};
+
+struct ambxc_ctx {
+ struct v4l2_fh fh;
+ struct ambxc_dev *dev;
+
+ struct v4l2_ctrl_handler hdl;
+ struct v4l2_ctrl *ctrls[128];
+
+ struct v4l2_m2m_ctx *m2m_ctx;
+
+ /* Source and destination queue data */
+ struct ambxc_q_data q_data[2];
+};
+
+static inline struct ambxc_ctx* file2ctx(struct file *file)
+{
+ return container_of(file->private_data, struct ambxc_ctx, fh);
+}
+
+#endif /* __AMBXC_H__ */
diff --git a/drivers/rpmsg/ambarella/host/ambxc/ambxc_ctl.c b/drivers/rpmsg/ambarella/host/ambxc/ambxc_ctl.c
new file mode 100644
index 00000000..d5320aa4
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/ambxc/ambxc_ctl.c
@@ -0,0 +1,75 @@
+/**
+ * History:
+ * 2012/09/15 - [Tzu-Jung Lee] created file
+ *
+ * Copyright 2008-2015 Ambarella Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/tty.h>
+#include <linux/remoteproc.h>
+#include <linux/rpmsg.h>
+
+static struct rpmsg_channel *rpdev_ambxc_ctl;
+
+int ambxc_ctl_send(const char *buf, int count)
+{
+ struct rpmsg_channel *rpdev = rpdev_ambxc_ctl;
+
+ while (rpmsg_trysend(rpdev, (char*)buf, count))
+ ;
+
+ return count;
+}
+
+static void rpmsg_ambxc_ctl_cb(struct rpmsg_channel *rpdev, void *data,
+ int len, void *priv, u32 src)
+{
+ //ambxc_ctl_cb((int)priv, data, len);
+}
+
+static int rpmsg_ambxc_ctl_probe(struct rpmsg_channel *rpdev)
+{
+ int ret = 0;
+ struct rpmsg_ns_msg nsm;
+ int index;
+
+ nsm.addr = rpdev->dst;
+ memcpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
+ nsm.flags = 0;
+
+ rpdev->ept->priv = (void*)index;
+ rpdev_ambxc_ctl = rpdev;
+ rpmsg_sendto(rpdev, &nsm, sizeof(nsm), rpdev->dst);
+
+ return ret;
+}
+
+static void rpmsg_ambxc_ctl_remove(struct rpmsg_channel *rpdev)
+{
+}
+
+static struct rpmsg_device_id rpmsg_ambxc_ctl_id_table[] = {
+ { .name = "ambxc_ctl_arm11", }, /* H: CA9-A, C: ARM11 */
+ { },
+};
+MODULE_DEVICE_TABLE(rpmsg, rpmsg_ambxc_ctl_id_table);
+
+struct rpmsg_driver rpmsg_ambxc_ctl_driver =
+{
+ .drv.name = "rpmsg_ambxc_ctl",
+ .drv.owner = THIS_MODULE,
+ .id_table = rpmsg_ambxc_ctl_id_table,
+ .probe = rpmsg_ambxc_ctl_probe,
+ .callback = rpmsg_ambxc_ctl_cb,
+ .remove = rpmsg_ambxc_ctl_remove,
+};
diff --git a/drivers/rpmsg/ambarella/host/ambxc/ambxc_ctrls.c b/drivers/rpmsg/ambarella/host/ambxc/ambxc_ctrls.c
new file mode 100644
index 00000000..e50e62cc
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/ambxc/ambxc_ctrls.c
@@ -0,0 +1,551 @@
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-vmalloc.h>
+#include <media/v4l2-ctrls.h>
+
+#include "ambxc.h"
+#include "ambxc_ctrls.h"
+
+#define IS_AMBXC_PRIV(x) ((V4L2_CTRL_ID2CLASS(x) == V4L2_CTRL_CLASS_MPEG) \
+ && V4L2_CTRL_DRIVER_PRIV(x))
+
+struct ambxc_control {
+ __u32 id;
+ enum v4l2_ctrl_type type;
+ __u8 name[32]; /* Whatever */
+ __s32 minimum; /* Note signedness */
+ __s32 maximum;
+ __s32 step;
+ __u32 menu_skip_mask;
+ __s32 default_value;
+ __u32 flags;
+ __u32 reserved[2];
+ __u8 is_volatile;
+};
+
+static struct ambxc_control controls[] = {
+ {
+ .id = V4L2_CID_MPEG_VIDEO_GOP_SIZE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = (1 << 16) - 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE,
+ .type = V4L2_CTRL_TYPE_MENU,
+ .minimum = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
+ .maximum = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES,
+ .default_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
+ .menu_skip_mask = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 1,
+ .maximum = (1 << 16) - 1,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 1900,
+ .maximum = (1 << 30) - 1,
+ .step = 1,
+ .default_value = 1900,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = (1 << 16) - 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_BITRATE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 1,
+ .maximum = (1 << 30) - 1,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VBV_SIZE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = (1 << 16) - 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = (1 << 16) - 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEADER_MODE,
+ .type = V4L2_CTRL_TYPE_MENU,
+ .minimum = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE,
+ .maximum = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
+ .default_value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE,
+ .menu_skip_mask = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_B_FRAMES,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = 2,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_PROFILE,
+ .type = V4L2_CTRL_TYPE_MENU,
+ .minimum = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
+ .maximum = V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH,
+ .default_value = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
+ .menu_skip_mask = ~(
+ (1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
+ (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
+ (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)
+ ),
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_LEVEL,
+ .type = V4L2_CTRL_TYPE_MENU,
+ .minimum = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
+ .maximum = V4L2_MPEG_VIDEO_H264_LEVEL_4_0,
+ .default_value = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL,
+ .type = V4L2_CTRL_TYPE_MENU,
+ .minimum = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0,
+ .maximum = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5,
+ .default_value = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0,
+ .menu_skip_mask = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE,
+ .type = V4L2_CTRL_TYPE_MENU,
+ .minimum = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED,
+ .maximum = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY,
+ .default_value = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED,
+ .menu_skip_mask = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = -6,
+ .maximum = 6,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = -6,
+ .maximum = 6,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE,
+ .type = V4L2_CTRL_TYPE_MENU,
+ .minimum = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
+ .maximum = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
+ .default_value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
+ .menu_skip_mask = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "MPEG4 I-Frame QP value",
+ .minimum = 1,
+ .maximum = 31,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "MPEG4 Minimum QP value",
+ .minimum = 1,
+ .maximum = 31,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "MPEG4 Maximum QP value",
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "MPEG4 P frame QP value",
+ .minimum = 1,
+ .maximum = 31,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "MPEG4 B frame QP value",
+ .minimum = 1,
+ .maximum = 31,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC,
+ .type = V4L2_CTRL_TYPE_MENU,
+ .minimum = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED,
+ .maximum = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED,
+ .default_value = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED,
+ .menu_skip_mask = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = (1 << 16) - 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = (1 << 16) - 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_I_PERIOD,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = (1 << 16) - 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE,
+ .type = V4L2_CTRL_TYPE_MENU,
+ .minimum = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE,
+ .maximum = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE,
+ .default_value = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE,
+ .menu_skip_mask = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_QPEL,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+};
+
+#define NUM_CTRLS ARRAY_SIZE(controls)
+
+/* Set controls - v4l2 control framework */
+static int ambxc_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct ambxc_ctx *ctx;
+ struct ambxc_dev *dev;
+ int ret = 0;
+
+ ctx = container_of(ctrl->handler, struct ambxc_ctx, hdl);
+ dev = ctx->dev;
+
+ switch (ctrl->id) {
+ case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+ break;
+ case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
+ break;
+ case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
+ break;
+ case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
+ break;
+ case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
+ break;
+ case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE:
+ break;
+ case V4L2_CID_MPEG_VIDEO_VBV_SIZE:
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE:
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
+ break;
+ case V4L2_CID_MPEG_VIDEO_B_FRAMES:
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
+ switch (ctrl->val) {
+ case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
+ break;
+ case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA:
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA:
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM:
+ break;
+ case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE:
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
+ break;
+ case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP:
+ case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP:
+ break;
+ case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP:
+ case V4L2_CID_MPEG_VIDEO_H263_MIN_QP:
+ break;
+ case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP:
+ case V4L2_CID_MPEG_VIDEO_H263_MAX_QP:
+ break;
+ case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP:
+ case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP:
+ break;
+ case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP:
+ case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP:
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE:
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH:
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT:
+ break;
+ case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
+ break;
+ case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
+ switch (ctrl->val) {
+ case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
+ break;
+ case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ break;
+ case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL:
+ break;
+ default:
+ v4l2_err(&dev->v4l2_dev, "Invalid control, id=%d, val=%d\n",
+ ctrl->id, ctrl->val);
+ ret = -EINVAL;
+ }
+ return ret;
+}
+
+static int ambxc_g_v_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct ambxc_ctx *ctx;
+ struct ambxc_dev *dev;
+
+ ctx = container_of(ctrl->handler, struct ambxc_ctx, hdl);
+ dev = ctx->dev;
+
+ switch (ctrl->id) {
+ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
+ break;
+ }
+
+ return 0;
+}
+
+static const struct v4l2_ctrl_ops ambxc_ctrl_ops = {
+ .s_ctrl = ambxc_s_ctrl,
+ .g_volatile_ctrl = ambxc_g_v_ctrl,
+};
+
+int ambxc_init_ctrls(struct ambxc_ctx *ctx)
+{
+ struct ambxc_dev *dev = ctx->dev;
+ struct v4l2_ctrl_config cfg;
+ struct ambxc_control *ctrl;
+ int i;
+
+ v4l2_ctrl_handler_init(&ctx->hdl, NUM_CTRLS);
+ if (ctx->hdl.error) {
+ dprintk(dev, "v4l2_ctrl_handler_init failed\n");
+ return ctx->hdl.error;
+ }
+
+ for (i = 0; i < NUM_CTRLS; i++) {
+
+ ctrl = &controls[i];
+
+ if (IS_AMBXC_PRIV(ctrl->id)) {
+
+ memset(&cfg, 0, sizeof(struct v4l2_ctrl_config));
+ cfg.ops = &ambxc_ctrl_ops;
+ cfg.id = ctrl->id;
+ cfg.min = ctrl->minimum;
+ cfg.max = ctrl->maximum;
+ cfg.def = ctrl->default_value;
+ cfg.name = ctrl->name;
+ cfg.type = ctrl->type;
+
+ cfg.step = ctrl->step;
+ cfg.menu_skip_mask = 0;
+
+ ctx->ctrls[i] = v4l2_ctrl_new_custom(&ctx->hdl,
+ &cfg, NULL);
+ }
+ else {
+ if (ctrl->type == V4L2_CTRL_TYPE_MENU) {
+ ctx->ctrls[i] = v4l2_ctrl_new_std_menu(
+ &ctx->hdl,
+ &ambxc_ctrl_ops, ctrl->id,
+ ctrl->maximum, 0,
+ ctrl->default_value);
+ }
+ else {
+ ctx->ctrls[i] = v4l2_ctrl_new_std(
+ &ctx->hdl,
+ &ambxc_ctrl_ops, ctrl->id,
+ ctrl->minimum,
+ ctrl->maximum, ctrl->step,
+ ctrl->default_value);
+ }
+ }
+ if (ctx->hdl.error) {
+ dprintk(dev, "Adding control (%d) failed\n", i);
+ return ctx->hdl.error;
+ }
+ if (ctrl->is_volatile && ctx->ctrls[i])
+ ctx->ctrls[i]->flags |= V4L2_CTRL_FLAG_VOLATILE;
+ }
+
+ v4l2_ctrl_handler_setup(&ctx->hdl);
+
+ return 0;
+}
+
+void ambxc_release_ctrls(struct ambxc_ctx *ctx)
+{
+ v4l2_ctrl_handler_free(&ctx->hdl);
+}
diff --git a/drivers/rpmsg/ambarella/host/ambxc/ambxc_ctrls.h b/drivers/rpmsg/ambarella/host/ambxc/ambxc_ctrls.h
new file mode 100644
index 00000000..9657575a
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/ambxc/ambxc_ctrls.h
@@ -0,0 +1,8 @@
+#ifndef __AMBXC_CTRLS_H__
+#define __AMBXC_CTRLS_H__
+
+extern int ambxc_init_ctrls(struct ambxc_ctx *ctx);
+extern void ambxc_release_ctrls(struct ambxc_ctx *ctx);
+extern const struct v4l2_ioctl_ops ambxc_ioctl_ops;
+
+#endif /* __AMBXC_CTRLS_H__ */
diff --git a/drivers/rpmsg/ambarella/host/ambxc/ambxc_ioctl.c b/drivers/rpmsg/ambarella/host/ambxc/ambxc_ioctl.c
new file mode 100644
index 00000000..38cf36b3
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/ambxc/ambxc_ioctl.c
@@ -0,0 +1,651 @@
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/timer.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+#include <linux/platform_device.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-event.h>
+#include <media/videobuf2-vmalloc.h>
+
+#include "ambxc.h"
+
+/* Flags that indicate a format can be used for capture/output */
+#define MEM2MEM_CAPTURE (1 << 0)
+#define MEM2MEM_OUTPUT (1 << 1)
+
+extern struct ambxc_q_data* get_q_data(struct ambxc_ctx *ctx,
+ enum v4l2_buf_type type);
+
+struct ambxc_fmt formats[] = {
+ {
+ .name = "H264 with start codes",
+ .fourcc = V4L2_PIX_FMT_H264,
+ .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
+ },
+ {
+ .name = "MPEG-2 ES",
+ .fourcc = V4L2_PIX_FMT_MPEG2,
+ .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
+ },
+ {
+ .name = "MPEG-1/2/4 Multiplexed",
+ .fourcc = V4L2_PIX_FMT_MPEG,
+ .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
+ },
+};
+
+struct v4l2_frmsize_discrete framesize[] = {
+
+ { 1920, 1080},
+ { 1280, 720},
+};
+
+static struct ambxc_fmt* find_format(struct v4l2_format *f)
+{
+ struct ambxc_fmt *fmt;
+ unsigned int k;
+
+ for (k = 0; k < NUM_FORMATS; k++) {
+ fmt = &formats[k];
+ if (fmt->fourcc == f->fmt.pix.pixelformat)
+ break;
+ }
+
+ if (k == NUM_FORMATS)
+ return NULL;
+
+ return &formats[k];
+}
+
+struct v4l2_frmsize_discrete* find_framesize(struct ambxc_ctx *ctx,
+ struct v4l2_format *f)
+{
+ struct v4l2_frmsize_discrete *frmsz;
+ struct ambxc_q_data *q_data;
+
+ int i = 0;
+ frmsz = &framesize[0];
+
+ /* find the exact match first */
+ for (i = 0; i < ARRAY_SIZE(framesize); i++) {
+
+ frmsz = &framesize[i];
+
+ if (frmsz->height == f->fmt.pix.height &&
+ frmsz->width == f->fmt.pix.width)
+ return frmsz;
+ }
+
+ /* return current framesize */
+ q_data = get_q_data(ctx, f->type);
+
+ for (i = 0; i < ARRAY_SIZE(framesize); i++) {
+
+ frmsz = &framesize[i];
+
+ if (frmsz->height == q_data->height &&
+ frmsz->width == q_data->width)
+ return frmsz;
+ }
+
+ /* return the last available framesize */
+ return frmsz;
+}
+
+
+/*
+ * video ioctls
+ */
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+{
+ strncpy(cap->driver, AMBXC_NAME, sizeof(cap->driver) - 1);
+ strncpy(cap->card, AMBXC_NAME, sizeof(cap->card) - 1);
+ snprintf(cap->bus_info, sizeof(cap->bus_info),
+ "platform:%s", AMBXC_NAME);
+ cap->device_caps = V4L2_CAP_VIDEO_M2M |
+ V4L2_CAP_VIDEO_CAPTURE |
+ V4L2_CAP_VIDEO_OUTPUT |
+ V4L2_CAP_STREAMING;
+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+
+ return 0;
+}
+
+static struct v4l2_input input = {
+ .name = "Camera 0",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .index = 0,
+};
+
+static int enum_fmt(struct v4l2_fmtdesc *f, u32 type)
+{
+ int i, num;
+ struct ambxc_fmt *fmt;
+
+ num = 0;
+
+ for (i = 0; i < NUM_FORMATS; ++i) {
+ if (formats[i].types & type) {
+ /* index-th format of type type found ? */
+ if (num == f->index)
+ break;
+ /* Correct type but haven't reached our index yet,
+ * just increment per-type index */
+ ++num;
+ }
+ }
+
+ if (i < NUM_FORMATS) {
+ /* Format found */
+ fmt = &formats[i];
+ strncpy(f->description, fmt->name, sizeof(f->description) - 1);
+ f->pixelformat = fmt->fourcc;
+ f->flags = V4L2_FMT_FLAG_COMPRESSED;
+ return 0;
+ }
+
+ /* Format not found */
+ return -EINVAL;
+}
+
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ return enum_fmt(f, MEM2MEM_CAPTURE);
+}
+
+static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ return enum_fmt(f, MEM2MEM_OUTPUT);
+}
+
+static int vidioc_g_fmt(struct ambxc_ctx *ctx, struct v4l2_format *f)
+{
+ struct vb2_queue *vq;
+ struct ambxc_q_data *q_data;
+
+ vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
+ if (!vq)
+ return -EINVAL;
+
+ q_data = get_q_data(ctx, f->type);
+
+ f->fmt.pix.width = q_data->width;
+ f->fmt.pix.height = q_data->height;
+ f->fmt.pix.field = V4L2_FIELD_NONE;
+ f->fmt.pix.pixelformat = q_data->fmt->fourcc;
+ f->fmt.pix.bytesperline = 0;
+ f->fmt.pix.sizeimage = BUF_SIZE;
+
+ return 0;
+}
+
+static int vidioc_g_fmt_vid_out(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ return vidioc_g_fmt(file2ctx(file), f);
+}
+
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ return vidioc_g_fmt(file2ctx(file), f);
+}
+
+static int vidioc_try_fmt(struct v4l2_format *f, struct ambxc_fmt *fmt)
+{
+ enum v4l2_field field;
+
+ field = f->fmt.pix.field;
+
+ if (field == V4L2_FIELD_ANY)
+ field = V4L2_FIELD_NONE;
+ else if (field != V4L2_FIELD_NONE)
+ return -EINVAL;
+
+ f->fmt.pix.field = field;
+ f->fmt.pix.bytesperline = 0;
+ f->fmt.pix.sizeimage = BUF_SIZE;
+
+ return 0;
+}
+
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct ambxc_fmt *fmt;
+ struct ambxc_ctx *ctx = file2ctx(file);
+
+ fmt = find_format(f);
+ if (!fmt || !(fmt->types & MEM2MEM_CAPTURE)) {
+ v4l2_err(&ctx->dev->v4l2_dev,
+ "Fourcc format (0x%08x) invalid.\n",
+ f->fmt.pix.pixelformat);
+ return -EINVAL;
+ }
+
+ return vidioc_try_fmt(f, fmt);
+}
+
+static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct ambxc_fmt *fmt;
+ struct ambxc_ctx *ctx = file2ctx(file);
+
+ fmt = find_format(f);
+ if (!fmt || !(fmt->types & MEM2MEM_OUTPUT)) {
+ v4l2_err(&ctx->dev->v4l2_dev,
+ "Fourcc format (0x%08x) invalid.\n",
+ f->fmt.pix.pixelformat);
+ return -EINVAL;
+ }
+
+ return vidioc_try_fmt(f, fmt);
+}
+
+static int vidioc_s_fmt(struct ambxc_ctx *ctx, struct v4l2_format *f)
+{
+ struct ambxc_q_data *q_data;
+ struct vb2_queue *vq;
+ struct v4l2_frmsize_discrete *frmsz;
+
+ vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
+ if (!vq)
+ return -EINVAL;
+
+ q_data = get_q_data(ctx, f->type);
+ if (!q_data)
+ return -EINVAL;
+
+ if (vb2_is_busy(vq)) {
+ v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__);
+ return -EBUSY;
+ }
+
+ frmsz = find_framesize(ctx, f);
+
+ q_data->fmt = find_format(f);
+ q_data->width = frmsz->width;
+ q_data->height = frmsz->height;
+ q_data->sizeimage = BUF_SIZE;
+
+ return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ int ret;
+
+ ret = vidioc_try_fmt_vid_cap(file, priv, f);
+ if (ret)
+ return ret;
+
+ return vidioc_s_fmt(file2ctx(file), f);
+}
+
+static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ int ret;
+
+ ret = vidioc_try_fmt_vid_out(file, priv, f);
+ if (ret)
+ return ret;
+
+ ret = vidioc_s_fmt(file2ctx(file), f);
+ return ret;
+}
+
+static int vidioc_enum_framesizes(struct file *file,
+ void *priv, struct v4l2_frmsizeenum *frms)
+{
+ if (frms->index >= ARRAY_SIZE(framesize))
+ return -EINVAL;
+
+ switch (frms->pixel_format) {
+ case V4L2_PIX_FMT_H264:
+ case V4L2_PIX_FMT_MPEG2:
+ frms->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+ frms->discrete = framesize[frms->index];
+
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int vidioc_reqbufs(struct file *file, void *priv,
+ struct v4l2_requestbuffers *reqbufs)
+{
+ struct ambxc_ctx *ctx = file2ctx(file);
+
+ return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
+}
+
+static int vidioc_querybuf(struct file *file, void *priv,
+ struct v4l2_buffer *buf)
+{
+ struct ambxc_ctx *ctx = file2ctx(file);
+
+ return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
+}
+
+static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+{
+ struct ambxc_ctx *ctx = file2ctx(file);
+
+ return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+{
+ struct ambxc_ctx *ctx = file2ctx(file);
+
+ return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
+}
+
+static int vidioc_streamon(struct file *file, void *priv,
+ enum v4l2_buf_type type)
+{
+ struct ambxc_ctx *ctx = file2ctx(file);
+
+ return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
+}
+
+static int vidioc_streamoff(struct file *file, void *priv,
+ enum v4l2_buf_type type)
+{
+ struct ambxc_ctx *ctx = file2ctx(file);
+
+ return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
+}
+
+static int vidioc_enum_input(struct file *file, void *priv,
+ struct v4l2_input *inp)
+{
+ if (inp->index >= 1)
+ return -EINVAL;
+
+ inp->type = V4L2_INPUT_TYPE_CAMERA;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
+{
+ if (i >= 1)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int vidioc_enum_output(struct file *file, void *priv,
+ struct v4l2_output *outp)
+{
+ if (outp->index >= 1)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int vidioc_g_output(struct file *file, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int vidioc_s_output(struct file *file, void *priv, unsigned int i)
+{
+ if (i >= 1)
+ return -EINVAL;
+
+ return 0;
+}
+
+extern int ambxc_ctl_send(const char *buf, int count);
+
+struct ambxc_cmd {
+
+ char *cmd;
+ int dly;
+};
+
+struct ambxc_cmd cmd_1080i_xc_start[] = {
+// {"d:\\ash\\Xcode\\XCODE_H2H_1080I_ES_NFS_CFG.ash", 8},
+// {"d:\\ash\\Xcode\\XCODE_H2H_1080I_ES_NFS_START.ash", 0},
+ { NULL, 0 }
+};
+
+struct ambxc_cmd cmd_720p_xc_start[] = {
+// {"d:\\ash\\Xcode\\XCODE_H2H_720P_ES_NFS_CFG.ash", 8},
+// {"d:\\ash\\Xcode\\XCODE_H2H_720P_ES_NFS_START.ash", 0},
+ { NULL, 0 }
+};
+
+struct ambxc_cmd *cmd_xc_start = cmd_720p_xc_start;
+
+struct timer_list cmd_timer;
+
+struct ambxc_cmd cmd_enc_stop[] = {
+ { "amba voch stop --par ENC_H264_1080I_AO_STOP -s 0 -c 0T", 1 },
+ { NULL, 0 }
+};
+
+static void do_xc_cmd(unsigned long priv)
+{
+ struct ambxc_cmd *cmds = (void *)priv;
+ char cmd_buf[128];
+
+ while (cmds->cmd) {
+
+ sprintf(cmd_buf, "%s\n", cmds->cmd);
+ printk(KERN_DEBUG "%s\n", cmd_buf);
+ ambxc_ctl_send(cmd_buf, strlen(cmd_buf));
+ mdelay(cmds->dly * 1000);
+ cmds++;
+ }
+}
+
+void do_xc_start(struct ambxc_ctx *ctx)
+{
+ struct ambxc_q_data *q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+
+ dprintk(ctx->dev, "do_xc_start:\n");
+
+ if (q_data->height == 720)
+ cmd_xc_start = cmd_720p_xc_start;
+ else
+ cmd_xc_start = cmd_1080i_xc_start;
+
+ do_xc_cmd((unsigned long)cmd_xc_start);
+}
+
+static void do_xc_stop(struct ambxc_ctx *ctx)
+{
+ dprintk(ctx->dev, "do_xcode_stop: (wait EOS from itron for 20 secs)\n");
+
+ setup_timer(&cmd_timer, do_xc_cmd, (unsigned long)cmd_enc_stop);
+ mod_timer(&cmd_timer, jiffies + msecs_to_jiffies(20 * 1000));
+}
+
+int vidioc_encoder_cmd(struct file *file, void *priv,
+ struct v4l2_encoder_cmd *cmd)
+{
+ struct ambxc_ctx *ctx = file2ctx(file);
+
+ switch (cmd->cmd) {
+ case V4L2_ENC_CMD_START:
+
+ if (cmd->flags != 0)
+ return -EINVAL;
+
+ do_xc_start(ctx);
+
+ break;
+
+ case V4L2_ENC_CMD_STOP:
+
+ if (cmd->flags != 0)
+ return -EINVAL;
+
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int vidioc_decoder_cmd(struct file *file, void *priv,
+ struct v4l2_decoder_cmd *cmd)
+{
+ struct ambxc_ctx *ctx = file2ctx(file);
+ switch (cmd->cmd) {
+ case V4L2_DEC_CMD_START:
+ if (cmd->flags != 0)
+ return -EINVAL;
+
+ do_xc_start(ctx);
+ break;
+
+ case V4L2_DEC_CMD_STOP:
+ if (cmd->flags != 0)
+ return -EINVAL;
+
+ while (!list_empty(&ctx->m2m_ctx->out_q_ctx.rdy_queue)) {
+ dprintk(ctx->dev, "wait until all queued OUTPUT buffers are sent\n");
+ msleep(1000);
+ }
+
+ do_xc_stop(ctx);
+
+ break;
+
+ default:
+ return -EINVAL;
+
+ }
+ return 0;
+}
+
+static int vidioc_subscribe_event(struct v4l2_fh *fh,
+ const struct v4l2_event_subscription *sub)
+{
+ switch (sub->type) {
+ case V4L2_EVENT_EOS:
+ return v4l2_event_subscribe(fh, sub, 2, NULL);
+ default:
+ return -EINVAL;
+ }
+}
+
+static int vidioc_g_parm(struct file *file, void *fh,
+ struct v4l2_streamparm *a) {
+ int rval = 0;
+#if 0
+ struct omap24xxcam_fh *ofh = fh;
+ struct omap24xxcam_device *cam = ofh->cam;
+
+ mutex_lock(&cam->mutex);
+ rval = vidioc_int_g_parm(cam->sdev, a);
+ mutex_unlock(&cam->mutex);
+#endif
+ return rval;
+}
+
+static int vidioc_s_parm(struct file *file, void *fh,
+ struct v4l2_streamparm *a)
+{
+ int rval = 0;
+#if 0
+ struct omap24xxcam_fh *ofh = fh;
+ struct omap24xxcam_device *cam = ofh->cam;
+ struct v4l2_streamparm old_streamparm;
+ int rval;
+
+ mutex_lock(&cam->mutex);
+ if (cam->streaming) {
+ rval = -EBUSY;
+ goto out;
+ }
+
+ old_streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ rval = vidioc_int_g_parm(cam->sdev, &old_streamparm);
+ if (rval)
+ goto out;
+
+ rval = vidioc_int_s_parm(cam->sdev, a);
+ if (rval)
+ goto out;
+
+ rval = omap24xxcam_sensor_if_enable(cam);
+ /*
+ * Revert to old streaming parameters if enabling sensor
+ * interface with the new ones failed.
+ */
+ if (rval)
+ vidioc_int_s_parm(cam->sdev, &old_streamparm);
+
+out:
+ mutex_unlock(&cam->mutex);
+#endif
+
+ return rval;
+}
+
+const struct v4l2_ioctl_ops ambxc_ioctl_ops = {
+
+ .vidioc_querycap = vidioc_querycap,
+
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+
+ .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
+ .vidioc_g_fmt_vid_out = vidioc_g_fmt_vid_out,
+ .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out,
+ .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out,
+
+ .vidioc_reqbufs = vidioc_reqbufs,
+ .vidioc_querybuf = vidioc_querybuf,
+
+ .vidioc_qbuf = vidioc_qbuf,
+ .vidioc_dqbuf = vidioc_dqbuf,
+
+ .vidioc_streamon = vidioc_streamon,
+ .vidioc_streamoff = vidioc_streamoff,
+
+ .vidioc_enum_input = vidioc_enum_input,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+
+ .vidioc_enum_output = vidioc_enum_output,
+ .vidioc_g_output = vidioc_g_output,
+ .vidioc_s_output = vidioc_s_output,
+
+ .vidioc_encoder_cmd = vidioc_encoder_cmd,
+ .vidioc_decoder_cmd = vidioc_decoder_cmd,
+
+ .vidioc_enum_framesizes = vidioc_enum_framesizes,
+
+ .vidioc_subscribe_event = vidioc_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+
+ .vidioc_g_parm = vidioc_g_parm,
+ .vidioc_s_parm = vidioc_s_parm,
+};
diff --git a/drivers/rpmsg/ambarella/host/ambxc/ambxc_rpmsg.c b/drivers/rpmsg/ambarella/host/ambxc/ambxc_rpmsg.c
new file mode 100644
index 00000000..2def2c91
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/ambxc/ambxc_rpmsg.c
@@ -0,0 +1,170 @@
+#include <linux/module.h>
+#include <linux/rpmsg.h>
+#include <linux/err.h>
+#include <linux/remoteproc.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+
+#include <linux/kfifo.h>
+#include <linux/delay.h>
+
+#include <plat/ambcache.h>
+
+typedef struct xnfs_info_s {
+
+ char *addr;
+ int size;
+ int count;
+ void *priv;
+} xnfs_info_t;
+
+struct xnfs_struct {
+
+ int id;
+ struct kfifo fifo;
+ spinlock_t lock;
+ wait_queue_head_t queue;
+ struct rpmsg_channel *rpdev;
+};
+
+static struct xnfs_struct g_wnfs;
+static struct xnfs_struct g_rnfs;
+
+ssize_t xnfs_read(char *buf, size_t len)
+{
+ struct xnfs_struct *xnfs = &g_wnfs;
+ xnfs_info_t info;
+ int n = 0;
+ char *va;
+ struct timespec ts, ts1, ts2;
+
+ getnstimeofday(&ts1);
+ wait_event_interruptible(xnfs->queue,
+ kfifo_out_locked(&xnfs->fifo, &info,
+ sizeof(info), &xnfs->lock));
+
+ getnstimeofday(&ts2);
+ if (!info.size) {
+ rpmsg_send(xnfs->rpdev, &n, sizeof(n));
+ return 0;
+ }
+
+ va = (void *)ambarella_phys_to_virt((unsigned long)info.addr);
+ n = info.size * info.count;
+ ts = timespec_sub(ts2, ts1);
+
+ printk(KERN_DEBUG "rpmsg: Linux got 0x%08x Bytes for %lu.%09lu Seconds\n",
+ info.count, ts.tv_sec, ts.tv_nsec);
+
+ ambcache_flush_range((void *)va, n);
+ memcpy(buf, va, n);
+
+ /* ack to release fread of iTRON side */
+ rpmsg_send(xnfs->rpdev, &n, sizeof(n));
+
+ return n;
+}
+
+ssize_t xnfs_write(char *buf, size_t len)
+{
+ struct xnfs_struct *xnfs = &g_rnfs;
+ char *va;
+ int size;
+ xnfs_info_t info;
+
+ wait_event_interruptible(xnfs->queue,
+ kfifo_out_locked(&xnfs->fifo, &info,
+ sizeof(info), &xnfs->lock));
+
+ va = (void *)ambarella_phys_to_virt((unsigned long)info.addr);
+ size = info.size * info.count;
+
+ BUG_ON(size < len);
+
+ if (len > 0) {
+
+ memcpy(va, buf, len);
+ ambcache_clean_range((void *)va, len);
+ }
+ if (len == 0)
+ printk(KERN_DEBUG "rpmsg: uItron got 0 bytes\n");
+
+ rpmsg_send(xnfs->rpdev, &len, sizeof(len));
+
+ return len;
+}
+
+static void rpmsg_xnfs_cb(struct rpmsg_channel *rpdev, void *data,
+ int len, void *priv, u32 src)
+{
+ struct xnfs_struct *xnfs = priv;
+
+ BUG_ON(len != sizeof(xnfs_info_t));
+ kfifo_in_locked(&xnfs->fifo, (char *)data, len, &xnfs->lock);
+ wake_up_interruptible(&xnfs->queue);
+}
+
+static int xnfs_init(struct xnfs_struct *xnfs)
+{
+ int ret;
+
+ spin_lock_init(&xnfs->lock);
+ init_waitqueue_head(&xnfs->queue);
+
+ ret = kfifo_alloc(&xnfs->fifo, 4096 * 16, GFP_KERNEL);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static struct rpmsg_device_id rpmsg_xnfs_id_table[] = {
+ { .name = "rnfs_arm11", },
+ { .name = "wnfs_arm11", },
+ { },
+};
+MODULE_DEVICE_TABLE(rpmsg, rpmsg_xnfs_id_table);
+
+static int rpmsg_xnfs_probe(struct rpmsg_channel *rpdev)
+{
+ int ret = 0;
+ struct rpmsg_ns_msg nsm;
+ struct xnfs_struct *xnfs = NULL;
+
+ nsm.addr = rpdev->dst;
+ memcpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
+ nsm.flags = 0;
+
+ if (!strcmp(rpdev->id.name, rpmsg_xnfs_id_table[0].name)) {
+ xnfs = &g_rnfs;
+ xnfs->id = 0;
+ printk("RPMSG Ready from NFS Server [ARM11] is ready\n");
+
+ } else if (!strcmp(rpdev->id.name, rpmsg_xnfs_id_table[1].name)) {
+ xnfs = &g_wnfs;
+ xnfs->id = 1;
+ printk("RPMSG Write to NFS Server [ARM11] is ready\n");
+ }
+
+ xnfs_init(xnfs);
+ xnfs->rpdev = rpdev;
+
+ rpdev->ept->priv = xnfs;
+
+ rpmsg_send(rpdev, &nsm, sizeof(nsm));
+
+ return ret;
+}
+
+static void rpmsg_xnfs_remove(struct rpmsg_channel *rpdev)
+{
+}
+
+struct rpmsg_driver rpmsg_xnfs_driver = {
+ .drv.name = KBUILD_MODNAME,
+ .drv.owner = THIS_MODULE,
+ .id_table = rpmsg_xnfs_id_table,
+ .probe = rpmsg_xnfs_probe,
+ .callback = rpmsg_xnfs_cb,
+ .remove = rpmsg_xnfs_remove,
+};
diff --git a/drivers/rpmsg/ambarella/host/ambxc/ambxc_vdev.c b/drivers/rpmsg/ambarella/host/ambxc/ambxc_vdev.c
new file mode 100644
index 00000000..5f07eb9d
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/ambxc/ambxc_vdev.c
@@ -0,0 +1,595 @@
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+#include <linux/rpmsg.h>
+
+#include <linux/platform_device.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
+#include <media/videobuf2-vmalloc.h>
+
+#include "ambxc.h"
+#include "ambxc_ctrls.h"
+
+#define AMBXC_MODULE_NAME "ambxc"
+
+struct ambxc_dev *g_dev;
+
+extern struct rpmsg_driver rpmsg_ambxc_ctl_driver;
+extern struct rpmsg_driver rpmsg_xnfs_driver;
+
+extern struct ambxc_fmt formats[];
+extern struct v4l2_frmsize_discrete framesize[];
+
+extern void output_buf_queued(void);
+extern ssize_t xnfs_read(char __user *buf, size_t len);
+extern ssize_t xnfs_write(char __user *buf, size_t len);
+
+static void ambxc_dev_release(struct device *dev)
+{
+}
+
+static struct platform_device ambxc_pdev = {
+ .name = AMBXC_NAME,
+ .dev.release = ambxc_dev_release,
+};
+
+struct ambxc_q_data* get_q_data(struct ambxc_ctx *ctx,
+ enum v4l2_buf_type type)
+{
+ switch (type) {
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ return &ctx->q_data[V4L2_M2M_SRC];
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ return &ctx->q_data[V4L2_M2M_DST];
+ default:
+ BUG();
+ }
+ return NULL;
+}
+
+/*
+ * mem2mem callbacks
+ */
+
+static int job_ready(void *priv)
+{
+#if 0
+ struct ambxc_ctx *ctx = priv;
+
+ if (v4l2_m2m_num_src_bufs_ready(ctx->m2m_ctx)
+ || v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx)) {
+ dprintk(ctx->dev, "Not enough buffers available\n");
+ return 0;
+ }
+#endif
+
+ return 1;
+}
+
+static void job_abort(void *priv)
+{
+ // struct ambxc_ctx *ctx = priv;
+}
+
+static void ambxc_lock(void *priv)
+{
+ struct ambxc_ctx *ctx = priv;
+ struct ambxc_dev *dev = ctx->dev;
+
+ mutex_lock(&dev->dev_mutex);
+}
+
+static void ambxc_unlock(void *priv)
+{
+ struct ambxc_ctx *ctx = priv;
+ struct ambxc_dev *dev = ctx->dev;
+
+ mutex_unlock(&dev->dev_mutex);
+}
+
+
+/* device_run() - prepares and starts the device
+ *
+ * This simulates all the immediate preparations required before starting
+ * a device. This will be called by the framework when it decides to schedule
+ * a particular instance.
+ */
+/***************************************************************************/
+
+static int thread_capture(void *data)
+{
+ struct ambxc_dev *dev = data;
+ struct ambxc_ctx *ctx = dev->ctx;
+ struct vb2_buffer *vb;
+ char *p;
+ ssize_t n;
+
+ set_freezable();
+
+ for (;;) {
+
+ if (kthread_should_stop()) {
+ try_to_freeze();
+ break;
+ }
+
+ wait_event_interruptible(dev->queue_capture,
+ v4l2_m2m_next_dst_buf(ctx->m2m_ctx));
+
+ vb = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
+
+ p = vb2_plane_vaddr(vb, 0);
+ n = xnfs_read(p, BUF_SIZE);
+
+ if (n > 0) {
+
+ vb->v4l2_buf.field = V4L2_FIELD_NONE;
+ do_gettimeofday(&vb->v4l2_buf.timestamp);
+ vb2_set_plane_payload(vb, 0, n);
+ vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+ }
+ if (n == 0) {
+ const struct v4l2_event ev = {
+ .type = V4L2_EVENT_EOS
+ };
+ dprintk(ctx->dev, "got EOS from itron, and queue it to userspace\n");
+ v4l2_event_queue_fh(& ctx->fh, & ev);
+ }
+ }
+
+ return 0;
+}
+
+static int thread_feed(void *data)
+{
+ struct ambxc_dev *dev = data;
+ struct ambxc_ctx *ctx = dev->ctx;
+ struct vb2_buffer *vb;
+ char *p;
+ ssize_t n;
+
+ set_freezable();
+
+ for (;;) {
+
+ if (kthread_should_stop()) {
+ try_to_freeze();
+ break;
+ }
+
+ wait_event_interruptible(dev->queue_feed,
+ v4l2_m2m_next_src_buf(ctx->m2m_ctx));
+
+ vb = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
+ p = vb2_plane_vaddr(vb, 0);
+ n = vb2_get_plane_payload(vb, 0);
+ xnfs_write(p, n);
+
+ v4l2_m2m_buf_done(vb, VB2_BUF_STATE_DONE);
+ }
+
+ return 0;
+}
+
+static void device_run(void *priv)
+{
+ // struct ambxc_ctx *ctx = priv;
+}
+
+/*
+ * Queue operations
+ */
+
+static int ambxc_queue_setup(struct vb2_queue *vq,
+ const struct v4l2_format *fmt,
+ unsigned int *nbuffers, unsigned int *nplanes,
+ unsigned int sizes[], void *alloc_ctxs[])
+{
+ struct ambxc_ctx *ctx = vb2_get_drv_priv(vq);
+ struct ambxc_q_data *q_data;
+ unsigned int size, count = *nbuffers;
+
+ q_data = get_q_data(ctx, vq->type);
+
+ size = BUF_SIZE;
+
+ while (size * count > MEM2MEM_VID_MEM_LIMIT)
+ (count)--;
+
+ *nplanes = 1;
+ *nbuffers = count;
+ sizes[0] = size;
+
+ dprintk(ctx->dev, "get %d buffer(s) of size %d each.\n", count, size);
+
+ return 0;
+}
+
+static int ambxc_buf_prepare(struct vb2_buffer *vb)
+{
+ struct ambxc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ struct ambxc_q_data *q_data;
+
+ q_data = get_q_data(ctx, vb->vb2_queue->type);
+
+ if (vb2_plane_size(vb, 0) < q_data->sizeimage) {
+ dprintk(ctx->dev, "%s data will not fit into plane (%lu < %lu)\n",
+ __func__, vb2_plane_size(vb, 0), (long)q_data->sizeimage);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void ambxc_buf_queue(struct vb2_buffer *vb)
+{
+ struct ambxc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
+
+ if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type))
+ wake_up_interruptible(&ctx->dev->queue_feed);
+ else
+ wake_up_interruptible(&ctx->dev->queue_capture);
+}
+
+static void ambxc_wait_prepare(struct vb2_queue *q)
+{
+ struct ambxc_ctx *ctx = vb2_get_drv_priv(q);
+ ambxc_unlock(ctx);
+}
+
+static void ambxc_wait_finish(struct vb2_queue *q)
+{
+ struct ambxc_ctx *ctx = vb2_get_drv_priv(q);
+ ambxc_lock(ctx);
+}
+
+extern void do_xc_start(struct ambxc_ctx *ctx);
+static int start_streaming(struct vb2_queue *q, unsigned int count)
+{
+ struct ambxc_ctx *ctx = vb2_get_drv_priv(q);
+
+ dprintk(ctx->dev, "start streaming type:%d\n", q->type);
+
+ if ((q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+ ctx->m2m_ctx->out_q_ctx.q.streaming) ||
+ (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+ ctx->m2m_ctx->cap_q_ctx.q.streaming)) {
+ do_xc_start(ctx);
+ }
+
+ return 0;
+}
+
+static int stop_streaming(struct vb2_queue *q)
+{
+ struct ambxc_ctx *ctx = vb2_get_drv_priv(q);
+
+ dprintk(ctx->dev, "stop streaming type:%d\n", q->type);
+
+ return 0;
+}
+
+static struct vb2_ops ambxc_qops = {
+ .queue_setup = ambxc_queue_setup,
+ .buf_prepare = ambxc_buf_prepare,
+ .buf_queue = ambxc_buf_queue,
+ .wait_prepare = ambxc_wait_prepare,
+ .wait_finish = ambxc_wait_finish,
+ .start_streaming = start_streaming,
+ .stop_streaming = stop_streaming,
+};
+
+static int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
+{
+ struct ambxc_ctx *ctx = priv;
+ int ret;
+
+ src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
+ src_vq->drv_priv = ctx;
+ src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+ src_vq->ops = &ambxc_qops;
+ src_vq->mem_ops = &vb2_vmalloc_memops;
+ src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+
+ ret = vb2_queue_init(src_vq);
+ if (ret)
+ return ret;
+
+ dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
+ dst_vq->drv_priv = ctx;
+ dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+ dst_vq->ops = &ambxc_qops;
+ dst_vq->mem_ops = &vb2_vmalloc_memops;
+ dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+
+ return vb2_queue_init(dst_vq);
+}
+
+/*
+ * File operations
+ */
+static int ambxc_open(struct file *file)
+{
+ struct ambxc_dev *dev = video_drvdata(file);
+ struct ambxc_ctx *ctx = NULL;
+ int rc = 0;
+
+ if (mutex_lock_interruptible(&dev->dev_mutex))
+ return -ERESTARTSYS;
+#if 0
+ if ((atomic_read(&dev->ref_cnt) == 2)) {
+ rc = -EBUSY;
+ goto open_unlock;
+ }
+#endif
+
+ if ((atomic_read(&dev->ref_cnt) > 0)) {
+ rc = 0;
+ atomic_inc(&dev->ref_cnt);
+ ctx = dev->ctx;
+ file->private_data = &ctx->fh;
+ goto open_unlock;
+ }
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx) {
+ rc = -ENOMEM;
+ goto open_unlock;
+ }
+
+ v4l2_fh_init(&ctx->fh, video_devdata(file));
+ file->private_data = &ctx->fh;
+ ctx->dev = dev;
+
+ if (ambxc_init_ctrls(ctx))
+ goto open_unlock;
+
+ ctx->fh.ctrl_handler = &ctx->hdl;
+
+ ctx->q_data[V4L2_M2M_SRC].fmt = &formats[0];
+ ctx->q_data[V4L2_M2M_SRC].sizeimage = BUF_SIZE;
+ ctx->q_data[V4L2_M2M_SRC].width = framesize[0].width;
+ ctx->q_data[V4L2_M2M_SRC].height = framesize[0].height;
+ ctx->q_data[V4L2_M2M_DST] = ctx->q_data[V4L2_M2M_SRC];
+
+ ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init);
+
+ if (IS_ERR(ctx->m2m_ctx)) {
+ rc = PTR_ERR(ctx->m2m_ctx);
+ ambxc_release_ctrls(ctx);
+ kfree(ctx);
+ goto open_unlock;
+ }
+
+ v4l2_fh_add(&ctx->fh);
+
+ atomic_inc(&dev->ref_cnt);
+ dev->ctx = ctx;
+ init_waitqueue_head(&dev->queue_capture);
+ init_waitqueue_head(&dev->queue_feed);
+ dev->kthread_capture = kthread_run(thread_capture, dev,
+ dev->v4l2_dev.name);
+ dev->kthread_feed = kthread_run(thread_feed, dev, dev->v4l2_dev.name);
+
+ dprintk(dev, "Created instance %p, m2m_ctx: %p\n", ctx, ctx->m2m_ctx);
+
+open_unlock:
+ mutex_unlock(&dev->dev_mutex);
+ return rc;
+}
+
+static int ambxc_release(struct file *file)
+{
+ struct ambxc_dev *dev = video_drvdata(file);
+ struct ambxc_ctx *ctx = file2ctx(file);
+
+ if ((atomic_read(&dev->ref_cnt) == 1)) {
+#if 0
+ dprintk(dev, "Releasing instance %p\n", ctx);
+
+ kthread_stop(dev->kthread);
+ if (IS_ERR(dev->kthread)) {
+ v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
+ return PTR_ERR(dev->kthread);
+ }
+
+ v4l2_fh_del(&ctx->fh);
+ v4l2_fh_exit(&ctx->fh);
+ v4l2_ctrl_handler_free(&ctx->hdl);
+ mutex_lock(&dev->dev_mutex);
+ v4l2_m2m_ctx_release(ctx->m2m_ctx);
+ mutex_unlock(&dev->dev_mutex);
+ kfree(ctx);
+#endif
+ }
+
+ // atomic_dec(&dev->ref_cnt);
+
+ return 0;
+}
+
+static unsigned int ambxc_poll(struct file *file,
+ struct poll_table_struct *wait)
+{
+ struct ambxc_ctx *ctx = file2ctx(file);
+
+ return v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
+}
+
+static int ambxc_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct ambxc_dev *dev = video_drvdata(file);
+ struct ambxc_ctx *ctx = file2ctx(file);
+ int res;
+
+ if (mutex_lock_interruptible(&dev->dev_mutex))
+ return -ERESTARTSYS;
+
+ res = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
+
+ mutex_unlock(&dev->dev_mutex);
+
+ return res;
+}
+
+static const struct v4l2_file_operations ambxc_fops = {
+ .owner = THIS_MODULE,
+ .open = ambxc_open,
+ .release = ambxc_release,
+ .poll = ambxc_poll,
+ .unlocked_ioctl = video_ioctl2,
+ .mmap = ambxc_mmap,
+};
+
+static struct v4l2_m2m_ops m2m_ops = {
+ .device_run = device_run,
+ .job_ready = job_ready,
+ .job_abort = job_abort,
+ .lock = ambxc_lock,
+ .unlock = ambxc_unlock,
+};
+
+static struct video_device ambxc_videodev = {
+ .name = AMBXC_NAME,
+ .vfl_dir = VFL_DIR_M2M,
+ .fops = &ambxc_fops,
+ .ioctl_ops = &ambxc_ioctl_ops,
+ .minor = -1,
+ .release = video_device_release,
+};
+
+static int ambxc_probe(struct platform_device *pdev)
+{
+ struct ambxc_dev *dev;
+ struct video_device *vfd;
+ int ret;
+
+ dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return -ENOMEM;
+
+ spin_lock_init(&dev->irqlock);
+
+ ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
+ if (ret)
+ return ret;
+
+ atomic_set(&dev->inst, 0);
+ atomic_set(&dev->ref_cnt, 0);
+ mutex_init(&dev->dev_mutex);
+
+ vfd = video_device_alloc();
+ if (!vfd) {
+ v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n");
+ ret = -ENOMEM;
+ goto unreg_dev;
+ }
+
+ *vfd = ambxc_videodev;
+ vfd->lock = &dev->dev_mutex;
+
+ ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
+ if (ret) {
+ v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
+ goto rel_vdev;
+ }
+
+ video_set_drvdata(vfd, dev);
+ snprintf(vfd->name, sizeof(vfd->name), "%s", ambxc_videodev.name);
+ dev->vfd = vfd;
+ // v4l2_device_set_name(&dev->v4l2_dev, vfd->name, &dev->inst);
+
+ v4l2_info(&dev->v4l2_dev, AMBXC_MODULE_NAME
+ "Device registered as /dev/%d\n", vfd->num);
+
+ platform_set_drvdata(pdev, dev);
+
+ dev->m2m_dev = v4l2_m2m_init(&m2m_ops);
+ if (IS_ERR(dev->m2m_dev)) {
+ v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n");
+ ret = PTR_ERR(dev->m2m_dev);
+ goto err_m2m;
+ }
+
+ g_dev = dev; // FIXME;
+ return 0;
+
+err_m2m:
+ v4l2_m2m_release(dev->m2m_dev);
+ video_unregister_device(dev->vfd);
+rel_vdev:
+ video_device_release(vfd);
+unreg_dev:
+ v4l2_device_unregister(&dev->v4l2_dev);
+
+ return ret;
+}
+
+static int ambxc_remove(struct platform_device *pdev)
+{
+ struct ambxc_dev *dev = platform_get_drvdata(pdev);
+
+ v4l2_info(&dev->v4l2_dev, "Removing " AMBXC_MODULE_NAME);
+ v4l2_m2m_release(dev->m2m_dev);
+ video_unregister_device(dev->vfd);
+ v4l2_device_unregister(&dev->v4l2_dev);
+
+ return 0;
+}
+
+static struct platform_driver ambxc_pdrv = {
+ .probe = ambxc_probe,
+ .remove = ambxc_remove,
+ .driver = {
+ .name = AMBXC_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init ambxc_init(void)
+{
+ int ret;
+
+ ret = register_rpmsg_driver(&rpmsg_ambxc_ctl_driver);
+ if (ret)
+ return ret;
+ ret = register_rpmsg_driver(&rpmsg_xnfs_driver);
+ if (ret)
+ return ret;
+
+ ret = platform_device_register(&ambxc_pdev);
+ if (ret)
+ return ret;
+
+ ret = platform_driver_register(&ambxc_pdrv);
+ if (ret)
+ platform_device_unregister(&ambxc_pdev);
+
+ return 0;
+}
+
+static void __exit ambxc_exit(void)
+{
+ platform_driver_unregister(&ambxc_pdrv);
+ platform_device_unregister(&ambxc_pdev);
+ unregister_rpmsg_driver(&rpmsg_xnfs_driver);
+ unregister_rpmsg_driver(&rpmsg_ambxc_ctl_driver);
+}
+
+module_init(ambxc_init);
+module_exit(ambxc_exit);
+
+MODULE_DESCRIPTION("Ambarella A8 Video Codec Driver");
+MODULE_AUTHOR("Tzu-Jung Lee, <tjlee@ambarella.com>");
+MODULE_VERSION("0.0.1");
diff --git a/drivers/rpmsg/ambarella/host/aservice/Kconfig b/drivers/rpmsg/ambarella/host/aservice/Kconfig
new file mode 100644
index 00000000..4f2e986c
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/aservice/Kconfig
@@ -0,0 +1,5 @@
+config RPMSG_AUDIOSERVICE
+ tristate "audio service"
+ depends on RPMSG
+ help
+ A audio service client for interacting with Itron on ARM11
diff --git a/drivers/rpmsg/ambarella/host/aservice/Makefile b/drivers/rpmsg/ambarella/host/aservice/Makefile
new file mode 100644
index 00000000..5b8d2df9
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/aservice/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_RPMSG_AUDIOSERVICE) += rpmsg_aservice.o
diff --git a/drivers/rpmsg/ambarella/host/aservice/rpmsg_aservice.c b/drivers/rpmsg/ambarella/host/aservice/rpmsg_aservice.c
new file mode 100644
index 00000000..59e64d47
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/aservice/rpmsg_aservice.c
@@ -0,0 +1,348 @@
+/*
+ * rpmsg audio service driver
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/rpmsg.h>
+#include <linux/err.h>
+#include <linux/remoteproc.h>
+
+#include <linux/poll.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/kfifo.h>
+
+#include <linux/virtio_ring.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/wait.h>
+
+#define DEVICE_NAME "aservice"
+
+enum aio_cmd {
+ AIO_CMD_SETUP = 0,
+ AIO_CMD_START = 1,
+ AIO_CMD_STOP = 2,
+ AIO_CMD_CLOSE = 3,
+ AIO_CMD_NONE = 0xFF
+};
+
+enum aio_type {
+ ENCODER = 0,
+ DECODER,
+ XCODER,
+ BYPASS
+};
+
+enum aio_dir {
+ ARM_TO_LINUX = 0,
+ LINUX_TO_ARM,
+ BIDRECTION,
+};
+
+enum aio_encoder {
+ AAC_ENC = 0,
+ AC3_ENC,
+ MP2_ENC
+};
+
+enum aio_decoder {
+ AAC_DEC = 0,
+ AC3_DEC,
+ MP2_DEC
+};
+
+//test aservice structure
+
+typedef struct aio_buf_s {
+ u32 command;
+ u8 *arm_buf_base; /**< ARM side buffer write pointer >*/
+ u32 arm_buf_limit; /**< ARM side buffer write pointer >*/
+ u32 arm_buf_wptr; /**< ARM side buffer write pointer >*/
+ u32 arm_buf_rptr; /**< ARM side buffer read pointer >*/
+ u32 arm_buf_vaddr; /** <Linux side buffer virtual address (mmap), for iTron side debug or information > */
+
+ u8 *linux_buf_base; /**< ARM side buffer write pointer >*/
+ u32 linux_buf_limit; /**< ARM side buffer write pointer >*/
+ u32 linux_buf_wptr; /**< Linux side buffer write pointer >*/
+ u32 linux_buf_rptr; /**< Linux side buffer read pointer >*/
+ u32 linux_buf_vaddr; /** <Linux side buffer virtual address (mmap), for iTron side debug or information > */
+ u32 decoder;
+ u32 encoder;
+ u32 aio_type;
+ u32 aio_direction;
+ u32 self;
+} aio_buf_t;
+
+struct aservice_ret_msg {
+ s32 rval;
+};
+
+struct aservice_struct {
+ spinlock_t lock;
+ struct rpmsg_channel *rpdev;
+ struct miscdevice fdev;
+ aio_buf_t *aio_buf;
+ u32 finish_flag;
+};
+
+//init waiting queue
+static DECLARE_WAIT_QUEUE_HEAD(msgq);
+static struct aservice_struct g_aservice;
+
+static int device_open(struct inode *inode, struct file *filp)
+{
+ filp->private_data = &g_aservice;
+
+ return 0;
+}
+
+static ssize_t device_write(struct file *filp, const char *buf,
+ size_t count, loff_t * off)
+{
+ struct aservice_struct *aservice = filp->private_data;
+
+ printk("Enter devide write\n");
+ //might deal with different write msgs
+ aservice->finish_flag = 1;
+ wake_up_interruptible(&msgq);
+ return count;
+}
+
+static ssize_t device_read(struct file *filp, char *buf,
+ size_t len, loff_t * offset)
+{
+ struct aservice_struct *aservice = filp->private_data;
+ aio_buf_t *aio_buf = aservice->aio_buf;
+ int rval;
+
+ printk("Enter device read\n");
+
+ if (aio_buf != NULL) {
+ switch(aio_buf->command) {
+ case AIO_CMD_SETUP:
+ case AIO_CMD_START:
+ case AIO_CMD_STOP:
+ case AIO_CMD_CLOSE: {
+ printk("Command! %d\n", aio_buf->command);
+ rval = copy_to_user(buf, aio_buf, sizeof(aio_buf_t));
+ if(rval)
+ {
+ printk("copy to user failed %d %d\n", rval, sizeof(aio_buf_t));
+ return -1;
+ }
+ aio_buf->command = AIO_CMD_NONE;
+ break;
+ }
+ case AIO_CMD_NONE: //no command
+ return -1;
+ break;
+ }
+ return 0;
+ }
+ else
+ return -1;
+}
+
+static int device_release(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static int device_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ struct aservice_struct *aservice = filp->private_data;
+ aio_buf_t *aio_buf = aservice->aio_buf;
+ int rval = 0;
+ unsigned long size;
+
+ size = vma->vm_end - vma->vm_start; //size from userspace
+
+ printk("Doing mmap, size = %lu\n", size);
+
+ vma->vm_pgoff = (aio_buf->self) >> PAGE_SHIFT;
+
+ rval = remap_pfn_range(vma,
+ vma->vm_start,
+ vma->vm_pgoff,
+ size,
+ vma->vm_page_prot);
+
+ if (rval < 0)
+ printk("We got some error\n");
+
+ //mmap this size of memory based on memory address from uItron side
+ //maybe more memory management if there is only one kernel device
+ return rval;
+}
+
+static struct file_operations fops = {
+ .read = device_read,
+ .write = device_write,
+ .open = device_open,
+ .mmap = device_mmap,
+ .release = device_release
+};
+
+static int aservice_init(struct aservice_struct *aservice)
+{
+ spin_lock_init(&aservice->lock);
+
+ printk("RPMSG aservice [ARM11] now is ready at /dev/%s\n", DEVICE_NAME);
+
+ aservice->fdev.name = DEVICE_NAME;
+ aservice->fdev.fops = &fops;
+ aservice->aio_buf = NULL;
+ aservice->finish_flag = 0;
+ misc_register(&aservice->fdev);
+
+ return 0;
+}
+
+static void rpmsg_aservice_cb(struct rpmsg_channel *rpdev, void *data,
+ int len, void *priv, u32 src)
+{
+ struct aservice_struct *aservice = priv;
+ struct aservice_ret_msg msg;
+ aio_buf_t *aio_buf_test;
+
+ aio_buf_t *aio_buf = data;
+ aservice->aio_buf = data;
+
+ printk("recieve msg : rpmsg_aservice_cb +\n");
+
+ printk("length %d\n", len);
+ printk("My address is %08X\n", (u32)aio_buf);
+ printk("command %d\n",aio_buf->command);
+ printk("buf base %08X\n",(u32)aio_buf->arm_buf_base); /**< ARM side buffer write pointer >*/
+ printk("buf limit %08X\n",aio_buf->arm_buf_limit); /**< ARM side buffer write pointer >*/
+ printk("wptr %08X\n",aio_buf->arm_buf_wptr); /**< ARM side buffer write pointer >*/
+ printk("rptr %08X\n",aio_buf->arm_buf_rptr); /**< ARM side buffer read pointer >*/
+ printk("buf vaddr %08X\n",aio_buf->arm_buf_vaddr); /** <Linux side buffer virtual address (mmap), for iTron side debug or information > */
+
+ printk("buf base %08X\n",(u32)aio_buf->linux_buf_base); /**< ARM side buffer write pointer >*/
+ printk("buf limit %08X\n",aio_buf->linux_buf_limit); /**< ARM side buffer write pointer >*/
+ printk("buf wptr %08X\n",aio_buf->linux_buf_wptr); /**< Linux side buffer write pointer >*/
+ printk("rptr %08X\n",aio_buf->linux_buf_rptr); /**< Linux side buffer read pointer >*/
+ printk("buf vaddr %08X\n",aio_buf->linux_buf_vaddr); /** <Linux side buffer virtual address (mmap), for iTron side debug or information > */
+
+ printk("encode %d\n",aio_buf->encoder);
+ printk("decode %d\n",aio_buf->decoder);
+ printk("type %d\n",aio_buf->aio_type);
+ printk("dir %d\n",aio_buf->aio_direction);
+ printk("self %08X\n", aio_buf->self);
+
+ aio_buf_test = (aio_buf_t *)phys_to_virt(aio_buf->self);
+ printk("aio buf test to %08X\n", (u32)aio_buf_test);
+ printk("command %d\n",aio_buf_test->command);
+ printk("buf base %08X\n",(u32)aio_buf_test->arm_buf_base); /**< ARM side buffer write pointer >*/
+ printk("buf limit %08X\n",aio_buf_test->arm_buf_limit); /**< ARM side buffer write pointer >*/
+ printk("wptr %08X\n",aio_buf_test->arm_buf_wptr); /**< ARM side buffer write pointer >*/
+ printk("rptr %08X\n",aio_buf_test->arm_buf_rptr); /**< ARM side buffer read pointer >*/
+ printk("buf vaddr %08X\n",aio_buf_test->arm_buf_vaddr); /** <Linux side buffer virtual address (mmap), for iTron side debug or information > */
+
+ printk("Let's write something\n");
+ aio_buf_test->command = 2;
+ aio_buf_test->arm_buf_base = 0xDEADBEEF;
+ aio_buf_test->arm_buf_limit = 0x2000;
+ aio_buf_test->arm_buf_wptr = 0x12345678;
+ aio_buf_test->arm_buf_rptr = 0x87654321;
+ aio_buf_test->arm_buf_vaddr = 0x11111111;
+
+ printk("command %d\n",aio_buf_test->command);
+ printk("buf base %08X\n",(u32)aio_buf_test->arm_buf_base); /**< ARM side buffer write pointer >*/
+ printk("buf limit %08X\n",aio_buf_test->arm_buf_limit); /**< ARM side buffer write pointer >*/
+ printk("wptr %08X\n",aio_buf_test->arm_buf_wptr); /**< ARM side buffer write pointer >*/
+ printk("rptr %08X\n",aio_buf_test->arm_buf_rptr); /**< ARM side buffer read pointer >*/
+ printk("buf vaddr %08X\n",aio_buf_test->arm_buf_vaddr); /** <Linux side buffer virtual address (mmap), for iTron side debug or information > */
+
+ switch(aio_buf->command)
+ {
+ case AIO_CMD_SETUP:
+ printk("setup command\n");
+ break;
+ case AIO_CMD_START:
+ printk("start command\n");
+ break;
+ case AIO_CMD_STOP:
+ printk("start command\n");
+ break;
+ case AIO_CMD_CLOSE:
+ printk("close command\n");
+ default:
+ printk("Bad command\n");
+ break;
+ }
+
+ msg.rval = -1;
+ printk("msg val %d\n", msg.rval);
+ wait_event_interruptible(msgq, aservice->finish_flag != 0);
+ if (aservice->finish_flag)
+ aservice->finish_flag = 0;
+ printk("waiting queue done, send back to uItron\n");
+ //return a msg done, will using wait queue for application handshaking
+ rpmsg_sendto(rpdev, &msg, sizeof(msg), rpdev->dst);
+
+}
+
+static int rpmsg_aservice_probe(struct rpmsg_channel *rpdev)
+{
+ int ret = 0;
+ struct rpmsg_ns_msg nsm;
+ struct aservice_struct *aservice = &g_aservice;
+
+ nsm.addr = rpdev->dst;
+ memcpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
+ nsm.flags = 0;
+
+ aservice_init(aservice);
+ aservice->rpdev = rpdev;
+
+ rpdev->ept->priv = aservice;
+
+ rpmsg_sendto(rpdev, &nsm, sizeof(nsm), rpdev->dst);
+
+ return ret;
+}
+
+static void rpmsg_aservice_remove(struct rpmsg_channel *rpdev)
+{
+ struct aservice_struct *aservice = &g_aservice;
+ misc_deregister(&aservice->fdev);
+}
+
+static struct rpmsg_device_id rpmsg_aservice_id_table[] = {
+ { .name = "aservice_arm11", },
+ { },
+};
+MODULE_DEVICE_TABLE(rpmsg, rpmsg_aservice_id_table);
+
+static struct rpmsg_driver rpmsg_aservice_driver = {
+ .drv.name = KBUILD_MODNAME,
+ .drv.owner = THIS_MODULE,
+ .id_table = rpmsg_aservice_id_table,
+ .probe = rpmsg_aservice_probe,
+ .callback = rpmsg_aservice_cb,
+ .remove = rpmsg_aservice_remove,
+};
+
+static int __init rpmsg_aservice_init(void)
+{
+ return register_rpmsg_driver(&rpmsg_aservice_driver);
+}
+
+static void __exit rpmsg_aservice_fini(void)
+{
+ unregister_rpmsg_driver(&rpmsg_aservice_driver);
+}
+
+module_init(rpmsg_aservice_init);
+module_exit(rpmsg_aservice_fini);
+
+MODULE_DESCRIPTION("RPMSG audio service");
diff --git a/drivers/rpmsg/ambarella/host/echo/Kconfig b/drivers/rpmsg/ambarella/host/echo/Kconfig
new file mode 100644
index 00000000..ac0b9f2d
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/echo/Kconfig
@@ -0,0 +1,5 @@
+config RPMSG_ECHO
+ tristate "Echo"
+ depends on RPMSG
+ help
+ A sample of rpmsg program which implement an echo server
diff --git a/drivers/rpmsg/ambarella/host/echo/Makefile b/drivers/rpmsg/ambarella/host/echo/Makefile
new file mode 100644
index 00000000..dc166881
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/echo/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_RPMSG_ECHO) += rpmsg_echo.o
diff --git a/drivers/rpmsg/ambarella/host/echo/rpmsg_echo.c b/drivers/rpmsg/ambarella/host/echo/rpmsg_echo.c
new file mode 100644
index 00000000..3e4ad33b
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/echo/rpmsg_echo.c
@@ -0,0 +1,71 @@
+/*
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/rpmsg.h>
+#include <linux/err.h>
+#include <linux/remoteproc.h>
+
+static void rpmsg_echo_cb(struct rpmsg_channel *rpdev, void *data, int len,
+ void *priv, u32 src)
+{
+ printk("[ %20s ] recv msg: [%s] from 0x%x and len %d\n",
+ __func__, (const char*)data, src, len);
+
+ /* Echo the recved message back */
+ rpmsg_send(rpdev, data, len);
+}
+
+static int rpmsg_echo_probe(struct rpmsg_channel *rpdev)
+{
+ int ret = 0;
+ struct rpmsg_ns_msg nsm;
+
+ nsm.addr = rpdev->dst;
+ memcpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
+ nsm.flags = 0;
+
+ rpmsg_send(rpdev, &nsm, sizeof(nsm));
+
+ return ret;
+}
+
+static void rpmsg_echo_remove(struct rpmsg_channel *rpdev)
+{
+}
+
+static struct rpmsg_device_id rpmsg_echo_id_table[] = {
+ { .name = "echo_ca9_b", },
+ { .name = "echo_arm11", },
+ { .name = "echo_cortex", },
+ { },
+};
+MODULE_DEVICE_TABLE(rpmsg, rpmsg_echo_id_table);
+
+static struct rpmsg_driver rpmsg_echo_driver = {
+ .drv.name = KBUILD_MODNAME,
+ .drv.owner = THIS_MODULE,
+ .id_table = rpmsg_echo_id_table,
+ .probe = rpmsg_echo_probe,
+ .callback = rpmsg_echo_cb,
+ .remove = rpmsg_echo_remove,
+};
+
+static int __init rpmsg_echo_init(void)
+{
+ return register_rpmsg_driver(&rpmsg_echo_driver);
+}
+
+static void __exit rpmsg_echo_fini(void)
+{
+ unregister_rpmsg_driver(&rpmsg_echo_driver);
+}
+
+module_init(rpmsg_echo_init);
+module_exit(rpmsg_echo_fini);
+
+MODULE_DESCRIPTION("RPMSG Echo Server");
diff --git a/drivers/rpmsg/ambarella/host/rnfs/Kconfig b/drivers/rpmsg/ambarella/host/rnfs/Kconfig
new file mode 100644
index 00000000..ca407b90
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/rnfs/Kconfig
@@ -0,0 +1,6 @@
+config RPMSG_RNFS
+ tristate "Read from NFS Server"
+ depends on RPMSG
+ depends on !RPMSG_AMBXC
+ help
+ A sample of read file from NFS Server
diff --git a/drivers/rpmsg/ambarella/host/rnfs/Makefile b/drivers/rpmsg/ambarella/host/rnfs/Makefile
new file mode 100644
index 00000000..b48d2444
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/rnfs/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_RPMSG_RNFS) += rpmsg_rnfs.o
diff --git a/drivers/rpmsg/ambarella/host/rnfs/rpmsg_rnfs.c b/drivers/rpmsg/ambarella/host/rnfs/rpmsg_rnfs.c
new file mode 100644
index 00000000..b06074d2
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/rnfs/rpmsg_rnfs.c
@@ -0,0 +1,338 @@
+/*
+ * rpmsg read from nfs server driver
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/rpmsg.h>
+#include <linux/err.h>
+#include <linux/remoteproc.h>
+
+#include <linux/poll.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/kfifo.h>
+
+#include <linux/virtio_ring.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+
+#define DEVICE_NAME "rnfs"
+
+
+typedef int redev_nfs_FILE;
+typedef struct nfs_fread_info_s {
+ int *addr;
+ int size;
+ int count;
+ redev_nfs_FILE *file;
+}
+nfs_fread_info_t;
+
+struct rnfs_struct {
+ struct kfifo fifo;
+ spinlock_t lock;
+ struct rpmsg_channel *rpdev;
+ struct miscdevice fdev;
+ nfs_fread_info_t unfinished;
+};
+
+static struct rnfs_struct g_rnfs;
+
+static int device_open(struct inode *inode, struct file *filp)
+{
+ filp->private_data = &g_rnfs;
+
+ return 0;
+}
+
+static ssize_t device_write(struct file *filp, const char *buf,
+ size_t count, loff_t *off)
+{
+ struct rnfs_struct *rnfs = filp->private_data;
+ //struct rpmsg_channel *rpdev = rnfs->rpdev;
+ unsigned int ret;
+ unsigned int avail;
+ unsigned int unfinished = count;
+ unsigned int cpsize;
+ unsigned int cpsize_total;
+ char *rp = buf;
+
+ //printk("device_write: rp 0x%x unfinished %x\n", rp, unfinished);
+
+ cpsize_total = 0;
+ while(unfinished > 0) {
+ avail = kfifo_avail(&rnfs->fifo);
+ if(avail == 0) {
+ //printk("rpmsg_rnfs_cb: msleep(1000);");
+ msleep(5);
+ cpsize = 0;
+ } else if(avail > unfinished){
+ cpsize = unfinished;
+ } else if(avail <= unfinished) {
+ cpsize = avail;
+ }
+
+ if(cpsize > 0) {
+ ret = kfifo_in_locked(&rnfs->fifo, (char *)rp, cpsize, &rnfs->lock);
+ rp += cpsize;
+ unfinished -= cpsize;
+ cpsize_total += cpsize;
+ }
+ //printk("device_write: avail %x rp 0x%x unfinished %x\n", avail, rp, unfinished);
+ }
+
+ if(cpsize_total != count)
+ printk("rnfs device_write: cpsize_total != count\n");
+
+ return cpsize_total;
+}
+
+int rnfs_test_counter = 0;
+static ssize_t device_read(struct file *filp, char *buf,
+ size_t len, loff_t *offset)
+{
+ struct rnfs_struct *rnfs = filp->private_data;
+ int bytes_read = 0;
+ // char c;
+ char *vaddr;
+ nfs_fread_info_t nfs_fread_info;
+ int copy_size;
+ int unfinished_size;
+ int ret;
+ int len_remain = len;
+
+ //printk(" ====================== device_read %d ======================\n", rnfs_test_counter);
+
+//rnfs_test_counter ++;
+ if(rnfs_test_counter > 2000) {
+ printk("device_read: force 0\n");
+ rnfs_test_counter = 0;
+ return 0;
+ }
+
+// while (kfifo_out_locked(&rnfs->fifo, &c, sizeof(c), &rnfs->lock)) {
+//
+// *buf++ = c;
+// bytes_read++;
+// }
+
+// blocking = filp->??
+
+ while(len_remain > 0) {
+ switch (rnfs->unfinished.count) {
+ case 0:
+ //reload
+// while(1) {
+ ret = kfifo_out_locked(&rnfs->fifo, &nfs_fread_info, sizeof(nfs_fread_info_t), &rnfs->lock);
+ //printk("reload: info %d/%d\n", ret, sizeof(nfs_fread_info_t));
+// //if ret==not ready, sleep
+// if(ret < sizeof(nfs_fread_info_t))
+// if(blocking)
+// sleep();
+// else return -EAGAIN;
+// else
+// break;
+// }
+ if(ret < sizeof(nfs_fread_info_t)) {
+ msleep(5);
+ //printk("reload: not ready %d\n", ret);
+ break;
+ } else {
+ if(nfs_fread_info.size == 0xdeadbeef) {
+ printk("nfs_fread_info.size == 0xdeadbeef");
+ rnfs_test_counter = 2000000;
+ rpmsg_sendto(rnfs->rpdev, &bytes_read, sizeof(int), rnfs->rpdev->dst); //ack to release fread of iTRON side
+ return 0;
+ }
+ memcpy(&(rnfs->unfinished), &nfs_fread_info, sizeof(nfs_fread_info_t));
+ //printk("reload: x%x %d %d\n", rnfs->unfinished.addr, rnfs->unfinished.size, rnfs->unfinished.count);
+ }
+
+ default:
+ //fill-up buf
+ unfinished_size = rnfs->unfinished.size * rnfs->unfinished.count;
+ copy_size = (len_remain > unfinished_size) ? unfinished_size : len_remain;
+ if(copy_size>0) {
+ vaddr = (void *)ambarella_phys_to_virt((unsigned long)rnfs->unfinished.addr);
+ memcpy(buf, vaddr, copy_size);
+ bytes_read += copy_size;
+ buf += copy_size;
+ unfinished_size -= copy_size;
+
+ if(unfinished_size > 0) {
+ rnfs->unfinished.count = unfinished_size / rnfs->unfinished.size;
+ rnfs->unfinished.addr = (int *)((unsigned int)rnfs->unfinished.addr + copy_size);
+ } else {
+ memset(&(rnfs->unfinished), 0, sizeof(nfs_fread_info_t));
+ rpmsg_sendto(rnfs->rpdev, &bytes_read, sizeof(int), rnfs->rpdev->dst); //ack to release fread of iTRON side
+ //printk("ack\n");
+ }
+ len_remain -= copy_size;
+ }
+ //printk("fillup: %d/%d \n", bytes_read, len);
+ }
+ }
+
+// while (kfifo_out_locked(&rnfs->fifo, &nfs_fread_info, sizeof(nfs_fread_info_t), &rnfs->lock)) {
+// // vaddr = ambarella_phys_to_virt(nfs_fread_info.addr);
+// // bytes_read += nfs_fread_info.size*nfs_fread_info.count;
+// // memcpy(buf, vaddr, nfs_fread_info.size*nfs_fread_info.count);
+// // buf += bytes_read;
+// //printk("device_read: x%x x%x\n", vaddr, bytes_read);
+// bytes_read = len;
+// }
+
+ //rpmsg_sendto(g_rnfs.rpdev, &bytes_read, sizeof(int), g_rnfs.rpdev->dst);
+ //printk("device_read: final bytes_read %d/%d \n", bytes_read, len);
+
+ return bytes_read;
+}
+
+static int device_release(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static struct file_operations fops = {
+ .read = device_read,
+ .write = device_write,
+ .open = device_open,
+ .release = device_release
+};
+
+static int rnfs_init(struct rnfs_struct *rnfs)
+{
+ int ret;
+
+ spin_lock_init(&rnfs->lock);
+
+ ret = kfifo_alloc(&rnfs->fifo, 1024*1024*2, GFP_KERNEL);
+ if (ret)
+ return ret;
+
+ printk("RPMSG Read from NFS Server [ARM11] now is ready at /dev/%s\n", DEVICE_NAME);
+
+ rnfs->fdev.name = DEVICE_NAME;
+ rnfs->fdev.fops = &fops;
+ rnfs->fdev.minor = MISC_DYNAMIC_MINOR;
+ memset(&(rnfs->unfinished), 0, sizeof(nfs_fread_info_t));
+ misc_register(&rnfs->fdev);
+
+ return 0;
+}
+
+static void rpmsg_rnfs_cb(struct rpmsg_channel *rpdev, void *data,
+ int len, void *priv, u32 src)
+{
+ struct rnfs_struct *rnfs = priv;
+ unsigned int ret;
+ unsigned int avail;
+ unsigned int unfinished = len;
+ unsigned int cpsize;
+ unsigned int cpsize_total;
+ char *wp;
+ nfs_fread_info_t *info = data;
+#define EOF_TIMEOUT (20)
+ unsigned int timeout = EOF_TIMEOUT;
+
+ cpsize_total = 0;
+ unfinished = info->size*info->count;
+ printk("rpmsg_rnfs_cb: p 0x%x v 0x%x %x %x\n", info->addr, wp, info->size, info->count);
+ wp = (void *)ambarella_phys_to_virt((unsigned long)info->addr);
+ printk("rpmsg_rnfs_cb: p 0x%x v 0x%x %x %x\n", info->addr, wp, info->size, info->count);
+
+ while(unfinished > 0) {
+ avail = kfifo_len(&rnfs->fifo);
+ if(avail == 0) {
+ //printk("rpmsg_rnfs_cb: msleep(1000);");
+ msleep(5);
+ cpsize = 0;
+ timeout--;
+ if(timeout == 0) {
+ printk("rpmsg_rnfs_cb: could be eof\n");
+ break;
+ }
+ } else if(avail > unfinished){
+ cpsize = unfinished;
+ } else if(avail <= unfinished) {
+ cpsize = avail;
+ }
+
+ if(cpsize > 0) {
+ ret = kfifo_out_locked(&rnfs->fifo, wp, cpsize, &rnfs->lock);
+ wp += cpsize;
+ unfinished -= cpsize;
+ cpsize_total += cpsize;
+ }
+ printk("rpmsg_rnfs_cb: avail %x wp %x, unfinished %x\n", avail, wp, unfinished);
+ }
+
+ if(cpsize_total != info->size*info->count)
+ printk("rnfs rpmsg_rnfs_cb: cpsize_total != count\n");
+
+ //ack to release fread of iTRON side
+ rpmsg_sendto(rnfs->rpdev, &cpsize_total, sizeof(unsigned int), rnfs->rpdev->dst);
+ printk("rnfs rpmsg_rnfs_cb: ack iTRON\n");
+
+}
+
+static int rpmsg_rnfs_probe(struct rpmsg_channel *rpdev)
+{
+ int ret = 0;
+ struct rpmsg_ns_msg nsm;
+ struct rnfs_struct *rnfs = &g_rnfs;
+
+ nsm.addr = rpdev->dst;
+ memcpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
+ nsm.flags = 0;
+
+ rnfs_init(rnfs);
+ rnfs->rpdev = rpdev;
+
+ rpdev->ept->priv = rnfs;
+
+ rpmsg_sendto(rpdev, &nsm, sizeof(nsm), rpdev->dst);
+
+ return ret;
+}
+
+static void rpmsg_rnfs_remove(struct rpmsg_channel *rpdev)
+{
+ struct rnfs_struct *rnfs = &g_rnfs;
+ misc_deregister(&rnfs->fdev);
+}
+
+static struct rpmsg_device_id rpmsg_rnfs_id_table[] = {
+ { .name = "rnfs_arm11", },
+ { },
+};
+MODULE_DEVICE_TABLE(rpmsg, rpmsg_rnfs_id_table);
+
+static struct rpmsg_driver rpmsg_rnfs_driver = {
+ .drv.name = KBUILD_MODNAME,
+ .drv.owner = THIS_MODULE,
+ .id_table = rpmsg_rnfs_id_table,
+ .probe = rpmsg_rnfs_probe,
+ .callback = rpmsg_rnfs_cb,
+ .remove = rpmsg_rnfs_remove,
+};
+
+static int __init rpmsg_rnfs_init(void)
+{
+ return register_rpmsg_driver(&rpmsg_rnfs_driver);
+}
+
+static void __exit rpmsg_rnfs_fini(void)
+{
+ unregister_rpmsg_driver(&rpmsg_rnfs_driver);
+}
+
+module_init(rpmsg_rnfs_init);
+module_exit(rpmsg_rnfs_fini);
+
+MODULE_DESCRIPTION("RPMSG Read from NFS Server");
diff --git a/drivers/rpmsg/ambarella/host/rsh/Kconfig b/drivers/rpmsg/ambarella/host/rsh/Kconfig
new file mode 100644
index 00000000..f89c7e7a
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/rsh/Kconfig
@@ -0,0 +1,7 @@
+config RPMSG_RSH
+ tristate "Remote Shell"
+ depends on RPMSG
+ select AMBARELLA_RSH
+ help
+ A Remote shell client for interacting with Itron on ARM11
+ and Linux on CA9-B
diff --git a/drivers/rpmsg/ambarella/host/rsh/Makefile b/drivers/rpmsg/ambarella/host/rsh/Makefile
new file mode 100644
index 00000000..112c56a6
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/rsh/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_RPMSG_RSH) += rpmsg_rsh.o
diff --git a/drivers/rpmsg/ambarella/host/rsh/rpmsg_rsh.c b/drivers/rpmsg/ambarella/host/rsh/rpmsg_rsh.c
new file mode 100644
index 00000000..52ca5f00
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/rsh/rpmsg_rsh.c
@@ -0,0 +1,106 @@
+/**
+ * History:
+ * 2012/09/15 - [Tzu-Jung Lee] created file
+ *
+ * Copyright 2008-2015 Ambarella Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/tty.h>
+#include <linux/remoteproc.h>
+#include <linux/rpmsg.h>
+
+extern int rsh_init_driver(void);
+extern int rsh_init_device(int index, void *rpdev);
+
+extern void rsh_cb(int index, void *data, int len);
+
+int do_rsh_write(void *rpdev, const unsigned char *buf, int count)
+{
+ while (rpmsg_trysend(rpdev, (char*)buf, count))
+ ;
+
+ return count;
+}
+
+static void rpmsg_rsh_cb(struct rpmsg_channel *rpdev, void *data,
+ int len, void *priv, u32 src)
+{
+ rsh_cb((int)priv, data, len);
+}
+
+static int rpmsg_rsh_probe(struct rpmsg_channel *rpdev)
+{
+ int ret = 0;
+ struct rpmsg_ns_msg nsm;
+ int index;
+
+ nsm.addr = rpdev->dst;
+ memcpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
+ nsm.flags = 0;
+
+ if (!strcmp(rpdev->id.name, "rsh_ca9_b"))
+ index = 0;
+ else if (!strcmp(rpdev->id.name, "rsh_arm11"))
+ index = 1;
+ else if (!strcmp(rpdev->id.name, "rsh_ca9_b"))
+ index = 2;
+ else
+ return -1;
+
+ rpdev->ept->priv = (void*)index;
+
+ rpmsg_sendto(rpdev, &nsm, sizeof(nsm), rpdev->dst);
+
+ rsh_init_device(index, rpdev);
+
+ return ret;
+}
+
+static void rpmsg_rsh_remove(struct rpmsg_channel *rpdev)
+{
+}
+
+static struct rpmsg_device_id rpmsg_rsh_id_table[] = {
+ { .name = "rsh_ca9_b", }, /* H: CA9-A, C: CA9-B */
+ { .name = "rsh_arm11", }, /* H: CA9-A, C: ARM11 */
+ { .name = "rsh_ca9_a", }, /* H: CA9-B, C: ARM11 */
+ { },
+};
+MODULE_DEVICE_TABLE(rpmsg, rpmsg_rsh_id_table);
+
+static struct rpmsg_driver rpmsg_rsh_driver =
+{
+ .drv.name = KBUILD_MODNAME,
+ .drv.owner = THIS_MODULE,
+ .id_table = rpmsg_rsh_id_table,
+ .probe = rpmsg_rsh_probe,
+ .callback = rpmsg_rsh_cb,
+ .remove = rpmsg_rsh_remove,
+};
+
+static int __init rpmsg_rsh_init(void)
+{
+ rsh_init_driver();
+
+ return register_rpmsg_driver(&rpmsg_rsh_driver);
+}
+
+static void __exit rpmsg_rsh_fini(void)
+{
+ unregister_rpmsg_driver(&rpmsg_rsh_driver);
+}
+
+module_init(rpmsg_rsh_init);
+module_exit(rpmsg_rsh_fini);
+
+MODULE_DESCRIPTION("RPMSG Remote Shell");
diff --git a/drivers/rpmsg/ambarella/host/veth/Kconfig b/drivers/rpmsg/ambarella/host/veth/Kconfig
new file mode 100644
index 00000000..a315c12e
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/veth/Kconfig
@@ -0,0 +1,6 @@
+config RPMSG_VETH
+ tristate "Virtual Ethernet"
+ depends on RPMSG
+ select AMBARELLA_VETH
+ help
+ A virtualized ethernet device over RPMSG bus.
diff --git a/drivers/rpmsg/ambarella/host/veth/Makefile b/drivers/rpmsg/ambarella/host/veth/Makefile
new file mode 100644
index 00000000..8f05d650
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/veth/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_RPMSG_VETH) += rpmsg_veth.o
diff --git a/drivers/rpmsg/ambarella/host/veth/rpmsg_veth.c b/drivers/rpmsg/ambarella/host/veth/rpmsg_veth.c
new file mode 100644
index 00000000..71b311c7
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/veth/rpmsg_veth.c
@@ -0,0 +1,73 @@
+#include <linux/rpmsg.h>
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+extern struct platform_device ambveth_device;
+extern void ambveth_enqueue(void *priv, void *data, int len);
+
+static struct rpmsg_channel *g_rpdev;
+
+int ambveth_do_send(void *data, int len)
+{
+ return rpmsg_trysend(g_rpdev, data, len);
+}
+
+static void rpmsg_veth_server_cb(struct rpmsg_channel *rpdev, void *data, int len,
+ void *priv, u32 src)
+{
+ ambveth_enqueue(priv, data, len);
+}
+
+static int rpmsg_veth_server_probe(struct rpmsg_channel *rpdev)
+{
+ int ret = 0;
+ struct rpmsg_ns_msg nsm;
+
+ platform_device_register(&ambveth_device);
+ rpdev->ept->priv = &ambveth_device;
+
+ nsm.addr = rpdev->dst;
+ memcpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
+ nsm.flags = 0;
+
+ g_rpdev = rpdev;
+ rpmsg_send(rpdev, &nsm, sizeof(nsm));
+
+ return ret;
+}
+
+static void rpmsg_veth_server_remove(struct rpmsg_channel *rpdev)
+{
+}
+
+static struct rpmsg_device_id rpmsg_veth_server_id_table[] = {
+ { .name = "veth_ca9_b", },
+ { .name = "veth_arm11", },
+ { },
+};
+MODULE_DEVICE_TABLE(rpmsg, rpmsg_veth_server_id_table);
+
+struct rpmsg_driver rpmsg_veth_server_driver = {
+ .drv.name = KBUILD_MODNAME,
+ .drv.owner = THIS_MODULE,
+ .id_table = rpmsg_veth_server_id_table,
+ .probe = rpmsg_veth_server_probe,
+ .callback = rpmsg_veth_server_cb,
+ .remove = rpmsg_veth_server_remove,
+};
+
+static int __init rpmsg_veth_server_init(void)
+{
+ return register_rpmsg_driver(&rpmsg_veth_server_driver);
+}
+
+static void __exit rpmsg_veth_server_fini(void)
+{
+ unregister_rpmsg_driver(&rpmsg_veth_server_driver);
+}
+
+module_init(rpmsg_veth_server_init);
+module_exit(rpmsg_veth_server_fini);
+
+MODULE_DESCRIPTION("RPMSG VETH");
diff --git a/drivers/rpmsg/ambarella/host/vgpio/Kconfig b/drivers/rpmsg/ambarella/host/vgpio/Kconfig
new file mode 100644
index 00000000..3ec92c8d
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/vgpio/Kconfig
@@ -0,0 +1,6 @@
+config RPMSG_VGPIO
+ tristate "Virtual GPIO"
+ depends on RPMSG
+ select AMBARELLA_VGPIO
+ help
+ A virtualized GPIO device over RPMSG bus.
diff --git a/drivers/rpmsg/ambarella/host/vgpio/Makefile b/drivers/rpmsg/ambarella/host/vgpio/Makefile
new file mode 100644
index 00000000..a1ca3eb2
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/vgpio/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_RPMSG_VGPIO) += rpmsg_vgpio.o
diff --git a/drivers/rpmsg/ambarella/host/vgpio/rpmsg_vgpio.c b/drivers/rpmsg/ambarella/host/vgpio/rpmsg_vgpio.c
new file mode 100644
index 00000000..28706dfc
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/vgpio/rpmsg_vgpio.c
@@ -0,0 +1,579 @@
+/*
+ * arch/arm/plat-ambarella/generic/gpio.c
+ *
+ * History:
+ * 2007/11/21 - [Grady Chen] created file
+ * 2008/01/08 - [Anthony Ginger] Add GENERIC_GPIO support.
+ * 2013/10/19 - [Tzu-Jung Lee] Port to vitrtual GPIO support.
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/device.h>
+#include <linux/seq_file.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/rpmsg.h>
+
+enum VGPIO_CMD {
+
+ VGPIO_REQUEST,
+ VGPIO_RELEASE,
+ VGPIO_QUERY,
+ VGPIO_CONFIG,
+ VGPIO_GET,
+ VGPIO_SET,
+};
+
+struct rpmsg_vgpio_msg {
+
+ int cmd;
+ int func;
+ u32 offset;
+ int value;
+ int result;
+};
+
+struct vgpio_chip
+{
+ struct gpio_chip chip;
+ struct mutex mtx;
+ struct rpmsg_vgpio_msg msg;
+ struct completion comp;
+ struct rpmsg_channel *rpdev;
+};
+
+extern struct vgpio_chip vgpio_chip;
+
+#define to_vgpio_chip(c) \
+ container_of(c, struct vgpio_chip, chip)
+
+void rpmsg_vgpio_do_send(void *data)
+{
+ struct vgpio_chip *vchip = data;
+ struct rpmsg_vgpio_msg *msg = &vchip->msg;
+
+ rpmsg_trysend(vchip->rpdev, msg, sizeof(*msg));
+
+ switch (msg->cmd) {
+ case VGPIO_REQUEST:
+ case VGPIO_RELEASE:
+ case VGPIO_QUERY:
+ case VGPIO_CONFIG:
+ case VGPIO_GET:
+ case VGPIO_SET:
+ wait_for_completion(&vchip->comp);
+ break;
+ default:
+ pr_err("%s: invalid vgpio command %d.\n", __func__, msg->cmd);
+ break;
+ }
+}
+
+static void rpmsg_vgpio_cb(struct rpmsg_channel *rpdev, void *data, int len,
+ void *priv, u32 src)
+{
+ struct vgpio_chip *vchip = priv;
+ struct rpmsg_vgpio_msg *msg = data;
+
+ vchip->msg = *msg;
+
+ complete(&vchip->comp);
+}
+
+static int rpmsg_vgpio_probe(struct rpmsg_channel *rpdev)
+{
+ int ret = 0;
+ struct rpmsg_ns_msg nsm;
+
+ vgpio_chip.rpdev = rpdev;
+ rpdev->ept->priv = &vgpio_chip;
+
+ nsm.addr = rpdev->dst;
+ memcpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
+ nsm.flags = 0;
+
+ rpmsg_send(rpdev, &nsm, sizeof(nsm));
+
+ mutex_init(&vgpio_chip.mtx);
+ init_completion(&vgpio_chip.comp);
+
+ ret = gpiochip_add(&vgpio_chip.chip);
+ if (ret)
+ pr_err("%s: gpiochip_add(vgpio)fail %d.\n", __func__, ret);
+
+ return ret;
+}
+
+static void rpmsg_vgpio_remove(struct rpmsg_channel *rpdev)
+{
+}
+
+static struct rpmsg_device_id rpmsg_vgpio_id_table[] = {
+ { .name = "vgpio_ca9_a_and_arm11", },
+ { .name = "vgpio_ca9_b_and_arm11", },
+ { },
+};
+MODULE_DEVICE_TABLE(rpmsg, rpmsg_vgpio_id_table);
+
+struct rpmsg_driver rpmsg_vgpio_driver = {
+ .drv.name = KBUILD_MODNAME,
+ .drv.owner = THIS_MODULE,
+ .id_table = rpmsg_vgpio_id_table,
+ .probe = rpmsg_vgpio_probe,
+ .callback = rpmsg_vgpio_cb,
+ .remove = rpmsg_vgpio_remove,
+};
+
+/* ==========================================================================*/
+
+static int __init rpmsg_vgpio_init(void)
+{
+ return register_rpmsg_driver(&rpmsg_vgpio_driver);
+}
+
+static void __exit rpmsg_vgpio_fini(void)
+{
+ unregister_rpmsg_driver(&rpmsg_vgpio_driver);
+}
+
+static int rpmsg_vgpio_request(struct gpio_chip *chip, unsigned offset,
+ int request)
+{
+ struct vgpio_chip *vchip = to_vgpio_chip(chip);
+ struct rpmsg_vgpio_msg *msg = &vchip->msg;
+ int retval = 0;
+
+ mutex_lock(&vchip->mtx);
+
+ msg->cmd = request ? VGPIO_REQUEST : VGPIO_RELEASE;
+ msg->offset = offset;
+ rpmsg_vgpio_do_send(vchip);
+ retval = msg->result;
+
+ mutex_unlock(&vchip->mtx);
+
+ return retval;
+}
+
+static int rpmsg_vgpio_config(struct gpio_chip *chip, u32 offset, int func)
+{
+ struct vgpio_chip *vchip = to_vgpio_chip(chip);
+ struct rpmsg_vgpio_msg *msg = &vchip->msg;
+ int retval = 0;
+
+ mutex_lock(&vchip->mtx);
+
+ msg->cmd = VGPIO_CONFIG;
+ msg->offset = offset;
+ msg->func = func;
+ rpmsg_vgpio_do_send(vchip);
+ retval = msg->result;
+
+ mutex_unlock(&vchip->mtx);
+
+ return retval;
+}
+
+static int rpmsg_vgpio_query(struct gpio_chip *chip, u32 offset)
+{
+ struct vgpio_chip *vchip = to_vgpio_chip(chip);
+ struct rpmsg_vgpio_msg *msg = &vchip->msg;
+ int retval = 0;
+
+ mutex_lock(&vchip->mtx);
+
+ msg->cmd = VGPIO_QUERY;
+ msg->offset = offset;
+ rpmsg_vgpio_do_send(vchip);
+
+ if (msg->func == GPIO_FUNC_SW_INPUT)
+ retval = 1;
+ else if (msg->func == GPIO_FUNC_SW_OUTPUT)
+ retval = 0;
+ else
+ retval = -EINVAL;
+ mutex_unlock(&vchip->mtx);
+
+ return retval;
+}
+
+static int rpmsg_vgpio_set(struct gpio_chip *chip, u32 offset, int value)
+{
+ struct vgpio_chip *vchip = to_vgpio_chip(chip);
+ struct rpmsg_vgpio_msg *msg = &vchip->msg;
+ int retval = 0;
+
+ mutex_lock(&vchip->mtx);
+
+ msg->cmd = VGPIO_SET;
+ msg->offset = offset;
+ msg->value = value;
+ rpmsg_vgpio_do_send(vchip);
+ retval = msg->result;
+
+ mutex_unlock(&vchip->mtx);
+
+ return retval;
+}
+
+static int rpmsg_vgpio_get(struct gpio_chip *chip, u32 offset)
+{
+ struct vgpio_chip *vchip = to_vgpio_chip(chip);
+ struct rpmsg_vgpio_msg *msg = &vchip->msg;
+ int retval = 0;
+
+ mutex_lock(&vchip->mtx);
+
+ msg->cmd = VGPIO_GET;
+ msg->offset = offset;
+ rpmsg_vgpio_do_send(vchip);
+ retval = msg->value;
+
+ mutex_unlock(&vchip->mtx);
+
+ return retval;
+}
+
+/* ==========================================================================*/
+
+static int rpmsg_vgpio_chip_request(struct gpio_chip *chip, unsigned offset)
+{
+ return rpmsg_vgpio_request(chip, offset, 1);
+}
+
+static void rpmsg_vgpio_chip_free(struct gpio_chip *chip, unsigned offset)
+{
+ rpmsg_vgpio_request(chip, offset, 0);
+}
+
+static int rpmsg_vgpio_chip_get_direction(struct gpio_chip *chip,
+ unsigned offset)
+{
+ return rpmsg_vgpio_query(chip, offset);
+}
+
+static int rpmsg_vgpio_chip_direction_input(struct gpio_chip *chip,
+ unsigned offset)
+{
+ return rpmsg_vgpio_config(chip, offset, GPIO_FUNC_SW_INPUT);
+}
+
+static int rpmsg_vgpio_chip_get(struct gpio_chip *chip, unsigned offset)
+{
+ return rpmsg_vgpio_get(chip, offset);
+}
+
+static int rpmsg_vgpio_chip_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ if (rpmsg_vgpio_config(chip, offset, GPIO_FUNC_SW_OUTPUT) < 0)
+ return -1;
+
+ return rpmsg_vgpio_set(chip, offset, value);
+}
+
+static void rpmsg_vgpio_chip_set(struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ rpmsg_vgpio_set(chip, offset, value);
+}
+
+static int rpmsg_vgpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ if ((chip->base + offset) < GPIO_MAX_LINES)
+ return GPIO_INT_VEC(chip->base + offset);
+
+ return -EINVAL;
+}
+
+static void rpmsg_vgpio_chip_dbg_show(struct seq_file *s,
+ struct gpio_chip *chip)
+{
+ struct vgpio_chip *vchip = to_vgpio_chip(chip);
+
+ int value;
+ int dir;
+ int i = 0;
+
+ for (i = 0; i < GPIO_MAX_LINES; i++) {
+ dir = rpmsg_vgpio_query(chip, i);
+ value = rpmsg_vgpio_get(chip, i);
+ seq_printf(s, "%2d:", i);
+ if (dir > 0)
+ seq_printf(s, " IN, %d\n", value);
+ else if (dir == 0)
+ seq_printf(s, " OUT, %d\n", value);
+ else
+ seq_printf(s, " HW\n");
+ }
+}
+
+struct vgpio_chip vgpio_chip = {
+
+ .chip = {
+ .label = "vgpio",
+ .owner = THIS_MODULE,
+ .request = rpmsg_vgpio_chip_request,
+ .free = rpmsg_vgpio_chip_free,
+ .get_direction = rpmsg_vgpio_chip_get_direction,
+ .direction_input = rpmsg_vgpio_chip_direction_input,
+ .get = rpmsg_vgpio_chip_get,
+ .direction_output = rpmsg_vgpio_chip_direction_output,
+ .set = rpmsg_vgpio_chip_set,
+ .to_irq = rpmsg_vgpio_to_irq,
+ .dbg_show = rpmsg_vgpio_chip_dbg_show,
+ .base = 0,
+ .ngpio = AMBGPIO_SIZE,
+ .can_sleep = 0,
+ .exported = 0,
+ },
+};
+
+/* ==========================================================================*/
+
+void ambarella_gpio_config(int id, int func)
+{
+ u32 offset = id & 0x1f;
+
+ rpmsg_vgpio_config(&vgpio_chip.chip, offset, func);
+}
+EXPORT_SYMBOL(ambarella_gpio_config);
+
+void ambarella_gpio_set(int id, int value)
+{
+ u32 offset = id & 0x1f;
+
+ rpmsg_vgpio_set(&vgpio_chip.chip, offset, value);
+}
+EXPORT_SYMBOL(ambarella_gpio_set);
+
+int ambarella_gpio_get(int id)
+{
+ u32 offset = id & 0x1f;
+
+ return rpmsg_vgpio_get(&vgpio_chip.chip, offset);
+}
+EXPORT_SYMBOL(ambarella_gpio_get);
+/* ==========================================================================*/
+u32 ambarella_gpio_suspend(u32 level) { return 0; }
+u32 ambarella_gpio_resume(u32 level) { return 0; }
+/* ==========================================================================*/
+
+static void ambarella_gpio_mwait(struct ambarella_gpio_io_info *pinfo,
+ int can_sleep)
+{
+ if (can_sleep)
+ msleep(pinfo->active_delay);
+ else
+ mdelay(pinfo->active_delay);
+
+}
+int ambarella_set_gpio_output_can_sleep(
+ struct ambarella_gpio_io_info *pinfo, u32 on, int can_sleep)
+{
+ int retval = 0;
+
+ if (pinfo == NULL) {
+ pr_err("%s: pinfo is NULL.\n", __func__);
+ retval = -1;
+ goto ambarella_set_gpio_output_can_sleep_exit;
+ }
+ if (pinfo->gpio_id < 0 ) {
+ pr_debug("%s: wrong gpio id %d.\n", __func__, pinfo->gpio_id);
+ retval = -1;
+ goto ambarella_set_gpio_output_can_sleep_exit;
+ }
+
+ pr_debug("%s: Gpio[%d] %s, level[%s], delay[%dms].\n", __func__,
+ pinfo->gpio_id, on ? "ON" : "OFF",
+ pinfo->active_level ? "HIGH" : "LOW",
+ pinfo->active_delay);
+ if (pinfo->gpio_id >= EXT_GPIO(0)) {
+ pr_debug("%s: try expander gpio id %d.\n",
+ __func__, pinfo->gpio_id);
+ if (on) {
+ gpio_direction_output(pinfo->gpio_id,
+ pinfo->active_level);
+ } else {
+ gpio_direction_output(pinfo->gpio_id,
+ !pinfo->active_level);
+ }
+ } else {
+ ambarella_gpio_config(pinfo->gpio_id, GPIO_FUNC_SW_OUTPUT);
+ if (on) {
+ ambarella_gpio_set(pinfo->gpio_id,
+ pinfo->active_level);
+ } else {
+ ambarella_gpio_set(pinfo->gpio_id,
+ !pinfo->active_level);
+ }
+ }
+ ambarella_gpio_mwait(pinfo, can_sleep);
+
+ambarella_set_gpio_output_can_sleep_exit:
+ return retval;
+}
+EXPORT_SYMBOL(ambarella_set_gpio_output_can_sleep);
+
+u32 ambarella_get_gpio_input_can_sleep(
+ struct ambarella_gpio_io_info *pinfo, int can_sleep)
+{
+ u32 gpio_value = 0;
+
+ if (pinfo == NULL) {
+ pr_err("%s: pinfo is NULL.\n", __func__);
+ goto ambarella_get_gpio_input_can_sleep_exit;
+ }
+ if (pinfo->gpio_id < 0 ) {
+ pr_debug("%s: wrong gpio id %d.\n", __func__, pinfo->gpio_id);
+ goto ambarella_get_gpio_input_can_sleep_exit;
+ }
+
+ if (pinfo->gpio_id >= EXT_GPIO(0)) {
+ pr_debug("%s: try expander gpio id %d.\n",
+ __func__, pinfo->gpio_id);
+ gpio_direction_input(pinfo->gpio_id);
+ ambarella_gpio_mwait(pinfo, can_sleep);
+ gpio_value = gpio_get_value(pinfo->gpio_id);
+ } else {
+ ambarella_gpio_config(pinfo->gpio_id, GPIO_FUNC_SW_INPUT);
+ ambarella_gpio_mwait(pinfo, can_sleep);
+ gpio_value = ambarella_gpio_get(pinfo->gpio_id);
+ }
+
+ pr_debug("%s: {gpio[%d], level[%s], delay[%dms]} get[%d].\n",
+ __func__, pinfo->gpio_id,
+ pinfo->active_level ? "HIGH" : "LOW",
+ pinfo->active_delay, gpio_value);
+
+ambarella_get_gpio_input_can_sleep_exit:
+ return (gpio_value == pinfo->active_level) ? 1 : 0;
+}
+EXPORT_SYMBOL(ambarella_get_gpio_input_can_sleep);
+
+int ambarella_set_gpio_reset_can_sleep(
+ struct ambarella_gpio_io_info *pinfo, int can_sleep)
+{
+ int retval = 0;
+
+ if (pinfo == NULL) {
+ pr_err("%s: pinfo is NULL.\n", __func__);
+ retval = -1;
+ goto ambarella_set_gpio_reset_can_sleep_exit;
+ }
+ if (pinfo->gpio_id < 0 ) {
+ pr_debug("%s: wrong gpio id %d.\n", __func__, pinfo->gpio_id);
+ retval = -1;
+ goto ambarella_set_gpio_reset_can_sleep_exit;
+ }
+
+ pr_debug("%s: Reset gpio[%d], level[%s], delay[%dms].\n",
+ __func__, pinfo->gpio_id,
+ pinfo->active_level ? "HIGH" : "LOW",
+ pinfo->active_delay);
+ if (pinfo->gpio_id >= EXT_GPIO(0)) {
+ pr_debug("%s: try expander gpio id %d.\n",
+ __func__, pinfo->gpio_id);
+ gpio_direction_output(pinfo->gpio_id, pinfo->active_level);
+ ambarella_gpio_mwait(pinfo, can_sleep);
+
+ gpio_direction_output(pinfo->gpio_id, !pinfo->active_level);
+ ambarella_gpio_mwait(pinfo, can_sleep);
+ } else {
+ ambarella_gpio_config(pinfo->gpio_id, GPIO_FUNC_SW_OUTPUT);
+ ambarella_gpio_set(pinfo->gpio_id, pinfo->active_level);
+ ambarella_gpio_mwait(pinfo, can_sleep);
+
+ ambarella_gpio_set(pinfo->gpio_id, !pinfo->active_level);
+ ambarella_gpio_mwait(pinfo, can_sleep);
+ }
+
+ambarella_set_gpio_reset_can_sleep_exit:
+ return retval;
+}
+EXPORT_SYMBOL(ambarella_set_gpio_reset_can_sleep);
+
+/* ==========================================================================*/
+int ambarella_set_gpio_output(struct ambarella_gpio_io_info *pinfo, u32 on)
+{
+ return ambarella_set_gpio_output_can_sleep(pinfo, on, 0);
+}
+EXPORT_SYMBOL(ambarella_set_gpio_output);
+
+u32 ambarella_get_gpio_input(struct ambarella_gpio_io_info *pinfo)
+{
+ return ambarella_get_gpio_input_can_sleep(pinfo, 0);
+}
+EXPORT_SYMBOL(ambarella_get_gpio_input);
+
+int ambarella_set_gpio_reset(struct ambarella_gpio_io_info *pinfo)
+{
+ return ambarella_set_gpio_reset_can_sleep(pinfo, 0);
+}
+EXPORT_SYMBOL(ambarella_set_gpio_reset);
+
+int ambarella_is_valid_gpio_irq(struct ambarella_gpio_irq_info *pinfo)
+{
+ int bvalid = 0;
+
+ if (pinfo == NULL) {
+ pr_err("%s: pinfo is NULL.\n", __func__);
+ goto ambarella_is_valid_gpio_irq_exit;
+ }
+
+ if ((pinfo->irq_gpio < 0 ) || (pinfo->irq_gpio >= ARCH_NR_GPIOS))
+ goto ambarella_is_valid_gpio_irq_exit;
+
+ if ((pinfo->irq_type != IRQ_TYPE_EDGE_RISING) &&
+ (pinfo->irq_type != IRQ_TYPE_EDGE_FALLING) &&
+ (pinfo->irq_type != IRQ_TYPE_EDGE_BOTH) &&
+ (pinfo->irq_type != IRQ_TYPE_LEVEL_HIGH) &&
+ (pinfo->irq_type != IRQ_TYPE_LEVEL_LOW))
+ goto ambarella_is_valid_gpio_irq_exit;
+
+ if ((pinfo->irq_gpio_val != GPIO_HIGH) &&
+ (pinfo->irq_gpio_val != GPIO_LOW))
+ goto ambarella_is_valid_gpio_irq_exit;
+
+ if ((pinfo->irq_gpio_mode != GPIO_FUNC_SW_INPUT) &&
+ (pinfo->irq_gpio_mode != GPIO_FUNC_SW_OUTPUT) &&
+ (pinfo->irq_gpio_mode != GPIO_FUNC_HW))
+ goto ambarella_is_valid_gpio_irq_exit;
+
+ if ((pinfo->irq_gpio_mode != GPIO_FUNC_HW) &&
+ ((pinfo->irq_line < GPIO_INT_VEC(0)) ||
+ (pinfo->irq_line >= NR_IRQS)))
+ goto ambarella_is_valid_gpio_irq_exit;
+
+ bvalid = 1;
+
+ambarella_is_valid_gpio_irq_exit:
+ return bvalid;
+}
+EXPORT_SYMBOL(ambarella_is_valid_gpio_irq);
+
+module_init(rpmsg_vgpio_init);
+module_exit(rpmsg_vgpio_fini);
+
+MODULE_DESCRIPTION("RPMSG VGPIO");
diff --git a/drivers/rpmsg/ambarella/host/wnfs/Kconfig b/drivers/rpmsg/ambarella/host/wnfs/Kconfig
new file mode 100644
index 00000000..0dd1884e
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/wnfs/Kconfig
@@ -0,0 +1,6 @@
+config RPMSG_WNFS
+ tristate "Write to NFS Server"
+ depends on RPMSG
+ depends on !RPMSG_AMBXC
+ help
+ A sample of rpmsg program which implement an echo server
diff --git a/drivers/rpmsg/ambarella/host/wnfs/Makefile b/drivers/rpmsg/ambarella/host/wnfs/Makefile
new file mode 100644
index 00000000..3b132131
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/wnfs/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_RPMSG_WNFS) += rpmsg_wnfs.o
diff --git a/drivers/rpmsg/ambarella/host/wnfs/rpmsg_wnfs.c b/drivers/rpmsg/ambarella/host/wnfs/rpmsg_wnfs.c
new file mode 100644
index 00000000..35ccb819
--- /dev/null
+++ b/drivers/rpmsg/ambarella/host/wnfs/rpmsg_wnfs.c
@@ -0,0 +1,266 @@
+/*
+ * rpmsg write to nfs server driver
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/rpmsg.h>
+#include <linux/err.h>
+#include <linux/remoteproc.h>
+
+#include <linux/poll.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/kfifo.h>
+
+#include <linux/virtio_ring.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+
+#define DEVICE_NAME "wnfs"
+
+
+typedef int redev_nfs_FILE;
+typedef struct nfs_fwrite_info_s
+{
+ int* addr;
+ int size;
+ int count;
+ redev_nfs_FILE *file;
+}
+nfs_fwrite_info_t;
+
+struct wnfs_struct {
+ struct kfifo fifo;
+ spinlock_t lock;
+ struct rpmsg_channel *rpdev;
+ struct miscdevice fdev;
+ nfs_fwrite_info_t unfinished;
+};
+
+static struct wnfs_struct g_wnfs;
+
+static int device_open(struct inode *inode, struct file *filp)
+{
+ filp->private_data = &g_wnfs;
+
+ return 0;
+}
+
+static ssize_t device_write(struct file *filp, const char *buf,
+ size_t count, loff_t * off)
+{
+ struct wnfs_struct *wnfs = filp->private_data;
+ struct rpmsg_channel *rpdev = wnfs->rpdev;
+
+ rpmsg_sendto(rpdev, (void *)buf, count, rpdev->dst);
+
+ return count;
+}
+
+int wnfs_test_counter = 0;
+static ssize_t device_read(struct file *filp, char *buf,
+ size_t len, loff_t * offset)
+{
+ struct wnfs_struct *wnfs = filp->private_data;
+ int bytes_read = 0;
+ // char c;
+ char *vaddr;
+ nfs_fwrite_info_t nfs_fwrite_info;
+ int copy_size;
+ int unfinished_size;
+ int ret;
+ int len_remain = len;
+
+ //printk(" ====================== device_read %d ======================\n", wnfs_test_counter);
+
+//wnfs_test_counter ++;
+if(wnfs_test_counter > 2000)
+{
+ printk("device_read: force 0\n");
+ wnfs_test_counter = 0;
+ return 0;
+}
+
+// while (kfifo_out_locked(&wnfs->fifo, &c, sizeof(c), &wnfs->lock)) {
+//
+// *buf++ = c;
+// bytes_read++;
+// }
+
+// blocking = filp->??
+
+ while(len_remain > 0) {
+ switch (wnfs->unfinished.count) {
+ case 0:
+ //reload
+// while(1) {
+ ret = kfifo_out_locked(&wnfs->fifo, &nfs_fwrite_info, sizeof(nfs_fwrite_info_t), &wnfs->lock);
+ //printk("reload: info %d/%d\n", ret, sizeof(nfs_fwrite_info_t));
+// //if ret==not ready, sleep
+// if(ret < sizeof(nfs_fwrite_info_t))
+// if(blocking)
+// sleep();
+// else return -EAGAIN;
+// else
+// break;
+// }
+ if(ret < sizeof(nfs_fwrite_info_t)) {
+ msleep(5);
+ //printk("reload: not ready %d\n", ret);
+ break;
+ } else {
+ if(nfs_fwrite_info.size == 0xdeadbeef) {
+ printk("nfs_fwrite_info.size == 0xdeadbeef");
+ wnfs_test_counter = 2000000;
+ rpmsg_sendto(wnfs->rpdev, &bytes_read, sizeof(int), wnfs->rpdev->dst); //ack to release fread of iTRON side
+ return 0;
+ }
+ memcpy(&(wnfs->unfinished), &nfs_fwrite_info, sizeof(nfs_fwrite_info_t));
+ //printk("reload: x%x %d %d\n", wnfs->unfinished.addr, wnfs->unfinished.size, wnfs->unfinished.count);
+ }
+
+ default:
+ //fill-up buf
+ unfinished_size = wnfs->unfinished.size * wnfs->unfinished.count;
+ copy_size = (len_remain > unfinished_size) ? unfinished_size : len_remain;
+ if(copy_size>0)
+ {
+ vaddr = (void*)ambarella_phys_to_virt((unsigned long)wnfs->unfinished.addr);
+ memcpy(buf, vaddr, copy_size);
+ bytes_read += copy_size;
+ buf += copy_size;
+ unfinished_size -= copy_size;
+
+ if(unfinished_size > 0) {
+ wnfs->unfinished.count = unfinished_size / wnfs->unfinished.size;
+ wnfs->unfinished.addr = (int*)((unsigned int)wnfs->unfinished.addr + copy_size);
+ } else {
+ memset(&(wnfs->unfinished), 0, sizeof(nfs_fwrite_info_t));
+ rpmsg_sendto(wnfs->rpdev, &bytes_read, sizeof(int), wnfs->rpdev->dst); //ack to release fread of iTRON side
+ //printk("ack\n");
+ }
+ len_remain -= copy_size;
+ }
+ //printk("fillup: %d/%d \n", bytes_read, len);
+ }
+ }
+
+// while (kfifo_out_locked(&wnfs->fifo, &nfs_fwrite_info, sizeof(nfs_fwrite_info_t), &wnfs->lock)) {
+// // vaddr = ambarella_phys_to_virt(nfs_fwrite_info.addr);
+// // bytes_read += nfs_fwrite_info.size*nfs_fwrite_info.count;
+// // memcpy(buf, vaddr, nfs_fwrite_info.size*nfs_fwrite_info.count);
+// // buf += bytes_read;
+// //printk("device_read: x%x x%x\n", vaddr, bytes_read);
+// bytes_read = len;
+// }
+
+ //rpmsg_sendto(g_wnfs.rpdev, &bytes_read, sizeof(int), g_wnfs.rpdev->dst);
+ //printk("device_read: final bytes_read %d/%d \n", bytes_read, len);
+
+ return bytes_read;
+}
+
+static int device_release(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static struct file_operations fops = {
+ .read = device_read,
+ .write = device_write,
+ .open = device_open,
+ .release = device_release
+};
+
+static int wnfs_init(struct wnfs_struct *wnfs)
+{
+ int ret;
+
+ spin_lock_init(&wnfs->lock);
+
+ ret = kfifo_alloc(&wnfs->fifo, 4096*16, GFP_KERNEL);
+ if (ret)
+ return ret;
+
+ printk("RPMSG Write to NFS Server [ARM11] now is ready at /dev/%s\n", DEVICE_NAME);
+
+ wnfs->fdev.name = DEVICE_NAME;
+ wnfs->fdev.fops = &fops;
+ memset(&(wnfs->unfinished), 0, sizeof(nfs_fwrite_info_t));
+ misc_register(&wnfs->fdev);
+
+ return 0;
+}
+
+static void rpmsg_wnfs_cb(struct rpmsg_channel *rpdev, void *data,
+ int len, void *priv, u32 src)
+{
+ struct wnfs_struct *wnfs = priv;
+ int n;
+ //printk("rpmsg_wnfs_cb +\n");
+
+ n = kfifo_in_locked(&wnfs->fifo, (char *)data, len, &wnfs->lock);
+ //printk("rpmsg_wnfs_cb -:%d\n", n);
+//rpmsg_sendto(rpdev, &len, sizeof(int), rpdev->dst);
+}
+
+static int rpmsg_wnfs_probe(struct rpmsg_channel *rpdev)
+{
+ int ret = 0;
+ struct rpmsg_ns_msg nsm;
+ struct wnfs_struct *wnfs = &g_wnfs;
+
+ nsm.addr = rpdev->dst;
+ memcpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
+ nsm.flags = 0;
+
+ wnfs_init(wnfs);
+ wnfs->rpdev = rpdev;
+
+ rpdev->ept->priv = wnfs;
+
+ rpmsg_sendto(rpdev, &nsm, sizeof(nsm), rpdev->dst);
+
+ return ret;
+}
+
+static void rpmsg_wnfs_remove(struct rpmsg_channel *rpdev)
+{
+ struct wnfs_struct *wnfs = &g_wnfs;
+ misc_deregister(&wnfs->fdev);
+}
+
+static struct rpmsg_device_id rpmsg_wnfs_id_table[] = {
+ { .name = "wnfs_arm11", },
+ { },
+};
+MODULE_DEVICE_TABLE(rpmsg, rpmsg_wnfs_id_table);
+
+static struct rpmsg_driver rpmsg_wnfs_driver = {
+ .drv.name = KBUILD_MODNAME,
+ .drv.owner = THIS_MODULE,
+ .id_table = rpmsg_wnfs_id_table,
+ .probe = rpmsg_wnfs_probe,
+ .callback = rpmsg_wnfs_cb,
+ .remove = rpmsg_wnfs_remove,
+};
+
+static int __init rpmsg_wnfs_init(void)
+{
+ return register_rpmsg_driver(&rpmsg_wnfs_driver);
+}
+
+static void __exit rpmsg_wnfs_fini(void)
+{
+ unregister_rpmsg_driver(&rpmsg_wnfs_driver);
+}
+
+module_init(rpmsg_wnfs_init);
+module_exit(rpmsg_wnfs_fini);
+
+MODULE_DESCRIPTION("RPMSG Write to NFS Server");
diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c
index b6135d4d..403d0f30 100644
--- a/drivers/rpmsg/virtio_rpmsg_bus.c
+++ b/drivers/rpmsg/virtio_rpmsg_bus.c
@@ -33,6 +33,8 @@
#include <linux/wait.h>
#include <linux/rpmsg.h>
#include <linux/mutex.h>
+#include <linux/remoteproc.h>
+#include <plat/remoteproc.h>
/**
* struct virtproc_info - virtual remote processor state
@@ -62,7 +64,11 @@ struct virtproc_info {
void *rbufs, *sbufs;
int last_sbuf;
dma_addr_t bufs_dma;
+#if defined(CONFIG_RPMSG_TX_SPINLOCK)
+ spinlock_t tx_lock;
+#else
struct mutex tx_lock;
+#endif
struct idr endpoints;
struct mutex endpoints_lock;
wait_queue_head_t sendq;
@@ -82,6 +88,13 @@ struct rpmsg_channel_info {
u32 dst;
};
+#if defined(CONFIG_RPMSG_TX_SPINLOCK)
+#define rpmsg_tx_lock(x) spin_lock_irq(x)
+#define rpmsg_tx_unlock(x) spin_unlock_irq(x)
+#else
+#define rpmsg_tx_lock(x) mutex_lock(x)
+#define rpmsg_tx_unlock(x) mutex_unlock(x)
+#endif
#define to_rpmsg_channel(d) container_of(d, struct rpmsg_channel, dev)
#define to_rpmsg_driver(d) container_of(d, struct rpmsg_driver, drv)
@@ -102,8 +115,14 @@ struct rpmsg_channel_info {
* can change this without changing anything in the firmware of the remote
* processor.
*/
-#define RPMSG_NUM_BUFS (512)
-#define RPMSG_BUF_SIZE (512)
+
+/*
+ * Keep the following sync'ed to the copy which shared between processors
+ * arch/arm/plat-ambarella/include/plat/remoteproc_cfg.h
+ */
+#define RPMSG_NUM_BUFS (CONFIG_RPMSG_NUM_BUFS)
+#define RPMSG_BUF_SIZE (CONFIG_RPMSG_BUF_SIZE)
+
#define RPMSG_TOTAL_BUF_SPACE (RPMSG_NUM_BUFS * RPMSG_BUF_SIZE)
/*
@@ -573,7 +592,7 @@ static void *get_a_tx_buf(struct virtproc_info *vrp)
void *ret;
/* support multiple concurrent senders */
- mutex_lock(&vrp->tx_lock);
+ rpmsg_tx_lock(&vrp->tx_lock);
/*
* either pick the next unused tx buffer
@@ -585,7 +604,7 @@ static void *get_a_tx_buf(struct virtproc_info *vrp)
else
ret = virtqueue_get_buf(vrp->svq, &len);
- mutex_unlock(&vrp->tx_lock);
+ rpmsg_tx_unlock(&vrp->tx_lock);
return ret;
}
@@ -609,14 +628,14 @@ static void *get_a_tx_buf(struct virtproc_info *vrp)
static void rpmsg_upref_sleepers(struct virtproc_info *vrp)
{
/* support multiple concurrent senders */
- mutex_lock(&vrp->tx_lock);
+ rpmsg_tx_lock(&vrp->tx_lock);
/* are we the first sleeping context waiting for tx buffers ? */
if (atomic_inc_return(&vrp->sleepers) == 1)
/* enable "tx-complete" interrupts before dozing off */
virtqueue_enable_cb(vrp->svq);
- mutex_unlock(&vrp->tx_lock);
+ rpmsg_tx_unlock(&vrp->tx_lock);
}
/**
@@ -636,14 +655,14 @@ static void rpmsg_upref_sleepers(struct virtproc_info *vrp)
static void rpmsg_downref_sleepers(struct virtproc_info *vrp)
{
/* support multiple concurrent senders */
- mutex_lock(&vrp->tx_lock);
+ rpmsg_tx_lock(&vrp->tx_lock);
/* are we the last sleeping context waiting for tx buffers ? */
if (atomic_dec_and_test(&vrp->sleepers))
/* disable "tx-complete" interrupts */
virtqueue_disable_cb(vrp->svq);
- mutex_unlock(&vrp->tx_lock);
+ rpmsg_tx_unlock(&vrp->tx_lock);
}
/**
@@ -749,12 +768,14 @@ int rpmsg_send_offchannel_raw(struct rpmsg_channel *rpdev, u32 src, u32 dst,
dev_dbg(dev, "TX From 0x%x, To 0x%x, Len %d, Flags %d, Reserved %d\n",
msg->src, msg->dst, msg->len,
msg->flags, msg->reserved);
+#if 0
print_hex_dump(KERN_DEBUG, "rpmsg_virtio TX: ", DUMP_PREFIX_NONE, 16, 1,
msg, sizeof(*msg) + msg->len, true);
+#endif
sg_init_one(&sg, msg, sizeof(*msg) + len);
- mutex_lock(&vrp->tx_lock);
+ rpmsg_tx_lock(&vrp->tx_lock);
/* add message to the remote processor's virtqueue */
err = virtqueue_add_outbuf(vrp->svq, &sg, 1, msg, GFP_KERNEL);
@@ -771,7 +792,7 @@ int rpmsg_send_offchannel_raw(struct rpmsg_channel *rpdev, u32 src, u32 dst,
/* tell the remote processor it has a pending message to read */
virtqueue_kick(vrp->svq);
out:
- mutex_unlock(&vrp->tx_lock);
+ rpmsg_tx_unlock(&vrp->tx_lock);
return err;
}
EXPORT_SYMBOL(rpmsg_send_offchannel_raw);
@@ -786,8 +807,10 @@ static int rpmsg_recv_single(struct virtproc_info *vrp, struct device *dev,
dev_dbg(dev, "From: 0x%x, To: 0x%x, Len: %d, Flags: %d, Reserved: %d\n",
msg->src, msg->dst, msg->len,
msg->flags, msg->reserved);
+#if 0
print_hex_dump(KERN_DEBUG, "rpmsg_virtio RX: ", DUMP_PREFIX_NONE, 16, 1,
msg, sizeof(*msg) + msg->len, true);
+#endif
/*
* We currently use fixed-sized buffers, so trivially sanitize
@@ -942,6 +965,9 @@ static void rpmsg_ns_cb(struct rpmsg_channel *rpdev, void *data, int len,
static int rpmsg_probe(struct virtio_device *vdev)
{
+ struct rproc *rproc = vdev_to_rproc(vdev);
+ struct ambarella_rproc_pdata *pdata;
+
vq_callback_t *vq_cbs[] = { rpmsg_recv_done, rpmsg_xmit_done };
const char *names[] = { "input", "output" };
struct virtqueue *vqs[2];
@@ -957,7 +983,11 @@ static int rpmsg_probe(struct virtio_device *vdev)
idr_init(&vrp->endpoints);
mutex_init(&vrp->endpoints_lock);
+#if defined(CONFIG_RPMSG_TX_SPINLOCK)
+ spin_lock_init(&vrp->tx_lock);
+#else
mutex_init(&vrp->tx_lock);
+#endif
init_waitqueue_head(&vrp->sendq);
/* We expect two virtqueues, rx and tx (and in this order) */
@@ -968,10 +998,15 @@ static int rpmsg_probe(struct virtio_device *vdev)
vrp->rvq = vqs[0];
vrp->svq = vqs[1];
+#if 0
/* allocate coherent memory for the buffers */
bufs_va = dma_alloc_coherent(vdev->dev.parent->parent,
RPMSG_TOTAL_BUF_SPACE,
&vrp->bufs_dma, GFP_KERNEL);
+#else
+ pdata = rproc->priv;
+ bufs_va = (void *)ambarella_phys_to_virt((unsigned long)pdata->buf_addr_pa);
+#endif
if (!bufs_va) {
err = -ENOMEM;
goto vqs_del;
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index b9838130..2e49c5ee 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1092,6 +1092,12 @@ config RTC_DRV_MV
This driver can also be built as a module. If so, the module
will be called rtc-mv.
+config RTC_DRV_AMBARELLA
+ tristate "Ambarella SoC RTC"
+ depends on PLAT_AMBARELLA
+ help
+ RTC (Realtime Clock) driver for Ambarella SoC.
+
config RTC_DRV_PS3
tristate "PS3 RTC"
depends on PPC_PS3
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index c33f86f1..fefba95d 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_RTC_DRV_88PM860X) += rtc-88pm860x.o
obj-$(CONFIG_RTC_DRV_88PM80X) += rtc-88pm80x.o
obj-$(CONFIG_RTC_DRV_AB3100) += rtc-ab3100.o
obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o
+obj-$(CONFIG_RTC_DRV_AMBARELLA) += rtc-ambarella.o
obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o
obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o
obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o
diff --git a/drivers/rtc/rtc-ambarella.c b/drivers/rtc/rtc-ambarella.c
new file mode 100644
index 00000000..c8203ae5
--- /dev/null
+++ b/drivers/rtc/rtc-ambarella.c
@@ -0,0 +1,375 @@
+/*
+ * drivers/rtc/ambarella_rtc.c
+ *
+ * History:
+ * 2008/04/01 - [Cao Rongrong] Support pause and resume
+ * 2009/01/22 - [Anthony Ginger] Port to 2.6.28
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+#include <linux/clk.h>
+#include <asm/uaccess.h>
+#include <mach/hardware.h>
+#include <plat/rtc.h>
+
+#define AMBRTC_TIME 0
+#define AMBRTC_ALARM 1
+
+struct ambarella_rtc {
+ struct rtc_device *rtc;
+ void __iomem *reg;
+ struct device *dev;
+
+ /* limitation for old rtc:
+ * 1. cannot detect power lost
+ * 2. the msb 2bits are reserved. */
+ bool is_limited;
+ int irq;
+};
+
+
+static inline void ambrtc_reset_rtc(struct ambarella_rtc *ambrtc)
+{
+ u32 delay = ambrtc->is_limited ? 3 : 1;
+
+ amba_writel(ambrtc->reg + RTC_RESET_OFFSET, 0x01);
+ msleep(delay);
+ amba_writel(ambrtc->reg + RTC_RESET_OFFSET, 0x00);
+ msleep(delay);
+}
+
+static int ambrtc_get_alarm_or_time(struct ambarella_rtc *ambrtc,
+ int time_alarm)
+{
+ u32 reg_offs, val_sec;
+
+ if (time_alarm == AMBRTC_TIME)
+ reg_offs = RTC_CURT_OFFSET;
+ else
+ reg_offs = RTC_ALAT_OFFSET;
+
+ val_sec = amba_readl(ambrtc->reg + reg_offs);
+ /* because old rtc cannot use the msb 2bits, we add 0x40000000
+ * here, this is a pure software workaround. And the result is that
+ * the time must be started at least from 2004.01.10 13:38:00 */
+ if (ambrtc->is_limited)
+ val_sec |= 0x40000000;
+
+ return val_sec;
+}
+
+static int ambrtc_set_alarm_or_time(struct ambarella_rtc *ambrtc,
+ int time_alarm, unsigned long secs)
+{
+ u32 time_val, alarm_val;
+
+ if (ambrtc->is_limited && secs < 0x40000000) {
+ dev_err(ambrtc->dev,
+ "Invalid date[0x%lx](2004.01.10 13:38:00 ~ )\n", secs);
+ return -EINVAL;
+ }
+
+ if (time_alarm == AMBRTC_TIME) {
+ time_val = secs;
+ alarm_val = amba_readl(ambrtc->reg + RTC_ALAT_OFFSET);
+ } else {
+ alarm_val = secs;
+ time_val = amba_readl(ambrtc->reg + RTC_CURT_OFFSET);
+ // only for wakeup ambarella internal PWC
+ amba_writel(ambrtc->reg + RTC_PWC_SET_STATUS_OFFSET, 0x28);
+ }
+
+ if (ambrtc->is_limited) {
+ time_val &= 0x3fffffff;
+ alarm_val &= 0x3fffffff;
+ }
+
+ amba_writel(ambrtc->reg + RTC_POS0_OFFSET, 0x80);
+ amba_writel(ambrtc->reg + RTC_POS1_OFFSET, 0x80);
+ amba_writel(ambrtc->reg + RTC_POS2_OFFSET, 0x80);
+
+ /* reset time and alarm to 0 first */
+ amba_writel(ambrtc->reg + RTC_PWC_ALAT_OFFSET, 0x0);
+ amba_writel(ambrtc->reg + RTC_PWC_CURT_OFFSET, 0x0);
+ ambrtc_reset_rtc(ambrtc);
+
+ /* now write the required value to time or alarm */
+ amba_writel(ambrtc->reg + RTC_PWC_CURT_OFFSET, time_val);
+ amba_writel(ambrtc->reg + RTC_PWC_ALAT_OFFSET, alarm_val);
+ ambrtc_reset_rtc(ambrtc);
+
+ return 0;
+}
+
+static int ambrtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ struct ambarella_rtc *ambrtc;
+ u32 time_sec;
+
+ ambrtc = dev_get_drvdata(dev);
+
+ time_sec = ambrtc_get_alarm_or_time(ambrtc, AMBRTC_TIME);
+
+ rtc_time_to_tm(time_sec, tm);
+
+ return 0;
+}
+
+static int ambrtc_set_mmss(struct device *dev, unsigned long secs)
+{
+ struct ambarella_rtc *ambrtc;
+
+ ambrtc = dev_get_drvdata(dev);
+
+ return ambrtc_set_alarm_or_time(ambrtc, AMBRTC_TIME, secs);
+}
+
+
+static int ambrtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct ambarella_rtc *ambrtc;
+ u32 alarm_sec, time_sec;
+ u32 rtc_status;
+
+ ambrtc = dev_get_drvdata(dev);
+
+ alarm_sec = ambrtc_get_alarm_or_time(ambrtc, AMBRTC_ALARM);
+ rtc_time_to_tm(alarm_sec, &alrm->time);
+
+ time_sec = ambrtc_get_alarm_or_time(ambrtc, AMBRTC_TIME);
+ alrm->enabled = alarm_sec > time_sec;
+
+ rtc_status = amba_readl(ambrtc->reg + RTC_STATUS_OFFSET);
+ alrm->pending = !!(rtc_status & RTC_STATUS_ALA_WK);
+
+ return 0;
+}
+
+static int ambrtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct ambarella_rtc *ambrtc;
+ unsigned long alarm_sec;
+
+ ambrtc = dev_get_drvdata(dev);
+
+ rtc_tm_to_time(&alrm->time, &alarm_sec);
+
+ return ambrtc_set_alarm_or_time(ambrtc, AMBRTC_ALARM, alarm_sec);
+}
+
+static int ambrtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+ return 0;
+}
+
+static irqreturn_t ambrtc_alarm_irq(int irq, void *dev_id)
+{
+ struct ambarella_rtc *ambrtc = (struct ambarella_rtc *)dev_id;
+
+ if(ambrtc->rtc)
+ rtc_update_irq(ambrtc->rtc, 1, RTC_IRQF | RTC_AF);
+
+ return IRQ_HANDLED;
+}
+
+static int ambrtc_ioctl(struct device *dev, unsigned int cmd,
+ unsigned long arg)
+{
+ struct ambarella_rtc *ambrtc;
+ int lbat, rval = 0;
+
+ ambrtc = dev_get_drvdata(dev);
+
+ if (ambrtc->is_limited)
+ return -ENOIOCTLCMD;
+
+ switch (cmd) {
+ case RTC_VL_READ:
+ lbat = !!amba_readl(ambrtc->reg + RTC_PWC_LBAT_OFFSET);
+ rval = put_user(lbat, (int __user *)arg);
+ break;
+ default:
+ rval = -ENOIOCTLCMD;
+ break;
+ }
+
+ return rval;
+}
+
+static const struct rtc_class_ops ambarella_rtc_ops = {
+ .ioctl = ambrtc_ioctl,
+ .read_time = ambrtc_read_time,
+ .set_mmss = ambrtc_set_mmss,
+ .read_alarm = ambrtc_read_alarm,
+ .set_alarm = ambrtc_set_alarm,
+ .alarm_irq_enable = ambrtc_alarm_irq_enable,
+};
+
+static void ambrtc_check_power_lost(struct ambarella_rtc *ambrtc)
+{
+ u32 status, need_rst, time_sec;
+
+ if (ambrtc->is_limited) {
+ status = amba_readl(ambrtc->reg + RTC_STATUS_OFFSET);
+ need_rst = !(status & RTC_STATUS_PC_RST);
+ } else {
+ status = amba_readl(ambrtc->reg + RTC_PWC_REG_STA_OFFSET);
+ need_rst = !(status & RTC_PWC_LOSS_MASK);
+ amba_setbitsl(ambrtc->reg + RTC_PWC_SET_STATUS_OFFSET,
+ RTC_PWC_LOSS_MASK);
+ }
+
+ if (need_rst) {
+ dev_warn(ambrtc->dev, "=====RTC ever lost power=====\n");
+ time_sec = ambrtc->is_limited ? 0x40000000 : 0;
+ ambrtc_set_alarm_or_time(ambrtc, AMBRTC_TIME, time_sec);
+ }
+}
+
+
+static int ambrtc_probe(struct platform_device *pdev)
+{
+ struct ambarella_rtc *ambrtc;
+ struct resource *mem;
+ void __iomem *reg;
+ int ret;
+ unsigned int wakeup_support;
+ struct device_node *np = pdev->dev.of_node;
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (mem == NULL) {
+ dev_err(&pdev->dev, "Get mem resource failed!\n");
+ return -ENXIO;
+ }
+
+ reg = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
+ if (!reg) {
+ dev_err(&pdev->dev, "devm_ioremap() failed\n");
+ return -ENOMEM;
+ }
+
+ ambrtc = devm_kzalloc(&pdev->dev, sizeof(*ambrtc), GFP_KERNEL);
+ if (mem == NULL) {
+ dev_err(&pdev->dev, "no memory!\n");
+ return -ENOMEM;
+ }
+
+ ambrtc->irq = platform_get_irq(pdev, 0);
+ if (ambrtc->irq < 0) {
+ ambrtc->irq = -1;
+ } else {
+ ret = devm_request_irq(&pdev->dev, ambrtc->irq, ambrtc_alarm_irq, IRQF_SHARED,
+ "rtc alarm", ambrtc);
+ if (ret) {
+ dev_err(&pdev->dev, "could not request irq %d for rtc alarm\n", ambrtc->irq);
+ return ret;
+ }
+ }
+
+ ambrtc->reg = reg;
+ ambrtc->dev = &pdev->dev;
+ ambrtc->is_limited = !!of_find_property(pdev->dev.of_node,
+ "amb,is-limited", NULL);
+ platform_set_drvdata(pdev, ambrtc);
+ ambrtc_check_power_lost(ambrtc);
+
+ wakeup_support = !!of_get_property(np, "rtc,wakeup", NULL);
+ if (wakeup_support)
+ device_set_wakeup_capable(&pdev->dev, 1);
+
+ ambrtc->rtc = devm_rtc_device_register(&pdev->dev, "rtc-ambarella",
+ &ambarella_rtc_ops, THIS_MODULE);
+ if (IS_ERR(ambrtc->rtc)) {
+ dev_err(&pdev->dev, "devm_rtc_device_register fail.\n");
+ return PTR_ERR(ambrtc->rtc);
+ }
+
+ ambrtc->rtc->uie_unsupported = 1;
+
+ return 0;
+}
+
+static int ambrtc_remove(struct platform_device *pdev)
+{
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static const struct of_device_id ambarella_rtc_dt_ids[] = {
+ {.compatible = "ambarella,rtc", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ambarella_rtc_dt_ids);
+
+#ifdef CONFIG_PM_SLEEP
+static int ambarella_rtc_suspend(struct device *dev)
+{
+ struct ambarella_rtc *ambrtc = dev_get_drvdata(dev);
+
+ if (device_may_wakeup(dev)){
+ if (ambrtc->irq != -1)
+ enable_irq_wake(ambrtc->irq);
+ }
+
+ return 0;
+}
+
+static int ambarella_rtc_resume(struct device *dev)
+{
+ struct ambarella_rtc *ambrtc = dev_get_drvdata(dev);
+
+ if (device_may_wakeup(dev)) {
+ if (ambrtc->irq != -1)
+ disable_irq_wake(ambrtc->irq);
+ }
+ return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(ambarella_rtc_pm_ops, ambarella_rtc_suspend, ambarella_rtc_resume);
+
+static struct platform_driver ambarella_rtc_driver = {
+ .probe = ambrtc_probe,
+ .remove = ambrtc_remove,
+ .driver = {
+ .name = "ambarella-rtc",
+ .owner = THIS_MODULE,
+ .of_match_table = ambarella_rtc_dt_ids,
+ .pm = &ambarella_rtc_pm_ops,
+ },
+};
+
+module_platform_driver(ambarella_rtc_driver);
+
+MODULE_DESCRIPTION("Ambarella Onchip RTC Driver");
+MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 92a9345d..f6b1f019 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -49,6 +49,15 @@ config SPI_MASTER
controller and the protocol drivers for the SPI slave chips
that are connected.
+config SPI_SLAVE
+# boolean "SPI Slave Support"
+ boolean
+ default SPI
+ help
+ If your system has an slave-capable SPI controller (which
+ takes the clock and chipselect), you can enable that
+ controller for the SPI master chips that are connected.
+
if SPI_MASTER
comment "SPI Master Controller Drivers"
@@ -60,6 +69,12 @@ config SPI_ALTERA
help
This is the driver for the Altera SPI Controller.
+config SPI_AMBARELLA
+ tristate "Ambarella SPI Controller"
+ depends on PLAT_AMBARELLA
+ help
+ This selects a driver for the Ambarella SPI Controller.
+
config SPI_ATH79
tristate "Atheros AR71XX/AR724X/AR913X SPI controller driver"
depends on ATH79 && GPIOLIB
@@ -539,4 +554,16 @@ endif # SPI_MASTER
# (slave support would go here)
+if SPI_SLAVE
+
+comment "SPI Slave Controller Drivers"
+
+config SPI_SLAVE_AMBARELLA
+ tristate "Ambarella SPI Slave Controller"
+ depends on PLAT_AMBARELLA
+ help
+ This selects a driver for the Ambarella SPI Slave Controller.
+
+endif # SPI_SLAVE
+
endif # SPI
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 33f9c095..cd4e3c6e 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_SPI_SPIDEV) += spidev.o
# SPI master controller drivers (bus)
obj-$(CONFIG_SPI_ALTERA) += spi-altera.o
+obj-$(CONFIG_SPI_AMBARELLA) += spi-ambarella.o
obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o
obj-$(CONFIG_SPI_ATH79) += spi-ath79.o
obj-$(CONFIG_SPI_AU1550) += spi-au1550.o
@@ -74,3 +75,4 @@ obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi-topcliff-pch.o
obj-$(CONFIG_SPI_TXX9) += spi-txx9.o
obj-$(CONFIG_SPI_XCOMM) += spi-xcomm.o
obj-$(CONFIG_SPI_XILINX) += spi-xilinx.o
+obj-$(CONFIG_SPI_SLAVE_AMBARELLA) += spi_slave_ambarella.o
diff --git a/drivers/spi/spi-ambarella.c b/drivers/spi/spi-ambarella.c
new file mode 100644
index 00000000..1f444b70
--- /dev/null
+++ b/drivers/spi/spi-ambarella.c
@@ -0,0 +1,951 @@
+/*
+ * linux/drivers/spi/spi-ambarella.c
+ *
+ * History:
+ * 2014/08/29 - [Zhenwu Xue]
+
+ *
+ * Copyright (C) 2012-2016, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spidev.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmapool.h>
+#include <asm/io.h>
+#include <mach/io.h>
+#include <plat/spi.h>
+#include <plat/dma.h>
+#include <plat/rct.h>
+
+#define AMBARELLA_SPI_BUF_MAX_LEN (1024 * 20) //4096
+#define AMBARELLA_SPI_MAX_XFER_PER_MSG 32
+#define AMBARELLA_SPI_MAX_CS_NUM 8
+
+struct ambarella_spi {
+ struct device *dev;
+ struct dma_chan *tx_dma_chan;
+ struct dma_chan *rx_dma_chan;
+ struct spi_message *msg;
+ struct spi_transfer *transfers[AMBARELLA_SPI_MAX_XFER_PER_MSG];
+ struct clk *clk;
+ struct tasklet_struct tasklet;
+ void __iomem *virt;
+
+ u8 *tx_dma_buf;
+ u8 *rx_dma_buf;
+ dma_addr_t tx_dma_phys;
+ dma_addr_t rx_dma_phys;
+
+ u32 dma_buf_size;
+ u32 phys;
+ u32 clk_freq;
+ u32 dma_used:1;
+ u32 msb_first_only:1;
+ u32 ridx, widx;
+ u32 cspol;
+ int cs_pins[AMBARELLA_SPI_MAX_CS_NUM];
+ int xfer_id, n_xfer;
+ int cs_active;
+ int rw;
+ int irq;
+};
+
+static void ambarella_spi_next_transfer(void *args);
+
+static int ambarella_spi_of_parse(struct platform_device *pdev,
+ struct spi_master *master)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct ambarella_spi *ambspi = spi_master_get_devdata(master);
+ int rval;
+
+ ambspi->clk = clk_get(NULL, "gclk_ssi");
+ if (IS_ERR(ambspi->clk)) {
+ dev_err(&pdev->dev, "Get PLL failed!\n");
+ return PTR_ERR(ambspi->clk);
+ }
+
+ rval = of_property_read_u32(np, "amb,clk-freq", &ambspi->clk_freq);
+ if (rval < 0) {
+ dev_err(&pdev->dev, "invalid clk-freq! %d\n", rval);
+ return rval;
+ }
+
+ return 0;
+}
+
+static void ambarella_spi_setup(struct ambarella_spi *bus, struct spi_device *spi)
+{
+ spi_ctrl0_reg_t cr0;
+ u32 ssi_clk, sckdv;
+
+ cr0.w = 0;
+ cr0.s.dfs = spi->bits_per_word - 1;
+ if (spi->mode & SPI_CPHA) {
+ cr0.s.scph = 1;
+ } else {
+ cr0.s.scph = 0;
+ }
+ if (spi->mode & SPI_CPOL) {
+ cr0.s.scpol = 1;
+ } else {
+ cr0.s.scpol = 0;
+ }
+ if (spi->mode & SPI_LOOP) {
+ cr0.s.srl = 1;
+ } else {
+ cr0.s.srl = 0;
+ }
+ if (spi->mode & SPI_LSB_FIRST) {
+ cr0.s.tx_lsb = 1;
+ cr0.s.rx_lsb = 1;
+ } else {
+ cr0.s.tx_lsb = 0;
+ cr0.s.rx_lsb = 0;
+ }
+
+ cr0.s.hold = 0;
+ cr0.s.byte_ws = 0;
+ cr0.s.fc_en = 0;
+ cr0.s.residue = 1;
+ amba_writel(bus->virt + SPI_CTRLR0_OFFSET, cr0.w);
+
+ ssi_clk = bus->clk_freq;
+ if(spi->max_speed_hz > ssi_clk / 2) {
+ spi->max_speed_hz = ssi_clk / 2;
+ }
+ sckdv = (ssi_clk / spi->max_speed_hz + 1) & 0xfffe;
+ amba_writel(bus->virt + SPI_BAUDR_OFFSET, sckdv);
+
+ bus->cspol = (spi->mode & SPI_CS_HIGH) ? 1 : 0;
+ gpio_set_value(spi->cs_gpio, bus->cspol);
+ bus->cs_active = 1;
+}
+
+static void ambarella_spi_stop(struct ambarella_spi *bus)
+{
+ amba_readl(bus->virt + SPI_ICR_OFFSET);
+ amba_readl(bus->virt + SPI_ISR_OFFSET);
+
+ amba_writel(bus->virt + SPI_SSIENR_OFFSET, 0);
+ amba_writel(bus->virt + SPI_SER_OFFSET, 0);
+
+ if (bus->dma_used)
+ amba_writel(bus->virt + SPI_DMAC_OFFSET, 0);
+}
+
+static void ambarella_spi_prepare_transfer(struct ambarella_spi *bus)
+{
+ struct spi_message *msg;
+ struct spi_transfer *xfer;
+ const void *wbuf, *rbuf;
+ spi_ctrl0_reg_t cr0;
+
+ bus->widx = 0;
+ bus->ridx = 0;
+
+ msg = bus->msg;
+ xfer = bus->transfers[bus->xfer_id];
+
+ wbuf = xfer->tx_buf;
+ rbuf = xfer->rx_buf;
+ if (wbuf && !rbuf) {
+ bus->rw = SPI_WRITE_ONLY;
+ }
+ if (!wbuf && rbuf) {
+ bus->rw = SPI_READ_ONLY;
+ }
+ if (wbuf && rbuf) {
+ bus->rw = SPI_WRITE_READ;
+ }
+ msg->actual_length += xfer->len;
+
+ cr0.w = amba_readl(bus->virt + SPI_CTRLR0_OFFSET);
+ cr0.s.tmod = SPI_WRITE_READ;
+ amba_writel(bus->virt + SPI_CTRLR0_OFFSET, cr0.w);
+
+ if (!bus->cs_active) {
+ gpio_set_value(msg->spi->cs_gpio, bus->cspol);
+ bus->cs_active = 1;
+ }
+
+ amba_writel(bus->virt + SPI_SSIENR_OFFSET, 0);
+ amba_writel(bus->virt + SPI_SER_OFFSET, 0);
+ if (bus->dma_used) {
+ if (bus->msg->spi->bits_per_word <= 8) {
+ amba_writel(bus->virt + SPI_RXFTLR_OFFSET, 8 - 1);
+ } else {
+ amba_writel(bus->virt + SPI_RXFTLR_OFFSET, 4 - 1);
+ }
+ amba_writel(bus->virt + SPI_DMAC_OFFSET, 0x3);
+ } else {
+ disable_irq_nosync(bus->irq);
+ amba_writel(bus->virt + SPI_IMR_OFFSET, SPI_TXEIS_MASK);
+ amba_writel(bus->virt + SPI_TXFTLR_OFFSET, 0);
+ amba_writel(bus->virt + SPI_RXFTLR_OFFSET, 1);
+ }
+ amba_writel(bus->virt + SPI_SSIENR_OFFSET, 1);
+}
+
+static void ambarella_spi_start_transfer(struct ambarella_spi *bus)
+{
+ struct spi_device *spi;
+ struct spi_transfer *xfer;
+ struct dma_slave_config tx_cfg, rx_cfg;
+ struct dma_async_tx_descriptor *txd, *rxd;
+ u32 len, widx, ridx, xfer_len, i;
+ void *wbuf, *rbuf;
+ u16 tmp;
+
+ xfer = bus->transfers[bus->xfer_id];
+ spi = bus->msg->spi;
+
+ wbuf = (void *)xfer->tx_buf;
+ rbuf = (void *)xfer->rx_buf;
+ widx = bus->widx;
+ ridx = bus->ridx;
+
+ len = xfer->len;
+ if (!bus->dma_used) {
+ if (bus->msg->spi->bits_per_word > 8)
+ len >>= 1;
+ }
+
+ dma_sync_single_for_cpu(bus->dev, bus->tx_dma_phys, len, DMA_TO_DEVICE);
+
+ switch (bus->rw) {
+ case SPI_WRITE_ONLY:
+ case SPI_WRITE_READ:
+ if (!bus->dma_used) {
+ xfer_len = min_t(int, len - widx, SPI_DATA_FIFO_SIZE_16);
+ for(i = 0; i < xfer_len; i++) {
+ if (bus->msg->spi->bits_per_word <= 8)
+ tmp = ((u8 *)wbuf)[widx++];
+ else
+ tmp = ((u16 *)wbuf)[widx++];
+ amba_writel(bus->virt + SPI_DR_OFFSET, tmp);
+ }
+ } else {
+ memcpy(bus->tx_dma_buf, xfer->tx_buf, len);
+ }
+ break;
+ case SPI_READ_ONLY:
+ if (!bus->dma_used) {
+ xfer_len = min_t(int, len - ridx, SPI_DATA_FIFO_SIZE_16);
+ for(i = 0; i < xfer_len; i++)
+ amba_writel(bus->virt + SPI_DR_OFFSET, SPI_DUMMY_DATA);
+ } else {
+ memset(bus->tx_dma_buf, 0xFF, len);
+ }
+
+ break;
+ default:
+ break;
+ }
+
+ if (bus->dma_used) {
+ /* TX DMA */
+ tx_cfg.dst_addr = bus->phys + SPI_DR_OFFSET;
+ if (spi->bits_per_word <= 8) {
+ tx_cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+ } else {
+ tx_cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+ }
+ tx_cfg.dst_maxburst = 8;
+ tx_cfg.direction = DMA_MEM_TO_DEV;
+
+ BUG_ON(dmaengine_slave_config(bus->tx_dma_chan, &tx_cfg) < 0);
+
+ dma_sync_single_for_device(bus->dev, bus->tx_dma_phys, len, DMA_TO_DEVICE);
+
+ txd = dmaengine_prep_slave_single(bus->tx_dma_chan, bus->tx_dma_phys, len,
+ DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT |
+ DMA_COMPL_SKIP_SRC_UNMAP | DMA_COMPL_SKIP_DEST_UNMAP | DMA_CTRL_ACK);
+ BUG_ON (!txd);
+
+ txd->callback = NULL;
+ txd->callback_param = NULL;
+ dmaengine_submit(txd);
+
+ dma_async_issue_pending(bus->tx_dma_chan);
+
+ /* RX DMA */
+ rx_cfg.src_addr = bus->phys + SPI_DR_OFFSET;
+ if (spi->bits_per_word <= 8) {
+ rx_cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+ } else {
+ rx_cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+ }
+ rx_cfg.src_maxburst = 8;
+ rx_cfg.direction = DMA_DEV_TO_MEM;
+
+ BUG_ON(dmaengine_slave_config(bus->rx_dma_chan, &rx_cfg) < 0);
+
+ rxd = dmaengine_prep_slave_single(bus->rx_dma_chan, bus->rx_dma_phys, len,
+ DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK |
+ DMA_COMPL_SKIP_SRC_UNMAP | DMA_COMPL_SKIP_DEST_UNMAP);
+ BUG_ON(!rxd);
+
+ rxd->callback = ambarella_spi_next_transfer;
+ rxd->callback_param = bus;
+
+ dma_sync_single_for_device(bus->dev, bus->rx_dma_phys, len, DMA_FROM_DEVICE);
+
+ dmaengine_submit(rxd);
+ dma_async_issue_pending(bus->rx_dma_chan);
+ } else {
+ bus->widx = widx;
+ enable_irq(bus->irq);
+ }
+
+ amba_writel(bus->virt + SPI_SER_OFFSET, 1 << spi->chip_select);
+}
+
+static void ambarella_spi_next_transfer(void *args)
+{
+ struct ambarella_spi *bus = args;
+ struct spi_transfer *xfer;
+
+ xfer = bus->transfers[bus->xfer_id++];
+
+ if (bus->dma_used) {
+ switch (bus->rw) {
+ case SPI_WRITE_READ:
+ case SPI_READ_ONLY:
+ dma_sync_single_for_cpu(bus->dev, bus->rx_dma_phys, xfer->len, DMA_FROM_DEVICE);
+ memcpy(xfer->rx_buf, bus->rx_dma_buf, xfer->len);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (xfer->cs_change) {
+ gpio_set_value(bus->msg->spi->cs_gpio, bus->cspol^1);
+ bus->cs_active = 0;
+ }
+
+ if (bus->xfer_id >= bus->n_xfer) {
+ gpio_set_value(bus->msg->spi->cs_gpio, bus->cspol^1);
+ bus->cs_active = 0;
+
+ ambarella_spi_stop(bus);
+ spi_finalize_current_message(bus->msg->spi->master);
+ } else {
+ ambarella_spi_prepare_transfer(bus);
+ ambarella_spi_start_transfer(bus);
+ }
+}
+
+static void ambarella_spi_tasklet(unsigned long data)
+{
+ struct ambarella_spi *bus = (struct ambarella_spi *)data;
+ struct spi_transfer *xfer;
+ void *rbuf;
+ u32 widx, ridx, len, rxflr, xfer_len;
+ u32 status, finish_transfer = 0;
+ u16 i, tmp;
+
+ xfer = bus->transfers[bus->xfer_id];
+
+ /* Wait until SPI idle */
+ status = amba_readl(bus->virt + SPI_SR_OFFSET);
+ if (status & 0x1) {
+ /* Transfer is still in progress */
+ for (i = 0; i < MAX_QUERY_TIMES; i++) {
+ status = amba_readl(bus->virt + SPI_SR_OFFSET);
+ if (!(status & 0x1))
+ break;
+ }
+ if (status & 0x1) {
+ tasklet_schedule(&bus->tasklet);
+ return;
+ }
+ }
+
+ rbuf = (void *)xfer->rx_buf;
+ widx = bus->widx;
+ ridx = bus->ridx;
+ len = xfer->len;
+
+ if (bus->msg->spi->bits_per_word > 8)
+ len >>= 1;
+
+ /* Fetch data from FIFO */
+ switch (bus->rw) {
+ case SPI_READ_ONLY:
+ case SPI_WRITE_READ:
+ xfer_len = len - ridx;
+ rxflr = amba_readl(bus->virt + SPI_RXFLR_OFFSET);
+ if (xfer_len > rxflr)
+ xfer_len = rxflr;
+ for(i = 0; i < xfer_len; i++) {
+ tmp = amba_readl(bus->virt + SPI_DR_OFFSET);
+ if (bus->msg->spi->bits_per_word <= 8)
+ ((u8 *)rbuf)[ridx++] = tmp & 0xff;
+ else
+ ((u16 *)rbuf)[ridx++] = tmp;
+ }
+ bus->ridx = ridx;
+ break;
+ default:
+ break;
+ }
+
+ /* Check whether the current transfer ends */
+ switch (bus->rw) {
+ case SPI_WRITE_ONLY:
+ if (widx == len)
+ finish_transfer = 1;
+ break;
+ case SPI_READ_ONLY:
+ if (ridx == len)
+ finish_transfer = 1;
+ break;
+ case SPI_WRITE_READ:
+ if (ridx == len && widx == len)
+ finish_transfer = 1;
+ break;
+ default:
+ break;
+ }
+
+ /* End transfer or continue filling FIFO */
+ if (finish_transfer) {
+ ambarella_spi_next_transfer((void *) bus);
+ enable_irq(bus->irq);
+ } else {
+ ambarella_spi_start_transfer(bus);
+ }
+}
+
+static int ambarella_spi_one_message(struct spi_master *master, struct spi_message *msg)
+{
+ int err = 0;
+ struct spi_device *spi;
+ struct ambarella_spi *bus;
+ struct spi_transfer *xfer;
+
+ spi = msg->spi;
+ bus = spi_master_get_devdata(master);
+
+ msg->status = 0;
+ msg->actual_length = 0;
+ bus->msg = msg;
+
+ if (list_empty(&msg->transfers)) {
+ spi_finalize_current_message(master);
+ goto ambarella_spi_transfer_exit;
+ }
+
+ if (!gpio_is_valid(spi->cs_gpio)) {
+ dev_err(&master->dev, "cs %d is invalid!\n", spi->cs_gpio);
+ err = -EINVAL;
+ goto ambarella_spi_transfer_exit;
+ }
+
+ if (spi->bits_per_word < 4 || spi->bits_per_word > 16) {
+ err = -EINVAL;
+ goto ambarella_spi_transfer_exit;
+ }
+
+ if (!spi->max_speed_hz) {
+ err = -EINVAL;
+ goto ambarella_spi_transfer_exit;
+ }
+
+ if (spi->bits_per_word > 8) {
+ list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+ if (xfer->len & 0x1) {
+ err = -EINVAL;
+ goto ambarella_spi_transfer_exit;
+ }
+ }
+ }
+
+ if ((spi->mode & SPI_LSB_FIRST) && bus->msb_first_only) {
+ dev_err(&master->dev, "SPI[%d] only supports msb first tx-rx", master->bus_num);
+ err = -EINVAL;
+ goto ambarella_spi_transfer_exit;
+ }
+
+ bus->n_xfer = 0;
+ bus->xfer_id = 0;
+ list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+ if (xfer->len > AMBARELLA_SPI_BUF_MAX_LEN) {
+ err = -EINVAL;
+ goto ambarella_spi_transfer_exit;
+ }
+ bus->transfers[bus->n_xfer++] = xfer;
+ }
+
+ ambarella_spi_setup(bus, spi);
+ ambarella_spi_prepare_transfer(bus);
+ ambarella_spi_start_transfer(bus);
+
+ambarella_spi_transfer_exit:
+ return err;
+}
+
+static irqreturn_t ambarella_spi_isr(int irq, void *dev_data)
+{
+ struct ambarella_spi *bus = dev_data;
+
+ if (amba_readl(bus->virt + SPI_ISR_OFFSET)) {
+ disable_irq_nosync(bus->irq);
+ amba_writel(bus->virt + SPI_ISR_OFFSET, 0);
+
+ ambarella_spi_tasklet((unsigned long)bus);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int ambarella_spi_dma_channel_allocate(struct ambarella_spi *bus,
+ bool dma_to_memory)
+{
+ struct dma_chan *dma_chan;
+ dma_addr_t dma_phys;
+ u8 *dma_buf;
+ int ret = 0;
+
+ dma_chan = dma_request_slave_channel(bus->dev,
+ dma_to_memory ? "rx" : "tx");
+ if (IS_ERR(dma_chan)) {
+ ret = PTR_ERR(dma_chan);
+ if (ret != -EPROBE_DEFER)
+ dev_err(bus->dev,
+ "Dma channel is not available: %d\n", ret);
+ return ret;
+ }
+
+ dma_buf = dma_alloc_coherent(bus->dev, bus->dma_buf_size,
+ &dma_phys, GFP_KERNEL);
+ if (!dma_buf) {
+ dev_err(bus->dev, " Not able to allocate the dma buffer\n");
+ dma_release_channel(dma_chan);
+ return -ENOMEM;
+ }
+
+ if (dma_to_memory) {
+ bus->rx_dma_chan = dma_chan;
+ bus->rx_dma_buf = dma_buf;
+ bus->rx_dma_phys = dma_phys;
+ } else {
+ bus->tx_dma_chan = dma_chan;
+ bus->tx_dma_buf = dma_buf;
+ bus->tx_dma_phys = dma_phys;
+ }
+
+ return ret;
+}
+
+static void ambarella_spi_dma_channel_free(struct ambarella_spi *bus,
+ bool dma_to_memory)
+{
+ u8 *dma_buf;
+ dma_addr_t dma_phys;
+ struct dma_chan *dma_chan;
+
+ if (dma_to_memory) {
+ dma_buf = bus->rx_dma_buf;
+ dma_chan = bus->rx_dma_chan;
+ dma_phys = bus->rx_dma_phys;
+ bus->rx_dma_chan = NULL;
+ bus->rx_dma_buf = NULL;
+ } else {
+ dma_buf = bus->tx_dma_buf;
+ dma_chan = bus->tx_dma_chan;
+ dma_phys = bus->tx_dma_phys;
+ bus->tx_dma_buf = NULL;
+ bus->tx_dma_chan = NULL;
+ }
+ if (!dma_chan)
+ return;
+
+ dma_free_coherent(bus->dev, bus->dma_buf_size, dma_buf, dma_phys);
+ dma_release_channel(dma_chan);
+}
+
+static int ambarella_spi_hw_setup(struct spi_device *spi)
+{
+ struct ambarella_spi *bus = spi_master_get_devdata(spi->master);
+ int err = 0;
+
+ if (gpio_is_valid(spi->cs_gpio) &&
+ (bus->cs_pins[spi->chip_select] != spi->cs_gpio)) {
+ err = gpio_request(spi->cs_gpio, dev_name(&spi->dev));
+ if (err < 0) {
+ dev_err(&spi->dev, "can't get CS: %d\n", err);
+ return -EINVAL;
+ }
+ gpio_direction_output(spi->cs_gpio, (spi->mode & SPI_CS_HIGH) ? 0 : 1);
+ bus->cs_pins[spi->chip_select] = spi->cs_gpio;
+ }
+
+ return 0;
+}
+
+static int ambarella_spi_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ void __iomem *reg;
+ struct ambarella_spi *bus;
+ struct spi_master *master;
+ int i;
+ int err = 0;
+ int irq;
+ u32 val;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ err = -EINVAL;
+ goto exit_spi_probe;
+ }
+
+ reg = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!reg) {
+ err = -ENOMEM;
+ goto exit_spi_probe;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "no irq resource!\n");
+ err = -ENODEV;
+ goto exit_spi_probe;
+ }
+
+ master = spi_alloc_master(&pdev->dev, sizeof(*bus));
+ if (!master) {
+ err = -ENOMEM;
+ goto exit_spi_probe;
+ }
+
+ bus = spi_master_get_devdata(master);
+ bus->phys = res->start;
+ bus->virt = reg;
+ bus->irq = irq;
+ bus->dev = &pdev->dev;
+
+ for (i = 0; i < AMBARELLA_SPI_MAX_CS_NUM; i++)
+ bus->cs_pins[i] = -1;
+
+ err = ambarella_spi_of_parse(pdev, master);
+ if (err < 0) {
+ goto exit_free_master;
+ }
+
+ clk_set_rate(bus->clk, bus->clk_freq);
+ amba_writel(reg + SPI_SSIENR_OFFSET, 0);
+ amba_writel(reg + SPI_IMR_OFFSET, 0);
+
+ master->dev.of_node = pdev->dev.of_node;
+ master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_CS_HIGH;
+ master->transfer_one_message = ambarella_spi_one_message;
+ master->setup = ambarella_spi_hw_setup;
+ platform_set_drvdata(pdev, master);
+
+ /* check if hw only supports msb first tx/rx */
+ if (of_find_property(pdev->dev.of_node, "amb,msb-first-only", NULL)) {
+ bus->msb_first_only = 1;
+ dev_info(&pdev->dev,"Only supports msb first tx-rx\n");
+ } else {
+ bus->msb_first_only = 0;
+ master->mode_bits |= SPI_LSB_FIRST;
+ }
+
+ /* check if using dma */
+ if (of_find_property(pdev->dev.of_node, "amb,dma-used", NULL)) {
+ bus->dma_used = 1;
+ dev_info(&pdev->dev,"DMA is used\n");
+
+ /* Enable DMA Channel 0/1 as SSI0 Tx and Rx */
+ val = amba_readl(AHB_SCRATCHPAD_REG(0x0c));
+ val &= 0xff9fffff;
+ val |= 0x00200000;
+ amba_writel(AHB_SCRATCHPAD_REG(0x0c), val);
+
+ bus->dma_buf_size = AMBARELLA_SPI_BUF_MAX_LEN;
+ err = ambarella_spi_dma_channel_allocate(bus, false);
+ if (err < 0)
+ goto exit_free_master;
+ err = ambarella_spi_dma_channel_allocate(bus, true);
+ if (err < 0)
+ goto exit_tx_dma_irq_free;
+ } else {
+ bus->dma_used = 0;
+ /* request IRQ */
+ err = devm_request_irq(&pdev->dev, irq, ambarella_spi_isr,
+ IRQF_TRIGGER_HIGH, dev_name(&pdev->dev), bus);
+ if (err)
+ goto exit_free_master;
+
+ tasklet_init(&bus->tasklet, ambarella_spi_tasklet, (unsigned long)bus);
+ }
+
+ err = spi_register_master(master);
+ if (err)
+ goto exit_rx_dma_free;
+
+ dev_info(&pdev->dev, "Ambarella spi controller %d created.\r\n", master->bus_num);
+
+ return err;
+
+exit_rx_dma_free:
+ if (bus->dma_used)
+ ambarella_spi_dma_channel_free(bus, true);
+exit_tx_dma_irq_free:
+ if (bus->dma_used)
+ ambarella_spi_dma_channel_free(bus, false);
+ else
+ free_irq(irq, bus);
+exit_free_master:
+ spi_master_put(master);
+exit_spi_probe:
+ return err;
+}
+
+static int ambarella_spi_remove(struct platform_device *pdev)
+{
+ struct spi_master *master;
+ struct ambarella_spi *bus;
+ int i;
+
+ master = platform_get_drvdata(pdev);
+ bus = spi_master_get_devdata(master);
+
+ if (!bus->dma_used)
+ tasklet_kill(&bus->tasklet);
+ else {
+ if (bus->tx_dma_chan)
+ ambarella_spi_dma_channel_free(bus, false);
+
+ if (bus->rx_dma_chan)
+ ambarella_spi_dma_channel_free(bus, true);
+ }
+
+ ambarella_spi_stop(bus);
+
+ for (i = 0; i < AMBARELLA_SPI_MAX_CS_NUM; i++) {
+ if (gpio_is_valid(bus->cs_pins[i]))
+ gpio_free(bus->cs_pins[i]);
+ }
+
+ spi_unregister_master(master);
+
+ return 0;
+}
+
+int ambarella_spi_write(amba_spi_cfg_t *spi_cfg, amba_spi_write_t *spi_w)
+{
+ int err = 0;
+ struct spi_master *master;
+ struct spi_device spi;
+ struct ambarella_spi *bus;
+
+ master = spi_busnum_to_master(spi_w->bus_id);
+ if (!master) {
+ err = -EINVAL;
+ goto ambarella_spi_write_exit;
+ }
+
+ bus = spi_master_get_devdata(master);
+
+ spi.master = master;
+ spi.bits_per_word = spi_cfg->cfs_dfs;
+ spi.mode = spi_cfg->spi_mode;
+ spi.max_speed_hz = spi_cfg->baud_rate;
+ spi.chip_select = spi_w->cs_id;
+ spi.cs_gpio = bus->cs_pins[spi.chip_select];
+
+ err = spi_write_then_read(&spi, spi_w->buffer, spi_w->n_size, NULL, 0);
+
+ambarella_spi_write_exit:
+ return err;
+}
+EXPORT_SYMBOL(ambarella_spi_write);
+
+int ambarella_spi_read(amba_spi_cfg_t *spi_cfg, amba_spi_read_t *spi_r)
+{
+ int err = 0;
+ struct spi_master *master;
+ struct spi_device spi;
+ struct ambarella_spi *bus;
+
+ master = spi_busnum_to_master(spi_r->bus_id);
+ if (!master) {
+ err = -EINVAL;
+ goto ambarella_spi_read_exit;
+ }
+
+ bus = spi_master_get_devdata(master);
+
+ spi.master = master;
+ spi.bits_per_word = spi_cfg->cfs_dfs;
+ spi.mode = spi_cfg->spi_mode;
+ spi.max_speed_hz = spi_cfg->baud_rate;
+ spi.chip_select = spi_r->cs_id;
+ spi.cs_gpio = bus->cs_pins[spi.chip_select];
+
+ err = spi_write_then_read(&spi, NULL, 0, spi_r->buffer, spi_r->n_size);
+
+ambarella_spi_read_exit:
+ return err;
+}
+EXPORT_SYMBOL(ambarella_spi_read);
+
+int ambarella_spi_write_then_read(amba_spi_cfg_t *spi_cfg,
+ amba_spi_write_then_read_t *spi_wtr)
+{
+ int err = 0;
+ struct spi_master *master;
+ struct spi_device spi;
+ struct ambarella_spi *bus;
+
+ master = spi_busnum_to_master(spi_wtr->bus_id);
+ if (!master) {
+ err = -EINVAL;
+ goto ambarella_spi_write_then_read_exit;
+ }
+
+ bus = spi_master_get_devdata(master);
+
+ spi.master = master;
+ spi.bits_per_word = spi_cfg->cfs_dfs;
+ spi.mode = spi_cfg->spi_mode;
+ spi.max_speed_hz = spi_cfg->baud_rate;
+ spi.chip_select = spi_wtr->cs_id;
+ spi.cs_gpio = bus->cs_pins[spi.chip_select];
+
+ err = spi_write_then_read(&spi,
+ spi_wtr->w_buffer, spi_wtr->w_size,
+ spi_wtr->r_buffer, spi_wtr->r_size);
+
+ambarella_spi_write_then_read_exit:
+ return err;
+}
+EXPORT_SYMBOL(ambarella_spi_write_then_read);
+
+int ambarella_spi_write_and_read(amba_spi_cfg_t *spi_cfg,
+ amba_spi_write_and_read_t *spi_war)
+{
+ int err = 0;
+ struct spi_master *master;
+ struct spi_device spi;
+ struct ambarella_spi *bus;
+ struct spi_message msg;
+ struct spi_transfer x[1];
+
+ master = spi_busnum_to_master(spi_war->bus_id);
+ if (!master) {
+ err = -EINVAL;
+ goto ambarella_spi_write_and_read_exit;
+ }
+
+ bus = spi_master_get_devdata(master);
+
+ spi.master = master;
+ spi.bits_per_word = spi_cfg->cfs_dfs;
+ spi.mode = spi_cfg->spi_mode;
+ spi.max_speed_hz = spi_cfg->baud_rate;
+ spi.chip_select = spi_war->cs_id;
+ spi.cs_gpio = bus->cs_pins[spi.chip_select];
+
+ spi_message_init(&msg);
+ memset(x, 0, sizeof x);
+ x->tx_buf = spi_war->w_buffer;
+ x->rx_buf = spi_war->r_buffer;
+ x->len = spi_war->n_size;
+ spi_message_add_tail(x, &msg);
+
+ err = spi_sync(&spi, &msg);
+
+ambarella_spi_write_and_read_exit:
+ return err;
+}
+EXPORT_SYMBOL(ambarella_spi_write_and_read);
+
+#ifdef CONFIG_PM
+static int ambarella_spi_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ dev_dbg(&pdev->dev, "%s exit with 0 @ %d\n", __func__, state.event);
+
+ return 0;
+}
+
+static int ambarella_spi_resume(struct platform_device *pdev)
+{
+ struct spi_master *master = platform_get_drvdata(pdev);
+ struct ambarella_spi *bus = spi_master_get_devdata(master);
+
+ clk_set_rate(bus->clk, bus->clk_freq);
+
+ dev_dbg(&pdev->dev, "%s exit with 0\n", __func__);
+
+ return 0;
+}
+#endif
+
+static const struct of_device_id ambarella_spi_dt_ids[] = {
+ {.compatible = "ambarella,spi", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ambarella_spi_dt_ids);
+
+static struct platform_driver ambarella_spi_driver = {
+ .probe = ambarella_spi_probe,
+ .remove = ambarella_spi_remove,
+#ifdef CONFIG_PM
+ .suspend = ambarella_spi_suspend,
+ .resume = ambarella_spi_resume,
+#endif
+ .driver = {
+ .name = "ambarella-spi",
+ .owner = THIS_MODULE,
+ .of_match_table = ambarella_spi_dt_ids,
+ },
+};
+
+static int ambarella_spi_init(void)
+{
+ return platform_driver_register(&ambarella_spi_driver);
+}
+
+static void ambarella_spi_exit(void)
+{
+ platform_driver_unregister(&ambarella_spi_driver);
+}
+
+module_init(ambarella_spi_init);
+module_exit(ambarella_spi_exit);
+
+MODULE_DESCRIPTION("Ambarella Media Processor SPI Bus Controller");
+MODULE_AUTHOR("Zhenwu Xue, <zwxue@ambarella.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi_slave_ambarella.c b/drivers/spi/spi_slave_ambarella.c
new file mode 100644
index 00000000..439d2bac
--- /dev/null
+++ b/drivers/spi/spi_slave_ambarella.c
@@ -0,0 +1,638 @@
+/*
+ * linux/drivers/spi/spi_slave_ambarella.c
+ *
+ * History:
+ * 2012/02/21 - [Zhenwu Xue] created file
+ *
+ * Copyright (C) 2004-2012, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spidev.h>
+#include <linux/fs.h>
+#include <linux/of.h>
+#include <linux/ioctl.h>
+#include <asm/uaccess.h>
+#include <plat/spi.h>
+
+#define MAX_SPI_SLAVES 8
+
+#define SPI_RXFIS_MASK 0x00000010
+#define SPI_RXOIS_MASK 0x00000008
+#define SPI_RXUIS_MASK 0x00000004
+
+#define BUFFER_LEN 4096
+
+#define DUMMY_DATA 0xffff
+
+static int rx_ftlr = 8;
+module_param(rx_ftlr, int, 0644);
+
+struct ambarella_spi_slave {
+ void __iomem *regbase;
+
+ int major;
+ char dev_name[32];
+ struct class *psClass;
+ struct device *psDev;
+
+ u16 mode;
+ u16 bpw;
+
+ int count;
+ struct mutex um_mtx;
+
+ u16 r_buf[BUFFER_LEN];
+ u16 r_buf_start;
+ u16 r_buf_end;
+ u16 r_buf_empty;
+ u16 r_buf_full;
+ u16 r_buf_round;
+ spinlock_t r_buf_lock;
+
+ u16 w_buf[BUFFER_LEN];
+ u16 w_buf_start;
+ u16 w_buf_end;
+ u16 w_buf_empty;
+ u16 w_buf_full;
+ u16 w_buf_round;
+ spinlock_t w_buf_lock;
+};
+
+DEFINE_MUTEX(g_mtx);
+static int amb_slave_id = 0;
+static struct ambarella_spi_slave *priv_array[MAX_SPI_SLAVES] =
+ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
+
+static int ambarella_spi_slave_inithw(struct ambarella_spi_slave *priv)
+{
+ struct clk *clk;
+ u32 ctrlr0;
+
+ clk = clk_get(NULL, "gclk_ssi2");
+ if (!IS_ERR_OR_NULL(clk))
+ clk_set_rate(clk, 13500000);
+
+ /* Initial Register Settings */
+ ctrlr0 = (SPI_CFS << 12) | (SPI_WRITE_READ << 8) | (priv->mode << 6) |
+ (SPI_FRF << 4) | (priv->bpw - 1);
+ amba_writel(priv->regbase + SPI_CTRLR0_OFFSET, ctrlr0);
+
+ amba_writel(priv->regbase + SPI_TXFTLR_OFFSET, 0);
+ amba_writel(priv->regbase + SPI_RXFTLR_OFFSET, rx_ftlr - 1);
+ amba_writel(priv->regbase + SPI_IMR_OFFSET, SPI_RXFIS_MASK);
+
+ return 0;
+}
+
+static irqreturn_t ambarella_spi_slave_isr(int irq, void *dev_data)
+{
+ struct ambarella_spi_slave *priv = dev_data;
+ u32 i, rxflr, txflr;
+
+ if (amba_readl(priv->regbase + SPI_ISR_OFFSET)) {
+ txflr = 16 - amba_readl(priv->regbase + SPI_TXFLR_OFFSET);
+ spin_lock(&priv->w_buf_lock);
+ if (priv->w_buf_empty) {
+ for (i = 0; i < txflr; i++) {
+ amba_writel(priv->regbase + SPI_DR_OFFSET, DUMMY_DATA);
+ }
+ } else {
+ priv->w_buf_full = 0;
+ if (priv->w_buf_round & 0x01) {
+ if (BUFFER_LEN - priv->w_buf_start > txflr) {
+ for (i = 0; i < txflr; i++) {
+ amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[priv->w_buf_start++]);
+ }
+ } else if (BUFFER_LEN - priv->w_buf_start + priv->w_buf_end > txflr) {
+ for (i = 0; i < BUFFER_LEN - priv->w_buf_start; i++) {
+ amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[priv->w_buf_start++]);
+ }
+ for (i = 0; i < txflr + priv->w_buf_start - BUFFER_LEN; i++) {
+ amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[i]);
+ }
+ priv->w_buf_start = i + 1;
+ priv->w_buf_round++;
+ } else {
+ for (i = 0; i < BUFFER_LEN - priv->w_buf_start; i++) {
+ amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[priv->w_buf_start++]);
+ }
+ for (i = 0; i < priv->w_buf_end; i++) {
+ amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[i]);
+ }
+ for (i = 0; i < txflr + priv->w_buf_start - BUFFER_LEN - priv->w_buf_end; i++) {
+ amba_writel(priv->regbase + SPI_DR_OFFSET, DUMMY_DATA);
+ }
+ priv->w_buf_empty = 1;
+ }
+ } else {
+ if (priv->w_buf_end - priv->w_buf_start > txflr) {
+ for (i = 0; i < txflr; i++) {
+ amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[priv->w_buf_start++]);
+ }
+ } else {
+ for (i = 0; i < priv->w_buf_end - priv->w_buf_start; i++) {
+ amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[priv->w_buf_start++]);
+ }
+ for (i = 0; i < txflr - priv->w_buf_end + priv->w_buf_start; i++) {
+ amba_writel(priv->regbase + SPI_DR_OFFSET, DUMMY_DATA);
+ }
+ priv->w_buf_empty = 1;
+ }
+ }
+ }
+ spin_unlock(&priv->w_buf_lock);
+
+ rxflr = amba_readl(priv->regbase + SPI_RXFLR_OFFSET);
+ spin_lock(&priv->r_buf_lock);
+ if (priv->r_buf_empty) {
+ priv->r_buf_start = 0;
+ priv->r_buf_end = 0;
+ priv->r_buf_empty = 0;
+ }
+
+ for (i = 0; i < rxflr; i++) {
+ if (priv->r_buf_full) {
+ printk("%s: Rx buffer overflow!!\n", __FILE__);
+ priv->r_buf_start++;
+ if (priv->r_buf_start >= BUFFER_LEN) {
+ priv->r_buf_start = 0;
+ priv->r_buf_round++;
+ }
+ }
+
+ priv->r_buf[priv->r_buf_end++] = amba_readl(priv->regbase + SPI_DR_OFFSET);
+ if (priv->r_buf_end >= BUFFER_LEN) {
+ priv->r_buf_end = 0;
+ priv->r_buf_round++;
+ }
+
+ if (priv->r_buf_round & 0x01) {
+ if (priv->r_buf_end >= priv->r_buf_start) {
+ priv->r_buf_full = 1;
+ }
+ }
+ }
+ spin_unlock(&priv->r_buf_lock);
+
+ amba_writel(priv->regbase + SPI_ISR_OFFSET, 0);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int spi_slave_open(struct inode *inode, struct file *filp)
+{
+ int i, ret = 0;
+ struct ambarella_spi_slave *priv = NULL;
+
+ mutex_lock(&g_mtx);
+
+ for (i = 0; i < MAX_SPI_SLAVES; i++) {
+ if (priv_array[i] && MKDEV(priv_array[i]->major, 0) == inode->i_rdev) {
+ priv = priv_array[i];
+ break;
+ }
+ }
+ mutex_lock(&priv->um_mtx);
+ if (!priv->count) {
+ priv->count++;
+ filp->private_data = priv;
+ } else {
+ ret = -ENXIO;
+ }
+ mutex_unlock(&priv->um_mtx);
+
+ mutex_unlock(&g_mtx);
+
+ return ret;
+}
+
+static ssize_t
+spi_slave_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
+{
+ ssize_t ret = 0;
+ struct ambarella_spi_slave *priv;
+ int result;
+
+ priv = (struct ambarella_spi_slave *)filp->private_data;
+
+ spin_lock(&priv->r_buf_lock);
+
+ if (!priv->r_buf_empty) {
+ if (priv->r_buf_round & 0x01) {
+ if ((BUFFER_LEN - priv->r_buf_start) * 2 >= count) {
+ result = copy_to_user(buf, (void *)&priv->r_buf[priv->r_buf_start], count);
+ priv->r_buf_start += count / 2;
+ ret = count;
+ } else if ((BUFFER_LEN - priv->r_buf_start + priv->r_buf_end) * 2 >= count) {
+ result = copy_to_user(buf, (void *)&priv->r_buf[priv->r_buf_start], (BUFFER_LEN - priv->r_buf_start) * 2);
+ result = copy_to_user(buf + (BUFFER_LEN - priv->r_buf_start) * 2, (void *)priv->r_buf, count - (BUFFER_LEN - priv->r_buf_start) * 2);
+ priv->r_buf_start = BUFFER_LEN - priv->r_buf_start + priv->r_buf_end - count / 2;
+ priv->r_buf_round++;
+ ret = count;
+ } else {
+ result = copy_to_user(buf, (void *)&priv->r_buf[priv->r_buf_start], (BUFFER_LEN - priv->r_buf_start) * 2);
+ result = copy_to_user(buf + (BUFFER_LEN - priv->r_buf_start) * 2, (void *)priv->r_buf, priv->r_buf_end * 2);
+ priv->r_buf_start = priv->r_buf_end;
+ priv->r_buf_round++;
+ ret = (BUFFER_LEN - priv->r_buf_start + priv->r_buf_end) * 2;
+ }
+ } else {
+ if ((priv->r_buf_end - priv->r_buf_start) * 2 > count) {
+ ret = count;
+ } else {
+ ret = (priv->r_buf_end - priv->r_buf_start) * 2;
+ }
+ result = copy_to_user(buf, (void *)&priv->r_buf[priv->r_buf_start], ret);
+ priv->r_buf_start += ret / 2;
+ }
+
+ if (priv->r_buf_start >= BUFFER_LEN) {
+ priv->r_buf_start = 0;
+ priv->r_buf_round++;
+ }
+ }
+
+ spin_unlock(&priv->r_buf_lock);
+
+ return ret;
+}
+
+static ssize_t
+spi_slave_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *f_pos)
+{
+ ssize_t ret = 0;
+ struct ambarella_spi_slave *priv;
+ int txflr, i, result;
+
+ priv = (struct ambarella_spi_slave *)filp->private_data;
+
+ spin_lock(&priv->w_buf_lock);
+
+ if (!priv->w_buf_full) {
+ if (priv->w_buf_empty) {
+ priv->w_buf_empty = 0;
+
+ if (count < 2 * BUFFER_LEN) {
+ ret = count;
+ priv->w_buf_start = 0;
+ priv->w_buf_end = count / 2;
+ priv->w_buf_round = 0;
+ result = copy_from_user(priv->w_buf, buf, ret);
+ } else {
+ ret = 2 * BUFFER_LEN;
+ priv->w_buf_full = 1;
+ priv->w_buf_start = 0;
+ priv->w_buf_end = 0;
+ priv->w_buf_round = 1;
+ result = copy_from_user(priv->w_buf, buf, ret);
+ }
+ } else {
+ if (priv->w_buf_round & 0x01) {
+ if (count < (priv->w_buf_start - priv->w_buf_end) * 2) {
+ ret = count;
+ result = copy_from_user((void *)&priv->w_buf[priv->w_buf_end], buf, ret);
+ priv->w_buf_end += ret / 2;
+ } else {
+ ret = (priv->w_buf_start - priv->w_buf_end) * 2;
+ result = copy_from_user(&priv->w_buf[priv->w_buf_end], buf, ret);
+ priv->w_buf_end = priv->w_buf_start;
+ priv->w_buf_full = 1;
+ }
+ } else {
+ if (count <= (BUFFER_LEN - priv->w_buf_end) * 2) {
+ ret = count;
+ result = copy_from_user((void *)&priv->w_buf[priv->w_buf_end], buf, ret);
+ priv->w_buf_end += ret / 2;
+ } else if (count < (BUFFER_LEN + priv->w_buf_start - priv->w_buf_end) * 2) {
+ ret = count;
+ result = copy_from_user((void *)&priv->w_buf[priv->w_buf_end], buf, (BUFFER_LEN - priv->w_buf_end) * 2);
+ result = copy_from_user((void *)priv->w_buf, buf + (BUFFER_LEN - priv->w_buf_end) * 2, ret - (BUFFER_LEN - priv->w_buf_end) * 2);
+ priv->w_buf_end = priv->w_buf_end + ret / 2 - BUFFER_LEN;
+ priv->w_buf_round++;
+ } else {
+ ret = (BUFFER_LEN + priv->w_buf_start - priv->w_buf_end) * 2;
+ result = copy_from_user((void *)&priv->w_buf[priv->w_buf_end], buf, (BUFFER_LEN - priv->w_buf_end) * 2);
+ result = copy_from_user((void *)priv->w_buf, buf + (BUFFER_LEN - priv->w_buf_end) * 2, ret - (BUFFER_LEN - priv->w_buf_end) * 2);
+ priv->w_buf_end = priv->w_buf_start;
+ priv->w_buf_round++;
+ priv->w_buf_full = 1;
+ }
+ }
+ }
+
+ if (priv->w_buf_end >= BUFFER_LEN) {
+ priv->w_buf_end = 0;
+ priv->w_buf_round++;
+ }
+ }
+
+ txflr = 16 - amba_readl(priv->regbase + SPI_TXFLR_OFFSET);
+ priv->w_buf_full = 0;
+ if (priv->w_buf_round & 0x01) {
+ if (BUFFER_LEN - priv->w_buf_start > txflr) {
+ for (i = 0; i < txflr; i++) {
+ amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[priv->w_buf_start++]);
+ }
+ } else if (BUFFER_LEN - priv->w_buf_start + priv->w_buf_end > txflr) {
+ for (i = 0; i < BUFFER_LEN - priv->w_buf_start; i++) {
+ amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[priv->w_buf_start++]);
+ }
+ for (i = 0; i < txflr + priv->w_buf_start - BUFFER_LEN; i++) {
+ amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[i]);
+ }
+ priv->w_buf_start = i + 1;
+ priv->w_buf_round++;
+ } else {
+ for (i = 0; i < BUFFER_LEN - priv->w_buf_start; i++) {
+ amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[priv->w_buf_start++]);
+ }
+ for (i = 0; i < priv->w_buf_end; i++) {
+ amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[i]);
+ }
+ for (i = 0; i < txflr + priv->w_buf_start - BUFFER_LEN - priv->w_buf_end; i++) {
+ amba_writel(priv->regbase + SPI_DR_OFFSET, DUMMY_DATA);
+ }
+ priv->w_buf_empty = 1;
+ }
+ } else {
+ if (priv->w_buf_end - priv->w_buf_start > txflr) {
+ for (i = 0; i < txflr; i++) {
+ amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[priv->w_buf_start++]);
+ }
+ } else {
+ for (i = 0; i < priv->w_buf_end - priv->w_buf_start; i++) {
+ amba_writel(priv->regbase + SPI_DR_OFFSET, priv->w_buf[priv->w_buf_start++]);
+ }
+ for (i = 0; i < txflr - priv->w_buf_end + priv->w_buf_start; i++) {
+ amba_writel(priv->regbase + SPI_DR_OFFSET, DUMMY_DATA);
+ }
+ priv->w_buf_empty = 1;
+ }
+ }
+
+ spin_unlock(&priv->w_buf_lock);
+
+ return ret;
+}
+
+long spi_slave_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ int err = -ENOIOCTLCMD;
+
+ switch(cmd)
+ {
+ default:
+ break;
+ }
+
+ return err;
+}
+
+static int spi_slave_release(struct inode *inode, struct file *filp)
+{
+ int ret = 0;
+ struct ambarella_spi_slave *priv;
+
+ priv = (struct ambarella_spi_slave *)filp->private_data;
+
+ mutex_lock(&priv->um_mtx);
+ if (priv->count) {
+ priv->count--;
+ }
+ mutex_unlock(&priv->um_mtx);
+
+ return ret;
+}
+
+static struct file_operations spi_slave_fops = {
+ .open = spi_slave_open,
+ .read = spi_slave_read,
+ .write = spi_slave_write,
+ .unlocked_ioctl = spi_slave_ioctl,
+ .release = spi_slave_release,
+};
+
+static int ambarella_spi_slave_probe(struct platform_device *pdev)
+{
+ struct ambarella_spi_slave *priv = NULL;
+ struct resource *res;
+ int irq, i, rval = 0;
+ int major_id = 0;
+ void __iomem *reg;
+
+ /* Get Base Address */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "get mem resource failed\n");
+ return -ENOENT;
+ }
+
+ reg = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!reg) {
+ dev_err(&pdev->dev, "devm_ioremap() failed\n");
+ return -ENOMEM;
+ }
+
+ /* Get IRQ NO. */
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "get irq failed\n");
+ return -ENOENT;
+ }
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv) {
+ dev_err(&pdev->dev, "no memory\n");
+ return -ENOMEM;
+ }
+
+ priv->regbase = reg;
+
+ priv->mode = 3;
+ priv->bpw = 16;
+
+ priv->r_buf_empty = 1;
+ priv->r_buf_full = 0;
+ priv->w_buf_empty = 1;
+ priv->w_buf_full = 0;
+
+ spin_lock_init(&priv->r_buf_lock);
+ spin_lock_init(&priv->w_buf_lock);
+ mutex_init(&priv->um_mtx);
+
+ ambarella_spi_slave_inithw(priv);
+
+ /* Request IRQ */
+ rval = devm_request_irq(&pdev->dev, irq, ambarella_spi_slave_isr,
+ IRQF_TRIGGER_HIGH, dev_name(&pdev->dev), priv);
+ if (rval) {
+ rval = -EIO;
+ goto ambarella_spi_slave_probe_exit;
+ }
+
+ pdev->id = amb_slave_id++;
+ sprintf(priv->dev_name, "slave_spi%d", pdev->id);
+ major_id = register_chrdev(0, priv->dev_name, &spi_slave_fops);
+ if (major_id <= 0) {
+ rval = -EIO;
+ printk("Error: %s: Unable to get major number\n", __FILE__);
+ goto ambarella_spi_slave_probe_exit;
+ }
+
+ priv->major = major_id;
+
+ priv->psClass = class_create(THIS_MODULE, priv->dev_name);
+ if (IS_ERR(priv->psClass)) {
+ rval = -EIO;
+ printk("Error: %s: Unable to create class\n", __FILE__);
+ goto ambarella_spi_slave_probe_exit;
+ }
+
+ priv->psDev = device_create(priv->psClass, NULL, MKDEV(major_id, 0),
+ priv, priv->dev_name);
+ if (IS_ERR(priv->psDev)) {
+ rval = -EIO;
+ printk("Error: %s: Unable to create device\n", __FILE__);
+ goto ambarella_spi_slave_probe_exit;
+ }
+
+ platform_set_drvdata(pdev, priv);
+
+ if (pdev->id < MAX_SPI_SLAVES) {
+ mutex_lock(&g_mtx);
+ priv_array[pdev->id] = priv;
+ mutex_unlock(&g_mtx);
+ } else {
+ rval = -EIO;
+ printk("Error: %s: platform device id %d is greater than %d\n",
+ __FILE__, pdev->id, MAX_SPI_SLAVES - 1);
+ goto ambarella_spi_slave_probe_exit;
+ }
+
+ dev_info(&pdev->dev, "Ambarella SPI Slave Controller %d created!\n", pdev->id);
+
+ amba_writel(priv->regbase + SPI_SSIENR_OFFSET, 1);
+ for (i = 0; i < 16; i++) {
+ amba_writel(priv->regbase + SPI_DR_OFFSET, i);
+ }
+
+ return 0;
+
+ambarella_spi_slave_probe_exit:
+ if (rval < 0) {
+ if (priv->psDev) {
+ device_destroy(priv->psClass, MKDEV(major_id, 0));
+ }
+ if (priv->psClass) {
+ class_destroy(priv->psClass);
+ }
+ if (major_id > 0) {
+ unregister_chrdev(major_id, priv->dev_name);
+ }
+ }
+
+ return rval;
+}
+
+static int ambarella_spi_slave_remove(struct platform_device *pdev)
+{
+ struct ambarella_spi_slave *priv;
+
+ priv = platform_get_drvdata(pdev);
+
+ mutex_lock(&g_mtx);
+ priv_array[pdev->id] = NULL;
+ mutex_unlock(&g_mtx);
+
+ mutex_lock(&priv->um_mtx);
+
+ if (priv->psDev) {
+ device_destroy(priv->psClass, MKDEV(priv->major, 0));
+ }
+ if (priv->psClass) {
+ class_destroy(priv->psClass);
+ }
+ if (priv->major > 0) {
+ unregister_chrdev(priv->major, priv->dev_name);
+ }
+
+ mutex_unlock(&priv->um_mtx);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int ambarella_spi_slave_suspend_noirq(struct device *dev)
+{
+ return 0;
+}
+
+static int ambarella_spi_slave_resume_noirq(struct device *dev)
+{
+ return 0;
+}
+
+static const struct dev_pm_ops ambarella_spi_slave_dev_pm_ops = {
+ .suspend_noirq = ambarella_spi_slave_suspend_noirq,
+ .resume_noirq = ambarella_spi_slave_resume_noirq,
+};
+#endif
+
+static const struct of_device_id ambarella_spi_slave_dt_ids[] = {
+ {.compatible = "ambarella,spi-slave", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ambarella_spi_slave_dt_ids);
+
+static struct platform_driver ambarella_spi_slave_driver = {
+ .probe = ambarella_spi_slave_probe,
+ .remove = ambarella_spi_slave_remove,
+ .driver = {
+ .name = "ambarella-spi-slave",
+ .owner = THIS_MODULE,
+ .of_match_table = ambarella_spi_slave_dt_ids,
+#ifdef CONFIG_PM
+ .pm = &ambarella_spi_slave_dev_pm_ops,
+#endif
+ },
+};
+
+static int __init ambarella_spi_slave_init(void)
+{
+ return platform_driver_register(&ambarella_spi_slave_driver);
+}
+
+static void __exit ambarella_spi_slave_exit(void)
+{
+ platform_driver_unregister(&ambarella_spi_slave_driver);
+}
+
+subsys_initcall(ambarella_spi_slave_init);
+module_exit(ambarella_spi_slave_exit);
+
+MODULE_DESCRIPTION("Ambarella Media Processor SPI Slave Controller");
+MODULE_AUTHOR("Zhenwu Xue, <zwxue@ambarella.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 7e7006fd..72a14c9f 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -11,6 +11,22 @@ source "drivers/tty/serial/8250/Kconfig"
comment "Non-8250 serial port support"
+config SERIAL_AMBARELLA
+ tristate "Ambarella Media Soc serial port support"
+ depends on PLAT_AMBARELLA
+ select SERIAL_CORE
+ help
+ If you have a machine based on an Ambarella Media SoC you
+ can enable its onboard serial ports by enabling this option.
+
+config SERIAL_AMBARELLA_CONSOLE
+ bool "Console on Ambarella Media SoC serial port"
+ depends on SERIAL_AMBARELLA=y
+ select SERIAL_CORE_CONSOLE
+ help
+ If you have enabled the serial port on the Ambarella Media SoC
+ you can make it the console by answering Y to this option.
+
config SERIAL_AMBA_PL010
tristate "ARM AMBA PL010 serial port support"
depends on ARM_AMBA && (BROKEN || !ARCH_VERSATILE)
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index eedfec40..bf6588d3 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -2,6 +2,8 @@
# Makefile for the kernel serial device drivers.
#
+obj-$(CONFIG_SERIAL_AMBARELLA) += ambarella_uart.o
+
obj-$(CONFIG_SERIAL_CORE) += serial_core.o
obj-$(CONFIG_SERIAL_21285) += 21285.o
diff --git a/drivers/tty/serial/ambarella_uart.c b/drivers/tty/serial/ambarella_uart.c
new file mode 100644
index 00000000..768a7e68
--- /dev/null
+++ b/drivers/tty/serial/ambarella_uart.c
@@ -0,0 +1,1529 @@
+/*
+ * drivers/tty/serial/ambarella_uart.c
+ *
+ * Author: Anthony Ginger <hfjiang@ambarella.com>
+ *
+ * Copyright (C) 2004-2011, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#if defined(CONFIG_SERIAL_AMBARELLA_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/clk.h>
+#include <linux/syscore_ops.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/serial_reg.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/delay.h>
+#include <mach/hardware.h>
+#include <plat/clk.h>
+#include <plat/uart.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmapool.h>
+#include <plat/dma.h>
+#include <linux/slab.h>
+
+#define AMBA_UART_RX_DMA_BUFFER_SIZE 4096
+#define AMBA_UART_MIN_DMA 16
+#define AMBA_UART_LSR_ANY (UART_LSR_OE | UART_LSR_BI |UART_LSR_PE | UART_LSR_FE)
+
+#define AMBARELLA_UART_RESET_FLAG 0 /* bit 0 */
+
+struct ambarella_uart_port {
+ struct uart_port port;
+ struct clk *uart_pll;
+ unsigned long flags;
+ u32 msr_used : 1;
+ u32 tx_fifo_fix : 1;
+ u32 less_reg : 1;
+ u32 txdma_used:1;
+ u32 rxdma_used:1;
+ u32 mcr;
+ u32 c_cflag;
+ /* following are for dma transfer */
+ struct dma_chan *rx_dma_chan;
+ struct dma_chan *tx_dma_chan;
+ unsigned char *rx_dma_buf_virt;
+ unsigned char *tx_dma_buf_virt;
+ dma_addr_t rx_dma_buf_phys;
+ dma_addr_t tx_dma_buf_phys;
+ dma_addr_t buf_phys_a;
+ dma_addr_t buf_phys_b;
+ unsigned char *buf_virt_a;
+ unsigned char *buf_virt_b;
+ bool use_buf_b;
+ struct dma_async_tx_descriptor *tx_dma_desc;
+ struct dma_async_tx_descriptor *rx_dma_desc;
+ dma_cookie_t tx_cookie;
+ dma_cookie_t rx_cookie;
+ int tx_bytes_requested;
+ int rx_bytes_requested;
+ int tx_in_progress;
+};
+
+static struct ambarella_uart_port ambarella_port[UART_INSTANCES];
+
+static void __serial_ambarella_stop_tx(struct uart_port *port, u32 tx_fifo_fix)
+{
+ u32 ier, iir;
+
+ if (tx_fifo_fix) {
+ ier = amba_readl(port->membase + UART_IE_OFFSET);
+ if ((ier & UART_IE_PTIME) != UART_IE_PTIME)
+ amba_writel(port->membase + UART_IE_OFFSET,
+ ier | (UART_IE_PTIME | UART_IE_ETBEI));
+
+ iir = amba_readl(port->membase + UART_II_OFFSET);
+ amba_writel(port->membase + UART_IE_OFFSET,
+ ier & ~(UART_IE_PTIME | UART_IE_ETBEI));
+ (void)(iir);
+ } else {
+ amba_clrbitsl(port->membase + UART_IE_OFFSET, UART_IE_ETBEI);
+ }
+}
+
+static u32 __serial_ambarella_read_ms(struct uart_port *port, u32 tx_fifo_fix)
+{
+ u32 ier, ms;
+
+ if (tx_fifo_fix) {
+ ier = amba_readl(port->membase + UART_IE_OFFSET);
+ if ((ier & UART_IE_EDSSI) != UART_IE_EDSSI)
+ amba_writel(port->membase + UART_IE_OFFSET,
+ ier | UART_IE_EDSSI);
+
+ ms = amba_readl(port->membase + UART_MS_OFFSET);
+ if ((ier & UART_IE_EDSSI) != UART_IE_EDSSI)
+ amba_writel(port->membase + UART_IE_OFFSET, ier);
+ } else {
+ ms = amba_readl(port->membase + UART_MS_OFFSET);
+ }
+
+ return ms;
+}
+
+static void __serial_ambarella_enable_ms(struct uart_port *port)
+{
+ amba_setbitsl(port->membase + UART_IE_OFFSET, UART_IE_EDSSI);
+}
+
+static void __serial_ambarella_disable_ms(struct uart_port *port)
+{
+ amba_clrbitsl(port->membase + UART_IE_OFFSET, UART_IE_EDSSI);
+}
+
+static inline void wait_for_tx(struct uart_port *port)
+{
+ u32 ls;
+
+ ls = amba_readl(port->membase + UART_LS_OFFSET);
+ while ((ls & UART_LS_TEMT) != UART_LS_TEMT) {
+ cpu_relax();
+ ls = amba_readl(port->membase + UART_LS_OFFSET);
+ }
+}
+
+static inline void wait_for_rx(struct uart_port *port)
+{
+ u32 ls;
+
+ ls = amba_readl(port->membase + UART_LS_OFFSET);
+ while ((ls & UART_LS_DR) != UART_LS_DR) {
+ cpu_relax();
+ ls = amba_readl(port->membase + UART_LS_OFFSET);
+ }
+}
+
+static inline int tx_fifo_is_full(struct uart_port *port)
+{
+ return !(amba_readl(port->membase + UART_US_OFFSET) & UART_US_TFNF);
+}
+
+/* ==========================================================================*/
+static void serial_ambarella_hw_setup(struct uart_port *port)
+{
+ struct ambarella_uart_port *amb_port;
+
+ amb_port = (struct ambarella_uart_port *)(port->private_data);
+
+ if (!test_and_set_bit(AMBARELLA_UART_RESET_FLAG, &amb_port->flags)) {
+ clk_set_rate(amb_port->uart_pll, ambarella_clk_get_ref_freq());
+ port->uartclk = clk_get_rate(amb_port->uart_pll);
+ /* reset the whole UART only once */
+ amba_writel(port->membase + UART_SRR_OFFSET, 0x01);
+ mdelay(1);
+ amba_writel(port->membase + UART_SRR_OFFSET, 0x00);
+ }
+
+ amba_writel(port->membase + UART_IE_OFFSET,
+ DEFAULT_AMBARELLA_UART_IER | UART_IE_PTIME);
+ amba_writel(port->membase + UART_FC_OFFSET,
+ UART_FC_FIFOE | UART_FC_RX_2_TO_FULL |
+ UART_FC_TX_EMPTY | UART_FC_XMITR | UART_FC_RCVRR);
+ amba_writel(port->membase + UART_IE_OFFSET,
+ DEFAULT_AMBARELLA_UART_IER);
+
+ if (amb_port->txdma_used || amb_port->rxdma_used) {
+ /* we must use 14bytes as trigger, because if we use 8bytes, FIFO may
+ * be empty due to dma burst size is also set to 8bytes before dma complete,
+ * in this case, if FIFO is empty, but no more data is received, timeout irq
+ * can't be trigged after, we don't have chance to push the data that dma has
+ * transfered any more.
+ */
+ amba_writel(port->membase + UART_FC_OFFSET,
+ UART_FC_FIFOE | UART_FC_RX_2_TO_FULL |
+ UART_FC_TX_EMPTY | UART_FC_XMITR |
+ UART_FC_RCVRR |UART_FCR_DMA_SELECT);
+ amba_writel(port->membase + UART_DMAE_OFFSET,
+ (amb_port->txdma_used << 1) | amb_port->rxdma_used);
+ }
+}
+
+static inline void serial_ambarella_receive_chars(struct uart_port *port,
+ u32 tmo)
+{
+ u32 ch, flag, ls;
+ int max_count;
+
+ ls = amba_readl(port->membase + UART_LS_OFFSET);
+ max_count = port->fifosize;
+
+ do {
+ flag = TTY_NORMAL;
+ if (unlikely(ls & (UART_LS_BI | UART_LS_PE |
+ UART_LS_FE | UART_LS_OE))) {
+ if (ls & UART_LS_BI) {
+ ls &= ~(UART_LS_FE | UART_LS_PE);
+ port->icount.brk++;
+
+ if (uart_handle_break(port))
+ goto ignore_char;
+ }
+ if (ls & UART_LS_FE)
+ port->icount.frame++;
+ if (ls & UART_LS_PE)
+ port->icount.parity++;
+ if (ls & UART_LS_OE)
+ port->icount.overrun++;
+
+ ls &= port->read_status_mask;
+
+ if (ls & UART_LS_BI)
+ flag = TTY_BREAK;
+ else if (ls & UART_LS_FE)
+ flag = TTY_FRAME;
+ else if (ls & UART_LS_PE)
+ flag = TTY_PARITY;
+ else if (ls & UART_LS_OE)
+ flag = TTY_OVERRUN;
+
+ if (ls & UART_LS_OE) {
+ printk(KERN_DEBUG "%s: OVERFLOW\n", __func__);
+ }
+ }
+
+ if (likely(ls & UART_LS_DR)) {
+ ch = amba_readl(port->membase + UART_RB_OFFSET);
+ port->icount.rx++;
+ tmo = 0;
+
+ if (uart_handle_sysrq_char(port, ch))
+ goto ignore_char;
+
+ uart_insert_char(port, ls, UART_LS_OE, ch, flag);
+ } else {
+ if (tmo) {
+ ch = amba_readl(port->membase + UART_RB_OFFSET);
+ /* printk(KERN_DEBUG "False TMO get %d\n", ch); */
+ }
+ }
+
+ignore_char:
+ ls = amba_readl(port->membase + UART_LS_OFFSET);
+ } while ((ls & UART_LS_DR) && (max_count-- > 0));
+
+ spin_unlock(&port->lock);
+ tty_flip_buffer_push(&port->state->port);
+ spin_lock(&port->lock);
+}
+
+static void serial_ambarella_transmit_chars(struct uart_port *port)
+{
+ struct circ_buf *xmit = &port->state->xmit;
+ struct ambarella_uart_port *amb_port;
+ int count;
+
+ amb_port = (struct ambarella_uart_port *)(port->private_data);
+
+ if (port->x_char) {
+ amba_writel(port->membase + UART_TH_OFFSET, port->x_char);
+ port->icount.tx++;
+ port->x_char = 0;
+ return;
+ }
+
+ if (uart_tx_stopped(port) || uart_circ_empty(xmit)) {
+ __serial_ambarella_stop_tx(port, amb_port->tx_fifo_fix);
+ return;
+ }
+
+ count = port->fifosize;
+ while (count-- > 0) {
+ if (!amb_port->less_reg && tx_fifo_is_full(port))
+ break;
+ amba_writel(port->membase + UART_TH_OFFSET, xmit->buf[xmit->tail]);
+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+ port->icount.tx++;
+ if (uart_circ_empty(xmit))
+ break;
+ }
+
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(port);
+ if (uart_circ_empty(xmit))
+ __serial_ambarella_stop_tx(port, amb_port->tx_fifo_fix);
+}
+
+static inline void serial_ambarella_check_modem_status(struct uart_port *port)
+{
+ struct ambarella_uart_port *amb_port;
+ u32 ms;
+
+ amb_port = (struct ambarella_uart_port *)(port->private_data);
+
+ if (amb_port->msr_used) {
+ ms = __serial_ambarella_read_ms(port, amb_port->tx_fifo_fix);
+
+ if (ms & UART_MS_RI)
+ port->icount.rng++;
+ if (ms & UART_MS_DSR)
+ port->icount.dsr++;
+ if (ms & UART_MS_DCTS)
+ uart_handle_cts_change(port, (ms & UART_MS_CTS));
+ if (ms & UART_MS_DDCD)
+ uart_handle_dcd_change(port, (ms & UART_MS_DCD));
+
+ wake_up_interruptible(&port->state->port.delta_msr_wait);
+ }
+}
+
+static char serial_ambarella_decode_rx_error(struct ambarella_uart_port *amb_port,
+ unsigned long lsr)
+{
+ char flag = TTY_NORMAL;
+
+ if (unlikely(lsr & AMBA_UART_LSR_ANY)) {
+ if (lsr & UART_LSR_OE) {
+ /* Overrrun error */
+ flag |= TTY_OVERRUN;
+ amb_port->port.icount.overrun++;
+ dev_err(amb_port->port.dev, "Got overrun errors\n");
+ } else if (lsr & UART_LSR_PE) {
+ /* Parity error */
+ flag |= TTY_PARITY;
+ amb_port->port.icount.parity++;
+ dev_err(amb_port->port.dev, "Got Parity errors\n");
+ } else if (lsr & UART_LSR_FE) {
+ flag |= TTY_FRAME;
+ amb_port->port.icount.frame++;
+ dev_err(amb_port->port.dev, "Got frame errors\n");
+ } else if (lsr & UART_LSR_BI) {
+ dev_err(amb_port->port.dev, "Got Break\n");
+ amb_port->port.icount.brk++;
+ /* If FIFO read error without any data, reset Rx FIFO */
+ if (!(lsr & UART_LSR_DR) && (lsr & UART_LSR_FIFOE))
+ amba_writel(amb_port->port.membase + UART_SRR_OFFSET,
+ UART_FCR_CLEAR_RCVR);
+ }
+ }
+ return flag;
+}
+
+static void serial_ambarella_handle_rx_pio(struct ambarella_uart_port *amb_port,
+ struct tty_port *tty)
+{
+ do {
+ char flag = TTY_NORMAL;
+ unsigned long lsr = 0;
+ unsigned char ch;
+
+ lsr = amba_readl(amb_port->port.membase + UART_LS_OFFSET);
+ if (!(lsr & UART_LS_DR))
+ break;
+
+ flag = serial_ambarella_decode_rx_error(amb_port, lsr);
+ ch = (unsigned char) amba_readl(amb_port->port.membase + UART_RB_OFFSET);
+ amb_port->port.icount.rx++;
+
+ if (!uart_handle_sysrq_char(&amb_port->port, ch) && tty)
+ tty_insert_flip_char(tty, ch, flag);
+ } while (1);
+
+ return;
+}
+
+static void serial_ambarella_copy_rx_to_tty(struct ambarella_uart_port *amb_port,
+ struct tty_port *tty, int count);
+static int serial_ambarella_start_rx_dma(struct ambarella_uart_port *amb_port);
+
+static void serial_ambarella_dma_rx_irq(struct ambarella_uart_port *amb_port)
+{
+ struct tty_port *port = &amb_port->port.state->port;
+ struct tty_struct *tty = tty_port_tty_get(&amb_port->port.state->port);
+ struct dma_tx_state state;
+ size_t pending;
+
+ dmaengine_tx_status(amb_port->rx_dma_chan, amb_port->rx_cookie, &state);
+ dmaengine_terminate_all(amb_port->rx_dma_chan);
+
+ pending = amb_port->rx_bytes_requested - state.residue;
+ BUG_ON(pending > AMBA_UART_RX_DMA_BUFFER_SIZE);
+
+ /* switch the rx buffer */
+ amb_port->use_buf_b = !amb_port->use_buf_b;
+
+ serial_ambarella_start_rx_dma(amb_port);
+
+ serial_ambarella_copy_rx_to_tty(amb_port, port, pending);
+
+ serial_ambarella_handle_rx_pio(amb_port, port);
+
+ if (tty) {
+ tty_flip_buffer_push(port);
+ tty_kref_put(tty);
+ }
+}
+
+static void serial_ambarella_start_tx(struct uart_port *port);
+
+static irqreturn_t serial_ambarella_irq(int irq, void *dev_id)
+{
+ struct uart_port *port = dev_id;
+ int rval = IRQ_HANDLED;
+ u32 ii;
+ unsigned long flags;
+
+ struct ambarella_uart_port *amb_port;
+ amb_port = (struct ambarella_uart_port *)(port->private_data);
+
+ spin_lock_irqsave(&port->lock, flags);
+
+ ii = amba_readl(port->membase + UART_II_OFFSET);
+ switch (ii & 0x0F) {
+ case UART_II_MODEM_STATUS_CHANGED:
+ serial_ambarella_check_modem_status(port);
+ break;
+
+ case UART_II_THR_EMPTY:
+ if (amb_port->txdma_used)
+ serial_ambarella_start_tx(port);
+ else
+ serial_ambarella_transmit_chars(port);
+ break;
+
+ case UART_II_RCV_STATUS:
+ case UART_II_RCV_DATA_AVAIL:
+ serial_ambarella_receive_chars(port, 0);
+ break;
+ case UART_II_CHAR_TIMEOUT:
+ if (amb_port->rxdma_used){
+ struct ambarella_uart_port *amb_port;
+ amb_port = (struct ambarella_uart_port *)(port->private_data);
+ serial_ambarella_dma_rx_irq(amb_port);
+ } else {
+ serial_ambarella_receive_chars(port, 1);
+ }
+ break;
+
+ case UART_II_NO_INT_PENDING:
+ break;
+ default:
+ printk(KERN_DEBUG "%s: 0x%x\n", __func__, ii);
+ break;
+ }
+
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ return rval;
+}
+
+/* ==========================================================================*/
+static void serial_ambarella_enable_ms(struct uart_port *port)
+{
+ __serial_ambarella_enable_ms(port);
+}
+
+static void serial_ambarella_start_next_tx(struct ambarella_uart_port *amb_port);
+
+static void serial_ambarella_tx_dma_complete(void *args)
+{
+ struct ambarella_uart_port *amb_port = args;
+ struct circ_buf *xmit = &amb_port->port.state->xmit;
+ struct dma_tx_state state;
+ unsigned long flags;
+ int count;
+
+ dmaengine_tx_status(amb_port->tx_dma_chan, amb_port->tx_cookie, &state);
+ count = amb_port->tx_bytes_requested - state.residue;
+ spin_lock_irqsave(&amb_port->port.lock, flags);
+ xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1);
+ amb_port->tx_in_progress = 0;
+ amb_port->port.icount.tx += count;
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(&amb_port->port);
+ serial_ambarella_start_next_tx(amb_port);
+ spin_unlock_irqrestore(&amb_port->port.lock, flags);
+}
+
+static int serial_ambarella_start_tx_dma(struct ambarella_uart_port *amb_port,
+ unsigned long count)
+{
+ struct circ_buf *xmit = &amb_port->port.state->xmit;
+ dma_addr_t tx_phys_addr;
+ int tx_bytes;
+
+ dma_sync_single_for_device(amb_port->port.dev, amb_port->tx_dma_buf_phys,
+ UART_XMIT_SIZE, DMA_TO_DEVICE);
+
+ tx_bytes = count & ~(0xF);
+ tx_phys_addr = amb_port->tx_dma_buf_phys + xmit->tail;
+ amb_port->tx_dma_desc = dmaengine_prep_slave_single(amb_port->tx_dma_chan,
+ tx_phys_addr, tx_bytes, DMA_MEM_TO_DEV,
+ DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_SRC_UNMAP |
+ DMA_COMPL_SKIP_DEST_UNMAP | DMA_CTRL_ACK);
+ if (!amb_port->tx_dma_desc) {
+ dev_err(amb_port->port.dev, "Not able to get desc for Tx\n");
+ return -EIO;
+ }
+
+ amb_port->tx_dma_desc->callback = serial_ambarella_tx_dma_complete;
+ amb_port->tx_dma_desc->callback_param = amb_port;
+ amb_port->tx_bytes_requested = tx_bytes;
+ amb_port->tx_in_progress = 1;
+ amb_port->tx_cookie = dmaengine_submit(amb_port->tx_dma_desc);
+ dma_async_issue_pending(amb_port->tx_dma_chan);
+
+ return 0;
+}
+
+static void serial_ambarella_start_next_tx(struct ambarella_uart_port *amb_port)
+{
+ struct circ_buf *xmit = &amb_port->port.state->xmit;
+ struct uart_port *port;
+ unsigned long tail, count;
+
+ port = &amb_port->port;
+
+ tail = (unsigned long)&xmit->buf[xmit->tail];
+ count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
+ if (!count)
+ return;
+
+ wait_for_tx(port);
+ if (count < AMBA_UART_MIN_DMA)
+ serial_ambarella_transmit_chars(port);
+ else
+ serial_ambarella_start_tx_dma(amb_port, count);
+}
+
+static void serial_ambarella_start_tx(struct uart_port *port)
+{
+ struct ambarella_uart_port *amb_port;
+ struct tty_struct *tty;
+
+ amb_port = (struct ambarella_uart_port *)(port->private_data);
+ tty = tty_port_tty_get(&amb_port->port.state->port);
+
+ amba_setbitsl(port->membase + UART_IE_OFFSET, UART_IE_ETBEI);
+
+ if (amb_port->txdma_used) {
+ if (tty->hw_stopped ||amb_port->tx_in_progress)
+ return;
+ serial_ambarella_start_next_tx(amb_port);
+ } else {
+ /* if FIFO status register is not provided, we have no idea about
+ * the Tx FIFO is full or not, so we need to wait for the Tx Empty
+ * Interrupt comming, then we can start to transfer data. */
+ if (amb_port->less_reg)
+ return;
+
+ serial_ambarella_transmit_chars(port);
+ }
+}
+
+static void serial_ambarella_copy_rx_to_tty(struct ambarella_uart_port *amb_port,
+ struct tty_port *tty, int count)
+{
+ dma_addr_t old_buf_phys;
+ unsigned char *old_buf_virt;
+
+ amb_port->port.icount.rx += count;
+ if (!tty) {
+ dev_err(amb_port->port.dev, "No tty port\n");
+ return;
+ }
+
+ /* use old buffer to copy data to tty, and use new buffer to receive */
+ if (amb_port->use_buf_b) {
+ old_buf_phys = amb_port->buf_phys_a;
+ old_buf_virt = amb_port->buf_virt_a;
+ } else {
+ old_buf_phys = amb_port->buf_phys_b;
+ old_buf_virt = amb_port->buf_virt_b;
+ }
+
+ dma_sync_single_for_cpu(amb_port->port.dev, old_buf_phys,
+ AMBA_UART_RX_DMA_BUFFER_SIZE, DMA_FROM_DEVICE);
+
+ tty_insert_flip_string(tty, old_buf_virt, count);
+}
+
+static void serial_ambarella_rx_dma_complete(void *args)
+{
+ struct ambarella_uart_port *amb_port = args;
+ struct tty_struct *tty = tty_port_tty_get(&amb_port->port.state->port);
+ struct uart_port *u = &amb_port->port;
+ struct tty_port *port = &u->state->port;
+ int count = amb_port->rx_bytes_requested;
+ unsigned long flags;
+
+ /* switch the rx buffer */
+ amb_port->use_buf_b = !amb_port->use_buf_b;
+ serial_ambarella_start_rx_dma(amb_port);
+
+ serial_ambarella_copy_rx_to_tty(amb_port, port, count);
+
+ spin_lock_irqsave(&u->lock, flags);
+ if (tty) {
+ tty_flip_buffer_push(port);
+ tty_kref_put(tty);
+ }
+ spin_unlock_irqrestore(&u->lock, flags);
+}
+
+static int serial_ambarella_start_rx_dma(struct ambarella_uart_port *amb_port)
+{
+ unsigned int count = AMBA_UART_RX_DMA_BUFFER_SIZE;
+
+ if (amb_port->use_buf_b) {
+ amb_port->rx_dma_buf_virt = amb_port->buf_virt_b;
+ amb_port->rx_dma_buf_phys = amb_port->buf_phys_b;
+ } else {
+ amb_port->rx_dma_buf_virt = amb_port->buf_virt_a;
+ amb_port->rx_dma_buf_phys = amb_port->buf_phys_a;
+ }
+
+ amb_port->rx_dma_desc = dmaengine_prep_slave_single(amb_port->rx_dma_chan,
+ amb_port->rx_dma_buf_phys, count, DMA_DEV_TO_MEM,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK| DMA_COMPL_SKIP_SRC_UNMAP |
+ DMA_COMPL_SKIP_DEST_UNMAP);
+
+ if (!amb_port->rx_dma_desc) {
+ dev_err(amb_port->port.dev, "Not able to get desc for Rx\n");
+ return -EIO;
+ }
+
+ amb_port->rx_dma_desc->callback = serial_ambarella_rx_dma_complete;
+ amb_port->rx_dma_desc->callback_param = amb_port;
+ dma_sync_single_for_device(amb_port->port.dev, amb_port->rx_dma_buf_phys,
+ count, DMA_TO_DEVICE);
+ amb_port->rx_bytes_requested = count;
+ amb_port->rx_cookie = dmaengine_submit(amb_port->rx_dma_desc);
+ dma_async_issue_pending(amb_port->rx_dma_chan);
+
+ return 0;
+}
+
+static void serial_ambarella_stop_tx(struct uart_port *port)
+{
+ struct ambarella_uart_port *amb_port;
+
+ amb_port = (struct ambarella_uart_port *)(port->private_data);
+
+ __serial_ambarella_stop_tx(port, amb_port->tx_fifo_fix);
+}
+
+static void serial_ambarella_stop_rx(struct uart_port *port)
+{
+ amba_clrbitsl(port->membase + UART_IE_OFFSET, UART_IE_ERBFI);
+}
+
+static unsigned int serial_ambarella_tx_empty(struct uart_port *port)
+{
+ unsigned int lsr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&port->lock, flags);
+ lsr = amba_readl(port->membase + UART_LS_OFFSET);
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ return ((lsr & (UART_LS_TEMT | UART_LS_THRE)) ==
+ (UART_LS_TEMT | UART_LS_THRE)) ? TIOCSER_TEMT : 0;
+}
+
+static unsigned int serial_ambarella_get_mctrl(struct uart_port *port)
+{
+ struct ambarella_uart_port *amb_port;
+ u32 ms, mctrl = 0;
+
+ amb_port = (struct ambarella_uart_port *)(port->private_data);
+
+ if (amb_port->msr_used) {
+ ms = __serial_ambarella_read_ms(port, amb_port->tx_fifo_fix);
+
+ if (ms & UART_MS_CTS)
+ mctrl |= TIOCM_CTS;
+ if (ms & UART_MS_DSR)
+ mctrl |= TIOCM_DSR;
+ if (ms & UART_MS_RI)
+ mctrl |= TIOCM_RI;
+ if (ms & UART_MS_DCD)
+ mctrl |= TIOCM_CD;
+ }
+
+ return mctrl;
+}
+
+static void serial_ambarella_set_mctrl(struct uart_port *port,
+ unsigned int mctrl)
+{
+ struct ambarella_uart_port *amb_port;
+ u32 mcr, mcr_new = 0;
+
+ amb_port = (struct ambarella_uart_port *)(port->private_data);
+
+ if (amb_port->msr_used) {
+ mcr = amba_readl(port->membase + UART_MC_OFFSET);
+
+ if (mctrl & TIOCM_DTR)
+ mcr_new |= UART_MC_DTR;
+ if (mctrl & TIOCM_RTS)
+ mcr_new |= UART_MC_RTS;
+ if (mctrl & TIOCM_OUT1)
+ mcr_new |= UART_MC_OUT1;
+ if (mctrl & TIOCM_OUT2)
+ mcr_new |= UART_MC_OUT2;
+ if (mctrl & TIOCM_LOOP)
+ mcr_new |= UART_MC_LB;
+
+ mcr_new |= amb_port->mcr;
+ if (mcr_new != mcr) {
+ if ((mcr & UART_MC_AFCE) == UART_MC_AFCE) {
+ mcr &= ~UART_MC_AFCE;
+ amba_writel(port->membase + UART_MC_OFFSET,
+ mcr);
+ }
+ amba_writel(port->membase + UART_MC_OFFSET, mcr_new);
+ }
+ }
+}
+
+static void serial_ambarella_break_ctl(struct uart_port *port, int break_state)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&port->lock, flags);
+ if (break_state != 0)
+ amba_setbitsl(port->membase + UART_LC_OFFSET, UART_LC_BRK);
+ else
+ amba_clrbitsl(port->membase + UART_LC_OFFSET, UART_LC_BRK);
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static bool serial_ambarella_dma_filter(struct dma_chan *chan, void *fparam)
+{
+ int chan_id;
+ bool ret = false;
+
+ chan_id = *(int *)fparam;
+
+ if (ambarella_dma_channel_id(chan) == chan_id)
+ ret = true;
+
+ return ret;
+}
+
+static int serial_ambarella_dma_channel_allocate(struct ambarella_uart_port *amb_port,
+ bool dma_to_memory)
+{
+ struct dma_chan *dma_chan;
+ struct dma_slave_config dma_sconfig;
+ dma_addr_t dma_phys;
+ dma_cap_mask_t mask;
+ unsigned char *dma_buf;
+ int ret, chan_id;
+
+ if (dma_to_memory)
+ chan_id = UART_RX_DMA_CHAN;
+ else
+ chan_id = UART_TX_DMA_CHAN;
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+ dma_chan = dma_request_channel(mask, serial_ambarella_dma_filter, &chan_id);
+ if (!dma_chan) {
+ dev_err(amb_port->port.dev,
+ "Dma channel is not available, will try later\n");
+ return -EPROBE_DEFER;
+ }
+
+ if (dma_to_memory) {
+ /* use double buffer to handle rx */
+ dma_buf = kmalloc(AMBA_UART_RX_DMA_BUFFER_SIZE, GFP_KERNEL);
+ dma_phys = virt_to_phys(dma_buf);
+ if (!dma_buf) {
+ dev_err(amb_port->port.dev,
+ "Not able to allocate the dma buffer a\n");
+ dma_release_channel(dma_chan);
+ return -ENOMEM;
+ }
+
+ amb_port->buf_virt_a = dma_buf;
+ amb_port->buf_phys_a = dma_phys;
+
+ /* buffer b */
+ dma_buf = kmalloc(AMBA_UART_RX_DMA_BUFFER_SIZE, GFP_KERNEL);
+ dma_phys = virt_to_phys(dma_buf);
+ if (!dma_buf) {
+ dev_err(amb_port->port.dev,
+ "Not able to allocate the dma buffer b\n");
+ dma_release_channel(dma_chan);
+ return -ENOMEM;
+ }
+
+ amb_port->buf_virt_b = dma_buf;
+ amb_port->buf_phys_b = dma_phys;
+
+ } else {
+ dma_phys = dma_map_single(amb_port->port.dev,
+ amb_port->port.state->xmit.buf, UART_XMIT_SIZE,
+ DMA_TO_DEVICE);
+ dma_buf = amb_port->port.state->xmit.buf;
+ }
+
+ if (dma_to_memory) {
+ dma_sconfig.src_addr = amb_port->port.mapbase + UART_DMAF_OFFSET;
+ dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+ dma_sconfig.src_maxburst = 8;
+ dma_sconfig.direction = DMA_DEV_TO_MEM;
+ } else {
+ dma_sconfig.dst_addr = amb_port->port.mapbase + UART_DMAF_OFFSET;
+ dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+ dma_sconfig.dst_maxburst = 16;
+ dma_sconfig.direction = DMA_MEM_TO_DEV;
+ }
+
+ ret = dmaengine_slave_config(dma_chan, &dma_sconfig);
+ if (ret < 0) {
+ dev_err(amb_port->port.dev,
+ "Dma slave config failed, err = %d\n", ret);
+ goto scrub;
+ }
+
+ if (dma_to_memory) {
+ amb_port->rx_dma_chan = dma_chan;
+ amb_port->rx_dma_buf_virt = amb_port->buf_virt_a;
+ amb_port->rx_dma_buf_phys = amb_port->buf_phys_a;
+ } else {
+ amb_port->tx_dma_chan = dma_chan;
+ amb_port->tx_dma_buf_virt = dma_buf;
+ amb_port->tx_dma_buf_phys = dma_phys;
+ }
+ return 0;
+
+scrub:
+ dma_release_channel(dma_chan);
+ return ret;
+}
+
+static int serial_ambarella_startup(struct uart_port *port)
+{
+ int rval = 0;
+ struct ambarella_uart_port *amb_port;
+
+ amb_port = (struct ambarella_uart_port *)(port->private_data);
+
+ serial_ambarella_hw_setup(port);
+
+ rval = request_irq(port->irq, serial_ambarella_irq,
+ IRQF_TRIGGER_HIGH, dev_name(port->dev), port);
+
+ if (amb_port->txdma_used) {
+ rval = serial_ambarella_dma_channel_allocate(amb_port, false);
+ if (rval < 0) {
+ dev_err(amb_port->port.dev, "Tx Dma allocation failed, err = %d\n", rval);
+ return -EBUSY;
+ }
+ }
+
+ if (amb_port->rxdma_used) {
+ amb_port->use_buf_b = false;
+
+ rval = serial_ambarella_dma_channel_allocate(amb_port, true);
+ if (rval < 0) {
+ dev_err(amb_port->port.dev, "Rx Dma allocation failed, err = %d\n", rval);
+ return -EBUSY;
+ }
+
+ rval = serial_ambarella_start_rx_dma(amb_port);
+ if (rval < 0) {
+ dev_err(amb_port->port.dev, "Not able to start Rx DMA\n");
+ return rval;
+ }
+ }
+
+ return rval;
+}
+
+static void serial_ambarella_hw_deinit(struct ambarella_uart_port *amb_port)
+{
+ struct uart_port *port = &amb_port->port;
+
+ /* Disable interrupts */
+ amba_writel(port->membase + UART_IE_OFFSET, 0);
+ /* Reset the Rx and Tx FIFOs */
+ amba_writel(port->membase + UART_SRR_OFFSET,
+ UART_FCR_CLEAR_XMIT| UART_FCR_CLEAR_RCVR);
+}
+
+static void serial_ambarella_dma_channel_free(struct ambarella_uart_port *amb_port,
+ bool dma_to_memory)
+{
+ struct dma_chan *dma_chan;
+
+ if (dma_to_memory) {
+ kfree(amb_port->buf_virt_a);
+ kfree(amb_port->buf_virt_b);
+
+ dma_chan = amb_port->rx_dma_chan;
+ amb_port->rx_dma_chan = NULL;
+ amb_port->rx_dma_buf_phys = 0;
+ amb_port->rx_dma_buf_virt = NULL;
+ amb_port->buf_phys_a = 0;
+ amb_port->buf_virt_a = NULL;
+ amb_port->buf_phys_b = 0;
+ amb_port->buf_virt_b = NULL;
+ } else {
+ dma_unmap_single(amb_port->port.dev, amb_port->tx_dma_buf_phys,
+ UART_XMIT_SIZE, DMA_TO_DEVICE);
+ dma_chan = amb_port->tx_dma_chan;
+ amb_port->tx_dma_chan = NULL;
+ amb_port->tx_dma_buf_phys = 0;
+ amb_port->tx_dma_buf_virt = NULL;
+ }
+ dma_release_channel(dma_chan);
+}
+
+static void serial_ambarella_shutdown(struct uart_port *port)
+{
+ struct ambarella_uart_port *amb_port;
+ unsigned long flags;
+
+ amb_port = (struct ambarella_uart_port *)(port->private_data);
+
+ spin_lock_irqsave(&port->lock, flags);
+
+ if (amb_port->txdma_used || amb_port->rxdma_used) {
+ serial_ambarella_hw_deinit(amb_port);
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ if (amb_port->txdma_used) {
+ dmaengine_terminate_all(amb_port->tx_dma_chan);
+ serial_ambarella_dma_channel_free(amb_port, false);
+ amb_port->tx_in_progress = 0;
+ }
+ if (amb_port->rxdma_used) {
+ dmaengine_terminate_all(amb_port->rx_dma_chan);
+ serial_ambarella_dma_channel_free(amb_port, true);
+ }
+
+ spin_lock_irqsave(&port->lock, flags);
+ }
+
+ amba_clrbitsl(port->membase + UART_LC_OFFSET, UART_LC_BRK);
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ free_irq(port->irq, port);
+}
+
+static void serial_ambarella_set_termios(struct uart_port *port,
+ struct ktermios *termios, struct ktermios *old)
+{
+ struct ambarella_uart_port *amb_port;
+ unsigned int baud, quot;
+ u32 lc = 0x0;
+
+ amb_port = (struct ambarella_uart_port *)(port->private_data);
+ amb_port->c_cflag = termios->c_cflag;
+
+ port->uartclk = clk_get_rate(amb_port->uart_pll);
+ switch (termios->c_cflag & CSIZE) {
+ case CS5:
+ lc |= UART_LC_CLS_5_BITS;
+ break;
+ case CS6:
+ lc |= UART_LC_CLS_6_BITS;
+ break;
+ case CS7:
+ lc |= UART_LC_CLS_7_BITS;
+ break;
+ case CS8:
+ default:
+ lc |= UART_LC_CLS_8_BITS;
+ break;
+ }
+
+ if (termios->c_cflag & CSTOPB)
+ lc |= UART_LC_STOP_2BIT;
+ else
+ lc |= UART_LC_STOP_1BIT;
+
+ if (termios->c_cflag & PARENB) {
+ if (termios->c_cflag & PARODD)
+ lc |= (UART_LC_PEN | UART_LC_ODD_PARITY);
+ else
+ lc |= (UART_LC_PEN | UART_LC_EVEN_PARITY);
+ }
+
+ baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
+ quot = uart_get_divisor(port, baud);
+
+ disable_irq(port->irq);
+ uart_update_timeout(port, termios->c_cflag, baud);
+
+ port->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
+ if (termios->c_iflag & INPCK)
+ port->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
+ if (termios->c_iflag & (BRKINT | PARMRK))
+ port->read_status_mask |= UART_LSR_BI;
+
+ port->ignore_status_mask = 0;
+ if (termios->c_iflag & IGNPAR)
+ port->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
+ if (termios->c_iflag & IGNBRK) {
+ port->ignore_status_mask |= UART_LSR_BI;
+ if (termios->c_iflag & IGNPAR)
+ port->ignore_status_mask |= UART_LSR_OE;
+ }
+ if ((termios->c_cflag & CREAD) == 0)
+ port->ignore_status_mask |= UART_LSR_DR;
+
+ if ((termios->c_cflag & CRTSCTS) == 0)
+ amb_port->mcr &= ~UART_MC_AFCE;
+ else
+ amb_port->mcr |= UART_MC_AFCE;
+
+ amba_writel(port->membase + UART_LC_OFFSET, UART_LC_DLAB);
+ amba_writel(port->membase + UART_DLL_OFFSET, quot & 0xff);
+ amba_writel(port->membase + UART_DLH_OFFSET, (quot >> 8) & 0xff);
+ amba_writel(port->membase + UART_LC_OFFSET, lc);
+ if (UART_ENABLE_MS(port, termios->c_cflag))
+ __serial_ambarella_enable_ms(port);
+ else
+ __serial_ambarella_disable_ms(port);
+ serial_ambarella_set_mctrl(port, port->mctrl);
+
+ enable_irq(port->irq);
+}
+
+static void serial_ambarella_pm(struct uart_port *port,
+ unsigned int state, unsigned int oldstate)
+{
+}
+
+static void serial_ambarella_release_port(struct uart_port *port)
+{
+}
+
+static int serial_ambarella_request_port(struct uart_port *port)
+{
+ return 0;
+}
+
+static void serial_ambarella_config_port(struct uart_port *port, int flags)
+{
+}
+
+static int serial_ambarella_verify_port(struct uart_port *port,
+ struct serial_struct *ser)
+{
+ int rval = 0;
+
+ if (ser->type != PORT_UNKNOWN && ser->type != PORT_UART00)
+ rval = -EINVAL;
+ if (port->irq != ser->irq)
+ rval = -EINVAL;
+ if (ser->io_type != SERIAL_IO_MEM)
+ rval = -EINVAL;
+
+ return rval;
+}
+
+static const char *serial_ambarella_type(struct uart_port *port)
+{
+ return "ambuart";
+}
+
+#ifdef CONFIG_CONSOLE_POLL
+static void serial_ambarella_poll_put_char(struct uart_port *port,
+ unsigned char chr)
+{
+ struct ambarella_uart_port *amb_port;
+
+ amb_port = (struct ambarella_uart_port *)(port->private_data);
+ if (!port->suspended) {
+ wait_for_tx(port);
+ amba_writel(port->membase + UART_TH_OFFSET, chr);
+ }
+}
+
+static int serial_ambarella_poll_get_char(struct uart_port *port)
+{
+ struct ambarella_uart_port *amb_port;
+
+ amb_port = (struct ambarella_uart_port *)(port->private_data);
+ if (!port->suspended) {
+ wait_for_rx(port);
+ return amba_readl(port->membase + UART_RB_OFFSET);
+ }
+ return 0;
+}
+#endif
+
+struct uart_ops serial_ambarella_pops = {
+ .tx_empty = serial_ambarella_tx_empty,
+ .set_mctrl = serial_ambarella_set_mctrl,
+ .get_mctrl = serial_ambarella_get_mctrl,
+ .stop_tx = serial_ambarella_stop_tx,
+ .start_tx = serial_ambarella_start_tx,
+ .stop_rx = serial_ambarella_stop_rx,
+ .enable_ms = serial_ambarella_enable_ms,
+ .break_ctl = serial_ambarella_break_ctl,
+ .startup = serial_ambarella_startup,
+ .shutdown = serial_ambarella_shutdown,
+ .set_termios = serial_ambarella_set_termios,
+ .pm = serial_ambarella_pm,
+ .type = serial_ambarella_type,
+ .release_port = serial_ambarella_release_port,
+ .request_port = serial_ambarella_request_port,
+ .config_port = serial_ambarella_config_port,
+ .verify_port = serial_ambarella_verify_port,
+#ifdef CONFIG_CONSOLE_POLL
+ .poll_put_char = serial_ambarella_poll_put_char,
+ .poll_get_char = serial_ambarella_poll_get_char,
+#endif
+};
+
+/* ==========================================================================*/
+#if defined(CONFIG_SERIAL_AMBARELLA_CONSOLE)
+
+static struct uart_driver serial_ambarella_reg;
+static void ambarella_uart_of_enumerate(void);
+
+static void serial_ambarella_console_putchar(struct uart_port *port, int ch)
+{
+ wait_for_tx(port);
+ amba_writel(port->membase + UART_TH_OFFSET, ch);
+}
+
+static void serial_ambarella_console_write(struct console *co,
+ const char *s, unsigned int count)
+{
+ struct uart_port *port;
+ int locked = 1;
+ unsigned long flags;
+
+ port = &ambarella_port[co->index].port;
+
+ if (!port->suspended) {
+ local_irq_save(flags);
+ if (port->sysrq) {
+ locked = 0;
+ } else if (oops_in_progress) {
+ locked = spin_trylock(&port->lock);
+ } else {
+ spin_lock(&port->lock);
+ locked = 1;
+ }
+
+ uart_console_write(port, s, count,
+ serial_ambarella_console_putchar);
+ wait_for_tx(port);
+
+ if (locked)
+ spin_unlock(&port->lock);
+ local_irq_restore(flags);
+ }
+}
+
+static int __init serial_ambarella_console_setup(struct console *co,
+ char *options)
+{
+ struct ambarella_uart_port *amb_port;
+ struct uart_port *port;
+ int baud = 115200, bits = 8, parity = 'n', flow = 'n';
+
+ if (co->index < 0 || co->index >= serial_ambarella_reg.nr)
+ co->index = 0;
+
+ amb_port = &ambarella_port[co->index];
+ amb_port->uart_pll = clk_get(NULL, "gclk_uart");
+
+ port = &ambarella_port[co->index].port;
+ if (!port->membase) {
+ pr_err("No device available for console\n");
+ return -ENODEV;
+ }
+
+ port->ops = &serial_ambarella_pops;
+ port->private_data = &ambarella_port[co->index];
+ port->line = co->index;
+
+ serial_ambarella_hw_setup(port);
+
+ if (options)
+ uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+ return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static struct console serial_ambarella_console = {
+ .name = "ttyS",
+ .write = serial_ambarella_console_write,
+ .device = uart_console_device,
+ .setup = serial_ambarella_console_setup,
+ .flags = CON_PRINTBUFFER | CON_ANYTIME,
+ .index = -1,
+ .data = &serial_ambarella_reg,
+};
+
+#ifdef CONFIG_PM
+/* when no_console_suspend is specified in cmdline, Linux thought the console
+ * would never suspend. But actually we may put system into STR and power off
+ * the SoC, so the console must be initialized when system exit STR.
+ *
+ * NOTE: We MUST ensure that no information will be output via UART until
+ * syscore_resume() is completed, otherwise the UART may be in deadloop.
+ */
+static void serial_ambarella_console_resume(void)
+{
+ struct console *co = &serial_ambarella_console;
+ struct ambarella_uart_port *amb_port;
+ struct uart_port *port;
+ struct ktermios termios;
+
+ if (console_suspend_enabled)
+ return;
+
+ if (co->index < 0 || co->index >= serial_ambarella_reg.nr)
+ return;
+
+ amb_port = &ambarella_port[co->index];
+
+ port = &ambarella_port[co->index].port;
+ if (!port->membase)
+ return;
+
+ clear_bit(AMBARELLA_UART_RESET_FLAG, &amb_port->flags);
+ serial_ambarella_hw_setup(port);
+
+ memset(&termios, 0, sizeof(struct ktermios));
+ termios.c_cflag = amb_port->c_cflag;
+ port->ops->set_termios(port, &termios, NULL);
+}
+
+static struct syscore_ops ambarella_console_syscore_ops = {
+ .resume = serial_ambarella_console_resume,
+};
+#endif
+
+static int __init serial_ambarella_console_init(void)
+{
+ struct device_node *np;
+ const char *name;
+ int id;
+
+ ambarella_uart_of_enumerate();
+
+ name = of_get_property(of_chosen, "linux,stdout-path", NULL);
+ if (name == NULL)
+ return -ENODEV;
+
+ np = of_find_node_by_path(name);
+ if (!np)
+ return -ENODEV;
+
+ id = of_alias_get_id(np, "serial");
+ if (id < 0 || id >= serial_ambarella_reg.nr)
+ return -ENODEV;
+
+ ambarella_port[id].port.membase = of_iomap(np, 0);
+
+ register_console(&serial_ambarella_console);
+
+#ifdef CONFIG_PM
+ register_syscore_ops(&ambarella_console_syscore_ops);
+#endif
+
+ return 0;
+}
+
+console_initcall(serial_ambarella_console_init);
+
+#define AMBARELLA_CONSOLE &serial_ambarella_console
+#else
+#define AMBARELLA_CONSOLE NULL
+#endif
+
+/* ==========================================================================*/
+static struct uart_driver serial_ambarella_reg = {
+ .owner = THIS_MODULE,
+ .driver_name = "ambarella-uart",
+ .dev_name = "ttyS",
+ .major = TTY_MAJOR,
+ .minor = 64,
+ .nr = 0,
+ .cons = AMBARELLA_CONSOLE,
+};
+
+static int serial_ambarella_probe(struct platform_device *pdev)
+{
+ struct ambarella_uart_port *amb_port;
+ struct resource *mem;
+ struct pinctrl *pinctrl;
+ int irq, id, rval = 0;
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem) {
+ dev_err(&pdev->dev, "no mem resource!\n");
+ return -ENODEV;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "no irq resource!\n");
+ return -ENODEV;
+ }
+
+ id = of_alias_get_id(pdev->dev.of_node, "serial");
+ if (id < 0 || id >= serial_ambarella_reg.nr) {
+ dev_err(&pdev->dev, "Invalid uart ID %d!\n", id);
+ return -ENXIO;
+ }
+
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+ if (IS_ERR(pinctrl)) {
+ dev_err(&pdev->dev, "Failed to request pinctrl\n");
+ return PTR_ERR(pinctrl);
+ }
+
+ amb_port = &ambarella_port[id];
+
+ amb_port->uart_pll = clk_get(NULL, "gclk_uart");
+ if (IS_ERR(amb_port->uart_pll)) {
+ dev_err(&pdev->dev, "Get uart clk failed!\n");
+ return PTR_ERR(amb_port->uart_pll);
+ }
+
+ amb_port->mcr = DEFAULT_AMBARELLA_UART_MCR;
+ /* check if using modem status register, available for non-uart0. */
+ if (of_find_property(pdev->dev.of_node, "amb,msr-used", NULL))
+ amb_port->msr_used = 1;
+ else
+ amb_port->msr_used = 0;
+ /* check if workaround for tx fifo is needed */
+ if (of_find_property(pdev->dev.of_node, "amb,tx-fifo-fix", NULL))
+ amb_port->tx_fifo_fix = 1;
+ else
+ amb_port->tx_fifo_fix = 0;
+ /* check if registers like FIFO status register are NOT provided. */
+ if (of_find_property(pdev->dev.of_node, "amb,less-reg", NULL))
+ amb_port->less_reg = 1;
+ else
+ amb_port->less_reg = 0;
+ /* check if using tx dma */
+ if (of_find_property(pdev->dev.of_node, "amb,txdma-used", NULL)) {
+ amb_port->txdma_used = 1;
+ dev_info(&pdev->dev,"Serial[%d] use txdma\n", id);
+ }
+ else
+ amb_port->txdma_used = 0;
+ /* check if using rx dma */
+ if (of_find_property(pdev->dev.of_node, "amb,rxdma-used", NULL)) {
+ amb_port->rxdma_used = 1;
+ dev_info(&pdev->dev,"Serial[%d] use rxdma\n", id);
+ } else {
+ amb_port->rxdma_used = 0;
+ }
+
+ amb_port->port.dev = &pdev->dev;
+ amb_port->port.type = PORT_UART00;
+ amb_port->port.iotype = UPIO_MEM;
+ amb_port->port.fifosize = UART_FIFO_SIZE;
+ amb_port->port.uartclk = clk_get_rate(amb_port->uart_pll);
+ amb_port->port.ops = &serial_ambarella_pops;
+ amb_port->port.private_data = amb_port;
+ amb_port->port.irq = irq;
+ amb_port->port.line = id;
+ amb_port->port.mapbase = mem->start;
+ amb_port->port.membase =
+ devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
+ if (!amb_port->port.membase) {
+ dev_err(&pdev->dev, "can't ioremap UART\n");
+ return -ENOMEM;
+ }
+
+ rval = uart_add_one_port(&serial_ambarella_reg, &amb_port->port);
+ if (rval < 0) {
+ dev_err(&pdev->dev, "failed to add port: %d, %d!\n", id, rval);
+ }
+
+ platform_set_drvdata(pdev, amb_port);
+
+ return rval;
+}
+
+static int serial_ambarella_remove(struct platform_device *pdev)
+{
+ struct ambarella_uart_port *amb_port;
+ int rval = 0;
+
+ amb_port = platform_get_drvdata(pdev);
+ rval = uart_remove_one_port(&serial_ambarella_reg, &amb_port->port);
+ if (rval < 0)
+ dev_err(&pdev->dev, "uart_remove_one_port fail %d!\n", rval);
+
+ dev_notice(&pdev->dev,
+ "Remove Ambarella Media Processor UART.\n");
+
+ return rval;
+}
+
+#ifdef CONFIG_PM
+static int serial_ambarella_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ struct ambarella_uart_port *amb_port;
+ int rval = 0;
+
+ amb_port = platform_get_drvdata(pdev);
+ rval = uart_suspend_port(&serial_ambarella_reg, &amb_port->port);
+
+ dev_dbg(&pdev->dev, "%s exit with %d @ %d\n",
+ __func__, rval, state.event);
+
+ return rval;
+}
+
+static int serial_ambarella_resume(struct platform_device *pdev)
+{
+ struct ambarella_uart_port *amb_port;
+ int rval = 0;
+
+ amb_port = platform_get_drvdata(pdev);
+
+ clear_bit(AMBARELLA_UART_RESET_FLAG, &amb_port->flags);
+ serial_ambarella_hw_setup(&amb_port->port);
+
+ rval = uart_resume_port(&serial_ambarella_reg, &amb_port->port);
+
+ dev_dbg(&pdev->dev, "%s exit with %d\n", __func__, rval);
+
+ return rval;
+}
+#endif
+
+static const struct of_device_id ambarella_serial_of_match[] = {
+ { .compatible = "ambarella,uart" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ambarella_serial_of_match);
+
+static void ambarella_uart_of_enumerate(void)
+{
+ struct device_node *np;
+ int nr = 0;
+
+ if (serial_ambarella_reg.nr <= 0) {
+ for_each_matching_node(np, ambarella_serial_of_match) {
+ nr++;
+ }
+
+ if (nr > UART_INSTANCES)
+ nr = UART_INSTANCES;
+
+ serial_ambarella_reg.nr = nr;
+ }
+}
+
+
+static struct platform_driver serial_ambarella_driver = {
+ .probe = serial_ambarella_probe,
+ .remove = serial_ambarella_remove,
+#ifdef CONFIG_PM
+ .suspend = serial_ambarella_suspend,
+ .resume = serial_ambarella_resume,
+#endif
+ .driver = {
+ .name = "ambarella-uart",
+ .of_match_table = ambarella_serial_of_match,
+ },
+};
+
+int __init serial_ambarella_init(void)
+{
+ int rval;
+
+ ambarella_uart_of_enumerate();
+
+ rval = uart_register_driver(&serial_ambarella_reg);
+ if (rval < 0)
+ return rval;
+
+ rval = platform_driver_register(&serial_ambarella_driver);
+ if (rval < 0)
+ uart_unregister_driver(&serial_ambarella_reg);
+
+ return rval;
+}
+
+void __exit serial_ambarella_exit(void)
+{
+ platform_driver_unregister(&serial_ambarella_driver);
+ uart_unregister_driver(&serial_ambarella_reg);
+}
+
+module_init(serial_ambarella_init);
+module_exit(serial_ambarella_exit);
+
+MODULE_AUTHOR("Anthony Ginger");
+MODULE_DESCRIPTION("Ambarella Media Processor UART driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ambarella-uart");
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 92e1dc94..3c62bf2c 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -96,7 +96,7 @@ config USB
traditional PC serial port. The bus supplies power to peripherals
and allows for hot swapping. Up to 127 USB peripherals can be
connected to a single USB host in a tree structure.
-
+
The USB host is the root of the tree, the peripherals are the
leaves and the inner nodes are special USB devices called hubs.
Most PCs now have USB host ports, used to connect peripherals
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index f41aa0d0..1fdee11a 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -435,6 +435,18 @@ config USB_GOKU
dynamically linked module called "goku_udc" and to force all
gadget drivers to also be dynamically linked.
+#config USB_GADGET_AMBARELLA
+config USB_AMBARELLA
+ tristate "Ambarella USB Device Controller"
+ depends on PLAT_AMBARELLA
+ help
+ Many AMBARLLA processors (such as the A2/A5S/iONE/S2...) have a
+ full/high speed USB Device Controller.
+
+ Say "y" to link the driver statically, or "m" to build a
+ dynamically linked module called "ambarella_udc" and force all
+ gadget drivers to also be dynamically linked.
+
config USB_EG20T
tristate "Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7831) UDC"
depends on PCI && GENERIC_HARDIRQS
@@ -818,6 +830,20 @@ config USB_G_PRINTER
For more information, see Documentation/usb/gadget_printer.txt
which includes sample code for accessing the device file.
+config USB_AMB_STREAM
+ tristate "Gadget Ambarella Data Streaming"
+ depends on USB_AMBARELLA
+ select USB_LIBCOMPOSITE
+ help
+ Gadget Ambarella Data Streaming is a single-configuration
+ single-interface device.
+ The driver needs two bulk-capable endpoints, and one interrupt-capable
+ endpoint is optional. It may need special protocol that can be
+ designed at top layer to transfer data with host.
+
+ Say "y" to link the driver statically, or "m" to build a
+ dynamically linked module called "g_amb_stream".
+
if TTY
config USB_CDC_COMPOSITE
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 6afd1665..fff150cd 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o
obj-$(CONFIG_USB_S3C_HSOTG) += s3c-hsotg.o
obj-$(CONFIG_USB_S3C_HSUDC) += s3c-hsudc.o
obj-$(CONFIG_USB_LPC32XX) += lpc32xx_udc.o
+obj-$(CONFIG_USB_AMBARELLA) += ambarella_udc.o
obj-$(CONFIG_USB_EG20T) += pch_udc.o
obj-$(CONFIG_USB_MV_UDC) += mv_udc.o
mv_udc-y := mv_udc_core.o
@@ -58,6 +59,7 @@ gadgetfs-y := inode.o
g_mass_storage-y := mass_storage.o
g_printer-y := printer.o
g_cdc-y := cdc2.o
+g_amb_stream-y := amb_stream.o
g_multi-y := multi.o
g_hid-y := hid.o
g_dbgp-y := dbgp.o
@@ -77,6 +79,7 @@ obj-$(CONFIG_USB_G_SERIAL) += g_serial.o
obj-$(CONFIG_USB_G_PRINTER) += g_printer.o
obj-$(CONFIG_USB_MIDI_GADGET) += g_midi.o
obj-$(CONFIG_USB_CDC_COMPOSITE) += g_cdc.o
+obj-$(CONFIG_USB_AMB_STREAM) += g_amb_stream.o
obj-$(CONFIG_USB_G_HID) += g_hid.o
obj-$(CONFIG_USB_G_DBGP) += g_dbgp.o
obj-$(CONFIG_USB_G_MULTI) += g_multi.o
diff --git a/drivers/usb/gadget/amb_stream.c b/drivers/usb/gadget/amb_stream.c
new file mode 100644
index 00000000..ae69b4f7
--- /dev/null
+++ b/drivers/usb/gadget/amb_stream.c
@@ -0,0 +1,1344 @@
+/*
+* amb_stream.c -- Ambarella Data Streaming Gadget
+*
+* History:
+* 2009/01/01 - [Cao Rongrong] created file
+*
+* Copyright (C) 2008 by Ambarella, Inc.
+* http://www.ambarella.com
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*/
+
+
+/*
+ * Ambarella Data Streaming Gadget only needs two bulk endpoints, and it
+ * supports single configurations.
+ *
+ * Module options include:
+ * buflen=N default N=4096, buffer size used
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+
+#include <linux/usb/composite.h>
+#include <linux/device.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+
+#include "gadget_chips.h"
+
+#include <mach/hardware.h>
+
+USB_GADGET_COMPOSITE_OPTIONS();
+
+#define DRIVER_VERSION "15 July 2016"
+
+static const char shortname[] = "g_amb_stream";
+static const char longname[] = "Ambarella Data Streaming Gadget";
+
+/* ==========================================================================*/
+#define AMBA_DEV_MAJOR (248)
+#define AMBA_DEV_MINOR_PUBLIC_START (128)
+#define AMBA_DEV_MINOR_PUBLIC_END (240)
+/*-------------------------------------------------------------------------*/
+#ifdef DEBUG
+#define AMB_DBG(dev,fmt,args...) \
+ dev_printk(KERN_DEBUG , &(dev)->gadget->dev , fmt , ## args)
+#else
+#define AMB_DBG(dev,fmt,args...) \
+ do { } while (0)
+#endif /* DEBUG */
+
+#define AMB_ERROR(dev,fmt,args...) \
+ dev_printk(KERN_ERR , &(dev)->gadget->dev , fmt , ## args)
+
+#define AMB_INFO(dev,fmt,args...) \
+ dev_printk(KERN_INFO , &(dev)->gadget->dev , fmt , ## args)
+/*-------------------------------------------------------------------------*/
+#define AMB_GADGET_MAJOR AMBA_DEV_MAJOR
+#define AMB_GADGET_MINOR_START (AMBA_DEV_MINOR_PUBLIC_START + 0)
+/*-------------------------------------------------------------------------*/
+static struct cdev ag_cdev;
+
+/* big enough to hold our biggest descriptor */
+#define USB_BUFSIZ 256
+/*-------------------------------------------------------------------------*/
+#define AG_NOTIFY_INTERVAL 5 /* 1 << 5 == 32 msec */
+#define AG_NOTIFY_MAXPACKET 8
+
+#define SIMPLE_CMD_SIZE 32
+struct amb_cmd {
+ u32 signature;
+ u32 command;
+ u32 parameter[(SIMPLE_CMD_SIZE / sizeof(u32)) - 2];
+};
+
+struct amb_rsp {
+ u32 signature;
+ u32 response;
+ u32 parameter0;
+ u32 parameter1;
+};
+
+struct amb_ack {
+ u32 signature;
+ u32 acknowledge;
+ u32 parameter0;
+ u32 parameter1;
+};
+
+/* for bNotifyType */
+#define PORT_STATUS_CHANGE 0x55
+#define PORT_NOTIFY_IDLE 0xff
+/* for value */
+#define PORT_FREE_ALL 2
+#define PORT_CONNECT 1
+#define PORT_NO_CONNECT 0
+/* for status */
+#define DEVICE_OPENED 1
+#define DEVICE_NOT_OPEN 0
+
+struct amb_notify {
+ u16 bNotifyType;
+ u16 port_id;
+ u16 value;
+ u16 status;
+};
+
+struct amb_notify g_port = {
+ .bNotifyType = PORT_NOTIFY_IDLE,
+ .port_id = 0xffff,
+ .value = 0,
+};
+
+/*-------------------------------------------------------------------------*/
+#define AMB_DATA_STREAM_MAGIC 'u'
+#define AMB_DATA_STREAM_WR_RSP _IOW(AMB_DATA_STREAM_MAGIC, 1, struct amb_rsp *)
+#define AMB_DATA_STREAM_RD_CMD _IOR(AMB_DATA_STREAM_MAGIC, 1, struct amb_cmd *)
+#define AMB_DATA_STREAM_STATUS_CHANGE _IOW(AMB_DATA_STREAM_MAGIC, 2, struct amb_notify *)
+/*-------------------------------------------------------------------------*/
+struct amb_dev {
+ spinlock_t lock;
+ wait_queue_head_t wq;
+ struct mutex mtx;
+
+ int config;
+ struct usb_gadget *gadget;
+ struct usb_request *notify_req;
+
+ struct usb_ep *in_ep;
+ struct usb_ep *out_ep;
+ struct usb_ep *notify_ep;
+
+ struct list_head in_idle_list; /* list of idle write requests */
+ struct list_head in_queue_list; /* list of queueing write requests */
+ struct list_head out_req_list; /* list of bulk out requests */
+
+ struct usb_function func;
+
+ int open_count;
+ int error;
+ char interface;
+};
+
+struct amb_dev *ag_device;
+static dev_t ag_dev_id;
+static struct class *ag_class;
+/*-------------------------------------------------------------------------*/
+static void notify_worker(struct work_struct *work);
+static DECLARE_WORK(notify_work, notify_worker);
+/*-------------------------------------------------------------------------*/
+static unsigned int buflen = (48*1024);
+module_param (buflen, uint, S_IRUGO);
+MODULE_PARM_DESC(buflen, "buffer length, default=48K");
+
+static unsigned int qdepth = 5;
+module_param (qdepth, uint, S_IRUGO);
+MODULE_PARM_DESC(qdepth, "bulk transfer queue depth, default=5");
+/*-------------------------------------------------------------------------*/
+/*
+ * DESCRIPTORS ... most are static, but strings and (full)
+ * configuration descriptors are built on demand.
+ */
+
+#define STRING_SOURCE_SINK USB_GADGET_FIRST_AVAIL_IDX
+
+#define DRIVER_VENDOR_ID 0x4255 /* Ambarella */
+#define DRIVER_PRODUCT_ID 0x0001
+
+#define DEV_CONFIG_VALUE 1
+
+static struct usb_device_descriptor ag_device_desc = {
+ .bLength = sizeof ag_device_desc,
+ .bDescriptorType = USB_DT_DEVICE,
+
+ .bcdUSB = cpu_to_le16 (0x0200),
+ .bDeviceClass = USB_CLASS_VENDOR_SPEC,
+
+ .idVendor = cpu_to_le16 (DRIVER_VENDOR_ID),
+ .idProduct = cpu_to_le16 (DRIVER_PRODUCT_ID),
+ .bNumConfigurations = 1,
+};
+
+static struct usb_config_descriptor amb_bulk_config = {
+ .bLength = sizeof amb_bulk_config,
+ .bDescriptorType = USB_DT_CONFIG,
+
+ .bNumInterfaces = 1,
+ .bConfigurationValue = DEV_CONFIG_VALUE,
+ .iConfiguration = STRING_SOURCE_SINK,
+ .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
+};
+
+/* one interface in each configuration */
+static struct usb_interface_descriptor amb_data_stream_intf = {
+ .bLength = sizeof amb_data_stream_intf,
+ .bDescriptorType = USB_DT_INTERFACE,
+
+ .bNumEndpoints = 3,
+ .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
+ .iInterface = STRING_SOURCE_SINK,
+};
+
+/* two full speed bulk endpoints; their use is config-dependent */
+
+static struct usb_endpoint_descriptor fs_bulk_in_desc = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+
+ .bEndpointAddress = USB_DIR_IN,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usb_endpoint_descriptor fs_bulk_out_desc = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+
+ .bEndpointAddress = USB_DIR_OUT,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usb_endpoint_descriptor fs_intr_in_desc = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = USB_DIR_IN,
+ .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .wMaxPacketSize = cpu_to_le16(AG_NOTIFY_MAXPACKET),
+ .bInterval = 1 << AG_NOTIFY_INTERVAL,
+};
+
+static struct usb_descriptor_header *fs_amb_data_stream_function[] = {
+ (struct usb_descriptor_header *) &amb_data_stream_intf,
+ (struct usb_descriptor_header *) &fs_bulk_out_desc,
+ (struct usb_descriptor_header *) &fs_bulk_in_desc,
+ (struct usb_descriptor_header *) &fs_intr_in_desc,
+ NULL,
+};
+
+static struct usb_endpoint_descriptor hs_bulk_in_desc = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+
+ /* bEndpointAddress will be copied from fs_bulk_in_desc during amb_bind() */
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = cpu_to_le16 (512),
+};
+
+static struct usb_endpoint_descriptor hs_bulk_out_desc = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = cpu_to_le16 (512),
+};
+
+static struct usb_endpoint_descriptor hs_intr_in_desc = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = USB_DIR_IN,
+ .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .wMaxPacketSize = cpu_to_le16(AG_NOTIFY_MAXPACKET),
+ .bInterval = AG_NOTIFY_INTERVAL + 4,
+};
+
+static struct usb_qualifier_descriptor dev_qualifier = {
+ .bLength = sizeof dev_qualifier,
+ .bDescriptorType = USB_DT_DEVICE_QUALIFIER,
+
+ .bcdUSB = cpu_to_le16 (0x0200),
+ .bDeviceClass = USB_CLASS_VENDOR_SPEC,
+
+ .bNumConfigurations = 1,
+};
+
+static struct usb_descriptor_header *hs_amb_data_stream_function[] = {
+ (struct usb_descriptor_header *) &amb_data_stream_intf,
+ (struct usb_descriptor_header *) &hs_bulk_in_desc,
+ (struct usb_descriptor_header *) &hs_bulk_out_desc,
+ (struct usb_descriptor_header *) &hs_intr_in_desc,
+ NULL,
+};
+
+static struct usb_otg_descriptor otg_descriptor = {
+ .bLength = sizeof otg_descriptor,
+ .bDescriptorType = USB_DT_OTG,
+ .bmAttributes = USB_OTG_SRP,
+};
+
+static const struct usb_descriptor_header *otg_desc[] = {
+ (struct usb_descriptor_header *) &otg_descriptor,
+ NULL,
+};
+/*-------------------------------------------------------------------------*/
+static char serial[40] = "123456789ABC";
+
+/* static strings, in UTF-8 */
+static struct usb_string strings[] = {
+ [USB_GADGET_MANUFACTURER_IDX].s = "",
+ [USB_GADGET_PRODUCT_IDX].s = longname,
+ [USB_GADGET_SERIAL_IDX].s = serial,
+ [STRING_SOURCE_SINK].s = "bulk in and out data",
+ { } /* end of list */
+};
+
+static struct usb_gadget_strings stringtab_dev = {
+ .language = 0x0409, /* en-us */
+ .strings = strings,
+};
+
+static struct usb_gadget_strings *dev_strings[] = {
+ &stringtab_dev,
+ NULL,
+};
+
+/*-------------------------------------------------------------------------*/
+/* add a request to the tail of a list */
+void req_put(struct amb_dev *dev,
+ struct list_head *head, struct usb_request *req)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->lock, flags);
+ list_add_tail(&req->list, head);
+ spin_unlock_irqrestore(&dev->lock, flags);
+}
+
+/* get a request and remove it from the head of a list */
+struct usb_request *req_get(struct amb_dev *dev, struct list_head *head)
+{
+ struct usb_request *req;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->lock, flags);
+ if (list_empty(head)) {
+ req = NULL;
+ } else {
+ req = list_first_entry(head, struct usb_request, list);
+ list_del(&req->list);
+ }
+ spin_unlock_irqrestore(&dev->lock, flags);
+ return req;
+}
+
+/* get a request and move it from the head of "from" list
+ * to the head of "to" list
+ */
+struct usb_request *req_move(struct amb_dev *dev,
+ struct list_head *from, struct list_head *to)
+{
+ struct usb_request *req;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->lock, flags);
+ if (list_empty(from)) {
+ req = NULL;
+ } else {
+ req = list_first_entry(from, struct usb_request, list);
+ list_move_tail(&req->list, to);
+ }
+ spin_unlock_irqrestore(&dev->lock, flags);
+ return req;
+}
+
+static int amb_send(u8 *buf, u32 len)
+{
+ struct amb_dev *dev = ag_device;
+ struct usb_request *req = NULL;
+ int rval = 0;
+
+ if (buf == NULL || len > buflen)
+ return -EFAULT;
+
+ if(wait_event_interruptible(dev->wq,
+ (req = req_move(dev, &dev->in_idle_list, &dev->in_queue_list))
+ || dev->error)){
+ rval = -EINTR;
+ goto exit;
+ }
+
+ if(dev->error) {
+ AMB_ERROR(dev, "%s: device error", __func__);
+ spin_lock_irq(&dev->lock);
+ if (req)
+ list_move_tail(&req->list, &dev->in_idle_list);
+ spin_unlock_irq(&dev->lock);
+ rval = -EIO;
+ goto exit;
+ }
+
+ memcpy(req->buf, buf, len);
+
+ req->length = len;
+ rval = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC);
+ if (rval != 0) {
+ AMB_ERROR(dev, "%s: cannot queue bulk in request, "
+ "rval=%d\n", __func__, rval);
+ spin_lock_irq(&dev->lock);
+ list_move_tail(&req->list, &dev->in_idle_list);
+ spin_unlock_irq(&dev->lock);
+ goto exit;
+ }
+
+exit:
+ return rval;
+}
+
+static int amb_recv(u8 *buf, u32 len)
+{
+ struct amb_dev *dev = ag_device;
+ struct usb_request *req = NULL;
+ int rval = 0;
+
+ if (buf == NULL || len > buflen)
+ return -EFAULT;
+
+ if(wait_event_interruptible(dev->wq,
+ (req = req_get(dev, &dev->out_req_list)) || dev->error)){
+ return -EINTR;
+ }
+
+ if (req) {
+ memcpy(buf, req->buf, req->actual);
+
+ req->length = buflen;
+ if ((rval = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC))) {
+ AMB_ERROR(dev, "%s: can't queue bulk out request, "
+ "rval = %d\n", __func__, rval);
+ }
+ }
+
+ if(dev->error) {
+ AMB_ERROR(dev, "%s: device error", __func__);
+ rval = -EIO;
+ }
+
+ return rval;
+}
+
+
+/*-------------------------------------------------------------------------*/
+static long ag_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ int rval = 0;
+ struct amb_dev *dev = ag_device;
+ struct amb_cmd _cmd;
+ struct amb_rsp rsp;
+ struct amb_notify notify;
+
+ AMB_DBG(dev, "%s: Enter\n", __func__);
+
+ mutex_lock(&dev->mtx);
+
+ switch (cmd) {
+ case AMB_DATA_STREAM_WR_RSP:
+
+ if(copy_from_user(&rsp, (struct amb_rsp __user *)arg, sizeof(rsp))){
+ mutex_unlock(&dev->mtx);
+ return -EFAULT;
+ }
+
+ rval = amb_send((u8 *)&rsp, sizeof(rsp));
+ break;
+
+ case AMB_DATA_STREAM_RD_CMD:
+
+ rval = amb_recv((u8 *)&_cmd, sizeof(_cmd));
+ if(rval < 0)
+ break;
+
+ if(copy_to_user((struct amb_cmd __user *)arg, &_cmd, sizeof(_cmd))){
+ mutex_unlock(&dev->mtx);
+ return -EFAULT;
+ }
+
+ break;
+
+ case AMB_DATA_STREAM_STATUS_CHANGE:
+ if(copy_from_user(&notify, (struct amb_notify __user *)arg, sizeof(notify))){
+ mutex_unlock(&dev->mtx);
+ return -EFAULT;
+ }
+
+ spin_lock_irq(&dev->lock);
+ g_port.bNotifyType = notify.bNotifyType;
+ g_port.port_id = notify.port_id;
+ g_port.value = notify.value;
+ spin_unlock_irq(&dev->lock);
+ break;
+
+ default:
+ rval = -ENOIOCTLCMD;
+ break;
+ }
+
+ mutex_unlock(&dev->mtx);
+
+ AMB_DBG(dev, "%s: Exit\n", __func__);
+
+ return rval;
+}
+static int ag_open(struct inode *inode, struct file *filp)
+{
+ struct amb_dev *dev = ag_device;
+ struct usb_request *req = NULL;
+ int rval = 0;
+
+ mutex_lock(&dev->mtx);
+
+ /* gadget have not been configured */
+ if(dev->config == 0){
+ rval = -ENOTCONN;
+ goto exit;
+ }
+
+ if(dev->open_count > 0){
+ rval = -EBUSY;
+ goto exit;
+ }
+
+ dev->open_count++;
+ dev->error = 0;
+
+ /* throw away the data received on last connection */
+ while ((req = req_get(dev, &dev->out_req_list))) {
+ /* re-use the req again */
+ req->length = buflen;
+ if ((rval = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC))) {
+ AMB_ERROR(dev, "%s: can't queue bulk out request, "
+ "rval = %d\n", __func__, rval);
+ break;
+ }
+ }
+exit:
+ mutex_unlock(&dev->mtx);
+ return rval;
+}
+
+static int ag_release(struct inode *inode, struct file *filp)
+{
+ struct amb_dev *dev = ag_device;
+ struct usb_request *req;
+ int rval = 0;
+
+ mutex_lock(&dev->mtx);
+
+ /* dequeue the bulk-in request */
+ while ((req = req_move(dev, &dev->in_queue_list, &dev->in_idle_list))) {
+ rval = usb_ep_dequeue(dev->in_ep, req);
+ if (rval != 0) {
+ AMB_ERROR(dev, "%s: cannot dequeue bulk in request, "
+ "rval=%d\n", __func__, rval);
+ break;
+ }
+ }
+
+ dev->open_count--;
+
+ spin_lock_irq(&dev->lock);
+ g_port.bNotifyType = PORT_STATUS_CHANGE;
+ g_port.port_id = 0xffff;
+ g_port.value = PORT_FREE_ALL;
+ g_port.status = DEVICE_NOT_OPEN;
+ spin_unlock_irq(&dev->lock);
+
+ mutex_unlock(&dev->mtx);
+
+ return rval;
+}
+
+static int ag_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct amb_dev *dev = ag_device;
+ struct usb_request *req = NULL;
+ int len = 0, rval = 0;
+
+ mutex_lock(&dev->mtx);
+
+ while(count > 0){
+ if(wait_event_interruptible(dev->wq,
+ (req = req_get(dev, &dev->out_req_list)) || dev->error)){
+ mutex_unlock(&dev->mtx);
+ return -EINTR;
+ }
+
+ if(dev->error){
+ AMB_ERROR(dev, "%s: device error", __func__);
+ if (req) {
+ req->length = buflen;
+ rval = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC);
+ if (rval)
+ AMB_ERROR(dev, "%s: "
+ "can't queue bulk out request, "
+ "rval = %d\n", __func__, rval);
+ }
+ mutex_unlock(&dev->mtx);
+ return -EIO;
+ }
+
+ if(copy_to_user(buf + len, req->buf, req->actual)){
+ pr_err("len = %d, actual = %d\n", len, req->actual);
+ mutex_unlock(&dev->mtx);
+ return -EFAULT;
+ }
+ len += req->actual;
+ count -= req->actual;
+
+ req->length = buflen;
+ if ((rval = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC))) {
+ AMB_ERROR(dev, "%s: can't queue bulk out request, "
+ "rval = %d\n", __func__, rval);
+ len = rval;
+ break;
+ }
+
+ if (len % buflen != 0)
+ break;
+ }
+
+ mutex_unlock(&dev->mtx);
+
+ return len;
+}
+
+static int ag_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ int rval, size, len = 0;
+ struct amb_dev *dev = ag_device;
+ struct usb_request *req = NULL;
+
+ mutex_lock(&dev->mtx);
+
+ while(count > 0) {
+ if(wait_event_interruptible(dev->wq,
+ (req = req_move(dev, &dev->in_idle_list, &dev->in_queue_list))
+ || dev->error)){
+ mutex_unlock(&dev->mtx);
+ return -EINTR;
+ }
+
+ if(dev->error){
+ AMB_ERROR(dev, "%s: device error", __func__);
+ spin_lock_irq(&dev->lock);
+ if (req)
+ list_move_tail(&req->list, &dev->in_idle_list);
+ spin_unlock_irq(&dev->lock);
+ mutex_unlock(&dev->mtx);
+ return -EIO;
+ }
+
+ size = count < buflen ? count : buflen;
+ if(copy_from_user(req->buf, buf + len, size)){
+ mutex_unlock(&dev->mtx);
+ return -EFAULT;
+ }
+
+ req->length = size;
+ if ((count - size == 0) && (size % dev->in_ep->maxpacket == 0))
+ req->zero = 1;
+
+ rval = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC);
+ if (rval != 0) {
+ AMB_ERROR(dev, "%s: cannot queue bulk in request, "
+ "rval=%d\n", __func__, rval);
+ list_move_tail(&req->list, &dev->in_idle_list);
+ mutex_unlock(&dev->mtx);
+ return rval;
+ }
+
+ count -= size;
+ len += size;
+ }
+
+ mutex_unlock(&dev->mtx);
+
+ AMB_DBG(dev, "%s: Exit\n", __func__);
+
+ return len;
+}
+
+static const struct file_operations ag_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = ag_ioctl,
+ .open = ag_open,
+ .read = ag_read,
+ .write = ag_write,
+ .release = ag_release
+};
+
+static void amb_notify_complete (struct usb_ep *ep, struct usb_request *req);
+
+static void notify_worker(struct work_struct *work)
+{
+ struct amb_dev *dev = ag_device;
+ struct usb_request *req = NULL;
+ struct amb_notify *event = NULL;
+ unsigned long flags;
+ int rval = 0;
+
+ if (dev && (req = dev->notify_req)) {
+ event = req->buf;
+ spin_lock_irqsave(&dev->lock, flags);
+ memcpy(event, &g_port, sizeof(struct amb_notify));
+ g_port.bNotifyType = PORT_NOTIFY_IDLE;
+ g_port.port_id = 0xffff;
+ g_port.value = 0;
+ if(dev->open_count > 0)
+ g_port.status = DEVICE_OPENED;
+ else
+ g_port.status = DEVICE_NOT_OPEN;
+
+ req->length = AG_NOTIFY_MAXPACKET;
+ req->complete = amb_notify_complete;
+ req->context = dev;
+ req->zero = !(req->length % dev->notify_ep->maxpacket);
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+ rval = usb_ep_queue(dev->notify_ep, req, GFP_ATOMIC);
+ if (rval < 0)
+ AMB_DBG(dev, "status buf queue --> %d\n", rval);
+ }
+}
+
+static struct usb_request *amb_alloc_buf_req (struct usb_ep *ep,
+ unsigned length, gfp_t kmalloc_flags)
+{
+ struct usb_request *req;
+
+ req = usb_ep_alloc_request(ep, kmalloc_flags);
+ if (req) {
+ req->length = length;
+ req->buf = kmalloc(length, kmalloc_flags);
+ if (!req->buf) {
+ usb_ep_free_request(ep, req);
+ req = NULL;
+ }
+ }
+ return req;
+}
+
+static void amb_free_buf_req (struct usb_ep *ep, struct usb_request *req)
+{
+ if(req){
+ if (req->buf){
+ kfree(req->buf);
+ req->buf = NULL;
+ }
+ usb_ep_free_request(ep, req);
+ }
+}
+
+static void amb_bulk_in_complete (struct usb_ep *ep, struct usb_request *req)
+{
+ struct amb_dev *dev = ep->driver_data;
+ int status = req->status;
+ unsigned long flags;
+ int rval = 0;
+
+ spin_lock_irqsave(&dev->lock, flags);
+ switch (status) {
+ case 0: /* normal completion? */
+ dev->error = 0;
+ list_move_tail(&req->list, &dev->in_idle_list);
+ break;
+ /* this endpoint is normally active while we're configured */
+ case -ECONNRESET: /* request dequeued */
+ dev->error = 1;
+ usb_ep_fifo_flush(ep);
+ break;
+ case -ESHUTDOWN: /* disconnect from host */
+ dev->error = 1;
+ amb_free_buf_req(ep, req);
+ break;
+ default:
+ AMB_ERROR(dev, "%s complete --> %d, %d/%d\n", ep->name,
+ status, req->actual, req->length);
+ dev->error = 1;
+ /* queue request again */
+ rval = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC);
+ if (rval != 0) {
+ AMB_ERROR(dev, "%s: cannot queue bulk in request, "
+ "rval=%d\n", __func__, rval);
+ }
+ break;
+ }
+ wake_up_interruptible(&dev->wq);
+ spin_unlock_irqrestore(&dev->lock, flags);
+}
+
+static void amb_bulk_out_complete (struct usb_ep *ep, struct usb_request *req)
+{
+ struct amb_dev *dev = ep->driver_data;
+ int status = req->status;
+ unsigned long flags;
+ int rval = 0;
+
+ spin_lock_irqsave(&dev->lock, flags);
+ switch (status) {
+ case 0: /* normal completion */
+ dev->error = 0;
+ list_add_tail(&req->list, &dev->out_req_list);
+ break;
+ /* this endpoint is normally active while we're configured */
+ case -ECONNRESET: /* request dequeued */
+ dev->error = 1;
+ usb_ep_fifo_flush(ep);
+ break;
+ case -ESHUTDOWN: /* disconnect from host */
+ dev->error = 1;
+ amb_free_buf_req(ep, req);
+ break;
+ default:
+ AMB_ERROR(dev, "%s complete --> %d, %d/%d\n", ep->name,
+ status, req->actual, req->length);
+ dev->error = 1;
+ /* queue request again */
+ rval = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC);
+ if (rval != 0) {
+ AMB_ERROR(dev, "%s: cannot queue bulk in request, "
+ "rval=%d\n", __func__, rval);
+ }
+ break;
+ }
+ wake_up_interruptible(&dev->wq);
+ spin_unlock_irqrestore(&dev->lock, flags);
+}
+
+static void amb_notify_complete (struct usb_ep *ep, struct usb_request *req)
+{
+ struct amb_dev *dev = ep->driver_data;
+ int status = req->status;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->lock, flags);
+ req->context = NULL;
+
+ switch (status) {
+ case 0: /* normal completion */
+ /* issue the second notification if host reads the previous one */
+ schedule_work(&notify_work);
+ break;
+
+ /* this endpoint is normally active while we're configured */
+ case -ECONNRESET: /* request dequeued */
+ usb_ep_fifo_flush(ep);
+ break;
+ case -ESHUTDOWN: /* disconnect from host */
+ amb_free_buf_req(ep, req);
+ break;
+ default:
+ AMB_ERROR(dev, "%s complete --> %d, %d/%d\n", ep->name,
+ status, req->actual, req->length);
+ break;
+ }
+ spin_unlock_irqrestore(&dev->lock, flags);
+}
+
+static void amb_start_notify (struct amb_dev *dev)
+{
+ struct usb_request *req = dev->notify_req;
+ struct amb_notify *event;
+ int value;
+
+ /* flush old status
+ * FIXME iff req->context != null just dequeue it
+ */
+ //usb_ep_disable(dev->notify_ep);
+ //usb_ep_enable(dev->notify_ep);
+
+ event = req->buf;
+ event->bNotifyType = cpu_to_le16(PORT_NOTIFY_IDLE);
+ event->port_id = cpu_to_le16 (0);
+ event->value = cpu_to_le32 (0);
+ event->status = DEVICE_NOT_OPEN;
+
+ req->length = AG_NOTIFY_MAXPACKET;
+ req->complete = amb_notify_complete;
+ req->context = dev;
+ req->zero = !(req->length % dev->notify_ep->maxpacket);
+
+ value = usb_ep_queue(dev->notify_ep, req, GFP_ATOMIC);
+ if (value < 0)
+ AMB_DBG (dev, "status buf queue --> %d\n", value);
+}
+/*-------------------------------------------------------------------------*/
+static void amb_cfg_unbind(struct usb_configuration *c)
+{
+ device_destroy(ag_class, ag_dev_id);
+}
+
+static struct usb_configuration amb_config_driver = {
+ .label = "AMB Stream Gadget",
+ .unbind = amb_cfg_unbind,
+ .bConfigurationValue = 1,
+ //.iConfiguration = STRING_SOURCE_SINK,
+ .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
+ .MaxPower = 1,
+};
+
+static int amb_set_stream_config(struct amb_dev *dev)
+{
+ int result = 0, i;
+ struct usb_gadget *gadget = dev->gadget;
+ struct usb_ep *ep;
+ struct usb_request *req;
+
+ /* one endpoint writes data in (to the host) */
+ result = config_ep_by_speed(gadget, &(dev->func), dev->in_ep);
+ if (result)
+ goto exit;
+ result = usb_ep_enable(dev->in_ep);
+ if (result != 0) {
+ AMB_ERROR(dev, "%s: can't enable %s, result=%d\n",
+ __func__, dev->in_ep->name, result);
+ goto exit;
+ }
+
+ /* one endpoint reads data out (from the host) */
+ result = config_ep_by_speed(gadget, &(dev->func), dev->out_ep);
+ if (result)
+ goto exit;
+ result = usb_ep_enable(dev->out_ep);
+ if (result != 0) {
+ AMB_ERROR(dev, "%s: can't enable %s, result=%d\n",
+ __func__, dev->out_ep->name, result);
+ usb_ep_disable(dev->in_ep);
+ goto exit;
+ }
+
+ /* one endpoint report status (to the host) */
+ result = config_ep_by_speed(gadget, &(dev->func), dev->notify_ep);
+ if (result)
+ goto exit;
+ result = usb_ep_enable(dev->notify_ep);
+ if (result != 0) {
+ AMB_ERROR(dev, "%s: can't enable %s, result=%d\n",
+ __func__, dev->notify_ep->name, result);
+ usb_ep_disable(dev->out_ep);
+ usb_ep_disable(dev->in_ep);
+ dev->out_ep->desc = NULL;
+ dev->in_ep->desc = NULL;
+ goto exit;
+ }
+
+ /* allocate and queue read requests */
+ ep = dev->out_ep;
+ ep->driver_data = dev;
+ for (i = 0; i < qdepth && result == 0; i++) {
+ req = amb_alloc_buf_req(ep, buflen, GFP_ATOMIC);
+ if (req) {
+ req->complete = amb_bulk_out_complete;
+ result = usb_ep_queue(ep, req, GFP_ATOMIC);
+ if (result < 0) {
+ AMB_ERROR(dev, "%s: can't queue bulk out request, "
+ "rval = %d\n", __func__, result);
+ }
+ } else {
+ AMB_ERROR(dev, "%s: can't allocate bulk in requests\n", __func__);
+ result = -ENOMEM;
+ goto exit;
+ }
+ }
+
+ /* allocate write requests, and put on free list */
+ ep = dev->in_ep;
+ ep->driver_data = dev;
+ for (i = 0; i < qdepth; i++) {
+ req = amb_alloc_buf_req(ep, buflen, GFP_ATOMIC);
+ if (req) {
+ req->complete = amb_bulk_in_complete;
+ req_put(dev, &dev->in_idle_list, req);
+ } else {
+ AMB_ERROR(dev, "%s: can't allocate bulk in requests\n", __func__);
+ result = -ENOMEM;
+ goto exit;
+ }
+ }
+
+ ep = dev->notify_ep;
+ ep->driver_data = dev;
+ if (dev->notify_ep) {
+ dev->notify_req = amb_alloc_buf_req(ep,
+ AG_NOTIFY_MAXPACKET,GFP_ATOMIC);
+ amb_start_notify(dev);
+ }
+
+exit:
+ /* caller is responsible for cleanup on error */
+ return result;
+}
+
+static void amb_reset_config (struct amb_dev *dev)
+{
+ struct usb_request *req;
+ unsigned long flags;
+
+ if (dev->config == 0)
+ return;
+ dev->config = 0;
+
+ spin_lock_irqsave(&dev->lock, flags);
+
+ /* free write requests on the free list */
+ while(!list_empty(&dev->in_idle_list)) {
+ req = list_entry(dev->in_idle_list.next,
+ struct usb_request, list);
+ list_del_init(&req->list);
+ req->length = buflen;
+ amb_free_buf_req(dev->in_ep, req);
+ }
+ while(!list_empty(&dev->in_queue_list)) {
+ req = list_entry(dev->in_queue_list.prev,
+ struct usb_request, list);
+ list_del_init(&req->list);
+ req->length = buflen;
+ amb_free_buf_req(dev->in_ep, req);
+ }
+
+ while(!list_empty(&dev->out_req_list)) {
+ req = list_entry(dev->out_req_list.prev,
+ struct usb_request, list);
+ list_del_init(&req->list);
+ req->length = buflen;
+ amb_free_buf_req(dev->out_ep, req);
+ }
+
+ spin_unlock_irqrestore(&dev->lock, flags);
+ /* just disable endpoints, forcing completion of pending i/o.
+ * all our completion handlers free their requests in this case.
+ */
+ /* Disable the endpoints */
+ if (dev->notify_ep)
+ usb_ep_disable(dev->notify_ep);
+ usb_ep_disable(dev->in_ep);
+ usb_ep_disable(dev->out_ep);
+}
+
+static int amb_set_interface(struct amb_dev *dev, unsigned number)
+{
+ int result = 0;
+
+ /* Free the current interface */
+ //amb_reset_config(dev);
+
+ result = amb_set_stream_config(dev);
+
+ if (!result) {
+ dev->interface = number;
+ dev->config = 1;
+ }
+ return result;
+}
+
+static int __init amb_func_bind(struct usb_configuration *c,
+ struct usb_function *f)
+{
+ struct amb_dev *dev = container_of(f, struct amb_dev, func);
+ struct usb_composite_dev *cdev = c->cdev;
+ struct usb_ep *ep;
+ int id;
+ int ret = 0;
+
+ id = usb_interface_id(c, f);
+ if (id < 0)
+ return id;
+ amb_data_stream_intf.bInterfaceNumber = id;
+
+ /* allocate bulk endpoints */
+ ep = usb_ep_autoconfig(cdev->gadget, &fs_bulk_in_desc);
+ if (!ep) {
+autoconf_fail:
+ ERROR(cdev, "%s: can't autoconfigure on %s\n",
+ f->name, cdev->gadget->name);
+ return -ENODEV;
+ }
+ ep->driver_data = dev; /* claim the endpoint */
+ dev->in_ep = ep;
+
+ ep = usb_ep_autoconfig(cdev->gadget, &fs_bulk_out_desc);
+ if (!ep) {
+ goto autoconf_fail;
+ }
+ ep->driver_data = dev; /* claim the endpoint */
+ dev->out_ep = ep;
+
+ ep = usb_ep_autoconfig(cdev->gadget, &fs_intr_in_desc);
+ if (!ep) {
+ goto autoconf_fail;
+ }
+ dev->notify_ep = ep;
+ ep->driver_data = dev; /* claim the endpoint */
+
+ /* support all relevant hardware speeds... we expect that when
+ * hardware is dual speed, all bulk-capable endpoints work at
+ * both speeds
+ */
+ hs_bulk_in_desc.bEndpointAddress = fs_bulk_in_desc.bEndpointAddress;
+ hs_bulk_out_desc.bEndpointAddress = fs_bulk_out_desc.bEndpointAddress;
+ hs_intr_in_desc.bEndpointAddress = fs_intr_in_desc.bEndpointAddress;
+
+ ret = usb_assign_descriptors(f, fs_amb_data_stream_function,
+ hs_amb_data_stream_function, NULL);
+ if (ret)
+ goto fail;
+
+ printk("AMB STREAM: %s speed IN/%s OUT/%s NOTIFY/%s\n",
+ gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
+ dev->in_ep->name, dev->out_ep->name,dev->notify_ep->name);
+ return 0;
+fail:
+ usb_free_all_descriptors(f);
+ if (dev->in_ep)
+ dev->in_ep->driver_data = NULL;
+ if (dev->out_ep)
+ dev->out_ep->driver_data = NULL;
+ if (dev->notify_ep)
+ dev->notify_ep->driver_data = NULL;
+
+ printk("%s: can't bind, err %d\n", f->name, ret);
+ return ret;
+}
+
+static void amb_func_unbind(struct usb_configuration *c,
+ struct usb_function *f)
+{
+ usb_free_all_descriptors(f);
+}
+
+static int amb_func_set_alt(struct usb_function *f,
+ unsigned inf, unsigned alt)
+{
+ struct amb_dev *dev = container_of(f, struct amb_dev, func);
+ int ret = -ENOTSUPP;
+
+ if (!alt)
+ ret = amb_set_interface(dev, inf);
+ return ret;
+}
+
+static void amb_func_disable(struct usb_function *f)
+{
+ struct amb_dev *dev = container_of(f, struct amb_dev, func);
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->lock, flags);
+ amb_reset_config(dev);
+ spin_unlock_irqrestore(&dev->lock, flags);
+}
+
+static int __init amb_bind_config(struct usb_configuration *c)
+{
+ struct usb_gadget *gadget = c->cdev->gadget;
+ struct amb_dev *dev;
+ struct device *pdev;
+ int status = -ENOMEM;
+
+ usb_ep_autoconfig_reset(gadget);
+
+ dev = kzalloc(sizeof(struct amb_dev), GFP_KERNEL);
+ if (!dev)
+ return -ENOMEM;
+
+ dev->func.name = shortname;
+ dev->func.bind = amb_func_bind;
+ dev->func.unbind = amb_func_unbind;
+ dev->func.set_alt = amb_func_set_alt;
+ dev->func.disable = amb_func_disable;
+
+ spin_lock_init (&dev->lock);
+ mutex_init(&dev->mtx);
+ init_waitqueue_head(&dev->wq);
+ INIT_LIST_HEAD(&dev->in_idle_list);
+ INIT_LIST_HEAD(&dev->in_queue_list);
+ INIT_LIST_HEAD(&dev->out_req_list);
+
+ dev->gadget = gadget;
+ dev->error = 0;
+ ag_device = dev;
+
+ status = usb_add_function(c, &dev->func);
+ if (status) {
+ kfree(dev);
+ return status;
+ }
+
+ /* Setup the sysfs files for the gadget. */
+ pdev = device_create(ag_class, NULL, ag_dev_id,
+ NULL, "amb_gadget");
+ if (IS_ERR(pdev)) {
+ status = PTR_ERR(pdev);
+ ERROR(dev, "Failed to create device: amb_gadget\n");
+ goto fail;
+ }
+
+ usb_gadget_set_selfpowered(gadget);
+
+ if (gadget->is_otg) {
+ otg_descriptor.bmAttributes |= USB_OTG_HNP;
+ amb_config_driver.descriptors = otg_desc;
+ amb_config_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+ }
+#if 0
+ spin_lock_init (&dev->lock);
+ mutex_init(&dev->mtx);
+ init_waitqueue_head(&dev->wq);
+ INIT_LIST_HEAD(&dev->in_idle_list);
+ INIT_LIST_HEAD(&dev->in_queue_list);
+ INIT_LIST_HEAD(&dev->out_req_list);
+
+ dev->gadget = gadget;
+ dev->error = 0;
+ ag_device = dev;
+#endif
+ return 0;
+
+fail:
+ amb_cfg_unbind(c);
+ return status;
+}
+
+static int amb_unbind(struct usb_composite_dev *cdev)
+{
+#if 0
+ struct usb_gadget *gadget = cdev->gadget;
+ struct amb_dev *dev = get_gadget_data (gadget);
+
+ kfree (dev);
+ set_gadget_data(gadget, NULL);
+ ag_device = NULL;
+#else
+#endif
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static int __init amb_bind(struct usb_composite_dev *cdev)
+{
+ int ret;
+ ret = usb_string_ids_tab(cdev, strings);
+ if (ret < 0)
+ return ret;
+
+ ag_device_desc.iManufacturer = strings[USB_GADGET_MANUFACTURER_IDX].id;
+ ag_device_desc.iProduct = strings[USB_GADGET_PRODUCT_IDX].id;
+ ag_device_desc.iSerialNumber = strings[USB_GADGET_SERIAL_IDX].id;
+ amb_config_driver.iConfiguration = strings[STRING_SOURCE_SINK].id;
+
+ ret = usb_add_config(cdev, &amb_config_driver, amb_bind_config);
+ if (ret < 0)
+ return ret;
+
+ usb_composite_overwrite_options(cdev, &coverwrite);
+ INFO(cdev, "%s, version: " DRIVER_VERSION "\n", longname);
+
+ return 0;
+}
+
+static __refdata struct usb_composite_driver amb_gadget_driver = {
+ .name = shortname,
+ .dev = &ag_device_desc,
+ .strings = dev_strings,
+ .max_speed = USB_SPEED_HIGH,
+ .bind = amb_bind,
+ .unbind = amb_unbind,
+};
+
+static int __init amb_gadget_init(void)
+{
+ int rval = 0;
+
+ ag_class = class_create(THIS_MODULE, "amb_stream_gadget");
+ if (IS_ERR(ag_class)) {
+ rval = PTR_ERR(ag_class);
+ pr_err("unable to create usb_gadget class %d\n", rval);
+ return rval;
+ }
+
+ if (buflen >= 65536) {
+ pr_err("amb_gadget_init: buflen is too large\n");
+ rval = -EINVAL;
+ goto out1;
+ }
+
+ ag_dev_id = MKDEV(AMB_GADGET_MAJOR, AMB_GADGET_MINOR_START);
+ rval = register_chrdev_region(ag_dev_id, 1, "amb_gadget");
+ if(rval < 0){
+ pr_err("amb_gadget_init: register devcie number error!\n");
+ goto out1;
+ }
+
+ cdev_init(&ag_cdev, &ag_fops);
+ ag_cdev.owner = THIS_MODULE;
+ rval = cdev_add(&ag_cdev, ag_dev_id, 1);
+ if (rval) {
+ pr_err("amb_gadget_init: cdev_add failed\n");
+ unregister_chrdev_region(ag_dev_id, 1);
+ goto out1;
+ }
+
+ rval = usb_composite_probe(&amb_gadget_driver);
+ if (rval) {
+ pr_err("amb_gadget_init: cannot register gadget driver, "
+ "rval=%d\n", rval);
+ class_destroy(ag_class);
+ goto out0;
+ }
+out1:
+ if(rval)
+ class_destroy(ag_class);
+out0:
+ return rval;
+}
+module_init (amb_gadget_init);
+
+static void __exit amb_gadget_exit (void)
+{
+ usb_composite_unregister(&amb_gadget_driver);
+
+ unregister_chrdev_region(ag_dev_id, 1);
+ cdev_del(&ag_cdev);
+ class_destroy(ag_class);
+}
+module_exit (amb_gadget_exit);
+
+MODULE_AUTHOR ("Cao Rongrong <rrcao@ambarella.com>");
+MODULE_LICENSE ("GPL");
+
+
diff --git a/drivers/usb/gadget/ambarella_udc.c b/drivers/usb/gadget/ambarella_udc.c
new file mode 100644
index 00000000..ea855a75
--- /dev/null
+++ b/drivers/usb/gadget/ambarella_udc.c
@@ -0,0 +1,2349 @@
+/*
+* linux/drivers/usb/gadget/ambarella_udc.c
+* driver for High/Full speed USB device controller on Ambarella processors
+*
+* History:
+* 2008/06/12 - [Cao Rongrong] created file
+* 2009/03/16 - [Cao Rongrong] Change DMA descriptor allocate mode
+*
+* Copyright (C) 2008 by Ambarella, Inc.
+* http://www.ambarella.com
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the
+* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+* Boston, MA 02111-1307, USA.
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmapool.h>
+#include <linux/usb.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/otg.h>
+#include <linux/proc_fs.h>
+#include <linux/of.h>
+#include <mach/hardware.h>
+#include <plat/rct.h>
+#include <plat/udc.h>
+#include "ambarella_udc.h"
+
+#define DRIVER_DESC "Ambarella USB Device Controller Gadget"
+#define DRIVER_VERSION "12 August 2015"
+#define DRIVER_AUTHOR "Cao Rongrong <rrcao@ambarella.com>"
+
+#define DMA_ADDR_INVALID (~(dma_addr_t)0)
+
+static const char gadget_name[] = "ambarella_udc";
+#if 0
+static const char driver_desc[] = DRIVER_DESC;
+static const char ep0name [] = "ep0";
+#endif
+
+static const char *amb_ep_string[] = {
+ "ep0in", "ep1in", "ep2in", "ep3in",
+ "ep4in", "ep5in", "ep6in", "ep7in",
+ "ep8in", "ep9in", "ep10in", "ep11in",
+ "ep12in", "ep13in", "ep14in", "ep15in",
+
+ "ep0out", "ep1out", "ep2out", "ep3out",
+ "ep4out", "ep5out", "ep6out", "ep7out",
+ "ep8out", "ep9out", "ep10out", "ep11out",
+ "ep12out", "ep13out", "ep14out", "ep15out"
+};
+
+/*************************** DEBUG FUNCTION ***************************/
+#define DEBUG_NORMAL 0
+#define DEBUG_VERBOSE 1
+
+#define AMBARELLA_USB_DEBUG 0
+#if AMBARELLA_USB_DEBUG
+
+#define dprintk(level,format,args...) \
+ do { \
+ if(level < 1) \
+ printk(KERN_DEBUG "%s: " format, __FUNCTION__,## args); \
+ } while(0)
+
+#else
+#define dprintk(args...) do { } while(0)
+#endif
+
+
+static inline struct ambarella_ep *to_ambarella_ep(struct usb_ep *ep)
+{
+ return container_of(ep, struct ambarella_ep, ep);
+}
+
+static inline struct ambarella_udc *to_ambarella_udc(struct usb_gadget *gadget)
+{
+ return container_of(gadget, struct ambarella_udc, gadget);
+}
+
+static inline struct ambarella_request *to_ambarella_req(struct usb_request *req)
+{
+ return container_of(req, struct ambarella_request, req);
+}
+
+
+/************** PROC FILESYSTEM BEGIN *****************/
+
+static void ambarella_uevent_work(struct work_struct *data)
+{
+ struct ambarella_udc *udc;
+ char buf_status[64];
+ char buf_vbus[64];
+ char buf_driver[64];
+ char *envp[4];
+
+ udc = container_of(data, struct ambarella_udc, uevent_work);
+ buf_status[0] = '\0';
+ buf_vbus[0] = '\0';
+ buf_driver[0] = '\0';
+
+ spin_lock_irq(&udc->lock);
+ if (udc->pre_state == udc->gadget.state) {
+ spin_unlock_irq(&udc->lock);
+ return;
+ }
+
+ udc->pre_state = udc->gadget.state;
+ snprintf(buf_status, sizeof(buf_status),
+ "AMBUDC_STATUS=%s", usb_state_string(udc->gadget.state));
+ snprintf(buf_vbus, sizeof(buf_vbus), "AMBUDC_VBUS=%s",
+ udc->vbus_status ? "Connected" : "Disconnected");
+ snprintf(buf_driver, sizeof(buf_driver), "AMBUDC_DRIVER=%s",
+ udc->driver ? udc->driver->driver.name : "NULL");
+ spin_unlock_irq(&udc->lock);
+
+ envp[0] = buf_status;
+ envp[1] = buf_vbus;
+ envp[2] = buf_driver;
+ envp[3] = NULL;
+ kobject_uevent_env(&udc->dev->kobj, KOBJ_CHANGE, envp);
+}
+
+/* ========================================================================== */
+#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+#include <linux/seq_file.h>
+
+static const char proc_node_name[] = "driver/udc";
+static int ambarella_udc_proc_show(struct seq_file *m, void *v)
+{
+ struct ambarella_udc *udc;
+ struct usb_ctrlrequest *crq;
+
+ unsigned long flags;
+ udc = (struct ambarella_udc *)m->private;
+ crq = (struct usb_ctrlrequest *)&udc->setup[0];
+
+ spin_lock_irqsave(&udc->lock, flags);
+
+ /* basic device status */
+ seq_printf(m,
+ DRIVER_DESC "\n"
+ "Name: %s\n"
+ "Version: %s\n"
+ "Author: %s\n\n"
+ "Gadget driver: %s\n"
+ "Host: %s\n\n",
+ gadget_name,
+ DRIVER_VERSION,
+ DRIVER_AUTHOR,
+ udc->driver ? udc->driver->driver.name : "(none)",
+ udc->vbus_status ? (udc->gadget.speed == USB_SPEED_HIGH ?
+ "high speed" : "full speed") : "disconnected");
+
+ seq_printf(m, "AMBUDC_STATUS=%s",
+ usb_state_string(udc->gadget.state));
+
+ seq_printf(m,
+ "the last setup packet is: \n"
+ "bRequestType = 0x%02x, bRequest = 0x%02x,\n"
+ "wValue = 0x%04x, wIndex = 0x%04x, wLength = 0x%04x\n\n",
+ crq->bRequestType, crq->bRequest, crq->wValue, crq->wIndex,
+ crq->wLength);
+ spin_unlock_irqrestore(&udc->lock, flags);
+ return 0;
+}
+static int ambarella_udc_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ambarella_udc_proc_show, PDE_DATA(inode));
+}
+
+static const struct file_operations ambarella_udc_fops = {
+ .open = ambarella_udc_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+#define remove_debugfs_files() remove_proc_entry(proc_node_name, NULL)
+#endif /* CONFIG_USB_GADGET_DEBUG_FILES */
+
+/************** PROC FILESYSTEM END*****************/
+
+static void ambarella_regaddr_map(struct ambarella_udc *udc)
+{
+ u32 i;
+
+ for(i = 0; i < EP_NUM_MAX; i++) {
+ struct ambarella_ep *ep;
+ ep = &udc->ep[i];
+ if(ep->dir == USB_DIR_IN){
+ ep->ep_reg.ctrl_reg = USB_EP_IN_CTRL_REG(ep->id);
+ ep->ep_reg.sts_reg = USB_EP_IN_STS_REG(ep->id);
+ ep->ep_reg.buf_sz_reg = USB_EP_IN_BUF_SZ_REG(ep->id);
+ ep->ep_reg.max_pkt_sz_reg =
+ USB_EP_IN_MAX_PKT_SZ_REG(ep->id);
+ ep->ep_reg.dat_desc_ptr_reg =
+ USB_EP_IN_DAT_DESC_PTR_REG(ep->id);
+ } else {
+ ep->ep_reg.ctrl_reg = USB_EP_OUT_CTRL_REG(ep->id - 16);
+ ep->ep_reg.sts_reg = USB_EP_OUT_STS_REG(ep->id - 16);
+ ep->ep_reg.buf_sz_reg =
+ USB_EP_OUT_PKT_FRM_NUM_REG(ep->id - 16);
+ ep->ep_reg.max_pkt_sz_reg =
+ USB_EP_OUT_MAX_PKT_SZ_REG(ep->id - 16);
+ ep->ep_reg.dat_desc_ptr_reg =
+ USB_EP_OUT_DAT_DESC_PTR_REG(ep->id - 16);
+ }
+
+ ep->ep_reg.setup_buf_ptr_reg = (i == CTRL_OUT) ?
+ USB_EP_OUT_SETUP_BUF_PTR_REG(ep->id - 16) : (u32)NULL;
+ }
+}
+
+
+static void ambarella_disable_all_intr(void)
+{
+ /* device interrupt mask register */
+ amba_writel(USB_DEV_INTR_MSK_REG, 0x0000007f);
+ amba_writel(USB_DEV_EP_INTR_MSK_REG, 0xffffffff);
+ amba_writel(USB_DEV_INTR_REG, 0x0000007f);
+ amba_writel(USB_DEV_EP_INTR_REG, 0xffffffff);
+}
+
+static void ambarella_ep_fifo_flush(struct ambarella_ep *ep)
+{
+ if(ep->dir == USB_DIR_IN) /* Empty Tx FIFO */
+ amba_setbitsl(ep->ep_reg.ctrl_reg, USB_EP_FLUSH);
+ else { /* Empty RX FIFO */
+ if (!(amba_readl(USB_DEV_STS_REG) & USB_DEV_RXFIFO_EMPTY_STS)) {
+ int retry_count = 1000;
+
+ amba_setbitsl(USB_DEV_CTRL_REG, USB_DEV_NAK);
+ amba_setbitsl(USB_DEV_CTRL_REG, USB_DEV_FLUSH_RXFIFO);
+ while(!(amba_readl(USB_DEV_STS_REG) & USB_DEV_RXFIFO_EMPTY_STS)) {
+ if (retry_count-- < 0) {
+ printk (KERN_ERR "%s: failed", __func__);
+ break;
+ }
+ udelay(5);
+ }
+ amba_clrbitsl(USB_DEV_CTRL_REG, USB_DEV_NAK);
+ }
+ }
+}
+
+
+/*
+ * Name: ambarella_flush_fifo
+ * Description:
+ * Empty Tx/Rx FIFO of DMA
+ */
+static void ambarella_udc_fifo_flush(struct ambarella_udc *udc)
+{
+ struct ambarella_ep *ep;
+ u32 ep_id;
+
+ for (ep_id = 0; ep_id < EP_NUM_MAX; ep_id++) {
+ ep = &udc->ep[ep_id];
+ if(ep->ep.desc == NULL && !IS_EP0(ep))
+ continue;
+ ambarella_ep_fifo_flush(ep);
+ }
+}
+
+static void ambarella_udc_reset(void __iomem *reset_reg, struct device_node *np)
+{
+ amba_rct_setbitsl(reset_reg, UDC_SOFT_RESET_MASK);
+ msleep(1);
+ amba_rct_clrbitsl(reset_reg, UDC_SOFT_RESET_MASK);
+};
+
+static void ambarella_init_usb(struct ambarella_udc *udc)
+{
+ u32 value;
+
+ /* disconnect to host */
+ amba_setbitsl(USB_DEV_CTRL_REG, USB_DEV_SOFT_DISCON);
+ /* disable all interrupts */
+ ambarella_disable_all_intr();
+ /* disable Tx and Rx DMA */
+ amba_clrbitsl(USB_DEV_CTRL_REG, USB_DEV_RCV_DMA_EN | USB_DEV_TRN_DMA_EN);
+ /* flush dma fifo, may used in AMboot */
+ ambarella_udc_fifo_flush(udc);
+
+ /* device config register */
+ value = USB_DEV_SPD_HI |
+ USB_DEV_SELF_POWER |
+ USB_DEV_PHY_8BIT |
+ USB_DEV_UTMI_DIR_BI |
+ USB_DEV_HALT_ACK |
+ USB_DEV_SET_DESC_STALL |
+ USB_DEV_DDR |
+ USB_DEV_CSR_PRG_EN |
+ USB_DEV_REMOTE_WAKEUP_EN;
+
+ amba_setbitsl(USB_DEV_CFG_REG, value);
+
+ /* device control register */
+ value = USB_DEV_DESC_UPD_PYL |
+ USB_DEV_LITTLE_ENDN |
+ USB_DEV_DMA_MD;
+
+ amba_setbitsl(USB_DEV_CTRL_REG, value);
+
+ // udelay(200); // FIXME: how long to wait is the best?
+}
+
+
+/*
+ * Name: init_setup_descriptor
+ * Description:
+ * Config the setup packet to specific endpoint register
+ */
+static void init_setup_descriptor(struct ambarella_udc *udc)
+{
+ struct ambarella_ep *ep = &udc->ep[CTRL_OUT];
+
+ udc->setup_buf->status = USB_DMA_BUF_HOST_RDY;
+ udc->setup_buf->reserved = 0xffffffff;
+ udc->setup_buf->data0 = 0xffffffff;
+ udc->setup_buf->data1 = 0xffffffff;
+
+ amba_writel(ep->ep_reg.setup_buf_ptr_reg, udc->setup_addr | udc->dma_fix);
+}
+
+
+static int init_null_pkt_desc(struct ambarella_udc *udc)
+{
+ udc->dummy_desc = dma_pool_alloc(udc->desc_dma_pool, GFP_KERNEL,
+ &udc->dummy_desc_addr);
+ if(udc->dummy_desc == NULL){
+ printk(KERN_ERR "No memory to DMA\n");
+ return -ENOMEM;
+ }
+
+ udc->dummy_desc->data_ptr = udc->dummy_desc_addr | udc->dma_fix;
+ udc->dummy_desc->reserved = 0xffffffff;
+ udc->dummy_desc->next_desc_ptr = udc->dummy_desc_addr | udc->dma_fix;
+ udc->dummy_desc->status = USB_DMA_BUF_HOST_RDY | USB_DMA_LAST;
+
+ return 0;
+}
+
+static void init_ep0(struct ambarella_udc *udc)
+{
+ struct ambarella_ep_reg *ep_reg;
+
+ ep_reg = &udc->ep[CTRL_IN].ep_reg;
+ amba_writel(ep_reg->ctrl_reg, USB_EP_TYPE_CTRL);
+ amba_writel(ep_reg->buf_sz_reg, USB_TXFIFO_DEPTH_CTRLIN);
+ amba_writel(ep_reg->max_pkt_sz_reg, USB_EP_CTRLIN_MAX_PKT_SZ);
+ udc->ep[CTRL_IN].ctrl_sts_phase = 0;
+
+ ep_reg = &udc->ep[CTRL_OUT].ep_reg;
+ amba_writel(ep_reg->ctrl_reg, USB_EP_TYPE_CTRL);
+ amba_writel(ep_reg->max_pkt_sz_reg, USB_EP_CTRL_MAX_PKT_SZ);
+ init_setup_descriptor(udc);
+ udc->ep[CTRL_OUT].ctrl_sts_phase = 0;
+
+ /* This should be set after gadget->bind */
+ udc->ep[CTRL_OUT].ep.driver_data = udc->ep[CTRL_IN].ep.driver_data;
+
+ /* FIXME: For A5S, this bit must be set,
+ * or USB_UDC_REG can't be read or write */
+ amba_setbitsl(USB_DEV_CTRL_REG, USB_DEV_REMOTE_WAKEUP);
+
+ /* setup ep0 CSR. Note: ep0-in and ep0-out share the same CSR reg */
+ amba_clrbitsl(USB_UDC_REG(CTRL_IN), 0x7ff << 19);
+ amba_setbitsl(USB_UDC_REG(CTRL_IN), USB_EP_CTRL_MAX_PKT_SZ << 19);
+ /* the direction bit should not take effect for ep0 */
+ amba_setbitsl(USB_UDC_REG(CTRL_IN), 0x1 << 4);
+}
+
+static int ambarella_map_dma_buffer(struct ambarella_ep *ep,
+ struct ambarella_request *req)
+{
+ struct ambarella_udc *udc = ep->udc;
+ enum dma_data_direction dmadir;
+
+ dmadir = (ep->dir & USB_DIR_IN) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+
+ if (likely(!req->use_aux_buf)) {
+ /* map req.buf, and get req's dma address */
+ if (req->req.dma == DMA_ADDR_INVALID) {
+ req->req.dma = dma_map_single(udc->dev,
+ req->req.buf, req->req.length, dmadir);
+ /* dma address isn't 8-byte align */
+ if(req->req.dma & 0x7){
+ printk("dma address isn't 8-byte align\n");
+ BUG();
+ }
+ req->mapped = 1;
+ } else {
+ dma_sync_single_for_device(udc->dev,
+ req->req.dma, req->req.length, dmadir);
+ req->mapped = 0;
+ }
+ } else {
+ if (req->dma_aux == DMA_ADDR_INVALID) {
+ req->dma_aux = dma_map_single(udc->dev,
+ req->buf_aux, req->req.length, dmadir);
+ /* dma address isn't 8-byte align */
+ if(req->dma_aux & 0x7){
+ printk("dma address isn't 8-byte align\n");
+ BUG();
+ }
+ req->mapped = 1;
+ } else {
+ dma_sync_single_for_device(udc->dev,
+ req->dma_aux, req->req.length, dmadir);
+ req->mapped = 0;
+ }
+ }
+
+ return 0;
+}
+
+
+static int ambarella_unmap_dma_buffer(struct ambarella_ep *ep,
+ struct ambarella_request *req)
+{
+ struct ambarella_udc *udc = ep->udc;
+ enum dma_data_direction dmadir;
+
+ dmadir = (ep->dir & USB_DIR_IN) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+
+ if (likely(!req->use_aux_buf)) {
+ if (req->mapped) {
+ dma_unmap_single(udc->dev,
+ req->req.dma, req->req.length, dmadir);
+ req->req.dma = DMA_ADDR_INVALID;
+ req->mapped = 0;
+ } else {
+ dma_sync_single_for_cpu(udc->dev,
+ req->req.dma, req->req.length, dmadir);
+ }
+ } else {
+ if (req->mapped) {
+ dma_unmap_single(udc->dev,
+ req->dma_aux, req->req.length, dmadir);
+ req->dma_aux = DMA_ADDR_INVALID;
+ req->mapped = 0;
+ } else {
+ dma_sync_single_for_cpu(udc->dev,
+ req->dma_aux, req->req.length, dmadir);
+ }
+ }
+
+ return 0;
+}
+
+static struct ambarella_data_desc *ambarella_get_last_desc(struct ambarella_ep *ep)
+{
+ struct ambarella_data_desc *desc = ep->data_desc;
+ int retry_count = 1000;
+
+ while(desc && (desc->status & USB_DMA_LAST) == 0) {
+ if (retry_count-- < 0) {
+ printk(KERN_ERR "Can't find the last descriptor\n");
+ break;
+ }
+
+ if (desc->last_aux == 1)
+ break;
+
+ desc = desc->next_desc_virt;
+ };
+
+ return desc;
+}
+
+static u32 ambarella_check_bna_error (struct ambarella_ep *ep, u32 ep_status)
+{
+ u32 retval = 0;
+
+ /* Error: Buffer Not Available */
+ if (ep_status & USB_EP_BUF_NOT_AVAIL) {
+ //printk(KERN_ERR "[USB]:BNA error in %s\n", ep->ep.name);
+ amba_writel(ep->ep_reg.sts_reg, USB_EP_BUF_NOT_AVAIL);
+ retval = 1;
+ }
+
+ return retval;
+}
+
+static u32 ambarella_check_he_error (struct ambarella_ep *ep, u32 ep_status)
+{
+ u32 retval = 0;
+
+ /* Error: Host Error */
+ if (ep_status & USB_EP_HOST_ERR) {
+ printk(KERN_ERR "[USB]:HE error in %s\n", ep->ep.name);
+ amba_writel(ep->ep_reg.sts_reg, USB_EP_HOST_ERR);
+ retval = 1;
+ }
+
+ return retval;
+}
+
+static u32 ambarella_check_dma_error (struct ambarella_ep *ep)
+{
+ u32 retval = 0, sts_tmp1, sts_tmp2;
+
+ if(ep->last_data_desc){
+ sts_tmp1 = ep->last_data_desc->status & USB_DMA_BUF_STS;
+ sts_tmp2 = ep->last_data_desc->status & USB_DMA_RXTX_STS;
+ if ((sts_tmp1 != USB_DMA_BUF_DMA_DONE) || (sts_tmp2 != USB_DMA_RXTX_SUCC)){
+ //printk(KERN_ERR "%s: DMA failed\n", ep->ep.name);
+ retval = 1;
+ }
+ }
+
+
+ return retval;
+}
+
+
+static void ambarella_free_descriptor(struct ambarella_ep *ep,
+ struct ambarella_request *req)
+{
+ struct ambarella_data_desc *data_desc, *next_data_desc;
+ struct dma_pool *desc_dma_pool = ep->udc->desc_dma_pool;
+ int i;
+
+ next_data_desc = req->data_desc;
+ for(i = 0; i < req->desc_count; i++){
+ data_desc = next_data_desc;
+ data_desc->status = USB_DMA_BUF_HOST_BUSY | USB_DMA_LAST;
+ data_desc->data_ptr = 0xffffffff;
+ data_desc->next_desc_ptr = 0;
+ data_desc->last_aux = 1;
+ next_data_desc = data_desc->next_desc_virt;
+ dma_pool_free(desc_dma_pool, data_desc, data_desc->cur_desc_addr);
+ }
+
+ req->desc_count = 0;
+ req->data_desc = NULL;
+ req->data_desc_addr = 0;
+}
+
+static int ambarella_reuse_descriptor(struct ambarella_ep *ep,
+ struct ambarella_request *req, u32 desc_count, dma_addr_t start_address)
+{
+ struct ambarella_udc *udc = ep->udc;
+ struct ambarella_data_desc *data_desc, *next_data_desc;
+ u32 data_transmit, rest_bytes, i;
+ dma_addr_t buf_dma_address;
+
+ next_data_desc = req->data_desc;
+ for(i = 0; i < desc_count; i++){
+ rest_bytes = req->req.length - i * ep->ep.maxpacket;
+ if(ep->dir == USB_DIR_IN)
+ data_transmit = rest_bytes < ep->ep.maxpacket ?
+ rest_bytes : ep->ep.maxpacket;
+ else
+ data_transmit = 0;
+
+ data_desc = next_data_desc;
+ data_desc->status = USB_DMA_BUF_HOST_RDY | data_transmit;
+ data_desc->reserved = 0xffffffff;
+ buf_dma_address = start_address + i * ep->ep.maxpacket;
+ data_desc->data_ptr = buf_dma_address | udc->dma_fix;
+ data_desc->last_aux = 0;
+
+ next_data_desc = data_desc->next_desc_virt;
+ }
+
+ /* Patch last one. */
+ data_desc->status |= USB_DMA_LAST;
+ data_desc->last_aux = 1;
+
+ return 0;
+}
+
+static int ambarella_prepare_descriptor(struct ambarella_ep *ep,
+ struct ambarella_request *req, gfp_t gfp)
+{
+ struct ambarella_udc *udc = ep->udc;
+ struct ambarella_data_desc *data_desc = NULL;
+ struct ambarella_data_desc *prev_data_desc = NULL;
+ dma_addr_t desc_phys, start_address, buf_dma_address;
+ u32 desc_count, data_transmit, rest_bytes, i;
+
+ if (likely(!req->use_aux_buf))
+ start_address = req->req.dma;
+ else
+ start_address = req->dma_aux;
+
+ desc_count = (req->req.length + ep->ep.maxpacket - 1) / ep->ep.maxpacket;
+ if(req->req.zero && (req->req.length % ep->ep.maxpacket == 0))
+ desc_count++;
+ if(desc_count == 0)
+ desc_count = 1;
+
+ req->active_desc_count = desc_count;
+
+ if (desc_count <= req->desc_count) {
+ ambarella_reuse_descriptor(ep, req, desc_count, start_address);
+ return 0;
+ }
+
+ if(req->desc_count > 0)
+ ambarella_free_descriptor(ep, req);
+
+ req->desc_count = desc_count;
+
+ for(i = 0; i < desc_count; i++){
+ rest_bytes = req->req.length - i * ep->ep.maxpacket;
+ if(ep->dir == USB_DIR_IN)
+ data_transmit = rest_bytes < ep->ep.maxpacket ?
+ rest_bytes : ep->ep.maxpacket;
+ else
+ data_transmit = 0;
+
+ data_desc = dma_pool_alloc(udc->desc_dma_pool, gfp, &desc_phys);
+ if (!data_desc) {
+ req->desc_count = i;
+ if(req->desc_count > 0)
+ ambarella_free_descriptor(ep, req);
+ return -ENOMEM;
+ }
+
+ data_desc->status = USB_DMA_BUF_HOST_RDY | data_transmit;
+ data_desc->reserved = 0xffffffff;
+ buf_dma_address = start_address + i * ep->ep.maxpacket;
+ data_desc->data_ptr = buf_dma_address | udc->dma_fix;
+ data_desc->next_desc_ptr = 0;
+ data_desc->rsvd1 = 0xffffffff;
+ data_desc->last_aux = 0;
+ data_desc->cur_desc_addr = desc_phys;
+
+ if(prev_data_desc){
+ prev_data_desc->next_desc_ptr = desc_phys | udc->dma_fix;
+ prev_data_desc->next_desc_virt = data_desc;
+ }
+
+ prev_data_desc = data_desc;
+
+ if(i == 0){
+ req->data_desc = data_desc;
+ req->data_desc_addr = desc_phys;
+ }
+ }
+
+ /* Patch last one */
+ data_desc->status |= USB_DMA_LAST;
+ data_desc->next_desc_ptr = 0;
+ data_desc->next_desc_virt = NULL;
+ data_desc->last_aux = 1;
+
+ return 0;
+}
+
+static void ambarella_clr_ep_nak(struct ambarella_ep *ep)
+{
+ struct ambarella_ep_reg *ep_reg = &ep->ep_reg;
+
+ amba_setbitsl(ep_reg->ctrl_reg, USB_EP_CLR_NAK);
+ if (amba_readl(ep_reg->ctrl_reg) & USB_EP_NAK_STS) {
+ /* can't clear NAK, let somebody clear it after Rx DMA is done. */
+ ep->need_cnak = 1;
+ }else{
+ ep->need_cnak = 0;
+ }
+}
+
+static void ambarella_set_ep_nak(struct ambarella_ep *ep)
+{
+ amba_setbitsl(ep->ep_reg.ctrl_reg, USB_EP_SET_NAK);
+}
+
+static void ambarella_enable_rx_dma(struct ambarella_ep *ep)
+{
+ ep->dma_going = 1;
+ amba_setbitsl(USB_DEV_CTRL_REG, USB_DEV_RCV_DMA_EN);
+}
+
+static void ambarella_patch_iso_desc(struct ambarella_udc *udc,
+ struct ambarella_request * req, struct ambarella_ep *ep, int frame_fix)
+{
+ struct ambarella_data_desc *data_desc;
+ u32 current_frame, max_packet_num, i, j;
+
+ current_frame = ambarella_udc_get_frame(&udc->gadget);
+ data_desc = req->data_desc;
+
+ /* according to USB2.0 spec, each microframe can send 3 packets at most */
+ for (i = 0; i < req->active_desc_count; i += j) {
+ if ((req->active_desc_count - i) >= ISO_MAX_PACKET)
+ max_packet_num = ISO_MAX_PACKET;
+ else
+ max_packet_num = req->active_desc_count - i;
+
+ for (j = 0; j < max_packet_num; j++) {
+ data_desc->status |= ((current_frame + ep->frame_offset + frame_fix) << 16);
+ data_desc->status |= (max_packet_num << 14);
+ data_desc = data_desc->next_desc_virt;
+ }
+ }
+}
+
+static void ambarella_set_tx_dma(struct ambarella_ep *ep,
+ struct ambarella_request * req, int frame_fix)
+{
+ struct ambarella_udc *udc = ep->udc;
+ struct ambarella_ep_reg *ep_reg = &ep->ep_reg;
+
+ if (IS_ISO_IN_EP(ep))
+ ambarella_patch_iso_desc(udc, req, ep, frame_fix);
+
+ ep->data_desc = req->data_desc;
+ amba_writel(ep_reg->dat_desc_ptr_reg, req->data_desc_addr | udc->dma_fix);
+ /* set Poll command to transfer data to Tx FIFO */
+ amba_setbitsl(ep_reg->ctrl_reg, USB_EP_POLL_DEMAND);
+ ep->dma_going = 1;
+}
+
+
+static void ambarella_set_rx_dma(struct ambarella_ep *ep,
+ struct ambarella_request * req)
+{
+ struct ambarella_ep_reg *ep_reg = &ep->ep_reg;
+ struct ambarella_udc *udc = ep->udc;
+ u32 i;
+
+ if(req){
+ ep->data_desc = req->data_desc;
+ amba_writel(ep_reg->dat_desc_ptr_reg,
+ req->data_desc_addr | udc->dma_fix);
+ } else {
+ /* receive zero-length-packet */
+ udc->dummy_desc->status = USB_DMA_BUF_HOST_RDY | USB_DMA_LAST;
+ amba_writel(ep_reg->dat_desc_ptr_reg,
+ udc->dummy_desc_addr | udc->dma_fix);
+ }
+
+ /* enable dma completion interrupt for next RX data */
+ amba_clrbitsl(USB_DEV_EP_INTR_MSK_REG, 1 << ep->id);
+ /* re-enable DMA read */
+ ambarella_enable_rx_dma(ep);
+
+ if (amba_readl(USB_DEV_STS_REG) & USB_DEV_RXFIFO_EMPTY_STS) {
+ /* clear NAK for TX dma */
+ for (i = 0; i < EP_NUM_MAX; i++) {
+ struct ambarella_ep *_ep = &udc->ep[i];
+ if (_ep->need_cnak == 1)
+ ambarella_clr_ep_nak(_ep);
+ }
+ }
+
+ /* clear NAK */
+ ambarella_clr_ep_nak(ep);
+}
+
+static int ambarella_handle_ep_stall(struct ambarella_ep *ep, u32 ep_status)
+{
+ int ret = 0;
+
+ if (ep_status & USB_EP_RCV_CLR_STALL) {
+ amba_setbitsl(ep->ep_reg.ctrl_reg, USB_EP_CLR_NAK);
+ amba_clrbitsl(ep->ep_reg.ctrl_reg, USB_EP_STALL);
+ amba_setbitsl(ep->ep_reg.sts_reg, USB_EP_RCV_CLR_STALL);
+ ret = 1;
+ }
+
+ if (ep_status & USB_EP_RCV_SET_STALL) {
+ amba_setbitsl(ep->ep_reg.ctrl_reg, USB_EP_STALL);
+ if (ep->dir == USB_DIR_IN)
+ amba_setbitsl(ep->ep_reg.ctrl_reg, USB_EP_FLUSH);
+ amba_setbitsl(ep->ep_reg.sts_reg, USB_EP_RCV_SET_STALL);
+ ret = 1;
+ }
+
+ return ret;
+}
+
+static void ambarella_handle_request_packet(struct ambarella_udc *udc)
+{
+ struct usb_ctrlrequest *crq;
+ int ret;
+
+ ambarella_ep_nuke(&udc->ep[CTRL_OUT], -EPROTO); // Todo
+
+ /* read out setup packet */
+ udc->setup[0] = udc->setup_buf->data0;
+ udc->setup[1] = udc->setup_buf->data1;
+ /* reinitialize setup packet */
+ init_setup_descriptor(udc);
+
+ crq = (struct usb_ctrlrequest *) &udc->setup[0];
+
+ dprintk(DEBUG_NORMAL, "bRequestType = 0x%02x, bRequest = 0x%02x, "
+ "wValue = 0x%04x, wIndex = 0x%04x, wLength = 0x%04x\n",
+ crq->bRequestType, crq->bRequest, crq->wValue, crq->wIndex,
+ crq->wLength);
+
+ if((crq->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD){
+ switch(crq->bRequest)
+ {
+ case USB_REQ_GET_STATUS:
+ case USB_REQ_SET_ADDRESS:
+ case USB_REQ_CLEAR_FEATURE:
+ case USB_REQ_SET_FEATURE:
+ pr_err("%s: This bRequest is not implemented!\n"
+ "\tbRequestType = 0x%02x, bRequest = 0x%02x,\n"
+ "\twValue = 0x%04x, wIndex = 0x%04x, wLength = 0x%04x\n",
+ __func__,
+ crq->bRequestType, crq->bRequest, crq->wValue, crq->wIndex,
+ crq->wLength);
+ }
+ }
+
+ if (crq->bRequestType & USB_DIR_IN)
+ udc->gadget.ep0 = &udc->ep[CTRL_IN].ep;
+
+ else
+ udc->gadget.ep0 = &udc->ep[CTRL_OUT].ep;
+
+ spin_unlock(&udc->lock);
+ ret = udc->driver->setup(&udc->gadget, crq);
+ spin_lock(&udc->lock);
+ if (ret < 0) {
+ pr_err("%s: SETUP request failed (%d)\n", __func__, ret);
+ amba_setbitsl(udc->ep[CTRL_IN].ep_reg.ctrl_reg, USB_EP_STALL | USB_EP_FLUSH);
+ /* Re-enable Rx DMA to receive next setup packet */
+ ambarella_enable_rx_dma(&udc->ep[CTRL_OUT]);
+ ambarella_clr_ep_nak(&udc->ep[CTRL_OUT]);
+ }
+
+ return;
+
+}
+
+static void ambarella_handle_data_in(struct ambarella_ep *ep)
+{
+ struct ambarella_request *req = NULL;
+ struct ambarella_udc *udc = ep->udc;
+
+ /* get request */
+ if (list_empty(&ep->queue)) {
+ printk(KERN_DEBUG "%s: req NULL\n", __func__);
+ return ;
+ }
+
+ req = list_first_entry(&ep->queue, struct ambarella_request,queue);
+
+ /* If error happened, issue the request again */
+ if (ambarella_check_dma_error(ep))
+ req->req.status = -EPROTO;
+ else {
+ /* No error happened, so all the data has been sent to host */
+ req->req.actual = req->req.length;
+ }
+
+ ambarella_udc_done(ep, req, 0);
+
+ if(ep->id == CTRL_IN){
+ /* For STATUS-OUT stage */
+ udc->ep[CTRL_OUT].ctrl_sts_phase = 1;
+ ambarella_set_rx_dma(&udc->ep[CTRL_OUT], NULL);
+ }
+}
+
+static int ambarella_handle_data_out(struct ambarella_ep *ep)
+{
+ struct ambarella_request *req = NULL;
+ struct ambarella_udc *udc = ep->udc;
+ u32 recv_size = 0, req_size;
+
+ /* get request */
+ if (list_empty(&ep->queue)) {
+ printk(KERN_DEBUG "%s: req NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ req = list_first_entry(&ep->queue, struct ambarella_request,queue);
+
+ /* If error happened, issue the request again */
+ if (ambarella_check_dma_error(ep))
+ req->req.status = -EPROTO;
+
+ recv_size = ep->last_data_desc->status & USB_DMA_RXTX_BYTES;
+ if (!recv_size && req->req.length == UDC_DMA_MAXPACKET) {
+ /* on 64k packets the RXBYTES field is zero */
+ recv_size = UDC_DMA_MAXPACKET;
+ }
+
+ req_size = req->req.length - req->req.actual;
+ if (recv_size > req_size) {
+ if ((req_size % ep->ep.maxpacket) != 0)
+ req->req.status = -EOVERFLOW;
+ recv_size = req_size;
+ }
+
+ req->req.actual += recv_size;
+
+ ambarella_udc_done(ep, req, 0);
+
+ if(ep->id == CTRL_OUT) {
+ /* For STATUS-IN stage */
+ ambarella_clr_ep_nak(&udc->ep[CTRL_IN]);
+ /* Re-enable Rx DMA to receive next setup packet */
+ ambarella_enable_rx_dma(ep);
+ ep->dma_going = 0;
+ }
+
+ return 0;
+}
+
+
+static void ambarella_udc_done(struct ambarella_ep *ep,
+ struct ambarella_request *req, int status)
+{
+ unsigned halted_tmp, need_queue = 0;
+ struct ambarella_request *next_req;
+
+ halted_tmp = ep->halted;
+
+ list_del_init(&req->queue);
+
+ if(!list_empty(&ep->queue) && !ep->halted && !ep->cancel_transfer){
+ need_queue = 1;
+ } else if (!IS_EP0(ep) && (ep->dir == USB_DIR_IN) && !ep->cancel_transfer) {
+ /* ep->ep.desc = NULL when ep disabled */
+ if (!ep->ep.desc || IS_ISO_IN_EP(ep))
+ ambarella_set_ep_nak(ep);
+ amba_setbitsl(USB_DEV_EP_INTR_MSK_REG, 1 << ep->id);
+ }
+
+ if (likely (req->req.status == -EINPROGRESS))
+ req->req.status = status;
+ else
+ status = req->req.status;
+
+ ambarella_unmap_dma_buffer(ep, req);
+
+ if (req->use_aux_buf && ep->dir != USB_DIR_IN)
+ memcpy(req->req.buf, req->buf_aux, req->req.actual);
+
+ ep->data_desc = NULL;
+ ep->last_data_desc = NULL;
+
+ ep->halted = 1;
+ spin_unlock(&ep->udc->lock);
+ req->req.complete(&ep->ep, &req->req);
+ spin_lock(&ep->udc->lock);
+ ep->halted = halted_tmp;
+
+ if(need_queue){
+ next_req = list_first_entry (&ep->queue,
+ struct ambarella_request, queue);
+
+ switch(ep->dir) {
+ case USB_DIR_IN:
+ /* no need to wait for IN-token for ISO transfer */
+ if (IS_ISO_IN_EP(ep)) {
+ amba_writel(ep->ep_reg.sts_reg, USB_EP_IN_PKT);
+ ambarella_set_tx_dma(ep, next_req, 1);
+ }
+ ambarella_clr_ep_nak(ep);
+ break;
+ case USB_DIR_OUT:
+ ambarella_set_rx_dma(ep, next_req);
+ break;
+ default:
+ return;
+ }
+ }
+}
+
+static void ambarella_ep_nuke(struct ambarella_ep *ep, int status)
+{
+ while (!list_empty (&ep->queue)) {
+ struct ambarella_request *req;
+ req = list_first_entry(&ep->queue,
+ struct ambarella_request, queue);
+ ambarella_udc_done(ep, req, status);
+ }
+}
+
+/*
+ * Name: device_interrupt
+ * Description:
+ * Process related device interrupt
+ */
+static void udc_device_interrupt(struct ambarella_udc *udc, u32 int_value)
+{
+ /* case 1. Get set_config or set_interface request from host */
+ if (int_value & (USB_DEV_SET_CFG | USB_DEV_SET_INTF)) {
+ struct usb_ctrlrequest crq;
+ u32 i, ret, csr_config;
+
+ if(int_value & USB_DEV_SET_CFG) {
+ /* Ack the SC interrupt */
+ amba_writel(USB_DEV_INTR_REG, USB_DEV_SET_CFG);
+ udc->cur_config = (u16)(amba_readl(USB_DEV_STS_REG) & USB_DEV_CFG_NUM);
+
+ crq.bRequestType = 0x00;
+ crq.bRequest = USB_REQ_SET_CONFIGURATION;
+ crq.wValue = cpu_to_le16(udc->cur_config);
+ crq.wIndex = 0x0000;
+ crq.wLength = 0x0000;
+ } else if(int_value & USB_DEV_SET_INTF){
+ /* Ack the SI interrupt */
+ amba_writel(USB_DEV_INTR_REG, USB_DEV_SET_INTF);
+ udc->cur_intf = (amba_readl(USB_DEV_STS_REG) & USB_DEV_INTF_NUM) >> 4;
+ udc->cur_alt = (amba_readl(USB_DEV_STS_REG) & USB_DEV_ALT_SET) >> 8;
+
+ crq.bRequestType = 0x01;
+ crq.bRequest = USB_REQ_SET_INTERFACE;
+ crq.wValue = cpu_to_le16(udc->cur_alt);
+ crq.wIndex = cpu_to_le16(udc->cur_intf);
+ crq.wLength = 0x0000;
+ }
+
+ for (i = 0; i < EP_NUM_MAX; i++){
+ udc->ep[i].halted = 0;
+ amba_clrbitsl(udc->ep[i].ep_reg.ctrl_reg, USB_EP_STALL);
+ }
+
+ /* setup ep0 CSR. Note: ep0-in and ep0-out share the same CSR reg */
+ csr_config = (udc->cur_config << 7) | (udc->cur_intf << 11) |
+ (udc->cur_alt << 15);
+ amba_clrbitsl(USB_UDC_REG(CTRL_IN), 0xfff << 7);
+ amba_setbitsl(USB_UDC_REG(CTRL_IN), csr_config);
+
+ udc->auto_ack_0_pkt = 1;
+ ambarella_ep_nuke(&udc->ep[CTRL_OUT], -EPROTO);
+ spin_unlock(&udc->lock);
+ ret = udc->driver->setup(&udc->gadget, &crq);
+ spin_lock(&udc->lock);
+ if(ret < 0)
+ printk(KERN_ERR "set config failed. (%d)\n", ret);
+
+ /* told UDC the configuration is done, and to ack HOST
+ * UDC has to ack the host quickly, or Host will think failed,
+ * do don't add much debug message when receive SC/SI irq.*/
+ amba_setbitsl(USB_DEV_CTRL_REG, USB_DEV_CSR_DONE);
+ udelay(150);
+ usb_gadget_set_state(&udc->gadget, USB_STATE_CONFIGURED);
+ schedule_work(&udc->uevent_work);
+
+ }
+
+ /* case 2. Get reset Interrupt */
+ else if (int_value & USB_DEV_RESET) {
+
+ dprintk(DEBUG_NORMAL, "USB reset IRQ\n");
+
+ amba_writel(USB_DEV_INTR_REG, USB_DEV_RESET);
+
+ ambarella_disable_all_intr();
+
+ if (udc->host_suspended && udc->driver && udc->driver->resume){
+ spin_unlock(&udc->lock);
+ udc->driver->resume(&udc->gadget);
+ spin_lock(&udc->lock);
+ udc->host_suspended = 0;
+ }
+
+ ambarella_stop_activity(udc);
+
+ udc->gadget.speed = USB_SPEED_UNKNOWN;
+ udc->auto_ack_0_pkt = 0;
+ udc->remote_wakeup_en = 0;
+
+ udc->udc_is_enabled = 0;
+ ambarella_udc_enable(udc);
+
+ usb_gadget_set_state(&udc->gadget, USB_STATE_ATTACHED);
+ schedule_work(&udc->uevent_work);
+#if 0
+ /* enable suspend interrupt */
+ amba_clrbitsl(USB_DEV_INTR_MSK_REG, UDC_INTR_MSK_US);
+#endif
+ }
+
+ /* case 3. Get suspend Interrupt */
+ else if (int_value & USB_DEV_SUSP) {
+
+ pr_err("%s: USB suspend IRQ\n", __func__);
+
+ amba_writel(USB_DEV_INTR_REG, USB_DEV_SUSP);
+
+ if (udc->driver->suspend) {
+ udc->host_suspended = 1;
+ spin_unlock(&udc->lock);
+ udc->driver->suspend(&udc->gadget);
+ spin_lock(&udc->lock);
+ }
+ }
+
+ /* case 4. enumeration complete */
+ else if(int_value & USB_DEV_ENUM_CMPL) {
+ u32 value = 0;
+
+ /* Ack the CMPL interrupt */
+ amba_writel(USB_DEV_INTR_REG, USB_DEV_ENUM_CMPL);
+
+ value = amba_readl(USB_DEV_STS_REG) & USB_DEV_ENUM_SPD;
+
+ if(value == USB_DEV_ENUM_SPD_HI) { /* high speed */
+
+ dprintk(DEBUG_NORMAL,"enumeration IRQ - "
+ "High-speed bus detected\n");
+ udc->gadget.speed = USB_SPEED_HIGH;
+ } else if (value == USB_DEV_ENUM_SPD_FU) { /* full speed */
+
+ dprintk(DEBUG_NORMAL,"enumeration IRQ - "
+ "Full-speed bus detected\n");
+ udc->gadget.speed = USB_SPEED_FULL;
+ } else {
+ printk(KERN_ERR "Not supported speed!"
+ "USB_DEV_STS_REG = 0x%x\n", value);
+ udc->gadget.speed = USB_SPEED_UNKNOWN;
+
+ }
+ } /* ENUM COMPLETE */
+ else {
+ printk(KERN_ERR "Unknown Interrupt:0x%08x\n", int_value);
+ /* Ack the Unknown interrupt */
+ amba_writel(USB_DEV_INTR_REG, int_value);
+ }
+}
+
+
+/*
+ * Name: udc_epin_interrupt
+ * Description:
+ * Process IN(CTRL or BULK) endpoint interrupt
+ */
+static void udc_epin_interrupt(struct ambarella_udc *udc, u32 ep_id)
+{
+ u32 ep_status = 0;
+ struct ambarella_ep *ep = &udc->ep[ep_id];
+ struct ambarella_request *req;
+
+ ep_status = amba_readl(ep->ep_reg.sts_reg);
+
+ /* TxFIFO is empty, but we've not used this bit, so just ignored simply. */
+ if (ep_status == USB_EP_TXFIFO_EMPTY) {
+ amba_writel(ep->ep_reg.sts_reg, ep_status);
+ return;
+ }
+
+ dprintk(DEBUG_NORMAL, "%s: ep_status = 0x%08x\n", ep->ep.name, ep_status);
+
+ if (ambarella_handle_ep_stall(ep, ep_status))
+ return;
+
+ if (ambarella_check_bna_error(ep, ep_status)
+ || ambarella_check_he_error(ep, ep_status)) {
+ struct ambarella_request *req = NULL;
+ ep->dma_going = 0;
+ ep->cancel_transfer = 0;
+ ep->need_cnak = 0;
+ if (!list_empty(&ep->queue)) {
+ req = list_first_entry(&ep->queue, struct ambarella_request,queue);
+ req->req.status = -EPROTO;
+ ambarella_udc_done(ep, req, 0);
+ }
+ return;
+ }
+
+ if (ep_status & USB_EP_TRN_DMA_CMPL) {
+ /* write dummy desc to try to avoid BNA error */
+ ep->udc->dummy_desc->status =
+ USB_DMA_BUF_HOST_RDY | USB_DMA_LAST;
+ amba_writel(ep->ep_reg.dat_desc_ptr_reg,
+ udc->dummy_desc_addr | udc->dma_fix);
+
+ if(ep->halted || ep->dma_going == 0 || ep->cancel_transfer == 1
+ || list_empty(&ep->queue)) {
+ ep_status &= (USB_EP_IN_PKT | USB_EP_TRN_DMA_CMPL);
+ amba_writel(ep->ep_reg.sts_reg, ep_status);
+ ep->dma_going = 0;
+ ep->cancel_transfer = 0;
+ return;
+ }
+
+ ep->dma_going = 0;
+ ep->cancel_transfer = 0;
+ ep->need_cnak = 0;
+
+ ep->last_data_desc = ambarella_get_last_desc(ep);
+ if(ep->last_data_desc == NULL){
+ printk(KERN_ERR "%s: last_data_desc is NULL\n", ep->ep.name);
+ BUG();
+ return;
+ }
+ ambarella_handle_data_in(&udc->ep[ep_id]);
+ } else if(ep_status & USB_EP_IN_PKT) {
+#if 0
+ if (IS_ISO_IN_EP(ep))
+ goto finish;
+#endif
+
+ if(!ep->halted && !ep->cancel_transfer && !list_empty(&ep->queue)){
+ req = list_first_entry(&ep->queue,
+ struct ambarella_request, queue);
+ ambarella_set_tx_dma(ep, req, 0);
+ } else if (ep->dma_going == 0 || ep->halted || ep->cancel_transfer) {
+ ambarella_set_ep_nak(ep);
+ }
+ ep->cancel_transfer = 0;
+ } else if (ep_status != 0){
+ pr_err("%s: %s, Unknown int source(0x%08x)\n", __func__,
+ ep->ep.name, ep_status);
+ amba_writel(ep->ep_reg.sts_reg, ep_status);
+ return;
+ }
+
+//finish:
+ if (ep_status != 0) {
+ ep_status &= (USB_EP_IN_PKT | USB_EP_TRN_DMA_CMPL | USB_EP_TXFIFO_EMPTY);
+// ep_status &= (USB_EP_IN_PKT | USB_EP_TRN_DMA_CMPL | USB_EP_RCV_CLR_STALL);
+ amba_writel(ep->ep_reg.sts_reg, ep_status);
+ }
+}
+
+
+/*
+ * Name: udc_epout_interrupt
+ * Description:
+ * Process OUT endpoint interrupt
+ */
+static void udc_epout_interrupt(struct ambarella_udc *udc, u32 ep_id)
+{
+ struct ambarella_ep *ep = &udc->ep[ep_id];
+ u32 desc_status, ep_status, i;
+
+ /* check the status bits for what kind of packets in */
+ ep_status = amba_readl(ep->ep_reg.sts_reg);
+
+ if (ambarella_handle_ep_stall(ep, ep_status))
+ return;
+
+
+ if(ep_id == CTRL_OUT) {
+ /* Cope with setup-data packet */
+ if((ep_status & USB_EP_OUT_PKT_MSK) == USB_EP_SETUP_PKT){
+ amba_writel(ep->ep_reg.sts_reg, USB_EP_SETUP_PKT);
+ ep->ctrl_sts_phase = 0;
+ ep->dma_going = 0;
+ ambarella_handle_request_packet(udc);
+ }
+ }
+
+ /* Cope with normal data packet */
+ if((ep_status & USB_EP_OUT_PKT_MSK) == USB_EP_OUT_PKT) {
+
+ amba_writel(ep->ep_reg.sts_reg, USB_EP_OUT_PKT);
+ ep->dma_going = 0;
+
+ /* Just cope with the zero-length packet */
+ if(ep->ctrl_sts_phase == 1) {
+ ep->ctrl_sts_phase = 0;
+ ambarella_enable_rx_dma(ep);
+ ep->dma_going = 0;
+ return;
+ }
+
+ if(ep->halted || ep->cancel_transfer || list_empty(&ep->queue)) {
+ amba_writel(ep->ep_reg.sts_reg, ep_status);
+ return;
+ }
+
+ if (ambarella_check_bna_error(ep, ep_status))
+ return;
+
+ if(ambarella_check_he_error(ep, ep_status) && !list_empty(&ep->queue)) {
+ struct ambarella_request *req = NULL;
+ req = list_first_entry(&ep->queue,
+ struct ambarella_request, queue);
+ req->req.status = -EPROTO;
+ ambarella_udc_done(ep, req, 0);
+ return;
+ }
+
+ ep->last_data_desc = ambarella_get_last_desc(ep);
+ if(ep->last_data_desc == NULL){
+ pr_err("%s: %s, last_data_desc is NULL\n", __func__, ep->ep.name);
+ BUG();
+ return;
+ }
+
+ if(ep_id != CTRL_OUT){
+ desc_status = ep->last_data_desc->status;
+ /* received data */
+ if((desc_status & USB_DMA_BUF_STS) == USB_DMA_BUF_DMA_DONE) {
+ amba_setbitsl(USB_DEV_EP_INTR_MSK_REG, 1 << ep_id);
+ ambarella_set_ep_nak(ep);
+ }
+ }
+
+ ambarella_handle_data_out(ep);
+
+ /* clear NAK for TX dma */
+ if (amba_readl(USB_DEV_STS_REG) & USB_DEV_RXFIFO_EMPTY_STS) {
+ for (i = 0; i < EP_NUM_MAX; i++) {
+ struct ambarella_ep *_ep = &udc->ep[i];
+ if (_ep->need_cnak == 1)
+ ambarella_clr_ep_nak(_ep);
+ }
+ }
+ }
+
+ return;
+}
+
+static irqreturn_t ambarella_udc_irq(int irq, void *_dev)
+{
+ struct ambarella_udc *udc = _dev;
+ u32 value, handled = 0, i, ep_irq;
+
+ spin_lock(&udc->lock);
+ /* If gadget driver is not connected, do not handle the interrupt */
+ if (!udc->driver) {
+ amba_writel(USB_DEV_INTR_REG, amba_readl(USB_DEV_INTR_REG));
+ amba_writel(USB_DEV_EP_INTR_REG, amba_readl(USB_DEV_EP_INTR_REG));
+ ambarella_udc_set_pullup(udc, 0);
+ }
+
+ /* 1. check if device interrupt */
+ value = amba_readl(USB_DEV_INTR_REG);
+ if(value) {
+
+ dprintk(DEBUG_NORMAL, "device int value = 0x%x\n", value);
+
+ handled = 1;
+ udc_device_interrupt(udc, value);
+
+ }
+ /* 2. check if endpoint interrupt */
+ value = amba_readl(USB_DEV_EP_INTR_REG);
+ if(value) {
+ handled = 1;
+
+ for(i = 0; i < EP_NUM_MAX; i++){
+ ep_irq = 1 << i;
+ if (!(value & ep_irq))
+ continue;
+
+ /* ack the endpoint interrupt */
+ amba_writel(USB_DEV_EP_INTR_REG, ep_irq);
+
+ /* irq for out ep ? */
+ if (i >= EP_IN_NUM)
+ udc_epout_interrupt(udc, i);
+ else
+ udc_epin_interrupt(udc, i);
+
+ value &= ~ep_irq;
+ if(value == 0)
+ break;
+ }
+ }
+
+ spin_unlock(&udc->lock);
+
+ return IRQ_RETVAL(handled);
+}
+
+static void ambarella_vbus_timer(unsigned long data)
+{
+ struct ambarella_udc *udc = (struct ambarella_udc *)data;
+ enum usb_device_state state;
+ u32 raw_status, connected, suspended;
+
+ suspended = (amba_readl(USB_DEV_STS_REG) & USB_DEV_SUSP_STS);
+ raw_status = amba_readl(AHB_SCRATCHPAD_REG(0x04));
+ connected = !!(raw_status & (1 << 26));
+
+ if (suspended)
+ usb_gadget_set_state(&udc->gadget, USB_STATE_SUSPENDED);
+
+ if (udc->vbus_status != connected) {
+ state = connected ? USB_STATE_ATTACHED : USB_STATE_NOTATTACHED;
+ usb_gadget_set_state(&udc->gadget, state);
+ udc->vbus_status = connected;
+ schedule_work(&udc->uevent_work);
+ if (udc->driver != NULL)
+ ambarella_udc_vbus_session(&udc->gadget, udc->vbus_status);
+ }
+
+ mod_timer(&udc->vbus_timer, jiffies + VBUS_POLL_TIMEOUT);
+}
+
+static void ambarella_stop_activity(struct ambarella_udc *udc)
+{
+ struct usb_gadget_driver *driver = udc->driver;
+ struct ambarella_ep *ep;
+ u32 i;
+
+ /* Disable Tx and Rx DMA */
+ amba_clrbitsl(USB_DEV_CTRL_REG, USB_DEV_RCV_DMA_EN | USB_DEV_TRN_DMA_EN);
+
+ if (udc->gadget.speed == USB_SPEED_UNKNOWN)
+ driver = NULL;
+ udc->gadget.speed = USB_SPEED_UNKNOWN;
+
+ for (i = 0; i < EP_NUM_MAX; i++) {
+ ep = &udc->ep[i];
+
+ if(ep->ep.desc == NULL && !IS_EP0(ep))
+ continue;
+
+ ambarella_set_ep_nak(ep);
+
+ ep->halted = 1;
+ ambarella_ep_nuke(ep, -ESHUTDOWN);
+ }
+ if (driver) {
+ spin_unlock(&udc->lock);
+ driver->disconnect(&udc->gadget);
+ spin_lock(&udc->lock);
+ }
+
+ ambarella_udc_reinit(udc);
+}
+
+static int ambarella_udc_ep_enable(struct usb_ep *_ep,
+ const struct usb_endpoint_descriptor *desc)
+{
+ struct ambarella_udc *udc;
+ struct ambarella_ep *ep = to_ambarella_ep(_ep);
+ u32 max_packet, tmp, type, idx = 0;
+ unsigned long flags;
+
+ /* Sanity check */
+ if (!_ep || !desc || IS_EP0(ep)
+ || desc->bDescriptorType != USB_DT_ENDPOINT) {
+ printk("%s ep %d is inval \n",__func__,ep->id);
+ return -EINVAL;
+ }
+ udc = ep->udc;
+ if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN)
+ return -ESHUTDOWN;
+
+ max_packet = usb_endpoint_maxp(desc) & 0x7ff;
+
+ spin_lock_irqsave(&udc->lock, flags);
+ ep->ep.maxpacket = max_packet;
+ ep->ep.desc = desc;
+ ep->halted = 0;
+ ep->data_desc = NULL;
+ ep->last_data_desc = NULL;
+ ep->ctrl_sts_phase = 0;
+ ep->dma_going = 0;
+ ep->cancel_transfer = 0;
+ ep->frame_offset = (1 << (desc->bInterval - 1));
+
+ if(ep->dir == USB_DIR_IN){
+ idx = ep->id;
+ } else {
+ idx = ep->id - CTRL_OUT_UDC_IDX;
+ }
+
+ /* setup CSR */
+ amba_clrbitsl(USB_UDC_REG(idx), 0x3fffffff);
+ tmp = (desc->bEndpointAddress & 0xf) << 0;
+ tmp |= (desc->bEndpointAddress >> 7) << 4;
+ tmp |= (desc->bmAttributes & 0x3) << 5;
+ tmp |= udc->cur_config << 7;
+ tmp |= udc->cur_intf << 11;
+ tmp |= udc->cur_alt << 15;
+ tmp |= max_packet << 19;
+ amba_setbitsl(USB_UDC_REG(idx), tmp);
+
+ type = (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) << 4;
+ amba_writel(ep->ep_reg.ctrl_reg, type | USB_EP_SET_NAK);
+
+ if(ep->dir == USB_DIR_IN) {
+ /* NOTE: total IN fifo size must be less than 576 * 4B */
+ tmp = max_packet / 4;
+#if 0
+ if (IS_ISO_IN_EP(ep))
+ tmp *= max_packet > 1024 ? 1 : max_packet > 512 ? 2 : 3;
+ else
+#endif
+ tmp *= 2;
+ amba_writel(ep->ep_reg.buf_sz_reg, tmp);
+ }
+ amba_writel(ep->ep_reg.max_pkt_sz_reg, max_packet);
+
+ spin_unlock_irqrestore(&udc->lock, flags);
+
+ return 0;
+}
+
+static int ambarella_udc_ep_disable(struct usb_ep *_ep)
+{
+ struct ambarella_ep *ep = to_ambarella_ep(_ep);
+ unsigned long flags;
+
+ if (!_ep || !ep->ep.desc) {
+ dprintk(DEBUG_NORMAL, "%s not enabled\n",
+ _ep ? ep->ep.name : NULL);
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&ep->udc->lock, flags);
+
+ ep->ep.desc = NULL;
+ ep->halted = 1;
+ ambarella_ep_nuke(ep, -ESHUTDOWN);
+
+ ambarella_set_ep_nak(ep);
+
+ if(ep->dir == USB_DIR_IN){
+ /* clear DMA poll demand bit */
+ amba_clrbitsl(ep->ep_reg.ctrl_reg, USB_EP_POLL_DEMAND);
+ /* clear status register */
+ amba_setbitsl(ep->ep_reg.sts_reg, USB_EP_IN_PKT);
+ /* flush the fifo */
+ amba_setbitsl(ep->ep_reg.ctrl_reg, USB_EP_FLUSH);
+ }
+
+ /* disable irqs */
+ amba_setbitsl(USB_DEV_EP_INTR_MSK_REG, 1 << ep->id);
+
+ spin_unlock_irqrestore(&ep->udc->lock, flags);
+
+ return 0;
+}
+
+
+static struct usb_request *
+ambarella_udc_alloc_request(struct usb_ep *_ep, gfp_t mem_flags)
+{
+ struct ambarella_request *req;
+
+ if (!_ep)
+ return NULL;
+
+ req = kzalloc (sizeof(struct ambarella_request), mem_flags);
+ if (!req)
+ return NULL;
+
+ req->req.dma = DMA_ADDR_INVALID;
+ INIT_LIST_HEAD (&req->queue);
+ req->desc_count = 0;
+
+ req->buf_aux = NULL;
+ req->dma_aux = DMA_ADDR_INVALID;
+ req->use_aux_buf = 0;
+
+ return &req->req;
+}
+
+
+static void
+ambarella_udc_free_request(struct usb_ep *_ep, struct usb_request *_req)
+{
+ struct ambarella_ep *ep = to_ambarella_ep(_ep);
+ struct ambarella_request *req = to_ambarella_req(_req);
+
+ if (!ep || !_req)
+ return;
+
+ if(req->desc_count > 0)
+ ambarella_free_descriptor(ep, req);
+
+ if (req->buf_aux) {
+ kfree(req->buf_aux);
+ req->buf_aux = NULL;
+ }
+
+ WARN_ON (!list_empty (&req->queue));
+ kfree(req);
+}
+
+
+static int ambarella_udc_queue(struct usb_ep *_ep, struct usb_request *_req,
+ gfp_t gfp_flags)
+{
+ struct ambarella_request *req = NULL;
+ struct ambarella_ep *ep = NULL;
+ struct ambarella_udc *udc;
+ unsigned long flags;
+ int i;
+
+ if (unlikely (!_ep)) {
+ pr_err("%s: _ep is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ ep = to_ambarella_ep(_ep);
+ udc = ep->udc;
+
+ for(i = 0; i < EP_NUM_MAX; i++) {
+ struct ambarella_ep *endp;
+ endp = &udc->ep[i];
+
+ if (endp != NULL && endp->dma_going) //Check for any ongoing DMA
+ break;
+
+ //If no other onging DMA and the current req is for ISO, enable the DMA
+ if((i == EP_NUM_MAX - 1) && IS_ISO_IN_EP(ep)) {
+ amba_setbitsl(USB_DEV_CTRL_REG,
+ USB_DEV_RCV_DMA_EN | USB_DEV_TRN_DMA_EN);
+ }
+ }
+
+ if (unlikely (!ep->ep.desc && !IS_EP0(ep))) {
+ pr_err("%s: %s, invalid args\n", __func__, _ep->name);
+ return -EINVAL;
+ }
+
+ if( unlikely( !udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN)){
+ dprintk(DEBUG_NORMAL, "%s: %01d %01d\n", _ep->name,
+ !udc->driver, udc->gadget.speed==USB_SPEED_UNKNOWN);
+ return -ESHUTDOWN;
+ }
+
+ if (unlikely(!_req )) {
+ pr_err("%s: %s, _req is NULL\n", __func__, _ep->name);
+ return -EINVAL;
+ }
+
+ req = to_ambarella_req(_req);
+ if (unlikely(!req->req.complete || !req->req.buf
+ || !list_empty(&req->queue))) {
+ pr_err("%s: %s, %01d %01d %01d\n", __func__, _ep->name,
+ !_req->complete, !_req->buf, !list_empty(&req->queue));
+
+ return -EINVAL;
+ }
+
+ if(IS_EP0(ep) && (udc->auto_ack_0_pkt == 1)){
+ /* It's status stage in setup packet. And A2/A3 will
+ * automatically send the zero-length packet to Host */
+ udc->auto_ack_0_pkt = 0;
+ req->req.actual = 0;
+ req->req.complete(&ep->ep, &req->req);
+ return 0;
+ }
+
+ /* check whether USB is suspended */
+ if(amba_readl(USB_DEV_STS_REG) & USB_DEV_SUSP_STS){
+ pr_err("%s: UDC is suspended!\n", __func__);
+ return -ESHUTDOWN;
+ }
+
+ if (unlikely((unsigned long)req->req.buf & 0x7)) {
+ req->use_aux_buf = 1;
+
+ if (req->buf_aux == NULL) {
+ req->buf_aux = kmalloc(UDC_DMA_MAXPACKET, GFP_ATOMIC);
+ if (req->buf_aux == NULL)
+ return -ENOMEM;
+ }
+
+ if (ep->dir == USB_DIR_IN)
+ memcpy(req->buf_aux, req->req.buf, req->req.length);
+ } else {
+ req->use_aux_buf = 0;
+ }
+
+ ambarella_map_dma_buffer(ep, req);
+
+ /* disable IRQ handler's bottom-half */
+ spin_lock_irqsave(&udc->lock, flags);
+
+ _req->status = -EINPROGRESS;
+ _req->actual = 0;
+
+ ambarella_prepare_descriptor(ep, req, gfp_flags);
+
+ /* kickstart this i/o queue? */
+ //if (list_empty(&ep->queue) && !ep->halted) {
+ if (list_empty(&ep->queue)) {
+ /* when the data length in ctrl-out transfer is zero, we just
+ * need to implement the STATUS-IN stage. But we don't
+ * implement the case that the data length in ctrl-in transfer
+ * is zero. */
+ if(req->req.length == 0) {
+ if(ep->id == CTRL_OUT) {
+ ambarella_udc_done(ep, req, 0);
+ /* told UDC the configuration is done, and to ack HOST */
+ //amba_setbitsl(USB_DEV_CTRL_REG, USB_DEV_CSR_DONE);
+ //udelay(150);
+ /* For STATUS-IN stage */
+ ambarella_clr_ep_nak(&udc->ep[CTRL_IN]);
+ /* Re-enable Rx DMA to receive next setup packet */
+ ambarella_set_rx_dma(ep, NULL);
+ ep->dma_going = 0;
+ goto finish;
+ } else if (ep->id == CTRL_IN) {
+ //printk("the data length of ctrl-in is zero\n");
+ //BUG();
+ }
+ }
+
+ if (ep->dir == USB_DIR_IN) {
+ /* no need to wait for IN-token for ISO transfer */
+#if 0
+ if (IS_ISO_IN_EP(ep)) {
+ amba_writel(ep->ep_reg.sts_reg, USB_EP_IN_PKT);
+ ambarella_set_tx_dma(ep, req);
+ }
+#endif
+ /* enable dma completion interrupt for current TX data */
+ amba_clrbitsl(USB_DEV_EP_INTR_MSK_REG, 1 << ep->id);
+ ambarella_clr_ep_nak(ep);
+ } else {
+ ambarella_set_rx_dma(ep, req);
+ }
+ }
+
+ list_add_tail(&req->queue, &ep->queue);
+
+finish:
+ /* enable IRQ handler's bottom-half */
+ spin_unlock_irqrestore(&udc->lock, flags);
+
+ return 0;
+}
+
+static int ambarella_udc_dequeue(struct usb_ep *_ep, struct usb_request *_req)
+{
+ struct ambarella_ep *ep = to_ambarella_ep(_ep);
+ struct ambarella_request *req;
+ unsigned long flags;
+ unsigned halted;
+
+ if (!ep->udc->driver)
+ return -ESHUTDOWN;
+
+ if (!_ep || !_req)
+ return -EINVAL;
+
+ spin_lock_irqsave(&ep->udc->lock, flags);
+
+ /* make sure the request is actually queued on this endpoint */
+ list_for_each_entry (req, &ep->queue, queue) {
+ if (&req->req == _req)
+ break;
+ }
+ if (&req->req != _req) {
+ spin_unlock_irqrestore(&ep->udc->lock, flags);
+ return -EINVAL;
+ }
+
+ halted = ep->halted;
+ ep->halted = 1;
+
+ /* request in processing */
+ if((ep->data_desc == req->data_desc) && (ep->dma_going == 1)) {
+ if (ep->dir == USB_DIR_IN)
+ ep->cancel_transfer = 1;
+ else {
+ u32 tmp, desc_status;
+ /* stop potential receive DMA */
+ tmp = amba_readl(USB_DEV_CTRL_REG);
+ amba_clrbitsl(USB_DEV_CTRL_REG, USB_DEV_RCV_DMA_EN);
+
+ /* cancel transfer later in ISR if descriptor was touched. */
+ desc_status = req->data_desc->status;
+ if (desc_status != USB_DMA_BUF_HOST_RDY)
+ ep->cancel_transfer = 1;
+
+ amba_writel(USB_DEV_CTRL_REG, tmp);
+ }
+ }
+
+ ambarella_udc_done(ep, req, -ECONNRESET);
+
+ ep->halted = halted;
+ spin_unlock_irqrestore(&ep->udc->lock, flags);
+
+ return 0;
+}
+
+/*
+ * ambarella_udc_set_halt
+ */
+static int ambarella_udc_set_halt(struct usb_ep *_ep, int value)
+{
+ struct ambarella_ep *ep = to_ambarella_ep(_ep);
+ unsigned long flags;
+
+ if (unlikely (!_ep || (!ep->ep.desc && !IS_EP0(ep)))) {
+ pr_err("%s: %s, -EINVAL 1\n", __func__,_ep->name);
+ return -EINVAL;
+ }
+ if (!ep->udc->driver || ep->udc->gadget.speed == USB_SPEED_UNKNOWN){
+ pr_err("%s: %s, -ESHUTDOWN\n", __func__, _ep->name);
+ return -ESHUTDOWN;
+ }
+ /* isochronous transfer never halts because there is no handshake
+ * to report a halt condition */
+ if (ep->ep.desc /* not ep0 */ && IS_ISO_IN_EP(ep)) {
+ pr_err("%s: %s, -EINVAL 2\n", __func__, _ep->name);
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&ep->udc->lock, flags);
+
+ /* set/clear, then synch memory views with the device */
+ if (value) { /* stall endpoint */
+ if (ep->dir == USB_DIR_IN) {
+ amba_setbitsl(ep->ep_reg.ctrl_reg, USB_EP_STALL | USB_EP_FLUSH);
+ } else {
+ int retry_count = 10000;
+ /* Wait Rx-FIFO to be empty */
+ while(!(amba_readl(USB_DEV_STS_REG) & USB_DEV_RXFIFO_EMPTY_STS)){
+ if (retry_count-- < 0) {
+ printk(KERN_ERR"[USB] stall_endpoint:failed");
+ break;
+ }
+ }
+ amba_setbitsl(ep->ep_reg.ctrl_reg, USB_EP_STALL);
+ }
+ } else { /* clear stall endpoint */
+ amba_clrbitsl(ep->ep_reg.ctrl_reg, USB_EP_STALL);
+ }
+
+ ep->halted = !!value;
+
+ spin_unlock_irqrestore(&ep->udc->lock, flags);
+
+ return 0;
+}
+
+
+static const struct usb_ep_ops ambarella_ep_ops = {
+ .enable = ambarella_udc_ep_enable,
+ .disable = ambarella_udc_ep_disable,
+
+ .alloc_request = ambarella_udc_alloc_request,
+ .free_request = ambarella_udc_free_request,
+
+ .queue = ambarella_udc_queue,
+ .dequeue = ambarella_udc_dequeue,
+
+ .set_halt = ambarella_udc_set_halt,
+ /* fifo ops not implemented */
+};
+
+/*------------------------- usb_gadget_ops ----------------------------------*/
+
+
+static int ambarella_udc_get_frame(struct usb_gadget *_gadget)
+{
+ return (amba_readl(USB_DEV_STS_REG) >> 18) & 0x7ff;
+}
+
+
+static int ambarella_udc_wakeup(struct usb_gadget *_gadget)
+{
+ struct ambarella_udc *udc = to_ambarella_udc(_gadget);
+ u32 tmp;
+
+ tmp = amba_readl(USB_DEV_CFG_REG);
+ /* Remote wakeup feature not enabled by host */
+ if ((!udc->remote_wakeup_en) || (!(tmp & USB_DEV_REMOTE_WAKEUP_EN)))
+ return -ENOTSUPP;
+
+ tmp = amba_readl(USB_DEV_STS_REG);
+ /* not suspended? */
+ if (!(tmp & USB_DEV_SUSP_STS))
+ return 0;
+
+ /* trigger force resume */
+ amba_setbitsl(USB_DEV_CTRL_REG, USB_DEV_REMOTE_WAKEUP);
+
+ return 0;
+}
+
+static int ambarella_udc_set_pullup(struct ambarella_udc *udc, int is_on)
+{
+ if (is_on) {
+ ambarella_udc_enable(udc);
+ /* reconnect to host */
+ amba_clrbitsl(USB_DEV_CTRL_REG, USB_DEV_SOFT_DISCON);
+ } else {
+ if (udc->gadget.speed != USB_SPEED_UNKNOWN)
+ ambarella_stop_activity(udc);
+ /* disconnect to host */
+ amba_setbitsl(USB_DEV_CTRL_REG, USB_DEV_SOFT_DISCON);
+ ambarella_udc_disable(udc);
+ }
+
+ return 0;
+}
+
+static int ambarella_udc_vbus_session(struct usb_gadget *gadget, int is_active)
+{
+ unsigned long flags;
+ struct ambarella_udc *udc = to_ambarella_udc(gadget);
+
+ spin_lock_irqsave(&udc->lock, flags);
+ if (udc->driver)
+ ambarella_udc_set_pullup(udc, is_active);
+ else
+ ambarella_udc_set_pullup(udc, 0);
+ spin_unlock_irqrestore(&udc->lock, flags);
+
+ return 0;
+}
+
+static int ambarella_udc_pullup(struct usb_gadget *gadget, int is_on)
+{
+ unsigned long flags;
+ struct ambarella_udc *udc = to_ambarella_udc(gadget);
+
+ spin_lock_irqsave(&udc->lock, flags);
+ ambarella_udc_set_pullup(udc, is_on);
+ spin_unlock_irqrestore(&udc->lock, flags);
+
+ return 0;
+}
+
+static int ambarella_udc_start(struct usb_gadget *gadget,
+ struct usb_gadget_driver *driver)
+{
+ struct ambarella_udc *udc = to_ambarella_udc(gadget);
+ unsigned long flags;
+
+ spin_lock_irqsave(&udc->lock, flags);
+
+ /* Hook the driver */
+ driver->driver.bus = NULL;
+ udc->driver = driver;
+ /* Enable udc */
+ ambarella_udc_enable(udc);
+
+ spin_unlock_irqrestore(&udc->lock, flags);
+
+ return 0;
+}
+
+static int ambarella_udc_stop(struct usb_gadget *gadget,
+ struct usb_gadget_driver *driver)
+{
+ struct ambarella_udc *udc = to_ambarella_udc(gadget);
+ unsigned long flags;
+
+ spin_lock_irqsave(&udc->lock, flags);
+
+ ambarella_stop_activity(udc);
+ ambarella_udc_disable(udc);
+ udc->driver = NULL;
+
+ spin_unlock_irqrestore(&udc->lock, flags);
+
+ return 0;
+}
+
+static const struct usb_gadget_ops ambarella_ops = {
+ .get_frame = ambarella_udc_get_frame,
+ .wakeup = ambarella_udc_wakeup,
+ .pullup = ambarella_udc_pullup,
+ .vbus_session = ambarella_udc_vbus_session,
+ /*.set_selfpowered: Always selfpowered */
+ .udc_start = ambarella_udc_start,
+ .udc_stop = ambarella_udc_stop,
+};
+
+/*------------------------- gadget driver handling---------------------------*/
+
+/* Tears down device */
+static void ambarella_gadget_release(struct device *dev)
+{
+ struct ambarella_udc *udc = dev_get_drvdata(dev);
+ kfree(udc);
+}
+
+static void ambarella_init_gadget(struct ambarella_udc *udc,
+ struct platform_device *pdev)
+{
+ struct ambarella_ep *ep;
+ u32 i;
+
+ spin_lock_init (&udc->lock);
+
+ udc->gadget.ops = &ambarella_ops;
+ udc->gadget.name = gadget_name;
+ udc->gadget.max_speed = USB_SPEED_HIGH;
+ udc->gadget.ep0 = &udc->ep[CTRL_IN].ep;
+ pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+
+ /* set basic ep parameters */
+ for (i = 0; i < EP_NUM_MAX; i++) {
+ ep = &udc->ep[i];
+ ep->ep.name = amb_ep_string[i];
+ ep->id = i;
+ ep->ep.ops = &ambarella_ep_ops;
+ ep->ep.maxpacket = (unsigned short) ~0;
+
+ if (i < EP_IN_NUM) {
+ ep->dir = USB_DIR_IN;
+ } else {
+ ep->dir = USB_DIR_OUT;
+ }
+ }
+
+ udc->ep[CTRL_IN].ep.maxpacket = USB_EP_CTRL_MAX_PKT_SZ;
+ udc->ep[CTRL_OUT].ep.maxpacket = USB_EP_CTRL_MAX_PKT_SZ;
+
+ return;
+}
+
+static void ambarella_udc_enable(struct ambarella_udc *udc)
+{
+ if (udc->udc_is_enabled)
+ return;
+
+ udc->udc_is_enabled = 1;
+
+ /* Disable Tx and Rx DMA */
+ amba_clrbitsl(USB_DEV_CTRL_REG,
+ USB_DEV_RCV_DMA_EN | USB_DEV_TRN_DMA_EN);
+
+ /* flush all of dma fifo */
+ ambarella_udc_fifo_flush(udc);
+
+ /* initialize ep0 register */
+ init_ep0(udc);
+
+ /* enable ep0 interrupt. */
+ amba_clrbitsl(USB_DEV_EP_INTR_MSK_REG,
+ USB_DEV_MSK_EP0_IN | USB_DEV_MSK_EP0_OUT);
+
+ /* enable Tx and Rx DMA */
+ amba_setbitsl(USB_DEV_CTRL_REG,
+ USB_DEV_RCV_DMA_EN | USB_DEV_TRN_DMA_EN);
+
+ /* enable device interrupt:
+ * Set_Configure, Set_Interface, Speed Enumerate Complete, Reset */
+ amba_clrbitsl(USB_DEV_INTR_MSK_REG,
+ USB_DEV_MSK_SET_CFG |
+ USB_DEV_MSK_SET_INTF |
+ USB_DEV_MSK_SPD_ENUM_CMPL |
+ USB_DEV_MSK_RESET);
+}
+
+static void ambarella_udc_disable(struct ambarella_udc *udc)
+{
+ /* Disable all interrupts and Clear the interrupt registers */
+ ambarella_disable_all_intr();
+
+ /* Disable Tx and Rx DMA */
+ amba_clrbitsl(USB_DEV_CTRL_REG, USB_DEV_RCV_DMA_EN | USB_DEV_TRN_DMA_EN);
+
+ udc->gadget.speed = USB_SPEED_UNKNOWN;
+ udc->udc_is_enabled = 0;
+}
+
+
+/*
+ * ambarella_udc_reinit
+ */
+static void ambarella_udc_reinit(struct ambarella_udc *udc)
+{
+ u32 i;
+
+ /* device/ep0 records init */
+ INIT_LIST_HEAD (&udc->gadget.ep_list);
+ INIT_LIST_HEAD (&udc->gadget.ep0->ep_list);
+ udc->auto_ack_0_pkt = 0;
+ udc->remote_wakeup_en = 0;
+
+ for (i = 0; i < EP_NUM_MAX; i++) {
+ struct ambarella_ep *ep = &udc->ep[i];
+
+ if (!IS_EP0(ep))
+ list_add_tail (&ep->ep.ep_list, &udc->gadget.ep_list);
+
+ ep->udc = udc;
+ ep->halted = 0;
+ ep->data_desc = NULL;
+ ep->last_data_desc = NULL;
+ INIT_LIST_HEAD (&ep->queue);
+ }
+}
+
+static int ambarella_udc_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct ambarella_udc *udc;
+ struct resource *res;
+ struct usb_phy *phy;
+ int retval;
+
+ dev_info(&pdev->dev, "%s: version %s\n", gadget_name, DRIVER_VERSION);
+
+ udc = devm_kzalloc(&pdev->dev, sizeof(struct ambarella_udc), GFP_KERNEL);
+ if (!udc) {
+ dev_err(&pdev->dev, "failed to allocate memory\n");
+ return -ENOMEM;
+ }
+ udc->dev = &pdev->dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "no mem resource for base_reg!\n");
+ return -ENXIO;
+ }
+
+ udc->base_reg = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (udc->base_reg == NULL) {
+ dev_err(&pdev->dev, "devm_ioremap() failed\n");
+ return -ENOMEM;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "no mem resource for reset_reg!\n");
+ return -ENXIO;
+ }
+
+ udc->reset_reg = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (udc->reset_reg == NULL) {
+ dev_err(&pdev->dev, "devm_ioremap() failed\n");
+ return -ENOMEM;
+ }
+
+ udc->irq = platform_get_irq(pdev, 0);
+ if (udc->irq < 0) {
+ dev_err(&pdev->dev, "no irq!\n");
+ return -ENODEV;
+ }
+
+ if (of_find_property(np, "amb,dma-addr-fix", NULL))
+ udc->dma_fix = 0xc0000000;
+ else
+ udc->dma_fix = 0;
+
+ /* get the PHY device */
+ phy = devm_usb_get_phy_by_phandle(&pdev->dev, "amb,usbphy", 0);
+ if (IS_ERR(phy)) {
+ dev_err(&pdev->dev, "Can't get USB PHY %ld\n", PTR_ERR(phy));
+ return -ENXIO;
+ }
+
+ usb_phy_init(phy);
+ udc->phy = phy;
+
+ ambarella_udc_reset(udc->reset_reg, np);
+
+ udc->udc_is_enabled = 0;
+ udc->vbus_status = 0;
+
+ ambarella_init_gadget(udc, pdev);
+ ambarella_udc_reinit(udc);
+ ambarella_regaddr_map(udc);
+
+ /*initial usb hardware, and set soft disconnect */
+ ambarella_init_usb(udc);
+
+ /* DMA pool create */
+ udc->desc_dma_pool = dma_pool_create("desc_dma_pool", NULL,
+ sizeof(struct ambarella_data_desc), 16, 0);
+ if (!udc->desc_dma_pool) {
+ pr_err("%s: can't get descriptor dma pool\n", __func__);
+ return -ENOMEM;
+ }
+
+ udc->setup_buf = dma_pool_alloc(udc->desc_dma_pool, GFP_KERNEL,
+ &udc->setup_addr);
+ if(udc->setup_buf == NULL) {
+ printk(KERN_ERR "No memory to DMA\n");
+ retval = -ENOMEM;
+ goto err_out1;
+ }
+
+ retval = init_null_pkt_desc(udc);
+ if(retval){
+ goto err_out2;
+ }
+
+ /* irq setup after old hardware state is cleaned up */
+ retval = devm_request_irq(&pdev->dev, udc->irq, ambarella_udc_irq,
+ IRQF_TRIGGER_HIGH, dev_name(&pdev->dev), udc);
+ if (retval != 0) {
+ pr_err("%s: cannot get irq %d\n", __func__, udc->irq);
+ goto err_out3;
+ }
+
+ setup_timer(&udc->vbus_timer,
+ ambarella_vbus_timer, (unsigned long)udc);
+ mod_timer(&udc->vbus_timer, jiffies + VBUS_POLL_TIMEOUT);
+
+ udc->pre_state = USB_STATE_NOTATTACHED;
+ INIT_WORK(&udc->uevent_work, ambarella_uevent_work);
+
+#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+ udc->proc_file = proc_create_data(proc_node_name, 0,
+ NULL, &ambarella_udc_fops, udc);
+ if (udc->proc_file == NULL) {
+ retval = -ENOMEM;
+ goto err_out3;
+ }
+#endif
+
+ /* Register gadget driver */
+ retval = usb_add_gadget_udc_release(&pdev->dev, &udc->gadget,
+ ambarella_gadget_release);
+ if (retval) {
+ goto err_out4;
+ }
+
+ platform_set_drvdata(pdev, udc);
+
+ return 0;
+
+err_out4:
+#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+ remove_debugfs_files();
+#endif
+err_out3:
+ dma_pool_free(udc->desc_dma_pool, udc->dummy_desc, udc->dummy_desc_addr);
+err_out2:
+ dma_pool_free(udc->desc_dma_pool, udc->setup_buf, udc->setup_addr);
+err_out1:
+ dma_pool_destroy(udc->desc_dma_pool);
+ return retval;
+}
+
+
+/*
+ * Name: ambarella_udc_remove
+ * Description:
+ * Remove udc driver.
+ */
+static int ambarella_udc_remove(struct platform_device *pdev)
+{
+ struct ambarella_udc *udc = platform_get_drvdata(pdev);
+
+ usb_del_gadget_udc(&udc->gadget);
+ if (udc->driver)
+ return -EBUSY;
+
+ del_timer_sync(&udc->vbus_timer);
+#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+ remove_debugfs_files();
+#endif
+ dma_pool_free(udc->desc_dma_pool, udc->dummy_desc, udc->dummy_desc_addr);
+ dma_pool_free(udc->desc_dma_pool, udc->setup_buf, udc->setup_addr);
+ dma_pool_destroy(udc->desc_dma_pool);
+
+ return 0;
+}
+
+
+#ifdef CONFIG_PM
+static int ambarella_udc_suspend(struct platform_device *pdev, pm_message_t message)
+{
+ unsigned long flags;
+ int retval = 0;
+ struct ambarella_udc *udc;
+
+ udc = platform_get_drvdata(pdev);
+ udc->sys_suspended = 1;
+ disable_irq(udc->irq);
+
+ del_timer_sync(&udc->vbus_timer);
+
+ spin_lock_irqsave(&udc->lock, flags);
+ ambarella_udc_set_pullup(udc, 0);
+ spin_unlock_irqrestore(&udc->lock, flags);
+
+ udc->udc_is_enabled = 0;
+ udc->vbus_status = 0;
+
+ dev_dbg(&pdev->dev, "%s exit with %d @ %d\n",
+ __func__, retval, message.event);
+
+ return retval;
+}
+
+static int ambarella_udc_resume(struct platform_device *pdev)
+{
+ unsigned long flags;
+ int retval = 0;
+ struct ambarella_udc *udc;
+
+ udc = platform_get_drvdata(pdev);
+ udc->sys_suspended = 0;
+
+ /* Initial USB PLL */
+ usb_phy_init(udc->phy);
+ /* Reset USB */
+ ambarella_udc_reset(udc->reset_reg, pdev->dev.of_node);
+ /*initial usb hardware */
+ ambarella_init_usb(udc);
+
+ enable_irq(udc->irq);
+
+ spin_lock_irqsave(&udc->lock, flags);
+ ambarella_udc_set_pullup(udc, 1);
+ spin_unlock_irqrestore(&udc->lock, flags);
+
+ setup_timer(&udc->vbus_timer,
+ ambarella_vbus_timer, (unsigned long)udc);
+ mod_timer(&udc->vbus_timer, jiffies + VBUS_POLL_TIMEOUT);
+
+ dev_dbg(&pdev->dev, "%s exit with %d\n", __func__, retval);
+
+ return retval;
+}
+#endif
+
+static const struct of_device_id ambarella_udc_dt_ids[] = {
+ { .compatible = "ambarella,udc" },
+ { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, ambarella_udc_dt_ids);
+
+static struct platform_driver ambarella_udc_driver = {
+ .driver = {
+ .name = "ambarella-udc",
+ .owner = THIS_MODULE,
+ .of_match_table = ambarella_udc_dt_ids,
+ },
+ .remove = ambarella_udc_remove,
+#ifdef CONFIG_PM
+ .suspend = ambarella_udc_suspend,
+ .resume = ambarella_udc_resume,
+#endif
+};
+
+module_platform_driver_probe(ambarella_udc_driver, ambarella_udc_probe);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ambarella-usbgadget");
+
diff --git a/drivers/usb/gadget/ambarella_udc.h b/drivers/usb/gadget/ambarella_udc.h
new file mode 100644
index 00000000..fef8433f
--- /dev/null
+++ b/drivers/usb/gadget/ambarella_udc.h
@@ -0,0 +1,202 @@
+/*
+* linux/drivers/usb/gadget/ambarella_udc.h
+* driver for High/Full speed
+USB device controller on Ambarella processors
+*
+* History:
+* 2008/06/12 - [Cao Rongrong] created file
+*
+* Copyright (C) 2008 by Ambarella, Inc.
+* http://www.ambarella.com
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the
+* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+* Boston, MA 02111-1307, USA.
+*/
+
+#ifndef _AMBARELLA_UDC_H
+#define _AMBARELLA_UDC_H
+
+#define CTRL_IN 0
+#define CTRL_OUT 16
+
+#define EP_IN_NUM 16
+#define EP_NUM_MAX 32
+
+#define CTRL_OUT_UDC_IDX 11
+
+#define ISO_MAX_PACKET 3
+
+#define IS_EP0(ep) (ep->id == CTRL_IN || ep->id == CTRL_OUT)
+#define IS_ISO_IN_EP(ep) (!IS_EP0(ep) && usb_endpoint_is_isoc_in(ep->ep.desc))
+
+#define UDC_DMA_MAXPACKET 65536
+
+#define VBUS_POLL_TIMEOUT msecs_to_jiffies(500)
+
+//-------------------------------------
+// Structure definition
+//-------------------------------------
+// SETUP buffer descriptor
+struct ambarella_setup_desc {
+ u32 status;
+ u32 reserved;
+ u32 data0;
+ u32 data1;
+ u32 rsvd1;
+ u32 rsvd2;
+ u32 rsvd3;
+ u32 rsvd4;
+};
+
+// IN/OUT data descriptor
+struct ambarella_data_desc {
+ u32 status;
+ u32 reserved;
+ u32 data_ptr;
+ u32 next_desc_ptr;
+ u32 rsvd1;
+ u32 last_aux; /* dma enginee may disturb the L bit in status
+ * field, so we use this field as auxiliary to
+ * mark the last descriptor */
+ dma_addr_t cur_desc_addr; /* dma address for this descriptor */
+ struct ambarella_data_desc *next_desc_virt;
+};
+
+
+struct ambarella_ep_reg {
+ u32 ctrl_reg;
+ u32 sts_reg;
+ u32 buf_sz_reg; // IN_EP: buf_sz_reg, OUT_EP: pkt_frm_num_reg
+ u32 max_pkt_sz_reg; // IN_EP: max_pkt_sz_reg, OUT EP: buffer_size_max_pkt_sz_reg
+ u32 setup_buf_ptr_reg; // Just for ep0
+ u32 dat_desc_ptr_reg;
+ //u32 rw_confirm; // For slave-only mode
+};
+
+
+struct ambarella_request {
+ struct list_head queue; /* ep's requests */
+ struct usb_request req;
+
+ int desc_count;
+ int active_desc_count;
+ dma_addr_t data_desc_addr; /* data_desc Physical Address */
+ struct ambarella_data_desc *data_desc;
+
+ dma_addr_t dma_aux;
+ void *buf_aux; /* If the original buffer of
+ * usb_req is not 8-bytes
+ * aligned, we use this buffer
+ * instead */
+ unsigned use_aux_buf : 1,
+ mapped : 1;
+};
+
+
+struct ambarella_ep {
+
+ struct list_head queue;
+ struct ambarella_udc *udc;
+ const struct usb_endpoint_descriptor *desc;
+ struct usb_ep ep;
+ u8 id;
+ u8 dir;
+
+ struct ambarella_ep_reg ep_reg;
+
+ struct ambarella_data_desc *data_desc;
+ struct ambarella_data_desc *last_data_desc;
+ dma_addr_t data_desc_addr; /* data_desc Physical Address */
+
+ unsigned halted : 1,
+ cancel_transfer : 1,
+ need_cnak : 1,
+ ctrl_sts_phase : 1,
+ dma_going : 1;
+
+ unsigned int frame_offset; /* iso frame num offset */
+};
+
+struct ambarella_udc {
+ spinlock_t lock;
+ struct device *dev;
+ void __iomem *base_reg;
+ void __iomem *reset_reg;
+ int irq;
+ struct usb_phy *phy;
+
+ struct proc_dir_entry *proc_file;
+ struct work_struct uevent_work;
+ struct timer_list vbus_timer;
+ enum usb_device_state pre_state;
+
+ struct usb_gadget gadget;
+ struct usb_gadget_driver *driver;
+
+ struct dma_pool *desc_dma_pool;
+
+ struct ambarella_ep ep[EP_NUM_MAX];
+ u32 setup[2];
+ dma_addr_t setup_addr;
+ struct ambarella_setup_desc *setup_buf;
+ dma_addr_t dummy_desc_addr;
+ struct ambarella_data_desc *dummy_desc;
+
+ u16 cur_config;
+ u16 cur_intf;
+ u16 cur_alt;
+
+ unsigned auto_ack_0_pkt : 1,
+ remote_wakeup_en : 1,
+ host_suspended : 1,
+ sys_suspended : 1,
+ reset_by_host : 1,
+ vbus_status : 1,
+ udc_is_enabled : 1;
+
+ /* dma_fix is only used for S2 chip, due to its DMA engine fault */
+ u32 dma_fix;
+};
+
+/* Function Declaration */
+static void ambarella_udc_done(struct ambarella_ep *ep,
+ struct ambarella_request *req, int status);
+
+static void ambarella_set_tx_dma(struct ambarella_ep *ep,
+ struct ambarella_request * req, int fix);
+
+static void ambarella_set_rx_dma(struct ambarella_ep *ep,
+ struct ambarella_request * req);
+
+static void ambarella_udc_reinit(struct ambarella_udc *udc);
+
+static int ambarella_udc_set_halt(struct usb_ep *_ep, int value);
+
+static void ambarella_ep_nuke(struct ambarella_ep *ep, int status);
+
+static void ambarella_stop_activity(struct ambarella_udc *udc);
+
+static void ambarella_udc_enable(struct ambarella_udc *udc);
+
+static void ambarella_udc_disable(struct ambarella_udc *udc);
+
+static int ambarella_udc_vbus_session(struct usb_gadget *gadget, int is_active);
+
+static int ambarella_udc_set_pullup(struct ambarella_udc *udc, int is_on);
+
+static int ambarella_udc_get_frame(struct usb_gadget *_gadget);
+
+#endif
+
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
index bcd04bc6..e39d2ddb 100644
--- a/drivers/usb/gadget/gadget_chips.h
+++ b/drivers/usb/gadget/gadget_chips.h
@@ -33,6 +33,7 @@
#define gadget_is_net2280(g) (!strcmp("net2280", (g)->name))
#define gadget_is_pxa(g) (!strcmp("pxa25x_udc", (g)->name))
#define gadget_is_pxa27x(g) (!strcmp("pxa27x_udc", (g)->name))
+#define gadget_is_ambarella(g) (!strcmp("ambarella_udc", (g)->name))
/**
* gadget_supports_altsettings - return true if altsettings work
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index 1f5f978d..9d4f2658 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -246,7 +246,7 @@ static int __init init(void)
*/
if (use_acm) {
serial_config_driver.label = "CDC ACM config";
- serial_config_driver.bConfigurationValue = 2;
+ serial_config_driver.bConfigurationValue = 1;
device_desc.bDeviceClass = USB_CLASS_COMM;
device_desc.idProduct =
cpu_to_le16(GS_CDC_PRODUCT_ID);
@@ -258,7 +258,7 @@ static int __init init(void)
cpu_to_le16(GS_CDC_OBEX_PRODUCT_ID);
} else {
serial_config_driver.label = "Generic Serial config";
- serial_config_driver.bConfigurationValue = 1;
+ serial_config_driver.bConfigurationValue = 2;
device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
device_desc.idProduct =
cpu_to_le16(GS_PRODUCT_ID);
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index 4b76124c..47e97fe3 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -239,7 +239,8 @@ rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags)
* but on at least one, checksumming fails otherwise. Note:
* RNDIS headers involve variable numbers of LE32 values.
*/
- skb_reserve(skb, NET_IP_ALIGN);
+ if (!gadget_is_ambarella(dev->gadget))
+ skb_reserve(skb, NET_IP_ALIGN);
req->buf = skb->data;
req->length = size;
@@ -563,6 +564,7 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb,
length = skb->len;
}
+
req->buf = skb->data;
req->context = skb;
req->complete = tx_complete;
diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
index 817a26cb..f4a04cfc 100644
--- a/drivers/usb/gadget/udc-core.c
+++ b/drivers/usb/gadget/udc-core.c
@@ -23,6 +23,7 @@
#include <linux/list.h>
#include <linux/err.h>
#include <linux/dma-mapping.h>
+#include <linux/workqueue.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
@@ -101,11 +102,18 @@ EXPORT_SYMBOL_GPL(usb_gadget_unmap_request);
/* ------------------------------------------------------------------------- */
+static void usb_gadget_state_work(struct work_struct *work)
+{
+ struct usb_gadget *gadget = work_to_gadget(work);
+
+ sysfs_notify(&gadget->dev.kobj, NULL, "status");
+}
+
void usb_gadget_set_state(struct usb_gadget *gadget,
enum usb_device_state state)
{
gadget->state = state;
- sysfs_notify(&gadget->dev.kobj, NULL, "state");
+ schedule_work(&gadget->work);
}
EXPORT_SYMBOL_GPL(usb_gadget_set_state);
@@ -192,6 +200,7 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
goto err1;
dev_set_name(&gadget->dev, "gadget");
+ INIT_WORK(&gadget->work, usb_gadget_state_work);
gadget->dev.parent = parent;
dma_set_coherent_mask(&gadget->dev, parent->coherent_dma_mask);
@@ -309,6 +318,7 @@ found:
usb_gadget_remove_driver(udc);
kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE);
+ flush_work(&gadget->work);
device_unregister(&udc->dev);
device_unregister(&gadget->dev);
}
diff --git a/drivers/usb/gadget/uvc_queue.c b/drivers/usb/gadget/uvc_queue.c
index de456a5a..509469de 100644
--- a/drivers/usb/gadget/uvc_queue.c
+++ b/drivers/usb/gadget/uvc_queue.c
@@ -120,6 +120,7 @@ static int uvc_queue_init(struct uvc_video_queue *queue,
queue->queue.buf_struct_size = sizeof(struct uvc_buffer);
queue->queue.ops = &uvc_queue_qops;
queue->queue.mem_ops = &vb2_vmalloc_memops;
+ queue->queue.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
ret = vb2_queue_init(&queue->queue);
if (ret)
return ret;
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 344d5e2f..8424c952 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -121,6 +121,14 @@ config USB_EHCI_BIG_ENDIAN_MMIO
config USB_EHCI_BIG_ENDIAN_DESC
bool
+config USB_EHCI_AMBARELLA
+ tristate "Ambarella EHCI support"
+ depends on USB_EHCI_HCD && ARCH_AMBARELLA
+ ---help---
+ This driver enables support for EHCI found in Ambarella SoCs.
+ Root Hub has NO inbuilt TT.
+ You will need to enable USB_PHY and Ambarella PHY driver as well.
+
config XPS_USB_HCD_XILINX
bool "Use Xilinx usb host EHCI controller core"
depends on (PPC32 || MICROBLAZE)
@@ -365,6 +373,14 @@ config USB_OHCI_HCD
if USB_OHCI_HCD
+config USB_OHCI_AMBARELLA
+ boolean "Ambarella OHCI support"
+ depends on ARCH_AMBARELLA
+ ---help---
+ This driver enables support for OHCI found in Ambarella SoCs.
+ Root Hub has NO inbuilt TT.
+ You will need to enable USB_PHY and Ambarella PHY driver as well.
+
config USB_OHCI_HCD_OMAP1
bool "OHCI support for OMAP1/2 chips"
depends on ARCH_OMAP1
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 4fb73c15..46a4cb86 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_USB_EHCI_HCD_SPEAR) += ehci-spear.o
obj-$(CONFIG_USB_EHCI_S5P) += ehci-s5p.o
obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o
obj-$(CONFIG_USB_EHCI_MSM) += ehci-msm.o
+obj-$(CONFIG_USB_EHCI_AMBARELLA) += ehci-ambarella.o
obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o
obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o
diff --git a/drivers/usb/host/ehci-ambarella.c b/drivers/usb/host/ehci-ambarella.c
new file mode 100644
index 00000000..affec7eb
--- /dev/null
+++ b/drivers/usb/host/ehci-ambarella.c
@@ -0,0 +1,247 @@
+/*
+* linux/drivers/usb/host/ehci-ambarella.c
+* driver for High speed (USB2.0) USB host controller on Ambarella processors
+*
+* History:
+* 2010/08/11 - [Cao Rongrong] created file
+*
+* Copyright (C) 2008 by Ambarella, Inc.
+* http://www.ambarella.com
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the
+* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+* Boston, MA 02111-1307, USA.
+*/
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/usb/ulpi.h>
+#include <linux/pm_runtime.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/of.h>
+#include <linux/dma-mapping.h>
+#include <mach/hardware.h>
+#include <plat/rct.h>
+
+#include "ehci.h"
+
+#define DRIVER_DESC "AMBARELLA-EHCI Host Controller driver"
+static const char hcd_name[] = "ehci-ambarella";
+
+
+struct ehci_ambarella_priv {
+ struct usb_phy *phy;
+ u32 nports;
+};
+
+static struct hc_driver __read_mostly ehci_ambarella_hc_driver;
+
+static int ambarella_ehci_setup(struct usb_hcd *hcd)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ struct ehci_ambarella_priv *priv;
+ int ret = 0;
+
+ /* registers start at offset 0x0 */
+ ehci->caps = hcd->regs;
+
+ ret = ehci_setup(hcd);
+ if (ret)
+ return ret;
+
+ /* EHCI will still detect 2 ports even though usb port1 is configured
+ * as device port, so we fake the port number manually and report
+ * it to EHCI.*/
+ priv = (struct ehci_ambarella_priv *)hcd_to_ehci(hcd)->priv;
+ ehci->hcs_params &= ~0xf;
+ ehci->hcs_params |= priv->nports;
+
+ return 0;
+}
+
+static const struct ehci_driver_overrides ehci_ambarella_overrides __initdata = {
+ .reset = ambarella_ehci_setup,
+ .extra_priv_size = sizeof(struct ehci_ambarella_priv),
+};
+
+static int ehci_ambarella_drv_probe(struct platform_device *pdev)
+{
+ struct ehci_ambarella_priv *priv;
+ struct usb_hcd *hcd;
+ struct usb_phy *phy;
+ struct resource *res;
+ int irq, ret;
+
+ if (usb_disabled())
+ return -ENODEV;
+
+ /* Right now device-tree probed devices don't get dma_mask set.
+ * Since shared usb code relies on it, set it here for now.
+ * Once we have dma capability bindings this can go away.
+ */
+ if (!pdev->dev.dma_mask)
+ pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+ if (!pdev->dev.coherent_dma_mask)
+ pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+
+ hcd = usb_create_hcd(&ehci_ambarella_hc_driver, &pdev->dev, "AmbUSB");
+ if (!hcd)
+ return -ENOMEM;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "Unable to get IRQ resource\n");
+ ret = irq;
+ goto amb_ehci_err;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "Unable to get memory resource\n");
+ ret = -ENODEV;
+ goto amb_ehci_err;
+ }
+
+ hcd->rsrc_start = res->start;
+ hcd->rsrc_len = resource_size(res);
+ hcd->regs = devm_ioremap(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len);
+ if (!hcd->regs) {
+ dev_err(&pdev->dev, "ioremap failed\n");
+ ret = -ENOMEM;
+ goto amb_ehci_err;
+ }
+
+ priv = (struct ehci_ambarella_priv *)hcd_to_ehci(hcd)->priv;
+
+ /* get the PHY device */
+ phy = devm_usb_get_phy_by_phandle(&pdev->dev, "amb,usbphy", 0);
+ if (IS_ERR(phy)) {
+ ret = PTR_ERR(phy);
+ dev_err(&pdev->dev, "Can't get USB PHY %d\n", ret);
+ goto amb_ehci_err;
+ }
+
+ ret = of_property_read_u32(phy->dev->of_node,
+ "amb,host-phy-num", &priv->nports);
+ if (ret < 0){
+ dev_err(&pdev->dev, "Can't get host phy num %d\n", ret);
+ goto amb_ehci_err;
+ }
+
+ usb_phy_init(phy);
+ priv->phy = phy;
+
+ ret = usb_add_hcd(hcd, irq, 0);
+ if (ret < 0)
+ goto amb_ehci_err;
+
+ platform_set_drvdata(pdev, hcd);
+
+ return 0;
+
+amb_ehci_err:
+ usb_put_hcd(hcd);
+ return ret;
+}
+
+static int ehci_ambarella_drv_remove(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+ usb_remove_hcd(hcd);
+ usb_put_hcd(hcd);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int ehci_ambarella_drv_resume(struct device *dev)
+{
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct ehci_ambarella_priv *priv;
+
+ priv = (struct ehci_ambarella_priv *)hcd_to_ehci(hcd)->priv;
+
+ usb_phy_init(priv->phy);
+
+ ehci_resume(hcd, false);
+
+ return 0;
+}
+
+static int ehci_ambarella_drv_suspend(struct device *dev)
+{
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
+ bool do_wakeup = device_may_wakeup(dev);
+
+ return ehci_suspend(hcd, do_wakeup);;
+}
+
+static struct dev_pm_ops ambarella_ehci_pmops = {
+ .suspend = ehci_ambarella_drv_suspend,
+ .resume = ehci_ambarella_drv_resume,
+ .freeze = ehci_ambarella_drv_suspend,
+ .thaw = ehci_ambarella_drv_resume,
+};
+
+#define AMBARELLA_EHCI_PMOPS &ambarella_ehci_pmops
+
+#else
+#define AMBARELLA_EHCI_PMOPS NULL
+#endif
+
+
+static struct of_device_id ambarella_ehci_dt_ids[] = {
+ { .compatible = "ambarella,ehci", },
+ { },
+};
+
+static struct platform_driver ehci_hcd_ambarella_driver = {
+ .probe = ehci_ambarella_drv_probe,
+ .remove = ehci_ambarella_drv_remove,
+ .shutdown = usb_hcd_platform_shutdown,
+ .driver = {
+ .name = "ambarella-ehci",
+ .of_match_table = of_match_ptr(ambarella_ehci_dt_ids),
+ .pm = AMBARELLA_EHCI_PMOPS,
+ }
+};
+
+static int __init ehci_ambarella_init(void)
+{
+ if (usb_disabled())
+ return -ENODEV;
+
+ pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+ ehci_init_driver(&ehci_ambarella_hc_driver, &ehci_ambarella_overrides);
+ return platform_driver_register(&ehci_hcd_ambarella_driver);
+}
+module_init(ehci_ambarella_init);
+
+static void __exit ehci_ambarella_cleanup(void)
+{
+ platform_driver_unregister(&ehci_hcd_ambarella_driver);
+}
+module_exit(ehci_ambarella_cleanup);
+
+MODULE_ALIAS("platform:ambarella-ehci");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index ca6289b4..7ddf38f5 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -694,6 +694,142 @@ ehci_hub_descriptor (
desc->wHubCharacteristics = cpu_to_le16(temp);
}
+/*-------------------------------------------------------------------------*/
+#define EHSET_TEST_SINGLE_STEP_SET_FEATURE 0x06
+
+static void usb_ehset_completion(struct urb *urb)
+{
+ struct completion *done = urb->context;
+
+ complete(done);
+}
+static int submit_single_step_set_feature(
+ struct usb_hcd *hcd,
+ struct urb *urb,
+ int is_setup
+);
+
+/*
+ * Allocate and initialize a control URB. This request will be used by the
+ * EHSET SINGLE_STEP_SET_FEATURE test in which the DATA and STATUS stages
+ * of the GetDescriptor request are sent 15 seconds after the SETUP stage.
+ * Return NULL if failed.
+ */
+static struct urb *request_single_step_set_feature_urb(
+ struct usb_device *udev,
+ void *dr,
+ void *buf,
+ struct completion *done
+) {
+ struct urb *urb;
+ struct usb_hcd *hcd = bus_to_hcd(udev->bus);
+ struct usb_host_endpoint *ep;
+
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb)
+ return NULL;
+
+ urb->pipe = usb_rcvctrlpipe(udev, 0);
+ ep = (usb_pipein(urb->pipe) ? udev->ep_in : udev->ep_out)
+ [usb_pipeendpoint(urb->pipe)];
+ if (!ep) {
+ usb_free_urb(urb);
+ return NULL;
+ }
+
+ urb->ep = ep;
+ urb->dev = udev;
+ urb->setup_packet = (void *)dr;
+ urb->transfer_buffer = buf;
+ urb->transfer_buffer_length = USB_DT_DEVICE_SIZE;
+ urb->complete = usb_ehset_completion;
+ urb->status = -EINPROGRESS;
+ urb->actual_length = 0;
+ urb->transfer_flags = URB_DIR_IN;
+ usb_get_urb(urb);
+ atomic_inc(&urb->use_count);
+ atomic_inc(&urb->dev->urbnum);
+ urb->setup_dma = dma_map_single(
+ hcd->self.controller,
+ urb->setup_packet,
+ sizeof(struct usb_ctrlrequest),
+ DMA_TO_DEVICE);
+ urb->transfer_dma = dma_map_single(
+ hcd->self.controller,
+ urb->transfer_buffer,
+ urb->transfer_buffer_length,
+ DMA_FROM_DEVICE);
+ urb->context = done;
+ return urb;
+}
+
+static int ehset_single_step_set_feature(struct usb_hcd *hcd, int port)
+{
+ int retval = -ENOMEM;
+ struct usb_ctrlrequest *dr;
+ struct urb *urb;
+ struct usb_device *udev;
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ struct usb_device_descriptor *buf;
+ DECLARE_COMPLETION_ONSTACK(done);
+
+ /* Obtain udev of the rhub's child port */
+ udev = usb_hub_find_child(hcd->self.root_hub, port);
+ if (!udev) {
+ ehci_err(ehci, "No device attached to the RootHub\n");
+ return -ENODEV;
+ }
+ buf = kmalloc(USB_DT_DEVICE_SIZE, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
+ if (!dr) {
+ kfree(buf);
+ return -ENOMEM;
+ }
+
+ /* Fill Setup packet for GetDescriptor */
+ dr->bRequestType = USB_DIR_IN;
+ dr->bRequest = USB_REQ_GET_DESCRIPTOR;
+ dr->wValue = cpu_to_le16(USB_DT_DEVICE << 8);
+ dr->wIndex = 0;
+ dr->wLength = cpu_to_le16(USB_DT_DEVICE_SIZE);
+ urb = request_single_step_set_feature_urb(udev, dr, buf, &done);
+ if (!urb)
+ goto cleanup;
+
+ /* Submit just the SETUP stage */
+ retval = submit_single_step_set_feature(hcd, urb, 1);
+ if (retval)
+ goto out1;
+ if (!wait_for_completion_timeout(&done, msecs_to_jiffies(2000))) {
+ usb_kill_urb(urb);
+ retval = -ETIMEDOUT;
+ ehci_err(ehci, "%s SETUP stage timed out on ep0\n", __func__);
+ goto out1;
+ }
+ msleep(15 * 1000);
+
+ /* Complete remaining DATA and STATUS stages using the same URB */
+ urb->status = -EINPROGRESS;
+ usb_get_urb(urb);
+ atomic_inc(&urb->use_count);
+ atomic_inc(&urb->dev->urbnum);
+ retval = submit_single_step_set_feature(hcd, urb, 0);
+ if (!retval && !wait_for_completion_timeout(&done,
+ msecs_to_jiffies(2000))) {
+ usb_kill_urb(urb);
+ retval = -ETIMEDOUT;
+ ehci_err(ehci, "%s IN stage timed out on ep0\n", __func__);
+ }
+out1:
+ usb_free_urb(urb);
+cleanup:
+ kfree(dr);
+ kfree(buf);
+ return retval;
+}
/*-------------------------------------------------------------------------*/
static int ehci_hub_control (
@@ -1076,7 +1212,13 @@ static int ehci_hub_control (
* about the EHCI-specific stuff.
*/
case USB_PORT_FEAT_TEST:
- if (!selector || selector > 5)
+ if (selector == EHSET_TEST_SINGLE_STEP_SET_FEATURE) {
+ spin_unlock_irqrestore(&ehci->lock, flags);
+ retval = ehset_single_step_set_feature(hcd,
+ wIndex);
+ spin_lock_irqsave(&ehci->lock, flags);
+ break;
+ } else if (!selector || selector > 5)
goto error;
spin_unlock_irqrestore(&ehci->lock, flags);
ehci_quiesce(ehci);
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index d34b399b..702a0e93 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -1143,6 +1143,107 @@ submit_async (
return rc;
}
+/*-------------------------------------------------------------------------*/
+/*
+ * This function creates the qtds and submits them for the
+ * SINGLE_STEP_SET_FEATURE Test.
+ * This is done in two parts: first SETUP req for GetDesc is sent then
+ * 15 seconds later, the IN stage for GetDesc starts to req data from dev
+ *
+ * is_setup : i/p arguement decides which of the two stage needs to be
+ * performed; TRUE - SETUP and FALSE - IN+STATUS
+ * Returns 0 if success
+ */
+static int submit_single_step_set_feature(
+ struct usb_hcd *hcd,
+ struct urb *urb,
+ int is_setup
+) {
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ struct list_head qtd_list;
+ struct list_head *head;
+
+ struct ehci_qtd *qtd, *qtd_prev;
+ dma_addr_t buf;
+ int len, maxpacket;
+ u32 token;
+
+ INIT_LIST_HEAD(&qtd_list);
+ head = &qtd_list;
+
+ /* URBs map to sequences of QTDs: one logical transaction */
+ qtd = ehci_qtd_alloc(ehci, GFP_KERNEL);
+ if (unlikely(!qtd))
+ return -1;
+ list_add_tail(&qtd->qtd_list, head);
+ qtd->urb = urb;
+
+ token = QTD_STS_ACTIVE;
+ token |= (EHCI_TUNE_CERR << 10);
+
+ len = urb->transfer_buffer_length;
+ /*
+ * Check if the request is to perform just the SETUP stage (getDesc)
+ * as in SINGLE_STEP_SET_FEATURE test, DATA stage (IN) happens
+ * 15 secs after the setup
+ */
+ if (is_setup) {
+ /* SETUP pid */
+ qtd_fill(ehci, qtd, urb->setup_dma,
+ sizeof(struct usb_ctrlrequest),
+ token | (2 /* "setup" */ << 8), 8);
+
+ submit_async(ehci, urb, &qtd_list, GFP_ATOMIC);
+ return 0; /*Return now; we shall come back after 15 seconds*/
+ }
+
+ /*
+ * IN: data transfer stage: buffer setup : start the IN txn phase for
+ * the get_Desc SETUP which was sent 15seconds back
+ */
+ token ^= QTD_TOGGLE; /*We need to start IN with DATA-1 Pid-sequence*/
+ buf = urb->transfer_dma;
+
+ token |= (1 /* "in" */ << 8); /*This is IN stage*/
+
+ maxpacket = max_packet(usb_maxpacket(urb->dev, urb->pipe, 0));
+
+ qtd_fill(ehci, qtd, buf, len, token, maxpacket);
+
+ /*
+ * Our IN phase shall always be a short read; so keep the queue running
+ * and let it advance to the next qtd which zero length OUT status
+ */
+ qtd->hw_alt_next = EHCI_LIST_END(ehci);
+
+ /* STATUS stage for GetDesc control request */
+ token ^= 0x0100; /* "in" <--> "out" */
+ token |= QTD_TOGGLE; /* force DATA1 */
+
+ qtd_prev = qtd;
+ qtd = ehci_qtd_alloc(ehci, GFP_ATOMIC);
+ if (unlikely(!qtd))
+ goto cleanup;
+ qtd->urb = urb;
+ qtd_prev->hw_next = QTD_NEXT(ehci, qtd->qtd_dma);
+ list_add_tail(&qtd->qtd_list, head);
+
+ /* dont fill any data in such packets */
+ qtd_fill(ehci, qtd, 0, 0, token, 0);
+
+ /* by default, enable interrupt on urb completion */
+ if (likely(!(urb->transfer_flags & URB_NO_INTERRUPT)))
+ qtd->hw_token |= cpu_to_hc32(ehci, QTD_IOC);
+
+ submit_async(ehci, urb, &qtd_list, GFP_KERNEL);
+
+ return 0;
+
+cleanup:
+ qtd_list_free(ehci, urb, head);
+ return -1;
+}
+
/*-------------------------------------------------------------------------*/
static void single_unlink_async(struct ehci_hcd *ehci, struct ehci_qh *qh)
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 03322d9c..642b4664 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -664,6 +664,13 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc)
#define writel_be(val, addr) __raw_writel(val, (__force unsigned *)addr)
#endif
+#if defined(CONFIG_PLAT_AMBARELLA_ADD_REGISTER_LOCK)
+#undef writel
+#undef readl
+#define writel(v, p) amba_writel(p, v)
+#define readl(p) amba_readl(p)
+#endif
+
static inline unsigned int ehci_readl(const struct ehci_hcd *ehci,
__u32 __iomem * regs)
{
diff --git a/drivers/usb/host/ohci-ambarella.c b/drivers/usb/host/ohci-ambarella.c
new file mode 100644
index 00000000..bc5b27d1
--- /dev/null
+++ b/drivers/usb/host/ohci-ambarella.c
@@ -0,0 +1,264 @@
+/*
+* linux/drivers/usb/host/ohci-ambarella.c
+* driver for Full speed (USB1.1) USB host controller on Ambarella processors
+*
+* History:
+* 2010/08/11 - [Cao Rongrong] created file
+*
+* Copyright (C) 2008 by Ambarella, Inc.
+* http://www.ambarella.com
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the
+* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+* Boston, MA 02111-1307, USA.
+*/
+
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <mach/hardware.h>
+
+extern int usb_disabled(void);
+
+struct ohci_ambarella {
+ struct ohci_hcd ohci;
+ struct usb_phy *phy;
+ u32 nports;
+};
+
+
+static struct ohci_ambarella *hcd_to_ohci_ambarella(struct usb_hcd *hcd)
+{
+ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+
+ return container_of(ohci, struct ohci_ambarella, ohci);
+}
+
+static int ohci_ambarella_start(struct usb_hcd *hcd)
+{
+ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+ struct ohci_ambarella *amb_ohci = hcd_to_ohci_ambarella(hcd);
+ int ret;
+
+ /* OHCI will still detect 2 ports even though usb port1 is configured
+ * as device port, so we fake the port number manually and report
+ * it to OHCI.*/
+ ohci->num_ports = amb_ohci->nports;
+
+ if ((ret = ohci_init(ohci)) < 0)
+ return ret;
+
+ if ((ret = ohci_run(ohci)) < 0) {
+ dev_err(hcd->self.controller, "can't start\n");
+ ohci_stop(hcd);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct hc_driver ohci_ambarella_hc_driver = {
+ .description = hcd_name,
+ .product_desc = "Ambarella OHCI",
+ .hcd_priv_size = sizeof(struct ohci_ambarella),
+
+ /*
+ * generic hardware linkage
+ */
+ .irq = ohci_irq,
+ .flags = HCD_USB11 | HCD_MEMORY,
+
+ /*
+ * basic lifecycle operations
+ */
+ .start = ohci_ambarella_start,
+ .stop = ohci_stop,
+ .shutdown = ohci_shutdown,
+
+ /*
+ * managing i/o requests and associated device resources
+ */
+ .urb_enqueue = ohci_urb_enqueue,
+ .urb_dequeue = ohci_urb_dequeue,
+ .endpoint_disable = ohci_endpoint_disable,
+
+ /*
+ * scheduling support
+ */
+ .get_frame_number = ohci_get_frame,
+
+ /*
+ * root hub support
+ */
+ .hub_status_data = ohci_hub_status_data,
+ .hub_control = ohci_hub_control,
+#ifdef CONFIG_PM
+ .bus_suspend = ohci_bus_suspend,
+ .bus_resume = ohci_bus_resume,
+#endif
+ .start_port_reset = ohci_start_port_reset,
+};
+
+static int ohci_hcd_ambarella_drv_probe(struct platform_device *pdev)
+{
+ struct ohci_ambarella *amb_ohci;
+ struct usb_hcd *hcd;
+ struct resource *res;
+ struct usb_phy *phy;
+ int irq, ret;
+
+ if (usb_disabled())
+ return -ENODEV;
+
+ /* Right now device-tree probed devices don't get dma_mask set.
+ * Since shared usb code relies on it, set it here for now.
+ * Once we have dma capability bindings this can go away.
+ */
+ if (!pdev->dev.dma_mask)
+ pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+ if (!pdev->dev.coherent_dma_mask)
+ pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+
+ hcd = usb_create_hcd(&ohci_ambarella_hc_driver, &pdev->dev, "AmbUSB");
+ if (!hcd)
+ return -ENOMEM;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "Unable to get IRQ resource\n");
+ ret = irq;
+ goto amb_ohci_err;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "Unable to get memory resource\n");
+ ret = -ENODEV;
+ goto amb_ohci_err;
+ }
+
+ hcd->rsrc_start = res->start;
+ hcd->rsrc_len = resource_size(res);
+ hcd->regs = devm_ioremap(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len);
+ if (!hcd->regs) {
+ dev_err(&pdev->dev, "ioremap failed\n");
+ ret = -ENOMEM;
+ goto amb_ohci_err;
+ }
+
+ amb_ohci = hcd_to_ohci_ambarella(hcd);
+
+ /* get the PHY device */
+ phy = devm_usb_get_phy_by_phandle(&pdev->dev, "amb,usbphy", 0);
+ if (IS_ERR(phy)) {
+ ret = PTR_ERR(phy);
+ dev_err(&pdev->dev, "Can't get USB PHY %d\n", ret);
+ goto amb_ohci_err;
+ }
+
+ ret = of_property_read_u32(phy->dev->of_node,
+ "amb,host-phy-num", &amb_ohci->nports);
+ if (ret < 0){
+ dev_err(&pdev->dev, "Can't get host phy num %d\n", ret);
+ goto amb_ohci_err;
+ }
+
+ usb_phy_init(phy);
+ amb_ohci->phy = phy;
+
+ ohci_hcd_init(hcd_to_ohci(hcd));
+
+ ret = usb_add_hcd(hcd, irq, IRQF_TRIGGER_HIGH);
+ if (ret < 0)
+ goto amb_ohci_err;
+
+ platform_set_drvdata(pdev, hcd);
+
+ return 0;
+
+amb_ohci_err:
+ usb_put_hcd(hcd);
+ return ret;
+}
+
+static int ohci_hcd_ambarella_drv_remove(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+ usb_remove_hcd(hcd);
+ usb_put_hcd(hcd);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+
+/* Maybe just need to suspend/resume controller via HAL function. */
+static int ohci_hcd_ambarella_drv_suspend(struct device *dev)
+{
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+
+ if (time_before(jiffies, ohci->next_statechange))
+ msleep(5);
+ ohci->next_statechange = jiffies;
+
+ return 0;
+}
+
+static int ohci_hcd_ambarella_drv_resume(struct device *dev)
+{
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+
+ if (time_before(jiffies, ohci->next_statechange))
+ msleep(5);
+ ohci->next_statechange = jiffies;
+
+ ohci_resume(hcd, false);
+
+ return 0;
+}
+
+static struct dev_pm_ops ambarella_ohci_pmops = {
+ .suspend = ohci_hcd_ambarella_drv_suspend,
+ .resume = ohci_hcd_ambarella_drv_resume,
+ .freeze = ohci_hcd_ambarella_drv_suspend,
+ .thaw = ohci_hcd_ambarella_drv_resume,
+};
+
+#define AMBARELLA_OHCI_PMOPS &ambarella_ohci_pmops
+
+#else
+#define AMBARELLA_OHCI_PMOPS NULL
+#endif
+
+static const struct of_device_id ambarella_ohci_dt_ids[] = {
+ { .compatible = "ambarella,ohci", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ambarella_ohci_dt_ids);
+
+static struct platform_driver ohci_hcd_ambarella_driver = {
+ .probe = ohci_hcd_ambarella_drv_probe,
+ .remove = ohci_hcd_ambarella_drv_remove,
+ .shutdown = usb_hcd_platform_shutdown,
+ .driver = {
+ .name = "ambarella-ohci",
+ .owner = THIS_MODULE,
+ .pm = AMBARELLA_OHCI_PMOPS,
+ .of_match_table = of_match_ptr(ambarella_ohci_dt_ids),
+ },
+};
+
+MODULE_ALIAS("platform:ambarella-ohci");
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 865946cd..93ecd114 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1151,6 +1151,11 @@ MODULE_LICENSE ("GPL");
#define DAVINCI_PLATFORM_DRIVER ohci_hcd_da8xx_driver
#endif
+#ifdef CONFIG_USB_OHCI_AMBARELLA
+#include "ohci-ambarella.c"
+#define AMBARELLA_PLATFORM_DRIVER ohci_hcd_ambarella_driver
+#endif
+
#ifdef CONFIG_USB_OHCI_HCD_PPC_OF
#include "ohci-ppc-of.c"
#define OF_PLATFORM_DRIVER ohci_hcd_ppc_of_driver
@@ -1211,6 +1216,7 @@ MODULE_LICENSE ("GPL");
!defined(AT91_PLATFORM_DRIVER) && \
!defined(NXP_PLATFORM_DRIVER) && \
!defined(DAVINCI_PLATFORM_DRIVER) && \
+ !defined(AMBARELLA_PLATFORM_DRIVER) && \
!defined(SPEAR_PLATFORM_DRIVER)
#error "missing bus glue for ohci-hcd"
#endif
@@ -1247,6 +1253,12 @@ static int __init ohci_hcd_mod_init(void)
goto error_platform;
#endif
+#ifdef AMBARELLA_PLATFORM_DRIVER
+ retval = platform_driver_register(&AMBARELLA_PLATFORM_DRIVER);
+ if (retval < 0)
+ goto error_ambarella_platform;
+#endif
+
#ifdef OMAP1_PLATFORM_DRIVER
retval = platform_driver_register(&OMAP1_PLATFORM_DRIVER);
if (retval < 0)
@@ -1394,6 +1406,10 @@ static int __init ohci_hcd_mod_init(void)
platform_driver_unregister(&PLATFORM_DRIVER);
error_platform:
#endif
+#ifdef AMBARELLA_PLATFORM_DRIVER
+ platform_driver_unregister(&AMBARELLA_PLATFORM_DRIVER);
+ error_ambarella_platform:
+#endif
#ifdef PS3_SYSTEM_BUS_DRIVER
ps3_ohci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
error_ps3:
@@ -1456,6 +1472,9 @@ static void __exit ohci_hcd_mod_exit(void)
#ifdef PLATFORM_DRIVER
platform_driver_unregister(&PLATFORM_DRIVER);
#endif
+#ifdef AMBARELLA_PLATFORM_DRIVER
+ platform_driver_unregister(&AMBARELLA_PLATFORM_DRIVER);
+#endif
#ifdef PS3_SYSTEM_BUS_DRIVER
ps3_ohci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
#endif
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
index a51e7d6a..ca91420f 100644
--- a/drivers/usb/misc/Kconfig
+++ b/drivers/usb/misc/Kconfig
@@ -200,6 +200,19 @@ config USB_TEST
See <http://www.linux-usb.org/usbtest/> for more information,
including sample test device firmware and "how to use it".
+config USB_EHSET_TEST_FIXTURE
+ tristate "USB EHSET Test Fixture driver"
+ help
+ Say Y here if you want to support the special test fixture device
+ used for the USB-IF Embedded Host High-Speed Electrical Test procedure.
+
+ When the test fixture is connected, it can enumerate as one of several
+ VID/PID pairs. This driver then initiates a corresponding test mode on
+ the downstream port to which the test fixture is attached.
+
+ See <http://www.usb.org/developers/onthego/EHSET_v1.01.pdf> for more
+ information.
+
config USB_ISIGHTFW
tristate "iSight firmware loading support"
select FW_LOADER
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
index 3e1bd70b..c9eafdfc 100644
--- a/drivers/usb/misc/Makefile
+++ b/drivers/usb/misc/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_USB_LED) += usbled.o
obj-$(CONFIG_USB_LEGOTOWER) += legousbtower.o
obj-$(CONFIG_USB_RIO500) += rio500.o
obj-$(CONFIG_USB_TEST) += usbtest.o
+obj-$(CONFIG_USB_EHSET_TEST_FIXTURE) += ehset.o
obj-$(CONFIG_USB_TRANCEVIBRATOR) += trancevibrator.o
obj-$(CONFIG_USB_USS720) += uss720.o
obj-$(CONFIG_USB_SEVSEG) += usbsevseg.o
diff --git a/drivers/usb/misc/ehset.c b/drivers/usb/misc/ehset.c
new file mode 100644
index 00000000..c31b4a33
--- /dev/null
+++ b/drivers/usb/misc/ehset.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <linux/usb/ch11.h>
+
+#define TEST_SE0_NAK_PID 0x0101
+#define TEST_J_PID 0x0102
+#define TEST_K_PID 0x0103
+#define TEST_PACKET_PID 0x0104
+#define TEST_HS_HOST_PORT_SUSPEND_RESUME 0x0106
+#define TEST_SINGLE_STEP_GET_DEV_DESC 0x0107
+#define TEST_SINGLE_STEP_SET_FEATURE 0x0108
+
+static int ehset_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ int ret = -EINVAL;
+ struct usb_device *dev = interface_to_usbdev(intf);
+ struct usb_device *hub_udev = dev->parent;
+ struct usb_device_descriptor *buf;
+ u8 portnum = dev->portnum;
+ u16 test_pid = le16_to_cpu(dev->descriptor.idProduct);
+
+ switch (test_pid) {
+ case TEST_SE0_NAK_PID:
+ ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
+ USB_REQ_SET_FEATURE, USB_RT_PORT,
+ USB_PORT_FEAT_TEST,
+ (TEST_SE0_NAK << 8) | portnum,
+ NULL, 0, 1000);
+ break;
+ case TEST_J_PID:
+ ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
+ USB_REQ_SET_FEATURE, USB_RT_PORT,
+ USB_PORT_FEAT_TEST,
+ (TEST_J << 8) | portnum,
+ NULL, 0, 1000);
+ break;
+ case TEST_K_PID:
+ ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
+ USB_REQ_SET_FEATURE, USB_RT_PORT,
+ USB_PORT_FEAT_TEST,
+ (TEST_K << 8) | portnum,
+ NULL, 0, 1000);
+ break;
+ case TEST_PACKET_PID:
+ ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
+ USB_REQ_SET_FEATURE, USB_RT_PORT,
+ USB_PORT_FEAT_TEST,
+ (TEST_PACKET << 8) | portnum,
+ NULL, 0, 1000);
+ break;
+ case TEST_HS_HOST_PORT_SUSPEND_RESUME:
+ /* Test: wait for 15secs -> suspend -> 15secs delay -> resume */
+ msleep(15 * 1000);
+ ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
+ USB_REQ_SET_FEATURE, USB_RT_PORT,
+ USB_PORT_FEAT_SUSPEND, portnum,
+ NULL, 0, 1000);
+ if (ret < 0)
+ break;
+
+ msleep(15 * 1000);
+ ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
+ USB_REQ_CLEAR_FEATURE, USB_RT_PORT,
+ USB_PORT_FEAT_SUSPEND, portnum,
+ NULL, 0, 1000);
+ break;
+ case TEST_SINGLE_STEP_GET_DEV_DESC:
+ /* Test: wait for 15secs -> GetDescriptor request */
+ msleep(15 * 1000);
+ buf = kmalloc(USB_DT_DEVICE_SIZE, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
+ USB_DT_DEVICE << 8, 0,
+ buf, USB_DT_DEVICE_SIZE,
+ USB_CTRL_GET_TIMEOUT);
+ kfree(buf);
+ break;
+ case TEST_SINGLE_STEP_SET_FEATURE:
+ /*
+ * GetDescriptor SETUP request -> 15secs delay -> IN & STATUS
+ *
+ * Note, this test is only supported on root hubs since the
+ * SetPortFeature handling can only be done inside the HCD's
+ * hub_control callback function.
+ */
+ if (hub_udev != dev->bus->root_hub) {
+ dev_err(&intf->dev, "SINGLE_STEP_SET_FEATURE test only supported on root hub\n");
+ break;
+ }
+
+ ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
+ USB_REQ_SET_FEATURE, USB_RT_PORT,
+ USB_PORT_FEAT_TEST,
+ (6 << 8) | portnum,
+ NULL, 0, 60 * 1000);
+
+ break;
+ default:
+ dev_err(&intf->dev, "%s: unsupported PID: 0x%x\n",
+ __func__, test_pid);
+ }
+
+ return (ret < 0) ? ret : 0;
+}
+
+static void ehset_disconnect(struct usb_interface *intf)
+{
+}
+
+static const struct usb_device_id ehset_id_table[] = {
+ { USB_DEVICE(0x1a0a, TEST_SE0_NAK_PID) },
+ { USB_DEVICE(0x1a0a, TEST_J_PID) },
+ { USB_DEVICE(0x1a0a, TEST_K_PID) },
+ { USB_DEVICE(0x1a0a, TEST_PACKET_PID) },
+ { USB_DEVICE(0x1a0a, TEST_HS_HOST_PORT_SUSPEND_RESUME) },
+ { USB_DEVICE(0x1a0a, TEST_SINGLE_STEP_GET_DEV_DESC) },
+ { USB_DEVICE(0x1a0a, TEST_SINGLE_STEP_SET_FEATURE) },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, ehset_id_table);
+
+static struct usb_driver ehset_driver = {
+ .name = "usb_ehset_test",
+ .probe = ehset_probe,
+ .disconnect = ehset_disconnect,
+ .id_table = ehset_id_table,
+};
+
+module_usb_driver(ehset_driver);
+
+MODULE_DESCRIPTION("USB Driver for EHSET Test Fixture");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index 2311b1e4..8f63a413 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -21,6 +21,13 @@ if USB_PHY
#
# USB Transceiver Drivers
#
+config USB_AMBARELLA_PHY
+ bool "Ambarella USB PHY support"
+ depends on ARCH_AMBARELLA
+ help
+ Enable this to support the Ambarella USB PHY.
+ Ambarella USB Phy is used by either UDC or EHCI/OHCI.
+
config AB8500_USB
tristate "AB8500 USB Transceiver Driver"
depends on AB8500_CORE
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
index a9169cb1..6675f0e0 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_USB_PHY) += phy.o
# transceiver drivers, keep the list sorted
+obj-$(CONFIG_USB_AMBARELLA_PHY) += phy-ambarella.o
obj-$(CONFIG_AB8500_USB) += phy-ab8500-usb.o
phy-fsl-usb2-objs := phy-fsl-usb.o phy-fsm-usb.o
obj-$(CONFIG_FSL_USB2_OTG) += phy-fsl-usb2.o
diff --git a/drivers/usb/phy/phy-ambarella.c b/drivers/usb/phy/phy-ambarella.c
new file mode 100644
index 00000000..8a442029
--- /dev/null
+++ b/drivers/usb/phy/phy-ambarella.c
@@ -0,0 +1,492 @@
+/*
+* linux/drivers/usb/phy/phy-ambarella.c
+*
+* History:
+* 2014/01/28 - [Cao Rongrong] created file
+*
+* Copyright (C) 2012 by Ambarella, Inc.
+* http://www.ambarella.com
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the
+* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+* Boston, MA 02111-1307, USA.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/usb/otg.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/io.h>
+#include <linux/of_gpio.h>
+#include <asm/uaccess.h>
+#include <plat/rct.h>
+
+#define DRIVER_NAME "ambarella_phy"
+
+/* PORT is termed as usb slot which is outside the chip, and
+ * PHY is termed as usb interface which is inside the chip */
+
+#define PHY_TO_DEVICE_PORT 0 /* rotue D+/D- signal to device port */
+#define PHY_TO_HOST_PORT 1 /* rotue D+/D- signal to host port */
+
+/* PORT_TYPE_XXX is only for the device port */
+#define PORT_TYPE_DEVICE 0 /* we should work as device */
+#define PORT_TYPE_OTG 1 /* we should work as host */
+
+struct ambarella_phy {
+ struct usb_phy phy;
+ void __iomem *pol_reg;
+ void __iomem *ana_reg;
+ void __iomem *own_reg;
+ u8 host_phy_num;
+ bool owner_invert;
+
+ int gpio_id;
+ bool id_is_otg;
+ int gpio_md;
+ bool md_host_active;
+ int gpio_hub;
+ bool hub_active;
+ u8 port_type; /* the behavior of the device port working */
+ u8 phy_route; /* route D+/D- signal to device or host port */
+
+#ifdef CONFIG_PM
+ u32 pol_val;
+ u32 own_val;
+#endif
+};
+
+#define to_ambarella_phy(p) container_of((p), struct ambarella_phy, phy)
+
+static inline bool ambarella_usb0_is_host(struct ambarella_phy *amb_phy)
+{
+ bool is_host;
+
+ if (amb_phy->owner_invert)
+ is_host = !(amba_rct_readl(amb_phy->own_reg) & USB0_IS_HOST_MASK);
+ else
+ is_host = !!(amba_rct_readl(amb_phy->own_reg) & USB0_IS_HOST_MASK);
+
+ return is_host;
+};
+
+static inline void ambarella_switch_to_host(struct ambarella_phy *amb_phy)
+{
+ if (amb_phy->owner_invert)
+ amba_rct_clrbitsl(amb_phy->own_reg, USB0_IS_HOST_MASK);
+ else
+ amba_rct_setbitsl(amb_phy->own_reg, USB0_IS_HOST_MASK);
+}
+
+static inline void ambarella_switch_to_device(struct ambarella_phy *amb_phy)
+{
+ if (amb_phy->owner_invert)
+ amba_rct_setbitsl(amb_phy->own_reg, USB0_IS_HOST_MASK);
+ else
+ amba_rct_clrbitsl(amb_phy->own_reg, USB0_IS_HOST_MASK);
+}
+
+static inline void ambarella_check_otg(struct ambarella_phy *amb_phy)
+{
+ /* if D+/D- is routed to device port which is working
+ * as otg, we need to switch the phy to host mode. */
+ if (amb_phy->phy_route == PHY_TO_DEVICE_PORT) {
+ if (amb_phy->port_type == PORT_TYPE_OTG)
+ ambarella_switch_to_host(amb_phy);
+ else
+ ambarella_switch_to_device(amb_phy);
+ }
+}
+
+static void __iomem *ambarella_phy_get_reg(struct platform_device *pdev, int index)
+{
+ struct resource *mem;
+ void __iomem *reg;
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, index);
+ if (!mem) {
+ dev_err(&pdev->dev, "No mem resource: %d!\n", index);
+ return NULL;
+ }
+
+ reg = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
+ if (!reg) {
+ dev_err(&pdev->dev, "devm_ioremap() failed: %d\n", index);
+ return NULL;
+ }
+
+ return reg;
+}
+
+static int ambarella_phy_proc_show(struct seq_file *m, void *v)
+{
+ struct ambarella_phy *amb_phy = m->private;
+ const char *port_status;
+ const char *phy_status;
+ int len = 0;
+
+ if (amb_phy->phy_route == PHY_TO_HOST_PORT)
+ port_status = "HOST";
+ else
+ port_status = "DEVICE";
+
+ if (ambarella_usb0_is_host(amb_phy))
+ phy_status = "HOST";
+ else
+ phy_status = "DEVICE";
+
+ len += seq_printf(m, "Possible parameter: host device\n");
+ len += seq_printf(m, "Current status:\n");
+ len += seq_printf(m, "\tport is %s: phy is %s\n\n",
+ port_status, phy_status);
+
+ return len;
+}
+
+static int ambarella_phy_proc_write(struct file *file,
+ const char __user *buffer, size_t count, loff_t *ppos)
+{
+ struct ambarella_phy *amb_phy = PDE_DATA(file_inode(file));
+ char n, str[32];
+
+ n = (count < 32) ? count : 32;
+
+ if (copy_from_user(str, buffer, n))
+ return -EFAULT;
+
+ str[n - 1] = '\0';
+
+ if (!strcasecmp(str, "host")) {
+ if (gpio_is_valid(amb_phy->gpio_md)) {
+ amb_phy->phy_route = PHY_TO_HOST_PORT;
+ gpio_direction_output(amb_phy->gpio_md,
+ amb_phy->md_host_active);
+ }
+
+ ambarella_switch_to_host(amb_phy);
+ } else if (!strcasecmp(str, "device")) {
+ if (gpio_is_valid(amb_phy->gpio_md)) {
+ amb_phy->phy_route = PHY_TO_DEVICE_PORT;
+ gpio_direction_output(amb_phy->gpio_md,
+ !amb_phy->md_host_active);
+ }
+
+ ambarella_check_otg(amb_phy);
+ } else {
+ pr_err("Invalid argument!\n");
+ }
+
+ return count;
+}
+
+static int ambarella_phy_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ambarella_phy_proc_show, PDE_DATA(inode));
+}
+
+static const struct file_operations proc_phy_switcher_fops = {
+ .open = ambarella_phy_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .write = ambarella_phy_proc_write,
+};
+
+static irqreturn_t ambarella_otg_detect_irq(int irq, void *dev_id)
+{
+ struct ambarella_phy *amb_phy = dev_id;
+
+ if (gpio_is_valid(amb_phy->gpio_id)) {
+ if (gpio_get_value_cansleep(amb_phy->gpio_id) == amb_phy->id_is_otg)
+ amb_phy->port_type = PORT_TYPE_OTG;
+ else
+ amb_phy->port_type = PORT_TYPE_DEVICE;
+ } else {
+ amb_phy->port_type = PORT_TYPE_DEVICE;
+ }
+
+ ambarella_check_otg(amb_phy);
+
+ return IRQ_HANDLED;
+}
+
+static int ambarella_init_phy_switcher(struct ambarella_phy *amb_phy)
+{
+ struct usb_phy *phy = &amb_phy->phy;
+ int irq, rval = 0;
+
+ /* only usb0 support to switch between host and device */
+ proc_create_data("usbphy0", S_IRUGO|S_IWUSR,
+ get_ambarella_proc_dir(), &proc_phy_switcher_fops, amb_phy);
+
+ /* request gpio for PHY HUB reset */
+ if (gpio_is_valid(amb_phy->gpio_hub)) {
+ rval = devm_gpio_request(phy->dev, amb_phy->gpio_hub, "hub reset");
+ if (rval < 0) {
+ dev_err(phy->dev, "Failed to request hub reset pin %d\n", rval);
+ return rval;
+ }
+ gpio_direction_output(amb_phy->gpio_hub, !amb_phy->hub_active);
+ }
+
+ if (gpio_is_valid(amb_phy->gpio_id)) {
+ rval = devm_gpio_request_one(phy->dev,
+ amb_phy->gpio_id, GPIOF_DIR_IN, "otg_id");
+ if (rval < 0){
+ dev_err(phy->dev, "Failed to request id pin %d\n", rval);
+ return rval;
+ }
+
+ if (gpio_get_value_cansleep(amb_phy->gpio_id) == amb_phy->id_is_otg)
+ amb_phy->port_type = PORT_TYPE_OTG;
+ else
+ amb_phy->port_type = PORT_TYPE_DEVICE;
+
+ irq = gpio_to_irq(amb_phy->gpio_id);
+
+ rval = devm_request_threaded_irq(phy->dev, irq, NULL,
+ ambarella_otg_detect_irq,
+ IRQ_TYPE_EDGE_BOTH | IRQF_ONESHOT,
+ "usb_otg_id", amb_phy);
+ if (rval) {
+ dev_err(phy->dev, "request usb_otg_id irq failed: %d\n", rval);
+ return rval;
+ }
+
+ } else {
+ amb_phy->port_type = PORT_TYPE_DEVICE;
+ }
+
+ /* rotue D+/D- signal to host or device port if control gpio existed */
+ if (gpio_is_valid(amb_phy->gpio_md)) {
+ rval = devm_gpio_request(phy->dev,
+ amb_phy->gpio_md, "phy_switcher");
+ if (rval) {
+ dev_err(phy->dev, "request phy_switcher gpio failed\n");
+ return rval;
+ }
+
+ /* if usb0 is configured as host, route D+/D- signal to
+ * host port, otherwise route them to device port. */
+ if (ambarella_usb0_is_host(amb_phy)) {
+ amb_phy->phy_route = PHY_TO_HOST_PORT;
+ gpio_direction_output(amb_phy->gpio_md,
+ amb_phy->md_host_active);
+ } else {
+ amb_phy->phy_route = PHY_TO_DEVICE_PORT;
+ gpio_direction_output(amb_phy->gpio_md,
+ !amb_phy->md_host_active);
+ }
+ } else {
+ amb_phy->phy_route = PHY_TO_DEVICE_PORT;
+ }
+
+ ambarella_check_otg(amb_phy);
+
+ return 0;
+}
+
+static int ambarella_init_host_phy(struct platform_device *pdev,
+ struct ambarella_phy *amb_phy)
+{
+ struct device_node *np = pdev->dev.of_node;
+ enum of_gpio_flags flags;
+ int ocp, rval;
+
+ /* get register for overcurrent polarity */
+ amb_phy->pol_reg = ambarella_phy_get_reg(pdev, 1);
+ if (!amb_phy->pol_reg)
+ return -ENXIO;
+
+ /* get register for usb phy owner configure */
+ amb_phy->own_reg = ambarella_phy_get_reg(pdev, 2);
+ if (!amb_phy->own_reg)
+ return -ENXIO;
+
+ /* see RCT Programming Guide for detailed info about ocp and owner */
+ rval = of_property_read_u32(np, "amb,ocp-polarity", &ocp);
+ if (rval == 0) {
+ amba_clrbitsl(amb_phy->pol_reg, 0x1 << 13);
+ amba_setbitsl(amb_phy->pol_reg, ocp << 13);
+ }
+
+ amb_phy->owner_invert = !!of_find_property(np, "amb,owner-invert", NULL);
+ if (of_find_property(np, "amb,owner-mask", NULL))
+ amba_setbitsl(amb_phy->own_reg, 0x1);
+
+ amb_phy->gpio_id = of_get_named_gpio_flags(np, "id-gpios", 0, &flags);
+ amb_phy->id_is_otg = !!(flags & OF_GPIO_ACTIVE_LOW);
+
+ amb_phy->gpio_md = of_get_named_gpio_flags(np, "md-gpios", 0, &flags);
+ amb_phy->md_host_active = !!(flags & OF_GPIO_ACTIVE_LOW);
+
+ amb_phy->gpio_hub = of_get_named_gpio_flags(np, "hub-gpios", 0, &flags);
+ amb_phy->hub_active = !!(flags & OF_GPIO_ACTIVE_LOW);
+
+ ambarella_init_phy_switcher(amb_phy);
+
+ return 0;
+}
+
+static int ambarella_phy_init(struct usb_phy *phy)
+{
+ struct ambarella_phy *amb_phy = to_ambarella_phy(phy);
+ u32 ana_val = 0x3006;
+
+ /* If there are 2 PHYs, no matter which PHY need to be initialized,
+ * we initialize all of them at the same time */
+
+ if (!(amba_readl(amb_phy->ana_reg) & ana_val)) {
+ amba_setbitsl(amb_phy->ana_reg, ana_val);
+ mdelay(1);
+ }
+
+ return 0;
+}
+
+static int ambarella_phy_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct ambarella_phy *amb_phy;
+ int host_phy_num, rval;
+
+ amb_phy = devm_kzalloc(&pdev->dev, sizeof(*amb_phy), GFP_KERNEL);
+ if (!amb_phy) {
+ dev_err(&pdev->dev, "Failed to allocate memory!\n");
+ return -ENOMEM;
+ }
+
+ amb_phy->phy.otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg),
+ GFP_KERNEL);
+ if (!amb_phy->phy.otg) {
+ dev_err(&pdev->dev, "Failed to allocate memory!\n");
+ return -ENOMEM;
+ }
+
+ amb_phy->phy.dev = &pdev->dev;
+ amb_phy->phy.label = DRIVER_NAME;
+ amb_phy->phy.init = ambarella_phy_init;
+
+ /* get register for usb phy power on */
+ amb_phy->ana_reg = ambarella_phy_get_reg(pdev, 0);
+ if (!amb_phy->ana_reg)
+ return -ENXIO;
+
+ rval = of_property_read_u32(np, "amb,host-phy-num", &host_phy_num);
+ if (rval < 0)
+ amb_phy->host_phy_num = 0;
+ else
+ amb_phy->host_phy_num = host_phy_num;
+
+ if (amb_phy->host_phy_num > 0)
+ ambarella_init_host_phy(pdev, amb_phy);
+
+ platform_set_drvdata(pdev, &amb_phy->phy);
+
+ rval = usb_add_phy_dev(&amb_phy->phy);
+ if (rval < 0)
+ return rval;
+
+ return 0;
+}
+
+static int ambarella_phy_remove(struct platform_device *pdev)
+{
+ struct ambarella_phy *amb_phy = platform_get_drvdata(pdev);
+
+ usb_remove_phy(&amb_phy->phy);
+
+ return 0;
+}
+
+static void ambarella_phy_shutdown(struct platform_device *pdev)
+{
+ struct ambarella_phy *amb_phy = platform_get_drvdata(pdev);
+
+ if (amb_phy->host_phy_num && gpio_is_valid(amb_phy->gpio_md)) {
+ gpio_direction_output(amb_phy->gpio_md,
+ !amb_phy->md_host_active);
+ }
+
+}
+
+#ifdef CONFIG_PM
+static int ambarella_phy_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ struct ambarella_phy *amb_phy = platform_get_drvdata(pdev);
+
+ amb_phy->pol_val = amba_readl(amb_phy->pol_reg);
+ amb_phy->own_val = amba_readl(amb_phy->own_reg);
+
+ return 0;
+}
+
+static int ambarella_phy_resume(struct platform_device *pdev)
+{
+ struct ambarella_phy *amb_phy = platform_get_drvdata(pdev);
+
+ amba_writel(amb_phy->pol_reg, amb_phy->pol_val);
+ amba_writel(amb_phy->own_reg, amb_phy->own_val);
+
+ return 0;
+}
+#endif
+
+static const struct of_device_id ambarella_phy_dt_ids[] = {
+ { .compatible = "ambarella,usbphy", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, ambarella_phy_dt_ids);
+
+static struct platform_driver ambarella_phy_driver = {
+ .probe = ambarella_phy_probe,
+ .remove = ambarella_phy_remove,
+ .shutdown = ambarella_phy_shutdown,
+#ifdef CONFIG_PM
+ .suspend = ambarella_phy_suspend,
+ .resume = ambarella_phy_resume,
+#endif
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = ambarella_phy_dt_ids,
+ },
+};
+
+/* We have to call ambarella_phy_module_init() before the drives using USB PHY
+ * like EHCI/OHCI/UDC, and after GPIO drivers including external GPIO chip, so
+ * we use subsys_initcall_sync here. */
+static int __init ambarella_phy_module_init(void)
+{
+ return platform_driver_register(&ambarella_phy_driver);
+}
+subsys_initcall_sync(ambarella_phy_module_init);
+
+static void __exit ambarella_phy_module_exit(void)
+{
+ platform_driver_unregister(&ambarella_phy_driver);
+}
+module_exit(ambarella_phy_module_exit);
+
+
+MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
+MODULE_DESCRIPTION("Ambarella USB PHY driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index 1d55762a..74baf736 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -51,6 +51,15 @@ config USB_SERIAL_GENERIC
support" be compiled as a module for this driver to be used
properly.
+
+config USB_SERIAL_U1960
+ tristate "USB Serial Driver for U1960"
+ help
+ Say Y here if you want to use U1960.
+
+ To compile this driver as a module, choose M here: the module
+ will be called aircable.
+
config USB_SERIAL_AIRCABLE
tristate "USB AIRcable Bluetooth Dongle Driver"
help
@@ -130,7 +139,7 @@ config USB_SERIAL_CYPRESS_M8
Supported microcontrollers in the CY4601 family are:
CY7C63741 CY7C63742 CY7C63743 CY7C64013
-
+
To compile this driver as a module, choose M here: the
module will be called cypress_m8.
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile
index cec63fa1..b4ad309d 100644
--- a/drivers/usb/serial/Makefile
+++ b/drivers/usb/serial/Makefile
@@ -3,7 +3,6 @@
#
# Object file lists.
-
obj-$(CONFIG_USB_SERIAL) += usbserial.o
usbserial-y := usb-serial.o generic.o bus.o
@@ -65,3 +64,4 @@ obj-$(CONFIG_USB_SERIAL_VIVOPAY_SERIAL) += vivopay-serial.o
obj-$(CONFIG_USB_SERIAL_XSENS_MT) += xsens_mt.o
obj-$(CONFIG_USB_SERIAL_ZIO) += zio.o
obj-$(CONFIG_USB_SERIAL_ZTE) += zte_ev.o
+obj-$(CONFIG_USB_SERIAL_U1960) +=u1960.o
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 006a2a72..9e818532 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -356,6 +356,9 @@ static void option_instat_callback(struct urb *urb);
*/
#define LONGCHEER_VENDOR_ID 0x1c9e
+/***Add for LONGSUNG LTE 4G MODEM U8300***/
+#define LONGSUNG_U8300_PRODUCT_ID 0x9b05
+
/* 4G Systems products */
/* This is the 4G XS Stick W14 a.k.a. Mobilcom Debitel Surf-Stick *
* It seems to contain a Qualcomm QSC6240/6290 chipset */
diff --git a/drivers/usb/serial/u1960.c b/drivers/usb/serial/u1960.c
new file mode 100644
index 00000000..dcf20e38
--- /dev/null
+++ b/drivers/usb/serial/u1960.c
@@ -0,0 +1,56 @@
+/*
+ * usb-serial driver for Quatech USB 2 devices
+ *
+ * Copyright (C) 2012 Bill Pemberton (wfp5p@virginia.edu)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ *
+ * These devices all have only 1 bulk in and 1 bulk out that is shared
+ * for all serial ports.
+ *
+ */
+
+#include <asm/unaligned.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/module.h>
+#include <linux/serial.h>
+#include <linux/usb.h>
+#include <linux/usb/serial.h>
+#include <linux/serial_reg.h>
+#include <linux/uaccess.h>
+
+#define DRIVER_DESC "u1960 USB to Serial Driver"
+
+static const struct usb_device_id id_table[] = {
+ {USB_DEVICE(0x1e89,0x1a20)},
+ {} /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, id_table);
+
+static struct usb_serial_driver u1960_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "U1960",
+ },
+ .description = DRIVER_DESC,
+ .id_table = id_table,
+ .num_ports = 1,
+};
+
+static struct usb_serial_driver *const serial_drivers[] = {
+ &u1960_device, NULL
+};
+
+module_usb_serial_driver(serial_drivers, id_table);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 2e937bda..af480f6b 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2347,6 +2347,16 @@ config FB_PRE_INIT_FB
Select this option if display contents should be inherited as set by
the bootloader.
+config FB_AMBARELLA
+ tristate "Ambarella Framebuffer support"
+ depends on FB && PLAT_AMBARELLA
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ help
+ Frame buffer driver for Ambarella chips.
+
config FB_MSM
tristate "MSM Framebuffer support"
depends on FB && ARCH_MSM
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index e8bae8dd..076d4717 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -141,6 +141,7 @@ obj-$(CONFIG_FB_SH_MOBILE_HDMI) += sh_mobile_hdmi.o
obj-$(CONFIG_FB_SH_MOBILE_MERAM) += sh_mobile_meram.o
obj-$(CONFIG_FB_SH_MOBILE_LCDC) += sh_mobile_lcdcfb.o
obj-$(CONFIG_FB_OMAP) += omap/
+obj-$(CONFIG_FB_AMBARELLA) += ambarella/
obj-y += omap2/
obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o
obj-$(CONFIG_FB_CARMINE) += carminefb.o
diff --git a/drivers/video/ambarella/Makefile b/drivers/video/ambarella/Makefile
new file mode 100644
index 00000000..0cc606b0
--- /dev/null
+++ b/drivers/video/ambarella/Makefile
@@ -0,0 +1,24 @@
+#
+# drivers/video/ambarella/Kconfig
+#
+# Author: Anthony Ginger <hfjiang@ambarella.com>
+#
+# Copyright (C) 2004-2009, Ambarella, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+obj-$(CONFIG_FB_AMBARELLA) += ambarella_fb.o
+
diff --git a/drivers/video/ambarella/ambarella_fb.c b/drivers/video/ambarella/ambarella_fb.c
new file mode 100644
index 00000000..3f35e944
--- /dev/null
+++ b/drivers/video/ambarella/ambarella_fb.c
@@ -0,0 +1,698 @@
+/*
+ * drivers/drivers/video/ambarella/ambarella_fb.c
+ *
+ * 2008/07/22 - [linnsong] Create
+ * 2009/03/03 - [Anthony Ginger] Port to 2.6.28
+ * 2009/12/15 - [Zhenwu Xue] Change fb_setcmap
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/list.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/clk.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+
+#include <asm/sizes.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#include <mach/init.h>
+#include <plat/fb.h>
+
+/* video=amb0fb:<x_res>x<y_res>,<x_virtual>x<y_virtual>,
+ <color_format>,<conversion_buffer>[,<prealloc_start>,<prealloc_length>] */
+
+#include "ambarella_fb_tbl.c"
+
+/* ========================================================================== */
+#ifdef CONFIG_PROC_FS
+static int ambarella_fb_proc_show(struct seq_file *m, void *v)
+{
+ int len;
+ struct ambarella_platform_fb *ambfb_data;
+ struct fb_info *info;
+
+ ambfb_data = (struct ambarella_platform_fb *)m->private;
+ info = ambfb_data->proc_fb_info;
+
+ wait_event_interruptible(ambfb_data->proc_wait,
+ (ambfb_data->proc_wait_flag > 0));
+ ambfb_data->proc_wait_flag = 0;
+ dev_dbg(info->device, "%s:%d %d.\n", __func__, __LINE__,
+ ambfb_data->proc_wait_flag);
+ len = seq_printf(m, "%04d %04d %04d %04d %04d %04d\n",
+ info->var.xres, info->var.yres,
+ info->fix.line_length,
+ info->var.xoffset, info->var.yoffset,
+ ambfb_data->color_format);
+
+ return len;
+}
+
+static int ambarella_fb_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ambarella_fb_proc_show, PDE_DATA(inode));
+}
+
+static const struct file_operations ambarella_fb_fops = {
+ .open = ambarella_fb_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+};
+#endif
+
+/* ========================================================================== */
+static int ambfb_setcmap(struct fb_cmap *cmap, struct fb_info *info)
+{
+ int errorCode = 0;
+ struct ambarella_platform_fb *ambfb_data;
+ int pos;
+ u16 *r, *g, *b, *t;
+ u8 *pclut_table, *pblend_table;
+
+ if (cmap == &info->cmap) {
+ errorCode = 0;
+ goto ambfb_setcmap_exit;
+ }
+
+ if (cmap->start != 0 || cmap->len != 256) {
+ dev_dbg(info->device,
+ "%s: Incorrect parameters: start = %d, len = %d\n",
+ __func__, cmap->start, cmap->len);
+ errorCode = -1;
+ goto ambfb_setcmap_exit;
+ }
+
+ if (!cmap->red || !cmap->green || !cmap->blue) {
+ dev_dbg(info->device, "%s: Incorrect rgb pointers!\n",
+ __func__);
+ errorCode = -1;
+ goto ambfb_setcmap_exit;
+ }
+
+ ambfb_data = (struct ambarella_platform_fb *)info->par;
+
+ mutex_lock(&ambfb_data->lock);
+
+ r = cmap->red;
+ g = cmap->green;
+ b = cmap->blue;
+ t = cmap->transp;
+ pclut_table = ambfb_data->clut_table;
+ pblend_table = ambfb_data->blend_table;
+ for (pos = 0; pos < 256; pos++) {
+ *pclut_table++ = *r++;
+ *pclut_table++ = *g++;
+ *pclut_table++ = *b++;
+ if (t) *pblend_table++ = *t++;
+ }
+
+ if (ambfb_data->setcmap) {
+ mutex_unlock(&ambfb_data->lock);
+ errorCode = ambfb_data->setcmap(cmap, info);
+ } else {
+ mutex_unlock(&ambfb_data->lock);
+ }
+
+ambfb_setcmap_exit:
+ dev_dbg(info->device, "%s:%d %d.\n", __func__, __LINE__, errorCode);
+ return errorCode;
+}
+
+static int ambfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ int errorCode = 0;
+ struct ambarella_platform_fb *ambfb_data;
+ u32 framesize = 0;
+
+ ambfb_data = (struct ambarella_platform_fb *)info->par;
+
+ mutex_lock(&ambfb_data->lock);
+ if (ambfb_data->check_var) {
+ errorCode = ambfb_data->check_var(var, info);
+ }
+ mutex_unlock(&ambfb_data->lock);
+
+ if (var->xres_virtual * var->bits_per_pixel / 8 > info->fix.line_length) {
+ errorCode = -ENOMEM;
+ dev_err(info->device, "%s: xres_virtual[%d] too big [%d]!\n",
+ __func__, var->xres_virtual * var->bits_per_pixel / 8,
+ info->fix.line_length);
+ }
+
+ framesize = info->fix.line_length * var->yres_virtual;
+ if (framesize > info->fix.smem_len) {
+ errorCode = -ENOMEM;
+ dev_err(info->device, "%s: framesize[%d] too big [%d]!\n",
+ __func__, framesize, info->fix.smem_len);
+ }
+
+ dev_dbg(info->device, "%s:%d %d.\n", __func__, __LINE__, errorCode);
+
+ return errorCode;
+}
+
+static int ambfb_set_par(struct fb_info *info)
+{
+ int errorCode = 0, i;
+ struct ambarella_platform_fb *ambfb_data;
+ struct fb_var_screeninfo *pvar;
+ static struct fb_var_screeninfo *cur_var;
+ int res_changed = 0;
+ int color_format_changed = 0;
+ enum ambarella_fb_color_format new_color_format;
+ const struct ambarella_fb_color_table *pTable;
+
+ ambfb_data = (struct ambarella_platform_fb *)info->par;
+ mutex_lock(&ambfb_data->lock);
+ cur_var = &ambfb_data->screen_var;
+ pvar = &info->var;
+
+ if (!ambfb_data->set_par)
+ goto ambfb_set_par_quick_exit;
+
+ /* Resolution changed */
+ if (pvar->xres != cur_var->xres || pvar->yres != cur_var->yres) {
+ res_changed = 1;
+ }
+
+ /* Color format changed */
+ if (pvar->bits_per_pixel != cur_var->bits_per_pixel ||
+ pvar->red.offset != cur_var->red.offset ||
+ pvar->red.length != cur_var->red.length ||
+ pvar->red.msb_right != cur_var->red.msb_right ||
+ pvar->green.offset != cur_var->green.offset ||
+ pvar->green.length != cur_var->green.length ||
+ pvar->green.msb_right != cur_var->green.msb_right ||
+ pvar->blue.offset != cur_var->blue.offset ||
+ pvar->blue.length != cur_var->blue.length ||
+ pvar->blue.msb_right != cur_var->blue.msb_right ||
+ pvar->transp.offset != cur_var->transp.offset ||
+ pvar->transp.length != cur_var->transp.length ||
+ pvar->transp.msb_right != cur_var->transp.msb_right) {
+
+ color_format_changed = 1;
+ }
+
+ if (!res_changed && !color_format_changed)
+ goto ambfb_set_par_quick_exit;
+
+ /* Find color format */
+ new_color_format = ambfb_data->color_format;
+ pTable = ambarella_fb_color_format_table;
+ for (i = 0; i < ARRAY_SIZE(ambarella_fb_color_format_table); i++) {
+ if (pTable->bits_per_pixel == pvar->bits_per_pixel &&
+ pTable->red.offset == pvar->red.offset &&
+ pTable->red.length == pvar->red.length &&
+ pTable->red.msb_right == pvar->red.msb_right &&
+ pTable->green.offset == pvar->green.offset &&
+ pTable->green.length == pvar->green.length &&
+ pTable->green.msb_right == pvar->green.msb_right &&
+ pTable->blue.offset == pvar->blue.offset &&
+ pTable->blue.length == pvar->blue.length &&
+ pTable->blue.msb_right == pvar->blue.msb_right &&
+ pTable->transp.offset == pvar->transp.offset &&
+ pTable->transp.length == pvar->transp.length &&
+ pTable->transp.msb_right == pvar->transp.msb_right) {
+
+ new_color_format = pTable->color_format;
+ break;
+ }
+ pTable++;
+ }
+
+ ambfb_data->color_format = new_color_format;
+ memcpy(cur_var, pvar, sizeof(*pvar));
+ mutex_unlock(&ambfb_data->lock);
+
+ errorCode = ambfb_data->set_par(info);
+ goto ambfb_set_par_normal_exit;
+
+ambfb_set_par_quick_exit:
+ memcpy(cur_var, pvar, sizeof(*pvar));
+ mutex_unlock(&ambfb_data->lock);
+
+ambfb_set_par_normal_exit:
+ dev_dbg(info->device, "%s:%d %d.\n", __func__, __LINE__, errorCode);
+
+ return errorCode;
+}
+
+static int ambfb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ int errorCode = 0;
+ struct ambarella_platform_fb *ambfb_data;
+
+ ambfb_data = (struct ambarella_platform_fb *)info->par;
+
+ ambfb_data->proc_wait_flag++;
+ wake_up(&(ambfb_data->proc_wait));
+ mutex_lock(&ambfb_data->lock);
+ ambfb_data->screen_var.xoffset = var->xoffset;
+ ambfb_data->screen_var.yoffset = var->yoffset;
+ if (ambfb_data->pan_display) {
+ errorCode = ambfb_data->pan_display(var, info);
+ }
+ mutex_unlock(&ambfb_data->lock);
+
+ dev_dbg(info->device, "%s:%d %d.\n", __func__, __LINE__, errorCode);
+
+ return 0;
+}
+
+static int ambfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ unsigned long size = vma->vm_end - vma->vm_start;
+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+ struct ambarella_platform_fb *ambfb_data = NULL;
+
+ ambfb_data = ambfb_data_ptr[info->dev->id];
+
+ if (offset + size > info->fix.smem_len)
+ return -EINVAL;
+
+ offset += info->fix.smem_start;
+
+ if(ambfb_data->conversion_buf.available)
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT,
+ size, vma->vm_page_prot))
+ return -EAGAIN;
+
+ dev_dbg(info->device, "%s: P(0x%08lx)->V(0x%08lx), size = 0x%08lx.\n",
+ __func__, offset, vma->vm_start, size);
+
+ return 0;
+}
+
+static int ambfb_blank(int blank_mode, struct fb_info *info)
+{
+ int errorCode = 0;
+ struct ambarella_platform_fb *ambfb_data;
+
+ ambfb_data = (struct ambarella_platform_fb *)info->par;
+
+ mutex_lock(&ambfb_data->lock);
+ if (ambfb_data->set_blank) {
+ errorCode = ambfb_data->set_blank(blank_mode, info);
+ }
+ mutex_unlock(&ambfb_data->lock);
+
+ dev_dbg(info->device, "%s:%d %d.\n", __func__, __LINE__, errorCode);
+
+ return errorCode;
+}
+
+static struct fb_ops ambfb_ops = {
+ .owner = THIS_MODULE,
+ .fb_check_var = ambfb_check_var,
+ .fb_set_par = ambfb_set_par,
+ .fb_pan_display = ambfb_pan_display,
+ .fb_fillrect = sys_fillrect,
+ .fb_copyarea = sys_copyarea,
+ .fb_imageblit = sys_imageblit,
+ .fb_mmap = ambfb_mmap,
+ .fb_setcmap = ambfb_setcmap,
+ .fb_blank = ambfb_blank,
+};
+
+static int ambfb_setup(struct device *dev, char *options,
+ struct ambarella_platform_fb *ambfb_data)
+{
+ int retval = -1;
+ int ssret;
+ int cl_xres;
+ int cl_yres;
+ int cl_xvirtual;
+ int cl_yvirtual;
+ int cl_format;
+ int cl_cvs_buf;
+ unsigned int cl_prealloc_start;
+ unsigned int cl_prealloc_length;
+
+ if (!options || !*options) {
+ goto ambfb_setup_exit;
+ }
+
+ ssret = sscanf(options, "%dx%d,%dx%d,%d,%d,%x,%x", &cl_xres, &cl_yres,
+ &cl_xvirtual, &cl_yvirtual, &cl_format, &cl_cvs_buf,
+ &cl_prealloc_start, &cl_prealloc_length);
+ if (ssret == 6) {
+ ambfb_data->screen_var.xres = cl_xres;
+ ambfb_data->screen_var.yres = cl_yres;
+ ambfb_data->screen_var.xres_virtual = cl_xvirtual;
+ ambfb_data->screen_var.yres_virtual = cl_yvirtual;
+ ambfb_data->color_format = cl_format;
+ ambfb_data->conversion_buf.available = cl_cvs_buf;
+ dev_dbg(dev, "%dx%d,%dx%d,%d,%d\n", cl_xres, cl_yres,
+ cl_xvirtual, cl_yvirtual, cl_format, cl_cvs_buf);
+ retval = 0;
+ } else if (ssret == 8) {
+ ambfb_data->screen_var.xres = cl_xres;
+ ambfb_data->screen_var.yres = cl_yres;
+ ambfb_data->screen_var.xres_virtual = cl_xvirtual;
+ ambfb_data->screen_var.yres_virtual = cl_yvirtual;
+ ambfb_data->color_format = cl_format;
+ ambfb_data->conversion_buf.available = cl_cvs_buf;
+
+ ambfb_data->screen_fix.smem_start = cl_prealloc_start;
+ ambfb_data->screen_fix.smem_len = cl_prealloc_length;
+ ambfb_data->use_prealloc = 1;
+ dev_dbg(dev, "%dx%d,%dx%d,%d,%d,%x,%x\n", cl_xres, cl_yres,
+ cl_xvirtual, cl_yvirtual, cl_format, cl_cvs_buf,
+ cl_prealloc_start, cl_prealloc_length);
+ retval = 0;
+ } else {
+ dev_err(dev, "Can not support %s@%d!\n", options, ssret);
+ }
+
+ambfb_setup_exit:
+ return retval;
+}
+
+static int ambfb_probe(struct platform_device *pdev)
+{
+ int errorCode = 0;
+ struct fb_info *info;
+ char fb_name[64];
+ char *option;
+ struct ambarella_platform_fb *ambfb_data = NULL;
+ u32 i, framesize, line_length;
+
+ ambfb_data = ambfb_data_ptr[pdev->id];
+
+ snprintf(fb_name, sizeof(fb_name), "amb%dfb", pdev->id);
+ if (fb_get_options(fb_name, &option)) {
+ dev_err(&pdev->dev, "%s: get fb options fail!\n", __func__);
+ errorCode = -ENODEV;
+ goto ambfb_probe_exit;
+ }
+ if (ambfb_setup(&pdev->dev, option, ambfb_data)) {
+ errorCode = -ENODEV;
+ goto ambfb_probe_exit;
+ }
+
+ info = framebuffer_alloc(sizeof(ambfb_data), &pdev->dev);
+ if (info == NULL) {
+ dev_err(&pdev->dev, "%s: framebuffer_alloc fail!\n", __func__);
+ errorCode = -ENOMEM;
+ goto ambfb_probe_exit;
+ }
+
+ if(get_ambarella_fbmem_size()) {
+ ambfb_data->use_prealloc = 1;
+ ambfb_data->conversion_buf.available = 1;
+ if((ambfb_data->screen_fix.smem_start == 0) ||
+ (ambfb_data->screen_fix.smem_len == 0) ||
+ (ambfb_data->screen_fix.smem_len > get_ambarella_fbmem_size())) {
+ errorCode = -EINVAL;
+ dev_err(&pdev->dev, "please set right fbmem start address in dts file\n");
+ goto ambfb_probe_release_framebuffer;
+ }
+ } else {
+ ambfb_data->use_prealloc = 0;
+ ambfb_data->conversion_buf.available = 0;
+ }
+
+ mutex_lock(&ambfb_data->lock);
+
+ info->fbops = &ambfb_ops;
+ info->par = ambfb_data;
+ info->var = ambfb_data->screen_var;
+ info->fix = ambfb_data->screen_fix;
+ info->flags = FBINFO_FLAG_DEFAULT;
+
+ /* Fill Color-related Variables */
+ for (i = 0; i < ARRAY_SIZE(ambarella_fb_color_format_table); i++) {
+ if (ambarella_fb_color_format_table[i].color_format ==
+ ambfb_data->color_format)
+ break;
+ }
+ if (i < ARRAY_SIZE(ambarella_fb_color_format_table)) {
+ info->var.bits_per_pixel =
+ ambarella_fb_color_format_table[i].bits_per_pixel;
+ info->var.red = ambarella_fb_color_format_table[i].red;
+ info->var.green = ambarella_fb_color_format_table[i].green;
+ info->var.blue = ambarella_fb_color_format_table[i].blue;
+ info->var.transp = ambarella_fb_color_format_table[i].transp;
+ } else {
+ dev_err(&pdev->dev, "%s: do not support color formate:%d!\n",
+ __func__, ambfb_data->color_format);
+ errorCode = -EINVAL;
+ goto ambfb_probe_release_framebuffer;
+ }
+
+ /* Malloc Framebuffer Memory */
+ line_length = (info->var.xres_virtual *
+ (info->var.bits_per_pixel / 8) + 31) & 0xffffffe0;
+ if (ambfb_data->use_prealloc == 0) {
+ info->fix.line_length = line_length;
+ } else {
+ info->fix.line_length =
+ (line_length > ambfb_data->prealloc_line_length) ?
+ line_length : ambfb_data->prealloc_line_length;
+ }
+
+ framesize = info->fix.line_length * info->var.yres_virtual;
+ if (framesize % PAGE_SIZE) {
+ framesize /= PAGE_SIZE;
+ framesize++;
+ framesize *= PAGE_SIZE;
+ }
+
+ if (ambfb_data->use_prealloc == 0) {
+ info->screen_base = kzalloc(framesize, GFP_KERNEL);
+ if (info->screen_base == NULL) {
+ dev_err(&pdev->dev, "%s(%d): Can't get %d bytes fbmem!\n",
+ __func__, __LINE__, framesize);
+ errorCode = -ENOMEM;
+ goto ambfb_probe_release_framebuffer;
+ }
+ info->fix.smem_start = virt_to_phys(info->screen_base);
+ info->fix.smem_len = framesize;
+ } else {
+ if ((info->fix.smem_start == 0) ||
+ (info->fix.smem_len < framesize)) {
+ dev_err(&pdev->dev, "%s: prealloc[0x%08x < 0x%08x]!\n",
+ __func__, info->fix.smem_len, framesize);
+ errorCode = -ENOMEM;
+ goto ambfb_probe_release_framebuffer;
+ }
+
+ info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
+ memset(info->screen_base, 0, info->fix.smem_len);
+ if (!info->screen_base) {
+ dev_err(&pdev->dev, "%s: ioremap() failed\n", __func__);
+ errorCode = -ENOMEM;
+ goto ambfb_probe_exit;
+ }
+
+ if (ambfb_data->conversion_buf.available) {
+ ambfb_data->conversion_buf.base_buf_phy =
+ ambfb_data->screen_fix.smem_start;
+ }
+ }
+
+ errorCode = fb_alloc_cmap(&info->cmap, 256, 1);
+ if (errorCode < 0) {
+ dev_err(&pdev->dev, "%s: fb_alloc_cmap fail!\n", __func__);
+ errorCode = -ENOMEM;
+ goto ambfb_probe_release_framebuffer;
+ }
+ for (i = info->cmap.start; i < info->cmap.len; i++) {
+ info->cmap.red[i] = i << 8;
+ info->cmap.green[i] = 128 << 8;
+ info->cmap.blue[i] = 128 << 8;
+ if (info->cmap.transp)
+ info->cmap.transp[i] = 12 << 8;
+ }
+
+ platform_set_drvdata(pdev, info);
+ ambfb_data->fb_status = AMBFB_ACTIVE_MODE;
+ mutex_unlock(&ambfb_data->lock);
+
+ errorCode = register_framebuffer(info);
+ if (errorCode < 0) {
+ dev_err(&pdev->dev, "%s: register_framebuffer fail!\n",
+ __func__);
+ errorCode = -ENOMEM;
+ mutex_lock(&ambfb_data->lock);
+ goto ambfb_probe_dealloc_cmap;
+ }
+
+ ambfb_data->proc_fb_info = info;
+
+#ifdef CONFIG_PROC_FS
+ ambfb_data->proc_file = proc_create_data(dev_name(&pdev->dev),
+ (S_IRUGO | S_IWUSR), get_ambarella_proc_dir(),
+ &ambarella_fb_fops, ambfb_data);
+ if (ambfb_data->proc_file == NULL) {
+ errorCode = -ENOMEM;
+ goto ambfb_probe_unregister_framebuffer;
+ }
+#endif
+
+ mutex_lock(&ambfb_data->lock);
+ ambfb_data->screen_var = info->var;
+ ambfb_data->screen_fix = info->fix;
+ mutex_unlock(&ambfb_data->lock);
+
+ dev_info(&pdev->dev,
+ "probe p[%dx%d] v[%dx%d] c[%d] b[%d] l[%d] @ [0x%08lx:0x%08x],base:0x%p!\n",
+ info->var.xres, info->var.yres, info->var.xres_virtual,
+ info->var.yres_virtual, ambfb_data->color_format,
+ ambfb_data->conversion_buf.available,
+ info->fix.line_length,
+ info->fix.smem_start, info->fix.smem_len, info->screen_base);
+ goto ambfb_probe_exit;
+
+ambfb_probe_unregister_framebuffer:
+ unregister_framebuffer(info);
+
+ambfb_probe_dealloc_cmap:
+ fb_dealloc_cmap(&info->cmap);
+
+ambfb_probe_release_framebuffer:
+ framebuffer_release(info);
+ ambfb_data->fb_status = AMBFB_STOP_MODE;
+ mutex_unlock(&ambfb_data->lock);
+
+ambfb_probe_exit:
+ return errorCode;
+}
+
+static int ambfb_remove(struct platform_device *pdev)
+{
+ struct fb_info *info;
+ struct ambarella_platform_fb *ambfb_data = NULL;
+
+ info = platform_get_drvdata(pdev);
+ if (info) {
+ ambfb_data = (struct ambarella_platform_fb *)info->par;
+
+#ifdef CONFIG_PROC_FS
+ proc_remove(ambfb_data->proc_file);
+#endif
+ unregister_framebuffer(info);
+
+ mutex_lock(&ambfb_data->lock);
+ ambfb_data->fb_status = AMBFB_STOP_MODE;
+ fb_dealloc_cmap(&info->cmap);
+ if (ambfb_data->use_prealloc == 0) {
+ if (info->screen_base) {
+ kfree(info->screen_base);
+ }
+ if (ambfb_data->conversion_buf.available) {
+ if (ambfb_data->conversion_buf.ping_buf) {
+ kfree(ambfb_data->conversion_buf.ping_buf);
+ }
+ if (ambfb_data->conversion_buf.pong_buf) {
+ kfree(ambfb_data->conversion_buf.pong_buf);
+ }
+ }
+ ambfb_data->screen_fix.smem_start = 0;
+ ambfb_data->screen_fix.smem_len = 0;
+ }
+ framebuffer_release(info);
+ mutex_unlock(&ambfb_data->lock);
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int ambfb_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ int errorCode = 0;
+
+ dev_dbg(&pdev->dev, "%s exit with %d @ %d\n",
+ __func__, errorCode, state.event);
+
+ return errorCode;
+}
+
+static int ambfb_resume(struct platform_device *pdev)
+{
+ int errorCode = 0;
+
+ dev_dbg(&pdev->dev, "%s exit with %d\n", __func__, errorCode);
+
+ return errorCode;
+}
+#endif
+
+static struct platform_driver ambfb_driver = {
+ .probe = ambfb_probe,
+ .remove = ambfb_remove,
+#ifdef CONFIG_PM
+ .suspend = ambfb_suspend,
+ .resume = ambfb_resume,
+#endif
+ .driver = {
+ .name = "ambarella-fb",
+ },
+};
+
+static struct platform_device ambarella_fb0 = {
+ .name = "ambarella-fb",
+ .id = 0,
+};
+
+static struct platform_device ambarella_fb1 = {
+ .name = "ambarella-fb",
+ .id = 1,
+};
+
+static int __init ambavoutfb_init(void)
+{
+ platform_device_register(&ambarella_fb0);
+ platform_device_register(&ambarella_fb1);
+ return platform_driver_register(&ambfb_driver);
+}
+
+static void __exit ambavoutfb_exit(void)
+{
+ platform_driver_unregister(&ambfb_driver);
+ platform_device_unregister(&ambarella_fb1);
+ platform_device_unregister(&ambarella_fb0);
+}
+
+MODULE_LICENSE("GPL");
+module_init(ambavoutfb_init);
+module_exit(ambavoutfb_exit);
+
diff --git a/drivers/video/ambarella/ambarella_fb_tbl.c b/drivers/video/ambarella/ambarella_fb_tbl.c
new file mode 100644
index 00000000..65e88057
--- /dev/null
+++ b/drivers/video/ambarella/ambarella_fb_tbl.c
@@ -0,0 +1,622 @@
+
+struct ambarella_fb_color_table {
+ enum ambarella_fb_color_format color_format;
+ int bits_per_pixel;
+ struct fb_bitfield red;
+ struct fb_bitfield green;
+ struct fb_bitfield blue;
+ struct fb_bitfield transp;
+};
+
+static const struct ambarella_fb_color_table ambarella_fb_color_format_table[] =
+{
+ {
+ .color_format = AMBFB_COLOR_CLUT_8BPP,
+ .bits_per_pixel = 8,
+ .red =
+ {
+ .offset = 0,
+ .length = 0,
+ .msb_right = 0,
+ },
+ .green =
+ {
+ .offset = 0,
+ .length = 0,
+ .msb_right = 0,
+ },
+ .blue =
+ {
+ .offset = 0,
+ .length = 0,
+ .msb_right = 0,
+ },
+ .transp =
+ {
+ .offset = 0,
+ .length = 0,
+ .msb_right = 0,
+ },
+ },
+
+ {
+ .color_format = AMBFB_COLOR_RGB565,
+ .bits_per_pixel = 16,
+ .red =
+ {
+ .offset = 11,
+ .length = 5,
+ .msb_right = 0,
+ },
+ .green =
+ {
+ .offset = 5,
+ .length = 6,
+ .msb_right = 0,
+ },
+ .blue =
+ {
+ .offset = 0,
+ .length = 5,
+ .msb_right = 0,
+ },
+ .transp =
+ {
+ .offset = 0,
+ .length = 0,
+ .msb_right = 0,
+ },
+ },
+
+ {
+ .color_format = AMBFB_COLOR_BGR565,
+ .bits_per_pixel = 16,
+ .red =
+ {
+ .offset = 0,
+ .length = 5,
+ .msb_right = 0,
+ },
+ .green =
+ {
+ .offset = 5,
+ .length = 6,
+ .msb_right = 0,
+ },
+ .blue =
+ {
+ .offset = 11,
+ .length = 5,
+ .msb_right = 0,
+ },
+ .transp =
+ {
+ .offset = 0,
+ .length = 0,
+ .msb_right = 0,
+ },
+ },
+
+ {
+ .color_format = AMBFB_COLOR_AGBR4444,
+ .bits_per_pixel = 16,
+ .red =
+ {
+ .offset = 0,
+ .length = 4,
+ .msb_right = 0,
+ },
+ .green =
+ {
+ .offset = 8,
+ .length = 4,
+ .msb_right = 0,
+ },
+ .blue =
+ {
+ .offset = 4,
+ .length = 4,
+ .msb_right = 0,
+ },
+ .transp =
+ {
+ .offset = 12,
+ .length = 4,
+ .msb_right = 0,
+ },
+ },
+
+ {
+ .color_format = AMBFB_COLOR_RGBA4444,
+ .bits_per_pixel = 16,
+ .red =
+ {
+ .offset = 12,
+ .length = 4,
+ .msb_right = 0,
+ },
+ .green =
+ {
+ .offset = 8,
+ .length = 4,
+ .msb_right = 0,
+ },
+ .blue =
+ {
+ .offset = 4,
+ .length = 4,
+ .msb_right = 0,
+ },
+ .transp =
+ {
+ .offset = 0,
+ .length = 4,
+ .msb_right = 0,
+ },
+ },
+
+ {
+ .color_format = AMBFB_COLOR_BGRA4444,
+ .bits_per_pixel = 16,
+ .red =
+ {
+ .offset = 4,
+ .length = 4,
+ .msb_right = 0,
+ },
+ .green =
+ {
+ .offset = 8,
+ .length = 4,
+ .msb_right = 0,
+ },
+ .blue =
+ {
+ .offset = 12,
+ .length = 4,
+ .msb_right = 0,
+ },
+ .transp =
+ {
+ .offset = 0,
+ .length = 4,
+ .msb_right = 0,
+ },
+ },
+
+ {
+ .color_format = AMBFB_COLOR_ABGR4444,
+ .bits_per_pixel = 16,
+ .red =
+ {
+ .offset = 0,
+ .length = 4,
+ .msb_right = 0,
+ },
+ .green =
+ {
+ .offset = 4,
+ .length = 4,
+ .msb_right = 0,
+ },
+ .blue =
+ {
+ .offset = 8,
+ .length = 4,
+ .msb_right = 0,
+ },
+ .transp =
+ {
+ .offset = 12,
+ .length = 4,
+ .msb_right = 0,
+ },
+ },
+
+ {
+ .color_format = AMBFB_COLOR_ARGB4444,
+ .bits_per_pixel = 16,
+ .red =
+ {
+ .offset = 8,
+ .length = 4,
+ .msb_right = 0,
+ },
+ .green =
+ {
+ .offset = 4,
+ .length = 4,
+ .msb_right = 0,
+ },
+ .blue =
+ {
+ .offset = 0,
+ .length = 4,
+ .msb_right = 0,
+ },
+ .transp =
+ {
+ .offset = 12,
+ .length = 4,
+ .msb_right = 0,
+ },
+ },
+
+ {
+ .color_format = AMBFB_COLOR_AGBR1555,
+ .bits_per_pixel = 16,
+ .red =
+ {
+ .offset = 0,
+ .length = 5,
+ .msb_right = 0,
+ },
+ .green =
+ {
+ .offset = 10,
+ .length = 5,
+ .msb_right = 0,
+ },
+ .blue =
+ {
+ .offset = 5,
+ .length = 5,
+ .msb_right = 0,
+ },
+ .transp =
+ {
+ .offset = 15,
+ .length = 1,
+ .msb_right = 0,
+ },
+ },
+
+ {
+ .color_format = AMBFB_COLOR_GBR1555,
+ .bits_per_pixel = 16,
+ .red =
+ {
+ .offset = 0,
+ .length = 5,
+ .msb_right = 0,
+ },
+ .green =
+ {
+ .offset = 10,
+ .length = 5,
+ .msb_right = 0,
+ },
+ .blue =
+ {
+ .offset = 5,
+ .length = 5,
+ .msb_right = 0,
+ },
+ .transp =
+ {
+ .offset = 0,
+ .length = 0,
+ .msb_right = 0,
+ },
+ },
+
+ {
+ .color_format = AMBFB_COLOR_RGBA5551,
+ .bits_per_pixel = 16,
+ .red =
+ {
+ .offset = 11,
+ .length = 5,
+ .msb_right = 0,
+ },
+ .green =
+ {
+ .offset = 6,
+ .length = 5,
+ .msb_right = 0,
+ },
+ .blue =
+ {
+ .offset = 1,
+ .length = 5,
+ .msb_right = 0,
+ },
+ .transp =
+ {
+ .offset = 0,
+ .length = 1,
+ .msb_right = 0,
+ },
+ },
+
+ {
+ .color_format = AMBFB_COLOR_BGRA5551,
+ .bits_per_pixel = 16,
+ .red =
+ {
+ .offset = 1,
+ .length = 5,
+ .msb_right = 0,
+ },
+ .green =
+ {
+ .offset = 6,
+ .length = 5,
+ .msb_right = 0,
+ },
+ .blue =
+ {
+ .offset = 11,
+ .length = 5,
+ .msb_right = 0,
+ },
+ .transp =
+ {
+ .offset = 0,
+ .length = 1,
+ .msb_right = 0,
+ },
+ },
+
+ {
+ .color_format = AMBFB_COLOR_ABGR1555,
+ .bits_per_pixel = 16,
+ .red =
+ {
+ .offset = 0,
+ .length = 5,
+ .msb_right = 0,
+ },
+ .green =
+ {
+ .offset = 5,
+ .length = 5,
+ .msb_right = 0,
+ },
+ .blue =
+ {
+ .offset = 10,
+ .length = 5,
+ .msb_right = 0,
+ },
+ .transp =
+ {
+ .offset = 15,
+ .length = 1,
+ .msb_right = 0,
+ },
+ },
+
+ {
+ .color_format = AMBFB_COLOR_ARGB1555,
+ .bits_per_pixel = 16,
+ .red =
+ {
+ .offset = 10,
+ .length = 5,
+ .msb_right = 0,
+ },
+ .green =
+ {
+ .offset = 5,
+ .length = 5,
+ .msb_right = 0,
+ },
+ .blue =
+ {
+ .offset = 0,
+ .length = 5,
+ .msb_right = 0,
+ },
+ .transp =
+ {
+ .offset = 15,
+ .length = 1,
+ .msb_right = 0,
+ },
+ },
+
+ {
+ .color_format = AMBFB_COLOR_AGBR8888,
+ .bits_per_pixel = 32,
+ .red =
+ {
+ .offset = 0,
+ .length = 8,
+ .msb_right = 0,
+ },
+ .green =
+ {
+ .offset = 16,
+ .length = 8,
+ .msb_right = 0,
+ },
+ .blue =
+ {
+ .offset = 8,
+ .length = 8,
+ .msb_right = 0,
+ },
+ .transp =
+ {
+ .offset = 24,
+ .length = 8,
+ .msb_right = 0,
+ },
+ },
+
+ {
+ .color_format = AMBFB_COLOR_RGBA8888,
+ .bits_per_pixel = 32,
+ .red =
+ {
+ .offset = 24,
+ .length = 8,
+ .msb_right = 0,
+ },
+ .green =
+ {
+ .offset = 16,
+ .length = 8,
+ .msb_right = 0,
+ },
+ .blue =
+ {
+ .offset = 8,
+ .length = 8,
+ .msb_right = 0,
+ },
+ .transp =
+ {
+ .offset = 0,
+ .length = 8,
+ .msb_right = 0,
+ },
+ },
+
+ {
+ .color_format = AMBFB_COLOR_BGRA8888,
+ .bits_per_pixel = 32,
+ .red =
+ {
+ .offset = 8,
+ .length = 8,
+ .msb_right = 0,
+ },
+ .green =
+ {
+ .offset = 16,
+ .length = 8,
+ .msb_right = 0,
+ },
+ .blue =
+ {
+ .offset = 24,
+ .length = 8,
+ .msb_right = 0,
+ },
+ .transp =
+ {
+ .offset = 0,
+ .length = 8,
+ .msb_right = 0,
+ },
+ },
+
+ {
+ .color_format = AMBFB_COLOR_ABGR8888,
+ .bits_per_pixel = 32,
+ .red =
+ {
+ .offset = 0,
+ .length = 8,
+ .msb_right = 0,
+ },
+ .green =
+ {
+ .offset = 8,
+ .length = 8,
+ .msb_right = 0,
+ },
+ .blue =
+ {
+ .offset = 16,
+ .length = 8,
+ .msb_right = 0,
+ },
+ .transp =
+ {
+ .offset = 24,
+ .length = 8,
+ .msb_right = 0,
+ },
+ },
+
+ {
+ .color_format = AMBFB_COLOR_ARGB8888,
+ .bits_per_pixel = 32,
+ .red =
+ {
+ .offset = 16,
+ .length = 8,
+ .msb_right = 0,
+ },
+ .green =
+ {
+ .offset = 8,
+ .length = 8,
+ .msb_right = 0,
+ },
+ .blue =
+ {
+ .offset = 0,
+ .length = 8,
+ .msb_right = 0,
+ },
+ .transp =
+ {
+ .offset = 24,
+ .length = 8,
+ .msb_right = 0,
+ },
+ },
+
+ {
+ .color_format = AMBFB_COLOR_AYUV8888,
+ .bits_per_pixel = 32,
+ .red =
+ {
+ .offset = 0,
+ .length = 8,
+ .msb_right = 0,
+ },
+ .green =
+ {
+ .offset = 16,
+ .length = 8,
+ .msb_right = 0,
+ },
+ .blue =
+ {
+ .offset = 8,
+ .length = 8,
+ .msb_right = 0,
+ },
+ .transp =
+ {
+ .offset = 24,
+ .length = 8,
+ .msb_right = 0,
+ },
+ },
+
+ {
+ .color_format = AMBFB_COLOR_VYU565,
+ .bits_per_pixel = 16,
+ .red =
+ {
+ .offset = 11,
+ .length = 5,
+ .msb_right = 0,
+ },
+ .green =
+ {
+ .offset = 5,
+ .length = 6,
+ .msb_right = 0,
+ },
+ .blue =
+ {
+ .offset = 0,
+ .length = 5,
+ .msb_right = 0,
+ },
+ .transp =
+ {
+ .offset = 0,
+ .length = 0,
+ .msb_right = 0,
+ },
+ },
+};
+
diff --git a/drivers/video/backlight/wm831x_bl.c b/drivers/video/backlight/wm831x_bl.c
index 9e5517a3..d6f69981 100644
--- a/drivers/video/backlight/wm831x_bl.c
+++ b/drivers/video/backlight/wm831x_bl.c
@@ -205,6 +205,8 @@ static int wm831x_backlight_probe(struct platform_device *pdev)
}
bl->props.brightness = max_isel;
+ bl->props.power = FB_BLANK_UNBLANK;
+ bl->props.fb_blank = FB_BLANK_UNBLANK;
platform_set_drvdata(pdev, bl);
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index e89fc313..60f5b635 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -115,6 +115,14 @@ config ARM_SP805_WATCHDOG
ARM Primecell SP805 Watchdog timer. This will reboot your system when
the timeout is reached.
+config AMBARELLA_WATCHDOG
+ tristate "Ambarella watchdog"
+ depends on PLAT_AMBARELLA
+ select WATCHDOG_CORE
+ help
+ Watchdog timer embedded into Ambarella chips. This will reboot your
+ system when the timeout is reached.
+
config AT91RM9200_WATCHDOG
tristate "AT91RM9200 watchdog"
depends on ARCH_AT91RM9200
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index a300b948..9cce2fba 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
# ARM Architecture
obj-$(CONFIG_ARM_SP805_WATCHDOG) += sp805_wdt.o
+obj-$(CONFIG_AMBARELLA_WATCHDOG) += ambarella_wdt.o
obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o
obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o
obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o
diff --git a/drivers/watchdog/ambarella_wdt.c b/drivers/watchdog/ambarella_wdt.c
new file mode 100644
index 00000000..8dab7e7b
--- /dev/null
+++ b/drivers/watchdog/ambarella_wdt.c
@@ -0,0 +1,295 @@
+/*
+ * linux/drivers/mmc/host/ambarella_sd.c
+ *
+ * Copyright (C) 2006-2007, Ambarella, Inc.
+ * Anthony Ginger, <hfjiang@ambarella.com>
+ *
+ * Ambarella Media Processor Watch Dog Timer
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/watchdog.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <plat/wdt.h>
+#include <plat/rct.h>
+
+
+#define AMBARELLA_WDT_MAX_CYCLE 0xffffffff
+
+static int heartbeat = -1; /* -1 means get value from FDT */
+module_param(heartbeat, int, 0);
+MODULE_PARM_DESC(heartbeat, "Initial watchdog heartbeat in seconds");
+
+static bool nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, bool, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+struct ambarella_wdt {
+ void __iomem *regbase;
+ struct clk *clk;
+ int irq;
+ struct watchdog_device wdd;
+ bool enabled;
+ u32 timeout; /* in cycle */
+};
+
+static int ambarella_wdt_start(struct watchdog_device *wdd)
+{
+ struct ambarella_wdt *ambwdt;
+ u32 ctrl_val;
+
+ ambwdt = watchdog_get_drvdata(wdd);
+ ambwdt->enabled = true;
+
+ ctrl_val = ambwdt->irq > 0 ? WDOG_CTR_INT_EN : WDOG_CTR_RST_EN;
+ ctrl_val |= WDOG_CTR_EN;
+
+ if (ambwdt->irq > 0)
+ amba_writel(ambwdt->regbase + WDOG_RST_WD_OFFSET, 0x00);
+ else
+ amba_writel(ambwdt->regbase + WDOG_RST_WD_OFFSET, 0xFF);
+
+ amba_writel(ambwdt->regbase + WDOG_CONTROL_OFFSET, ctrl_val);
+
+ return 0;
+}
+
+static int ambarella_wdt_stop(struct watchdog_device *wdd)
+{
+ struct ambarella_wdt *ambwdt;
+
+ ambwdt = watchdog_get_drvdata(wdd);
+ ambwdt->enabled = false;
+
+ amba_writel(ambwdt->regbase + WDOG_CONTROL_OFFSET, 0);
+
+ return 0;
+}
+
+static int ambarella_wdt_keepalive(struct watchdog_device *wdd)
+{
+ struct ambarella_wdt *ambwdt = watchdog_get_drvdata(wdd);
+
+ amba_writel(ambwdt->regbase + WDOG_RELOAD_OFFSET, ambwdt->timeout);
+ amba_writel(ambwdt->regbase + WDOG_RESTART_OFFSET, WDT_RESTART_VAL);
+
+ return 0;
+}
+
+static int ambarella_wdt_set_timeout(struct watchdog_device *wdd, u32 time)
+{
+ struct ambarella_wdt *ambwdt = watchdog_get_drvdata(wdd);
+ u32 freq;
+
+ wdd->timeout = time;
+
+ freq = clk_get_rate(clk_get(NULL, "gclk_apb"));
+ ambwdt->timeout = time * freq;
+ amba_writel(ambwdt->regbase + WDOG_RELOAD_OFFSET, ambwdt->timeout);
+
+ return 0;
+}
+
+static irqreturn_t ambarella_wdt_irq(int irq, void *devid)
+{
+ struct ambarella_wdt *ambwdt = devid;
+
+ amba_writel(ambwdt->regbase + WDOG_CLR_TMO_OFFSET, 0x01);
+
+ dev_info(ambwdt->wdd.dev, "Watchdog timer expired!\n");
+
+ return IRQ_HANDLED;
+}
+
+static const struct watchdog_info ambwdt_info = {
+ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
+ .identity = "Ambarella Watchdog",
+};
+
+static const struct watchdog_ops ambwdt_ops = {
+ .owner = THIS_MODULE,
+ .start = ambarella_wdt_start,
+ .stop = ambarella_wdt_stop,
+ .ping = ambarella_wdt_keepalive,
+ .set_timeout = ambarella_wdt_set_timeout,
+};
+
+static int ambarella_wdt_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct ambarella_wdt *ambwdt;
+ struct resource *mem;
+ void __iomem *reg;
+ int max_timeout, rval = 0;
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (mem == NULL) {
+ dev_err(&pdev->dev, "Get WDT mem resource failed!\n");
+ return -ENXIO;
+ }
+
+ reg = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
+ if (!reg) {
+ dev_err(&pdev->dev, "devm_ioremap() failed\n");
+ return -ENOMEM;
+ }
+
+ ambwdt = devm_kzalloc(&pdev->dev, sizeof(*ambwdt), GFP_KERNEL);
+ if (ambwdt == NULL) {
+ dev_err(&pdev->dev, "Out of memory!\n");
+ return -ENOMEM;
+ }
+
+ ambwdt->regbase = reg;
+
+ /* irq < 0 means to disable interrupt mode */
+ ambwdt->irq = platform_get_irq(pdev, 0);
+ if (ambwdt->irq > 0) {
+ rval = devm_request_irq(&pdev->dev, ambwdt->irq,
+ ambarella_wdt_irq, IRQF_TRIGGER_RISING,
+ dev_name(&pdev->dev), ambwdt);
+ if (rval < 0) {
+ dev_err(&pdev->dev, "Request IRQ failed!\n");
+ return -ENXIO;
+ }
+ }
+
+ ambwdt->clk = clk_get(NULL, "gclk_apb");
+ if (IS_ERR(ambwdt->clk)) {
+ dev_err(&pdev->dev, "no clk for wdt!\n");
+ return -ENODEV;
+ }
+
+ max_timeout = AMBARELLA_WDT_MAX_CYCLE / clk_get_rate(ambwdt->clk);
+
+ ambwdt->wdd.info = &ambwdt_info;
+ ambwdt->wdd.ops = &ambwdt_ops;
+ ambwdt->wdd.min_timeout = 0;
+ ambwdt->wdd.max_timeout = max_timeout;
+ ambwdt->wdd.bootstatus = amba_readl(WDT_RST_L_REG) ? 0 : WDIOF_CARDRESET;
+
+ if (!of_find_property(np, "amb,non-bootstatus", NULL)) {
+ /* WDT_RST_L_REG cannot be restored by "reboot" command,
+ * so reset it manually */
+ amba_setbitsl(UNLOCK_WDT_RST_L_REG, UNLOCK_WDT_RST_L_VAL);
+ amba_writel(WDT_RST_L_REG, 0x1);
+ amba_clrbitsl(UNLOCK_WDT_RST_L_REG, UNLOCK_WDT_RST_L_VAL);
+ }
+
+ watchdog_init_timeout(&ambwdt->wdd, heartbeat, &pdev->dev);
+ watchdog_set_nowayout(&ambwdt->wdd, nowayout);
+ watchdog_set_drvdata(&ambwdt->wdd, ambwdt);
+
+ ambarella_wdt_set_timeout(&ambwdt->wdd, ambwdt->wdd.timeout);
+ ambarella_wdt_stop(&ambwdt->wdd);
+
+ rval = watchdog_register_device(&ambwdt->wdd);
+ if (rval < 0) {
+ dev_err(&pdev->dev, "failed to register wdt!\n");
+ return rval;
+ }
+
+ platform_set_drvdata(pdev, ambwdt);
+
+ dev_notice(&pdev->dev, "Ambarella Watchdog Timer Probed.\n");
+
+ return 0;
+}
+
+static int ambarella_wdt_remove(struct platform_device *pdev)
+{
+ struct ambarella_wdt *ambwdt;
+ int rval = 0;
+
+ ambwdt = platform_get_drvdata(pdev);
+
+ ambarella_wdt_stop(&ambwdt->wdd);
+ watchdog_unregister_device(&ambwdt->wdd);
+
+ dev_notice(&pdev->dev, "Remove Ambarella Watchdog Timer.\n");
+
+ return rval;
+}
+
+static void ambarella_wdt_shutdown(struct platform_device *pdev)
+{
+ struct ambarella_wdt *ambwdt;
+
+ ambwdt = platform_get_drvdata(pdev);
+ ambarella_wdt_stop(&ambwdt->wdd);
+
+ dev_info(&pdev->dev, "%s @ %d.\n", __func__, system_state);
+}
+
+#ifdef CONFIG_PM
+
+static int ambarella_wdt_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ struct ambarella_wdt *ambwdt;
+ int rval = 0;
+
+ ambwdt = platform_get_drvdata(pdev);
+
+ if (watchdog_active(&ambwdt->wdd))
+ ambarella_wdt_stop(&ambwdt->wdd);
+
+ dev_dbg(&pdev->dev, "%s exit with %d @ %d\n",
+ __func__, rval, state.event);
+
+ return rval;
+}
+
+static int ambarella_wdt_resume(struct platform_device *pdev)
+{
+ struct ambarella_wdt *ambwdt;
+ int rval = 0;
+
+ ambwdt = platform_get_drvdata(pdev);
+
+ if (watchdog_active(&ambwdt->wdd)) {
+ ambarella_wdt_start(&ambwdt->wdd);
+ ambarella_wdt_keepalive(&ambwdt->wdd);
+ }
+
+ dev_dbg(&pdev->dev, "%s exit with %d\n", __func__, rval);
+
+ return rval;
+}
+#endif
+
+static const struct of_device_id ambarella_wdt_dt_ids[] = {
+ {.compatible = "ambarella,wdt", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ambarella_wdt_dt_ids);
+
+static struct platform_driver ambarella_wdt_driver = {
+ .probe = ambarella_wdt_probe,
+ .remove = ambarella_wdt_remove,
+ .shutdown = ambarella_wdt_shutdown,
+#ifdef CONFIG_PM
+ .suspend = ambarella_wdt_suspend,
+ .resume = ambarella_wdt_resume,
+#endif
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ambarella-wdt",
+ .of_match_table = ambarella_wdt_dt_ids,
+ },
+};
+
+module_platform_driver(ambarella_wdt_driver);
+
+MODULE_DESCRIPTION("Ambarella Media Processor Watch Dog Timer");
+MODULE_AUTHOR("Anthony Ginger, <hfjiang@ambarella.com>");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c
index 9dcb6d08..98fcb249 100644
--- a/drivers/watchdog/wm831x_wdt.c
+++ b/drivers/watchdog/wm831x_wdt.c
@@ -283,6 +283,11 @@ static int wm831x_wdt_probe(struct platform_device *pdev)
dev_set_drvdata(&pdev->dev, driver_data);
+ dev_notice(&pdev->dev,
+ "Wm831x PMIC Watch Dog Timer[%s].\n",
+ dev_name(&pdev->dev));
+
+
return 0;
err_gpio:
diff --git a/include/linux/ambbus.h b/include/linux/ambbus.h
new file mode 100644
index 00000000..02050174
--- /dev/null
+++ b/include/linux/ambbus.h
@@ -0,0 +1,29 @@
+/*
+ * AMB bus.
+ */
+
+#ifndef __LINUX_AMBBUS_H
+#define __LINUX_AMBBUS_H
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+
+struct amb_driver {
+ int (*match)(struct device *);
+ int (*probe)(struct device *);
+ int (*remove)(struct device *);
+ void (*shutdown)(struct device *);
+ int (*suspend)(struct device *, pm_message_t);
+ int (*resume)(struct device *);
+
+ struct device_driver driver;
+ struct device *devices;
+};
+
+#define to_amb_driver(x) container_of((x), struct amb_driver, driver)
+
+
+int amb_register_driver(struct amb_driver *);
+void amb_unregister_driver(struct amb_driver *);
+
+#endif /* __LINUX_AMBBUS_H */
diff --git a/include/linux/ambpriv_device.h b/include/linux/ambpriv_device.h
new file mode 100644
index 00000000..6f1c70aa
--- /dev/null
+++ b/include/linux/ambpriv_device.h
@@ -0,0 +1,71 @@
+/*
+ * ambpriv_device.h
+ *
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * Copyright (C) 2012-2016, Ambarella, Inc.
+ *
+ */
+
+#ifndef _AMBPRIV_DEVICE_H_
+#define _AMBPRIV_DEVICE_H_
+
+#include <linux/device.h>
+
+struct ambpriv_device {
+ const char * name;
+ int id;
+ struct device dev;
+ u32 num_resources;
+ struct resource * resource;
+
+ /* arch specific additions */
+ struct pdev_archdata archdata;
+};
+
+#define to_ambpriv_device(x) container_of((x), struct ambpriv_device, dev)
+
+extern int ambpriv_device_register(struct ambpriv_device *);
+extern void ambpriv_device_unregister(struct ambpriv_device *);
+
+extern struct bus_type ambpriv_bus_type;
+extern struct device ambpriv_bus;
+
+extern int ambpriv_add_devices(struct ambpriv_device **, int);
+extern struct ambpriv_device *ambpriv_device_alloc(const char *name, int id);
+extern int ambpriv_device_add_resources(struct ambpriv_device *pdev,
+ const struct resource *res,
+ unsigned int num);
+extern int ambpriv_device_add_data(struct ambpriv_device *pdev, const void *data, size_t size);
+extern int ambpriv_device_add(struct ambpriv_device *pdev);
+extern void ambpriv_device_del(struct ambpriv_device *pdev);
+extern void ambpriv_device_put(struct ambpriv_device *pdev);
+
+extern struct ambpriv_device *of_find_ambpriv_device_by_match(struct of_device_id *match);
+extern struct ambpriv_device *of_find_ambpriv_device_by_node(struct device_node *np);
+extern int ambpriv_get_irq(struct ambpriv_device *dev, unsigned int num);
+extern int ambpriv_get_irq_by_name(struct ambpriv_device *dev, const char *name);
+
+struct ambpriv_driver {
+ int (*probe)(struct ambpriv_device *);
+ int (*remove)(struct ambpriv_device *);
+ void (*shutdown)(struct ambpriv_device *);
+ int (*suspend)(struct ambpriv_device *, pm_message_t state);
+ int (*resume)(struct ambpriv_device *);
+ struct device_driver driver;
+};
+
+extern int ambpriv_driver_register(struct ambpriv_driver *);
+extern void ambpriv_driver_unregister(struct ambpriv_driver *);
+
+#define ambpriv_get_drvdata(_dev) dev_get_drvdata(&(_dev)->dev)
+#define ambpriv_set_drvdata(_dev,data) dev_set_drvdata(&(_dev)->dev, (data))
+
+extern struct ambpriv_device *ambpriv_create_bundle(struct ambpriv_driver *driver,
+ struct resource *res, unsigned int n_res,
+ const void *data, size_t size);
+
+extern int ambpriv_i2c_update_addr(const char *name, int bus, int addr);
+
+#endif /* _PLATFORM_DEVICE_H_ */
+
diff --git a/include/linux/bitrev.h b/include/linux/bitrev.h
index 7ffe03f4..12740525 100644
--- a/include/linux/bitrev.h
+++ b/include/linux/bitrev.h
@@ -5,11 +5,12 @@
extern u8 const byte_rev_table[256];
-static inline u8 bitrev8(u8 byte)
+static inline u8 bitrev_by_table(u8 in)
{
- return byte_rev_table[byte];
+ return byte_rev_table[in];
}
+extern u8 bitrev8(u8 in);
extern u16 bitrev16(u16 in);
extern u32 bitrev32(u32 in);
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index 7a13848d..38eb5dbb 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -611,25 +611,27 @@ static inline void __ftrace_enabled_restore(int enabled)
#endif
}
-#ifndef HAVE_ARCH_CALLER_ADDR
+/* All archs should have this, but we define it for consistency */
+#ifndef ftrace_return_address0
+# define ftrace_return_address0 __builtin_return_address(0)
+#endif
+
+/* Archs may use other ways for ADDR1 and beyond */
+#ifndef ftrace_return_address
# ifdef CONFIG_FRAME_POINTER
-# define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
-# define CALLER_ADDR1 ((unsigned long)__builtin_return_address(1))
-# define CALLER_ADDR2 ((unsigned long)__builtin_return_address(2))
-# define CALLER_ADDR3 ((unsigned long)__builtin_return_address(3))
-# define CALLER_ADDR4 ((unsigned long)__builtin_return_address(4))
-# define CALLER_ADDR5 ((unsigned long)__builtin_return_address(5))
-# define CALLER_ADDR6 ((unsigned long)__builtin_return_address(6))
+# define ftrace_return_address(n) __builtin_return_address(n)
# else
-# define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
-# define CALLER_ADDR1 0UL
-# define CALLER_ADDR2 0UL
-# define CALLER_ADDR3 0UL
-# define CALLER_ADDR4 0UL
-# define CALLER_ADDR5 0UL
-# define CALLER_ADDR6 0UL
+# define ftrace_return_address(n) 0UL
# endif
-#endif /* ifndef HAVE_ARCH_CALLER_ADDR */
+#endif
+
+#define CALLER_ADDR0 ((unsigned long)ftrace_return_address0)
+#define CALLER_ADDR1 ((unsigned long)ftrace_return_address(1))
+#define CALLER_ADDR2 ((unsigned long)ftrace_return_address(2))
+#define CALLER_ADDR3 ((unsigned long)ftrace_return_address(3))
+#define CALLER_ADDR4 ((unsigned long)ftrace_return_address(4))
+#define CALLER_ADDR5 ((unsigned long)ftrace_return_address(5))
+#define CALLER_ADDR6 ((unsigned long)ftrace_return_address(6))
#ifdef CONFIG_IRQSOFF_TRACER
extern void time_hardirqs_on(unsigned long a0, unsigned long a1);
diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
index 68391116..0d908f49 100644
--- a/include/linux/iio/iio.h
+++ b/include/linux/iio/iio.h
@@ -13,6 +13,16 @@
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/iio/types.h>
+
+/**
+ * struct iio_mount_matrix - iio mounting matrix
+ * @rotation: 3 dimensional space rotation matrix defining sensor alignment with
+ * main hardware
+ */
+struct iio_mount_matrix {
+ const char *rotation[9];
+};
+
/* IIO TODO LIST */
/*
* Provide means of adjusting timer accuracy.
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 5f4554b8..e36ae104 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -103,6 +103,18 @@
(((__x) - ((__d) / 2)) / (__d)); \
} \
)
+/*
+ * Same as above but for u64 dividends. divisor must be a 32-bit
+ * number.
+ */
+#define DIV_ROUND_CLOSEST_ULL(x, divisor)( \
+{ \
+ typeof(divisor) __d = divisor; \
+ unsigned long long _tmp = (x) + (__d) / 2; \
+ do_div(_tmp, __d); \
+ _tmp; \
+} \
+)
/*
* Multiplies an integer by a fraction, while avoiding unnecessary
diff --git a/include/linux/mdio-gpio.h b/include/linux/mdio-gpio.h
index 7c9fe3c2..fd43597c 100644
--- a/include/linux/mdio-gpio.h
+++ b/include/linux/mdio-gpio.h
@@ -17,6 +17,9 @@ struct mdio_gpio_platform_data {
/* GPIO numbers for bus pins */
unsigned int mdc;
unsigned int mdio;
+ unsigned int rst;
+
+ bool rst_active_low;
unsigned int phy_mask;
int irqs[PHY_MAX_ADDR];
diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h
index 76c22648..c93d1e01 100644
--- a/include/linux/mfd/wm831x/core.h
+++ b/include/linux/mfd/wm831x/core.h
@@ -238,6 +238,18 @@
#define WM831X_ON_PIN_TO_SHIFT 0 /* ON_PIN_TO - [1:0] */
#define WM831X_ON_PIN_TO_WIDTH 2 /* ON_PIN_TO - [1:0] */
+/*
+ * R16398 (0x400E) - ON Source
+ */
+#define WM831X_ON_SOURCE_ALARM 0x0020 /* ON_SOURCE_ALARM */
+#define WM831X_ON_SOURCE_ALARM_MASK 0x0020 /* ON_SOURCE_ALARM */
+#define WM831X_ON_SOURCE_ALARM_SHIFT 5 /* ON_SOURCE_ALARM */
+#define WM831X_ON_SOURCE_ALARM_WIDTH 1 /* ON_SOURCE_ALARM */
+#define WM831X_ON_SOURCE_ON_PIN 0x0010 /* ON_SOURCE_ON_PIN */
+#define WM831X_ON_SOURCE_ON_PIN_MASK 0x0010 /* ON_SOURCE_ON_PIN */
+#define WM831X_ON_SOURCE_ON_PIN_SHIFT 4 /* ON_SOURCE_ON_PIN */
+#define WM831X_ON_SOURCE_ON_PIN_WIDTH 1 /* ON_SOURCE_ON_PIN */
+
/*
* R16528 (0x4090) - Clock Control 1
*/
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index ab636344..8152ba7f 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -549,6 +549,7 @@ struct nand_chip {
#define NAND_MFR_AMD 0x01
#define NAND_MFR_MACRONIX 0xc2
#define NAND_MFR_EON 0x92
+#define NAND_MFR_GD 0xc8
/* The maximum expected count of bytes in the NAND ID sequence */
#define NAND_MAX_ID_LEN 8
diff --git a/include/linux/net.h b/include/linux/net.h
index 65545ac6..d00f1f74 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -291,4 +291,17 @@ extern int kernel_sock_shutdown(struct socket *sock,
#define MODULE_ALIAS_NET_PF_PROTO_NAME(pf, proto, name) \
MODULE_ALIAS("net-pf-" __stringify(pf) "-proto-" __stringify(proto) \
name)
+
+#ifdef CONFIG_WLAN_UPDATE_SEQ
+#define SOCK_SEQ_UPDATE 0xBADBEEF
+struct sock_sequence_update
+{
+ struct sock *sock;
+ unsigned short ident;
+ unsigned int seq;
+ unsigned int ack;
+ unsigned int seq_offset;
+ unsigned int ack_offset;
+};
+#endif
#endif /* _LINUX_NET_H */
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 9e11039d..13048f9a 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -337,6 +337,7 @@ struct phy_device {
* -1 means no interrupt
*/
int irq;
+ int irq_flags;
/* private data pointer */
/* For use by PHYs to maintain extra state */
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index f1b0dca6..942ef5e0 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -22,6 +22,7 @@
#include <linux/slab.h>
#include <linux/scatterlist.h>
#include <linux/types.h>
+#include <linux/workqueue.h>
#include <linux/usb/ch9.h>
struct usb_ep;
@@ -475,6 +476,7 @@ struct usb_gadget_ops {
/**
* struct usb_gadget - represents a usb slave device
+ * @work: (internal use) Workqueue to be used for sysfs_notify()
* @ops: Function pointers used to access hardware-specific operations.
* @ep0: Endpoint zero, used when reading or writing responses to
* driver setup() requests
@@ -520,6 +522,7 @@ struct usb_gadget_ops {
* device is acting as a B-Peripheral (so is_a_peripheral is false).
*/
struct usb_gadget {
+ struct work_struct work;
/* readonly to gadget driver */
const struct usb_gadget_ops *ops;
struct usb_ep *ep0;
@@ -538,6 +541,7 @@ struct usb_gadget {
unsigned out_epnum;
unsigned in_epnum;
};
+#define work_to_gadget(w) (container_of((w), struct usb_gadget, work))
static inline void set_gadget_data(struct usb_gadget *gadget, void *data)
{ dev_set_drvdata(&gadget->dev, data); }
diff --git a/include/net/sock.h b/include/net/sock.h
index 2317d122..1dbd6fac 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1661,8 +1661,15 @@ static inline void sk_filter_charge(struct sock *sk, struct sk_filter *fp)
/* Ungrab socket and destroy it, if it was the last reference. */
static inline void sock_put(struct sock *sk)
{
- if (atomic_dec_and_test(&sk->sk_refcnt))
+ if (atomic_dec_and_test(&sk->sk_refcnt)){
+ #ifdef CONFIG_WLAN_UPDATE_SEQ
+ extern struct sock_sequence_update ipv4_update;
+ if(ipv4_update.sock == sk){
+ ipv4_update.sock = NULL;
+ }
+ #endif
sk_free(sk);
+ }
}
extern int sk_receive_skb(struct sock *sk, struct sk_buff *skb,
diff --git a/include/sound/ak7755_pdata.h b/include/sound/ak7755_pdata.h
new file mode 100644
index 00000000..1350b1db
--- /dev/null
+++ b/include/sound/ak7755_pdata.h
@@ -0,0 +1,19 @@
+/*
+ * ak7755_pdata.h -- audio driver for ak4482
+ *
+ * Copyright (C) 2015 Asahi Kasei Microdevices Corporation
+ * Author Date Revision
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * 15/06/15 1.0
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
+ */
+
+#ifndef _AK7755_PDADA_H
+#define _AK7755_PDADA_H
+
+struct ak7755_platform_data {
+ int pdn_gpio;
+};
+
+#endif
+
diff --git a/include/sound/es8328.h b/include/sound/es8328.h
new file mode 100644
index 00000000..fdfc9461
--- /dev/null
+++ b/include/sound/es8328.h
@@ -0,0 +1,22 @@
+/*
+ * es8328.h -- ES8328 Soc Audio driver
+ *
+ * Copyright 2011 Ambarella Ltd.
+ *
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __SOUND_ES8328_H
+#define __SOUND_ES8328_H
+
+struct es8328_platform_data {
+ unsigned int power_pin;
+ unsigned int power_delay;
+};
+
+#endif
+
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 1634dc6e..86c01011 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -678,7 +678,13 @@ int hibernate(void)
flags |= SF_CRC32_MODE;
pr_debug("PM: writing image.\n");
+#ifdef CONFIG_ARCH_AMBARELLA
+ error = swsusp_write_mtd(flags);
+ if (error)
+ outer_resume();
+#else
error = swsusp_write(flags);
+#endif
swsusp_free();
if (!error)
power_down();
diff --git a/kernel/power/power.h b/kernel/power/power.h
index f770cad3..70db88d1 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -11,8 +11,19 @@ struct swsusp_info {
unsigned long image_pages;
unsigned long pages;
unsigned long size;
+#ifdef CONFIG_ARCH_AMBARELLA
+ unsigned long magic;
+ unsigned long addr;
+ unsigned long lzo_enable;
+ unsigned long crc32;
+#endif
} __attribute__((aligned(PAGE_SIZE)));
+#ifdef CONFIG_ARCH_AMBARELLA
+int swsusp_write_mtd(int flags);
+#endif
+
+
#ifdef CONFIG_HIBERNATION
/* kernel/power/snapshot.c */
extern void __init hibernate_reserved_size_init(void);
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 91c04f16..655eff1f 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -1660,6 +1660,10 @@ static int init_header(struct swsusp_info *info)
info->pages = snapshot_get_image_size();
info->size = info->pages;
info->size <<= PAGE_SHIFT;
+#ifdef CONFIG_ARCH_AMBARELLA
+ info->magic = 0x0badbeef;
+ info->addr = virt_to_phys(ambarella_cpu_resume);
+#endif
return init_header_complete(info);
}
@@ -1677,6 +1681,10 @@ pack_pfns(unsigned long *buf, struct memory_bitmap *bm)
buf[j] = memory_bm_next_pfn(bm);
if (unlikely(buf[j] == BM_END_OF_MAP))
break;
+
+#ifdef CONFIG_ARCH_AMBARELLA
+ buf[j] = __pfn_to_phys(buf[j]);
+#endif
/* Save page key for data page (s390 only). */
page_key_read(buf + j);
}
@@ -2353,3 +2361,8 @@ int restore_highmem(void)
return 0;
}
#endif /* CONFIG_HIGHMEM */
+
+
+#ifdef CONFIG_ARCH_AMBARELLA
+#include "../../arch/arm/mach-ambarella/hibernate.c"
+#endif
diff --git a/lib/bitrev.c b/lib/bitrev.c
index 39562034..9001fafa 100644
--- a/lib/bitrev.c
+++ b/lib/bitrev.c
@@ -42,9 +42,15 @@ const u8 byte_rev_table[256] = {
};
EXPORT_SYMBOL_GPL(byte_rev_table);
+u8 bitrev8(u8 byte)
+{
+ return bitrev_by_table(byte);
+}
+EXPORT_SYMBOL(bitrev8);
+
u16 bitrev16(u16 x)
{
- return (bitrev8(x & 0xff) << 8) | bitrev8(x >> 8);
+ return (bitrev_by_table(x & 0xff) << 8) | bitrev_by_table(x >> 8);
}
EXPORT_SYMBOL(bitrev16);
@@ -57,3 +63,4 @@ u32 bitrev32(u32 x)
return (bitrev16(x & 0xffff) << 16) | bitrev16(x >> 16);
}
EXPORT_SYMBOL(bitrev32);
+
diff --git a/make.inc b/make.inc
new file mode 100644
index 00000000..5bc285f9
--- /dev/null
+++ b/make.inc
@@ -0,0 +1,125 @@
+##
+## kernel/linux/make.inc
+##
+## History:
+## 2012/06/01 - [Cao Rongrong] Created file
+##
+## Copyright 2008-2015 Ambarella Inc. All Rights Reserved.
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+
+ifeq ($(CONFIG_LINUX_KERNEL_VERSION),"3.10")
+
+ARCH := arm
+export ARCH
+
+LOCAL_PATH:=$(call my-dir)
+
+#####
+
+.PHONY: linux
+
+linux: $(DOT_CONFIG)
+ @mkdir -p $(LINUX_OUT_DIR)
+ @if [ -f $(LINUX_OUT_DIR)/.config ]; then \
+ echo "Build Linux-$(CONFIG_LINUX_KERNEL_VERSION) with previous configuration ..."; \
+ else \
+ $(MAKE) $(AMBA_MAKE_PARA) defconfig_public_linux; \
+ fi
+ $(AMBA_MAKEFILE_V)$(MAKE) $(AMBA_MAKE_PARA) -C $(LINUX_SRC_DIR) O=$(LINUX_OUT_DIR) all
+ @if [ -n "$(KERNEL_INSTALL_PATH)" ]; then \
+ echo "Install Linux modules to $(KERNEL_INSTALL_PATH) ..."; \
+ mkdir -p $(KERNEL_INSTALL_PATH); \
+ $(MAKE) $(AMBA_MAKE_PARA) -C $(LINUX_SRC_DIR) O=$(LINUX_OUT_DIR) \
+ $(LINUX_INSTALL_FLAG) modules_install; \
+ find $(KERNEL_INSTALL_PATH)/lib/modules/ -name build | xargs -l1 rm -rf; \
+ find $(KERNEL_INSTALL_PATH)/lib/modules/ -name source | xargs -l1 rm -rf; \
+ fi
+ @cp -dpRf $(LINUX_OUT_DIR)/arch/arm/boot/Image $(KERNEL_OUT_DIR)/Image
+ @cp -dpRf $(LINUX_OUT_DIR)/arch/arm/boot/zImage $(KERNEL_OUT_DIR)/zImage
+ @echo "Build $@ Done."
+
+$(call add-target-into-build, linux)
+
+###
+
+.PHONY: menuconfig_public_linux
+
+menuconfig_public_linux: $(DOT_CONFIG)
+ @mkdir -p $(LINUX_OUT_DIR)
+ @$(MAKE) $(AMBA_MAKE_PARA) -C $(LINUX_SRC_DIR) O=$(LINUX_OUT_DIR) menuconfig
+
+###
+
+.PHONY: defconfig_public_linux
+
+defconfig_public_linux: $(DOT_CONFIG)
+ @echo "Build Linux-$(CONFIG_LINUX_KERNEL_VERSION) with $(KERNEL_DEFCONFIG) ..."
+ @mkdir -p $(LINUX_OUT_DIR)
+ @if [ -f $(AMB_BOARD_DIR)/config/kernel/$(KERNEL_DEFCONFIG) ]; then \
+ cp -dpRf $(AMB_BOARD_DIR)/config/kernel/$(KERNEL_DEFCONFIG) $(LINUX_OUT_DIR)/.config; \
+ $(MAKE) $(AMBA_MAKE_PARA) -C $(LINUX_SRC_DIR) O=$(LINUX_OUT_DIR) olddefconfig; \
+ else \
+ $(MAKE) $(AMBA_MAKE_PARA) -C $(LINUX_SRC_DIR) O=$(LINUX_OUT_DIR) $(KERNEL_DEFCONFIG); \
+ fi
+
+
+#####
+
+ifeq ($(CONFIG_KERNEL_DUAL_CPU),y)
+
+KERNEL_2NDCONFIG := $(shell echo $(CONFIG_KERNEL_2NDCONFIG_STRING))
+LINUX_OUT_DIR_2 := $(KERNEL_OUT_DIR)/linux_$(strip \
+ $(shell echo $(KERNEL_2NDCONFIG) | \
+ sed -e s/ambarella_// -e s/_defconfig//))
+
+.PHONY: linux_2
+
+linux_2: $(DOT_CONFIG)
+ @mkdir -p $(LINUX_OUT_DIR_2)
+ @if [ -f $(LINUX_OUT_DIR_2)/.config ]; then \
+ echo "Build Linux_2 with previous configuration ..."; \
+ else \
+ $(MAKE) $(AMBA_MAKE_PARA) defconfig_public_linux_2; \
+ fi
+ $(AMBA_MAKEFILE_V)$(MAKE) $(AMBA_MAKE_PARA) -C $(LINUX_SRC_DIR) O=$(LINUX_OUT_DIR_2) all
+ @cp -dpRf $(LINUX_OUT_DIR_2)/arch/arm/boot/Image $(KERNEL_OUT_DIR)/Image_2
+ @echo "Build $@ Done."
+
+$(call add-target-into-build, linux_2)
+
+###
+
+.PHONY: menuconfig_public_linux_2
+
+menuconfig_public_linux_2: $(DOT_CONFIG)
+ @mkdir -p $(LINUX_OUT_DIR_2)
+ @$(MAKE) $(AMBA_MAKE_PARA) -C $(LINUX_SRC_DIR) O=$(LINUX_OUT_DIR_2) menuconfig
+
+###
+
+.PHONY: defconfig_public_linux_2
+
+defconfig_public_linux_2: $(DOT_CONFIG)
+ @echo "Build Linux_2 with $(KERNEL_2NDCONFIG) ..."
+ @mkdir -p $(LINUX_OUT_DIR_2)
+ @if [ -f $(AMB_BOARD_DIR)/config/kernel/$(KERNEL_2NDCONFIG) ]; then \
+ cp -dpRf $(AMB_BOARD_DIR)/config/kernel/$(KERNEL_2NDCONFIG) $(LINUX_OUT_DIR_2)/.config; \
+ else \
+ $(MAKE) $(AMBA_MAKE_PARA) -C $(LINUX_SRC_DIR) O=$(LINUX_OUT_DIR_2) $(KERNEL_2NDCONFIG); \
+ fi
+
+endif
+
+#####
+
+endif
+
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
index 0a327b66..417d98da 100644
--- a/net/core/sysctl_net_core.c
+++ b/net/core/sysctl_net_core.c
@@ -21,7 +21,8 @@
#include <net/net_ratelimit.h>
static int zero = 0;
-static int one = 1;
+//to cease compile warning
+//static int one = 1;
static int ushort_max = USHRT_MAX;
static int min_sndbuf = SOCK_MIN_SNDBUF;
static int min_rcvbuf = SOCK_MIN_RCVBUF;
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index 8603ca82..3d556791 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -639,3 +639,5 @@ config TCP_MD5SIG
on the Internet.
If unsure, say N.
+config WLAN_UPDATE_SEQ
+ bool "Ambarella cooperate with wlan to update socket sequence"
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index ea78ef5a..af88080f 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -211,17 +211,22 @@ static struct sock *icmp_sk(struct net *net)
static inline struct sock *icmp_xmit_lock(struct net *net)
{
struct sock *sk;
+ int counter = 0;
local_bh_disable();
sk = icmp_sk(net);
- if (unlikely(!spin_trylock(&sk->sk_lock.slock))) {
+ while (unlikely(!spin_trylock(&sk->sk_lock.slock))) {
/* This can happen if the output path signals a
* dst_link_failure() for an outgoing ICMP packet.
*/
- local_bh_enable();
- return NULL;
+ if (counter > 3) {
+ local_bh_enable();
+ pr_debug("%s = %d\n", __func__, counter);
+ return NULL;
+ }
+ counter++;
}
return sk;
}
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 57e74508..e4f3f054 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -80,6 +80,10 @@
#include <linux/netlink.h>
#include <linux/tcp.h>
+#ifdef CONFIG_WLAN_UPDATE_SEQ
+extern int iphdr_updatebywlan(struct sock *sk, struct iphdr *iph);
+#endif
+
int sysctl_ip_default_ttl __read_mostly = IPDEFTTL;
EXPORT_SYMBOL(sysctl_ip_default_ttl);
@@ -395,6 +399,9 @@ packet_routed:
}
ip_select_ident_segs(skb, sk, skb_shinfo(skb)->gso_segs ?: 1);
+#ifdef CONFIG_WLAN_UPDATE_SEQ
+ iphdr_updatebywlan(sk, iph);
+#endif
skb->priority = sk->sk_priority;
skb->mark = sk->sk_mark;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 5d4bd6ca..9e303857 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -302,6 +302,11 @@ EXPORT_SYMBOL(tcp_memory_allocated);
struct percpu_counter tcp_sockets_allocated;
EXPORT_SYMBOL(tcp_sockets_allocated);
+#ifdef CONFIG_WLAN_UPDATE_SEQ
+struct sock_sequence_update ipv4_update = {0};
+EXPORT_SYMBOL(ipv4_update);
+#endif
+
/*
* TCP splice context
*/
@@ -532,6 +537,9 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
struct tcp_sock *tp = tcp_sk(sk);
int answ;
bool slow;
+#ifdef CONFIG_WLAN_UPDATE_SEQ
+ unsigned int sequence[3];
+#endif
switch (cmd) {
case SIOCINQ:
@@ -576,6 +584,20 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
else
answ = tp->write_seq - tp->snd_nxt;
break;
+
+#ifdef CONFIG_WLAN_UPDATE_SEQ
+ case SOCK_SEQ_UPDATE:
+ if (copy_from_user(sequence, (int __user *)arg, sizeof(sequence)))
+ return -EFAULT;
+
+
+ ipv4_update.sock = sk;
+ ipv4_update.ident = (u16)sequence[0];
+ ipv4_update.seq = sequence[1];
+ ipv4_update.ack = sequence[2];
+
+ return 0;
+#endif
default:
return -ENOIOCTLCMD;
}
@@ -584,6 +606,44 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
}
EXPORT_SYMBOL(tcp_ioctl);
+#ifdef CONFIG_WLAN_UPDATE_SEQ
+int tcphr_updatebywlan(struct sock *sk, struct tcphdr *th, struct sk_buff *skb)
+{
+ if (ipv4_update.sock != sk)
+ return 0;
+
+ if (ipv4_update.seq > 0){
+ ipv4_update.seq_offset = ipv4_update.seq - ntohl(th->seq);
+ ipv4_update.seq = 0;
+ }
+
+ if (ipv4_update.ack > 0){
+ ipv4_update.ack_offset = ipv4_update.ack - ntohl(th->ack_seq);
+ ipv4_update.ack = 0;
+ }
+
+ th->seq = htonl(ipv4_update.seq_offset + ntohl(th->seq));
+ th->ack_seq = htonl(ipv4_update.ack_offset + ntohl(th->ack_seq));
+
+ return 0;
+}
+
+EXPORT_SYMBOL(tcphr_updatebywlan);
+
+int iphdr_updatebywlan(struct sock *sk, struct iphdr *iph)
+{
+ if (ipv4_update.sock != sk)
+ return 0;
+
+ if (ipv4_update.ident > 0) {
+ iph->id = htons(ipv4_update.ident);
+ ipv4_update.ident = 0;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(iphdr_updatebywlan);
+#endif
+
static inline void tcp_mark_push(struct tcp_sock *tp, struct sk_buff *skb)
{
TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_PSH;
diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c
index 894b7cea..872b3a07 100644
--- a/net/ipv4/tcp_cubic.c
+++ b/net/ipv4/tcp_cubic.c
@@ -153,6 +153,27 @@ static void bictcp_init(struct sock *sk)
tcp_sk(sk)->snd_ssthresh = initial_ssthresh;
}
+static void bictcp_cwnd_event(struct sock *sk, enum tcp_ca_event event)
+{
+ if (event == CA_EVENT_TX_START) {
+ struct bictcp *ca = inet_csk_ca(sk);
+ u32 now = tcp_time_stamp;
+ s32 delta;
+
+ delta = now - tcp_sk(sk)->lsndtime;
+
+ /* We were application limited (idle) for a while.
+ * Shift epoch_start to keep cwnd growth to cubic curve.
+ */
+ if (ca->epoch_start && delta > 0) {
+ ca->epoch_start += delta;
+ if (after(ca->epoch_start, now))
+ ca->epoch_start = now;
+ }
+ return;
+ }
+}
+
/* calculate the cubic root of x using a table lookup followed by one
* Newton-Raphson iteration.
* Avg err ~= 0.195%
@@ -439,6 +460,7 @@ static struct tcp_congestion_ops cubictcp __read_mostly = {
.cong_avoid = bictcp_cong_avoid,
.set_state = bictcp_state,
.undo_cwnd = bictcp_undo_cwnd,
+ .cwnd_event = bictcp_cwnd_event,
.pkts_acked = bictcp_acked,
.owner = THIS_MODULE,
.name = "cubic",
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index f3b15bb7..d78de1b6 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -76,6 +76,11 @@
#include <asm/unaligned.h>
#include <net/netdma.h>
+#ifdef CONFIG_WLAN_UPDATE_SEQ
+extern struct sock_sequence_update ipv4_update;
+struct tcphdr th_copy;
+#endif
+
int sysctl_tcp_timestamps __read_mostly = 1;
int sysctl_tcp_window_scaling __read_mostly = 1;
int sysctl_tcp_sack __read_mostly = 1;
@@ -5114,13 +5119,29 @@ discard:
* the rest is checked inline. Fast processing is turned on in
* tcp_data_queue when everything is OK.
*/
+
+#ifndef CONFIG_WLAN_UPDATE_SEQ
int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
const struct tcphdr *th, unsigned int len)
+#else
+int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
+ const struct tcphdr *t, unsigned int len)
+#endif
{
struct tcp_sock *tp = tcp_sk(sk);
+#ifdef CONFIG_WLAN_UPDATE_SEQ
+ struct tcphdr *th = &th_copy;
+ memcpy(th, t, sizeof(struct tcphdr));
+ if (sk == ipv4_update.sock) {
+ th->seq -= ipv4_update.ack_offset;
+ th->ack_seq -= ipv4_update.seq_offset;
+ }
+#endif
+
if (unlikely(sk->sk_rx_dst == NULL))
inet_csk(sk)->icsk_af_ops->sk_rx_dst_set(sk, skb);
+
/*
* Header prediction.
* The code loosely follows the one in the famous
@@ -5639,14 +5660,28 @@ reset_and_undo:
* address independent.
*/
+#ifndef CONFIG_WLAN_UPDATE_SEQ
int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
const struct tcphdr *th, unsigned int len)
+#else
+int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
+ const struct tcphdr *t, unsigned int len)
+#endif
{
struct tcp_sock *tp = tcp_sk(sk);
struct inet_connection_sock *icsk = inet_csk(sk);
struct request_sock *req;
int queued = 0;
+#ifdef CONFIG_WLAN_UPDATE_SEQ
+ struct tcphdr *th = &th_copy;
+ memcpy(th, t, sizeof(struct tcphdr));
+ if (sk == ipv4_update.sock) {
+ th->seq -= ipv4_update.ack_offset;
+ th->ack_seq -= ipv4_update.seq_offset;
+ }
+#endif
+
tp->rx_opt.saw_tstamp = 0;
switch (sk->sk_state) {
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 11f27a45..6c33acb8 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -89,6 +89,9 @@ int sysctl_tcp_tw_reuse __read_mostly;
int sysctl_tcp_low_latency __read_mostly;
EXPORT_SYMBOL(sysctl_tcp_low_latency);
+#ifdef CONFIG_WLAN_UPDATE_SEQ
+extern struct sock_sequence_update ipv4_update;
+#endif
#ifdef CONFIG_TCP_MD5SIG
static int tcp_v4_md5_hash_hdr(char *md5_hash, const struct tcp_md5sig_key *key,
@@ -2007,6 +2010,16 @@ int tcp_v4_rcv(struct sk_buff *skb)
if (!sk)
goto no_tcp_socket;
+#ifdef CONFIG_WLAN_UPDATE_SEQ
+ if (ipv4_update.sock && sk == ipv4_update.sock){
+
+ TCP_SKB_CB(skb)->seq = ntohl(th->seq) - ipv4_update.ack_offset;
+ TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
+ skb->len - th->doff * 4);
+ TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq) - ipv4_update.seq_offset;
+ }
+#endif
+
process:
if (sk->sk_state == TCP_TIME_WAIT)
goto do_time_wait;
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 276b2830..5eb597c1 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -42,6 +42,10 @@
#include <linux/gfp.h>
#include <linux/module.h>
+#ifdef CONFIG_WLAN_UPDATE_SEQ
+extern int tcphr_updatebywlan(struct sock *sk, struct tcphdr *th, struct sk_buff *skb);
+#endif
+
/* People can turn this off for buggy TCP's found in printers etc. */
int sysctl_tcp_retrans_collapse __read_mostly = 1;
@@ -909,6 +913,10 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
th->dest = inet->inet_dport;
th->seq = htonl(tcb->seq);
th->ack_seq = htonl(tp->rcv_nxt);
+
+#ifdef CONFIG_WLAN_UPDATE_SEQ
+ tcphr_updatebywlan(sk, th, skb);
+#endif
*(((__be16 *)th) + 6) = htons(((tcp_header_size >> 2) << 12) |
tcb->tcp_flags);
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 9e675c76..625926c6 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -34,6 +34,7 @@ config SND_SOC_GENERIC_DMAENGINE_PCM
select SND_SOC_DMAENGINE_PCM
# All the supported SoCs
+source "sound/soc/ambarella/Kconfig"
source "sound/soc/atmel/Kconfig"
source "sound/soc/au1x/Kconfig"
source "sound/soc/blackfin/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 197b6ae5..af5c265c 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -10,6 +10,7 @@ snd-soc-core-objs += soc-generic-dmaengine-pcm.o
endif
obj-$(CONFIG_SND_SOC) += snd-soc-core.o
+obj-$(CONFIG_SND_SOC) += ambarella/
obj-$(CONFIG_SND_SOC) += codecs/
obj-$(CONFIG_SND_SOC) += generic/
obj-$(CONFIG_SND_SOC) += atmel/
diff --git a/sound/soc/ambarella/Kconfig b/sound/soc/ambarella/Kconfig
new file mode 100644
index 00000000..85fc1a68
--- /dev/null
+++ b/sound/soc/ambarella/Kconfig
@@ -0,0 +1,109 @@
+config SND_AMBARELLA_SOC
+ tristate "SoC Audio for the Ambarella chips"
+ depends on PLAT_AMBARELLA && SND_SOC
+ select SND_SOC_GENERIC_DMAENGINE_PCM
+ help
+ Say Y or M if you want to add support for codecs attached to
+ the AMBARELLA I2S interface. You will also need
+ to select the audio interfaces to support below.
+
+config SND_AMBARELLA_SOC_I2S
+ tristate
+
+menuconfig SND_AMBARELLA_BOARD
+ tristate "Ambarella Board Type"
+ depends on SND_AMBARELLA_SOC
+ help
+ Say Y or M to select specific ambarella board.
+
+if SND_AMBARELLA_BOARD
+
+config AMBA_BOARD
+ tristate "Ambarella General Board"
+ depends on SND_AMBARELLA_SOC
+ select SND_AMBARELLA_SOC_I2S
+ select SND_SOC_AMBARELLA_DUMMY
+ help
+ Say Y if you want to use ALSA driver on Ambarella General Board.
+
+endif
+
+menuconfig SND_AMBARELLA_CODEC
+ tristate "Select Codec for Ambarella Platform"
+ depends on SND_AMBARELLA_SOC
+ help
+ Say Y or M to select specific Codec for Ambarella Platform.
+
+if SND_AMBARELLA_CODEC
+
+config SND_SOC_AK4642_AMB
+ tristate "AK4642 for Ambarella Platform"
+ help
+ Support AK4642 for Ambarella Platform.
+
+config SND_SOC_AK4951_AMB
+ tristate "AK4951 for Ambarella Platform"
+ help
+ Support AK4951 for Ambarella Platform.
+
+config SND_SOC_AK4954_AMB
+ tristate "AK4954 for Ambarella Platform"
+ help
+ Support AK4951 for Ambarella Platform.
+
+config SND_SOC_AK7719_DSP
+ tristate "AK7719_DSP for Ambarella Platform"
+ depends on SND_AMBARELLA_SOC && (SND_SOC_AK4954_AMB || SND_SOC_AK4951_AMB)
+ help
+ Say Y if you want to add AK7719 DSP support for
+ SoC audio on Ambarella Board.
+ and the AK7719_DSP should be modprobed before AK4954/AK4951.
+
+config SND_SOC_AK7755
+ tristate "AK7755 for Ambarella Platform"
+ help
+ Support AK7755 for Ambarella Platform.
+
+config SND_SOC_TLV320ADC3xxx
+ tristate "TLV320ADC3xxx for Ambarella Platform"
+ help
+ Support TLV320ADC3xxx for Ambarella Platform.
+
+config SND_SOC_ES8388
+ tristate "ES8388 for Ambarella Platform"
+ help
+ Support ES8388 Audio Codec for Ambarella Platform.
+
+config SND_SOC_ES8374
+ tristate "ES8374 for Ambarella Platform"
+ help
+ ES8374 Audio Codec for Ambarella Platform.
+
+config SND_SOC_WM8974_AMB
+ tristate "WM8974 for Ambarella Platform"
+ help
+ Support WM8974 Audio Codec for Ambarella Platform.
+
+config SND_SOC_WM8940_AMB
+ tristate "WM8940 for Ambarella Platform"
+ help
+ Support WM8940 Audio Codec for Ambarella Platform
+
+config SND_SOC_ZL380TW
+ tristate "ZL380XX for Ambarella Platform"
+ help
+ Support ZL380XX Audio Codec for Ambarella Platform
+
+config SND_SOC_RT5670
+ tristate "RT5670 for Ambarella Platform"
+ help
+ Support RT5670 Audio Codec for Ambarella Platform
+
+config SND_SOC_AMBARELLA_DUMMY
+ tristate "Dummy Codec for Ambarella Platform"
+ help
+ Support Dummy Codec for Ambarella Platform
+
+endif
+
+
diff --git a/sound/soc/ambarella/Makefile b/sound/soc/ambarella/Makefile
new file mode 100644
index 00000000..36528a58
--- /dev/null
+++ b/sound/soc/ambarella/Makefile
@@ -0,0 +1,11 @@
+# AMBARELLA Platform Support
+snd-soc-ambarella-objs := ambarella_pcm.o
+snd-soc-ambarella-i2s-objs := ambarella_i2s.o
+
+obj-$(CONFIG_SND_AMBARELLA_SOC) += snd-soc-ambarella.o
+obj-$(CONFIG_SND_AMBARELLA_SOC_I2S) += snd-soc-ambarella-i2s.o
+
+# AMBARELLA Machine Support
+snd-soc-amba-board-objs := ambarella_board.o
+
+obj-$(CONFIG_AMBA_BOARD) += snd-soc-amba-board.o
diff --git a/sound/soc/ambarella/ambarella_board.c b/sound/soc/ambarella/ambarella_board.c
new file mode 100644
index 00000000..e493e8b2
--- /dev/null
+++ b/sound/soc/ambarella/ambarella_board.c
@@ -0,0 +1,424 @@
+/*
+ * sound/soc/ambarella_board.c
+ *
+ * Author: XianqingZheng <xqzheng@ambarella.com>
+ *
+ * History:
+ * 2015/04/28 - [XianqingZheng] Created file
+ *
+ * Copyright (C) 2014-2018, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <plat/audio.h>
+#include <linux/slab.h>
+#include <sound/pcm_params.h>
+
+static int fast_boot = 0;
+module_param(fast_boot, uint, 0664);
+
+static unsigned int dai_fmt;
+module_param(dai_fmt, uint, 0644);
+MODULE_PARM_DESC(dai_fmt, "DAI format.");
+/* clk_fmt :
+* 0 : mclk, bclk provided by cpu
+* 1 : bclk provide by cpu, mclk is not used
+* 2 : mclk provided by cpu, bclk is provided by codec
+* There are four type of connection:
+* clk_fmt=0:
+* cpu : codec:
+* MCLK ------> MCKI
+* BCLK ------> BICK
+* LRCK ------> LRCK
+* ...
+* clk_fmt=1:
+* cpu : codec:
+* MCLK is not used
+* BCLK ------> BICK
+* LRCK ------> LRCK
+* ...
+* clk_fmt=2:
+* cpu : codec:
+* MCLK ------> MCKI
+* BCLK <------ BICK
+* LRCK <------ LRCK
+* There are one connection we are not used, it is like clk_fmt=0,but power on the codec PLL.
+* It is a waster of power, so we do not use it.
+*/
+static unsigned int dummy_dai_fmt;
+module_param(dummy_dai_fmt, uint, 0644);
+
+static unsigned int clk_fmt;
+module_param(clk_fmt, uint, 0664);
+
+struct amb_clk {
+ int mclk;
+ int i2s_div;
+ int bclk;
+};
+
+static int amba_clk_config(struct snd_pcm_hw_params *params, struct amb_clk *clk)
+{
+ u32 channels, sample_bits, rate;
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ case SNDRV_PCM_FORMAT_S32_LE:
+ sample_bits = 32;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ sample_bits = 16;
+ break;
+ }
+
+ channels = params_channels(params);
+ rate = params_rate(params);
+
+ clk->mclk = 12288000;
+ clk->bclk = channels * rate * sample_bits;
+
+ clk->i2s_div = (clk->mclk / ( 2 * clk->bclk)) - 1;
+
+ return 0;
+}
+
+static int amba_general_board_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int rval = 0;
+ int i2s_mode;
+ struct amb_clk clk={0};
+
+ rval = amba_clk_config(params, &clk);
+ if (rval < 0) {
+ pr_err("amba can not support the sample rate\n");
+ goto hw_params_exit;
+ }
+
+ if (dai_fmt == 0)
+ i2s_mode = SND_SOC_DAIFMT_I2S;
+ else
+ i2s_mode = SND_SOC_DAIFMT_DSP_A;
+
+ /* set the I2S system data format*/
+ if (clk_fmt == 2) {
+ rval = snd_soc_dai_set_fmt(codec_dai,
+ i2s_mode | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
+ if (rval < 0) {
+ pr_err("can't set codec DAI configuration\n");
+ goto hw_params_exit;
+ }
+
+ rval = snd_soc_dai_set_fmt(cpu_dai,
+ i2s_mode | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
+ if (rval < 0) {
+ pr_err("can't set cpu DAI configuration\n");
+ goto hw_params_exit;
+ }
+ } else {
+
+ rval = snd_soc_dai_set_fmt(codec_dai,
+ i2s_mode | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+ if (rval < 0) {
+ pr_err("can't set codec DAI configuration\n");
+ goto hw_params_exit;
+ }
+
+ rval = snd_soc_dai_set_fmt(cpu_dai,
+ i2s_mode | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+ if (rval < 0) {
+ pr_err("can't set cpu DAI configuration\n");
+ goto hw_params_exit;
+ }
+ }
+
+ /* set the I2S system clock*/
+ switch(clk_fmt) {
+ case 0:
+ rval = snd_soc_dai_set_sysclk(codec_dai, clk_fmt, clk.mclk, 0);
+ break;
+ case 1:
+ rval = snd_soc_dai_set_sysclk(codec_dai, clk_fmt, clk.bclk, 0);
+ break;
+ case 2:
+ rval = snd_soc_dai_set_sysclk(codec_dai, clk_fmt, clk.mclk, 0);
+ break;
+ default:
+ pr_err("clk_fmt is wrong, just 0, 1, 2 is available!\n");
+ goto hw_params_exit;
+ }
+
+ if (rval < 0) {
+ pr_err("can't set codec MCLK configuration\n");
+ goto hw_params_exit;
+ }
+
+
+ rval = snd_soc_dai_set_sysclk(cpu_dai, AMBARELLA_CLKSRC_ONCHIP, clk.mclk, 0);
+ if (rval < 0) {
+ pr_err("can't set cpu MCLK configuration\n");
+ goto hw_params_exit;
+ }
+
+ rval = snd_soc_dai_set_clkdiv(cpu_dai, AMBARELLA_CLKDIV_LRCLK, clk.i2s_div);
+ if (rval < 0) {
+ pr_err("can't set cpu MCLK/SF ratio\n");
+ goto hw_params_exit;
+ }
+
+hw_params_exit:
+ return rval;
+}
+
+static int amba_dummy_board_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int i2s_mode, rval = 0;
+ struct amb_clk clk={0};
+
+ if (fast_boot)
+ return 0;
+ rval = amba_clk_config(params, &clk);
+ if (rval < 0) {
+ pr_err("amba can not support the sample rate\n");
+ goto hw_params_exit;
+ }
+
+ if (dummy_dai_fmt == 0)
+ i2s_mode = SND_SOC_DAIFMT_I2S;
+ else
+ i2s_mode = SND_SOC_DAIFMT_DSP_A;
+
+ /* set the I2S system data format*/
+ if(clk_fmt == 2) {
+ rval = snd_soc_dai_set_fmt(cpu_dai,
+ i2s_mode | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
+ } else {
+ rval = snd_soc_dai_set_fmt(cpu_dai,
+ i2s_mode | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+ }
+
+ if (rval < 0) {
+ printk(KERN_ERR "can't set cpu DAI configuration\n");
+ goto hw_params_exit;
+ }
+
+ /* set the I2S system clock*/
+ rval = snd_soc_dai_set_sysclk(cpu_dai, AMBARELLA_CLKSRC_ONCHIP, clk.mclk, 0);
+ if (rval < 0) {
+ printk(KERN_ERR "can't set cpu MCLK configuration\n");
+ goto hw_params_exit;
+ }
+
+ rval = snd_soc_dai_set_clkdiv(cpu_dai, AMBARELLA_CLKDIV_LRCLK, clk.i2s_div);
+ if (rval < 0) {
+ printk(KERN_ERR "can't set cpu MCLK/SF ratio\n");
+ goto hw_params_exit;
+ }
+
+hw_params_exit:
+ return rval;
+}
+
+static struct snd_soc_ops amba_general_board_ops = {
+ .hw_params = amba_general_board_hw_params,
+};
+
+static struct snd_soc_ops amba_dummy_board_ops = {
+ .hw_params = amba_dummy_board_hw_params,
+};
+
+/* ambevk machine dapm widgets */
+static const struct snd_soc_dapm_widget amba_dapm_widgets[] = {
+ SND_SOC_DAPM_MIC("Mic internal", NULL),
+ SND_SOC_DAPM_MIC("Mic external", NULL),
+ SND_SOC_DAPM_LINE("Line In", NULL),
+ SND_SOC_DAPM_LINE("Line Out", NULL),
+ SND_SOC_DAPM_HP("HP Jack", NULL),
+ SND_SOC_DAPM_SPK("Speaker", NULL),
+};
+
+static int amba_codec_init(struct snd_soc_pcm_runtime *rtd)
+{
+ return 0;
+}
+
+/* ambevk audio machine driver */
+static struct snd_soc_card snd_soc_card_amba = {
+ .owner = THIS_MODULE,
+ .dapm_widgets = amba_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(amba_dapm_widgets),
+};
+
+static int amba_soc_snd_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *cpup_np, *codec_np, *dummy_codec_np;
+ struct snd_soc_dai_link *amba_dai_link;
+ struct snd_soc_card *card = &snd_soc_card_amba;
+ int rval = 0;
+
+ card->dev = &pdev->dev;
+
+ if (snd_soc_of_parse_card_name(card, "amb,model")) {
+ dev_err(&pdev->dev, "Card name is not provided\n");
+ return -ENODEV;
+ }
+
+ cpup_np = of_parse_phandle(np, "amb,i2s-controllers", 0);
+ if (fast_boot)
+ codec_np = NULL;
+ else
+ codec_np = of_parse_phandle(np, "amb,audio-codec", 0);
+ dummy_codec_np = of_parse_phandle(np, "amb,dummy-codec", 0);
+ if (!cpup_np || !dummy_codec_np) {
+ dev_err(&pdev->dev, "phandle missing or invalid\n");
+ return -EINVAL;
+ }
+
+ if(codec_np) {
+ rval = snd_soc_of_parse_audio_routing(card,
+ "amb,audio-routing");
+ if(rval) {
+ dev_err(&pdev->dev, "amb,audio-routing is not specified, please doube check\n");
+ }
+
+ /*alloc two amba_dai_link for audio codec and dummy codec*/
+ amba_dai_link = devm_kzalloc(&pdev->dev, 2 * sizeof(*amba_dai_link), GFP_KERNEL);
+ if (amba_dai_link == NULL) {
+ dev_err(&pdev->dev, "alloc memory for amba_dai_link fail!\n");
+ return -ENOMEM;
+ }
+
+ amba_dai_link[0].codec_of_node = codec_np;
+ amba_dai_link[0].cpu_of_node = cpup_np;
+ amba_dai_link[0].platform_of_node = cpup_np;
+ amba_dai_link[0].init = amba_codec_init;
+ amba_dai_link[0].ops = &amba_general_board_ops;
+
+ amba_dai_link[1].codec_of_node = dummy_codec_np;
+ amba_dai_link[1].cpu_of_node = cpup_np;
+ amba_dai_link[1].platform_of_node = cpup_np;
+ amba_dai_link[1].init = amba_codec_init;
+ amba_dai_link[1].ops = &amba_dummy_board_ops;
+
+ card->dai_link = amba_dai_link;
+ card->num_links = 2;
+
+ /*get parameter from code_np to fill struct snd_soc_dai_link*/
+ rval = of_property_read_string_index(np, "amb,codec-name", 0, &card->dai_link[0].name);
+ if(rval < 0) {
+ dev_err(&pdev->dev, "codec-name got from device tree is invalid\n");
+ return -EINVAL;
+ }
+
+ rval = of_property_read_string_index(np, "amb,stream-name", 0, &card->dai_link[0].stream_name);
+ if(rval < 0) {
+ dev_err(&pdev->dev, "stream-name got from device tree is invalid\n");
+ return -EINVAL;
+ }
+
+ rval = of_property_read_string_index(np, "amb,codec-dai-name", 0, &card->dai_link[0].codec_dai_name);
+ if(rval < 0) {
+ dev_err(&pdev->dev, "codec-dai-name got from device tree is invalid\n");
+ return -EINVAL;
+ }
+
+ card->dai_link[1].name = "AMB-DUMMY";
+ card->dai_link[1].stream_name = "AMB-DUMMY-STREAM";
+ card->dai_link[1].codec_dai_name = "AMBARELLA_DUMMY_CODEC";
+
+ } else {
+ /*alloc only one amba_dai_link for dummy codec*/
+ amba_dai_link = devm_kzalloc(&pdev->dev, sizeof(*amba_dai_link), GFP_KERNEL);
+ if (amba_dai_link == NULL) {
+ dev_err(&pdev->dev, "alloc memory for amba_dai_link fail!\n");
+ return -ENOMEM;
+ }
+
+ amba_dai_link[0].codec_of_node = dummy_codec_np;
+ amba_dai_link[0].cpu_of_node = cpup_np;
+ amba_dai_link[0].platform_of_node = cpup_np;
+ amba_dai_link[0].init = amba_codec_init;
+ amba_dai_link[0].ops = &amba_dummy_board_ops;
+ card->dai_link = amba_dai_link;
+ card->num_links = 1;
+ card->dai_link[0].name = "AMB-DUMMY";
+ card->dai_link[0].stream_name = "AMB-DUMMY-STREAM";
+ card->dai_link[0].codec_dai_name = "AMBARELLA_DUMMY_CODEC";
+ }
+
+ of_node_put(codec_np);
+ of_node_put(cpup_np);
+ of_node_put(dummy_codec_np);
+
+ /*get dai_fmt and clk_fmt from device tree*/
+ of_property_read_u32(np, "amb,dai_fmt", &dai_fmt);
+ of_property_read_u32(np, "amb,dummy_dai_fmt", &dummy_dai_fmt);
+ of_property_read_u32(np, "amb,clk_fmt", &clk_fmt);
+
+ rval = snd_soc_register_card(card);
+ if (rval)
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", rval);
+
+ return rval;
+}
+
+static int amba_soc_snd_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_card(&snd_soc_card_amba);
+ if(snd_soc_card_amba.dapm_routes != NULL)
+ kfree(snd_soc_card_amba.dapm_routes);
+
+ return 0;
+}
+
+static const struct of_device_id amba_dt_ids[] = {
+ { .compatible = "ambarella,audio-board", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, amba_dt_ids);
+
+static struct platform_driver amba_soc_snd_driver = {
+ .driver = {
+ .name = "snd_soc_card_amba",
+ .owner = THIS_MODULE,
+ .pm = &snd_soc_pm_ops,
+ .of_match_table = amba_dt_ids,
+ },
+ .probe = amba_soc_snd_probe,
+ .remove = amba_soc_snd_remove,
+};
+
+module_platform_driver(amba_soc_snd_driver);
+
+MODULE_AUTHOR("XianqingZheng<xqzheng@ambarella.com>");
+MODULE_DESCRIPTION("Amabrella Board for ALSA");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("snd-soc-amba");
+
diff --git a/sound/soc/ambarella/ambarella_i2s.c b/sound/soc/ambarella/ambarella_i2s.c
new file mode 100644
index 00000000..8d28e81f
--- /dev/null
+++ b/sound/soc/ambarella/ambarella_i2s.c
@@ -0,0 +1,602 @@
+/*
+ * sound/soc/ambarella_i2s.c
+ *
+ * History:
+ * 2008/03/03 - [Eric Lee] created file
+ * 2008/04/16 - [Eric Lee] Removed the compiling warning
+ * 2009/01/22 - [Anthony Ginger] Port to 2.6.28
+ * 2009/03/05 - [Cao Rongrong] Update from 2.6.22.10
+ * 2009/06/10 - [Cao Rongrong] Port to 2.6.29
+ * 2009/06/29 - [Cao Rongrong] Support more mclk and fs
+ * 2010/10/25 - [Cao Rongrong] Port to 2.6.36+
+ * 2011/03/20 - [Cao Rongrong] Port to 2.6.38
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/pinctrl/consumer.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/dmaengine_pcm.h>
+#include <plat/dma.h>
+#include <plat/audio.h>
+#include "ambarella_pcm.h"
+#include "ambarella_i2s.h"
+
+static unsigned int capture_enabled = 1;
+module_param(capture_enabled, uint, 0644);
+MODULE_PARM_DESC(capture_enabled, "capture_enabled.");
+
+static unsigned int bclk_reverse = 0;
+module_param(bclk_reverse, uint, 0644);
+MODULE_PARM_DESC(bclk_reverse, "bclk_reverse.");
+
+static DEFINE_MUTEX(clock_reg_mutex);
+
+static inline void dai_tx_enable(void)
+{
+ amba_setbitsl(I2S_INIT_REG, I2S_TX_ENABLE_BIT);
+}
+
+static inline void dai_rx_enable(void)
+{
+ amba_setbitsl(I2S_INIT_REG, I2S_RX_ENABLE_BIT);
+}
+
+static inline void dai_tx_disable(void)
+{
+ amba_clrbitsl(I2S_INIT_REG, I2S_TX_ENABLE_BIT);
+}
+
+static inline void dai_rx_disable(void)
+{
+ if(capture_enabled)
+ amba_clrbitsl(I2S_INIT_REG, I2S_RX_ENABLE_BIT);
+}
+
+static inline void dai_tx_fifo_rst(void)
+{
+ amba_setbitsl(I2S_INIT_REG, I2S_TX_FIFO_RESET_BIT);
+}
+
+static inline void dai_rx_fifo_rst(void)
+{
+ if(capture_enabled)
+ amba_setbitsl(I2S_INIT_REG, I2S_RX_FIFO_RESET_BIT);
+}
+
+static inline void dai_fifo_rst(void)
+{
+ if(capture_enabled)
+ amba_setbitsl(I2S_INIT_REG, I2S_FIFO_RESET_BIT);
+}
+
+static int ambarella_i2s_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ if(substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+ dai_rx_disable();
+ dai_rx_fifo_rst();
+ } else {
+ dai_tx_disable();
+ dai_tx_fifo_rst();
+ }
+ return 0;
+}
+
+static int ambarella_i2s_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ int ret = 0;
+
+ /* Add a rule to enforce the DMA buffer align. */
+ ret = snd_pcm_hw_constraint_step(runtime, 0,
+ SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
+ if (ret)
+ goto ambarella_i2s_startup_exit;
+
+ ret = snd_pcm_hw_constraint_step(runtime, 0,
+ SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32);
+ if (ret)
+ goto ambarella_i2s_startup_exit;
+
+ ret = snd_pcm_hw_constraint_integer(runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (ret < 0)
+ goto ambarella_i2s_startup_exit;
+
+ return 0;
+ambarella_i2s_startup_exit:
+ return ret;
+}
+
+static int ambarella_i2s_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *cpu_dai)
+{
+ struct amb_i2s_priv *priv_data = snd_soc_dai_get_drvdata(cpu_dai);
+ struct ambarella_i2s_interface *i2s_intf = &priv_data->amb_i2s_intf;
+ u32 clock_reg;
+
+ if( capture_enabled == 0)
+ return 0;
+
+ /* Disable tx/rx before initializing */
+ dai_tx_disable();
+ dai_rx_disable();
+
+ i2s_intf->sfreq = params_rate(params);
+ i2s_intf->channels = params_channels(params);
+ amba_writel(I2S_REG(I2S_CHANNEL_SELECT_OFFSET), i2s_intf->channels / 2 - 1);
+
+ /* Set format */
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ i2s_intf->multi24 = 0;
+ i2s_intf->tx_ctrl = I2S_TX_UNISON_BIT;
+ i2s_intf->word_len = 15;
+ if (i2s_intf->mode == I2S_DSP_MODE) {
+ i2s_intf->slots = i2s_intf->channels - 1;
+ i2s_intf->word_pos = 15;
+ } else {
+ i2s_intf->slots = 0;
+ i2s_intf->word_pos = 0;
+ }
+ priv_data->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+ break;
+
+ case SNDRV_PCM_FORMAT_S24_LE: /* 32 bits, valie data in low 3 bytes. */
+ i2s_intf->multi24 = I2S_24BITMUX_MODE_ENABLE;
+ i2s_intf->tx_ctrl = 0;
+ i2s_intf->word_len = 23;
+ if (i2s_intf->mode == I2S_DSP_MODE) {
+ i2s_intf->slots = i2s_intf->channels - 1;
+ i2s_intf->word_pos = 0; /* ignored */
+ } else {
+ i2s_intf->slots = 0;
+ i2s_intf->word_pos = 0; /* ignored */
+ }
+ priv_data->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ break;
+
+ case SNDRV_PCM_FORMAT_S32_LE:
+ i2s_intf->multi24 = I2S_24BITMUX_MODE_ENABLE;
+ i2s_intf->tx_ctrl = 0;
+ i2s_intf->word_len = 31;
+ if (i2s_intf->mode == I2S_DSP_MODE) {
+ i2s_intf->slots = i2s_intf->channels - 1;
+ i2s_intf->word_pos = 0; /* ignored */
+ } else {
+ i2s_intf->slots = 0;
+ i2s_intf->word_pos = 0; /* ignored */
+ }
+ priv_data->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ break;
+
+ default:
+ goto hw_params_exit;
+ }
+
+ if (priv_data->dai_master == true) {
+ i2s_intf->tx_ctrl |= I2S_TX_WS_MST_BIT;
+ i2s_intf->rx_ctrl |= I2S_RX_WS_MST_BIT;
+ } else {
+ i2s_intf->tx_ctrl &= ~I2S_TX_WS_MST_BIT;
+ i2s_intf->rx_ctrl &= ~I2S_RX_WS_MST_BIT;
+ }
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ amba_writel(I2S_TX_CTRL_REG, i2s_intf->tx_ctrl);
+ amba_writel(I2S_TX_FIFO_LTH_REG, 0x10);
+ } else {
+ amba_writel(I2S_RX_CTRL_REG, i2s_intf->rx_ctrl);
+ amba_writel(I2S_RX_FIFO_GTH_REG, 0x20);
+ }
+
+ amba_writel(I2S_MODE_REG, i2s_intf->mode);
+ amba_writel(I2S_WLEN_REG, i2s_intf->word_len);
+ amba_writel(I2S_WPOS_REG, i2s_intf->word_pos);
+ amba_writel(I2S_SLOT_REG, i2s_intf->slots);
+ amba_writel(I2S_24BITMUX_MODE_REG, i2s_intf->multi24);
+
+ /* Set clock */
+ clk_set_rate(priv_data->mclk, i2s_intf->mclk);
+
+ mutex_lock(&clock_reg_mutex);
+
+ clock_reg = amba_readl(I2S_CLOCK_REG);
+ clock_reg &= ~DAI_CLOCK_MASK;
+ clock_reg |= i2s_intf->div;
+
+ if (priv_data->dai_master == true)
+ clock_reg |= I2S_CLK_MASTER_MODE;
+ else
+ clock_reg &= ~I2S_CLK_MASTER_MODE;
+
+ if (bclk_reverse)
+ clock_reg &= ~I2S_CLK_TX_PO_FALL;
+ else
+ clock_reg |= I2S_CLK_TX_PO_FALL;
+
+ amba_writel(I2S_CLOCK_REG, clock_reg);
+
+ mutex_unlock(&clock_reg_mutex);
+
+ dai_rx_enable();
+ dai_tx_enable();
+
+ msleep(1);
+
+ /* Notify HDMI that the audio interface is changed */
+ ambarella_audio_notify_transition(&priv_data->amb_i2s_intf,
+ AUDIO_NOTIFY_SETHWPARAMS);
+ return 0;
+
+hw_params_exit:
+ dai_rx_enable();
+ dai_tx_enable();
+ return -EINVAL;
+}
+
+static int ambarella_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *cpu_dai)
+{
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ dai_tx_enable();
+ else
+ dai_rx_enable();
+ break;
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
+ dai_tx_disable();
+ dai_tx_fifo_rst();
+ }else{
+ dai_rx_disable();
+ dai_rx_fifo_rst();
+ }
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * Set Ambarella I2S DAI format
+ */
+static int ambarella_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
+ unsigned int fmt)
+{
+ struct amb_i2s_priv *priv_data = snd_soc_dai_get_drvdata(cpu_dai);
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_LEFT_J:
+ priv_data->amb_i2s_intf.mode = I2S_LEFT_JUSTIFIED_MODE;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ priv_data->amb_i2s_intf.mode = I2S_RIGHT_JUSTIFIED_MODE;
+ break;
+ case SND_SOC_DAIFMT_I2S:
+ priv_data->amb_i2s_intf.mode = I2S_I2S_MODE;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ priv_data->amb_i2s_intf.mode = I2S_DSP_MODE;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ priv_data->dai_master = true;
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+ if (priv_data->amb_i2s_intf.mode != I2S_I2S_MODE) {
+ printk("DAI can't work in slave mode without standard I2S format!\n");
+ return -EINVAL;
+ }
+ priv_data->dai_master = false;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int ambarella_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct amb_i2s_priv *priv_data = snd_soc_dai_get_drvdata(cpu_dai);
+
+ switch (clk_id) {
+ case AMBARELLA_CLKSRC_ONCHIP:
+ priv_data->amb_i2s_intf.clksrc = clk_id;
+ priv_data->amb_i2s_intf.mclk = freq;
+ break;
+
+ case AMBARELLA_CLKSRC_EXTERNAL:
+ default:
+ printk("CLK SOURCE (%d) is not supported yet\n", clk_id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int ambarella_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
+ int div_id, int div)
+{
+ struct amb_i2s_priv *priv_data = snd_soc_dai_get_drvdata(cpu_dai);
+
+ switch (div_id) {
+ case AMBARELLA_CLKDIV_LRCLK:
+ priv_data->amb_i2s_intf.div = div;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int ambarella_i2s_dai_suspend(struct snd_soc_dai *dai)
+{
+ struct amb_i2s_priv *priv_data = snd_soc_dai_get_drvdata(dai);
+ struct ambarella_i2s_interface *i2s_intf = &priv_data->amb_i2s_intf;
+
+ priv_data->clock_reg = amba_readl(I2S_CLOCK_REG);
+ i2s_intf->mode = amba_readl(I2S_MODE_REG);
+ i2s_intf->word_len = amba_readl(I2S_WLEN_REG);
+ i2s_intf->word_pos = amba_readl(I2S_WPOS_REG);
+ i2s_intf->slots = amba_readl(I2S_SLOT_REG);
+ i2s_intf->channels = amba_readl(I2S_REG(I2S_CHANNEL_SELECT_OFFSET));
+ i2s_intf->rx_ctrl = amba_readl(I2S_RX_CTRL_REG);
+ i2s_intf->tx_ctrl = amba_readl(I2S_TX_CTRL_REG);
+ i2s_intf->rx_fifo_len = amba_readl(I2S_RX_FIFO_GTH_REG);
+ i2s_intf->tx_fifo_len = amba_readl(I2S_TX_FIFO_LTH_REG);
+ i2s_intf->multi24 = amba_readl(I2S_24BITMUX_MODE_REG);
+
+ return 0;
+}
+
+static int ambarella_i2s_dai_resume(struct snd_soc_dai *dai)
+{
+ struct amb_i2s_priv *priv_data = snd_soc_dai_get_drvdata(dai);
+ struct ambarella_i2s_interface *i2s_intf = &priv_data->amb_i2s_intf;
+
+ amba_writel(I2S_MODE_REG, i2s_intf->mode);
+ amba_writel(I2S_WLEN_REG, i2s_intf->word_len);
+ amba_writel(I2S_WPOS_REG, i2s_intf->word_pos);
+ amba_writel(I2S_SLOT_REG, i2s_intf->slots);
+ amba_writel(I2S_REG(I2S_CHANNEL_SELECT_OFFSET), i2s_intf->channels);
+ amba_writel(I2S_RX_CTRL_REG, i2s_intf->rx_ctrl);
+ amba_writel(I2S_TX_CTRL_REG, i2s_intf->tx_ctrl);
+ amba_writel(I2S_RX_FIFO_GTH_REG, i2s_intf->rx_fifo_len);
+ amba_writel(I2S_TX_FIFO_LTH_REG, i2s_intf->tx_fifo_len);
+ amba_writel(I2S_24BITMUX_MODE_REG,i2s_intf->multi24);
+ amba_writel(I2S_CLOCK_REG, priv_data->clock_reg);
+
+ return 0;
+}
+#else /* CONFIG_PM */
+#define ambarella_i2s_dai_suspend NULL
+#define ambarella_i2s_dai_resume NULL
+#endif /* CONFIG_PM */
+
+static int ambarella_i2s_dai_probe(struct snd_soc_dai *dai)
+{
+ u32 sfreq, clk_div = 3;
+ struct amb_i2s_priv *priv_data = snd_soc_dai_get_drvdata(dai);
+ struct ambarella_i2s_interface *i2s_intf = &priv_data->amb_i2s_intf;
+
+ dai->capture_dma_data = &priv_data->capture_dma_data;
+ dai->playback_dma_data = &priv_data->playback_dma_data;
+
+ if (priv_data->default_mclk == 12288000) {
+ sfreq = 48000;
+ } else if (priv_data->default_mclk == 11289600){
+ sfreq = 44100;
+ } else {
+ priv_data->default_mclk = 12288000;
+ sfreq = 48000;
+ }
+
+ clk_set_rate(priv_data->mclk, priv_data->default_mclk);
+
+ /*
+ * Dai default smapling rate, polarity configuration.
+ * Note: Just be configured, actually BCLK and LRCLK will not
+ * output to outside at this time.
+ */
+ if(capture_enabled)
+ amba_writel(I2S_CLOCK_REG, clk_div | I2S_CLK_TX_PO_FALL);
+
+ priv_data->dai_master = true;
+ i2s_intf->mode = I2S_I2S_MODE;
+ i2s_intf->clksrc = AMBARELLA_CLKSRC_ONCHIP;
+ i2s_intf->mclk = priv_data->default_mclk;
+ i2s_intf->div = clk_div;
+ i2s_intf->sfreq = sfreq;
+ i2s_intf->word_len = 15;
+ i2s_intf->word_pos = 0;
+ i2s_intf->slots = 0;
+ i2s_intf->channels = 2;
+
+ /* reset fifo */
+ dai_tx_enable();
+ dai_rx_enable();
+ dai_fifo_rst();
+
+ /* Notify HDMI that the audio interface is initialized */
+ ambarella_audio_notify_transition(&priv_data->amb_i2s_intf, AUDIO_NOTIFY_INIT);
+
+ return 0;
+}
+
+static int ambarella_i2s_dai_remove(struct snd_soc_dai *dai)
+{
+ struct amb_i2s_priv *priv_data = snd_soc_dai_get_drvdata(dai);
+
+ /* Disable I2S clock output */
+ amba_writel(I2S_CLOCK_REG, 0x0);
+
+ /* Notify that the audio interface is removed */
+ ambarella_audio_notify_transition(&priv_data->amb_i2s_intf,
+ AUDIO_NOTIFY_REMOVE);
+
+ return 0;
+}
+
+static const struct snd_soc_dai_ops ambarella_i2s_dai_ops = {
+ .prepare = ambarella_i2s_prepare,
+ .startup = ambarella_i2s_startup,
+ .hw_params = ambarella_i2s_hw_params,
+ .trigger = ambarella_i2s_trigger,
+ .set_fmt = ambarella_i2s_set_fmt,
+ .set_sysclk = ambarella_i2s_set_sysclk,
+ .set_clkdiv = ambarella_i2s_set_clkdiv,
+};
+
+static struct snd_soc_dai_driver ambarella_i2s_dai = {
+ .probe = ambarella_i2s_dai_probe,
+ .remove = ambarella_i2s_dai_remove,
+ .suspend = ambarella_i2s_dai_suspend,
+ .resume = ambarella_i2s_dai_resume,
+ .playback = {
+ .channels_min = 2,
+ .channels_max = 0, // initialized in ambarella_i2s_probe function
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE),
+ },
+ .capture = {
+ .channels_min = 2,
+ .channels_max = 0, // initialized in ambarella_i2s_probe function
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE),
+ },
+ .ops = &ambarella_i2s_dai_ops,
+ .symmetric_rates = 1,
+};
+
+static const struct snd_soc_component_driver ambarella_i2s_component = {
+ .name = "ambarella-i2s",
+};
+
+static int ambarella_i2s_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct amb_i2s_priv *priv_data;
+ struct pinctrl *pinctrl;
+ int channels, rval;
+
+ priv_data = devm_kzalloc(&pdev->dev, sizeof(*priv_data), GFP_KERNEL);
+ if (priv_data == NULL)
+ return -ENOMEM;
+
+ priv_data->playback_dma_data.addr = I2S_TX_LEFT_DATA_DMA_REG;
+ priv_data->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ priv_data->playback_dma_data.maxburst = 32;
+
+ priv_data->capture_dma_data.addr = I2S_RX_DATA_DMA_REG;
+ priv_data->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+ priv_data->capture_dma_data.maxburst = 32;
+ priv_data->mclk = clk_get(&pdev->dev, "gclk_audio");
+ if (IS_ERR(priv_data->mclk)) {
+ dev_err(&pdev->dev, "Get audio clk failed!\n");
+ return PTR_ERR(priv_data->mclk);
+ }
+
+ dev_set_drvdata(&pdev->dev, priv_data);
+
+ rval = of_property_read_u32(np, "amb,i2s-channels", &channels);
+ if (rval < 0) {
+ dev_err(&pdev->dev, "Get channels failed! %d\n", rval);
+ return -ENXIO;
+ }
+
+ of_property_read_u32(np, "amb,default-mclk", &priv_data->default_mclk);
+
+ ambarella_i2s_dai.playback.channels_max = channels;
+ ambarella_i2s_dai.capture.channels_max = channels;
+
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+ if (IS_ERR(pinctrl))
+ return PTR_ERR(pinctrl);
+
+ rval = snd_soc_register_component(&pdev->dev,
+ &ambarella_i2s_component, &ambarella_i2s_dai, 1);
+ if (rval < 0){
+ dev_err(&pdev->dev, "register DAI failed\n");
+ return rval;
+ }
+
+ rval = ambarella_pcm_platform_register(&pdev->dev);
+ if (rval) {
+ dev_err(&pdev->dev, "register PCM failed: %d\n", rval);
+ snd_soc_unregister_component(&pdev->dev);
+ return rval;
+ }
+
+ return 0;
+}
+
+static int ambarella_i2s_remove(struct platform_device *pdev)
+{
+ ambarella_pcm_platform_unregister(&pdev->dev);
+ snd_soc_unregister_component(&pdev->dev);
+
+ return 0;
+}
+
+static const struct of_device_id ambarella_i2s_dt_ids[] = {
+ { .compatible = "ambarella,i2s", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, ambarella_i2s_dt_ids);
+
+static struct platform_driver ambarella_i2s_driver = {
+ .probe = ambarella_i2s_probe,
+ .remove = ambarella_i2s_remove,
+
+ .driver = {
+ .name = "ambarella-i2s",
+ .owner = THIS_MODULE,
+ .of_match_table = ambarella_i2s_dt_ids,
+ },
+};
+
+module_platform_driver(ambarella_i2s_driver);
+
+MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
+MODULE_DESCRIPTION("Ambarella Soc I2S Interface");
+
+MODULE_LICENSE("GPL");
+
diff --git a/sound/soc/ambarella/ambarella_i2s.h b/sound/soc/ambarella/ambarella_i2s.h
new file mode 100644
index 00000000..9fa8e3b1
--- /dev/null
+++ b/sound/soc/ambarella/ambarella_i2s.h
@@ -0,0 +1,45 @@
+/*
+ * sound/soc/ambarella_i2s.h
+ *
+ * History:
+ * 2008/03/03 - [Eric Lee] created file
+ * 2008/04/16 - [Eric Lee] Removed the compiling warning
+ * 2009/01/22 - [Anthony Ginger] Port to 2.6.28
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef AMBARELLA_I2S_H_
+#define AMBARELLA_I2S_H_
+
+struct amb_i2s_priv {
+ struct clk *mclk;
+ bool dai_master;
+ u32 default_mclk;
+ u32 clock_reg;
+ u32 bclk_reverse;
+ struct ambarella_i2s_interface amb_i2s_intf;
+
+ struct snd_dmaengine_dai_dma_data playback_dma_data;
+ struct snd_dmaengine_dai_dma_data capture_dma_data;
+};
+
+int ambarella_i2s_add_controls(struct snd_soc_codec *codec);
+
+#endif /*AMBARELLA_I2S_H_*/
+
diff --git a/sound/soc/ambarella/ambarella_pcm.c b/sound/soc/ambarella/ambarella_pcm.c
new file mode 100644
index 00000000..8ffcd0ab
--- /dev/null
+++ b/sound/soc/ambarella/ambarella_pcm.c
@@ -0,0 +1,99 @@
+/*
+ * sound/soc/ambarella_pcm.c
+ *
+ * History:
+ * 2008/03/03 - [Eric Lee] created file
+ * 2008/04/16 - [Eric Lee] Removed the compiling warning
+ * 2008/08/07 - [Cao Rongrong] Fix the buffer bug,eg: size and allocation
+ * 2008/11/14 - [Cao Rongrong] Support pause and resume
+ * 2009/01/22 - [Anthony Ginger] Port to 2.6.28
+ * 2009/03/05 - [Cao Rongrong] Update from 2.6.22.10
+ * 2009/06/10 - [Cao Rongrong] Port to 2.6.29
+ * 2009/06/30 - [Cao Rongrong] Fix last_desc bug
+ * 2010/10/25 - [Cao Rongrong] Port to 2.6.36+
+ * 2011/03/20 - [Cao Rongrong] Port to 2.6.38
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/dmaengine_pcm.h>
+#include <plat/dma.h>
+
+
+#define AMBA_MAX_DESC_NUM 128
+#define AMBA_MIN_DESC_NUM 2
+#define AMBA_PERIOD_BYTES_MAX (128 * 1024)
+#define AMBA_PERIOD_BYTES_MIN 32
+#define AMBA_BUFFER_BYTES_MAX (256 * 1024)
+
+/*
+ * Note that we specify SNDRV_PCM_INFO_JOINT_DUPLEX here, but only because a
+ * limitation in the I2S driver requires the sample rates for playback and
+ * capture to be the same.
+ */
+static const struct snd_pcm_hardware ambarella_pcm_hardware = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE |
+ SNDRV_PCM_INFO_RESUME |
+ SNDRV_PCM_INFO_BATCH |
+ SNDRV_PCM_INFO_JOINT_DUPLEX,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ .period_bytes_min = AMBA_PERIOD_BYTES_MIN,
+ .period_bytes_max = AMBA_PERIOD_BYTES_MAX,
+ .periods_min = AMBA_MIN_DESC_NUM,
+ .periods_max = AMBA_MAX_DESC_NUM,
+ .buffer_bytes_max = AMBA_BUFFER_BYTES_MAX,
+};
+
+
+static const struct snd_dmaengine_pcm_config ambarella_dmaengine_pcm_config = {
+ .pcm_hardware = &ambarella_pcm_hardware,
+ .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
+ .prealloc_buffer_size = AMBA_BUFFER_BYTES_MAX,
+};
+
+int ambarella_pcm_platform_register(struct device *dev)
+{
+ return snd_dmaengine_pcm_register(dev, &ambarella_dmaengine_pcm_config,
+ SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
+ SND_DMAENGINE_PCM_FLAG_COMPAT);
+}
+EXPORT_SYMBOL_GPL(ambarella_pcm_platform_register);
+
+void ambarella_pcm_platform_unregister(struct device *dev)
+{
+ snd_dmaengine_pcm_unregister(dev);
+}
+EXPORT_SYMBOL_GPL(ambarella_pcm_platform_unregister);
+
+
+MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
+MODULE_DESCRIPTION("Ambarella Soc PCM DMA module");
+MODULE_LICENSE("GPL");
+
diff --git a/sound/soc/ambarella/ambarella_pcm.h b/sound/soc/ambarella/ambarella_pcm.h
new file mode 100644
index 00000000..1a3d7de0
--- /dev/null
+++ b/sound/soc/ambarella/ambarella_pcm.h
@@ -0,0 +1,36 @@
+/*
+ * sound/soc/ambarella_pcm.h
+ *
+ * History:
+ * 2008/03/03 - [Eric Lee] created file
+ * 2008/04/16 - [Eric Lee] Removed the compiling warning
+ * 2008/08/07 - [Cao Rongrong] Fix the buffer bug,eg: size and allocation
+ * 2008/11/14 - [Cao Rongrong] Support pause and resume
+ * 2009/01/22 - [Anthony Ginger] Port to 2.6.28
+ *
+ * Copyright (C) 2004-2009, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef _AMBARELLA_PCM_H
+#define _AMBARELLA_PCM_H
+
+int ambarella_pcm_platform_register(struct device *dev);
+void ambarella_pcm_platform_unregister(struct device *dev);
+
+#endif /* _AMBARELLA_PCM_H */
+
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 2f45f00e..f318c6b0 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -21,12 +21,19 @@ config SND_SOC_ALL_CODECS
select SND_SOC_ADAU1373 if I2C
select SND_SOC_ADAV80X
select SND_SOC_ADS117X
+ select SND_SOC_AMBARELLA_DUMMY
select SND_SOC_AK4104 if SPI_MASTER
select SND_SOC_AK4535 if I2C
select SND_SOC_AK4641 if I2C
select SND_SOC_AK4642 if I2C
+ select SND_SOC_AK4642_AMB if I2C
select SND_SOC_AK4671 if I2C
select SND_SOC_AK5386
+ select SND_SOC_AK4951_AMB if I2C
+ select SND_SOC_AK4954_AMB if I2C
+ select SND_SOC_WM8940_AMB if I2C
+ select SND_SOC_WM8974_AMB if I2C
+ select SND_SOC_AK7755 if SND_SOC_I2C_AND_SPI
select SND_SOC_ALC5623 if I2C
select SND_SOC_ALC5632 if I2C
select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
@@ -41,6 +48,9 @@ config SND_SOC_ALL_CODECS
select SND_SOC_DA732X if I2C
select SND_SOC_DA9055 if I2C
select SND_SOC_DFBMCS320
+ select SND_SOC_ES8328 if I2C
+ select SND_SOC_ES8374 if I2C
+ select SND_SOC_ES8388 if I2C
select SND_SOC_ISABELLE if I2C
select SND_SOC_JZ4740_CODEC
select SND_SOC_LM4857 if I2C
@@ -65,6 +75,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_STA529 if I2C
select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
select SND_SOC_TAS5086 if I2C
+ select SND_SOC_TLV320ADC3xxx if I2C
select SND_SOC_TLV320AIC23 if I2C
select SND_SOC_TLV320AIC26 if SPI_MASTER
select SND_SOC_TLV320AIC32X4 if I2C
@@ -125,6 +136,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_WM9705 if SND_SOC_AC97_BUS
select SND_SOC_WM9712 if SND_SOC_AC97_BUS
select SND_SOC_WM9713 if SND_SOC_AC97_BUS
+ select SND_SOC_ZL380TW if SND_SOC_I2C_AND_SPI
help
Normally ASoC codec drivers are only built if a machine driver which
uses them is also built since they are only usable with a machine
@@ -190,6 +202,9 @@ config SND_SOC_ADAV80X
config SND_SOC_ADS117X
tristate
+config SND_SOC_AMBARELLA_DUMMY
+ tristate
+
config SND_SOC_AK4104
tristate
@@ -202,12 +217,30 @@ config SND_SOC_AK4641
config SND_SOC_AK4642
tristate
+config SND_SOC_AK4642_AMB
+ tristate
+
config SND_SOC_AK4671
tristate
config SND_SOC_AK5386
tristate
+config SND_SOC_AK4951_AMB
+ tristate
+
+config SND_SOC_AK4954_AMB
+ tristate
+
+config SND_SOC_WM8940_AMB
+ tristate
+
+config SND_SOC_WM8974_AMB
+ tristate
+
+config SND_SOC_AK7755
+ tristate
+
config SND_SOC_ALC5623
tristate
config SND_SOC_ALC5632
@@ -269,6 +302,15 @@ config SND_SOC_DFBMCS320
config SND_SOC_DMIC
tristate
+config SND_SOC_ES8328
+ tristate
+
+config SND_SOC_ES8374
+ tristate
+
+config SND_SOC_ES8388
+ tristate
+
config SND_SOC_ISABELLE
tristate
@@ -525,3 +567,12 @@ config SND_SOC_ML26124
config SND_SOC_TPA6130A2
tristate
+
+config SND_SOC_TLV320ADC3xxx
+ tristate
+
+config SND_SOC_ZL380TW
+ tristate
+
+config SND_SOC_RT5670
+ tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index b9e41c9a..36c172e3 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -13,8 +13,17 @@ snd-soc-ak4104-objs := ak4104.o
snd-soc-ak4535-objs := ak4535.o
snd-soc-ak4641-objs := ak4641.o
snd-soc-ak4642-objs := ak4642.o
+snd-soc-ak4642-amb-objs := ak4642_amb.o
snd-soc-ak4671-objs := ak4671.o
snd-soc-ak5386-objs := ak5386.o
+snd-soc-ak4951-amb-objs := ak4951_amb.o
+snd-soc-ak4954-amb-objs := ak4954_amb.o
+snd-soc-ak7719-objs := ak7719_amb.o
+snd-soc-ak7755-objs := ak7755.o
+snd-soc-wm8940-amb-objs := wm8940_amb.o
+snd-soc-wm8974-amb-objs := wm8974_amb.o
+snd-soc-rt5670-objs := rt5670.o rt5670-dsp.o
+snd-soc-ambdummy-objs := ambarella_dummy.o
snd-soc-arizona-objs := arizona.o
snd-soc-cq93vc-objs := cq93vc.o
snd-soc-cs42l51-objs := cs42l51.o
@@ -29,6 +38,9 @@ snd-soc-da732x-objs := da732x.o
snd-soc-da9055-objs := da9055.o
snd-soc-dfbmcs320-objs := dfbmcs320.o
snd-soc-dmic-objs := dmic.o
+snd-soc-es8328-objs := es8328.o
+snd-soc-es8374-objs := es8374.o
+snd-soc-es8388-objs := es8388.o
snd-soc-isabelle-objs := isabelle.o
snd-soc-jz4740-codec-objs := jz4740.o
snd-soc-l3-objs := l3.o
@@ -57,6 +69,7 @@ snd-soc-sta32x-objs := sta32x.o
snd-soc-sta529-objs := sta529.o
snd-soc-stac9766-objs := stac9766.o
snd-soc-tas5086-objs := tas5086.o
+snd-soc-tlv320adc3xxx-amb-objs := tlv320adc3xxx_amb.o
snd-soc-tlv320aic23-objs := tlv320aic23.o
snd-soc-tlv320aic26-objs := tlv320aic26.o
snd-soc-tlv320aic3x-objs := tlv320aic3x.o
@@ -122,6 +135,7 @@ snd-soc-wm-hubs-objs := wm_hubs.o
# Amp
snd-soc-max9877-objs := max9877.o
snd-soc-tpa6130a2-objs := tpa6130a2.o
+snd-soc-zl380tw-objs := zl380tw.o
obj-$(CONFIG_SND_SOC_88PM860X) += snd-soc-88pm860x.o
obj-$(CONFIG_SND_SOC_AB8500_CODEC) += snd-soc-ab8500-codec.o
@@ -138,10 +152,19 @@ obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o
obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
+obj-$(CONFIG_SND_SOC_AK4642_AMB) += snd-soc-ak4642-amb.o
obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
obj-$(CONFIG_SND_SOC_AK5386) += snd-soc-ak5386.o
+obj-$(CONFIG_SND_SOC_AK4951_AMB) += snd-soc-ak4951-amb.o
+obj-$(CONFIG_SND_SOC_AK4954_AMB) += snd-soc-ak4954-amb.o
+obj-$(CONFIG_SND_SOC_AK7719_DSP) += snd-soc-ak7719.o
+obj-$(CONFIG_SND_SOC_AK7755) += snd-soc-ak7755.o
+obj-$(CONFIG_SND_SOC_WM8940_AMB) += snd-soc-wm8940-amb.o
+obj-$(CONFIG_SND_SOC_WM8974_AMB) += snd-soc-wm8974-amb.o
+obj-$(CONFIG_SND_SOC_RT5670) += snd-soc-rt5670.o
obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o
+obj-$(CONFIG_SND_SOC_AMBARELLA_DUMMY) += snd-soc-ambdummy.o
obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o
obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
@@ -156,6 +179,9 @@ obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o
obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o
obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o
obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
+obj-$(CONFIG_SND_SOC_ES8328) += snd-soc-es8328.o
+obj-$(CONFIG_SND_SOC_ES8374) += snd-soc-es8374.o
+obj-$(CONFIG_SND_SOC_ES8388) += snd-soc-es8388.o
obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o
obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
@@ -186,6 +212,7 @@ obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
obj-$(CONFIG_SND_SOC_TLV320AIC32X4) += snd-soc-tlv320aic32x4.o
obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o
+obj-$(CONFIG_SND_SOC_TLV320ADC3xxx) += snd-soc-tlv320adc3xxx-amb.o
obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o
obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
@@ -246,3 +273,4 @@ obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
# Amp
obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
+obj-$(CONFIG_SND_SOC_ZL380TW) += snd-soc-zl380tw.o
diff --git a/sound/soc/codecs/ak4642_amb.c b/sound/soc/codecs/ak4642_amb.c
new file mode 100644
index 00000000..6df1c709
--- /dev/null
+++ b/sound/soc/codecs/ak4642_amb.c
@@ -0,0 +1,841 @@
+/*
+ * ak4642.c -- AK4642 ALSA Soc Audio driver
+ *
+ * Copyright 2009 Ambarella Ltd.
+ *
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * Based on ak4535.c by Richard Purdie
+ *
+ * History:
+ * 2009/05/29 - [Cao Rongrong] Created file
+ * 2010/10/25 - [Cao Rongrong] Port to 2.6.36+
+ * 2011/03/20 - [Cao Rongrong] Port to 2.6.38
+ * 2013/01/14 - [Ken He] Port to 3.8
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/of_gpio.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+
+#include "ak4642_amb.h"
+
+#define AK4642_VERSION "0.3"
+
+
+/* codec private data */
+struct ak4642_priv {
+ unsigned int rst_pin;
+ unsigned int rst_active;
+ unsigned int sysclk;
+ unsigned int clk_id;
+};
+
+/*
+ * ak4642 register cache
+ */
+static const u8 ak4642_reg[AK4642_CACHEREGNUM] = {
+ 0x00, 0x00, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0x00,
+ 0xe1, 0xe1, 0x18, 0x00,
+ 0xe1, 0x18, 0x11, 0x08,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+};
+
+/**************** ALSA Controls and widgets **************/
+
+static int ak4642_get_mic_gain(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ unsigned short val, val1, val2;
+
+ val1 = snd_soc_read(codec, AK4642_SIG1);
+ val2 = snd_soc_read(codec, AK4642_SIG2);
+ val = (val2 & 0x20) >> 4 | (val1 & 0x01);
+
+ ucontrol->value.integer.value[0] = val;
+ return 0;
+}
+
+static int ak4642_set_mic_gain(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ unsigned short val, val1, val2;
+
+ val1 = snd_soc_read(codec, AK4642_SIG1);
+ val2 = snd_soc_read(codec, AK4642_SIG2);
+ val = (val2 & 0x20) >> 4 | (val1 & 0x01);
+
+ if (val == ucontrol->value.integer.value[0])
+ return 0;
+
+ val = ucontrol->value.integer.value[0];
+ val1 &= 0xfe;
+ val1 |= (val & 0x01);
+ snd_soc_write(codec, AK4642_SIG1, val1);
+ val2 &= 0xdf;
+ val2 |= ((val & 0x02) << 4);
+ snd_soc_write(codec, AK4642_SIG2, val2);
+
+ return 1;
+}
+
+static int ak4642_get_alc_gain(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ unsigned short val, val1, val2;
+
+ val1 = snd_soc_read(codec, AK4642_ALC1);
+ val2 = snd_soc_read(codec, AK4642_ALC3);
+ val = (val2 & 0x80) >> 6 | (val1 & 0x02) >> 1;
+
+ ucontrol->value.integer.value[0] = val;
+ return 0;
+}
+
+static int ak4642_set_alc_gain(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ unsigned short val, val1, val2;
+
+ val1 = snd_soc_read(codec, AK4642_ALC1);
+ val2 = snd_soc_read(codec, AK4642_ALC3);
+ val = (val2 & 0x80) >> 6 | (val1 & 0x02) >> 1;
+
+ if (val == ucontrol->value.integer.value[0])
+ return 0;
+
+ val = ucontrol->value.integer.value[0];
+ val1 &= 0xfd;
+ val1 |= ((val & 0x01) << 1);
+ snd_soc_write(codec, AK4642_ALC1, val1);
+ val2 &= 0x7f;
+ val2 |= ((val & 0x02) << 6);
+ snd_soc_write(codec, AK4642_ALC3, val2);
+
+ return 1;
+}
+
+static int ak4642_get_input_mux(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ unsigned short val, val1, val2;
+
+ val1 = snd_soc_read(codec, AK4642_PM3);
+ val2 = snd_soc_read(codec, AK4642_SIG1);
+
+ if(((val1 & 0x1e) == 0x06) && ((val2 & 0x04) == 0x00))
+ val = AK4642_LINE_IN_ON;
+ else if(((val1 & 0x18) == 0x18) && ((val2 & 0x04) == 0x04))
+ val = AK4642_BOTH_MIC_ON;
+ else
+ val = AK4642_INPUT_UNKNOWN;
+
+ ucontrol->value.integer.value[0] = val;
+ return 0;
+}
+
+static int ak4642_set_input_mux(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ unsigned short val, val1, val2;
+
+ val1 = snd_soc_read(codec, AK4642_PM3);
+ val2 = snd_soc_read(codec, AK4642_SIG1);
+
+ if(((val1 & 0x1e) == 0x06) && ((val2 & 0x04) == 0x00))
+ val = AK4642_LINE_IN_ON;
+ else if(((val1 & 0x18) == 0x18) && ((val2 & 0x04) == 0x04))
+ val = AK4642_BOTH_MIC_ON;
+ else
+ val = AK4642_INPUT_UNKNOWN;
+
+ if (val == ucontrol->value.integer.value[0])
+ return 0;
+
+ val = ucontrol->value.integer.value[0];
+
+ switch(val){
+ case AK4642_LINE_IN_ON:
+ snd_soc_update_bits(codec, AK4642_PM3, 0x18, 0x06);
+ snd_soc_update_bits(codec, AK4642_SIG1, 0x05, 0);
+ snd_soc_update_bits(codec, AK4642_SIG2, 0x20, 0);
+ break;
+ case AK4642_BOTH_MIC_ON:
+ snd_soc_update_bits(codec, AK4642_PM3, 0x18, 0x18);
+ snd_soc_update_bits(codec, AK4642_SIG1, 0x05, 0x05);
+ snd_soc_update_bits(codec, AK4642_SIG2, 0x20, 0x20);
+ break;
+ case AK4642_INPUT_UNKNOWN:
+ return 0;
+ }
+
+ return 1;
+}
+
+
+static const char *ak4642_lo_gain[] = {"+0db", "+2db"};
+static const char *ak4642_hp_gain[] = {"+0db", "+3.6db"};
+static const char *ak4642_sp_gain[] = {"+4.43db", "+6.43db", "+10.65db", "+12.65db"};
+static const char *ak4642_vol_ctrl[] = {"Independent", "Dependent"};
+static const char *ak4642_deemp[] = {"44.1kHz", "Off", "48kHz", "32kHz"};
+static const char *ak4642_hp_out[] = {"Stereo", "Mono"};
+static const char *ak4642_lsrc[] = {"LIN1", "LIN2"};
+static const char *ak4642_rsrc[] = {"RIN1", "RIN2"};
+static const char *ak4642_eq_gain[] = {"+0db", "+12db", "+24db"};
+static const char *ak4642_fil_sel[] = {"HPF", "LPF"};
+static const char *ak4642_mic_gain[] = {"0db", "+20db", "+26db", "+32db"};
+static const char *ak4642_alc_gain[] = {"0.375db", "0.750db", "1.125db", "1.500db"};
+static const char *ak4642_input_mux[] = {"Line-in", "Both Mic", "Unknown"};
+
+static const struct soc_enum ak4642_enum[] = {
+ SOC_ENUM_SINGLE(AK4642_SIG2, 7, 2, ak4642_lo_gain),
+ SOC_ENUM_SINGLE(AK4642_SIG2, 3, 4, ak4642_sp_gain),
+ SOC_ENUM_SINGLE(AK4642_MODE3, 4, 2, ak4642_vol_ctrl),
+ SOC_ENUM_SINGLE(AK4642_MODE3, 0, 4, ak4642_deemp),
+ SOC_ENUM_SINGLE(AK4642_MODE4, 3, 2, ak4642_vol_ctrl),
+ SOC_ENUM_SINGLE(AK4642_MODE4, 2, 2, ak4642_hp_out),
+ SOC_ENUM_SINGLE(AK4642_PM3, 5, 2, ak4642_hp_gain),
+ SOC_ENUM_SINGLE(AK4642_PM3, 1, 2, ak4642_lsrc),
+ SOC_ENUM_SINGLE(AK4642_PM3, 2, 2, ak4642_rsrc),
+ SOC_ENUM_SINGLE(AK4642_FSEL, 6, 3, ak4642_eq_gain),
+ SOC_ENUM_SINGLE(AK4642_F3EF1, 7, 2, ak4642_fil_sel),
+ SOC_ENUM_SINGLE(AK4642_E1EF1, 7, 2, ak4642_fil_sel),
+ SOC_ENUM_SINGLE_EXT(4, ak4642_mic_gain),
+ SOC_ENUM_SINGLE_EXT(4, ak4642_alc_gain),
+ SOC_ENUM_SINGLE_EXT(3, ak4642_input_mux),
+};
+
+static const struct snd_kcontrol_new ak4642_snd_controls[] = {
+ SOC_SINGLE("HP Mute Switch", AK4642_PM2, 6, 1, 0),
+ SOC_ENUM("Line Out Gain", ak4642_enum[0]),
+ SOC_ENUM("Speaker Gain", ak4642_enum[1]),
+ SOC_ENUM("Headphone Output Mode", ak4642_enum[5]),
+ SOC_ENUM("Headphone Gain", ak4642_enum[6]),
+ SOC_SINGLE("Mic Mute Switch", AK4642_SIG1, 2, 1, 1),
+
+ SOC_SINGLE("ALC Switch", AK4642_ALC1, 5, 1, 0),
+ SOC_SINGLE("ALC ZC Time", AK4642_TIMER, 4, 3, 0),
+ SOC_SINGLE("ALC Recovery Time", AK4642_TIMER, 2, 3, 0),
+ SOC_SINGLE("ALC ZC Detection Switch", AK4642_ALC1, 4, 1, 1),
+ SOC_SINGLE("ALC ATT Step", AK4642_TIMER, 2, 3, 0),
+ SOC_SINGLE("ALC Volume", AK4642_ALC2, 0, 255, 0),
+
+ SOC_SINGLE("Left Capture Volume", AK4642_LIVOL, 0, 255, 0),
+ SOC_SINGLE("Right Capture Volume", AK4642_RIVOL, 0, 255, 0),
+ SOC_SINGLE("Left Playback Volume", AK4642_LDVOL, 0, 255, 1),
+ SOC_SINGLE("Right Playback Volume", AK4642_RDVOL, 0, 255, 1),
+ SOC_ENUM("Playback Volume Control Mode", ak4642_enum[2]),
+ SOC_ENUM("Capture Volume Control Mode", ak4642_enum[4]),
+ SOC_SINGLE("Bass Boost Volume", AK4642_MODE3, 2, 3, 0),
+ SOC_ENUM("Playback Deemphasis", ak4642_enum[3]),
+
+ SOC_SINGLE("Left Differential Swtich", AK4642_PM3, 3, 1, 0),
+ SOC_SINGLE("Right Differential Swtich", AK4642_PM3, 4, 1, 0),
+ /* ADC Source Selector is only available when differential switch is off */
+ SOC_ENUM("Left ADC Source", ak4642_enum[7]),
+ SOC_ENUM("Right ADC Source", ak4642_enum[8]),
+ SOC_ENUM_EXT("Input Mux", ak4642_enum[14],
+ ak4642_get_input_mux, ak4642_set_input_mux),
+
+ SOC_ENUM("EQ Gain Select", ak4642_enum[9]),
+ SOC_SINGLE("Emphasis Filter Switch", AK4642_FSEL, 2, 1, 0),
+ SOC_ENUM("Emphasis Filter Select", ak4642_enum[10]),
+ SOC_SINGLE("Gain Compensation Filter Switch", AK4642_FSEL, 3, 1, 0),
+ SOC_SINGLE("Wind-noise Filter Switch", AK4642_FSEL, 4, 1, 0),
+ SOC_ENUM("Wind-noise Filter Select", ak4642_enum[11]),
+ SOC_SINGLE("Emphasis Filter 1 low Coeff", AK4642_F3EF0, 0, 255, 0),
+ SOC_SINGLE("Emphasis Filter 1 high Coeff", AK4642_F3EF1, 0, 63, 0),
+ SOC_SINGLE("Emphasis Filter 2 low Coeff", AK4642_F3EF2, 0, 255, 0),
+ SOC_SINGLE("Emphasis Filter 2 high Coeff", AK4642_F3EF3, 0, 63, 0),
+ SOC_SINGLE("Gain Compensation Filter 1 low Coeff", AK4642_EQEF0, 0, 255, 0),
+ SOC_SINGLE("Gain Compensation Filter 1 high Coeff", AK4642_EQEF1, 0, 255, 0),
+ SOC_SINGLE("Gain Compensation Filter 2 low Coeff", AK4642_EQEF2, 0, 255, 0),
+ SOC_SINGLE("Gain Compensation Filter 2 high Coeff", AK4642_EQEF3, 0, 63, 0),
+ SOC_SINGLE("Gain Compensation Filter 3 low Coeff", AK4642_EQEF4, 0, 255, 0),
+ SOC_SINGLE("Gain Compensation Filter 3 high Coeff", AK4642_EQEF5, 0, 255, 0),
+ SOC_SINGLE("Wind-noise Filter 1 low Coeff", AK4642_F3EF0, 0, 255, 0),
+ SOC_SINGLE("Wind-noise Filter 1 high Coeff", AK4642_F3EF1, 0, 63, 0),
+ SOC_SINGLE("Wind-noise Filter 2 low Coeff", AK4642_F3EF2, 0, 255, 0),
+ SOC_SINGLE("Wind-noise Filter 2 high Coeff", AK4642_F3EF3, 0, 63, 0),
+ SOC_ENUM_EXT("Mic Gain", ak4642_enum[12],
+ ak4642_get_mic_gain, ak4642_set_mic_gain),
+ SOC_ENUM_EXT("ALC Recovery Gain", ak4642_enum[13],
+ ak4642_get_alc_gain, ak4642_set_alc_gain),
+};
+
+/* Mono 1 Mixer */
+static const struct snd_kcontrol_new ak4642_hp_mixer_controls[] = {
+ SOC_DAPM_SINGLE("HP Playback Switch", AK4642_MODE4, 0, 1, 0),
+ SOC_DAPM_SINGLE("MIN HP Switch", AK4642_MODE4, 1, 1, 0),
+};
+
+/* Stereo Line Out Mixer */
+static const struct snd_kcontrol_new ak4642_lo_mixer_controls[] = {
+ SOC_DAPM_SINGLE("Line Playback Switch", AK4642_SIG1, 4, 1, 0),
+ SOC_DAPM_SINGLE("MIN LO Switch", AK4642_SIG2, 2, 1, 0),
+};
+
+/* Input Mixer */
+static const struct snd_kcontrol_new ak4642_sp_mixer_controls[] = {
+ SOC_DAPM_SINGLE("SP Playback Switch", AK4642_SIG1, 5, 1, 0),
+ SOC_DAPM_SINGLE("MIN SP Switch", AK4642_SIG1, 6, 1, 0),
+};
+
+/* line out switch */
+static const struct snd_kcontrol_new ak4642_lo_control =
+ SOC_DAPM_SINGLE("Switch", AK4642_PM1, 3, 1, 0);
+/* speaker switch */
+static const struct snd_kcontrol_new ak4642_sp_control =
+ SOC_DAPM_SINGLE("Switch", AK4642_SIG1, 7, 1, 0);
+
+/* ak4642 dapm widgets */
+static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = {
+ /* OUTPUT */
+ SND_SOC_DAPM_MIXER("Line Out Mixer", SND_SOC_NOPM, 0, 0,
+ &ak4642_lo_mixer_controls[0],
+ ARRAY_SIZE(ak4642_lo_mixer_controls)),
+ SND_SOC_DAPM_MIXER("Headphone Mixer", SND_SOC_NOPM, 0, 0,
+ &ak4642_hp_mixer_controls[0],
+ ARRAY_SIZE(ak4642_hp_mixer_controls)),
+ SND_SOC_DAPM_MIXER("Speaker Mixer", SND_SOC_NOPM, 0, 0,
+ &ak4642_sp_mixer_controls[0],
+ ARRAY_SIZE(ak4642_sp_mixer_controls)),
+
+ SND_SOC_DAPM_DAC("DAC", "Playback", AK4642_PM1, 2, 0),
+ SND_SOC_DAPM_PGA("Spk Amp", AK4642_PM1, 4, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("HP L Amp", AK4642_PM2, 5, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("HP R Amp", AK4642_PM2, 4, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Line Out Pga", AK4642_SIG2, 6, 1, NULL, 0),
+ SND_SOC_DAPM_SWITCH("Speaker Enable", SND_SOC_NOPM, 0, 0,
+ &ak4642_sp_control),
+ SND_SOC_DAPM_SWITCH("Line Out Enable", SND_SOC_NOPM, 0, 0,
+ &ak4642_lo_control),
+ SND_SOC_DAPM_OUTPUT("LOUT"),
+ SND_SOC_DAPM_OUTPUT("ROUT"),
+ SND_SOC_DAPM_OUTPUT("HPL"),
+ SND_SOC_DAPM_OUTPUT("HPR"),
+ SND_SOC_DAPM_OUTPUT("SPP"),
+ SND_SOC_DAPM_OUTPUT("SPN"),
+
+ /* INPUT */
+ SND_SOC_DAPM_ADC("Left ADC", "Capture", AK4642_PM1, 0, 0),
+ SND_SOC_DAPM_ADC("Right ADC", "Capture", AK4642_PM3, 0, 0),
+ SND_SOC_DAPM_PGA("MIN Input", AK4642_PM1, 5, 0, NULL, 0),
+ SND_SOC_DAPM_MICBIAS("Mic Bias", AK4642_SIG1, 2, 0),
+
+ SND_SOC_DAPM_INPUT("LIN1"),
+ SND_SOC_DAPM_INPUT("RIN1"),
+ SND_SOC_DAPM_INPUT("LIN2"),
+ SND_SOC_DAPM_INPUT("RIN2"),
+ SND_SOC_DAPM_INPUT("MIN"),
+};
+
+static const struct snd_soc_dapm_route ak4642_dapm_routes[] = {
+ /*line out mixer */
+ {"Line Out Mixer", "Line Playback Switch", "DAC"},
+ {"Line Out Mixer", "MIN LO Switch", "MIN Input"},
+
+ /* headphone mixer */
+ {"Headphone Mixer", "HP Playback Switch", "DAC"},
+ {"Headphone Mixer", "MIN HP Switch", "MIN Input"},
+
+ /*speaker mixer */
+ {"Speaker Mixer", "SP Playback Switch", "DAC"},
+ {"Speaker Mixer", "MIN SP Switch", "MIN Input"},
+
+ /* line out */
+ {"Line Out Pga", NULL, "Line Out Mixer"},
+ {"Line Out Enable", "Switch", "Line Out Pga"},
+ {"LOUT", NULL, "Line Out Enable"},
+ {"ROUT", NULL, "Line Out Enable"},
+
+ /* left headphone */
+ {"HP L Amp", NULL, "Headphone Mixer"},
+ {"HPL", NULL, "HP L Amp"},
+
+ /* right headphone */
+ {"HP R Amp", NULL, "Headphone Mixer"},
+ {"HPR", NULL, "HP R Amp"},
+
+ /* speaker */
+ {"Spk Amp", NULL, "Speaker Mixer"},
+ {"Speaker Enable", "Switch", "Spk Amp"},
+ {"SPP", NULL, "Speaker Enable"},
+ {"SPN", NULL, "Speaker Enable"},
+
+ /* INPUT */
+ {"MIN Input", NULL, "MIN"},
+ {"Left ADC", NULL, "LIN1"},
+ {"Left ADC", NULL, "LIN2"},
+ {"Right ADC", NULL, "RIN1"},
+ {"Right ADC", NULL, "RIN2"},
+};
+
+static int ak4642_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec);
+
+ ak4642->sysclk = freq;
+ ak4642->clk_id = clk_id;
+ return 0;
+}
+
+static int ak4642_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec);
+ int rate = params_rate(params);
+ u8 mode0, mode1;
+
+ mode0 = snd_soc_read(codec, AK4642_MODE1) & 0x0F;
+ mode1 = snd_soc_read(codec, AK4642_MODE2) & 0xD8;
+
+ if(ak4642->clk_id == AK4642_MCLK_IN) {
+ switch(ak4642->sysclk) {
+ case 11289600:
+ mode0 |= (4 << 4);
+ break;
+ case 12288000:
+ mode0 |= (5 << 4);
+ break;
+ case 12000000:
+ mode0 |= (6 << 4);
+ break;
+ case 24000000:
+ mode0 |= (7 << 4);
+ break;
+ case 13500000:
+ mode0 |= (0xC << 4);
+ break;
+ case 27000000:
+ mode0 |= (0xD << 4);
+ break;
+ default:
+ mode0 |= (5 << 4);
+ break;
+ }
+
+ snd_soc_write(codec, AK4642_MODE1, mode0);
+ snd_soc_update_bits(codec,AK4642_PM2,0x09,0x01);
+ } else if(ak4642->clk_id == AK4642_BCLK_IN) {
+ u32 oversampe = ak4642->sysclk / rate;
+
+ switch(oversampe) {
+ case 32:
+ mode0 |= (2 << 4);
+ break;
+ case 64:
+ mode0 |= (3 << 4);
+ break;
+ default:
+ mode0 |= (2 << 4);
+ break;
+ }
+
+ snd_soc_write(codec, AK4642_MODE1, mode0);
+ snd_soc_update_bits(codec,AK4642_PM2,0x09,0x01);
+
+ } else if(ak4642->clk_id == AK4642_MCLK_IN_BCLK_OUT) {
+ switch(ak4642->sysclk) {
+ case 11289600:
+ mode0 |= (4 << 4);
+ break;
+ case 12288000:
+ mode0 |= (5 << 4);
+ break;
+ case 12000000:
+ mode0 |= (6 << 4);
+ break;
+ case 24000000:
+ mode0 |= (7 << 4);
+ break;
+ case 13500000:
+ mode0 |= (0xC << 4);
+ break;
+ case 27000000:
+ mode0 |= (0xD << 4);
+ break;
+ default:
+ mode0 |= (5 << 4);
+ break;
+ }
+
+ snd_soc_write(codec, AK4642_MODE1, mode0);
+ snd_soc_update_bits(codec,AK4642_PM2,0x09,0x09);
+ }
+
+ if(ak4642->clk_id == AK4642_BCLK_IN) {
+ if(rate >= 7350 && rate <= 8000)
+ mode1 |= 0;
+ else if(rate > 8000 && rate <= 12000)
+ mode1 |= 1;
+ else if(rate > 12000 && rate <= 16000)
+ mode1 |= 2;
+ else if(rate > 16000 && rate <= 24000)
+ mode1 |= 3;
+ else if(rate > 24000 && rate <= 32000)
+ mode1 |= 0x22;
+ else if(rate > 32 && rate <= 48000)
+ mode1 |= 0x23;
+
+ snd_soc_write(codec, AK4642_MODE2, mode1);
+ } else {
+ switch(rate) {
+ case 7350:
+ mode1 |= 4;
+ break;
+ case 8000:
+ mode1 |= 0;
+ break;
+ case 11025:
+ mode1 |= 5;
+ break;
+ case 12000:
+ mode1 |= 1;
+ break;
+ case 14700:
+ mode1 |= 6;
+ break;
+ case 16000:
+ mode1 |= 2;
+ break;
+ case 22050:
+ mode1 |= 7;
+ break;
+ case 24000:
+ mode1 |= 3;
+ break;
+ case 29400:
+ mode1 |= 0x26;
+ break;
+ case 32000:
+ mode1 |= 0x22;
+ break;
+ case 44100:
+ mode1 |= 0x27;
+ break;
+ case 48000:
+ mode1 |= 0x23;
+ break;
+ default:
+ mode1 |= 0x23;
+ break;
+ }
+
+ snd_soc_write(codec, AK4642_MODE2, mode1);
+ }
+
+ return 0;
+}
+
+static int ak4642_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u8 mode1 = 0, mode2 = 0;
+
+ /* set master/slave audio interface */
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ snd_soc_update_bits(codec, AK4642_PM2, 0x08, 0);
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+ snd_soc_update_bits(codec, AK4642_PM2, 0x08, 0x08);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ mode1 = snd_soc_read(codec, AK4642_MODE1);
+ mode2 = snd_soc_read(codec, AK4642_MODE2);
+
+ /* interface format */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ mode1 |= 0x3;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ mode1 &= ~0x3;
+ mode2 &= ~0x18;
+ mode2 |= 0x10;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ mode1 &= ~0x3;
+ mode2 &= ~0x18;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ case SND_SOC_DAIFMT_RIGHT_J:
+ pr_info("We don't implement this format (%d) yet.\n", fmt);
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_write(codec, AK4642_MODE1, mode1);
+ snd_soc_write(codec, AK4642_MODE2, mode2);
+ return 0;
+}
+
+static int ak4642_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec = dai->codec;
+
+ if (mute){
+ snd_soc_update_bits(codec, AK4642_MODE3, 0x20, 0x20);
+ snd_soc_update_bits(codec, AK4642_PM2, 0x40, 0);
+ }
+ else{
+ snd_soc_update_bits(codec, AK4642_MODE3, 0x20, 0);
+ snd_soc_update_bits(codec, AK4642_PM2, 0x40, 0x40);
+ }
+
+ return 0;
+}
+
+static int ak4642_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ /* Everything is ON */
+ break;
+ case SND_SOC_BIAS_PREPARE:
+ break;
+ case SND_SOC_BIAS_STANDBY:
+ snd_soc_update_bits(codec, AK4642_PM1, 0x40, 0x40);
+ break;
+ case SND_SOC_BIAS_OFF:
+ /* Everything is OFF */
+ snd_soc_update_bits(codec, AK4642_PM1, 0x40, 0);
+ break;
+ }
+ codec->dapm.bias_level = level;
+ return 0;
+}
+
+
+#define AK4642_RATES SNDRV_PCM_RATE_8000_48000
+#define AK4642_FORMATS SNDRV_PCM_FMTBIT_S16_LE
+
+static const struct snd_soc_dai_ops ak4642_dai_ops = {
+ .hw_params = ak4642_hw_params,
+ .set_fmt = ak4642_set_dai_fmt,
+ .digital_mute = ak4642_mute,
+ .set_sysclk = ak4642_set_dai_sysclk,
+};
+
+static struct snd_soc_dai_driver ak4642_dai = {
+ .name = "ak4642-hifi",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = AK4642_RATES,
+ .formats = AK4642_FORMATS,},
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = AK4642_RATES,
+ .formats = AK4642_FORMATS,},
+ .ops = &ak4642_dai_ops,
+};
+
+static int ak4642_suspend(struct snd_soc_codec *codec)
+{
+ ak4642_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static int ak4642_resume(struct snd_soc_codec *codec)
+{
+ snd_soc_cache_sync(codec);
+ ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ return 0;
+}
+
+static int ak4642_probe(struct snd_soc_codec *codec)
+{
+ struct ak4642_priv *ak4642;
+ int ret;
+
+ dev_info(codec->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
+
+ ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
+ }
+
+ ak4642 = snd_soc_codec_get_drvdata(codec);
+
+ ret = devm_gpio_request(codec->dev, ak4642->rst_pin, "ak4642 reset");
+ if (ret < 0){
+ dev_err(codec->dev, "Failed to request rst_pin: %d\n", ret);
+ return ret;
+ }
+
+ /* Reset AK4642 codec */
+ gpio_direction_output(ak4642->rst_pin, ak4642->rst_active);
+ msleep(1);
+ gpio_direction_output(ak4642->rst_pin, !ak4642->rst_active);
+
+ /* power on device */
+ ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ /* Initial some register */
+ /* Select Input to ADC */
+ snd_soc_update_bits(codec, AK4642_PM3, 0x06, 0x06);
+ /* Open DAC to Line-Out */
+ snd_soc_update_bits(codec, AK4642_SIG1, 0x10, 0x10);
+ /* Open DAC to Headphone */
+ snd_soc_update_bits(codec, AK4642_MODE4, 0x01, 0x01);
+ /* Open Line-Out Switch */
+ snd_soc_update_bits(codec, AK4642_PM1, 0x08, 0x08);
+ snd_soc_write(codec, AK4642_LIVOL, 0x91); /* Input 0db */
+ snd_soc_write(codec, AK4642_RIVOL, 0x91); /* Input 0db */
+ /* Mic-Amp 0db */
+ snd_soc_update_bits(codec, AK4642_SIG1, 0x01, 0x01);
+ /* Mic-Amp 0db */
+ snd_soc_update_bits(codec, AK4642_SIG2, 0x20, 0x20);
+
+ snd_soc_add_codec_controls(codec, ak4642_snd_controls,
+ ARRAY_SIZE(ak4642_snd_controls));
+
+ return 0;
+}
+
+static int ak4642_remove(struct snd_soc_codec *codec)
+{
+ ak4642_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
+ .probe = ak4642_probe,
+ .remove = ak4642_remove,
+ .suspend = ak4642_suspend,
+ .resume = ak4642_resume,
+ .set_bias_level = ak4642_set_bias_level,
+ .reg_cache_default = ak4642_reg,
+ .reg_cache_size = ARRAY_SIZE(ak4642_reg),
+ .reg_word_size = sizeof(u8),
+ .reg_cache_step = 1,
+ .dapm_widgets = ak4642_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(ak4642_dapm_widgets),
+ .dapm_routes = ak4642_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(ak4642_dapm_routes),
+};
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static int ak4642_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct device_node *np = i2c->dev.of_node;
+ struct ak4642_priv *ak4642;
+ enum of_gpio_flags flags;
+ int rst_pin;
+
+ ak4642 = devm_kzalloc(&i2c->dev, sizeof(struct ak4642_priv), GFP_KERNEL);
+ if (ak4642 == NULL)
+ return -ENOMEM;
+
+
+ rst_pin = of_get_gpio_flags(np, 0, &flags);
+ if (rst_pin < 0 || !gpio_is_valid(rst_pin))
+ return -ENXIO;
+
+ ak4642->rst_pin = rst_pin;
+ ak4642->rst_active = !!(flags & OF_GPIO_ACTIVE_LOW);
+
+ i2c_set_clientdata(i2c, ak4642);
+ return snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_ak4642, &ak4642_dai, 1);
+}
+
+static int ak4642_i2c_remove(struct i2c_client *i2c)
+{
+ snd_soc_unregister_codec(&i2c->dev);
+ return 0;
+}
+
+static struct of_device_id ak4642_of_match[] = {
+ { .compatible = "ambarella,ak4642",},
+ {},
+};
+MODULE_DEVICE_TABLE(of, ak4642_of_match);
+
+static const struct i2c_device_id ak4642_i2c_id[] = {
+ { "ak4642", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ak4642_i2c_id);
+
+static struct i2c_driver ak4642_i2c_driver = {
+ .driver = {
+ .name = "ak4642-codec",
+ .owner = THIS_MODULE,
+ .of_match_table = ak4642_of_match,
+ },
+ .probe = ak4642_i2c_probe,
+ .remove = ak4642_i2c_remove,
+ .id_table = ak4642_i2c_id,
+};
+
+#endif
+
+static int __init ak4642_modinit(void)
+{
+ int ret;
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ ret = i2c_add_driver(&ak4642_i2c_driver);
+ if (ret != 0)
+ pr_err("Failed to register UDA1380 I2C driver: %d\n", ret);
+#endif
+ return ret;
+}
+module_init(ak4642_modinit);
+
+static void __exit ak4642_exit(void)
+{
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ i2c_del_driver(&ak4642_i2c_driver);
+#endif
+}
+module_exit(ak4642_exit);
+
+MODULE_DESCRIPTION("Soc AK4642 driver");
+MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
+MODULE_LICENSE("GPL");
+
diff --git a/sound/soc/codecs/ak4642_amb.h b/sound/soc/codecs/ak4642_amb.h
new file mode 100644
index 00000000..75377e3e
--- /dev/null
+++ b/sound/soc/codecs/ak4642_amb.h
@@ -0,0 +1,65 @@
+/*
+ * ak4642.h -- AK4642 Soc Audio driver
+ *
+ * Copyright 2009 Ambarella Ltd.
+ *
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _AK4642_H
+#define _AK4642_H
+
+/* AK4642 register space */
+
+#define AK4642_PM1 0x00
+#define AK4642_PM2 0x01
+#define AK4642_SIG1 0x02
+#define AK4642_SIG2 0x03
+#define AK4642_MODE1 0x04
+#define AK4642_MODE2 0x05
+#define AK4642_TIMER 0x06
+#define AK4642_ALC1 0x07
+#define AK4642_ALC2 0x08
+#define AK4642_LIVOL 0x09
+#define AK4642_LDVOL 0x0a
+#define AK4642_ALC3 0x0b
+#define AK4642_RIVOL 0x0c
+#define AK4642_RDVOL 0x0d
+#define AK4642_MODE3 0x0e
+#define AK4642_MODE4 0x0f
+#define AK4642_PM3 0x10
+#define AK4642_FSEL 0x11
+#define AK4642_F3EF0 0x12
+#define AK4642_F3EF1 0x13
+#define AK4642_F3EF2 0x14
+#define AK4642_F3EF3 0x15
+#define AK4642_EQEF0 0x16
+#define AK4642_EQEF1 0x17
+#define AK4642_EQEF2 0x18
+#define AK4642_EQEF3 0x19
+#define AK4642_EQEF4 0x1a
+#define AK4642_EQEF5 0x1b
+#define AK4642_F1EF0 0x1c
+#define AK4642_E1EF1 0x1d
+#define AK4642_E1EF2 0x1e
+#define AK4642_E1EF3 0x1f
+
+#define AK4642_CACHEREGNUM 0x20
+
+#define AK4642_SYSCLK 0
+
+#define AK4642_LINE_IN_ON 0
+#define AK4642_BOTH_MIC_ON 1
+#define AK4642_INPUT_UNKNOWN 2
+
+#define AK4642_MCLK_IN 0
+#define AK4642_BCLK_IN 1
+#define AK4642_MCLK_IN_BCLK_OUT 2
+
+
+
+#endif
diff --git a/sound/soc/codecs/ak4951_amb.c b/sound/soc/codecs/ak4951_amb.c
new file mode 100644
index 00000000..873b9c42
--- /dev/null
+++ b/sound/soc/codecs/ak4951_amb.c
@@ -0,0 +1,1317 @@
+/*
+ * ak4951_amb.c -- audio driver for AK4951
+ *
+ * Copyright 2014 Ambarella Ltd.
+ *
+ * Author: Diao Chengdong <cddiao@ambarella.com>
+ *
+ * History:
+ * 2014/03/27 - created
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/of_gpio.h>
+#include <linux/regmap.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+
+#include "ak4951_amb.h"
+
+//#define PLL_32BICK_MODE
+//#define PLL_64BICK_MODE
+
+//#define AK4951_DEBUG //used at debug mode
+//#define AK4951_CONTIF_DEBUG //used at debug mode
+
+#ifdef AK4951_DEBUG
+#define akdbgprt printk
+#else
+#define akdbgprt(format, arg...) do {} while (0)
+#endif
+
+#define LINEIN1_MIC_BIAS_CONNECT
+#define LINEIN2_MIC_BIAS_CONNECT
+
+/* AK4951 Codec Private Data */
+struct ak4951_priv {
+ unsigned int rst_pin;
+ unsigned int rst_active;
+ unsigned int sysclk;
+ unsigned int clkid;
+ struct regmap *regmap;
+ struct i2c_client* i2c_clt;
+ u8 reg_cache[AK4951_MAX_REGISTERS];
+ int onStereo;
+ int mic;
+ u8 fmt;
+};
+
+struct ak4951_priv *ak4951_data;
+
+/*
+ * ak4951 register
+ */
+static struct reg_default ak4951_reg_defaults[] = {
+ { 0, 0x00 },
+ { 1, 0x00 },
+ { 2, 0x06 },
+ { 3, 0x00 },
+ { 4, 0x44 },
+ { 5, 0x52 },
+ { 6, 0x09 },
+ { 7, 0x14 },
+ { 8, 0x00 },
+ { 9, 0x00 },
+ { 10, 0x60 },
+ { 11, 0x00 },
+ { 12, 0xE1 },
+ { 13, 0xE1 },
+ { 14, 0xE1 },
+ { 15, 0x00 },
+ { 16, 0x80 },
+ { 17, 0x80 },
+ { 18, 0x00 },
+ { 19, 0x18 },
+ { 20, 0x18 },
+ { 21, 0x00 },
+ { 22, 0x00 },
+ { 23, 0x00 },
+ { 24, 0x00 },
+ { 25, 0x00 },
+ { 26, 0x0C },
+ { 27, 0x01 },
+ { 28, 0x00 },
+ { 29, 0x03 },
+ { 30, 0xA9 },
+ { 31, 0x1F },
+ { 32, 0xAD },
+ { 33, 0x20 },
+ { 34, 0x7F },
+ { 35, 0x0C },
+ { 36, 0xFF },
+ { 37, 0x38 },
+ { 38, 0xA2 },
+ { 39, 0x83 },
+ { 40, 0x80 },
+ { 41, 0x2E },
+ { 42, 0x5B },
+ { 43, 0x23 },
+ { 44, 0x07 },
+ { 45, 0x28 },
+ { 46, 0xAA },
+ { 47, 0xEC },
+ { 48, 0x00 },
+ { 49, 0x00 },
+ { 50, 0x9F },
+ { 51, 0x00 },
+ { 52, 0x2B },
+ { 53, 0x3F },
+ { 54, 0xD4 },
+ { 55, 0xE0 },
+ { 56, 0x6A },
+ { 57, 0x00 },
+ { 58, 0x1B },
+ { 59, 0x3F },
+ { 60, 0xD4 },
+ { 61, 0xE0 },
+ { 62, 0x6A },
+ { 63, 0x00 },
+ { 64, 0xA2 },
+ { 65, 0x3E },
+ { 66, 0xD4 },
+ { 67, 0xE0 },
+ { 68, 0x6A },
+ { 69, 0x00 },
+ { 70, 0xA8 },
+ { 71, 0x38 },
+ { 72, 0xD4 },
+ { 73, 0xE0 },
+ { 74, 0x6A },
+ { 75, 0x00 },
+ { 76, 0x96 },
+ { 77, 0x1F },
+ { 78, 0xD4 },
+ { 79, 0xE0 },
+};
+
+static bool ak4951_volatile_register(struct device *dev,
+ unsigned int reg)
+{
+ switch (reg) {
+ case AK4951_00_POWER_MANAGEMENT1:
+ case AK4951_01_POWER_MANAGEMENT2:
+ case AK4951_02_SIGNAL_SELECT1:
+ case AK4951_03_SIGNAL_SELECT2:
+ case AK4951_04_SIGNAL_SELECT3:
+ case AK4951_05_MODE_CONTROL1:
+ case AK4951_06_MODE_CONTROL2:
+ case AK4951_07_MODE_CONTROL3:
+ case AK4951_08_DIGITL_MIC:
+ case AK4951_09_TIMER_SELECT:
+ case AK4951_0A_ALC_TIMER_SELECT:
+ case AK4951_0B_ALC_MODE_CONTROL1:
+ case AK4951_0C_ALC_MODE_CONTROL2:
+ case AK4951_0D_LCH_INPUT_VOLUME_CONTROL:
+ case AK4951_0E_RCH_INPUT_VOLUME_CONTROL:
+ case AK4951_0F_ALC_VOLUME:
+ case AK4951_10_LCH_MIC_GAIN_SETTING:
+ case AK4951_11_RCH_MIC_GAIN_SETTING:
+ case AK4951_12_BEEP_CONTROL:
+ case AK4951_13_LCH_DIGITAL_VOLUME_CONTROL:
+ case AK4951_14_RCH_DIGITAL_VOLUME_CONTROL:
+ case AK4951_15_EQ_COMMON_GAIN_SELECT:
+ case AK4951_16_EQ2_COMMON_GAIN_SELECT:
+ case AK4951_17_EQ3_COMMON_GAIN_SELECT:
+ case AK4951_18_EQ4_COMMON_GAIN_SELECT:
+ case AK4951_19_EQ5_COMMON_GAIN_SELECT:
+ case AK4951_1A_AUTO_HPF_CONTROL:
+ case AK4951_1B_DIGITAL_FILTER_SELECT1:
+ case AK4951_1C_DIGITAL_FILTER_SELECT2:
+ case AK4951_1D_DIGITAL_FILTER_MODE:
+ case AK4951_1E_HPF2_COEFFICIENT0:
+ case AK4951_1F_HPF2_COEFFICIENT1:
+ case AK4951_20_HPF2_COEFFICIENT2:
+ case AK4951_21_HPF2_COEFFICIENT3:
+ case AK4951_22_LPF_COEFFICIENT0:
+ case AK4951_23_LPF_COEFFICIENT1:
+ case AK4951_24_LPF_COEFFICIENT2:
+ case AK4951_25_LPF_COEFFICIENT3:
+ case AK4951_26_FIL3_COEFFICIENT0:
+ case AK4951_27_FIL3_COEFFICIENT1:
+ case AK4951_28_FIL3_COEFFICIENT2:
+ case AK4951_29_FIL3_COEFFICIENT3:
+ case AK4951_2A_EQ_COEFFICIENT0:
+ case AK4951_2B_EQ_COEFFICIENT1:
+ case AK4951_2C_EQ_COEFFICIENT2:
+ case AK4951_2D_EQ_COEFFICIENT3:
+ case AK4951_2E_EQ_COEFFICIENT4:
+ case AK4951_2F_EQ_COEFFICIENT5:
+ case AK4951_30_DIGITAL_FILTER_SELECT3:
+ case AK4951_31_DEVICE_INFO:
+ case AK4951_32_E1_COEFFICIENT0:
+ case AK4951_33_E1_COEFFICIENT1:
+ case AK4951_34_E1_COEFFICIENT2:
+ case AK4951_35_E1_COEFFICIENT3:
+ case AK4951_36_E1_COEFFICIENT4:
+ case AK4951_37_E1_COEFFICIENT5:
+ case AK4951_38_E2_COEFFICIENT0:
+ case AK4951_39_E2_COEFFICIENT1:
+ case AK4951_3A_E2_COEFFICIENT2:
+ case AK4951_3B_E2_COEFFICIENT3:
+ case AK4951_3C_E2_COEFFICIENT4:
+ case AK4951_3D_E2_COEFFICIENT5:
+ case AK4951_3E_E3_COEFFICIENT0:
+ case AK4951_3F_E3_COEFFICIENT1:
+ case AK4951_40_E3_COEFFICIENT2:
+ case AK4951_41_E3_COEFFICIENT3:
+ case AK4951_42_E3_COEFFICIENT4:
+ case AK4951_43_E3_COEFFICIENT5:
+ case AK4951_44_E4_COEFFICIENT0:
+ case AK4951_45_E4_COEFFICIENT1:
+ case AK4951_46_E4_COEFFICIENT2:
+ case AK4951_47_E4_COEFFICIENT3:
+ case AK4951_48_E4_COEFFICIENT4:
+ case AK4951_49_E4_COEFFICIENT5:
+ case AK4951_4A_E5_COEFFICIENT0:
+ case AK4951_4B_E5_COEFFICIENT1:
+ case AK4951_4C_E5_COEFFICIENT2:
+ case AK4951_4D_E5_COEFFICIENT3:
+ case AK4951_4E_E5_COEFFICIENT4:
+ case AK4951_4F_E5_COEFFICIENT5:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+static inline int aK4951_reset(struct regmap *map)
+{
+ return regmap_write(map, AK4951_00_POWER_MANAGEMENT1, 0x00);
+}
+
+/*
+ * MIC Gain control:
+ * from 6 to 26 dB in 6.5 dB steps
+ *
+ * MIC Gain control: (table 39)
+ *
+ * max : 0x00 : +12.0 dB
+ * ( 0.5 dB step )
+ * min : 0xFE : -115.0 dB
+ * mute: 0xFF
+ */
+static DECLARE_TLV_DB_SCALE(mgain_tlv, 600, 650, 0);
+
+/*
+ * Input Digital volume control: (Table 44)
+ *
+ * max : 0xF1 : +36.0 dB
+ * ( 0.375 dB step )
+ * min : 0x00 : -54.375 dB
+ * mute: 0x00 - 0x04
+ * from -54.375 to 36 dB in 0.375 dB steps mute instead of -54.375 dB)
+ */
+static DECLARE_TLV_DB_SCALE(ivol_tlv, -5437, 37, 1);
+
+/*
+ * Speaker output volume control: (Table 55)
+ *
+ * max : 0x11: +14.9dB
+ * 0x10: +11.1dB
+ * 0x01: +8.4 dB
+ * min : 0x00: +6.4 dB
+ * from 6.4 to 14.9 dB in 2.8 dB steps
+ */
+static DECLARE_TLV_DB_SCALE(spkout_tlv, 640, 280, 0);
+
+/*
+ * Output Digital volume control: (Table 49)
+ * (This can be used as Bluetooth I/F output volume)
+ *
+ * max : 0x00: +12.0 dB
+ * ( 0.5 dB step )
+ * min : 0x90: -66.0 dB
+ * from -90.0 to 12 dB in 0.5 dB steps (mute instead of -90.0 dB)
+ */
+static DECLARE_TLV_DB_SCALE(dvol_tlv, -9000, 50, 1);
+
+/*
+ * Programmable Filter Output volume control: (Table 46)
+ *
+ * max : 0x00: 0.0 dB
+ * ( 6 dB step )
+ * min : 0x11: -18.0 dB
+ * from -18 to 0 dB in 6 dB steps
+ */
+//static DECLARE_TLV_DB_SCALE(pfvol_tlv, -1800, 600, 0);
+
+/*For our Board -- cddiao*/
+static const char *mic_and_lin_select[] =
+{
+ "LIN",
+ "MIC",
+};
+
+
+static const struct soc_enum ak4951_micswitch_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mic_and_lin_select), mic_and_lin_select),
+};
+
+
+static int get_micstatus(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct ak4951_priv *ak4951 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = ak4951->mic;
+
+ return 0;
+
+}
+
+static int set_micstatus(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct ak4951_priv *ak4951 = snd_soc_codec_get_drvdata(codec);
+
+ ak4951->mic = ucontrol->value.enumerated.item[0];
+
+ if ( ak4951->mic ) {
+ snd_soc_update_bits(codec,AK4951_03_SIGNAL_SELECT2,0x0f,0x05);// LIN2 RIN2
+ }else {
+ snd_soc_update_bits(codec,AK4951_03_SIGNAL_SELECT2,0x0f,0x0a);// LIN3 RIN3
+ }
+ return 0;
+}
+
+
+
+static const char *stereo_on_select[] =
+{
+ "Stereo Emphasis Filter OFF",
+ "Stereo Emphasis Filter ON",
+};
+
+static const struct soc_enum ak4951_stereo_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(stereo_on_select), stereo_on_select),
+};
+
+static int ak4951_writeMask(struct snd_soc_codec *, u16, u16, u16);
+
+static int get_onstereo(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct ak4951_priv *ak4951 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = ak4951->onStereo;
+
+ return 0;
+
+}
+
+static int set_onstereo(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct ak4951_priv *ak4951 = snd_soc_codec_get_drvdata(codec);
+
+ ak4951->onStereo = ucontrol->value.enumerated.item[0];
+
+ if ( ak4951->onStereo ) {
+ ak4951_writeMask(codec, AK4951_1C_DIGITAL_FILTER_SELECT2, 0x30, 0x30);
+ }
+ else {
+ ak4951_writeMask(codec, AK4951_1C_DIGITAL_FILTER_SELECT2, 0x30, 0x00);
+ }
+
+ return 0;
+}
+
+#ifdef AK4951_DEBUG
+static const char *test_reg_select[] =
+{
+ "read AK4951 Reg 00:2F",
+ "read AK4951 Reg 30:4F",
+};
+
+static const struct soc_enum ak4951_enum[] =
+{
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(test_reg_select), test_reg_select),
+};
+
+static int nTestRegNo = 0;
+
+static int get_test_reg(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ /* Get the current output routing */
+ ucontrol->value.enumerated.item[0] = nTestRegNo;
+
+ return 0;
+
+}
+
+static int set_test_reg(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ u32 currMode = ucontrol->value.enumerated.item[0];
+ int i, value;
+ int regs, rege;
+
+ nTestRegNo = currMode;
+
+ switch(nTestRegNo) {
+ case 1:
+ regs = 0x30;
+ rege = 0x4F;
+ break;
+ default:
+ regs = 0x00;
+ rege = 0x2F;
+ break;
+ }
+
+ for ( i = regs ; i <= rege ; i++ ){
+ value = snd_soc_read(codec, i);
+ printk("***AK4951 Addr,Reg=(%x, %x)\n", i, value);
+ }
+
+ return(0);
+
+}
+#endif
+
+static const struct snd_kcontrol_new ak4951_snd_controls[] = {
+ SOC_SINGLE_TLV("Mic Gain Control",
+ AK4951_02_SIGNAL_SELECT1, 0, 0x07, 0, mgain_tlv),
+ SOC_SINGLE_TLV("Input Digital Volume",
+ AK4951_0D_LCH_INPUT_VOLUME_CONTROL, 0, 0xF1, 0, ivol_tlv),
+ SOC_SINGLE_TLV("Speaker Output Volume",
+ AK4951_03_SIGNAL_SELECT2, 6, 0x03, 0, spkout_tlv),
+ SOC_SINGLE_TLV("Digital Output Volume",
+ AK4951_13_LCH_DIGITAL_VOLUME_CONTROL, 0, 0xFF, 1, dvol_tlv),
+
+ SOC_SINGLE("High Path Filter 1", AK4951_1B_DIGITAL_FILTER_SELECT1, 1, 3, 0),
+ SOC_SINGLE("High Path Filter 2", AK4951_1C_DIGITAL_FILTER_SELECT2, 0, 1, 0),
+ SOC_SINGLE("Low Path Filter", AK4951_1C_DIGITAL_FILTER_SELECT2, 1, 1, 0),
+ SOC_SINGLE("5 Band Equalizer 1", AK4951_30_DIGITAL_FILTER_SELECT3, 0, 1, 0),
+ SOC_SINGLE("5 Band Equalizer 2", AK4951_30_DIGITAL_FILTER_SELECT3, 1, 1, 0),
+ SOC_SINGLE("5 Band Equalizer 3", AK4951_30_DIGITAL_FILTER_SELECT3, 2, 1, 0),
+ SOC_SINGLE("5 Band Equalizer 4", AK4951_30_DIGITAL_FILTER_SELECT3, 3, 1, 0),
+ SOC_SINGLE("5 Band Equalizer 5", AK4951_30_DIGITAL_FILTER_SELECT3, 4, 1, 0),
+ SOC_SINGLE("Auto Level Control 1", AK4951_0B_ALC_MODE_CONTROL1, 5, 1, 0),
+ SOC_SINGLE("Soft Mute Control", AK4951_07_MODE_CONTROL3, 5, 1, 0),
+ SOC_ENUM_EXT("Stereo Emphasis Filter Control", ak4951_stereo_enum[0], get_onstereo, set_onstereo),
+ SOC_ENUM_EXT("Mic and Lin Switch",ak4951_micswitch_enum[0],get_micstatus,set_micstatus),
+#ifdef AK4951_DEBUG
+ SOC_ENUM_EXT("Reg Read", ak4951_enum[0], get_test_reg, set_test_reg),
+#endif
+
+
+};
+
+static const char *ak4951_lin_select_texts[] =
+ {"LIN1", "LIN2", "LIN3"};
+
+static const struct soc_enum ak4951_lin_mux_enum =
+ SOC_ENUM_SINGLE(AK4951_03_SIGNAL_SELECT2, 2,
+ ARRAY_SIZE(ak4951_lin_select_texts), ak4951_lin_select_texts);
+
+static const struct snd_kcontrol_new ak4951_lin_mux_control =
+ SOC_DAPM_ENUM("LIN Select", ak4951_lin_mux_enum);
+
+static const char *ak4951_rin_select_texts[] =
+ {"RIN1", "RIN2", "RIN3"};
+
+static const struct soc_enum ak4951_rin_mux_enum =
+ SOC_ENUM_SINGLE(AK4951_03_SIGNAL_SELECT2, 0,
+ ARRAY_SIZE(ak4951_rin_select_texts), ak4951_rin_select_texts);
+
+static const struct snd_kcontrol_new ak4951_rin_mux_control =
+ SOC_DAPM_ENUM("RIN Select", ak4951_rin_mux_enum);
+//////////////////////////////////////////
+static const char *ak4951_lin1_select_texts[] =
+ {"LIN1", "Mic Bias"};
+
+static const struct soc_enum ak4951_lin1_mux_enum =
+ SOC_ENUM_SINGLE(0, 0,
+ ARRAY_SIZE(ak4951_lin1_select_texts), ak4951_lin1_select_texts);
+
+static const struct snd_kcontrol_new ak4951_lin1_mux_control =
+ SOC_DAPM_ENUM_VIRT("LIN1 Switch", ak4951_lin1_mux_enum);
+////////////////////////////////////////////
+
+static const char *ak4951_micbias_select_texts[] =
+ {"LIN1", "LIN2"};
+
+static const struct soc_enum ak4951_micbias_mux_enum =
+ SOC_ENUM_SINGLE(AK4951_02_SIGNAL_SELECT1, 4,
+ ARRAY_SIZE(ak4951_micbias_select_texts), ak4951_micbias_select_texts);
+
+static const struct snd_kcontrol_new ak4951_micbias_mux_control =
+ SOC_DAPM_ENUM("MIC bias Select", ak4951_micbias_mux_enum);
+
+static const char *ak4951_spklo_select_texts[] =
+ {"Speaker", "Line"};
+
+static const struct soc_enum ak4951_spklo_mux_enum =
+ SOC_ENUM_SINGLE(AK4951_01_POWER_MANAGEMENT2, 0,
+ ARRAY_SIZE(ak4951_spklo_select_texts), ak4951_spklo_select_texts);
+
+static const struct snd_kcontrol_new ak4951_spklo_mux_control =
+ SOC_DAPM_ENUM("SPKLO Select", ak4951_spklo_mux_enum);
+
+static const char *ak4951_adcpf_select_texts[] =
+ {"SDTI", "ADC"};
+
+static const struct soc_enum ak4951_adcpf_mux_enum =
+ SOC_ENUM_SINGLE(AK4951_1D_DIGITAL_FILTER_MODE, 1,
+ ARRAY_SIZE(ak4951_adcpf_select_texts), ak4951_adcpf_select_texts);
+
+static const struct snd_kcontrol_new ak4951_adcpf_mux_control =
+ SOC_DAPM_ENUM("ADCPF Select", ak4951_adcpf_mux_enum);
+
+
+static const char *ak4951_pfsdo_select_texts[] =
+ {"ADC", "PFIL"};
+
+static const struct soc_enum ak4951_pfsdo_mux_enum =
+ SOC_ENUM_SINGLE(AK4951_1D_DIGITAL_FILTER_MODE, 0,
+ ARRAY_SIZE(ak4951_pfsdo_select_texts), ak4951_pfsdo_select_texts);
+
+static const struct snd_kcontrol_new ak4951_pfsdo_mux_control =
+ SOC_DAPM_ENUM("PFSDO Select", ak4951_pfsdo_mux_enum);
+
+static const char *ak4951_pfdac_select_texts[] =
+ {"SDTI", "PFIL", "SPMIX"};
+
+static const struct soc_enum ak4951_pfdac_mux_enum =
+ SOC_ENUM_SINGLE(AK4951_1D_DIGITAL_FILTER_MODE, 2,
+ ARRAY_SIZE(ak4951_pfdac_select_texts), ak4951_pfdac_select_texts);
+
+static const struct snd_kcontrol_new ak4951_pfdac_mux_control =
+ SOC_DAPM_ENUM("PFDAC Select", ak4951_pfdac_mux_enum);
+
+
+static const char *ak4951_mic_select_texts[] =
+ {"AMIC", "DMIC"};
+
+static const struct soc_enum ak4951_mic_mux_enum =
+ SOC_ENUM_SINGLE(AK4951_08_DIGITL_MIC, 0,
+ ARRAY_SIZE(ak4951_mic_select_texts), ak4951_mic_select_texts);
+
+static const struct snd_kcontrol_new ak4951_mic_mux_control =
+ SOC_DAPM_ENUM("MIC Select", ak4951_mic_mux_enum);
+
+
+static const struct snd_kcontrol_new ak4951_dacsl_mixer_controls[] = {
+ SOC_DAPM_SINGLE("DACSL", AK4951_02_SIGNAL_SELECT1, 5, 1, 0),
+};
+
+static int ak4951_spklo_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event) //CONFIG_LINF
+{
+ struct snd_soc_codec *codec = w->codec;
+ u32 reg, nLOSEL;
+
+ akdbgprt("\t[AK4951] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ reg = snd_soc_read(codec, AK4951_01_POWER_MANAGEMENT2);
+ nLOSEL = (0x1 & reg);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU: /* before widget power up */
+ break;
+ case SND_SOC_DAPM_POST_PMU: /* after widget power up */
+ if ( nLOSEL ) {
+ akdbgprt("\t[AK4951] %s wait=300msec\n",__FUNCTION__);
+ mdelay(300);
+ }
+ else {
+ akdbgprt("\t[AK4951] %s wait=1msec\n",__FUNCTION__);
+ mdelay(1);
+ }
+ snd_soc_update_bits(codec, AK4951_02_SIGNAL_SELECT1, 0x80,0x80);
+ break;
+ case SND_SOC_DAPM_PRE_PMD: /* before widget power down */
+ snd_soc_update_bits(codec, AK4951_02_SIGNAL_SELECT1, 0x80,0x00);
+ mdelay(1);
+ break;
+ case SND_SOC_DAPM_POST_PMD: /* after widget power down */
+ if ( nLOSEL ) {
+ akdbgprt("\t[AK4951] %s wait=300msec\n",__FUNCTION__);
+ mdelay(300);
+ }
+ break;
+ }
+
+ return 0;
+}
+
+static const struct snd_soc_dapm_widget ak4951_dapm_widgets[] = {
+
+// ADC, DAC
+ SND_SOC_DAPM_ADC("ADC Left", "NULL", AK4951_00_POWER_MANAGEMENT1, 0, 0),
+ SND_SOC_DAPM_ADC("ADC Right", "NULL", AK4951_00_POWER_MANAGEMENT1, 1, 0),
+ SND_SOC_DAPM_DAC("DAC", "NULL", AK4951_00_POWER_MANAGEMENT1, 2, 0),
+
+#ifdef PLL_32BICK_MODE
+ SND_SOC_DAPM_SUPPLY("PMPLL", AK4951_01_POWER_MANAGEMENT2, 2, 0, NULL, 0),
+#else
+#ifdef PLL_64BICK_MODE
+ SND_SOC_DAPM_SUPPLY("PMPLL", AK4951_01_POWER_MANAGEMENT2, 2, 0, NULL, 0),
+#endif
+#endif
+
+ SND_SOC_DAPM_ADC("PFIL", "NULL", AK4951_00_POWER_MANAGEMENT1, 7, 0),
+
+ SND_SOC_DAPM_ADC("DMICL", "NULL", AK4951_08_DIGITL_MIC, 4, 0),
+ SND_SOC_DAPM_ADC("DMICR", "NULL", AK4951_08_DIGITL_MIC, 5, 0),
+
+ SND_SOC_DAPM_AIF_OUT("SDTO", "Capture", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("SDTI", "Playback", 0, SND_SOC_NOPM, 0, 0),
+
+// Analog Output
+ SND_SOC_DAPM_OUTPUT("HPL"),
+ SND_SOC_DAPM_OUTPUT("HPR"),
+ SND_SOC_DAPM_OUTPUT("SPKLO"),
+
+ SND_SOC_DAPM_PGA("HPL Amp", AK4951_01_POWER_MANAGEMENT2, 4, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("HPR Amp", AK4951_01_POWER_MANAGEMENT2, 5, 0, NULL, 0),
+
+ SND_SOC_DAPM_PGA("SPK Amp", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Line Amp", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_MIXER_E("SPKLO Mixer", AK4951_01_POWER_MANAGEMENT2, 1, 0,
+ &ak4951_dacsl_mixer_controls[0], ARRAY_SIZE(ak4951_dacsl_mixer_controls),
+ ak4951_spklo_event, (SND_SOC_DAPM_POST_PMU |SND_SOC_DAPM_PRE_PMD
+ |SND_SOC_DAPM_PRE_PMU |SND_SOC_DAPM_POST_PMD)),
+
+// Analog Input
+ SND_SOC_DAPM_INPUT("LIN1"),
+ SND_SOC_DAPM_INPUT("RIN1"),
+ SND_SOC_DAPM_INPUT("LIN2"),
+ SND_SOC_DAPM_INPUT("RIN2"),
+ SND_SOC_DAPM_INPUT("LIN3"),
+ SND_SOC_DAPM_INPUT("RIN3"),
+
+ SND_SOC_DAPM_MUX("LIN MUX", SND_SOC_NOPM, 0, 0, &ak4951_lin_mux_control),
+ SND_SOC_DAPM_MUX("RIN MUX", SND_SOC_NOPM, 0, 0, &ak4951_rin_mux_control),
+
+// MIC Bias
+ SND_SOC_DAPM_MICBIAS("Mic Bias", AK4951_02_SIGNAL_SELECT1, 3, 0),
+ SND_SOC_DAPM_VIRT_MUX("LIN1 MUX", SND_SOC_NOPM, 0, 0, &ak4951_lin1_mux_control),
+ SND_SOC_DAPM_MUX("Mic Bias MUX", SND_SOC_NOPM, 0, 0, &ak4951_micbias_mux_control),
+ SND_SOC_DAPM_MUX("SPKLO MUX", SND_SOC_NOPM, 0, 0, &ak4951_spklo_mux_control),
+
+
+// PFIL
+ SND_SOC_DAPM_MUX("PFIL MUX", SND_SOC_NOPM, 0, 0, &ak4951_adcpf_mux_control),
+ SND_SOC_DAPM_MUX("PFSDO MUX", SND_SOC_NOPM, 0, 0, &ak4951_pfsdo_mux_control),
+ SND_SOC_DAPM_MUX("PFDAC MUX", SND_SOC_NOPM, 0, 0, &ak4951_pfdac_mux_control),
+
+// Digital Mic
+ SND_SOC_DAPM_INPUT("DMICLIN"),
+ SND_SOC_DAPM_INPUT("DMICRIN"),
+
+ SND_SOC_DAPM_VIRT_MUX("MIC MUX", SND_SOC_NOPM, 0, 0, &ak4951_mic_mux_control),
+
+};
+
+
+static const struct snd_soc_dapm_route ak4951_intercon[] = {
+
+#ifdef PLL_32BICK_MODE
+ {"ADC Left", "NULL", "PMPLL"},
+ {"ADC Right", "NULL", "PMPLL"},
+ {"DAC", "NULL", "PMPLL"},
+#else
+#ifdef PLL_64BICK_MODE
+ {"ADC Left", "NULL", "PMPLL"},
+ {"ADC Right", "NULL", "PMPLL"},
+ {"DAC", "NULL", "PMPLL"},
+#endif
+#endif
+
+ {"Mic Bias MUX", "LIN1", "LIN1"},
+ {"Mic Bias MUX", "LIN2", "LIN2"},
+
+ {"Mic Bias", "NULL", "Mic Bias MUX"},
+
+ {"LIN1 MUX", "LIN1", "LIN1"},
+ {"LIN1 MUX", "Mic Bias", "Mic Bias"},
+
+ {"LIN MUX", "LIN1", "LIN1 MUX"},
+ {"LIN MUX", "LIN2", "Mic Bias"},
+ {"LIN MUX", "LIN3", "LIN3"},
+ {"RIN MUX", "RIN1", "RIN1"},
+ {"RIN MUX", "RIN2", "RIN2"},
+ {"RIN MUX", "RIN3", "RIN3"},
+ {"ADC Left", "NULL", "LIN MUX"},
+ {"ADC Right", "NULL", "RIN MUX"},
+
+ {"DMICL", "NULL", "DMICLIN"},
+ {"DMICR", "NULL", "DMICRIN"},
+
+ {"MIC MUX", "AMIC", "ADC Left"},
+ {"MIC MUX", "AMIC", "ADC Right"},
+ {"MIC MUX", "DMIC", "DMICL"},
+ {"MIC MUX", "DMIC", "DMICR"},
+
+ {"PFIL MUX", "SDTI", "SDTI"},
+ {"PFIL MUX", "ADC", "MIC MUX"},
+ {"PFIL", "NULL", "PFIL MUX"},
+
+ {"PFSDO MUX", "ADC", "MIC MUX"},
+ {"PFSDO MUX", "PFIL", "PFIL"},
+
+ {"SDTO", "NULL", "PFSDO MUX"},
+
+ {"PFDAC MUX", "SDTI", "SDTI"},
+ {"PFDAC MUX", "PFIL", "PFIL"},
+
+// {"DAC MUX", "PFDAC", "PFDAC MUX"},
+ {"DAC", "NULL", "PFDAC MUX"},
+
+// {"DAC", "NULL", "DAC MUX"},
+
+ {"HPL Amp", "NULL", "DAC"},
+ {"HPR Amp", "NULL", "DAC"},
+ {"HPL", "NULL", "HPL Amp"},
+ {"HPR", "NULL", "HPR Amp"},
+
+ {"SPKLO Mixer", "DACSL", "DAC"},
+ {"SPK Amp", "NULL", "SPKLO Mixer"},
+ {"Line Amp", "NULL", "SPKLO Mixer"},
+ {"SPKLO MUX", "Speaker", "SPK Amp"},
+ {"SPKLO MUX", "Line", "Line Amp"},
+ {"SPKLO", "NULL", "SPKLO MUX"},
+
+};
+
+static int ak4951_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ int rate = params_rate(params);
+ struct ak4951_priv *ak4951 = snd_soc_codec_get_drvdata(codec);
+ int oversample = 0;
+ u8 fs = 0;
+ akdbgprt("\t[AK4951] %s(%d)\n",__FUNCTION__,__LINE__);
+ oversample = ak4951->sysclk / rate;
+ switch (oversample) {
+ case 256:
+ fs &= (~AK4951_FS_CM1);
+ fs &= (~AK4951_FS_CM0);
+ break;
+ case 384:
+ fs &= (~AK4951_FS_CM1);
+ fs |= AK4951_FS_CM0;
+ break;
+ case 512:
+ fs |= AK4951_FS_CM1;
+ fs &= (~AK4951_FS_CM0);
+ break;
+ case 1024:
+ fs |= AK4951_FS_CM1;
+ fs |= AK4951_FS_CM0;
+ break;
+ default:
+ break;
+ }
+
+ if(ak4951->clkid == AK4951_BCLK_IN) {
+ switch (rate) {
+ case 8000:
+ fs |= AK4951_BICK_FS_8KHZ;
+ break;
+ case 11025:
+ fs |= AK4951_BICK_FS_11_025KHZ;
+ break;
+ case 12000:
+ fs |= AK4951_BICK_FS_12KHZ;
+ break;
+ case 16000:
+ fs |= AK4951_BICK_FS_16KHZ;
+ break;
+ case 22050:
+ fs |= AK4951_BICK_FS_22_05KHZ;
+ break;
+ case 24000:
+ fs |= AK4951_BICK_FS_24KHZ;
+ break;
+ case 32000:
+ fs |= AK4951_BICK_FS_32KHZ;
+ break;
+ case 44100:
+ fs |= AK4951_BICK_FS_44_1KHZ;
+ break;
+ case 48000:
+ fs |= AK4951_BICK_FS_48KHZ;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ } else {
+ switch (rate) {
+ case 8000:
+ fs |= AK4951_MCKI_FS_8KHZ;
+ break;
+ case 11025:
+ fs |= AK4951_MCKI_FS_11_025KHZ;
+ break;
+ case 12000:
+ fs |= AK4951_MCKI_FS_12KHZ;
+ break;
+ case 16000:
+ fs |= AK4951_MCKI_FS_16KHZ;
+ break;
+ case 22050:
+ fs |= AK4951_MCKI_FS_22_05KHZ;
+ break;
+ case 24000:
+ fs |= AK4951_MCKI_FS_24KHZ;
+ break;
+ case 32000:
+ fs |= AK4951_MCKI_FS_32KHZ;
+ break;
+ case 44100:
+ fs |= AK4951_MCKI_FS_44_1KHZ;
+ break;
+ case 48000:
+ fs |= AK4951_MCKI_FS_48KHZ;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ }
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ ak4951->fmt = 2 << 4;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ak4951->fmt = 3 << 4;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ ak4951->fmt = 3 << 4;
+ break;
+ default:
+ dev_err(codec->dev, "Can not support the format");
+ return -EINVAL;
+ }
+ snd_soc_write(codec, AK4951_06_MODE_CONTROL2, fs);
+
+ return 0;
+}
+
+static int ak4951_set_pll(u8 *pll, int clk_id,int freq)
+{
+ if (clk_id == AK4951_MCLK_IN_BCLK_OUT){
+ switch (freq) {
+ case 11289600:
+ *pll |= (4 << 4);
+ break;
+ case 12288000:
+ *pll |= (5 << 4);
+ break;
+ case 12000000:
+ *pll |= (6 << 4);
+ break;
+ case 24000000:
+ *pll |= (7 << 4);
+ break;
+ case 13500000:
+ *pll |= (0xC << 4);
+ break;
+ case 27000000:
+ *pll |= (0xD << 4);
+ break;
+ default:
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int ak4951_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
+ unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct ak4951_priv *ak4951 = snd_soc_codec_get_drvdata(codec);
+ u8 pllpwr = 0, pll = 0;
+
+ akdbgprt("\t[AK4951] %s(%d),CLK id is %d\n",__FUNCTION__,__LINE__, clk_id);
+
+ pll= snd_soc_read(codec, AK4951_05_MODE_CONTROL1);
+ akdbgprt("\t[AK4951] pll valuse is 0x%x\n",pll);
+ pll &=(~0xF0);
+ pllpwr = snd_soc_read(codec,AK4951_01_POWER_MANAGEMENT2);
+ akdbgprt("\t[AK4951] pllpwr valuse is 0x%x\n",pllpwr);
+ pllpwr &=(~0x0c);
+
+ if (clk_id == AK4951_MCLK_IN) {
+ pll |= AK4951_PLL_12_288MHZ;
+ pllpwr &= (~AK4951_PMPLL);
+ pllpwr &= (~AK4951_M_S);
+ }else if (clk_id == AK4951_BCLK_IN) {
+ pllpwr |= AK4951_PMPLL;
+ pllpwr &= (~AK4951_M_S);
+ pll |= ak4951->fmt;
+ }else if (clk_id == AK4951_MCLK_IN_BCLK_OUT) {
+ pllpwr |= AK4951_PMPLL;
+ pllpwr |= AK4951_M_S;
+ ak4951_set_pll(&pll, clk_id, freq);
+ }
+ snd_soc_write(codec, AK4951_05_MODE_CONTROL1, pll);
+ snd_soc_write(codec, AK4951_01_POWER_MANAGEMENT2, pllpwr);
+ msleep(5); //AKM suggested
+
+ ak4951->sysclk = freq;
+ ak4951->clkid = clk_id;
+ return 0;
+}
+
+static int ak4951_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+
+ struct snd_soc_codec *codec = dai->codec;
+ u8 mode;
+ u8 format;
+
+ akdbgprt("\t[AK4951] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ /* set master/slave audio interface */
+ mode = snd_soc_read(codec, AK4951_01_POWER_MANAGEMENT2);
+ format = snd_soc_read(codec, AK4951_05_MODE_CONTROL1);
+ format &= ~AK4951_DIF;
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ akdbgprt("\t[AK4951] %s(Slave)\n",__FUNCTION__);
+ mode &= ~(AK4951_M_S);
+ //format &= ~(AK4951_BCKO);
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+ akdbgprt("\t[AK4951] %s(Master)\n",__FUNCTION__);
+ mode |= AK4951_M_S;
+ //format |= (AK4951_BCKO);
+ break;
+ case SND_SOC_DAIFMT_CBS_CFM:
+ case SND_SOC_DAIFMT_CBM_CFS:
+ default:
+ dev_err(codec->dev, "Clock mode unsupported");
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ format |= AK4951_DIF_I2S_MODE;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ format |= AK4951_DIF_24MSB_MODE;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* set mode and format */
+
+ snd_soc_write(codec, AK4951_01_POWER_MANAGEMENT2, mode);
+ snd_soc_write(codec, AK4951_05_MODE_CONTROL1, format);
+
+ return 0;
+}
+
+/*
+ * Write with Mask to AK4951 register space
+ */
+static int ak4951_writeMask(
+struct snd_soc_codec *codec,
+u16 reg,
+u16 mask,
+u16 value)
+{
+ u16 olddata;
+ u16 newdata;
+
+ if ( (mask == 0) || (mask == 0xFF) ) {
+ newdata = value;
+ }
+ else {
+ olddata = snd_soc_read(codec, reg);
+ newdata = (olddata & ~(mask)) | value;
+ }
+
+ snd_soc_write(codec, (unsigned int)reg, (unsigned int)newdata);
+
+ akdbgprt("\t[ak4951_writeMask] %s(%d): (addr,data)=(%x, %x)\n",__FUNCTION__,__LINE__, reg, newdata);
+
+ return(0);
+}
+
+// * for AK4951
+static int ak4951_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *codec_dai)
+{
+ int ret = 0;
+ // struct snd_soc_codec *codec = codec_dai->codec;
+
+ akdbgprt("\t[AK4951] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ return ret;
+}
+
+
+static int ak4951_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ u8 reg;
+
+ akdbgprt("\t[AK4951] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ case SND_SOC_BIAS_PREPARE:
+ case SND_SOC_BIAS_STANDBY:
+ reg = snd_soc_read(codec, AK4951_00_POWER_MANAGEMENT1); // * for AK4951
+ snd_soc_write(codec, AK4951_00_POWER_MANAGEMENT1, // * for AK4951
+ reg | AK4951_PMVCM | AK4951_PMPFIL);
+ msleep(250); //AKM suggested
+ break;
+ case SND_SOC_BIAS_OFF:
+ snd_soc_write(codec, AK4951_00_POWER_MANAGEMENT1, 0x00); // * for AK4951
+ break;
+ }
+ codec->dapm.bias_level = level;
+ return 0;
+}
+
+#define AK4951_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
+ SNDRV_PCM_RATE_96000)
+
+#define AK4951_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_ops ak4951_dai_ops = {
+ .hw_params = ak4951_hw_params,
+ .set_sysclk = ak4951_set_dai_sysclk,
+ .set_fmt = ak4951_set_dai_fmt,
+ .trigger = ak4951_trigger,
+};
+
+struct snd_soc_dai_driver ak4951_dai[] = {
+ {
+ .name = "ak4951-hifi",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = AK4951_RATES,
+ .formats = AK4951_FORMATS,
+ },
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = AK4951_RATES,
+ .formats = AK4951_FORMATS,
+ },
+ .ops = &ak4951_dai_ops,
+ },
+};
+
+static int ak4951_probe(struct snd_soc_codec *codec)
+{
+ struct ak4951_priv *ak4951 = ak4951_data;
+ int ret = 0;
+
+ akdbgprt("\t[AK4951] %s(%d)\n",__FUNCTION__,__LINE__);
+ codec->control_data = ak4951->regmap;
+ snd_soc_codec_set_drvdata(codec, ak4951);
+ ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
+ }
+
+ akdbgprt("\t[AK4951] %s(%d) ak4951=%x\n",__FUNCTION__,__LINE__, (int)ak4951);
+
+ ret = devm_gpio_request(codec->dev, ak4951->rst_pin, "ak4951 reset");
+ if (ret < 0){
+ dev_err(codec->dev, "Failed to request rst_pin: %d\n", ret);
+ return ret;
+ }
+
+ /* Reset AK4951 codec */
+ gpio_direction_output(ak4951->rst_pin, ak4951->rst_active);
+ msleep(1);
+ gpio_direction_output(ak4951->rst_pin, !ak4951->rst_active);
+
+ /*The 0x00 register no Ack for the dummy command:write 0x00 to 0x00*/
+ ak4951->i2c_clt->flags |= I2C_M_IGNORE_NAK;
+ i2c_smbus_write_byte_data(ak4951->i2c_clt, (u8)(AK4951_00_POWER_MANAGEMENT1 & 0xFF), 0x00);
+ ak4951->i2c_clt->flags &= ~I2C_M_IGNORE_NAK;
+
+ ak4951_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ akdbgprt("\t[AK4951 bias] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ ak4951->onStereo = 0;
+ ak4951->mic = 1;
+ /*Enable Line out */
+ snd_soc_update_bits(codec,AK4951_01_POWER_MANAGEMENT2,0x02,0x02);
+ snd_soc_update_bits(codec,AK4951_02_SIGNAL_SELECT1, 0xa0,0xa0);//0x10100110
+
+ /*Enable LIN2*/
+ snd_soc_update_bits(codec,AK4951_02_SIGNAL_SELECT1,0x18,0x08);//MPWR1
+ snd_soc_update_bits(codec,AK4951_03_SIGNAL_SELECT2,0x0f,0x05);// LIN2 RIN2
+ snd_soc_update_bits(codec,AK4951_08_DIGITL_MIC,0x01,0x00);//AMIC
+ snd_soc_update_bits(codec,AK4951_1D_DIGITAL_FILTER_MODE,0x02,0x02);//ADC output
+ snd_soc_update_bits(codec,AK4951_1D_DIGITAL_FILTER_MODE,0x01,0x01);//ALC output
+ snd_soc_update_bits(codec,AK4951_02_SIGNAL_SELECT1,0x47,0x00);//Mic Gain 0x10100110
+ snd_soc_update_bits(codec,AK4951_0D_LCH_INPUT_VOLUME_CONTROL,0xff,0xb0);//Lch gain
+ snd_soc_update_bits(codec,AK4951_0E_RCH_INPUT_VOLUME_CONTROL,0xff,0xb0);//Lch gain
+ snd_soc_write(codec, AK4951_0B_ALC_MODE_CONTROL1, 0x20); //enable ALC
+ snd_soc_write(codec, AK4951_1B_DIGITAL_FILTER_SELECT1, 0x07); //enable HPF1
+ snd_soc_write(codec, AK4951_0C_ALC_MODE_CONTROL2, 0xF1);
+ /*Enable LIN3*/
+ //snd_soc_update_bits(codec,AK4951_03_SIGNAL_SELECT2,0x0f,0x0a);// LIN3 RIN3
+ return ret;
+
+}
+
+static int ak4951_remove(struct snd_soc_codec *codec)
+{
+
+ akdbgprt("\t[AK4951] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ ak4951_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+
+ return 0;
+}
+
+static int ak4951_suspend(struct snd_soc_codec *codec)
+{
+ struct ak4951_priv *ak4951 = snd_soc_codec_get_drvdata(codec);
+ int i;
+
+ for(i = 0; i < 7; i++) {
+ ak4951->reg_cache[i] = snd_soc_read(codec, i);
+ }
+
+ ak4951_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+ return 0;
+}
+
+static int ak4951_resume(struct snd_soc_codec *codec)
+{
+ struct ak4951_priv *ak4951 = snd_soc_codec_get_drvdata(codec);
+ int i;
+
+ for(i = 0; i < 7; i++) {
+ snd_soc_write(codec, i, ak4951->reg_cache[i]);
+ }
+
+ ak4951_set_bias_level(codec, codec->dapm.bias_level);
+
+ return 0;
+}
+
+
+struct snd_soc_codec_driver soc_codec_dev_ak4951 = {
+ .probe = ak4951_probe,
+ .remove = ak4951_remove,
+ .suspend = ak4951_suspend,
+ .resume = ak4951_resume,
+
+ .set_bias_level = ak4951_set_bias_level,
+
+ .controls = ak4951_snd_controls,
+ .num_controls = ARRAY_SIZE(ak4951_snd_controls),
+ .dapm_widgets = ak4951_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(ak4951_dapm_widgets),
+ .dapm_routes = ak4951_intercon,
+ .num_dapm_routes = ARRAY_SIZE(ak4951_intercon),
+};
+EXPORT_SYMBOL_GPL(soc_codec_dev_ak4951);
+
+static struct regmap_config ak4951_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .max_register = AK4951_MAX_REGISTERS,
+ .reg_defaults = ak4951_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(ak4951_reg_defaults),
+ .volatile_reg = ak4951_volatile_register,
+ .cache_type = REGCACHE_RBTREE,
+};
+
+static int ak4951_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct device_node *np = i2c->dev.of_node;
+ struct ak4951_priv *ak4951;
+ enum of_gpio_flags flags;
+ int rst_pin;
+ int ret = 0;
+
+ akdbgprt("\t[AK4951] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ ak4951 = devm_kzalloc(&i2c->dev, sizeof(struct ak4951_priv), GFP_KERNEL);
+ if (ak4951 == NULL)
+ return -ENOMEM;
+
+ rst_pin = of_get_gpio_flags(np, 0, &flags);
+ if (rst_pin < 0 || !gpio_is_valid(rst_pin))
+ return -ENXIO;
+
+ ak4951->i2c_clt = i2c;
+ ak4951->rst_pin = rst_pin;
+ ak4951->rst_active = !!(flags & OF_GPIO_ACTIVE_LOW);
+ i2c_set_clientdata(i2c, ak4951);
+ ak4951->regmap = devm_regmap_init_i2c(i2c, &ak4951_regmap);
+ if (IS_ERR(ak4951->regmap)) {
+ ret = PTR_ERR(ak4951->regmap);
+ dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
+ return ret;
+ }
+
+ ak4951_data = ak4951;
+
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_ak4951, &ak4951_dai[0], ARRAY_SIZE(ak4951_dai));
+ if (ret < 0){
+ kfree(ak4951);
+ akdbgprt("\t[AK4951 Error!] %s(%d)\n",__FUNCTION__,__LINE__);
+ }
+ return ret;
+}
+
+static int ak4951_i2c_remove(struct i2c_client *client)
+{
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
+ return 0;
+}
+
+static struct of_device_id ak4951_of_match[] = {
+ { .compatible = "ambarella,ak4951",},
+ {},
+};
+MODULE_DEVICE_TABLE(of, ak4951_of_match);
+
+static const struct i2c_device_id ak4951_i2c_id[] = {
+ { "ak4951", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ak4951_i2c_id);
+
+static struct i2c_driver ak4951_i2c_driver = {
+ .driver = {
+ .name = "ak4951-codec",
+ .owner = THIS_MODULE,
+ .of_match_table = ak4951_of_match,
+ },
+ .probe = ak4951_i2c_probe,
+ .remove = ak4951_i2c_remove,
+ .id_table = ak4951_i2c_id,
+};
+
+static int __init ak4951_modinit(void)
+{
+ int ret;
+ akdbgprt("\t[AK4951] %s(%d)\n", __FUNCTION__,__LINE__);
+
+ ret = i2c_add_driver(&ak4951_i2c_driver);
+ if (ret != 0)
+ pr_err("Failed to register ak4951 I2C driver: %d\n",ret);
+ return ret;
+}
+
+module_init(ak4951_modinit);
+
+static void __exit ak4951_exit(void)
+{
+ i2c_del_driver(&ak4951_i2c_driver);
+}
+module_exit(ak4951_exit);
+
+MODULE_DESCRIPTION("Soc AK4951 driver");
+MODULE_AUTHOR("Diao Chengdong<cddiao@ambarella.com>");
+MODULE_LICENSE("GPL");
+
diff --git a/sound/soc/codecs/ak4951_amb.h b/sound/soc/codecs/ak4951_amb.h
new file mode 100644
index 00000000..919ce5ed
--- /dev/null
+++ b/sound/soc/codecs/ak4951_amb.h
@@ -0,0 +1,167 @@
+/*
+ * ak4954_amb.h -- audio driver for AK4951
+ *
+ * Copyright 2014 Ambarella Ltd.
+ *
+ * Author: Diao Chengdong <cddiao@ambarella.com>
+ *
+ * History:
+ * 2014/03/27 - created
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
+#ifndef _AK4951_AMB_H
+#define _AK4951_AMB_H
+
+#define AK4954_CLOCK_PLAYBACK 1
+#define AK4954_CLOCK_CAPTURE 2
+#define AK4954_CLOCK_OTHER 4
+
+#define AK4951_00_POWER_MANAGEMENT1 0x00
+#define AK4951_01_POWER_MANAGEMENT2 0x01
+#define AK4951_02_SIGNAL_SELECT1 0x02
+#define AK4951_03_SIGNAL_SELECT2 0x03
+#define AK4951_04_SIGNAL_SELECT3 0x04
+#define AK4951_05_MODE_CONTROL1 0x05
+#define AK4951_06_MODE_CONTROL2 0x06
+#define AK4951_07_MODE_CONTROL3 0x07
+#define AK4951_08_DIGITL_MIC 0x08
+#define AK4951_09_TIMER_SELECT 0x09
+#define AK4951_0A_ALC_TIMER_SELECT 0x0A
+#define AK4951_0B_ALC_MODE_CONTROL1 0x0B
+#define AK4951_0C_ALC_MODE_CONTROL2 0x0C
+#define AK4951_0D_LCH_INPUT_VOLUME_CONTROL 0x0D
+#define AK4951_0E_RCH_INPUT_VOLUME_CONTROL 0x0E
+#define AK4951_0F_ALC_VOLUME 0x0F
+#define AK4951_10_LCH_MIC_GAIN_SETTING 0x10
+#define AK4951_11_RCH_MIC_GAIN_SETTING 0x11
+#define AK4951_12_BEEP_CONTROL 0x12
+#define AK4951_13_LCH_DIGITAL_VOLUME_CONTROL 0x13
+#define AK4951_14_RCH_DIGITAL_VOLUME_CONTROL 0x14
+#define AK4951_15_EQ_COMMON_GAIN_SELECT 0x15
+#define AK4951_16_EQ2_COMMON_GAIN_SELECT 0x16
+#define AK4951_17_EQ3_COMMON_GAIN_SELECT 0x17
+#define AK4951_18_EQ4_COMMON_GAIN_SELECT 0x18
+#define AK4951_19_EQ5_COMMON_GAIN_SELECT 0x19
+#define AK4951_1A_AUTO_HPF_CONTROL 0x1A
+#define AK4951_1B_DIGITAL_FILTER_SELECT1 0x1B
+#define AK4951_1C_DIGITAL_FILTER_SELECT2 0x1C
+#define AK4951_1D_DIGITAL_FILTER_MODE 0x1D
+#define AK4951_1E_HPF2_COEFFICIENT0 0x1E
+#define AK4951_1F_HPF2_COEFFICIENT1 0x1F
+#define AK4951_20_HPF2_COEFFICIENT2 0x20
+#define AK4951_21_HPF2_COEFFICIENT3 0x21
+#define AK4951_22_LPF_COEFFICIENT0 0x22
+#define AK4951_23_LPF_COEFFICIENT1 0x23
+#define AK4951_24_LPF_COEFFICIENT2 0x24
+#define AK4951_25_LPF_COEFFICIENT3 0x25
+#define AK4951_26_FIL3_COEFFICIENT0 0x26
+#define AK4951_27_FIL3_COEFFICIENT1 0x27
+#define AK4951_28_FIL3_COEFFICIENT2 0x28
+#define AK4951_29_FIL3_COEFFICIENT3 0x29
+#define AK4951_2A_EQ_COEFFICIENT0 0x2A
+#define AK4951_2B_EQ_COEFFICIENT1 0x2B
+#define AK4951_2C_EQ_COEFFICIENT2 0x2C
+#define AK4951_2D_EQ_COEFFICIENT3 0x2D
+#define AK4951_2E_EQ_COEFFICIENT4 0x2E
+#define AK4951_2F_EQ_COEFFICIENT5 0x2F
+
+#define AK4951_30_DIGITAL_FILTER_SELECT3 0x30
+#define AK4951_31_DEVICE_INFO 0x31
+#define AK4951_32_E1_COEFFICIENT0 0x32
+#define AK4951_33_E1_COEFFICIENT1 0x33
+#define AK4951_34_E1_COEFFICIENT2 0x34
+#define AK4951_35_E1_COEFFICIENT3 0x35
+#define AK4951_36_E1_COEFFICIENT4 0x36
+#define AK4951_37_E1_COEFFICIENT5 0x37
+#define AK4951_38_E2_COEFFICIENT0 0x38
+#define AK4951_39_E2_COEFFICIENT1 0x39
+#define AK4951_3A_E2_COEFFICIENT2 0x3A
+#define AK4951_3B_E2_COEFFICIENT3 0x3B
+#define AK4951_3C_E2_COEFFICIENT4 0x3C
+#define AK4951_3D_E2_COEFFICIENT5 0x3D
+#define AK4951_3E_E3_COEFFICIENT0 0x3E
+#define AK4951_3F_E3_COEFFICIENT1 0x3F
+#define AK4951_40_E3_COEFFICIENT2 0x40
+#define AK4951_41_E3_COEFFICIENT3 0x41
+#define AK4951_42_E3_COEFFICIENT4 0x42
+#define AK4951_43_E3_COEFFICIENT5 0x43
+#define AK4951_44_E4_COEFFICIENT0 0x44
+#define AK4951_45_E4_COEFFICIENT1 0x45
+#define AK4951_46_E4_COEFFICIENT2 0x46
+#define AK4951_47_E4_COEFFICIENT3 0x47
+#define AK4951_48_E4_COEFFICIENT4 0x48
+#define AK4951_49_E4_COEFFICIENT5 0x49
+#define AK4951_4A_E5_COEFFICIENT0 0x4A
+#define AK4951_4B_E5_COEFFICIENT1 0x4B
+#define AK4951_4C_E5_COEFFICIENT2 0x4C
+#define AK4951_4D_E5_COEFFICIENT3 0x4D
+#define AK4951_4E_E5_COEFFICIENT4 0x4E
+#define AK4951_4F_E5_COEFFICIENT5 0x4F
+
+#define AK4951_MAX_REGISTERS (AK4951_4F_E5_COEFFICIENT5 + 1)
+
+/* Bitfield Definitions */
+
+/* AK4954_00_POWER_MANAGEMENT1 (0x00) Fields */
+#define AK4951_PMVCM 0x40
+#define AK4951_PMPFIL 0x80
+
+/* AK4954_01_POWER_MANAGEMENT2 (0x01) Fields */
+#define AK4951_PMPLL 0x04
+#define AK4951_M_S 0x08
+
+/* AK4951_05_MODE_CONTROL1 (0x05) Fields */
+#define AK4951_DIF 0x03
+#define AK4951_DIF_24MSB_24LSB_MODE (0 << 0)
+#define AK4951_DIF_24MSB_16LSB_MODE (1 << 0)
+#define AK4951_DIF_24MSB_MODE (2 << 0)
+#define AK4951_DIF_I2S_MODE (3 << 0)
+#define AK4951_CKOFF 0x04
+#define AK4951_BCKO 0x08
+
+#define AK4951_PLL 0xF0
+#define AK4951_EXT_SLAVE 0
+#define AK4951_PLL_BICK32 (2 << 4)
+#define AK4951_PLL_BICK64 (3 << 4)
+#define AK4951_PLL_11_2896MHZ (4 << 4)
+#define AK4951_PLL_12_288MHZ (5 << 4)
+#define AK4951_PLL_12MHZ (6 << 4)
+#define AK4951_PLL_24MHZ (7 << 4)
+#define AK4951_PLL_13_5MHZ (12 << 4)
+#define AK4951_PLL_27MHZ (13 << 4)
+
+#define AK4951_MCLK_IN 0
+#define AK4951_BCLK_IN 1
+#define AK4951_MCLK_IN_BCLK_OUT 2
+
+/* AK4954_06_MODE_CONTROL2 (0x06) Fields */
+#define AK4951_FS 0x0F
+#define AK4951_MCKI_FS_8KHZ (0 << 0)
+#define AK4951_MCKI_FS_12KHZ (1 << 0)
+#define AK4951_MCKI_FS_16KHZ (2 << 0)
+#define AK4951_MCKI_FS_11_025KHZ (5 << 0)
+#define AK4951_MCKI_FS_22_05KHZ (7 << 0)
+#define AK4951_MCKI_FS_24KHZ (9 << 0)
+#define AK4951_MCKI_FS_32KHZ (10 << 0)
+#define AK4951_MCKI_FS_44_1KHZ (15 << 0)
+#define AK4951_MCKI_FS_48KHZ (11 << 0)
+
+#define AK4951_BICK_FS_8KHZ (0 << 0)
+#define AK4951_BICK_FS_12KHZ (1 << 0)
+#define AK4951_BICK_FS_16KHZ (5 << 0)
+#define AK4951_BICK_FS_11_025KHZ (2 << 0)
+#define AK4951_BICK_FS_22_05KHZ (7 << 0)
+#define AK4951_BICK_FS_24KHZ (6 << 0)
+#define AK4951_BICK_FS_32KHZ (10 << 0)
+#define AK4951_BICK_FS_44_1KHZ (8 << 0)
+#define AK4951_BICK_FS_48KHZ (11 << 0)
+
+#define AK4951_FS_CM0 (1 << 6)
+#define AK4951_FS_CM1 (1 << 7)
+
+#endif
diff --git a/sound/soc/codecs/ak4954_amb.c b/sound/soc/codecs/ak4954_amb.c
new file mode 100644
index 00000000..02ae6e7f
--- /dev/null
+++ b/sound/soc/codecs/ak4954_amb.c
@@ -0,0 +1,1513 @@
+/*
+ * ak4954_amb.c -- audio driver for AK4954
+ *
+ * Copyright 2014 Ambarella Ltd.
+ *
+ * Author: Diao Chengdong <cddiao@ambarella.com>
+ *
+ * History:
+ * 2014/03/27 - created
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/of_gpio.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+
+#include "ak4954_amb.h"
+
+//#define PLL_32BICK_MODE
+//#define PLL_64BICK_MODE
+
+//#define AK4954_DEBUG //used at debug mode
+//#define AK4954_CONTIF_DEBUG //used at debug mode
+
+#ifdef AK4954_DEBUG
+#define akdbgprt printk
+#else
+#define akdbgprt(format, arg...) do {} while (0)
+#endif
+
+#define LINEIN1_MIC_BIAS_CONNECT
+#define LINEIN2_MIC_BIAS_CONNECT
+
+/* AK4954 Codec Private Data */
+struct ak4954_priv {
+ unsigned int rst_pin;
+ unsigned int rst_active;
+ unsigned int sysclk;
+ unsigned int clkid;
+ struct snd_soc_codec codec;
+ u8 reg_cache[AK4954_MAX_REGISTERS];
+ int onDrc;
+ int onStereo;
+ int mic;
+};
+
+static struct snd_soc_codec *ak4954_codec;
+static struct ak4954_priv *ak4954_data;
+
+
+/* ak4954 register cache & default register settings */
+static const u8 ak4954_reg[AK4954_MAX_REGISTERS] = {
+ 0x00, /* 0x00 AK4954_00_POWER_MANAGEMENT1 */
+ 0x30, /* 0x01 AK4954_01_POWER_MANAGEMENT2 */
+ 0x0a, /* 0x02 AK4954_02_SIGNAL_SELECT1 */
+ 0x00, /* 0x03 AK4954_03_SIGNAL_SELECT2 */
+ 0x34, /* 0x04 AK4954_04_SIGNAL_SELECT3 */
+ 0x02, /* 0x05 AK4954_05_MODE_CONTROL1 */
+ 0x09, /* 0x06 AK4954_06_MODE_CONTROL2 */
+ 0x14, /* 0x07 AK4954_07_MODE_CONTROL3 */
+ 0x00, /* 0x08 AK4954_08_DIGITL_MIC */
+ 0x3A, /* 0x09 AK4954_09_TIMER_SELECT */
+ 0x48, /* 0x0A AK4954_0A_ALC_TIMER_SELECT */
+ 0x01, /* 0x0B AK4954_0B_ALC_MODE_CONTROL1 */
+ 0xE1, /* 0x0C AK4954_0C_ALC_MODE_CONTROL2 */
+ 0x91, /* 0x0D AK4954_0D_LCH_INPUT_VOLUME_CONTROL */
+ 0x91, /* 0x0E AK4954_0E_RCH_INPUT_VOLUME_CONTROL */
+ 0x00, /* 0x0F AK4954_0F_RESERVEDL */
+ 0x00, /* 0x10 AK4954_10_RESERVED */
+ 0x00, /* 0x11 AK4954_11_RESERVED */
+ 0x00, /* 0x12 AK4954_12_HP_OUTPUT_CONTROL */
+ 0x0C, /* 0x13 AK4954_13_LCH_DIGITAL_VOLUME_CONTROL */
+ 0x0C, /* 0x14 AK4954_14_RCH_DIGITAL_VOLUME_CONTROL */
+ 0x00, /* 0x15 AK4954_15_BEEP_FREQUENCY */
+ 0x00, /* 0x16 AK4954_16_BEEP_ON_TIME */
+ 0x00, /* 0x17 AK4954_17_BEEP_OFF_TIME */
+ 0x00, /* 0x18 AK4954_18_BEEP_REPEAT_COUNT */
+ 0x00, /* 0x19 AK4954_19_BEEP_VOLUME_CONTROL */
+ 0x00, /* 0x1A AK4954_1A_RESERVED */
+ 0x01, /* 0x1B AK4954_1B_DIGITAL_FILTER_SELECT1 */
+ 0x00, /* 0x1C AK4954_1C_DIGITAL_FILTER_SELECT2 */
+ 0x03, /* 0x1D AK4954_1D_DIGITAL_FILTER_MODE */
+ 0xA9, /* 0x1E AK4954_1E_HPF2_COEFFICIENT0 */
+ 0x1F, /* 0x1F AK4954_1F_HPF2_COEFFICIENT1 */
+ 0xAD, /* 0x20 AK4954_20_HPF2_COEFFICIENT2 */
+ 0x20, /* 0x21 AK4954_21_HPF2_COEFFICIENT3 */
+ 0x7F, /* 0x22 AK4954_22_LPF_COEFFICIENT0 */
+ 0x0C, /* 0x23 AK4954_23_LPF_COEFFICIENT1 */
+ 0xFF, /* 0x24 AK4954_24_LPF_COEFFICIENT2 */
+ 0x38, /* 0x25 AK4954_25_LPF_COEFFICIENT3 */
+ 0xA2, /* 0x26 AK4954_26_FIL3_COEFFICIENT0 */
+ 0x83, /* 0x27 AK4954_27_FIL3_COEFFICIENT1 */
+ 0x80, /* 0x28 AK4954_28_FIL3_COEFFICIENT2 */
+ 0x2E, /* 0x29 AK4954_29_FIL3_COEFFICIENT3 */
+ 0x5B, /* 0x2A AK4954_2A_EQ_COEFFICIENT0 */
+ 0x23, /* 0x2B AK4954_2B_EQ_COEFFICIENT1 */
+ 0x07, /* 0x2C AK4954_2C_EQ_COEFFICIENT2 */
+ 0x28, /* 0x2D AK4954_2D_EQ_COEFFICIENT3 */
+ 0xAA, /* 0x2E AK4954_2E_EQ_COEFFICIENT4 */
+ 0xEC, /* 0x2F AK4954_2F_EQ_COEFFICIENT5 */
+ 0x00, /* 0x30 AK4954_30_DIGITAL_FILTER_SELECT3 */
+ 0x00, /* 0x31 AK4954_31_RESERVED */
+ 0x9F, /* 0x32 AK4954_32_E1_COEFFICIENT0 */
+ 0x00, /* 0x33 AK4954_33_E1_COEFFICIENT1 */
+ 0x2B, /* 0x34 AK4954_34_E1_COEFFICIENT2 */
+ 0x3F, /* 0x35 AK4954_35_E1_COEFFICIENT3 */
+ 0xD4, /* 0x36 AK4954_36_E1_COEFFICIENT4 */
+ 0xE0, /* 0x37 AK4954_37_E1_COEFFICIENT5 */
+ 0x6A, /* 0x38 AK4954_38_E2_COEFFICIENT0 */
+ 0x00, /* 0x39 AK4954_39_E2_COEFFICIENT1 */
+ 0x1B, /* 0x3A AK4954_3A_E2_COEFFICIENT2 */
+ 0x3F, /* 0x3B AK4954_3B_E2_COEFFICIENT3 */
+ 0xD4, /* 0x3C AK4954_3C_E2_COEFFICIENT4 */
+ 0xE0, /* 0x3D AK4954_3D_E2_COEFFICIENT5 */
+ 0x6A, /* 0x3E AK4954_3E_E3_COEFFICIENT0 */
+ 0x00, /* 0x3F AK4954_3F_E3_COEFFICIENT1 */
+ 0xA2, /* 0x40 AK4954_40_E3_COEFFICIENT2 */
+ 0x3E, /* 0x41 AK4954_41_E3_COEFFICIENT3 */
+ 0xD4, /* 0x42 AK4954_42_E3_COEFFICIENT4 */
+ 0xE0, /* 0x43 AK4954_43_E3_COEFFICIENT5 */
+ 0x6A, /* 0x44 AK4954_44_E4_COEFFICIENT0 */
+ 0x00, /* 0x45 AK4954_45_E4_COEFFICIENT1 */
+ 0xA8, /* 0x46 AK4954_46_E4_COEFFICIENT2 */
+ 0x38, /* 0x47 AK4954_47_E4_COEFFICIENT3 */
+ 0xD4, /* 0x48 AK4954_48_E4_COEFFICIENT4 */
+ 0xE0, /* 0x49 AK4954_49_E4_COEFFICIENT5 */
+ 0x6A, /* 0x4A AK4954_4A_E5_COEFFICIENT0 */
+ 0x00, /* 0x4B AK4954_4B_E5_COEFFICIENT1 */
+ 0x96, /* 0x4C AK4954_4C_E5_COEFFICIENT2 */
+ 0x1F, /* 0x4D AK4954_4D_E5_COEFFICIENT3 */
+ 0xD4, /* 0x4E AK4954_4E_E5_COEFFICIENT4 */
+ 0xE0, /* 0x4F AK4954_4F_E5_COEFFICIENT5 */
+ 0x00, /* 0x50 AK4954_50_DRC_MODE_CONTROL */
+ 0x00, /* 0x51 AK4954_51_NS_CONTROL */
+ 0x11, /* 0x52 AK4954_52_NS_GAIN_ATT_CONTROL */
+ 0x90, /* 0x53 AK4954_53_NS_ON_LEVEL */
+ 0x8A, /* 0x54 AK4954_54_NS_OFF_LEVEL */
+ 0x07, /* 0x55 AK4954_55_NS_REFERENCE_SELECT */
+ 0x40, /* 0x56 AK4954_56_NS_LPF_COEFFICIENT0 */
+ 0x07, /* 0x57 AK4954_57_NS_LPF_COEFFICIENT1 */
+ 0x80, /* 0x58 AK4954_58_NS_LPF_COEFFICIENT2 */
+ 0x2E, /* 0x59 AK4954_59_NS_LPF_COEFFICIENT3 */
+ 0xA9, /* 0x5A AK4954_5A_NS_HPF_COEFFICIENT0 */
+ 0x1F, /* 0x5B AK4954_5B_NS_HPF_COEFFICIENT1 */
+ 0xAD, /* 0x5C AK4954_5C_NS_HPF_COEFFICIENT2 */
+ 0x20, /* 0x5D AK4954_5D_NS_HPF_COEFFICIENT3 */
+ 0x00, /* 0x5E AK4954_5E_RESERVED */
+ 0x00, /* 0x5F AK4954_5F_RESERVED */
+ 0x00, /* 0x60 AK4954_60_DVLC_FILTER_SELECT */
+ 0x6F, /* 0x61 AK4954_61_DVLC_MODE_CONTROL */
+ 0x18, /* 0x62 AK4954_62_DVLCL_CURVE_X1 */
+ 0x0C, /* 0x63 AK4954_63_DVLCL_CURVE_Y1 */
+ 0x10, /* 0x64 AK4954_64_DVLCL_CURVE_X2 */
+ 0x09, /* 0x65 AK4954_65_DVLCL_CURVE_Y2 */
+ 0x08, /* 0x66 AK4954_66_DVLCL_CURVE_X3 */
+ 0x08, /* 0x67 AK4954_67_DVLCL_CURVE_Y3 */
+ 0x7F, /* 0x68 AK4954_68_DVLCL_SLOPE1 */
+ 0x1D, /* 0x69 AK4954_69_DVLCL_SLOPE2 */
+ 0x03, /* 0x6A AK4954_6A_DVLCL_SLOPE3 */
+ 0x00, /* 0x6B AK4954_6B_DVLCL_SLOPE4 */
+ 0x18, /* 0x6C AK4954_6C_DVLCM_CURVE_X1 */
+ 0x0C, /* 0x6D AK4954_6D_DVLCM_CURVE_Y1 */
+ 0x10, /* 0x6E AK4954_6E_DVLCM_CURVE_X2 */
+ 0x06, /* 0x6F AK4954_6F_DVLCM_CURVE_Y2 */
+ 0x08, /* 0x70 AK4954_70_DVLCM_CURVE_X3 */
+ 0x04, /* 0x71 AK4954_71_DVLCM_CURVE_Y3 */
+ 0x7F, /* ox72 AK4954_72_DVLCM_SLOPE1 */
+ 0x4E, /* 0x73 AK4954_73_DVLCM_SLOPE2 */
+ 0x0C, /* 0x74 AK4954_74_DVLCM_SLOPE3 */
+ 0x00, /* 0x75 AK4954_75_DVLCM_SLOPE4 */
+ 0x1C, /* 0x76 AK4954_76_DVLCH_CURVE_X1 */
+ 0x10, /* 0x77 AK4954_77_DVLCH_CURVE_Y1 */
+ 0x10, /* 0x78 AK4954_78_DVLCH_CURVE_X2 */
+ 0x0C, /* 0x79 AK4954_79_DVLCH_CURVE_Y2 */
+ 0x08, /* 0x7A AK4954_7A_DVLCH_CURVE_X3 */
+ 0x09, /* 0x7B AK4954_7B_DVLCH_CURVE_Y3 */
+ 0x7F, /* 0x7C AK4954_7C_DVLCH_SLOPE1 */
+ 0x12, /* 0x7D AK4954_7D_DVLCH_SLOPE2 */
+ 0x07, /* 0x7E AK4954_7E_DVLCH_SLOPE3 */
+ 0x01, /* 0x7F AK4954_7F_DVLCH_SLOPE4 */
+ 0x50, /* 0x80 AK4954_80_DVLCL_LPF_COEFFICIENT0 */
+ 0x01, /* 0x81 AK4954_81_DVLCL_LPF_COEFFICIENT1 */
+ 0xA0, /* 0x82 AK4954_82_DVLCL_LPF_COEFFICIENT2 */
+ 0x22, /* 0x83 AK4954_83_DVLCL_LPF_COEFFICIENT3 */
+ 0xA9, /* 0x84 AK4954_84_DVLCM_HPF_COEFFICIENT0 */
+ 0x1F, /* 0x85 AK4954_85_DVLCM_HPF_COEFFICIENT1 */
+ 0xAD, /* 0x86 AK4954_86_DVLCM_HPF_COEFFICIENT2 */
+ 0x20, /* 0x87 AK4954_87_DVLCM_HPF_COEFFICIENT3 */
+ 0x04, /* 0x88 AK4954_88_DVLCM_LPF_COEFFICIENT0 */
+ 0x0A, /* 0x89 AK4954_89_DVLCM_LPF_COEFFICIENT1 */
+ 0x07, /* 0x8A AK4954_8A_DVLCM_LPF_COEFFICIENT2 */
+ 0x34, /* 0x8B AK4954_8B_DVLCM_LPF_COEFFICIENT3 */
+ 0xE6, /* 0x8C AK4954_8C_DVLCH_HPF_COEFFICIENT0 */
+ 0x1C, /* 0x8D AK4954_8D_DVLCH_HPF_COEFFICIENT1 */
+ 0x33, /* 0x8E AK4954_8E_DVLCH_HPF_COEFFICIENT2 */
+ 0x26, /* 0x8F AK4954_8F_DVLCH_HPF_COEFFICIENT3 */
+};
+
+
+static const struct {
+ int readable; /* Mask of readable bits */
+ int writable; /* Mask of writable bits */
+} ak4954_access_masks[] = {
+ { 0xEF, 0xEF }, //0x00
+ { 0x3F, 0x3F }, //0x01
+ { 0xBF, 0xBF }, //0x02
+ { 0xCF, 0xCF }, //0x03
+ { 0x3F, 0x3F }, //0x04
+ { 0x7F, 0x7F }, //0x05
+ { 0xCF, 0xCF }, //0x06
+ { 0xF7, 0xB7 }, //0x07
+ { 0x7B, 0x7B }, //0x08
+ { 0xFF, 0xFF }, //0x09
+ { 0xCF, 0xCF }, //0x0A
+ { 0xBF, 0xBF }, //0x0B
+ { 0xFF, 0xFF }, //0x0C
+ { 0xFF, 0xFF }, //0x0D
+ { 0xFF, 0xFF }, //0x0E
+ { 0x00, 0x00 }, //0x0F
+ { 0x00, 0x00 }, //0x10
+ { 0x00, 0x00 }, //0x11
+ { 0x80, 0x80 }, //0x12
+ { 0xFF, 0xFF }, //0x13
+ { 0xFF, 0xFF }, //0x14
+ { 0x83, 0x83 }, //0x15
+ { 0xFF, 0xFF }, //0x16
+ { 0xFF, 0xFF }, //0x17
+ { 0x7F, 0x7F }, //0x18
+ { 0x9F, 0x9F }, //0x19
+ { 0x00, 0x00 }, //0x1A
+ { 0x0F, 0x0F }, //0x1B
+ { 0xF3, 0xF3 }, //0x1C
+ { 0x87, 0x87 }, //0x1D
+ { 0xFF, 0xFF }, //0x1E
+ { 0xFF, 0xFF }, //0x1F
+ { 0xFF, 0xFF }, //0x20
+ { 0xFF, 0xFF }, //0x21
+ { 0xFF, 0xFF }, //0x22
+ { 0xFF, 0xFF }, //0x23
+ { 0xFF, 0xFF }, //0x24
+ { 0xFF, 0xFF }, //0x25
+ { 0xFF, 0xFF }, //0x26
+ { 0xFF, 0xFF }, //0x27
+ { 0xFF, 0xFF }, //0x28
+ { 0xFF, 0xFF }, //0x29
+ { 0xFF, 0xFF }, //0x2A
+ { 0xFF, 0xFF }, //0x2B
+ { 0xFF, 0xFF }, //0x2C
+ { 0xFF, 0xFF }, //0x2D
+ { 0xFF, 0xFF }, //0x2E
+ { 0xFF, 0xFF }, //0x2F
+ { 0x1F, 0x1F }, //0x30
+ { 0x00, 0x00 }, //0x31
+ { 0xFF, 0xFF }, //0x32
+ { 0xFF, 0xFF }, //0x33
+ { 0xFF, 0xFF }, //0x34
+ { 0xFF, 0xFF }, //0x35
+ { 0xFF, 0xFF }, //0x36
+ { 0xFF, 0xFF }, //0x37
+ { 0xFF, 0xFF }, //0x38
+ { 0xFF, 0xFF }, //0x39
+ { 0xFF, 0xFF }, //0x3A
+ { 0xFF, 0xFF }, //0x3B
+ { 0xFF, 0xFF }, //0x3C
+ { 0xFF, 0xFF }, //0x3D
+ { 0xFF, 0xFF }, //0x3E
+ { 0xFF, 0xFF }, //0x3F
+ { 0xFF, 0xFF }, //0x40
+ { 0xFF, 0xFF }, //0x41
+ { 0xFF, 0xFF }, //0x42
+ { 0xFF, 0xFF }, //0x43
+ { 0xFF, 0xFF }, //0x44
+ { 0xFF, 0xFF }, //0x45
+ { 0xFF, 0xFF }, //0x46
+ { 0xFF, 0xFF }, //0x47
+ { 0xFF, 0xFF }, //0x48
+ { 0xFF, 0xFF }, //0x49
+ { 0xFF, 0xFF }, //0x4A
+ { 0xFF, 0xFF }, //0x4B
+ { 0xFF, 0xFF }, //0x4C
+ { 0xFF, 0xFF }, //0x4D
+ { 0xFF, 0xFF }, //0x4E
+ { 0xFF, 0xFF }, //0x4F
+ { 0x7F, 0x7F }, //0x50
+ { 0x37, 0x37 }, //0x51
+ { 0x77, 0x77 }, //0x52
+ { 0xDF, 0xDF }, //0x53
+ { 0xDF, 0xDF }, //0x54
+ { 0x0F, 0x0F }, //0x55
+ { 0xFF, 0xFF }, //0x56
+ { 0xFF, 0xFF }, //0x57
+ { 0xFF, 0xFF }, //0x58
+ { 0xFF, 0xFF }, //0x59
+ { 0xFF, 0xFF }, //0x5A
+ { 0xFF, 0xFF }, //0x5B
+ { 0xFF, 0xFF }, //0x5C
+ { 0xFF, 0xFF }, //0x5D
+ { 0x00, 0x00 }, //0x5E
+ { 0x00, 0x00 }, //0x5F
+ { 0xFF, 0xFF }, //0x60
+ { 0xFF, 0xFF }, //0x61
+ { 0x7F, 0x7F }, //0x62
+ { 0x7F, 0x7F }, //0x63
+ { 0x7F, 0x7F }, //0x64
+ { 0x7F, 0x7F }, //0x65
+ { 0x7F, 0x7F }, //0x66
+ { 0x7F, 0x7F }, //0x67
+ { 0x7F, 0x7F }, //0x68
+ { 0x7F, 0x7F }, //0x69
+ { 0x7F, 0x7F }, //0x6A
+ { 0x7F, 0x7F }, //0x6B
+ { 0x7F, 0x7F }, //0x6C
+ { 0x7F, 0x7F }, //0x6D
+ { 0x7F, 0x7F }, //0x6E
+ { 0x7F, 0x7F }, //0x6F
+ { 0x7F, 0x7F }, //0x70
+ { 0x7F, 0x7F }, //0x71
+ { 0x7F, 0x7F }, //0x72
+ { 0x7F, 0x7F }, //0x73
+ { 0x7F, 0x7F }, //0x74
+ { 0x7F, 0x7F }, //0x75
+ { 0x7F, 0x7F }, //0x76
+ { 0x7F, 0x7F }, //0x77
+ { 0x7F, 0x7F }, //0x78
+ { 0x7F, 0x7F }, //0x79
+ { 0x7F, 0x7F }, //0x7A
+ { 0x7F, 0x7F }, //0x7B
+ { 0x7F, 0x7F }, //0x7C
+ { 0x7F, 0x7F }, //0x7D
+ { 0x7F, 0x7F }, //0x7E
+ { 0x7F, 0x7F }, //0x7F
+ { 0xFF, 0xFF }, //0x80
+ { 0xFF, 0xFF }, //0x81
+ { 0xFF, 0xFF }, //0x82
+ { 0xFF, 0xFF }, //0x83
+ { 0xFF, 0xFF }, //0x84
+ { 0xFF, 0xFF }, //0x85
+ { 0xFF, 0xFF }, //0x86
+ { 0xFF, 0xFF }, //0x87
+ { 0xFF, 0xFF }, //0x88
+ { 0xFF, 0xFF }, //0x89
+ { 0xFF, 0xFF }, //0x8A
+ { 0xFF, 0xFF }, //0x8B
+ { 0xFF, 0xFF }, //0x8C
+ { 0xFF, 0xFF }, //0x8D
+ { 0xFF, 0xFF }, //0x8E
+ { 0xFF, 0xFF } //0x8F
+
+};
+/*
+ * MIC Gain control:
+ * from 6 to 26 dB in 6.5 dB steps
+ */
+static DECLARE_TLV_DB_SCALE(mgain_tlv, 600, 650, 0);
+
+/*
+ * Input Digital volume control:
+ * from -54.375 to 36 dB in 0.375 dB steps mute instead of -54.375 dB)
+ */
+static DECLARE_TLV_DB_SCALE(ivol_tlv, -5437, 37, 1);
+
+/*
+ * Speaker output volume control:
+ * from -33 to 12 dB in 3 dB steps (mute instead of -33 dB)
+ */
+static DECLARE_TLV_DB_SCALE(spkout_tlv, 426, 200, 0);
+
+/*
+ * Output Digital volume control: (DATT-A)
+ * (This can be used as Bluetooth I/F output volume)
+ * from -57.5 to 6 dB in 0.5 dB steps (mute instead of -57.5 dB)
+ */
+static DECLARE_TLV_DB_SCALE(dvol_tlv, -6600, 50, 1);
+
+
+static const char *drc_on_select[] =
+{
+ "DRC OFF",
+ "DRC ON",
+};
+
+static const struct soc_enum ak4954_drc_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(drc_on_select), drc_on_select),
+};
+/*For our Board -- cddiao*/
+static const char *mic_and_lin_select[] =
+{
+ "LIN",
+ "MIC",
+};
+
+
+static const struct soc_enum ak4954_micswitch_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mic_and_lin_select), mic_and_lin_select),
+};
+
+
+static int get_micstatus(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct ak4954_priv *ak4954 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = ak4954->mic;
+
+ return 0;
+
+}
+
+static int set_micstatus(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct ak4954_priv *ak4954 = snd_soc_codec_get_drvdata(codec);
+
+ ak4954->mic = ucontrol->value.enumerated.item[0];
+
+ if ( ak4954->mic ) {
+ snd_soc_update_bits(codec,AK4954_03_SIGNAL_SELECT2,0x0f,0x05);// LIN2 RIN2
+ }else {
+ snd_soc_update_bits(codec,AK4954_03_SIGNAL_SELECT2,0x0f,0x0a);// LIN3 RIN3
+ }
+ return 0;
+}
+
+
+
+static const char *stereo_on_select[] =
+{
+ "Stereo Enphasis Filter OFF",
+ "Stereo Enphasis Filter ON",
+};
+
+static const struct soc_enum ak4954_stereo_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(stereo_on_select), stereo_on_select),
+};
+
+static int ak4954_writeMask(struct snd_soc_codec *, u16, u16, u16);
+static inline u32 ak4954_read_reg_cache(struct snd_soc_codec *, u16);
+
+static int get_ondrc(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct ak4954_priv *ak4954 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = ak4954->onDrc;
+
+ return 0;
+
+}
+
+static int set_ondrc(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct ak4954_priv *ak4954 = snd_soc_codec_get_drvdata(codec);
+
+ ak4954->onDrc = ucontrol->value.enumerated.item[0];
+
+ if ( ak4954->onDrc ) {
+ ak4954_writeMask(codec, AK4954_50_DRC_MODE_CONTROL, 0x3, 0x3);
+ ak4954_writeMask(codec, AK4954_60_DVLC_FILTER_SELECT, 0, 0x55);
+ }
+ else {
+ ak4954_writeMask(codec, AK4954_50_DRC_MODE_CONTROL, 0x3, 0x0);
+ ak4954_writeMask(codec, AK4954_60_DVLC_FILTER_SELECT, 0, 0x0);
+ }
+
+ return 0;
+}
+
+static int get_onstereo(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct ak4954_priv *ak4954 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = ak4954->onStereo;
+
+ return 0;
+
+}
+
+static int set_onstereo(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct ak4954_priv *ak4954 = snd_soc_codec_get_drvdata(codec);
+
+ ak4954->onStereo = ucontrol->value.enumerated.item[0];
+
+ if ( ak4954->onStereo ) {
+ ak4954_writeMask(codec, AK4954_1C_DIGITAL_FILTER_SELECT2, 0x30, 0x30);
+ }
+ else {
+ ak4954_writeMask(codec, AK4954_1C_DIGITAL_FILTER_SELECT2, 0x30, 0x00);
+ }
+
+ return 0;
+}
+
+#ifdef AK4954_DEBUG
+
+static const char *test_reg_select[] =
+{
+ "read AK4954 Reg 00:2F",
+ "read AK4954 Reg 30:5F",
+ "read AK4954 Reg 60:8F",
+};
+
+static const struct soc_enum ak4954_enum[] =
+{
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(test_reg_select), test_reg_select),
+};
+
+static int nTestRegNo = 0;
+
+static int get_test_reg(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ /* Get the current output routing */
+ ucontrol->value.enumerated.item[0] = nTestRegNo;
+
+ return 0;
+
+}
+
+static int set_test_reg(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ u32 currMode = ucontrol->value.enumerated.item[0];
+ int i, value;
+ int regs, rege;
+
+ nTestRegNo = currMode;
+
+ switch(nTestRegNo) {
+ case 1:
+ regs = 0x30;
+ rege = 0x5F;
+ break;
+ case 2:
+ regs = 0x60;
+ rege = 0x8F;
+ break;
+ default:
+ regs = 0x00;
+ rege = 0x2F;
+ break;
+ }
+
+ for ( i = regs ; i <= rege ; i++ ){
+ value = snd_soc_read(codec, i);
+ printk("***AK4954 Addr,Reg=(%x, %x)\n", i, value);
+ }
+
+ return(0);
+
+}
+
+#endif
+
+static const struct snd_kcontrol_new ak4954_snd_controls[] = {
+ SOC_SINGLE_TLV("Mic Gain Control",
+ AK4954_02_SIGNAL_SELECT1, 0, 0x07, 0, mgain_tlv),
+ SOC_SINGLE_TLV("Input Digital Volume",
+ AK4954_0D_LCH_INPUT_VOLUME_CONTROL, 0, 0xF1, 0, ivol_tlv),
+ SOC_SINGLE_TLV("Speaker Output Volume",
+ AK4954_03_SIGNAL_SELECT2, 6, 0x03, 0, spkout_tlv),
+ SOC_SINGLE_TLV("Digital Output Volume",
+ AK4954_13_LCH_DIGITAL_VOLUME_CONTROL, 0, 0x90, 1, dvol_tlv),
+
+ SOC_SINGLE("High Path Filter 1", AK4954_1B_DIGITAL_FILTER_SELECT1, 1, 3, 0),
+ SOC_SINGLE("High Path Filter 2", AK4954_1C_DIGITAL_FILTER_SELECT2, 0, 1, 0),
+ SOC_SINGLE("Low Path Filter", AK4954_1C_DIGITAL_FILTER_SELECT2, 1, 1, 0),
+ SOC_SINGLE("5 Band Equalizer 1", AK4954_30_DIGITAL_FILTER_SELECT3, 0, 1, 0),
+ SOC_SINGLE("5 Band Equalizer 2", AK4954_30_DIGITAL_FILTER_SELECT3, 1, 1, 0),
+ SOC_SINGLE("5 Band Equalizer 3", AK4954_30_DIGITAL_FILTER_SELECT3, 2, 1, 0),
+ SOC_SINGLE("5 Band Equalizer 4", AK4954_30_DIGITAL_FILTER_SELECT3, 3, 1, 0),
+ SOC_SINGLE("5 Band Equalizer 5", AK4954_30_DIGITAL_FILTER_SELECT3, 4, 1, 0),
+ SOC_SINGLE("Auto Level Control 1", AK4954_0B_ALC_MODE_CONTROL1, 5, 1, 0),
+ SOC_SINGLE("Soft Mute Control", AK4954_07_MODE_CONTROL3, 5, 1, 0),
+ SOC_ENUM_EXT("DRC Control", ak4954_drc_enum[0], get_ondrc, set_ondrc),
+ SOC_ENUM_EXT("Stereo Enphasis Filter Control", ak4954_stereo_enum[0], get_onstereo, set_onstereo),
+ SOC_ENUM_EXT("Mic and Lin Switch",ak4954_micswitch_enum[0],get_micstatus,set_micstatus),
+#ifdef AK4954_DEBUG
+ SOC_ENUM_EXT("Reg Read", ak4954_enum[0], get_test_reg, set_test_reg),
+#endif
+
+
+};
+
+static const char *ak4954_lin_select_texts[] =
+ {"LIN1", "LIN2", "LIN3"};
+
+static const struct soc_enum ak4954_lin_mux_enum =
+ SOC_ENUM_SINGLE(AK4954_03_SIGNAL_SELECT2, 2,
+ ARRAY_SIZE(ak4954_lin_select_texts), ak4954_lin_select_texts);
+
+static const struct snd_kcontrol_new ak4954_lin_mux_control =
+ SOC_DAPM_ENUM("LIN Select", ak4954_lin_mux_enum);
+
+static const char *ak4954_rin_select_texts[] =
+ {"RIN1", "RIN2", "RIN3"};
+
+static const struct soc_enum ak4954_rin_mux_enum =
+ SOC_ENUM_SINGLE(AK4954_03_SIGNAL_SELECT2, 0,
+ ARRAY_SIZE(ak4954_rin_select_texts), ak4954_rin_select_texts);
+
+static const struct snd_kcontrol_new ak4954_rin_mux_control =
+ SOC_DAPM_ENUM("RIN Select", ak4954_rin_mux_enum);
+
+static const char *ak4954_lin1_select_texts[] =
+ {"LIN1", "Mic Bias"};
+
+static const struct soc_enum ak4954_lin1_mux_enum =
+ SOC_ENUM_SINGLE(0, 0,
+ ARRAY_SIZE(ak4954_lin1_select_texts), ak4954_lin1_select_texts);
+
+static const struct snd_kcontrol_new ak4954_lin1_mux_control =
+ SOC_DAPM_ENUM_VIRT("LIN1 Switch", ak4954_lin1_mux_enum);
+
+
+static const char *ak4954_micbias_select_texts[] =
+ {"LIN1", "LIN2"};
+
+static const struct soc_enum ak4954_micbias_mux_enum =
+ SOC_ENUM_SINGLE(AK4954_02_SIGNAL_SELECT1, 4,
+ ARRAY_SIZE(ak4954_micbias_select_texts), ak4954_micbias_select_texts);
+
+static const struct snd_kcontrol_new ak4954_micbias_mux_control =
+ SOC_DAPM_ENUM("MIC bias Select", ak4954_micbias_mux_enum);
+
+static const char *ak4954_spklo_select_texts[] =
+ {"Speaker", "Line"};
+
+static const struct soc_enum ak4954_spklo_mux_enum =
+ SOC_ENUM_SINGLE(AK4954_01_POWER_MANAGEMENT2, 0,
+ ARRAY_SIZE(ak4954_spklo_select_texts), ak4954_spklo_select_texts);
+
+static const struct snd_kcontrol_new ak4954_spklo_mux_control =
+ SOC_DAPM_ENUM("SPKLO Select", ak4954_spklo_mux_enum);
+
+static const char *ak4954_adcpf_select_texts[] =
+ {"SDTI", "ADC"};
+
+static const struct soc_enum ak4954_adcpf_mux_enum =
+ SOC_ENUM_SINGLE(AK4954_1D_DIGITAL_FILTER_MODE, 1,
+ ARRAY_SIZE(ak4954_adcpf_select_texts), ak4954_adcpf_select_texts);
+
+static const struct snd_kcontrol_new ak4954_adcpf_mux_control =
+ SOC_DAPM_ENUM("ADCPF Select", ak4954_adcpf_mux_enum);
+
+
+static const char *ak4954_pfsdo_select_texts[] =
+ {"ADC", "PFIL"};
+
+static const struct soc_enum ak4954_pfsdo_mux_enum =
+ SOC_ENUM_SINGLE(AK4954_1D_DIGITAL_FILTER_MODE, 0,
+ ARRAY_SIZE(ak4954_pfsdo_select_texts), ak4954_pfsdo_select_texts);
+
+static const struct snd_kcontrol_new ak4954_pfsdo_mux_control =
+ SOC_DAPM_ENUM("PFSDO Select", ak4954_pfsdo_mux_enum);
+
+static const char *ak4954_pfdac_select_texts[] =
+ {"SDTI", "PFIL"};
+
+static const struct soc_enum ak4954_pfdac_mux_enum =
+ SOC_ENUM_SINGLE(AK4954_1D_DIGITAL_FILTER_MODE, 2,
+ ARRAY_SIZE(ak4954_pfdac_select_texts), ak4954_pfdac_select_texts);
+
+static const struct snd_kcontrol_new ak4954_pfdac_mux_control =
+ SOC_DAPM_ENUM("PFDAC Select", ak4954_pfdac_mux_enum);
+
+static const char *ak4954_dac_select_texts[] =
+ {"PFDAC", "DRC"};
+
+static const struct soc_enum ak4954_dac_mux_enum =
+ SOC_ENUM_SINGLE(AK4954_1D_DIGITAL_FILTER_MODE, 7,
+ ARRAY_SIZE(ak4954_dac_select_texts), ak4954_dac_select_texts);
+
+static const struct snd_kcontrol_new ak4954_dac_mux_control =
+ SOC_DAPM_ENUM("DAC Select", ak4954_dac_mux_enum);
+
+static const char *ak4954_mic_select_texts[] =
+ {"AMIC", "DMIC"};
+
+static const struct soc_enum ak4954_mic_mux_enum =
+ SOC_ENUM_SINGLE(AK4954_08_DIGITL_MIC, 0,
+ ARRAY_SIZE(ak4954_mic_select_texts), ak4954_mic_select_texts);
+
+static const struct snd_kcontrol_new ak4954_mic_mux_control =
+ SOC_DAPM_ENUM("MIC Select", ak4954_mic_mux_enum);
+
+
+static const struct snd_kcontrol_new ak4954_dacsl_mixer_controls[] = {
+ SOC_DAPM_SINGLE("DACSL", AK4954_02_SIGNAL_SELECT1, 5, 1, 0),
+};
+
+static int ak4954_spklo_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event) //CONFIG_LINF
+{
+ struct snd_soc_codec *codec = w->codec;
+ u32 reg, nLOSEL;
+
+ akdbgprt("\t[AK4954] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ reg = ak4954_read_reg_cache(codec, AK4954_01_POWER_MANAGEMENT2);
+ nLOSEL = (0x1 & reg);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU: /* before widget power up */
+ break;
+ case SND_SOC_DAPM_POST_PMU: /* after widget power up */
+ if ( nLOSEL ) {
+ akdbgprt("\t[AK4954] %s wait=300msec\n",__FUNCTION__);
+ mdelay(300);
+ }
+ else {
+ akdbgprt("\t[AK4954] %s wait=1msec\n",__FUNCTION__);
+ mdelay(1);
+ }
+ snd_soc_update_bits(codec, AK4954_02_SIGNAL_SELECT1, 0x80,0x80);
+ break;
+ case SND_SOC_DAPM_PRE_PMD: /* before widget power down */
+ snd_soc_update_bits(codec, AK4954_02_SIGNAL_SELECT1, 0x80,0x00);
+ mdelay(1);
+ break;
+ case SND_SOC_DAPM_POST_PMD: /* after widget power down */
+ if ( nLOSEL ) {
+ akdbgprt("\t[AK4954] %s wait=300msec\n",__FUNCTION__);
+ mdelay(300);
+ }
+ break;
+ }
+
+ return 0;
+}
+
+static const struct snd_soc_dapm_widget ak4954_dapm_widgets[] = {
+
+// ADC, DAC
+ SND_SOC_DAPM_ADC("ADC Left", "NULL", AK4954_00_POWER_MANAGEMENT1, 0, 0),
+ SND_SOC_DAPM_ADC("ADC Right", "NULL", AK4954_00_POWER_MANAGEMENT1, 1, 0),
+ SND_SOC_DAPM_DAC("DAC", "NULL", AK4954_00_POWER_MANAGEMENT1, 2, 0),
+
+#ifdef PLL_32BICK_MODE
+ SND_SOC_DAPM_SUPPLY("PMPLL", AK4954_01_POWER_MANAGEMENT2, 2, 0, NULL, 0),
+#else
+#ifdef PLL_64BICK_MODE
+ SND_SOC_DAPM_SUPPLY("PMPLL", AK4954_01_POWER_MANAGEMENT2, 2, 0, NULL, 0),
+#endif
+#endif
+
+ SND_SOC_DAPM_ADC("PFIL", "NULL", AK4954_00_POWER_MANAGEMENT1, 7, 0),
+ SND_SOC_DAPM_DAC("DRC", "NULL", AK4954_1D_DIGITAL_FILTER_MODE, 7, 0),
+
+ SND_SOC_DAPM_ADC("DMICL", "NULL", AK4954_08_DIGITL_MIC, 4, 0),
+ SND_SOC_DAPM_ADC("DMICR", "NULL", AK4954_08_DIGITL_MIC, 5, 0),
+
+ SND_SOC_DAPM_AIF_OUT("SDTO", "Capture", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("SDTI", "Playback", 0, SND_SOC_NOPM, 0, 0),
+
+// Analog Output
+ SND_SOC_DAPM_OUTPUT("HPL"),
+ SND_SOC_DAPM_OUTPUT("HPR"),
+ SND_SOC_DAPM_OUTPUT("SPKLO"),
+
+ SND_SOC_DAPM_PGA("HPL Amp", AK4954_01_POWER_MANAGEMENT2, 4, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("HPR Amp", AK4954_01_POWER_MANAGEMENT2, 5, 0, NULL, 0),
+
+ SND_SOC_DAPM_PGA("SPK Amp", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Line Amp", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_MIXER_E("SPKLO Mixer", AK4954_01_POWER_MANAGEMENT2, 1, 0,
+ &ak4954_dacsl_mixer_controls[0], ARRAY_SIZE(ak4954_dacsl_mixer_controls),
+ ak4954_spklo_event, (SND_SOC_DAPM_POST_PMU |SND_SOC_DAPM_PRE_PMD
+ |SND_SOC_DAPM_PRE_PMU |SND_SOC_DAPM_POST_PMD)),
+
+// Analog Input
+ SND_SOC_DAPM_INPUT("LIN1"),
+ SND_SOC_DAPM_INPUT("RIN1"),
+ SND_SOC_DAPM_INPUT("LIN2"),
+ SND_SOC_DAPM_INPUT("RIN2"),
+ SND_SOC_DAPM_INPUT("LIN3"),
+ SND_SOC_DAPM_INPUT("RIN3"),
+
+ SND_SOC_DAPM_MUX("LIN MUX", SND_SOC_NOPM, 0, 0, &ak4954_lin_mux_control),
+ SND_SOC_DAPM_MUX("RIN MUX", SND_SOC_NOPM, 0, 0, &ak4954_rin_mux_control),
+
+// MIC Bias
+ SND_SOC_DAPM_MICBIAS("Mic Bias", AK4954_02_SIGNAL_SELECT1, 3, 0),
+ SND_SOC_DAPM_VIRT_MUX("LIN1 MUX", SND_SOC_NOPM, 0, 0, &ak4954_lin1_mux_control),
+ SND_SOC_DAPM_MUX("Mic Bias MUX", SND_SOC_NOPM, 0, 0, &ak4954_micbias_mux_control),
+ SND_SOC_DAPM_MUX("SPKLO MUX", SND_SOC_NOPM, 0, 0, &ak4954_spklo_mux_control),
+
+
+// PFIL
+ SND_SOC_DAPM_MUX("PFIL MUX", SND_SOC_NOPM, 0, 0, &ak4954_adcpf_mux_control),
+ SND_SOC_DAPM_MUX("PFSDO MUX", SND_SOC_NOPM, 0, 0, &ak4954_pfsdo_mux_control),
+ SND_SOC_DAPM_MUX("PFDAC MUX", SND_SOC_NOPM, 0, 0, &ak4954_pfdac_mux_control),
+ SND_SOC_DAPM_MUX("DAC MUX", SND_SOC_NOPM, 0, 0, &ak4954_dac_mux_control),
+
+// Digital Mic
+ SND_SOC_DAPM_INPUT("DMICLIN"),
+ SND_SOC_DAPM_INPUT("DMICRIN"),
+
+ SND_SOC_DAPM_VIRT_MUX("MIC MUX", SND_SOC_NOPM, 0, 0, &ak4954_mic_mux_control),
+
+};
+
+
+static const struct snd_soc_dapm_route ak4954_intercon[] = {
+
+#ifdef PLL_32BICK_MODE
+ {"ADC Left", "NULL", "PMPLL"},
+ {"ADC Right", "NULL", "PMPLL"},
+ {"DAC", "NULL", "PMPLL"},
+#else
+#ifdef PLL_64BICK_MODE
+ {"ADC Left", "NULL", "PMPLL"},
+ {"ADC Right", "NULL", "PMPLL"},
+ {"DAC", "NULL", "PMPLL"},
+#endif
+#endif
+
+ {"Mic Bias MUX", "LIN1", "LIN1"},
+ {"Mic Bias MUX", "LIN2", "LIN2"},
+
+ {"Mic Bias", "NULL", "Mic Bias MUX"},
+
+ {"LIN1 MUX", "LIN1", "LIN1"},
+ {"LIN1 MUX", "Mic Bias", "Mic Bias"},
+
+ {"LIN MUX", "LIN1", "LIN1 MUX"},
+ {"LIN MUX", "LIN2", "Mic Bias"},
+ {"LIN MUX", "LIN3", "LIN3"},
+ {"RIN MUX", "RIN1", "RIN1"},
+ {"RIN MUX", "RIN2", "RIN2"},
+ {"RIN MUX", "RIN3", "RIN3"},
+ {"ADC Left", "NULL", "LIN MUX"},
+ {"ADC Right", "NULL", "RIN MUX"},
+
+ {"DMICL", "NULL", "DMICLIN"},
+ {"DMICR", "NULL", "DMICRIN"},
+
+ {"MIC MUX", "AMIC", "ADC Left"},
+ {"MIC MUX", "AMIC", "ADC Right"},
+ {"MIC MUX", "DMIC", "DMICL"},
+ {"MIC MUX", "DMIC", "DMICR"},
+
+ {"PFIL MUX", "SDTI", "SDTI"},
+ {"PFIL MUX", "ADC", "MIC MUX"},
+ {"PFIL", "NULL", "PFIL MUX"},
+
+ {"PFSDO MUX", "ADC", "MIC MUX"},
+ {"PFSDO MUX", "PFIL", "PFIL"},
+
+ {"SDTO", "NULL", "PFSDO MUX"},
+
+ {"PFDAC MUX", "SDTI", "SDTI"},
+ {"PFDAC MUX", "PFIL", "PFIL"},
+
+ {"DAC MUX", "PFDAC", "PFDAC MUX"},
+ {"DRC", "NULL", "PFDAC MUX"},
+ {"DAC MUX", "DRC", "DRC"},
+
+ {"DAC", "NULL", "DAC MUX"},
+
+ {"HPL Amp", "NULL", "DAC"},
+ {"HPR Amp", "NULL", "DAC"},
+ {"HPL", "NULL", "HPL Amp"},
+ {"HPR", "NULL", "HPR Amp"},
+
+ {"SPKLO Mixer", "DACSL", "DAC"},
+ {"SPK Amp", "NULL", "SPKLO Mixer"},
+ {"Line Amp", "NULL", "SPKLO Mixer"},
+ {"SPKLO MUX", "Speaker", "SPK Amp"},
+ {"SPKLO MUX", "Line", "Line Amp"},
+ {"SPKLO", "NULL", "SPKLO MUX"},
+
+};
+
+static int ak4954_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ int rate = params_rate(params);
+ struct ak4954_priv *ak4954 = snd_soc_codec_get_drvdata(codec);
+ int oversample = 0;
+ u8 fs = 0;
+
+ akdbgprt("\t[AK4954] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ oversample = ak4954->sysclk / rate;
+ switch (oversample) {
+ case 256:
+ fs &= (~AK4954_FS_CM1);
+ fs &= (~AK4954_FS_CM0);
+ break;
+ case 384:
+ fs &= (~AK4954_FS_CM1);
+ fs |= AK4954_FS_CM0;
+ break;
+ case 512:
+ fs |= AK4954_FS_CM1;
+ fs &= (~AK4954_FS_CM0);
+ break;
+ case 1024:
+ fs |= AK4954_FS_CM1;
+ fs |= AK4954_FS_CM0;
+ break;
+ default:
+ break;
+ }
+ switch (rate) {
+ case 8000:
+ fs |= AK4954_FS_8KHZ;
+ break;
+ case 11025:
+ fs |= AK4954_FS_11_025KHZ;
+ break;
+ case 12000:
+ fs |= AK4954_FS_12KHZ;
+ break;
+ case 16000:
+ fs |= AK4954_FS_16KHZ;
+ break;
+ case 22050:
+ fs |= AK4954_FS_22_05KHZ;
+ break;
+ case 24000:
+ fs |= AK4954_FS_24KHZ;
+ break;
+ case 32000:
+ fs |= AK4954_FS_32KHZ;
+ break;
+ case 44100:
+ fs |= AK4954_FS_44_1KHZ;
+ break;
+ case 48000:
+ fs |= AK4954_FS_48KHZ;
+ break;
+ case 64000:
+ fs |= AK4954_FS_64KHZ;
+ break;
+ case 88000:
+ fs |= AK4954_FS_88_2KHZ;
+ break;
+ case 96000:
+ fs |= AK4954_FS_96KHZ;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_write(codec, AK4954_06_MODE_CONTROL2, fs);
+
+ return 0;
+}
+
+static int ak4954_set_pll(u8 *pll, int clk_id,int freq)
+{
+ if (clk_id == AK4954_MCLK_IN_BCLK_OUT){
+ switch (freq) {
+ case 11289600:
+ *pll |= (2 << 4);
+ break;
+ case 12288000:
+ *pll |= (3 << 4);
+ break;
+ case 12000000:
+ *pll |= (4 << 4);
+ break;
+ case 24000000:
+ *pll |= (5 << 4);
+ break;
+ case 13500000:
+ *pll |= (6 << 4);
+ break;
+ case 27000000:
+ *pll |= (7 << 4);
+ break;
+ default:
+ break;
+ }
+ }else if (clk_id == AK4954_BCLK_IN) {
+ *pll |= (0 << 4);
+ }
+ return 0;
+}
+
+static int ak4954_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
+ unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct ak4954_priv *ak4954 = snd_soc_codec_get_drvdata(codec);
+ u8 pllpwr = 0, pll = 0;
+
+ akdbgprt("\t[AK4954] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ pll= snd_soc_read(codec, AK4954_05_MODE_CONTROL1);
+ pll &=(~0x70);
+ pllpwr = snd_soc_read(codec,AK4954_01_POWER_MANAGEMENT2);
+ pllpwr &=(~0x0c);
+
+ if (clk_id == AK4954_MCLK_IN) {
+ pllpwr &= (~AK4954_PMPLL);
+ pllpwr &= (~AK4954_M_S);
+ }else if (clk_id == AK4954_BCLK_IN) {
+ pllpwr |= AK4954_PMPLL;
+ pllpwr &= (~AK4954_M_S);
+ ak4954_set_pll(&pll, clk_id, freq);
+ }else if (clk_id == AK4954_MCLK_IN_BCLK_OUT) {
+ pllpwr |= AK4954_PMPLL;
+ pllpwr |= AK4954_M_S;
+ ak4954_set_pll(&pll, clk_id, freq);
+ }
+ snd_soc_write(codec, AK4954_05_MODE_CONTROL1, pll);
+ snd_soc_write(codec, AK4954_01_POWER_MANAGEMENT2, pllpwr);
+
+ ak4954->sysclk = freq;
+ ak4954->clkid = clk_id;
+ return 0;
+}
+
+static int ak4954_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+
+ struct snd_soc_codec *codec = dai->codec;
+ u8 mode;
+ u8 format;
+
+ akdbgprt("\t[AK4954] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ /* set master/slave audio interface */
+ mode = snd_soc_read(codec, AK4954_01_POWER_MANAGEMENT2);
+ format = snd_soc_read(codec, AK4954_05_MODE_CONTROL1);
+ format &= ~AK4954_DIF;
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ akdbgprt("\t[AK4954] %s(Slave)\n",__FUNCTION__);
+ mode &= ~(AK4954_M_S);
+ //format &= ~(AK4954_BCKO);
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+ akdbgprt("\t[AK4954] %s(Master)\n",__FUNCTION__);
+ mode |= (AK4954_M_S);
+ //format |= (AK4954_BCKO);
+ break;
+ case SND_SOC_DAIFMT_CBS_CFM:
+ case SND_SOC_DAIFMT_CBM_CFS:
+ default:
+ dev_err(codec->dev, "Clock mode unsupported");
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ format |= AK4954_DIF_24_16_I2S_MODE;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ format |= AK4954_DIF_24MSB_MODE;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* set mode and format */
+
+ snd_soc_write(codec, AK4954_01_POWER_MANAGEMENT2, mode);
+ snd_soc_write(codec, AK4954_05_MODE_CONTROL1, format);
+
+ return 0;
+}
+
+static int ak4954_volatile(struct snd_soc_codec *codec, unsigned int reg)
+{
+ int ret;
+
+ switch (reg) {
+// case :
+// ret = 1;
+ default:
+ ret = 0;
+ break;
+ }
+ return(ret);
+}
+
+static int ak4954_readable(struct snd_soc_codec *codec, unsigned int reg)
+{
+
+ if (reg >= ARRAY_SIZE(ak4954_access_masks))
+ return 0;
+ return ak4954_access_masks[reg].readable != 0;
+}
+
+/*
+ * Read ak4954 register cache
+ */
+static inline u32 ak4954_read_reg_cache(struct snd_soc_codec *codec, u16 reg)
+{
+ u8 *cache = codec->reg_cache;
+ BUG_ON(reg > ARRAY_SIZE(ak4954_reg));
+ return (u32)cache[reg];
+}
+
+#ifdef AK4954_CONTIF_DEBUG
+/*
+ * Write ak4954 register cache
+ */
+static inline void ak4954_write_reg_cache(
+struct snd_soc_codec *codec,
+u16 reg,
+u16 value)
+{
+ u8 *cache = codec->reg_cache;
+ BUG_ON(reg > ARRAY_SIZE(ak4954_reg));
+ cache[reg] = (u8)value;
+}
+
+unsigned int ak4954_i2c_read(struct snd_soc_codec *codec, unsigned int reg)
+{
+
+ int ret;
+
+ if ( reg == AK4954_10_RESERVED ) { // Dummy Register
+ ret = ak4954_read_reg_cache(codec, reg);
+ return ret;
+ }
+
+ ret = i2c_smbus_read_byte_data(codec->control_data, (u8)(reg & 0xFF));
+// ret = ak4954_read_reg_cache(codec, reg);
+
+// if ( reg < 3 )
+// akdbgprt("\t[ak4954] %s: (addr,data)=(%x, %x)\n",__FUNCTION__, reg, ret);
+
+ if (ret < 0)
+ akdbgprt("\t[AK4954] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ return ret;
+
+}
+
+static int ak4954_i2c_write(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int value)
+{
+ ak4954_write_reg_cache(codec, reg, value);
+
+ akdbgprt("\t[ak4954] %s: (addr,data)=(%x, %x)\n",__FUNCTION__, reg, value);
+
+ if ( reg == AK4954_10_RESERVED ) return 0; // Dummy Register
+ if(i2c_smbus_write_byte_data(codec->control_data, (u8)(reg & 0xFF), (u8)(value & 0xFF))<0) {
+ akdbgprt("\t[AK4954] %s(%d)\n",__FUNCTION__,__LINE__);
+ return EIO;
+ }
+
+ return 0;
+}
+#endif
+
+/*
+ * Write with Mask to AK4954 register space
+ */
+static int ak4954_writeMask(
+struct snd_soc_codec *codec,
+u16 reg,
+u16 mask,
+u16 value)
+{
+ u16 olddata;
+ u16 newdata;
+
+ if ( (mask == 0) || (mask == 0xFF) ) {
+ newdata = value;
+ }
+ else {
+ olddata = ak4954_read_reg_cache(codec, reg);
+ newdata = (olddata & ~(mask)) | value;
+ }
+
+ snd_soc_write(codec, (unsigned int)reg, (unsigned int)newdata);
+
+ akdbgprt("\t[ak4954_writeMask] %s(%d): (addr,data)=(%x, %x)\n",__FUNCTION__,__LINE__, reg, newdata);
+
+ return(0);
+}
+
+// * for AK4954
+static int ak4954_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *codec_dai)
+{
+ int ret = 0;
+ // struct snd_soc_codec *codec = codec_dai->codec;
+
+ akdbgprt("\t[AK4954] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ return ret;
+}
+
+
+static int ak4954_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ u8 reg;
+
+ akdbgprt("\t[AK4954] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ case SND_SOC_BIAS_PREPARE:
+ case SND_SOC_BIAS_STANDBY:
+ reg = snd_soc_read(codec, AK4954_00_POWER_MANAGEMENT1); // * for AK4954
+ snd_soc_write(codec, AK4954_00_POWER_MANAGEMENT1, // * for AK4954
+ reg | AK4954_PMVCM);
+ break;
+ case SND_SOC_BIAS_OFF:
+ snd_soc_write(codec, AK4954_00_POWER_MANAGEMENT1, 0x00); // * for AK4954
+ break;
+ }
+ codec->dapm.bias_level = level;
+ return 0;
+}
+
+#define AK4954_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
+ SNDRV_PCM_RATE_96000)
+
+#define AK4954_FORMATS SNDRV_PCM_FMTBIT_S16_LE
+
+
+static struct snd_soc_dai_ops ak4954_dai_ops = {
+ .hw_params = ak4954_hw_params,
+ .set_sysclk = ak4954_set_dai_sysclk,
+ .set_fmt = ak4954_set_dai_fmt,
+ .trigger = ak4954_trigger,
+};
+
+struct snd_soc_dai_driver ak4954_dai[] = {
+ {
+ .name = "ak4954-hifi",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = AK4954_RATES,
+ .formats = AK4954_FORMATS,
+ },
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = AK4954_RATES,
+ .formats = AK4954_FORMATS,
+ },
+ .ops = &ak4954_dai_ops,
+ },
+};
+
+static int ak4954_write_cache_reg(
+struct snd_soc_codec *codec,
+u16 regs,
+u16 rege)
+{
+ u32 reg, cache_data;
+
+ reg = regs;
+ do {
+ cache_data = ak4954_read_reg_cache(codec, reg);
+ snd_soc_write(codec, (unsigned int)reg, (unsigned int)cache_data);
+ reg ++;
+ } while (reg <= rege);
+
+ return(0);
+}
+
+
+static int ak4954_set_reg_digital_effect(struct snd_soc_codec *codec)
+{
+
+ ak4954_write_cache_reg(codec, AK4954_0A_ALC_TIMER_SELECT, AK4954_0D_LCH_INPUT_VOLUME_CONTROL);
+ ak4954_write_cache_reg(codec, AK4954_22_LPF_COEFFICIENT0, AK4954_2F_EQ_COEFFICIENT5);
+ ak4954_write_cache_reg(codec, AK4954_32_E1_COEFFICIENT0, AK4954_4F_E5_COEFFICIENT5);
+ ak4954_write_cache_reg(codec, AK4954_50_DRC_MODE_CONTROL, AK4954_8F_DVLCH_HPF_COEFFICIENT3);
+ return(0);
+}
+
+static int ak4954_probe(struct snd_soc_codec *codec)
+{
+ struct ak4954_priv *ak4954 = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
+
+ akdbgprt("\t[AK4954] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
+ }
+
+#ifdef AK4954_CONTIF_DEBUG
+ codec->write = ak4954_i2c_write;
+ codec->read = ak4954_i2c_read;
+#endif
+ ak4954_codec = codec;
+
+ akdbgprt("\t[AK4954] %s(%d) ak4954=%x\n",__FUNCTION__,__LINE__, (int)ak4954);
+
+ snd_soc_write(codec, AK4954_00_POWER_MANAGEMENT1, 0x00);
+ snd_soc_write(codec, AK4954_00_POWER_MANAGEMENT1, 0x00);
+
+ ak4954_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ akdbgprt("\t[AK4954 bias] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ ak4954_set_reg_digital_effect(codec);
+
+ akdbgprt("\t[AK4954 Effect] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ snd_soc_add_codec_controls(codec, ak4954_snd_controls,
+ ARRAY_SIZE(ak4954_snd_controls));
+ ak4954->onDrc = 0;
+ ak4954->onStereo = 0;
+ ak4954->mic = 1;
+ /*Enable Line out */
+ snd_soc_update_bits(codec,AK4954_01_POWER_MANAGEMENT2,0x02,0x02);
+ snd_soc_update_bits(codec,AK4954_02_SIGNAL_SELECT1, 0xa0,0xa0);
+
+ /*Enable LIN2*/
+ snd_soc_update_bits(codec,AK4954_02_SIGNAL_SELECT1,0x18,0x08);//MPWR1
+ snd_soc_update_bits(codec,AK4954_03_SIGNAL_SELECT2,0x0f,0x05);// LIN2 RIN2
+ snd_soc_update_bits(codec,AK4954_08_DIGITL_MIC,0x01,0x00);//AMIC
+ snd_soc_update_bits(codec,AK4954_1D_DIGITAL_FILTER_MODE,0x02,0x02);//ADC output
+ snd_soc_update_bits(codec,AK4954_1D_DIGITAL_FILTER_MODE,0x01,0x01);//ALC output
+ snd_soc_update_bits(codec,AK4954_02_SIGNAL_SELECT1,0x07,0x3);//Mic Gain
+ snd_soc_update_bits(codec,AK4954_0D_LCH_INPUT_VOLUME_CONTROL,0xff,0xb0);//Lch gain
+ snd_soc_update_bits(codec,AK4954_0E_RCH_INPUT_VOLUME_CONTROL,0xff,0xb0);//Lch gain
+
+ /*Enable LIN3*/
+ //snd_soc_update_bits(codec,AK4954_03_SIGNAL_SELECT2,0x0f,0x0a);// LIN3 RIN3
+
+ return ret;
+
+}
+
+static int ak4954_remove(struct snd_soc_codec *codec)
+{
+
+ akdbgprt("\t[AK4954] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ ak4954_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+
+ return 0;
+}
+
+static int ak4954_suspend(struct snd_soc_codec *codec)
+{
+ ak4954_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+ return 0;
+}
+
+static int ak4954_resume(struct snd_soc_codec *codec)
+{
+
+ ak4954_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ return 0;
+}
+
+
+struct snd_soc_codec_driver soc_codec_dev_ak4954 = {
+ .probe = ak4954_probe,
+ .remove = ak4954_remove,
+ .suspend = ak4954_suspend,
+ .resume = ak4954_resume,
+
+ .set_bias_level = ak4954_set_bias_level,
+ .reg_cache_size = ARRAY_SIZE(ak4954_reg),
+ .reg_word_size = sizeof(u8),
+ .reg_cache_default = ak4954_reg,
+ .readable_register = ak4954_readable,
+ .volatile_register = ak4954_volatile,
+ .dapm_widgets = ak4954_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(ak4954_dapm_widgets),
+ .dapm_routes = ak4954_intercon,
+ .num_dapm_routes = ARRAY_SIZE(ak4954_intercon),
+};
+EXPORT_SYMBOL_GPL(soc_codec_dev_ak4954);
+
+static int ak4954_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct device_node *np = i2c->dev.of_node;
+ struct ak4954_priv *ak4954;
+ enum of_gpio_flags flags;
+ int rst_pin;
+ struct snd_soc_codec *codec;
+ int ret=0;
+
+ akdbgprt("\t[AK4954] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ ak4954 = devm_kzalloc(&i2c->dev, sizeof(struct ak4954_priv), GFP_KERNEL);
+ if (ak4954 == NULL)
+ return -ENOMEM;
+
+ rst_pin = of_get_gpio_flags(np, 0, &flags);
+ if (rst_pin < 0 || !gpio_is_valid(rst_pin))
+ return -ENXIO;
+
+ ak4954->rst_pin = rst_pin;
+ ak4954->rst_active = !!(flags & OF_GPIO_ACTIVE_LOW);
+ codec = &ak4954->codec;
+ i2c_set_clientdata(i2c, ak4954);
+ codec->control_data = i2c;
+ ak4954_data = ak4954;
+
+ codec->dev = &i2c->dev;
+ snd_soc_codec_set_drvdata(codec, ak4954);
+
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_ak4954, &ak4954_dai[0], ARRAY_SIZE(ak4954_dai));
+ if (ret < 0){
+ kfree(ak4954);
+ akdbgprt("\t[AK4954 Error!] %s(%d)\n",__FUNCTION__,__LINE__);
+ }
+ return ret;
+}
+
+static int ak4954_i2c_remove(struct i2c_client *client)
+{
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
+ return 0;
+}
+
+static struct of_device_id ak4954_of_match[] = {
+ { .compatible = "ambarella,ak4954",},
+ {},
+};
+MODULE_DEVICE_TABLE(of, ak4954_of_match);
+
+static const struct i2c_device_id ak4954_i2c_id[] = {
+ { "ak4954", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ak4954_i2c_id);
+
+static struct i2c_driver ak4954_i2c_driver = {
+ .driver = {
+ .name = "ak4954-codec",
+ .owner = THIS_MODULE,
+ .of_match_table = ak4954_of_match,
+ },
+ .probe = ak4954_i2c_probe,
+ .remove = ak4954_i2c_remove,
+ .id_table = ak4954_i2c_id,
+};
+
+static int __init ak4954_modinit(void)
+{
+ int ret;
+ akdbgprt("\t[AK4954] %s(%d)\n", __FUNCTION__,__LINE__);
+
+ ret = i2c_add_driver(&ak4954_i2c_driver);
+ if (ret != 0)
+ pr_err("Failed to register ak4954 I2C driver: %d\n",ret);
+ return ret;
+}
+
+module_init(ak4954_modinit);
+
+static void __exit ak4954_exit(void)
+{
+ i2c_del_driver(&ak4954_i2c_driver);
+}
+module_exit(ak4954_exit);
+
+MODULE_DESCRIPTION("Soc AK4954 driver");
+MODULE_AUTHOR("Diao Chengdong<cddiao@ambarella.com>");
+MODULE_LICENSE("GPL");
+
diff --git a/sound/soc/codecs/ak4954_amb.h b/sound/soc/codecs/ak4954_amb.h
new file mode 100644
index 00000000..2f3bc844
--- /dev/null
+++ b/sound/soc/codecs/ak4954_amb.h
@@ -0,0 +1,228 @@
+/*
+ * ak4954_amb.h -- audio driver for AK4954
+ *
+ * Copyright 2014 Ambarella Ltd.
+ *
+ * Author: Diao Chengdong <cddiao@ambarella.com>
+ *
+ * History:
+ * 2014/03/27 - created
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
+#ifndef _AK4954_AMB_H
+#define _AK4954_AMB_H
+
+#define AK4954_CLOCK_PLAYBACK 1
+#define AK4954_CLOCK_CAPTURE 2
+#define AK4954_CLOCK_OTHER 4
+
+#define AK4954_00_POWER_MANAGEMENT1 0x00
+#define AK4954_01_POWER_MANAGEMENT2 0x01
+#define AK4954_02_SIGNAL_SELECT1 0x02
+#define AK4954_03_SIGNAL_SELECT2 0x03
+#define AK4954_04_SIGNAL_SELECT3 0x04
+#define AK4954_05_MODE_CONTROL1 0x05
+#define AK4954_06_MODE_CONTROL2 0x06
+#define AK4954_07_MODE_CONTROL3 0x07
+#define AK4954_08_DIGITL_MIC 0x08
+#define AK4954_09_TIMER_SELECT 0x09
+#define AK4954_0A_ALC_TIMER_SELECT 0x0A
+#define AK4954_0B_ALC_MODE_CONTROL1 0x0B
+#define AK4954_0C_ALC_MODE_CONTROL2 0x0C
+#define AK4954_0D_LCH_INPUT_VOLUME_CONTROL 0x0D
+#define AK4954_0E_RCH_INPUT_VOLUME_CONTROL 0x0E
+#define AK4954_0F_RESERVED 0x0F
+#define AK4954_10_RESERVED 0x10
+#define AK4954_11_RESERVED 0x11
+#define AK4954_12_HP_OUTPUT_CONTROL 0x12
+#define AK4954_13_LCH_DIGITAL_VOLUME_CONTROL 0x13
+#define AK4954_14_RCH_DIGITAL_VOLUME_CONTROL 0x14
+#define AK4954_15_BEEP_FREQUENCY 0x15
+#define AK4954_16_BEEP_ON_TIME 0x16
+#define AK4954_17_BEEP_OFF_TIME 0x17
+#define AK4954_18_BEEP_REPEAT_COUNT 0x18
+#define AK4954_19_BEEP_VOLUME_CONTROL 0x19
+#define AK4954_1A_RESERVED 0x1A
+#define AK4954_1B_DIGITAL_FILTER_SELECT1 0x1B
+#define AK4954_1C_DIGITAL_FILTER_SELECT2 0x1C
+#define AK4954_1D_DIGITAL_FILTER_MODE 0x1D
+#define AK4954_1E_HPF2_COEFFICIENT0 0x1E
+#define AK4954_1F_HPF2_COEFFICIENT1 0x1F
+#define AK4954_20_HPF2_COEFFICIENT2 0x20
+#define AK4954_21_HPF2_COEFFICIENT3 0x21
+#define AK4954_22_LPF_COEFFICIENT0 0x22
+#define AK4954_23_LPF_COEFFICIENT1 0x23
+#define AK4954_24_LPF_COEFFICIENT2 0x24
+#define AK4954_25_LPF_COEFFICIENT3 0x25
+#define AK4954_26_FIL3_COEFFICIENT0 0x26
+#define AK4954_27_FIL3_COEFFICIENT1 0x27
+#define AK4954_28_FIL3_COEFFICIENT2 0x28
+#define AK4954_29_FIL3_COEFFICIENT3 0x29
+#define AK4954_2A_EQ_COEFFICIENT0 0x2A
+#define AK4954_2B_EQ_COEFFICIENT1 0x2B
+#define AK4954_2C_EQ_COEFFICIENT2 0x2C
+#define AK4954_2D_EQ_COEFFICIENT3 0x2D
+#define AK4954_2E_EQ_COEFFICIENT4 0x2E
+#define AK4954_2F_EQ_COEFFICIENT5 0x2F
+
+#define AK4954_30_DIGITAL_FILTER_SELECT3 0x30
+#define AK4954_31_RESERVED 0x31
+#define AK4954_32_E1_COEFFICIENT0 0x32
+#define AK4954_33_E1_COEFFICIENT1 0x33
+#define AK4954_34_E1_COEFFICIENT2 0x34
+#define AK4954_35_E1_COEFFICIENT3 0x35
+#define AK4954_36_E1_COEFFICIENT4 0x36
+#define AK4954_37_E1_COEFFICIENT5 0x37
+#define AK4954_38_E2_COEFFICIENT0 0x38
+#define AK4954_39_E2_COEFFICIENT1 0x39
+#define AK4954_3A_E2_COEFFICIENT2 0x3A
+#define AK4954_3B_E2_COEFFICIENT3 0x3B
+#define AK4954_3C_E2_COEFFICIENT4 0x3C
+#define AK4954_3D_E2_COEFFICIENT5 0x3D
+#define AK4954_3E_E3_COEFFICIENT0 0x3E
+#define AK4954_3F_E3_COEFFICIENT1 0x3F
+#define AK4954_40_E3_COEFFICIENT2 0x40
+#define AK4954_41_E3_COEFFICIENT3 0x41
+#define AK4954_42_E3_COEFFICIENT4 0x42
+#define AK4954_43_E3_COEFFICIENT5 0x43
+#define AK4954_44_E4_COEFFICIENT0 0x44
+#define AK4954_45_E4_COEFFICIENT1 0x45
+#define AK4954_46_E4_COEFFICIENT2 0x46
+#define AK4954_47_E4_COEFFICIENT3 0x47
+#define AK4954_48_E4_COEFFICIENT4 0x48
+#define AK4954_49_E4_COEFFICIENT5 0x49
+#define AK4954_4A_E5_COEFFICIENT0 0x4A
+#define AK4954_4B_E5_COEFFICIENT1 0x4B
+#define AK4954_4C_E5_COEFFICIENT2 0x4C
+#define AK4954_4D_E5_COEFFICIENT3 0x4D
+#define AK4954_4E_E5_COEFFICIENT4 0x4E
+#define AK4954_4F_E5_COEFFICIENT5 0x4F
+
+#define AK4954_50_DRC_MODE_CONTROL 0x50
+#define AK4954_51_NS_CONTROL 0x51
+#define AK4954_52_NS_GAIN_ATT_CONTROL 0x52
+#define AK4954_53_NS_ON_LEVEL 0x53
+#define AK4954_54_NS_OFF_LEVEL 0x54
+#define AK4954_55_NS_REFERENCE_SELECT 0x55
+#define AK4954_56_NS_LPF_COEFFICIENT0 0x56
+#define AK4954_57_NS_LPF_COEFFICIENT1 0x57
+#define AK4954_58_NS_LPF_COEFFICIENT2 0x58
+#define AK4954_59_NS_LPF_COEFFICIENT3 0x59
+#define AK4954_5A_NS_HPF_COEFFICIENT0 0x5A
+#define AK4954_5B_NS_HPF_COEFFICIENT1 0x5B
+#define AK4954_5C_NS_HPF_COEFFICIENT2 0x5C
+#define AK4954_5D_NS_HPF_COEFFICIENT3 0x5D
+#define AK4954_5E_RESERVED 0x5E
+#define AK4954_5F_RESERVED 0x5F
+#define AK4954_60_DVLC_FILTER_SELECT 0x60
+#define AK4954_61_DVLC_MODE_CONTROL 0x61
+#define AK4954_62_DVLCL_CURVE_X1 0x62
+#define AK4954_63_DVLCL_CURVE_Y1 0x63
+#define AK4954_64_DVLCL_CURVE_X2 0x64
+#define AK4954_65_DVLCL_CURVE_Y2 0x65
+#define AK4954_66_DVLCL_CURVE_X3 0x66
+#define AK4954_67_DVLCL_CURVE_Y3 0x67
+#define AK4954_68_DVLCL_SLOPE1 0x68
+#define AK4954_69_DVLCL_SLOPE2 0x69
+#define AK4954_6A_DVLCL_SLOPE3 0x6A
+#define AK4954_6B_DVLCL_SLOPE4 0x6B
+#define AK4954_6C_DVLCM_CURVE_X1 0x6C
+#define AK4954_6D_DVLCM_CURVE_Y1 0x6D
+#define AK4954_6E_DVLCM_CURVE_X2 0x6E
+#define AK4954_6F_DVLCM_CURVE_Y2 0x6F
+#define AK4954_70_DVLCM_CURVE_X3 0x70
+#define AK4954_71_DVLCM_CURVE_Y3 0x71
+#define AK4954_72_DVLCM_SLOPE1 0x72
+#define AK4954_73_DVLCM_SLOPE2 0x73
+#define AK4954_74_DVLCM_SLOPE3 0x74
+#define AK4954_75_DVLCM_SLOPE4 0x75
+#define AK4954_76_DVLCH_CURVE_X1 0x76
+#define AK4954_77_DVLCH_CURVE_Y1 0x77
+#define AK4954_78_DVLCH_CURVE_X2 0x78
+#define AK4954_79_DVLCH_CURVE_Y2 0x79
+#define AK4954_7A_DVLCH_CURVE_X3 0x7A
+#define AK4954_7B_DVLCH_CURVE_Y3 0x7B
+#define AK4954_7C_DVLCH_SLOPE1 0x7C
+#define AK4954_7D_DVLCH_SLOPE2 0x7D
+#define AK4954_7E_DVLCH_SLOPE3 0x7E
+#define AK4954_7F_DVLCH_SLOPE4 0x7F
+
+#define AK4954_80_DVLCL_LPF_COEFFICIENT0 0x80
+#define AK4954_81_DVLCL_LPF_COEFFICIENT1 0x81
+#define AK4954_82_DVLCL_LPF_COEFFICIENT2 0x82
+#define AK4954_83_DVLCL_LPF_COEFFICIENT3 0x83
+#define AK4954_84_DVLCM_HPF_COEFFICIENT0 0x84
+#define AK4954_85_DVLCM_HPF_COEFFICIENT1 0x85
+#define AK4954_86_DVLCM_HPF_COEFFICIENT2 0x86
+#define AK4954_87_DVLCM_HPF_COEFFICIENT3 0x87
+#define AK4954_88_DVLCM_LPF_COEFFICIENT0 0x88
+#define AK4954_89_DVLCM_LPF_COEFFICIENT1 0x89
+#define AK4954_8A_DVLCM_LPF_COEFFICIENT2 0x8A
+#define AK4954_8B_DVLCM_LPF_COEFFICIENT3 0x8B
+#define AK4954_8C_DVLCH_HPF_COEFFICIENT0 0x8C
+#define AK4954_8D_DVLCH_HPF_COEFFICIENT1 0x8D
+#define AK4954_8E_DVLCH_HPF_COEFFICIENT2 0x8E
+#define AK4954_8F_DVLCH_HPF_COEFFICIENT3 0x8F
+
+#define AK4954_MAX_REGISTERS (AK4954_8F_DVLCH_HPF_COEFFICIENT3 + 1)
+
+/* Bitfield Definitions */
+
+/* AK4954_00_POWER_MANAGEMENT1 (0x00) Fields */
+#define AK4954_PMVCM 0x40
+
+/* AK4954_01_POWER_MANAGEMENT2 (0x01) Fields */
+#define AK4954_PMPLL 0x04
+#define AK4954_M_S 0x08
+
+/* AK4954_05_MODE_CONTROL1 (0x05) Fields */
+#define AK4954_DIF 0x07
+#define AK4954_DIF_24MSB_24LSB_MODE (0 << 0)
+#define AK4954_DIF_24MSB_16LSB_MODE (1 << 0)
+#define AK4954_DIF_24MSB_MODE (2 << 0)
+#define AK4954_DIF_24_16_I2S_MODE (3 << 0)
+#define AK4954_DIF_32MSB_MODE (4 << 0)
+#define AK4954_DIF_32_I2S_MODE (5 << 0)
+#define AK4954_BCKO 0x08
+
+#define AK4954_PLL 0x70
+#define AK4954_EXT_SLAVE 0
+#define AK4954_PLL_BICK32 (0 << 4)
+#define AK4954_PLL_BICK64 (1 << 4)
+#define AK4954_PLL_11_2896MHZ (2 << 4)
+#define AK4954_PLL_12MHZ (4 << 4)
+#define AK4954_PLL_24MHZ (5 << 4)
+#define AK4954_PLL_13_5MHZ (6 << 4)
+#define AK4954_PLL_27MHZ (7 << 4)
+
+
+
+#define AK4954_MCLK_IN 0
+#define AK4954_BCLK_IN 1
+#define AK4954_MCLK_IN_BCLK_OUT 2
+
+
+
+/* AK4954_06_MODE_CONTROL2 (0x06) Fields */
+#define AK4954_FS 0x0F
+#define AK4954_FS_8KHZ (0 << 0)
+#define AK4954_FS_11_025KHZ (1 << 0)
+#define AK4954_FS_12KHZ (2 << 0)
+#define AK4954_FS_16KHZ (4 << 0)
+#define AK4954_FS_22_05KHZ (5 << 0)
+#define AK4954_FS_24KHZ (6 << 0)
+#define AK4954_FS_32KHZ (8 << 0)
+#define AK4954_FS_44_1KHZ (9 << 0)
+#define AK4954_FS_48KHZ (10 << 0)
+#define AK4954_FS_64KHZ (12 << 0)
+#define AK4954_FS_88_2KHZ (13 << 0)
+#define AK4954_FS_96KHZ (14 << 0)
+#define AK4954_FS_CM0 (1 << 6)
+#define AK4954_FS_CM1 (1 << 7)
+
+#endif
diff --git a/sound/soc/codecs/ak7719_amb.c b/sound/soc/codecs/ak7719_amb.c
new file mode 100644
index 00000000..0de1c607
--- /dev/null
+++ b/sound/soc/codecs/ak7719_amb.c
@@ -0,0 +1,6416 @@
+/*
+ * sound/soc/ambarella/ak7719.c
+ *
+ * History:
+ * 2014/04/17 - [Ken He] Created file
+ *
+ * Copyright (C) 2014-2018, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/delay.h>
+#include <linux/skbuff.h>
+#include <linux/workqueue.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <plat/audio.h>
+
+#define DRIVER_NAME "AK7719"
+#define CRC16_CCITT (0x1021)
+//#define BY_PASS_DSP
+//#define AK7719_DEBUG
+
+#ifdef AK7719_DEBUG
+#define akdbgprt printk
+#else
+#define akdbgprt(format, arg...) do {} while (0)
+#endif
+
+static int crc_timeout = 10;
+module_param(crc_timeout, uint, 0664);
+
+static int aec = 1;
+module_param(aec, uint, 0664);
+
+struct ak7719_data {
+ unsigned int rst_pin;
+ unsigned int rst_active;
+ struct i2c_client *client;
+ struct device *dev;
+};
+
+struct ak7719_workqueue{
+ struct ak7719_data *data;
+ struct work_struct download_binary;
+};
+
+static struct ak7719_workqueue ak7719_work;
+static struct workqueue_struct *ak7719_wq;
+
+u8 pram_data[] = {
+ 0x0C, 0xB4, 0xED, 0x1E, 0x42,
+ 0x04, 0xA9, 0x1C, 0x6D, 0x49,
+ 0x04, 0x44, 0x82, 0x1A, 0x44,
+ 0x0F, 0x58, 0x7E, 0x4D, 0x88,
+ 0x0D, 0x5A, 0x7E, 0x89, 0x1D,
+ 0x03, 0x35, 0x1C, 0x03, 0x8C,
+ 0x0F, 0x4A, 0x05, 0x6C, 0x68,
+ 0x0A, 0x70, 0xFF, 0x60, 0xE7,
+ 0x01, 0x83, 0x9B, 0x95, 0x72,
+ 0x09, 0x79, 0x72, 0x83, 0xAE,
+ 0x07, 0xAE, 0xA6, 0x4F, 0x67,
+ 0x0E, 0xD9, 0xA5, 0xD2, 0x80,
+ 0x00, 0x7B, 0xE2, 0xEA, 0x9E,
+ 0x05, 0xDB, 0xB3, 0xF9, 0xAC,
+ 0x0E, 0x38, 0x0C, 0xB8, 0x91,
+ 0x03, 0x81, 0xB6, 0x89, 0xCA,
+ 0x0C, 0xDF, 0x09, 0xD1, 0x5F,
+ 0x0F, 0x78, 0x28, 0xDB, 0xF2,
+ 0x06, 0x67, 0x95, 0x59, 0x5B,
+ 0x0B, 0xF4, 0x98, 0x6B, 0x25,
+ 0x0A, 0x72, 0xD4, 0x2D, 0xBB,
+ 0x09, 0xAE, 0x33, 0x01, 0x57,
+ 0x09, 0x6B, 0xBD, 0xBA, 0x4F,
+ 0x01, 0x54, 0x86, 0x70, 0xBB,
+ 0x0F, 0x53, 0xBC, 0x3F, 0xE7,
+ 0x0B, 0xC4, 0x7B, 0x42, 0x4E,
+ 0x08, 0x79, 0x17, 0x62, 0xAD,
+ 0x0A, 0x33, 0xE5, 0x31, 0x10,
+ 0x04, 0x47, 0xD3, 0x15, 0x7C,
+ 0x01, 0x37, 0xC4, 0x85, 0x60,
+ 0x00, 0xA2, 0x23, 0xE4, 0xD4,
+ 0x07, 0x81, 0x74, 0x8D, 0x2F,
+ 0x03, 0x31, 0xCD, 0x59, 0xE3,
+ 0x02, 0x83, 0x5B, 0x76, 0x35,
+ 0x00, 0xD5, 0x02, 0x95, 0xE5,
+ 0x00, 0x0E, 0x1C, 0xDE, 0xA7,
+ 0x03, 0xCC, 0xE5, 0x7B, 0x43,
+ 0x07, 0x78, 0x7B, 0xC1, 0xF0,
+ 0x07, 0x99, 0x68, 0x27, 0x75,
+ 0x09, 0x26, 0xC9, 0x48, 0xCB,
+ 0x0A, 0xE2, 0x66, 0x20, 0x0F,
+ 0x00, 0x27, 0x5E, 0x03, 0x67,
+ 0x04, 0x85, 0x12, 0xD3, 0xDD,
+ 0x09, 0x6F, 0xCD, 0xA9, 0x87,
+ 0x0C, 0x65, 0x18, 0x5F, 0xD1,
+ 0x0F, 0xAC, 0xB4, 0x47, 0xD4,
+ 0x0C, 0x76, 0x67, 0x16, 0x91,
+ 0x0A, 0x05, 0x2B, 0x4B, 0xB2,
+ 0x0C, 0xE9, 0x3F, 0x75, 0x12,
+ 0x05, 0xC6, 0x96, 0xCD, 0x0A,
+ 0x0A, 0x3C, 0x32, 0xDF, 0x24,
+ 0x02, 0x09, 0x4E, 0xC1, 0xE5,
+ 0x07, 0x49, 0x92, 0xC6, 0xE0,
+ 0x04, 0xC4, 0x40, 0x31, 0x1A,
+ 0x02, 0x55, 0x86, 0x34, 0xDF,
+ 0x06, 0x15, 0xA2, 0xAC, 0x9B,
+ 0x0F, 0x93, 0x51, 0x30, 0x18,
+ 0x0A, 0x34, 0xBD, 0xA2, 0x8D,
+ 0x05, 0x67, 0xD6, 0xFA, 0x10,
+ 0x06, 0x58, 0x09, 0x7D, 0x54,
+ 0x06, 0x51, 0x2E, 0x70, 0x0F,
+ 0x0E, 0x7A, 0xAA, 0x64, 0x04,
+ 0x09, 0xED, 0xDD, 0xDD, 0xD9,
+ 0x03, 0x07, 0xB2, 0x2E, 0x5D,
+ 0x09, 0x1D, 0x88, 0xCF, 0x9B,
+ 0x09, 0x3C, 0x72, 0x57, 0xB8,
+ 0x04, 0x80, 0xCF, 0x70, 0x95,
+ 0x0B, 0x0D, 0xEB, 0xB9, 0x14,
+ 0x0B, 0x4F, 0xD9, 0x29, 0xF5,
+ 0x0A, 0xA6, 0xEE, 0xB1, 0x9D,
+ 0x09, 0x7F, 0x47, 0x8E, 0xB8,
+ 0x04, 0x1F, 0x74, 0x1A, 0xDB,
+ 0x0C, 0x5A, 0xF9, 0x28, 0x1A,
+ 0x07, 0x2E, 0x76, 0x7F, 0xA4,
+ 0x09, 0xEA, 0x48, 0x67, 0x3A,
+ 0x03, 0x35, 0xBB, 0xC3, 0x3E,
+ 0x03, 0x7F, 0x5C, 0xC8, 0x17,
+ 0x0B, 0x47, 0x9F, 0xB2, 0x20,
+ 0x07, 0x1B, 0x57, 0x9F, 0x5B,
+ 0x00, 0x84, 0x61, 0xB5, 0x1C,
+ 0x0B, 0xD3, 0x72, 0xA4, 0x1C,
+ 0x0F, 0xB2, 0x4B, 0xF2, 0x07,
+ 0x0C, 0xC0, 0x63, 0xA4, 0x58,
+ 0x0E, 0x8B, 0x1D, 0xE9, 0x14,
+ 0x0E, 0xE8, 0x37, 0xBB, 0x2A,
+ 0x0E, 0xF5, 0x50, 0x29, 0x5E,
+ 0x0D, 0xC0, 0xE7, 0x47, 0xF6,
+ 0x08, 0x90, 0xCA, 0x1A, 0x32,
+ 0x08, 0x77, 0x85, 0xF2, 0x57,
+ 0x00, 0x81, 0x10, 0x4A, 0xB6,
+ 0x0F, 0x3E, 0x6E, 0x54, 0x84,
+ 0x0C, 0x4E, 0x3D, 0xA2, 0x5D,
+ 0x08, 0xC2, 0x72, 0xBA, 0x35,
+ 0x0D, 0xE4, 0x50, 0xAD, 0x3F,
+ 0x08, 0x96, 0xFC, 0x9A, 0x9F,
+ 0x0C, 0xC6, 0x51, 0xA5, 0xFA,
+ 0x0A, 0x25, 0x34, 0xC0, 0x4E,
+ 0x08, 0x6B, 0xEE, 0xC8, 0x6B,
+ 0x06, 0xA1, 0xD0, 0x3C, 0xA6,
+ 0x08, 0x06, 0x73, 0xDB, 0x51,
+ 0x08, 0x1A, 0xCB, 0x6C, 0x10,
+ 0x05, 0x0F, 0xB8, 0xBD, 0xB1,
+ 0x01, 0x20, 0x94, 0xE5, 0x1E,
+ 0x00, 0xD8, 0x69, 0x1C, 0x64,
+ 0x0C, 0x3C, 0xC4, 0x02, 0x11,
+ 0x08, 0xE4, 0x87, 0xAF, 0x49,
+ 0x04, 0xA0, 0xBA, 0x7E, 0xCD,
+ 0x0D, 0xF9, 0x37, 0x35, 0x03,
+ 0x0C, 0xA3, 0x49, 0xFE, 0x26,
+ 0x09, 0x97, 0xF8, 0x3B, 0xBD,
+ 0x0F, 0x5D, 0x62, 0xDB, 0xD5,
+ 0x09, 0x03, 0x9B, 0x77, 0xC3,
+ 0x05, 0x27, 0x2C, 0xA2, 0xC9,
+ 0x04, 0x5F, 0x4F, 0xE1, 0xC3,
+ 0x04, 0x75, 0x05, 0x66, 0x17,
+ 0x0D, 0x28, 0x43, 0xBC, 0xE4,
+ 0x0D, 0x51, 0x57, 0x1A, 0xBC,
+ 0x04, 0x8B, 0x4C, 0x23, 0x0C,
+ 0x01, 0x35, 0x47, 0x9B, 0x91,
+ 0x02, 0xB4, 0xFF, 0x92, 0x5B,
+ 0x02, 0x6A, 0x66, 0x07, 0x13,
+ 0x0A, 0x97, 0x3D, 0x18, 0xE2,
+ 0x00, 0xF1, 0x1D, 0x81, 0xA4,
+ 0x0B, 0x05, 0xAF, 0xA8, 0x33,
+ 0x0A, 0xF2, 0xEC, 0x05, 0x8E,
+ 0x03, 0x5D, 0x87, 0x06, 0x79,
+ 0x01, 0xB2, 0xC3, 0xBC, 0x22,
+ 0x0C, 0xF6, 0x4B, 0xCC, 0x9F,
+ 0x08, 0x31, 0xC6, 0x73, 0x93,
+ 0x08, 0x70, 0x37, 0x31, 0x2C,
+ 0x0C, 0x09, 0xA3, 0xD3, 0x96,
+ 0x08, 0x3D, 0xD7, 0x22, 0x45,
+ 0x00, 0x7A, 0xC4, 0xB7, 0xA4,
+ 0x08, 0xCC, 0xC2, 0x32, 0x84,
+ 0x0F, 0xE8, 0xBB, 0xD2, 0x87,
+ 0x03, 0xEE, 0x81, 0x5F, 0x7C,
+ 0x09, 0x5F, 0x5D, 0x0E, 0x55,
+ 0x07, 0xDC, 0x0E, 0x72, 0xAD,
+ 0x0A, 0x09, 0xAC, 0xE1, 0x7B,
+ 0x06, 0xE7, 0xFA, 0x7F, 0xC1,
+ 0x03, 0x8B, 0x53, 0x44, 0xAE,
+ 0x08, 0xF3, 0xE6, 0xC3, 0x02,
+ 0x0F, 0x6A, 0x33, 0xA2, 0x29,
+ 0x00, 0x8C, 0x25, 0x2C, 0x89,
+ 0x03, 0xBE, 0xA5, 0x06, 0xD3,
+ 0x0F, 0xCF, 0x8F, 0xC9, 0x69,
+ 0x02, 0x0C, 0x2F, 0x1A, 0x1F,
+ 0x01, 0x63, 0xAC, 0xB5, 0xF4,
+ 0x04, 0xDE, 0x52, 0xE0, 0x16,
+ 0x07, 0x2C, 0xE1, 0x2B, 0x08,
+ 0x02, 0x1C, 0xA4, 0x3D, 0x55,
+ 0x0A, 0x19, 0x42, 0xFF, 0x4D,
+ 0x0E, 0xF0, 0xFF, 0x83, 0xDF,
+ 0x07, 0x32, 0x09, 0x4E, 0xD1,
+ 0x05, 0xCD, 0x8A, 0x97, 0xC6,
+ 0x09, 0xC5, 0x66, 0xC0, 0x3C,
+ 0x08, 0x3E, 0xD7, 0x86, 0xF4,
+ 0x00, 0x8A, 0xD1, 0xE7, 0xE5,
+ 0x02, 0xDF, 0x91, 0x57, 0x3A,
+ 0x03, 0x4F, 0x7B, 0x3F, 0xA2,
+ 0x0C, 0xDC, 0x28, 0x0F, 0xBA,
+ 0x01, 0x6D, 0x4A, 0x6D, 0x60,
+ 0x08, 0x0A, 0x44, 0x57, 0x78,
+ 0x02, 0x50, 0x3F, 0x6A, 0x24,
+ 0x0F, 0x84, 0x68, 0x9A, 0x00,
+ 0x0D, 0xFF, 0xDE, 0xBE, 0x27,
+ 0x04, 0x12, 0x9D, 0xA3, 0x07,
+ 0x0B, 0x15, 0x23, 0x89, 0xA1,
+ 0x00, 0x68, 0x60, 0x4E, 0x30,
+ 0x05, 0x2D, 0xEF, 0xE9, 0xF9,
+ 0x0E, 0x2B, 0x19, 0x59, 0x05,
+ 0x07, 0x26, 0x24, 0x62, 0xB1,
+ 0x0E, 0x69, 0x17, 0xC5, 0x8F,
+ 0x0A, 0xCF, 0x9D, 0x78, 0xDA,
+ 0x07, 0xB1, 0xFD, 0x7A, 0xB5,
+ 0x0F, 0x2A, 0x61, 0x60, 0x73,
+ 0x0F, 0x70, 0x9B, 0xC8, 0x67,
+ 0x07, 0xDA, 0xB7, 0x7B, 0xDE,
+ 0x02, 0x0E, 0xFE, 0x5C, 0xD5,
+ 0x07, 0x3B, 0x47, 0x99, 0x36,
+ 0x06, 0x47, 0x04, 0x17, 0x21,
+ 0x01, 0x70, 0x04, 0x61, 0x39,
+ 0x06, 0x1B, 0xD1, 0x72, 0x28,
+ 0x06, 0x9F, 0xB0, 0x4F, 0x74,
+ 0x04, 0xCC, 0x2C, 0x63, 0xE8,
+ 0x08, 0xFE, 0xE3, 0x9D, 0x45,
+ 0x07, 0xBE, 0x08, 0x35, 0x77,
+ 0x0A, 0xB5, 0x90, 0xD0, 0x09,
+ 0x02, 0x5C, 0xA0, 0xE7, 0x54,
+ 0x00, 0x2D, 0xF6, 0x42, 0x9F,
+ 0x0A, 0x69, 0x13, 0xC7, 0xE1,
+ 0x05, 0x7D, 0xD5, 0x96, 0x38,
+ 0x0A, 0x8E, 0xD6, 0xEC, 0x50,
+ 0x02, 0x37, 0x47, 0xA6, 0x27,
+ 0x0A, 0x8D, 0xB0, 0xF4, 0x9E,
+ 0x07, 0xA6, 0xE4, 0x54, 0x8F,
+ 0x03, 0x65, 0xF2, 0xBC, 0x87,
+ 0x05, 0x80, 0x1D, 0xD1, 0xAC,
+ 0x06, 0x93, 0x56, 0xCD, 0x8E,
+ 0x01, 0xD1, 0x82, 0xEE, 0xC5,
+ 0x07, 0xEB, 0x48, 0x92, 0xB9,
+ 0x00, 0x04, 0xBC, 0x15, 0xE5,
+ 0x0B, 0x21, 0xF4, 0xAF, 0x6D,
+ 0x0C, 0xEE, 0x68, 0x78, 0x20,
+ 0x0D, 0x73, 0x36, 0x54, 0xE5,
+ 0x05, 0xF9, 0xAE, 0xAF, 0x2E,
+ 0x0D, 0x5C, 0x4C, 0x40, 0x60,
+ 0x01, 0x84, 0xE5, 0x5C, 0xCD,
+ 0x07, 0xC8, 0xC8, 0xDA, 0x7F,
+ 0x09, 0x2D, 0xF9, 0x31, 0x11,
+ 0x01, 0x8C, 0xA3, 0x4F, 0xD9,
+ 0x00, 0x74, 0x14, 0xF8, 0xE6,
+ 0x08, 0xD6, 0x51, 0x8E, 0xD7,
+ 0x0D, 0x46, 0x29, 0x79, 0xB4,
+ 0x09, 0x9D, 0x4A, 0xAE, 0xE2,
+ 0x0B, 0x38, 0xDE, 0xD1, 0x10,
+ 0x07, 0x1F, 0x30, 0x73, 0x62,
+ 0x0C, 0x41, 0x47, 0xDA, 0x3D,
+ 0x01, 0xB1, 0xD2, 0x30, 0x2B,
+ 0x01, 0x98, 0x48, 0x0C, 0xE3,
+ 0x00, 0x4A, 0x50, 0xDE, 0x5B,
+ 0x0B, 0x42, 0xC5, 0x7D, 0xB2,
+ 0x03, 0x72, 0xCA, 0x6A, 0x43,
+ 0x05, 0x47, 0xF0, 0x74, 0x45,
+ 0x07, 0x2D, 0x39, 0xF7, 0x45,
+ 0x01, 0xBA, 0xD5, 0xEF, 0xAF,
+ 0x0A, 0xCF, 0x88, 0x6E, 0x07,
+ 0x06, 0x4E, 0xDE, 0xC4, 0x9B,
+ 0x0C, 0xBC, 0x2E, 0xC3, 0xA1,
+ 0x0D, 0xE0, 0xF7, 0xC3, 0xCC,
+ 0x0E, 0x59, 0xB4, 0x79, 0xEF,
+ 0x02, 0xD4, 0xF3, 0xB5, 0x71,
+ 0x0D, 0x10, 0xCE, 0xC6, 0x1A,
+ 0x05, 0x61, 0xBF, 0x33, 0x28,
+ 0x0E, 0xEC, 0xB4, 0xA4, 0xB7,
+ 0x0F, 0x51, 0x83, 0x86, 0x32,
+ 0x01, 0x2F, 0x7A, 0xF1, 0xCB,
+ 0x02, 0x61, 0xAB, 0x03, 0x53,
+ 0x0A, 0x0A, 0xDA, 0x15, 0x1F,
+ 0x09, 0xE4, 0x5C, 0x0E, 0x6A,
+ 0x0E, 0xBA, 0x8D, 0x0C, 0x29,
+ 0x0B, 0x66, 0x87, 0x7C, 0x75,
+ 0x01, 0xEF, 0x8B, 0x99, 0xCC,
+ 0x0B, 0x68, 0xDF, 0xA6, 0xCD,
+ 0x08, 0xE3, 0x6A, 0xE0, 0xD9,
+ 0x00, 0x10, 0x8E, 0x25, 0x90,
+ 0x03, 0x7A, 0x6E, 0xCB, 0x80,
+ 0x03, 0xF6, 0x41, 0xE1, 0x03,
+ 0x05, 0x99, 0x8A, 0xE5, 0x07,
+ 0x0F, 0xD1, 0x6B, 0x2C, 0x42,
+ 0x07, 0xDD, 0x04, 0xB4, 0x5E,
+ 0x0D, 0x3B, 0x7B, 0x07, 0x98,
+ 0x07, 0xB9, 0x9A, 0xE9, 0x20,
+ 0x09, 0x13, 0x9D, 0xC2, 0xEB,
+ 0x0D, 0x0E, 0xF2, 0xFF, 0x47,
+ 0x0D, 0x17, 0x32, 0x87, 0x04,
+ 0x03, 0xE7, 0xCD, 0x04, 0x9B,
+ 0x06, 0x25, 0x64, 0xC4, 0x40,
+ 0x01, 0x68, 0xCC, 0x57, 0x34,
+ 0x0D, 0x1C, 0x6A, 0x19, 0xA7,
+ 0x05, 0x14, 0x3F, 0x93, 0x13,
+ 0x0A, 0x18, 0x4F, 0x34, 0x9F,
+ 0x0E, 0xC7, 0x99, 0x67, 0x86,
+ 0x0A, 0x0D, 0x6F, 0xD8, 0x2D,
+ 0x01, 0x54, 0xC0, 0x17, 0x9E,
+ 0x08, 0x39, 0x50, 0x78, 0x6A,
+ 0x08, 0x31, 0xA5, 0xED, 0x9E,
+ 0x0D, 0xE1, 0xFF, 0x01, 0xFC,
+ 0x02, 0x64, 0x9D, 0x5D, 0xA7,
+ 0x03, 0x9B, 0x13, 0x63, 0x85,
+ 0x0B, 0x89, 0x88, 0x80, 0xC8,
+ 0x0C, 0x9C, 0xAB, 0x8D, 0xE1,
+ 0x05, 0x15, 0x81, 0x4F, 0xC4,
+ 0x0E, 0x3A, 0x69, 0x24, 0xE2,
+ 0x0A, 0x11, 0x26, 0xFF, 0x45,
+ 0x02, 0xB0, 0x10, 0xDF, 0x70,
+ 0x06, 0xDA, 0x30, 0x5A, 0xE7,
+ 0x08, 0x14, 0xAD, 0x28, 0xE2,
+ 0x03, 0xA4, 0xF7, 0xD0, 0x42,
+ 0x0B, 0x0A, 0x5C, 0xF4, 0x26,
+ 0x08, 0x7B, 0xF9, 0x7C, 0xAD,
+ 0x04, 0x25, 0xF2, 0x07, 0x96,
+ 0x06, 0x2A, 0x45, 0x1B, 0x57,
+ 0x03, 0x11, 0x00, 0x08, 0xEB,
+ 0x09, 0x56, 0x19, 0xDF, 0xB8,
+ 0x04, 0x57, 0x1D, 0x32, 0x56,
+ 0x06, 0x4D, 0xC0, 0xCC, 0x63,
+ 0x00, 0xD4, 0x72, 0x8B, 0xDD,
+ 0x0F, 0x9E, 0xAC, 0xE8, 0x75,
+ 0x0F, 0x60, 0x35, 0xFD, 0xA1,
+ 0x00, 0x5E, 0x9D, 0xC8, 0x27,
+ 0x03, 0xEB, 0x3B, 0x90, 0xCF,
+ 0x0F, 0xB6, 0xE8, 0x7F, 0x36,
+ 0x05, 0x1E, 0x38, 0xB1, 0x10,
+ 0x03, 0xF6, 0x6F, 0x3E, 0xAC,
+ 0x0E, 0x8E, 0xA0, 0x2E, 0x06,
+ 0x0A, 0x81, 0xA8, 0xCE, 0x32,
+ 0x00, 0x36, 0xC1, 0x64, 0x4D,
+ 0x01, 0x3E, 0xBC, 0xD6, 0xF8,
+ 0x06, 0x98, 0x60, 0x46, 0x54,
+ 0x0E, 0x78, 0x6C, 0xBA, 0xCB,
+ 0x00, 0x7C, 0x53, 0xAB, 0x73,
+ 0x0D, 0x6B, 0xF8, 0x60, 0x5A,
+ 0x0E, 0xBB, 0x83, 0x48, 0x93,
+ 0x0B, 0x50, 0x81, 0x9C, 0x32,
+ 0x0C, 0xA0, 0x6D, 0x0F, 0xF8,
+ 0x01, 0xF1, 0xBD, 0x60, 0x9D,
+ 0x0D, 0x1E, 0x7E, 0xDC, 0xA3,
+ 0x07, 0xE8, 0x13, 0xCC, 0x44,
+ 0x09, 0x94, 0xCB, 0x65, 0x58,
+ 0x03, 0x4D, 0x5A, 0xE1, 0x47,
+ 0x05, 0x4B, 0x68, 0x79, 0x35,
+ 0x0F, 0x01, 0x73, 0x63, 0x43,
+ 0x06, 0x2D, 0xF0, 0x56, 0x65,
+ 0x0B, 0xA0, 0xD6, 0xD9, 0x88,
+ 0x07, 0xD5, 0x40, 0xA5, 0xB1,
+ 0x0B, 0x03, 0xB1, 0x67, 0xA6,
+ 0x02, 0x43, 0x38, 0x5C, 0x62,
+ 0x01, 0xDE, 0x1D, 0xF2, 0xC1,
+ 0x02, 0xE6, 0x41, 0xA7, 0x10,
+ 0x00, 0xF8, 0x31, 0x12, 0x25,
+ 0x06, 0xB9, 0x12, 0xC8, 0x19,
+ 0x03, 0x09, 0xCA, 0x30, 0x2F,
+ 0x0B, 0x91, 0x40, 0xB6, 0x4F,
+ 0x09, 0xDE, 0x2D, 0xE8, 0xD5,
+ 0x0F, 0x18, 0xC2, 0xD7, 0xE9,
+ 0x08, 0xEB, 0x2E, 0xF1, 0xF7,
+ 0x03, 0xAD, 0xBB, 0x8B, 0xE5,
+ 0x06, 0x81, 0xCA, 0x32, 0xF3,
+ 0x07, 0x4A, 0xCD, 0x53, 0x4E,
+ 0x0A, 0x70, 0xBB, 0x33, 0x4B,
+ 0x07, 0xBD, 0xA1, 0xF7, 0xC5,
+ 0x00, 0x83, 0x0C, 0x74, 0x7D,
+ 0x0F, 0x63, 0x24, 0x31, 0xA8,
+ 0x01, 0x31, 0x12, 0x0E, 0x44,
+ 0x0F, 0x94, 0xEA, 0x3D, 0x2A,
+ 0x02, 0x85, 0x6B, 0xFB, 0xD5,
+ 0x0C, 0x61, 0x22, 0xCE, 0xB4,
+ 0x0E, 0x8D, 0xFF, 0x28, 0xB8,
+ 0x06, 0x59, 0xE1, 0xEE, 0x83,
+ 0x0B, 0x76, 0x0B, 0xD3, 0xDF,
+ 0x02, 0x95, 0xE7, 0xD0, 0xC4,
+ 0x08, 0x9E, 0x2A, 0x89, 0x08,
+ 0x0D, 0x79, 0x86, 0x87, 0x7C,
+ 0x03, 0xC0, 0x6B, 0x4B, 0x84,
+ 0x08, 0xA7, 0xBB, 0x73, 0xEF,
+ 0x0D, 0x48, 0x63, 0x6A, 0x62,
+ 0x00, 0x20, 0x10, 0x8C, 0xA7,
+ 0x06, 0xC3, 0xE8, 0x2E, 0x58,
+ 0x0A, 0xA2, 0x76, 0x49, 0x6F,
+ 0x05, 0xA9, 0x8B, 0x4C, 0x6D,
+ 0x01, 0xDD, 0x96, 0xE3, 0xAC,
+ 0x03, 0xC7, 0xDF, 0x06, 0xB6,
+ 0x0C, 0x16, 0xBC, 0xAE, 0x0F,
+ 0x07, 0xCA, 0x1D, 0x1C, 0xF4,
+ 0x06, 0xF0, 0x5D, 0x99, 0xC2,
+ 0x0D, 0x48, 0x41, 0x70, 0xFF,
+ 0x0F, 0xDE, 0x97, 0xF2, 0x14,
+ 0x07, 0x51, 0x07, 0xC1, 0x8A,
+ 0x08, 0x40, 0x37, 0xC4, 0x04,
+ 0x00, 0x21, 0x1A, 0x4A, 0x5F,
+ 0x0A, 0xF5, 0x53, 0x8A, 0x08,
+ 0x0C, 0x69, 0xEC, 0x5B, 0x62,
+ 0x0F, 0x31, 0x8A, 0x8A, 0x29,
+ 0x03, 0xA1, 0x80, 0x99, 0x63,
+ 0x03, 0xB9, 0x2D, 0x6D, 0xDD,
+ 0x06, 0xF8, 0xCD, 0x0A, 0x57,
+ 0x0B, 0x71, 0xBD, 0x52, 0x67,
+ 0x06, 0x25, 0xDA, 0x45, 0xF0,
+ 0x08, 0x1D, 0xE3, 0xF9, 0x07,
+ 0x0E, 0x2E, 0x64, 0x12, 0x9D,
+ 0x03, 0xBF, 0x1B, 0x91, 0x29,
+ 0x0D, 0xAB, 0x89, 0x88, 0x80,
+ 0x02, 0x30, 0x9E, 0xAF, 0x07,
+ 0x02, 0x3C, 0x42, 0x2F, 0x4F,
+ 0x05, 0x25, 0xBA, 0x26, 0xAF,
+ 0x00, 0x31, 0x96, 0x65, 0x6E,
+ 0x09, 0x8E, 0x32, 0xCF, 0x28,
+ 0x0C, 0x99, 0xFB, 0xB2, 0xDA,
+ 0x02, 0xA2, 0x34, 0xA2, 0xEE,
+ 0x0A, 0x73, 0x7C, 0x75, 0xF4,
+ 0x08, 0x67, 0x09, 0xDF, 0x7E,
+ 0x03, 0xC2, 0x7E, 0x03, 0x7C,
+ 0x06, 0xC9, 0x91, 0xBB, 0x67,
+ 0x03, 0x36, 0x2A, 0x47, 0x12,
+ 0x07, 0x13, 0x13, 0x00, 0x84,
+ 0x01, 0x39, 0x56, 0x9B, 0xD3,
+ 0x0A, 0x28, 0xD6, 0x1D, 0x32,
+ 0x03, 0xFE, 0xED, 0xCE, 0x40,
+ 0x0A, 0x28, 0x12, 0x7C, 0x0B,
+ 0x04, 0xE5, 0x7E, 0xBC, 0x68,
+ 0x05, 0xB7, 0x60, 0x37, 0x4E,
+ 0x00, 0x29, 0x5E, 0xDF, 0x7A,
+ 0x07, 0x49, 0xEB, 0x2A, 0x29,
+ 0x0E, 0x17, 0xB6, 0xEA, 0xCF,
+ 0x07, 0xFC, 0x1E, 0x7A, 0x0E,
+ 0x00, 0x4A, 0x76, 0x0D, 0x88,
+ 0x0C, 0x54, 0x8E, 0xB4, 0x1B,
+ 0x06, 0x22, 0x01, 0x8A, 0x76,
+ 0x02, 0xAC, 0x37, 0x24, 0x57,
+ 0x00, 0xAD, 0x3F, 0xE6, 0x24,
+ 0x0C, 0x9A, 0x99, 0x02, 0x77,
+ 0x01, 0xA5, 0xFD, 0x94, 0x8A,
+ 0x0B, 0x3C, 0x7D, 0x52, 0xED,
+ 0x0E, 0xC1, 0x6B, 0x68, 0x27,
+ 0x02, 0xBC, 0xB9, 0x83, 0x4A,
+ 0x03, 0xD7, 0x51, 0x23, 0x19,
+ 0x03, 0x6C, 0xD0, 0xEF, 0x31,
+ 0x06, 0x3D, 0xF1, 0x73, 0x20,
+ 0x0B, 0x6D, 0x1E, 0x7C, 0xD8,
+ 0x05, 0x1C, 0x6D, 0x5C, 0x45,
+ 0x04, 0x02, 0x13, 0x84, 0xE5,
+ 0x08, 0x6F, 0x4D, 0x4E, 0xAB,
+ 0x0A, 0x7E, 0xC9, 0xAB, 0xB3,
+ 0x05, 0x33, 0x01, 0x0A, 0x29,
+ 0x0B, 0xFA, 0x2C, 0xF3, 0x5C,
+ 0x08, 0xFB, 0xA0, 0x58, 0x17,
+ 0x02, 0xD7, 0xD5, 0xCE, 0x2F,
+ 0x09, 0x77, 0x03, 0x13, 0x6D,
+ 0x0E, 0xA2, 0x43, 0xB6, 0x54,
+ 0x09, 0xA1, 0xDE, 0x92, 0x3A,
+ 0x0B, 0xE2, 0xE6, 0xCC, 0xA3,
+ 0x0A, 0x3C, 0xF9, 0x3C, 0x18,
+ 0x08, 0xDA, 0xB8, 0x15, 0x82,
+ 0x04, 0x23, 0x09, 0x46, 0x7A,
+ 0x0E, 0x9B, 0x91, 0xCE, 0x3E,
+ 0x0D, 0x92, 0x5B, 0x7E, 0x20,
+ 0x06, 0x03, 0x19, 0xCA, 0x9D,
+ 0x04, 0x58, 0xEB, 0xAF, 0x7B,
+ 0x07, 0x41, 0xAD, 0x38, 0xCF,
+ 0x0F, 0xAA, 0x81, 0xC9, 0xF8,
+ 0x0E, 0x07, 0x38, 0x4C, 0x17,
+ 0x0B, 0x06, 0x70, 0xBD, 0xB3,
+ 0x03, 0xBC, 0x3D, 0xE0, 0xFD,
+ 0x09, 0xCC, 0x82, 0x53, 0x8A,
+ 0x05, 0xD3, 0x62, 0xA4, 0x4E,
+ 0x09, 0x71, 0x31, 0x10, 0x0E,
+ 0x0A, 0x03, 0x95, 0x61, 0xBA,
+ 0x0B, 0x22, 0x95, 0x69, 0xC1,
+ 0x08, 0xB6, 0x84, 0xD4, 0xFE,
+ 0x0A, 0x3A, 0x4D, 0x2F, 0xDB,
+ 0x0A, 0x57, 0x9A, 0xE3, 0xEE,
+ 0x0F, 0x59, 0x16, 0x0B, 0x6D,
+ 0x09, 0x08, 0x85, 0xE5, 0xEF,
+ 0x02, 0x75, 0x1E, 0x3A, 0x94,
+ 0x04, 0xE1, 0xF9, 0x6A, 0x87,
+ 0x00, 0x79, 0x42, 0x6F, 0x4B,
+ 0x01, 0x02, 0x25, 0x6A, 0x73,
+ 0x0C, 0xC4, 0xC2, 0x63, 0x4A,
+ 0x09, 0xE3, 0xE3, 0x10, 0x8C,
+ 0x0B, 0x2A, 0xD1, 0x7A, 0x54,
+ 0x09, 0x0A, 0xD3, 0xF6, 0x7B,
+ 0x04, 0x48, 0x6A, 0x94, 0xBF,
+ 0x09, 0x1A, 0x8F, 0xD1, 0x51,
+ 0x07, 0x32, 0x04, 0xD1, 0xB5,
+ 0x0A, 0xFC, 0x16, 0xBE, 0xAC,
+ 0x09, 0x2B, 0xDB, 0xB8, 0x26,
+ 0x05, 0x3D, 0x65, 0x12, 0x2B,
+ 0x0E, 0xF7, 0xAD, 0x0E, 0xC3,
+ 0x04, 0x02, 0x1C, 0x17, 0x32,
+ 0x05, 0x4E, 0x31, 0xE7, 0xFF,
+ 0x06, 0x90, 0x26, 0xD5, 0xF7,
+ 0x0F, 0xC1, 0xE2, 0x18, 0x4E,
+ 0x09, 0x86, 0xF1, 0x9C, 0x83,
+ 0x05, 0xA7, 0xEE, 0x92, 0xDF,
+ 0x0B, 0x1B, 0xB0, 0x14, 0xCA,
+ 0x0C, 0xB9, 0x20, 0xC5, 0xD9,
+ 0x0D, 0x8F, 0x50, 0x8D, 0x2D,
+ 0x03, 0xAD, 0x6C, 0xD4, 0x0A,
+ 0x0B, 0x97, 0xF0, 0x39, 0xE5,
+ 0x06, 0xDA, 0x24, 0x33, 0xB7,
+ 0x01, 0x9B, 0x7D, 0xE1, 0xFB,
+ 0x0B, 0xBF, 0x8E, 0x64, 0x17,
+ 0x06, 0x22, 0x13, 0x9B, 0x15,
+ 0x0F, 0x8C, 0x4B, 0x89, 0x8C,
+ 0x0C, 0x40, 0x10, 0x9C, 0xAE,
+ 0x06, 0x68, 0x65, 0x14, 0x2B,
+ 0x03, 0xD9, 0x25, 0xFF, 0x28,
+ 0x0A, 0x60, 0x31, 0xD4, 0x51,
+ 0x03, 0x44, 0xEE, 0xB2, 0xF6,
+ 0x03, 0x74, 0x1E, 0xDB, 0x8A,
+ 0x06, 0xFA, 0xA8, 0x14, 0x94,
+ 0x06, 0xE0, 0xF3, 0xA4, 0xF5,
+ 0x0F, 0xC9, 0x81, 0x8B, 0xDB,
+ 0x04, 0x3B, 0xC3, 0xF0, 0x4B,
+ 0x07, 0xDE, 0xF1, 0x26, 0x3E,
+ 0x0B, 0x9E, 0xD6, 0x2A, 0x7E,
+ 0x03, 0x57, 0x93, 0x11, 0x00,
+ 0x0F, 0xE0, 0xDF, 0xD6, 0x1B,
+ 0x03, 0x72, 0x28, 0x58, 0xDB,
+ 0x09, 0xC9, 0x47, 0x4E, 0x49,
+ 0x0C, 0x62, 0x48, 0xD2, 0xCC,
+ 0x07, 0x1A, 0x9F, 0xDE, 0x0D,
+ 0x04, 0x35, 0x37, 0x60, 0x82,
+ 0x05, 0x50, 0x29, 0x52, 0xD9,
+ 0x0B, 0x65, 0x1C, 0x67, 0x6D,
+ 0x0C, 0xCF, 0xF7, 0xB6, 0x5A,
+ 0x0B, 0x8F, 0xC6, 0x9E, 0xCB,
+ 0x09, 0x90, 0x4A, 0x7A, 0x0B,
+ 0x05, 0xEE, 0x01, 0x02, 0xF3,
+ 0x02, 0x21, 0xD8, 0x41, 0x3D,
+ 0x0E, 0x77, 0x4C, 0x77, 0x90,
+ 0x08, 0x50, 0xED, 0x7F, 0x53,
+ 0x0A, 0xFC, 0xA1, 0x59, 0xB8,
+ 0x0A, 0x51, 0xE9, 0x3D, 0x2F,
+ 0x06, 0xCB, 0xAC, 0x3D, 0xCD,
+ 0x07, 0x4E, 0xC1, 0x6B, 0xD9,
+ 0x0B, 0xD1, 0x47, 0x3B, 0x75,
+ 0x02, 0x93, 0x9A, 0x51, 0x15,
+ 0x00, 0x28, 0x96, 0x90, 0xD9,
+ 0x03, 0xF8, 0x6E, 0x31, 0x4B,
+ 0x0C, 0x95, 0xED, 0x1E, 0x45,
+ 0x03, 0x2B, 0x78, 0x6D, 0x5C,
+ 0x00, 0x45, 0x62, 0x11, 0xB6,
+ 0x09, 0x5B, 0x8F, 0x4D, 0xFB,
+ 0x0D, 0x5A, 0xFE, 0xC9, 0x1A,
+ 0x02, 0xB7, 0xBB, 0x8C, 0xB5,
+ 0x0F, 0x48, 0x1A, 0x2C, 0x47,
+ 0x0A, 0x70, 0xC1, 0x20, 0xE5,
+ 0x0D, 0x82, 0xD7, 0xD9, 0xC4,
+ 0x0E, 0xFB, 0x22, 0x8F, 0x58,
+ 0x0B, 0xAE, 0xEF, 0x43, 0x01,
+ 0x05, 0x5B, 0x1F, 0x5E, 0x1F,
+ 0x0C, 0x7A, 0x82, 0xE6, 0x73,
+ 0x05, 0xD9, 0x5C, 0xF9, 0x82,
+ 0x09, 0xBA, 0x52, 0x38, 0x98,
+ 0x04, 0x07, 0x43, 0x09, 0xF8,
+ 0x0C, 0xD6, 0xE1, 0x51, 0x71,
+ 0x04, 0xFD, 0x92, 0x57, 0x76,
+ 0x01, 0xE4, 0x56, 0x95, 0x83,
+ 0x0B, 0xF5, 0x38, 0xEB, 0x1D,
+ 0x0D, 0xF5, 0x21, 0xAD, 0x89,
+ 0x09, 0xAC, 0xCA, 0x81, 0x79,
+ 0x0E, 0xEE, 0x4A, 0x3A, 0x7B,
+ 0x01, 0x44, 0x26, 0x70, 0x88,
+ 0x0F, 0x43, 0x5C, 0x3F, 0xD6,
+ 0x0B, 0xC5, 0xF5, 0xC2, 0x6B,
+ 0x0F, 0xFA, 0xBD, 0xE2, 0xA4,
+ 0x0D, 0xB5, 0x61, 0x31, 0x2A,
+ 0x04, 0x47, 0x73, 0x95, 0x53,
+ 0x01, 0x35, 0x42, 0x85, 0x5A,
+ 0x00, 0xA5, 0x74, 0xE4, 0xD4,
+ 0x04, 0x06, 0x32, 0x83, 0x58,
+ 0x04, 0xB1, 0x9B, 0x59, 0xD7,
+ 0x02, 0x84, 0xA1, 0x36, 0x3D,
+ 0x03, 0x55, 0x51, 0x55, 0xDD,
+ 0x00, 0x0F, 0x74, 0x9E, 0x83,
+ 0x02, 0x8E, 0x85, 0x7B, 0x66,
+ 0x0B, 0x7A, 0x1F, 0xC1, 0xDD,
+ 0x07, 0x9A, 0x64, 0xA7, 0x5B,
+ 0x03, 0xE6, 0xC5, 0x44, 0x27,
+ 0x01, 0x61, 0x1F, 0xAC, 0x95,
+ 0x00, 0x25, 0xCA, 0xC3, 0x4F,
+ 0x02, 0x41, 0xEA, 0xD3, 0xC0,
+ 0x05, 0x6F, 0x89, 0xA9, 0xAF,
+ 0x00, 0x65, 0x7C, 0x1F, 0xE9,
+ 0x0F, 0xAC, 0xB4, 0x47, 0xE4,
+ 0x0A, 0xB6, 0xBC, 0x16, 0x84,
+ 0x06, 0x04, 0x0B, 0xCB, 0x83,
+ 0x07, 0x6A, 0xB8, 0x79, 0x26,
+ 0x05, 0xC2, 0x76, 0xCD, 0x39,
+ 0x0C, 0xCF, 0x83, 0xDF, 0x25,
+ 0x0E, 0x0B, 0xAE, 0xD1, 0xE3,
+ 0x01, 0x89, 0xB1, 0xC6, 0xD0,
+ 0x0F, 0x45, 0x9C, 0x21, 0x18,
+ 0x02, 0x55, 0x86, 0xB4, 0xD2,
+ 0x06, 0x15, 0xA7, 0xAC, 0xAA,
+ 0x03, 0x91, 0xB3, 0x30, 0x21,
+ 0x06, 0x34, 0xBB, 0xA2, 0xFD,
+ 0x05, 0x67, 0x8F, 0xBA, 0x36,
+ 0x05, 0xD8, 0xAD, 0x7D, 0x54,
+ 0x01, 0xD6, 0x71, 0xF0, 0x39,
+ 0x02, 0x7A, 0xEA, 0x2A, 0x77,
+ 0x0E, 0x6F, 0xA3, 0x1E, 0xE4,
+ 0x03, 0x05, 0xDE, 0x2E, 0x56,
+ 0x0E, 0x9A, 0x59, 0x8F, 0xA8,
+ 0x05, 0x23, 0x8D, 0xA7, 0x0D,
+ 0x03, 0x02, 0x17, 0xBC, 0x59,
+ 0x07, 0x0A, 0x13, 0xF9, 0x10,
+ 0x07, 0x47, 0xE3, 0xA5, 0xBA,
+ 0x0A, 0xA6, 0x40, 0x71, 0xAC,
+ 0x00, 0xE7, 0xA5, 0x83, 0x72,
+ 0x04, 0x9C, 0xA5, 0x9A, 0xDB,
+ 0x00, 0x5A, 0xFA, 0x88, 0x14,
+ 0x0F, 0x2E, 0xE4, 0x53, 0xA4,
+ 0x07, 0xD4, 0x44, 0x57, 0x8B,
+ 0x09, 0x34, 0x3B, 0xC3, 0x7E,
+ 0x0F, 0x7C, 0xDC, 0xC8, 0x25,
+ 0x0B, 0x46, 0x1F, 0x36, 0x2A,
+ 0x0B, 0x19, 0xB7, 0x13, 0x23,
+ 0x0C, 0x8C, 0x5B, 0xB9, 0x65,
+ 0x0B, 0xD3, 0x72, 0x3E, 0x54,
+ 0x0F, 0xB2, 0x4B, 0x72, 0xC9,
+ 0x07, 0x42, 0x36, 0xA4, 0x17,
+ 0x02, 0x8B, 0x3D, 0xA5, 0xA6,
+ 0x05, 0x6B, 0xEE, 0x37, 0x60,
+ 0x09, 0xF2, 0xAA, 0x69, 0x6B,
+ 0x01, 0xC5, 0x47, 0x49, 0xDD,
+ 0x04, 0x90, 0x8E, 0x57, 0x81,
+ 0x04, 0x77, 0xDE, 0xBC, 0x26,
+ 0x04, 0xB9, 0x95, 0xCA, 0x4F,
+ 0x04, 0xBC, 0xA3, 0x54, 0x8E,
+ 0x0A, 0xAE, 0x07, 0x62, 0x1C,
+ 0x04, 0xC2, 0xFC, 0x2C, 0x3E,
+ 0x06, 0xE4, 0x52, 0xA1, 0x0B,
+ 0x0D, 0x94, 0xF8, 0x9A, 0x59,
+ 0x0A, 0xC7, 0x61, 0xA5, 0xED,
+ 0x06, 0x3A, 0xCB, 0x3C, 0x49,
+ 0x00, 0x6B, 0x6E, 0xCD, 0x59,
+ 0x02, 0x21, 0xF1, 0xBE, 0x3B,
+ 0x08, 0xCC, 0xB4, 0xD7, 0x91,
+ 0x0B, 0x9D, 0x1D, 0xEC, 0xD4,
+ 0x0F, 0x0F, 0xF8, 0x3D, 0xC3,
+ 0x03, 0x20, 0x94, 0x6B, 0x14,
+ 0x0C, 0xD8, 0xAB, 0x1A, 0x27,
+ 0x00, 0x4E, 0xA4, 0x02, 0x24,
+ 0x08, 0xE0, 0x78, 0x6F, 0x7B,
+ 0x04, 0xA1, 0x1A, 0x7E, 0xFE,
+ 0x01, 0xF9, 0x5F, 0xB3, 0x39,
+ 0x00, 0xA3, 0x42, 0xFA, 0x15,
+ 0x09, 0x96, 0x68, 0xFB, 0x9A,
+ 0x0A, 0xDD, 0x62, 0xD7, 0xEE,
+ 0x0B, 0x26, 0xFC, 0x77, 0x03,
+ 0x01, 0x25, 0xCE, 0xA2, 0x76,
+ 0x04, 0x5E, 0x99, 0xA1, 0xE9,
+ 0x03, 0xF0, 0x09, 0x22, 0xDE,
+ 0x0D, 0x29, 0xD0, 0xBC, 0xC0,
+ 0x0D, 0x53, 0x18, 0xDA, 0x82,
+ 0x04, 0x88, 0x54, 0x23, 0x32,
+ 0x01, 0x33, 0x5B, 0x97, 0x25,
+ 0x0E, 0xB4, 0x7D, 0x92, 0x6C,
+ 0x0E, 0x5A, 0x66, 0x03, 0x2B,
+ 0x0A, 0x95, 0x14, 0x58, 0xEF,
+ 0x00, 0xF2, 0xD7, 0x41, 0xA8,
+ 0x00, 0x84, 0x73, 0xAA, 0x81,
+ 0x06, 0xF0, 0x8E, 0x07, 0x3E,
+ 0x03, 0x5F, 0xE4, 0x86, 0x75,
+ 0x06, 0x32, 0x9F, 0xBC, 0x3F,
+ 0x0C, 0xF7, 0xC5, 0x8C, 0x8C,
+ 0x0F, 0xB4, 0x79, 0xB3, 0x5A,
+ 0x08, 0x73, 0x55, 0x71, 0x08,
+ 0x0C, 0x08, 0x42, 0x13, 0xAF,
+ 0x0D, 0xBD, 0x37, 0x22, 0xBE,
+ 0x01, 0xFB, 0xA4, 0xB7, 0xE4,
+ 0x0F, 0x4D, 0xE0, 0xB2, 0x8D,
+ 0x0F, 0xE8, 0xB1, 0xD8, 0x1D,
+ 0x08, 0x6C, 0xBA, 0x58, 0x73,
+ 0x07, 0x5D, 0x35, 0x02, 0xAC,
+ 0x0D, 0xDC, 0x8E, 0x74, 0x9E,
+ 0x01, 0x08, 0xEA, 0x61, 0x7B,
+ 0x06, 0x87, 0x78, 0x71, 0x85,
+ 0x04, 0x09, 0xA0, 0x07, 0xA2,
+ 0x04, 0xF1, 0x86, 0xC5, 0x7D,
+ 0x0F, 0x69, 0x82, 0x62, 0x16,
+ 0x0C, 0x8C, 0x1E, 0x6A, 0xFB,
+ 0x06, 0x6E, 0x08, 0x0A, 0xEA,
+ 0x0D, 0xCA, 0xDE, 0xC9, 0xA9,
+ 0x04, 0x0D, 0x05, 0x1A, 0x6B,
+ 0x0D, 0x63, 0x3D, 0xB3, 0xFF,
+ 0x04, 0x96, 0x56, 0xE1, 0xD6,
+ 0x0E, 0xAA, 0x05, 0x26, 0xCF,
+ 0x03, 0x9F, 0x38, 0xB0, 0x30,
+ 0x0E, 0x19, 0x53, 0x76, 0xF5,
+ 0x07, 0x60, 0x1F, 0x8E, 0x1F,
+ 0x0C, 0xB1, 0xD8, 0xCE, 0xD1,
+ 0x0B, 0xCC, 0xEA, 0x91, 0xF4,
+ 0x09, 0xC3, 0x3E, 0x00, 0x12,
+ 0x08, 0x4E, 0x55, 0x8A, 0x70,
+ 0x07, 0x08, 0x40, 0x2B, 0x29,
+ 0x0E, 0xDE, 0x73, 0x53, 0x02,
+ 0x04, 0xC2, 0x0E, 0x3F, 0x91,
+ 0x07, 0x59, 0x67, 0x83, 0x3E,
+ 0x06, 0xEF, 0x8D, 0xA1, 0xB8,
+ 0x08, 0x0A, 0xC7, 0xD7, 0x6D,
+ 0x05, 0xD2, 0xF7, 0x2A, 0x2D,
+ 0x0B, 0x05, 0x4F, 0x9A, 0xDD,
+ 0x09, 0x76, 0xA7, 0xBE, 0xEE,
+ 0x0C, 0x02, 0x1E, 0x21, 0x4F,
+ 0x03, 0x1C, 0xA3, 0x8F, 0x2B,
+ 0x01, 0x99, 0x02, 0x40, 0xB0,
+ 0x00, 0xAC, 0xF7, 0xA9, 0x8C,
+ 0x08, 0x2E, 0xAF, 0x99, 0x13,
+ 0x03, 0x26, 0xE6, 0x20, 0x06,
+ 0x08, 0x69, 0x44, 0x85, 0xB6,
+ 0x0E, 0xCF, 0x53, 0xB4, 0x23,
+ 0x0B, 0xB0, 0x5A, 0xFC, 0x9B,
+ 0x0F, 0x2C, 0xD5, 0x66, 0x07,
+ 0x08, 0xF5, 0x99, 0x48, 0x53,
+ 0x07, 0xD3, 0x0E, 0xBB, 0xF5,
+ 0x02, 0x0F, 0x2F, 0x9C, 0xF0,
+ 0x09, 0x3A, 0x47, 0x9F, 0x0F,
+ 0x01, 0xC5, 0x7F, 0x57, 0x13,
+ 0x0D, 0x01, 0xE4, 0x61, 0x0B,
+ 0x0A, 0x18, 0x33, 0x72, 0x1B,
+ 0x0A, 0x9F, 0x32, 0x4B, 0x49,
+ 0x01, 0x4C, 0x8D, 0x63, 0x11,
+ 0x09, 0x7C, 0x03, 0x9D, 0x65,
+ 0x02, 0x3E, 0xD3, 0xF5, 0x8F,
+ 0x0C, 0xB5, 0xB8, 0x50, 0x10,
+ 0x05, 0xDF, 0x08, 0x67, 0x49,
+ 0x07, 0xA9, 0xF0, 0xCE, 0x25,
+ 0x0A, 0x6B, 0x97, 0x87, 0xCF,
+ 0x05, 0x7A, 0x31, 0x10, 0x4A,
+ 0x0A, 0x8F, 0x73, 0x6C, 0x6D,
+ 0x05, 0xB4, 0x10, 0xA6, 0x22,
+ 0x0D, 0x0A, 0xA2, 0x72, 0x9F,
+ 0x0C, 0x24, 0x6C, 0xD0, 0xAD,
+ 0x03, 0x66, 0xF6, 0xFC, 0xA8,
+ 0x05, 0x88, 0xBC, 0x91, 0x96,
+ 0x0D, 0x16, 0x3A, 0xC7, 0xB8,
+ 0x06, 0x52, 0x3E, 0xE2, 0x04,
+ 0x07, 0xE9, 0xC0, 0x52, 0x88,
+ 0x07, 0x82, 0x2E, 0x93, 0xE2,
+ 0x0D, 0x21, 0xBC, 0x6F, 0x54,
+ 0x09, 0x7F, 0xEF, 0xF5, 0xFD,
+ 0x01, 0x73, 0x20, 0x99, 0xE9,
+ 0x05, 0xFF, 0x09, 0x24, 0x59,
+ 0x01, 0x58, 0x2C, 0x44, 0x30,
+ 0x0D, 0x83, 0x1F, 0x18, 0x5C,
+ 0x0D, 0xC8, 0xA1, 0x56, 0xFA,
+ 0x02, 0xAF, 0xAC, 0xB9, 0xF6,
+ 0x0D, 0x8E, 0x43, 0x4B, 0xC8,
+ 0x00, 0x7D, 0xAC, 0xF8, 0xC8,
+ 0x00, 0xD6, 0xDD, 0x8E, 0x53,
+ 0x0E, 0xC2, 0xF0, 0xF5, 0xB2,
+ 0x0F, 0x95, 0x1D, 0x2E, 0x90,
+ 0x0F, 0x30, 0x24, 0x19, 0x92,
+ 0x02, 0x1F, 0xD0, 0xFB, 0xDA,
+ 0x06, 0x41, 0x29, 0xD6, 0xB9,
+ 0x02, 0x32, 0xBC, 0x34, 0x1E,
+ 0x04, 0x98, 0x05, 0x84, 0x2A,
+ 0x09, 0xCA, 0xB2, 0xDE, 0x9B,
+ 0x01, 0x42, 0xB4, 0x7D, 0x92,
+ 0x03, 0xFA, 0xE8, 0x64, 0x83,
+ 0x01, 0x4F, 0x17, 0xF6, 0xD8,
+ 0x07, 0x2B, 0x0B, 0xB7, 0x72,
+ 0x01, 0xBD, 0x7D, 0x6F, 0x9E,
+ 0x0D, 0x4A, 0xFE, 0xEE, 0x32,
+ 0x06, 0x4F, 0x1D, 0x04, 0xB1,
+ 0x0C, 0xBD, 0xF4, 0x83, 0x84,
+ 0x04, 0x64, 0x81, 0xC3, 0xF5,
+ 0x0E, 0x51, 0xB4, 0x79, 0xC2,
+ 0x0E, 0xAC, 0x4B, 0x35, 0x43,
+ 0x0D, 0x10, 0x45, 0x46, 0x27,
+ 0x09, 0x66, 0x84, 0xB7, 0x17,
+ 0x09, 0x69, 0xD9, 0x24, 0x8F,
+ 0x08, 0xD4, 0x41, 0x86, 0x3B,
+ 0x0D, 0x2F, 0xEA, 0xB1, 0xD6,
+ 0x09, 0xE3, 0xEE, 0x03, 0x5B,
+ 0x06, 0x0B, 0x5D, 0x57, 0xB5,
+ 0x0E, 0x61, 0x10, 0x0C, 0xCD,
+ 0x02, 0xBA, 0xC4, 0x0C, 0xD5,
+ 0x07, 0x6E, 0xBD, 0xF8, 0x49,
+ 0x0D, 0xEF, 0xCB, 0xD9, 0x33,
+ 0x0B, 0x68, 0xA0, 0x26, 0xFD,
+ 0x03, 0x61, 0x0E, 0xEE, 0x21,
+ 0x0C, 0x12, 0x6C, 0x27, 0x1B,
+ 0x0F, 0x7D, 0x57, 0xC5, 0x3F,
+ 0x0F, 0xF2, 0x29, 0x6F, 0xFF,
+ 0x02, 0x1D, 0x0B, 0x65, 0x1A,
+ 0x03, 0xD1, 0xED, 0xEC, 0x84,
+ 0x0B, 0xDD, 0x59, 0x76, 0xD4,
+ 0x0D, 0x3D, 0x98, 0x05, 0x2B,
+ 0x07, 0xBC, 0x7C, 0xE9, 0x0B,
+ 0x09, 0x15, 0xE3, 0x82, 0xC5,
+ 0x01, 0x0E, 0x70, 0xFF, 0xB4,
+ 0x0F, 0x17, 0x32, 0x04, 0xCA,
+ 0x0A, 0x65, 0x98, 0x06, 0x54,
+ 0x0A, 0xD2, 0xFD, 0x44, 0x74,
+ 0x0D, 0x1F, 0x37, 0x95, 0xB3,
+ 0x08, 0xD4, 0xB0, 0x95, 0x91,
+ 0x00, 0x92, 0x9F, 0xD3, 0x64,
+ 0x0C, 0x18, 0xFD, 0xB4, 0x87,
+ 0x09, 0x42, 0x4F, 0x67, 0x8F,
+ 0x06, 0x0D, 0xE0, 0x58, 0x24,
+ 0x0D, 0x54, 0x08, 0x57, 0xE6,
+ 0x08, 0x31, 0x52, 0x74, 0xAA,
+ 0x0C, 0x3A, 0x07, 0xEF, 0x1A,
+ 0x01, 0xE1, 0xB2, 0x07, 0x8C,
+ 0x02, 0x63, 0xE8, 0xDD, 0x90,
+ 0x03, 0x9F, 0x75, 0x23, 0xBB,
+ 0x07, 0x89, 0x98, 0x80, 0x75,
+ 0x0C, 0x9C, 0x89, 0x0D, 0xD1,
+ 0x02, 0x91, 0x07, 0xC9, 0xE0,
+ 0x09, 0xBF, 0x36, 0xA6, 0x5A,
+ 0x0D, 0x97, 0x09, 0x7F, 0x77,
+ 0x02, 0xB6, 0xAF, 0x1F, 0x47,
+ 0x01, 0x5A, 0x73, 0x5A, 0xFA,
+ 0x02, 0x15, 0x38, 0x2E, 0xE1,
+ 0x03, 0xA4, 0xF7, 0xD4, 0x48,
+ 0x07, 0x0B, 0xD9, 0x34, 0x31,
+ 0x08, 0x7F, 0xCC, 0x7C, 0x5C,
+ 0x04, 0x25, 0x2B, 0x47, 0xAD,
+ 0x0D, 0xAB, 0x84, 0x17, 0xE4,
+ 0x0F, 0x01, 0x00, 0x84, 0x67,
+ 0x05, 0x56, 0x9B, 0xD3, 0x45,
+ 0x04, 0x66, 0x9F, 0xB2, 0x79,
+ 0x02, 0x4D, 0x5C, 0xC0, 0x67,
+ 0x04, 0xD2, 0xAE, 0x8B, 0x18,
+ 0x0E, 0x1F, 0xE2, 0xE8, 0x35,
+ 0x0B, 0x60, 0xB5, 0xB5, 0x5E,
+ 0x05, 0x5E, 0x5D, 0x80, 0xDF,
+ 0x05, 0xEB, 0xB8, 0x90, 0xF7,
+ 0x0B, 0xB6, 0x6C, 0x77, 0xBD,
+ 0x00, 0x1E, 0xF8, 0xB9, 0xAB,
+ 0x02, 0x76, 0x0F, 0x3E, 0x6C,
+ 0x0F, 0x0F, 0xD0, 0x2E, 0x26,
+ 0x02, 0x01, 0x08, 0xCC, 0x36,
+ 0x07, 0xB5, 0x9F, 0xE7, 0x55,
+ 0x01, 0x3E, 0xE4, 0x16, 0xE1,
+ 0x02, 0x99, 0x00, 0xCA, 0x51,
+ 0x0D, 0xF3, 0x96, 0x3A, 0x0B,
+ 0x00, 0x7C, 0x67, 0xAB, 0x56,
+ 0x0A, 0xED, 0xFE, 0x24, 0x69,
+ 0x00, 0xBB, 0x01, 0xCE, 0xA4,
+ 0x0B, 0x61, 0x21, 0x9C, 0x1D,
+ 0x00, 0xD8, 0x2F, 0x0F, 0xFC,
+ 0x01, 0xF8, 0x73, 0x20, 0x91,
+ 0x06, 0x9F, 0xA0, 0xD8, 0xA9,
+ 0x00, 0x67, 0x4C, 0x4C, 0x40,
+ 0x0E, 0x1B, 0xD4, 0xE5, 0x5D,
+ 0x04, 0xCC, 0x14, 0xA1, 0x5A,
+ 0x02, 0xC9, 0x2D, 0xB9, 0x3B,
+ 0x0F, 0x01, 0x8C, 0xE3, 0x73,
+ 0x06, 0x24, 0xB5, 0x96, 0x41,
+ 0x07, 0xA0, 0xD2, 0xDD, 0xB8,
+ 0x0B, 0xD5, 0x40, 0xA5, 0x42,
+ 0x0F, 0x03, 0x1D, 0x27, 0xAE,
+ 0x09, 0xC2, 0xDE, 0xDE, 0xD9,
+ 0x0D, 0xD4, 0x0F, 0xF0, 0x42,
+ 0x0A, 0xE6, 0xC1, 0x29, 0xDA,
+ 0x07, 0x78, 0x57, 0xD2, 0x38,
+ 0x06, 0xB9, 0x18, 0x08, 0x19,
+ 0x0B, 0x09, 0x4A, 0xBC, 0xDE,
+ 0x03, 0xB7, 0xC2, 0xB4, 0x3D,
+ 0x0E, 0x5A, 0x32, 0xEA, 0x5E,
+ 0x08, 0x9F, 0x52, 0x13, 0xCF,
+ 0x04, 0xEA, 0xAC, 0xF1, 0xEA,
+ 0x0D, 0xAD, 0xAB, 0x05, 0x9B,
+ 0x06, 0x8B, 0x5A, 0xF2, 0xDB,
+ 0x0B, 0x3B, 0x2F, 0x5D, 0x72,
+ 0x0A, 0x70, 0x3D, 0xB3, 0x74,
+ 0x00, 0x3E, 0x29, 0xB7, 0xFD,
+ 0x00, 0x82, 0xBB, 0xB4, 0x40,
+ 0x08, 0xE4, 0x64, 0x71, 0x4E,
+ 0x0D, 0x31, 0x00, 0x08, 0x42,
+ 0x08, 0x17, 0x58, 0xBE, 0x32,
+ 0x0E, 0x85, 0x69, 0xBB, 0x2A,
+ 0x0B, 0xE4, 0x54, 0xCC, 0x31,
+ 0x0E, 0x8D, 0x2F, 0xA8, 0x89,
+ 0x0A, 0x59, 0xF3, 0xEE, 0xBA,
+ 0x07, 0x76, 0x0F, 0x5F, 0x6F,
+ 0x0E, 0x95, 0xE5, 0xDC, 0x35,
+ 0x0C, 0x9E, 0x3A, 0x85, 0x0C,
+ 0x0A, 0xFA, 0x80, 0x07, 0x78,
+ 0x03, 0xC9, 0x2F, 0x8B, 0xA0,
+ 0x0C, 0xA7, 0xE8, 0xFF, 0xE6,
+ 0x0E, 0xC9, 0x05, 0xEA, 0xE2,
+ 0x0E, 0x2A, 0x00, 0x8C, 0x1E,
+ 0x02, 0xC3, 0xFA, 0x62, 0x45,
+ 0x01, 0x52, 0x10, 0xC9, 0x6F,
+ 0x05, 0xA9, 0x18, 0x0C, 0x52,
+ 0x06, 0x5F, 0xC1, 0x63, 0xA8,
+ 0x0F, 0xC7, 0x8D, 0x06, 0xB3,
+ 0x07, 0x97, 0x62, 0xAA, 0x37,
+ 0x07, 0xC3, 0x78, 0x1C, 0xED,
+ 0x01, 0x7C, 0x12, 0x19, 0xC7,
+ 0x0D, 0x4C, 0xD2, 0xF0, 0xCD,
+ 0x0F, 0xD5, 0x07, 0x32, 0x0D,
+ 0x02, 0xDB, 0xB7, 0xCD, 0x8F,
+ 0x0A, 0x47, 0x09, 0xC4, 0xF6,
+ 0x0C, 0x21, 0x18, 0x4E, 0x6A,
+ 0x09, 0x74, 0xDC, 0x8A, 0x15,
+ 0x0B, 0xFC, 0x92, 0xDF, 0x95,
+ 0x0F, 0x30, 0x18, 0xCA, 0x33,
+ 0x03, 0xA2, 0x57, 0x59, 0x63,
+ 0x03, 0xBA, 0x9D, 0x2D, 0xDD,
+ 0x06, 0xFC, 0x9A, 0x8A, 0x57,
+ 0x0B, 0x79, 0x79, 0xD2, 0x7E,
+ 0x06, 0x25, 0xD3, 0xC5, 0xE8,
+ 0x01, 0x9C, 0x2F, 0x7F, 0x07,
+ 0x02, 0x24, 0xF4, 0x12, 0x99,
+ 0x0F, 0xCD, 0x7B, 0x55, 0x26,
+ 0x06, 0x2A, 0x47, 0x08, 0x80,
+ 0x0E, 0x31, 0x1C, 0x2B, 0x10,
+ 0x01, 0xB9, 0x94, 0x27, 0x4F,
+ 0x01, 0x23, 0x3F, 0x26, 0x66,
+ 0x0A, 0x30, 0x56, 0x69, 0x5F,
+ 0x05, 0x8E, 0xB0, 0xCF, 0x1B,
+ 0x0C, 0x52, 0x58, 0x3C, 0x5A,
+ 0x02, 0xAE, 0x96, 0xAD, 0xAE,
+ 0x0A, 0x72, 0x66, 0xF5, 0x94,
+ 0x04, 0x67, 0x0B, 0xDB, 0x32,
+ 0x01, 0x03, 0x5E, 0x8C, 0x02,
+ 0x0C, 0xC8, 0x25, 0x2B, 0x45,
+ 0x03, 0x36, 0xFA, 0x47, 0x1F,
+ 0x0D, 0xD3, 0xB1, 0x83, 0x05,
+ 0x01, 0x39, 0x56, 0x0B, 0xD1,
+ 0x02, 0x28, 0x54, 0x9F, 0xB2,
+ 0x0B, 0x7E, 0x4F, 0x40, 0xCA,
+ 0x0F, 0x28, 0xD2, 0xFE, 0xB5,
+ 0x02, 0xE5, 0x9E, 0x3E, 0xE8,
+ 0x05, 0xB7, 0x60, 0xB9, 0x71,
+ 0x00, 0x29, 0x5E, 0x51, 0x05,
+ 0x0D, 0xA9, 0xF6, 0xAB, 0x0A,
+ 0x0E, 0x17, 0xB6, 0x78, 0x77,
+ 0x07, 0xFC, 0x1E, 0xE8, 0xB9,
+ 0x00, 0x4A, 0x76, 0x9F, 0x8F,
+ 0x0C, 0x54, 0x8E, 0x26, 0x1C,
+ 0x06, 0x22, 0x01, 0x18, 0x71,
+ 0x02, 0xAC, 0x37, 0xB6, 0x50,
+ 0x00, 0xAD, 0x3F, 0x74, 0x23,
+ 0x0C, 0x9A, 0x99, 0xA0, 0x70,
+ 0x01, 0xA5, 0xFD, 0x16, 0x8D,
+ 0x0B, 0x3C, 0x7D, 0xD0, 0xD3,
+ 0x0E, 0xC1, 0x6B, 0xF6, 0xE2,
+ 0x02, 0xBC, 0xBB, 0x9D, 0x4C,
+ 0x03, 0xD7, 0x51, 0x3D, 0x5E,
+ 0x0F, 0x6C, 0xD0, 0xF2, 0x0D,
+ 0x08, 0x3D, 0xF1, 0x6E, 0x62,
+ 0x04, 0xED, 0x1E, 0x61, 0x5A,
+ 0x09, 0x1C, 0x6D, 0x41, 0x8E,
+ 0x04, 0x02, 0x11, 0xAA, 0xE7,
+ 0x06, 0xEF, 0x80, 0xC8, 0xA1,
+ 0x01, 0x7E, 0xC9, 0x2D, 0xF9,
+ 0x09, 0x0C, 0x81, 0x8C, 0xB0,
+ 0x07, 0xFA, 0x6C, 0x75, 0x82,
+ 0x02, 0x3B, 0x80, 0xD5, 0x6B,
+ 0x02, 0xD7, 0xD5, 0x50, 0xA5,
+ 0x09, 0x77, 0x03, 0x8D, 0x27,
+ 0x06, 0xA2, 0xC3, 0x28, 0xDE,
+ 0x01, 0x21, 0x7E, 0x5F, 0x70,
+ 0x02, 0xE2, 0x26, 0x71, 0xA9,
+ 0x03, 0xBC, 0x19, 0x81, 0xD2,
+ 0x01, 0x5B, 0x58, 0xA8, 0x08,
+ 0x0D, 0x22, 0xC9, 0x9A, 0x30,
+ 0x06, 0x1A, 0x31, 0x52, 0x34,
+ 0x05, 0x93, 0xDB, 0xE2, 0xEA,
+ 0x06, 0x03, 0x19, 0x56, 0x26,
+ 0x04, 0x58, 0xEB, 0x7C, 0x43,
+ 0x07, 0x41, 0xAD, 0x8B, 0xB6,
+ 0x0F, 0xAA, 0x81, 0x7A, 0x46,
+ 0x0E, 0x07, 0x3A, 0x7F, 0x5D,
+ 0x04, 0x86, 0x70, 0xA1, 0xF1,
+ 0x03, 0xBC, 0x3F, 0xFC, 0x75,
+ 0x05, 0xCC, 0x82, 0x4F, 0x76,
+ 0x09, 0xF3, 0x62, 0x89, 0x73,
+ 0x05, 0x71, 0x31, 0x04, 0x0A,
+ 0x06, 0x13, 0x95, 0x75, 0xFF,
+ 0x07, 0x22, 0x85, 0x7D, 0x79,
+ 0x04, 0xB7, 0xE4, 0xF0, 0x0E,
+ 0x0D, 0x32, 0x8D, 0x2F, 0xE8,
+ 0x0D, 0xD7, 0x66, 0x23, 0xED,
+ 0x0F, 0x5A, 0x76, 0x0B, 0x5C,
+ 0x0D, 0x02, 0x15, 0xE5, 0x9C,
+ 0x06, 0xF4, 0x3E, 0xBA, 0xC9,
+ 0x05, 0x61, 0x9B, 0x66, 0x87,
+ 0x04, 0x7F, 0xC1, 0xAF, 0x9A,
+ 0x05, 0x3B, 0x58, 0xA8, 0xE3,
+ 0x06, 0xC5, 0x48, 0xEF, 0xFC,
+ 0x0A, 0x61, 0x20, 0x34, 0x91,
+ 0x0F, 0xA8, 0x6B, 0x4E, 0x30,
+ 0x07, 0x0A, 0xDB, 0xD6, 0xC9,
+ 0x0D, 0xC9, 0xA9, 0xA8, 0x8C,
+ 0x04, 0x5A, 0x9F, 0xD1, 0x63,
+ 0x0D, 0xF3, 0x07, 0xDD, 0x06,
+ 0x0F, 0x6D, 0xF6, 0xB2, 0xAA,
+ 0x05, 0x2B, 0xCB, 0x9E, 0x9E,
+ 0x09, 0x3D, 0x75, 0x34, 0x9B,
+ 0x0C, 0x76, 0x00, 0x0E, 0xF0,
+ 0x06, 0x89, 0xBF, 0x1A, 0xF2,
+ 0x03, 0x4F, 0x0F, 0x67, 0xC9,
+ 0x01, 0x91, 0xC6, 0xD5, 0xC4,
+ 0x08, 0x40, 0x21, 0x98, 0x5E,
+ 0x09, 0x96, 0xF4, 0xDC, 0x86,
+ 0x09, 0xA6, 0x12, 0x52, 0xC2,
+ 0x0B, 0x53, 0xB0, 0x1C, 0xD5,
+ 0x0E, 0xBE, 0x48, 0xC7, 0x19,
+ 0x0B, 0x8F, 0xBA, 0x0D, 0x61,
+ 0x03, 0xAF, 0x7F, 0xD4, 0x0A,
+ 0x07, 0x97, 0x70, 0x37, 0xDF,
+ 0x03, 0x68, 0xC4, 0x33, 0x85,
+ 0x05, 0x90, 0x7D, 0xEC, 0x3F,
+ 0x0D, 0xBF, 0xD1, 0xE4, 0x1A,
+ 0x05, 0x23, 0x6F, 0x96, 0xD5,
+ 0x0B, 0x0F, 0x8B, 0x8C, 0x7A,
+ 0x09, 0xC3, 0xD0, 0x92, 0xEB,
+ 0x05, 0x68, 0x19, 0x1A, 0x6B,
+ 0x0F, 0xD9, 0x25, 0xBA, 0xE2,
+ 0x0A, 0x61, 0xCF, 0x54, 0x74,
+ 0x0F, 0x45, 0x8E, 0xB7, 0x8A,
+ 0x0F, 0x74, 0x1A, 0xFB, 0xB9,
+ 0x02, 0xF2, 0x28, 0x14, 0x2F,
+ 0x07, 0x6D, 0x93, 0x84, 0x75,
+ 0x0C, 0x41, 0xE7, 0x0B, 0x5B,
+ 0x0D, 0xB2, 0x23, 0xDE, 0x8F,
+ 0x04, 0xD4, 0x68, 0x25, 0xBB,
+ 0x0E, 0x97, 0xF6, 0x1A, 0xC7,
+ 0x03, 0xDD, 0x33, 0x21, 0x80,
+ 0x0D, 0x68, 0xFB, 0x76, 0x9B,
+ 0x03, 0x72, 0x28, 0x60, 0x95,
+ 0x0A, 0x4B, 0xEE, 0x7D, 0x8C,
+ 0x0A, 0x62, 0xDE, 0x52, 0xDE,
+ 0x0A, 0x18, 0xA5, 0x9E, 0x3E,
+ 0x09, 0xB0, 0x57, 0x60, 0xB5,
+ 0x0D, 0x50, 0xA1, 0x5C, 0xDD,
+ 0x02, 0xE7, 0x49, 0xED, 0x28,
+ 0x02, 0xCE, 0x17, 0x30, 0xA8,
+ 0x04, 0x86, 0x7C, 0x98, 0x72,
+ 0x0A, 0x11, 0xE2, 0x70, 0x45,
+ 0x0F, 0xED, 0xB7, 0x0E, 0x36,
+ 0x0F, 0x24, 0x6A, 0x81, 0x08,
+ 0x02, 0x72, 0xAC, 0x37, 0xA6,
+ 0x04, 0xD5, 0x06, 0xBF, 0x64,
+ 0x06, 0xFE, 0x98, 0x99, 0x80,
+ 0x06, 0xD0, 0x05, 0xFD, 0x16,
+ 0x0A, 0xCA, 0xBC, 0x6B, 0x52,
+ 0x0B, 0xEF, 0x61, 0x6D, 0x28,
+ 0x09, 0xD0, 0x48, 0x97, 0x01,
+ 0x0E, 0x93, 0xC7, 0x47, 0x23,
+ 0x0C, 0x2F, 0x6C, 0xF6, 0xAD,
+ 0x01, 0x78, 0xF0, 0xF1, 0x73,
+ 0x0A, 0x95, 0x06, 0x1E, 0x7D,
+ 0x04, 0xA8, 0xE2, 0xAD, 0x41,
+ 0x0C, 0x44, 0x02, 0x11, 0x84,
+ 0x0D, 0x58, 0xEF, 0x4D, 0x08,
+ 0x0B, 0x58, 0x7C, 0xC9, 0x0D,
+ 0x02, 0xB7, 0x31, 0x81, 0x8C,
+ 0x08, 0x4B, 0xFA, 0x2C, 0x75,
+ 0x0A, 0x78, 0xFB, 0x20, 0xE3,
+ 0x04, 0x82, 0x17, 0xD5, 0x40,
+ 0x0D, 0xF9, 0xD7, 0x03, 0x9D,
+ 0x0D, 0xAC, 0xA7, 0x43, 0x39,
+ 0x06, 0x58, 0x01, 0xD3, 0x5F,
+ 0x08, 0x69, 0xC2, 0xEB, 0x81,
+ 0x03, 0xD8, 0x28, 0x79, 0xB9,
+ 0x0A, 0x3A, 0xFA, 0xBD, 0x18,
+ 0x02, 0x06, 0x2E, 0x09, 0xC2,
+ 0x08, 0xDE, 0x1B, 0x9F, 0x02,
+ 0x0D, 0x34, 0x12, 0x5E, 0xB2,
+ 0x02, 0x2F, 0x83, 0x1C, 0xC6,
+ 0x07, 0xF4, 0x58, 0xEE, 0xE8,
+ 0x0A, 0x75, 0x72, 0x28, 0xBE,
+ 0x0D, 0xA7, 0x2A, 0x8C, 0x8A,
+ 0x0A, 0xEF, 0x87, 0x37, 0x0F,
+ 0x05, 0x45, 0x06, 0x7E, 0xFD,
+ 0x0A, 0x8A, 0x3C, 0x3A, 0xA0,
+ 0x0F, 0x8C, 0x4C, 0x87, 0xD3,
+ 0x04, 0x79, 0xF3, 0x67, 0x60,
+ 0x0A, 0x37, 0x42, 0xB4, 0x15,
+ 0x00, 0x46, 0x93, 0x9B, 0x21,
+ 0x04, 0xBE, 0xA2, 0x88, 0xA9,
+ 0x03, 0x25, 0x37, 0xE9, 0x94,
+ 0x05, 0xCF, 0xD2, 0x88, 0x6F,
+ 0x00, 0xF8, 0x56, 0x5C, 0x63,
+ 0x0E, 0x83, 0x5B, 0x73, 0xCF,
+ 0x04, 0xD7, 0x31, 0x10, 0xE0,
+ 0x05, 0x96, 0x94, 0x93, 0x7A,
+ 0x00, 0x0B, 0x81, 0x7E, 0xE6,
+ 0x0F, 0x7A, 0x3F, 0xC4, 0x2F,
+ 0x01, 0x9B, 0x17, 0x27, 0x60,
+ 0x0A, 0x6E, 0x25, 0x4D, 0x23,
+ 0x00, 0xE0, 0x73, 0x20, 0x11,
+ 0x02, 0xA7, 0xE7, 0xC3, 0x7A,
+ 0x04, 0x47, 0x0E, 0x53, 0xF7,
+ 0x09, 0x6F, 0xC9, 0xA7, 0xDC,
+ 0x00, 0x65, 0x1A, 0xDF, 0xE4,
+ 0x0A, 0xBC, 0x73, 0xCA, 0x1D,
+ 0x0E, 0x36, 0x4C, 0x16, 0xBE,
+ 0x0A, 0x05, 0x2B, 0xCF, 0x0E,
+ 0x04, 0xEB, 0x1D, 0x7B, 0x92,
+ 0x03, 0xC0, 0xC5, 0xCD, 0x06,
+ 0x09, 0xFF, 0x43, 0xDF, 0x17,
+ 0x0A, 0x0B, 0x0E, 0xDC, 0xA7,
+ 0x07, 0x88, 0xA1, 0x46, 0xDD,
+ 0x08, 0xC5, 0xBF, 0x21, 0x05,
+ 0x0E, 0x55, 0x86, 0xF9, 0x43,
+ 0x08, 0x15, 0xA7, 0xE9, 0x12,
+ 0x06, 0x13, 0xB3, 0x30, 0x18,
+ 0x0A, 0x4C, 0x3F, 0xAC, 0x10,
+ 0x09, 0x67, 0x8F, 0xBA, 0x0D,
+ 0x05, 0xF0, 0xAD, 0x78, 0x54,
+ 0x0A, 0x57, 0x97, 0x70, 0x39,
+ 0x02, 0x7A, 0xEA, 0x21, 0x3E,
+ 0x0D, 0xA7, 0xFA, 0x10, 0x61,
+ 0x05, 0x05, 0x91, 0xAE, 0x6C,
+ 0x0E, 0x9C, 0x5C, 0xCF, 0x86,
+ 0x05, 0x23, 0x8D, 0xAE, 0x56,
+ 0x0A, 0x80, 0x42, 0x3D, 0xDC,
+ 0x0B, 0x0D, 0xE9, 0xBC, 0xA7,
+ 0x0B, 0x36, 0x19, 0x20, 0xCD,
+ 0x0E, 0x27, 0xE0, 0x3C, 0xD4,
+ 0x01, 0x7E, 0xC5, 0x80, 0xF2,
+ 0x07, 0x9E, 0xD4, 0x14, 0x9B,
+ 0x00, 0x5A, 0xFA, 0xAD, 0x10,
+ 0x0F, 0x2E, 0xE0, 0x76, 0xE1,
+ 0x05, 0xD4, 0x44, 0x42, 0xD4,
+ 0x0B, 0x34, 0x2B, 0xD3, 0xF7,
+ 0x06, 0x7C, 0x96, 0xF8, 0xA5,
+ 0x09, 0x47, 0x9F, 0x86, 0xA0,
+ 0x05, 0x1B, 0x54, 0xB3, 0x9B,
+ 0x02, 0x84, 0xE9, 0x3B, 0xD6,
+ 0x09, 0x53, 0xC2, 0x2A, 0xD6,
+ 0x0F, 0xB0, 0x4B, 0x4E, 0x4D,
+ 0x0C, 0x41, 0xC3, 0x18, 0xD2,
+ 0x07, 0x0B, 0xFD, 0x65, 0x1E,
+ 0x06, 0xEA, 0x75, 0x31, 0x6A,
+ 0x0D, 0x77, 0x33, 0xAF, 0x14,
+ 0x04, 0x41, 0x05, 0x4B, 0x6B,
+ 0x01, 0x91, 0x0E, 0x35, 0x36,
+ 0x08, 0x77, 0x87, 0xEA, 0x1C,
+ 0x08, 0xB9, 0x90, 0x6C, 0x34,
+ 0x0F, 0x3E, 0x6C, 0x42, 0x0C,
+ 0x06, 0xAE, 0x26, 0x24, 0xC3,
+ 0x00, 0x42, 0xD2, 0xA0, 0xB7,
+ 0x0F, 0xE4, 0x90, 0xA1, 0xFF,
+ 0x0D, 0x14, 0x1C, 0x9A, 0x59,
+ 0x0E, 0x46, 0x9C, 0xA5, 0xFD,
+ 0x0C, 0x38, 0xD5, 0x3C, 0x7C,
+ 0x01, 0x69, 0xAE, 0xC1, 0x6B,
+ 0x00, 0xA2, 0x4A, 0x3C, 0xBA,
+ 0x09, 0x86, 0x13, 0xDA, 0x11,
+ 0x08, 0x94, 0xEF, 0x61, 0x50,
+ 0x0F, 0x0F, 0xF8, 0x38, 0xC4,
+ 0x03, 0xA2, 0x34, 0xE8, 0xA8,
+ 0x06, 0xDA, 0xBE, 0x1C, 0x6C,
+ 0x07, 0x4C, 0x44, 0x02, 0x11,
+ 0x04, 0xE5, 0x58, 0x7F, 0x4D,
+ 0x08, 0xA1, 0x5A, 0x5E, 0xC9,
+ 0x0D, 0xF9, 0x35, 0x23, 0xB0,
+ 0x0C, 0xA3, 0x4B, 0xFA, 0x9E,
+ 0x05, 0x96, 0x78, 0xFB, 0x13,
+ 0x06, 0xDD, 0x82, 0xD7, 0x61,
+ 0x00, 0xA5, 0x79, 0x42, 0xC7,
+ 0x0D, 0x27, 0xAE, 0xBE, 0x01,
+ 0x08, 0x5E, 0xD9, 0x8D, 0x5C,
+ 0x0F, 0xF0, 0x7B, 0xFE, 0x24,
+ 0x0A, 0x29, 0xDA, 0x31, 0xFB,
+ 0x09, 0x52, 0xB8, 0xD9, 0xF8,
+ 0x00, 0x8A, 0x04, 0x2F, 0x09,
+ 0x06, 0xB0, 0xDE, 0x1B, 0x82,
+ 0x02, 0xB4, 0xFD, 0x96, 0x5E,
+ 0x08, 0xAA, 0x46, 0x07, 0x99,
+ 0x06, 0x97, 0xF4, 0x18, 0xEB,
+ 0x0C, 0xF1, 0xF7, 0x01, 0xAD,
+ 0x03, 0x00, 0x2F, 0xEA, 0x01,
+ 0x02, 0x77, 0x4E, 0x17, 0xBA,
+ 0x06, 0x58, 0x84, 0xA6, 0xF0,
+ 0x04, 0x36, 0xA3, 0xAC, 0xBF,
+ 0x00, 0xF7, 0xC5, 0x8A, 0x80,
+ 0x03, 0xB4, 0x79, 0xB5, 0x20,
+ 0x04, 0x71, 0xB5, 0x37, 0xB3,
+ 0x00, 0x08, 0x46, 0x35, 0x57,
+ 0x0A, 0xBD, 0x37, 0x22, 0x85,
+ 0x09, 0xFB, 0x24, 0xB1, 0xE7,
+ 0x0C, 0xCC, 0x86, 0x32, 0x8D,
+ 0x05, 0x28, 0xA9, 0xD2, 0xDC,
+ 0x03, 0xA7, 0x07, 0xDB, 0x76,
+ 0x0B, 0x16, 0xD1, 0x02, 0x95,
+ 0x07, 0x95, 0x8E, 0xF4, 0xD4,
+ 0x0A, 0xC0, 0x8C, 0xE1, 0x7B,
+ 0x06, 0xCE, 0xF8, 0x7F, 0xC1,
+ 0x04, 0x8B, 0x99, 0x04, 0xA7,
+ 0x08, 0xF3, 0xE6, 0x45, 0x48,
+ 0x0B, 0x6A, 0x62, 0xE4, 0x2A,
+ 0x00, 0x8E, 0x27, 0x2A, 0xC3,
+ 0x01, 0x6E, 0x45, 0x0A, 0xD3,
+ 0x06, 0x49, 0x6F, 0x49, 0xA9,
+ 0x08, 0x0C, 0x65, 0x1A, 0x5F,
+ 0x01, 0x62, 0x2C, 0xB3, 0xC7,
+ 0x0D, 0x06, 0xB6, 0xEC, 0x16,
+ 0x0E, 0xAA, 0x05, 0x2B, 0xCB,
+ 0x03, 0x1C, 0xE9, 0x3B, 0x7F,
+ 0x02, 0x19, 0xC2, 0xF2, 0x50,
+ 0x0E, 0xF0, 0xFF, 0x83, 0xDF,
+ 0x0E, 0xB2, 0xE9, 0x4E, 0x11,
+ 0x09, 0x4D, 0x47, 0x91, 0xC6,
+ 0x05, 0xC4, 0xC4, 0x64, 0xBC,
+ 0x08, 0x4E, 0x51, 0x86, 0xF4,
+ 0x04, 0x8A, 0x95, 0xA7, 0x6C,
+ 0x0A, 0xDD, 0x93, 0x53, 0xB0,
+ 0x02, 0xC8, 0x64, 0xBF, 0xAA,
+ 0x07, 0x59, 0x63, 0x8F, 0xBA,
+ 0x0D, 0x6D, 0xD4, 0x2D, 0x7D,
+ 0x06, 0x0A, 0x57, 0x91, 0x70,
+ 0x01, 0xD2, 0xFA, 0xEA, 0xA4,
+ 0x03, 0x84, 0x6D, 0x9A, 0x1D,
+ 0x01, 0xFF, 0x07, 0xBE, 0x2E,
+ 0x0D, 0x90, 0xFD, 0xAF, 0xCF,
+ 0x0B, 0x15, 0x23, 0xAB, 0xA9,
+ 0x03, 0x8A, 0xCC, 0x42, 0x20,
+ 0x05, 0xAA, 0xCD, 0xE5, 0xF9,
+ 0x0C, 0xA9, 0x6F, 0xD5, 0x25,
+ 0x05, 0x24, 0xEC, 0xE0, 0x21,
+ 0x0F, 0x69, 0x7F, 0x45, 0x8E,
+ 0x02, 0xCF, 0x1F, 0x64, 0x1A,
+ 0x0B, 0xB0, 0x5A, 0xC9, 0xD9,
+ 0x02, 0xAF, 0x2E, 0xE0, 0xF3,
+ 0x02, 0xF5, 0xD4, 0x48, 0xE7,
+ 0x0B, 0xBB, 0xB4, 0x3B, 0xC3,
+ 0x0E, 0xEF, 0xDC, 0x5C, 0xC8,
+ 0x0C, 0xBB, 0xA7, 0x9F, 0x36,
+ 0x0A, 0x47, 0x1B, 0x51, 0x20,
+ 0x01, 0x00, 0x84, 0x67, 0x4B,
+ 0x08, 0x9B, 0x1E, 0x72, 0x28,
+ 0x06, 0x9F, 0xB2, 0x5B, 0x7E,
+ 0x04, 0xCD, 0x20, 0x7F, 0x28,
+ 0x04, 0xFE, 0x8B, 0x0D, 0xE5,
+ 0x08, 0x3E, 0xE8, 0x25, 0x37,
+ 0x06, 0xD5, 0x75, 0x40, 0xA9,
+ 0x08, 0x3C, 0x40, 0xF7, 0xC9,
+ 0x0D, 0x48, 0x30, 0xDE, 0x97,
+ 0x00, 0x89, 0xD7, 0xA7, 0x7C,
+ 0x09, 0x98, 0x79, 0x90, 0xCA,
+ 0x01, 0xEE, 0xFE, 0x6C, 0xD4,
+ 0x0E, 0x56, 0x2E, 0x30, 0x20,
+ 0x01, 0x69, 0x42, 0x64, 0xEE,
+ 0x07, 0xA6, 0xE4, 0x46, 0x2F,
+ 0x06, 0x7E, 0xF6, 0xF1, 0x5A,
+ 0x09, 0x80, 0xC6, 0x77, 0xA7,
+ 0x07, 0x14, 0x60, 0xCB, 0x38,
+ 0x0D, 0xD0, 0x6B, 0x42, 0x85,
+ 0x0B, 0xEA, 0xA0, 0x7E, 0x3E,
+ 0x00, 0x81, 0xCE, 0x9F, 0x15,
+ 0x0D, 0x20, 0x9C, 0x2F, 0x5D,
+ 0x00, 0xEF, 0x0F, 0xF6, 0x20,
+ 0x08, 0x73, 0xE0, 0x9A, 0xAD,
+ 0x07, 0x7D, 0x1C, 0xA9, 0xDC,
+ 0x05, 0xDE, 0x0C, 0x48, 0x42,
+ 0x0B, 0x86, 0x82, 0xD8, 0x6D,
+ 0x04, 0xC8, 0x61, 0x56, 0x3E,
+ 0x01, 0xAF, 0xBD, 0x35, 0xC1,
+ 0x0B, 0x8E, 0xCA, 0x4B, 0xF2,
+ 0x05, 0x75, 0x56, 0x74, 0x7B,
+ 0x0C, 0xD6, 0xDD, 0x42, 0xD4,
+ 0x05, 0x40, 0xA5, 0x74, 0xF3,
+ 0x03, 0x9D, 0x27, 0xA8, 0x10,
+ 0x0B, 0x38, 0xDE, 0xC4, 0x61,
+ 0x06, 0x55, 0xF0, 0x6B, 0xA2,
+ 0x0F, 0xC1, 0xC9, 0xCA, 0x3C,
+ 0x09, 0xB1, 0x52, 0x3C, 0xE1,
+ 0x06, 0x18, 0x45, 0x04, 0x23,
+ 0x01, 0xCB, 0x50, 0xD3, 0x9B,
+ 0x0D, 0x42, 0xB6, 0xBD, 0x9C,
+ 0x0B, 0xF2, 0x68, 0x62, 0x0A,
+ 0x09, 0x46, 0x97, 0x7A, 0x45,
+ 0x03, 0x2C, 0xF5, 0x75, 0xC2,
+ 0x05, 0xA3, 0x81, 0x2D, 0x2A,
+ 0x09, 0x53, 0x72, 0x6C, 0x87,
+ 0x02, 0x56, 0xDD, 0xC6, 0x06,
+ 0x08, 0xA4, 0x31, 0xC1, 0x3C,
+ 0x07, 0xF9, 0x74, 0xC7, 0x4C,
+ 0x0A, 0xD1, 0xB0, 0x79, 0x33,
+ 0x08, 0xA6, 0x02, 0x35, 0x61,
+ 0x01, 0x10, 0x1C, 0x46, 0x13,
+ 0x05, 0x61, 0xBD, 0x31, 0x28,
+ 0x01, 0x69, 0xFB, 0x28, 0x37,
+ 0x04, 0xD4, 0xCC, 0x06, 0x32,
+ 0x0D, 0x77, 0x68, 0xB1, 0x9C,
+ 0x05, 0xE9, 0xEE, 0x83, 0x42,
+ 0x04, 0x0B, 0x5B, 0x51, 0x02,
+ 0x05, 0xE5, 0xDC, 0x0E, 0x74,
+ 0x0E, 0xE2, 0x09, 0x0C, 0xE1,
+ 0x03, 0xE4, 0x87, 0x74, 0x3F,
+ 0x0B, 0xED, 0xF2, 0x99, 0x06,
+ 0x0F, 0x68, 0x73, 0xEA, 0x85,
+ 0x00, 0x61, 0x6E, 0xE2, 0x97,
+ 0x0A, 0x12, 0xF6, 0xA7, 0x22,
+ 0x0B, 0x7A, 0xEE, 0x48, 0x4A,
+ 0x0B, 0x76, 0xE9, 0x6F, 0xC9,
+ 0x0B, 0x98, 0x08, 0x61, 0x1A,
+ 0x05, 0x11, 0x60, 0x28, 0x4F,
+ 0x06, 0xDD, 0xC6, 0xB6, 0xEC,
+ 0x0A, 0xBE, 0xAB, 0x45, 0x1E,
+ 0x0F, 0xB8, 0x1C, 0x6D, 0xBD,
+ 0x07, 0x12, 0x1D, 0xC6, 0xF6,
+ 0x0D, 0xA7, 0x50, 0xFF, 0x83,
+ 0x06, 0x96, 0xD2, 0x05, 0x4E,
+ 0x09, 0xE5, 0xAD, 0x84, 0x51,
+ 0x06, 0xD5, 0xC6, 0xD2, 0x02,
+ 0x0B, 0x1A, 0x22, 0xD5, 0x82,
+ 0x0C, 0xDC, 0x08, 0x1B, 0x67,
+ 0x04, 0x90, 0xDC, 0x9E, 0x13,
+ 0x0A, 0xD8, 0xCB, 0xB1, 0xBB,
+ 0x02, 0xC7, 0x5A, 0xE7, 0x85,
+ 0x0A, 0x0D, 0x6D, 0xD5, 0xA9,
+ 0x0D, 0x54, 0x0A, 0x5A, 0x9E,
+ 0x0A, 0xF9, 0xD3, 0xFF, 0xE2,
+ 0x04, 0x33, 0x85, 0x7D, 0x90,
+ 0x07, 0x01, 0xE5, 0x82, 0xB4,
+ 0x0E, 0x64, 0x12, 0x0D, 0xA3,
+ 0x05, 0x7B, 0x1D, 0x26, 0x83,
+ 0x0B, 0x89, 0x88, 0x80, 0x42,
+ 0x00, 0x9C, 0xAB, 0x9D, 0x63,
+ 0x09, 0x14, 0x2B, 0x4F, 0xD9,
+ 0x05, 0xBF, 0x24, 0xA6, 0x60,
+ 0x0A, 0x94, 0x69, 0x7F, 0x45,
+ 0x0E, 0xB2, 0xCF, 0x13, 0xF0,
+ 0x0A, 0xDB, 0xB0, 0x56, 0x3F,
+ 0x01, 0x94, 0x4F, 0x2E, 0xE0,
+ 0x0D, 0x24, 0x38, 0xD4, 0x48,
+ 0x0E, 0x43, 0x1B, 0x38, 0x3B,
+ 0x0A, 0xFF, 0xCD, 0x62, 0x15,
+ 0x01, 0xA4, 0xDB, 0x5B, 0x9F,
+ 0x02, 0x2A, 0x47, 0x8B, 0xD7,
+ 0x07, 0x11, 0x00, 0xA4, 0xE1,
+ 0x0D, 0x56, 0x99, 0xD3, 0xF2,
+ 0x0C, 0xD6, 0x3F, 0xB2, 0xCB,
+ 0x0F, 0x4D, 0x8C, 0xC4, 0xDA,
+ 0x08, 0xD2, 0x7E, 0x9D, 0x1F,
+ 0x05, 0x9E, 0x3E, 0xFE, 0x77,
+ 0x07, 0x60, 0xB5, 0xE3, 0xD2,
+ 0x09, 0x5E, 0x5D, 0xE6, 0xE5,
+ 0x00, 0xF9, 0xC8, 0x9D, 0x0E,
+ 0x0D, 0xB4, 0xE2, 0x77, 0x83,
+ 0x0C, 0x1E, 0xF8, 0xB5, 0x14,
+ 0x0A, 0x76, 0x8F, 0x22, 0xA8,
+ 0x04, 0x8E, 0x34, 0xBE, 0x26,
+ 0x02, 0x01, 0x0A, 0xC2, 0x72,
+ 0x08, 0x37, 0xA6, 0xE4, 0xD0,
+ 0x0D, 0x3F, 0x64, 0x96, 0xFC,
+ 0x0A, 0x99, 0x00, 0xC6, 0x51,
+ 0x05, 0xFD, 0x16, 0x3A, 0xCB,
+ 0x0C, 0x7D, 0xD0, 0x6B, 0x6E,
+ 0x0A, 0x6B, 0xEA, 0xA6, 0x50,
+ 0x00, 0x91, 0x81, 0xCE, 0x8F,
+ 0x07, 0x51, 0x2D, 0x98, 0x24,
+ 0x04, 0x10, 0x47, 0x0E, 0x2F,
+ 0x05, 0xD9, 0xF3, 0x26, 0x94,
+ 0x01, 0x1E, 0xEE, 0x58, 0xB7,
+ 0x0C, 0x6D, 0x5C, 0x48, 0x4F,
+ 0x0A, 0xD0, 0x24, 0xE4, 0x8F,
+ 0x07, 0x65, 0x48, 0xA7, 0x5A,
+ 0x0E, 0xC9, 0x2D, 0xF9, 0x35,
+ 0x03, 0x01, 0x8C, 0xA7, 0x40,
+ 0x02, 0xED, 0xD5, 0x97, 0xAF,
+ 0x03, 0x88, 0x56, 0xDB, 0x82,
+ 0x0F, 0x54, 0xE0, 0xA9, 0x79,
+ 0x0F, 0x4B, 0x1D, 0x23, 0xAE,
+ 0x08, 0x41, 0xA7, 0x5E, 0xC9,
+ 0x09, 0xDE, 0x9F, 0xF0, 0xBB,
+ 0x08, 0xE4, 0xE8, 0x29, 0xDB,
+ 0x04, 0xF8, 0x35, 0x52, 0xF8,
+ 0x0A, 0xB8, 0x9C, 0x8A, 0x87,
+ 0x01, 0x09, 0xCE, 0xB4, 0xD4,
+ 0x03, 0x91, 0xC2, 0xB4, 0x3D,
+ 0x02, 0x5A, 0x72, 0x6A, 0x66,
+ 0x03, 0x19, 0x46, 0x97, 0xF4,
+ 0x0C, 0xEB, 0x28, 0xF5, 0xF7,
+ 0x09, 0xAD, 0x3B, 0x05, 0x6F,
+ 0x0A, 0x80, 0xCA, 0xF2, 0xEE,
+ 0x07, 0x3A, 0x4F, 0x5D, 0x44,
+ 0x02, 0x70, 0xB9, 0xB7, 0x43,
+ 0x04, 0x3F, 0x60, 0xF7, 0x05,
+ 0x0C, 0x83, 0xD3, 0xB4, 0x79,
+ 0x03, 0x62, 0xA4, 0x71, 0xB5,
+ 0x05, 0x31, 0x10, 0x0C, 0x46,
+ 0x0B, 0x17, 0x41, 0xB1, 0x77,
+ 0x02, 0x9D, 0xE9, 0xFB, 0x24,
+ 0x05, 0xE4, 0xD4, 0xC8, 0x46,
+ 0x0E, 0x99, 0x2F, 0xE8, 0xA7,
+ 0x06, 0x1B, 0xE3, 0xEE, 0xC9,
+ 0x0B, 0x76, 0x03, 0x5F, 0x55,
+ 0x09, 0x95, 0xE5, 0xDC, 0x0E,
+ 0x0C, 0x9E, 0x32, 0x8F, 0x0C,
+ 0x0B, 0x79, 0xCA, 0x07, 0x68,
+ 0x07, 0xC1, 0x67, 0x8B, 0x99,
+ 0x04, 0xA7, 0x64, 0xF3, 0xE6,
+ 0x0E, 0x48, 0xE3, 0x6A, 0xE2,
+ 0x0E, 0x20, 0x84, 0x8C, 0x39,
+ 0x0A, 0xC3, 0x7A, 0x62, 0x06,
+ 0x0A, 0xD3, 0xF6, 0x4B, 0xEC,
+ 0x01, 0x29, 0x3C, 0x0C, 0xA5,
+ 0x03, 0x5D, 0xD1, 0x6F, 0xAC,
+ 0x09, 0xC5, 0x6C, 0x06, 0xBE,
+ 0x00, 0x0A, 0xBE, 0xAA, 0x12,
+ 0x03, 0xE3, 0x38, 0x1A, 0xE9,
+ 0x05, 0xF4, 0xB2, 0x19, 0x02,
+ 0x0A, 0xDB, 0x0E, 0xF0, 0xE8,
+ 0x0F, 0xD7, 0x17, 0x32, 0x38,
+ 0x07, 0xD3, 0xE3, 0xC1, 0xCA,
+ 0x0B, 0xC4, 0x60, 0x44, 0xD4,
+ 0x08, 0x8B, 0x38, 0x42, 0x55,
+ 0x0E, 0xA4, 0x5C, 0x8C, 0x15,
+ 0x0E, 0xEE, 0x92, 0xD3, 0xD3,
+ 0x09, 0x32, 0xAB, 0xCA, 0x30,
+ 0x05, 0xA0, 0x7E, 0x59, 0x66,
+ 0x03, 0xA5, 0xF2, 0x91, 0xE9,
+ 0x04, 0x7F, 0x54, 0x06, 0x17,
+ 0x0D, 0x72, 0x80, 0xD2, 0x7E,
+ 0x02, 0x8D, 0x93, 0x89, 0xED,
+ 0x02, 0x0D, 0x61, 0xF9, 0x07,
+ 0x07, 0x2C, 0x64, 0x1E, 0xDD,
+ 0x09, 0xCD, 0x2C, 0x15, 0x2B,
+ 0x0D, 0xAB, 0x89, 0x8E, 0x8A,
+ 0x0A, 0x30, 0x18, 0xAB, 0xCD,
+ 0x03, 0x79, 0x15, 0xAE, 0x37,
+ 0x0D, 0x25, 0xBF, 0x22, 0xA6,
+ 0x08, 0x31, 0x10, 0x69, 0xBF,
+ 0x05, 0x8F, 0x32, 0xCB, 0x48,
+ 0x04, 0x1A, 0xDB, 0xB4, 0x03,
+ 0x0E, 0xA8, 0x14, 0xAB, 0x2E,
+ 0x08, 0x5B, 0x2C, 0xF5, 0x14,
+ 0x08, 0x4E, 0x87, 0xDB, 0x7E,
+ 0x00, 0xC3, 0xFE, 0x0F, 0x0D,
+ 0x0C, 0xC8, 0x25, 0x35, 0x0E,
+ 0x07, 0xAE, 0x8A, 0x4A, 0xDB,
+ 0x0B, 0x0C, 0xEE, 0xFC, 0x87,
+ 0x09, 0x39, 0xD4, 0x1B, 0x93,
+ 0x08, 0xC8, 0x5E, 0x1A, 0x38,
+ 0x0B, 0x7E, 0x4D, 0xCC, 0xC0,
+ 0x0B, 0xAA, 0xD2, 0x7C, 0x0B,
+ 0x04, 0x67, 0x9E, 0xBC, 0x68,
+ 0x0C, 0x35, 0x62, 0x37, 0x75,
+ 0x08, 0xAB, 0x5E, 0x5F, 0x40,
+ 0x07, 0x49, 0xEB, 0x2E, 0xDA,
+ 0x0E, 0x17, 0xB6, 0xEE, 0xFD,
+ 0x07, 0xFC, 0x1E, 0x7E, 0x73,
+ 0x00, 0x4A, 0x76, 0x09, 0x74,
+ 0x0C, 0x54, 0x8E, 0x36, 0xAE,
+ 0x0E, 0xA0, 0x01, 0x0A, 0x42,
+ 0x02, 0xAC, 0x37, 0xA6, 0xE4,
+ 0x00, 0xAD, 0x3F, 0x64, 0x96,
+ 0x0C, 0x9A, 0x9B, 0x86, 0x8C,
+ 0x0A, 0xA5, 0xFD, 0x16, 0x3A,
+ 0x0B, 0x3C, 0x7D, 0xDE, 0x76,
+ 0x06, 0xC1, 0xE7, 0xE4, 0xE0,
+ 0x0A, 0x34, 0x1B, 0x8C, 0x0E,
+ 0x0A, 0xD7, 0x91, 0x21, 0x5C,
+ 0x01, 0xEC, 0x1D, 0xEF, 0x0F,
+ 0x08, 0x3D, 0xF3, 0x77, 0x29,
+ 0x0C, 0xEC, 0x9E, 0x70, 0xD8,
+ 0x00, 0x9E, 0x2D, 0x5E, 0xCC,
+ 0x0E, 0x00, 0xDC, 0x04, 0xE1,
+ 0x08, 0x6F, 0x4D, 0xCE, 0x2B,
+ 0x02, 0xFC, 0xEB, 0x21, 0xF9,
+ 0x0F, 0x31, 0xCB, 0x0C, 0xAB,
+ 0x00, 0xFA, 0x2C, 0x75, 0x96,
+ 0x08, 0xFB, 0xA0, 0xDB, 0x99,
+ 0x09, 0x54, 0xDB, 0xCD, 0x20,
+ 0x07, 0xF7, 0xCE, 0x9D, 0x27,
+ 0x02, 0xA2, 0x41, 0x78, 0x5D,
+ 0x01, 0xA1, 0x5E, 0x11, 0xF0,
+ 0x03, 0xE3, 0x66, 0x41, 0x69,
+ 0x02, 0xBC, 0x59, 0xBC, 0x12,
+ 0x08, 0xDA, 0xB8, 0x9C, 0x95,
+ 0x0C, 0xEA, 0xA9, 0xC7, 0x70,
+ 0x06, 0x1A, 0x35, 0x42, 0x74,
+ 0x04, 0x92, 0x9B, 0xF2, 0x6A,
+ 0x0F, 0x83, 0xF9, 0x46, 0x97,
+ 0x04, 0x58, 0xEF, 0x28, 0xB5,
+ 0x07, 0x41, 0xA9, 0xBB, 0xC6,
+ 0x0F, 0xAA, 0x81, 0x4A, 0x03,
+ 0x04, 0xE7, 0x3A, 0xCA, 0xEF,
+ 0x04, 0x86, 0x74, 0xBD, 0xB3,
+ 0x01, 0xBC, 0x33, 0xE0, 0x77,
+ 0x07, 0xCC, 0x82, 0x43, 0x34,
+ 0x08, 0xF2, 0xA2, 0xA4, 0x71,
+ 0x04, 0xF0, 0xD1, 0x10, 0x08,
+ 0x06, 0x13, 0x93, 0x6F, 0xF4,
+ 0x0D, 0xC2, 0x9D, 0xEC, 0x4C,
+ 0x06, 0xB7, 0xE4, 0xC4, 0x4C,
+ 0x06, 0x32, 0x8D, 0x2F, 0xE8,
+ 0x00, 0x57, 0xB9, 0xE3, 0xEE,
+ 0x0B, 0x5B, 0xF2, 0x09, 0xDF,
+ 0x05, 0x02, 0x95, 0x65, 0xD6,
+ 0x06, 0xF6, 0x9A, 0xBA, 0x49,
+ 0x06, 0xE3, 0x9E, 0x66, 0x85,
+ 0x00, 0xFD, 0x81, 0x6D, 0x0B,
+ 0x09, 0x04, 0xA4, 0xEA, 0x79,
+ 0x0C, 0xC7, 0xA8, 0x63, 0x62,
+ 0x02, 0x62, 0x20, 0x90, 0x8C,
+ 0x07, 0x2A, 0xC0, 0xFC, 0xE4,
+ 0x05, 0x0A, 0xD2, 0xF0, 0xC3,
+ 0x0F, 0xC9, 0xA9, 0x98, 0x0C,
+ 0x0D, 0x98, 0x3F, 0x53, 0xE3,
+ 0x0C, 0xB3, 0xC4, 0x5F, 0x8C,
+ 0x0C, 0xEE, 0xF2, 0xBE, 0xA2,
+ 0x05, 0x2B, 0xCB, 0x38, 0x1C,
+ 0x09, 0x3D, 0x76, 0x94, 0xD3,
+ 0x02, 0xF6, 0xCC, 0x08, 0x3A,
+ 0x05, 0x81, 0x31, 0x97, 0x33,
+ 0x01, 0x4F, 0x51, 0x6B, 0xCD,
+ 0x02, 0x13, 0x86, 0x57, 0x44,
+ 0x04, 0x40, 0x21, 0x9A, 0xFF,
+ 0x05, 0x86, 0xF7, 0xDE, 0x38,
+ 0x05, 0xA7, 0xEF, 0x90, 0x6C,
+ 0x03, 0x53, 0x30, 0x9C, 0xC0,
+ 0x0E, 0xBD, 0x4B, 0xC7, 0x51,
+ 0x07, 0x8F, 0xBA, 0x0B, 0xE7,
+ 0x00, 0xAF, 0x3D, 0xD8, 0x4A,
+ 0x0D, 0x95, 0x9A, 0xB9, 0xDA,
+ 0x0A, 0xEA, 0x24, 0x35, 0x0F,
+ 0x05, 0x18, 0x7D, 0x6D, 0x7F,
+ 0x0D, 0xBC, 0xC2, 0x64, 0x1A,
+ 0x0D, 0xA3, 0xCF, 0x9D, 0xDF,
+ 0x0B, 0x0F, 0xCB, 0x05, 0x48,
+ 0x0A, 0x40, 0xDD, 0x1C, 0xA3,
+ 0x0D, 0xE9, 0xB9, 0x12, 0xE1,
+ 0x0F, 0xD9, 0x25, 0x3F, 0x26,
+ 0x06, 0x60, 0x31, 0x94, 0x69,
+ 0x07, 0x47, 0xCE, 0xB0, 0x4F,
+ 0x05, 0x76, 0xEA, 0x5B, 0xB8,
+ 0x0A, 0xFA, 0xAC, 0x14, 0xAF,
+ 0x0E, 0xE0, 0x7F, 0xA4, 0xF5,
+ 0x06, 0x48, 0x63, 0x0D, 0xDB,
+ 0x0C, 0x3B, 0x45, 0x7C, 0x8F,
+ 0x0C, 0x5D, 0x48, 0x25, 0x3B,
+ 0x0F, 0x1D, 0x77, 0xA8, 0xC7,
+ 0x03, 0xD5, 0x33, 0x11, 0xC0,
+ 0x0E, 0x63, 0xCD, 0x56, 0x0B,
+ 0x03, 0x72, 0x28, 0x50, 0x95,
+ 0x02, 0x4B, 0x72, 0xCD, 0x4C,
+ 0x00, 0x63, 0x24, 0xD2, 0xFE,
+ 0x03, 0x1F, 0x05, 0x9C, 0xBE,
+ 0x02, 0x37, 0x40, 0x60, 0xBD,
+ 0x05, 0x50, 0x2D, 0x5E, 0x5D,
+ 0x00, 0xE7, 0x45, 0xEB, 0xA8,
+ 0x02, 0xCE, 0x13, 0xB0, 0x68,
+ 0x0F, 0x87, 0x7B, 0x1C, 0x78,
+ 0x09, 0x91, 0xCA, 0x76, 0x8F,
+ 0x06, 0xEE, 0x35, 0x8C, 0xB6,
+ 0x06, 0xA4, 0x06, 0x01, 0xC8,
+ 0x08, 0x70, 0x56, 0xB7, 0xB6,
+ 0x04, 0x50, 0xAD, 0x39, 0x6E,
+ 0x0E, 0xFC, 0x1E, 0x99, 0x40,
+ 0x0E, 0xD0, 0x22, 0x7F, 0x96,
+ 0x0A, 0xCB, 0x3C, 0x7D, 0x13,
+ 0x01, 0x6C, 0x3F, 0x6B, 0xE8,
+ 0x02, 0x52, 0xBC, 0xBD, 0xC1,
+ 0x0E, 0x93, 0xD7, 0x51, 0x21,
+ 0x0D, 0xE5, 0x0C, 0xD0, 0xEF,
+ 0x07, 0x79, 0xBD, 0x73, 0xF3,
+ 0x0A, 0x97, 0xED, 0x9E, 0x7E,
+ 0x0A, 0xA9, 0x1C, 0x6B, 0x1C,
+ 0x0C, 0x44, 0x02, 0x11, 0x84,
+ 0x04, 0x12, 0x2F, 0x4D, 0xC8,
+ 0x09, 0x5A, 0xFA, 0xC9, 0x6D,
+ 0x01, 0xB4, 0xB0, 0x83, 0x0C,
+ 0x09, 0x48, 0xF9, 0xAC, 0x7D,
+ 0x04, 0x78, 0xFB, 0xA6, 0x96,
+ 0x0D, 0x82, 0xD7, 0xD5, 0x40,
+ 0x04, 0xB3, 0x17, 0x03, 0x9D,
+ 0x0F, 0x2F, 0x23, 0x41, 0xB8,
+ 0x04, 0xDA, 0xA7, 0x5E, 0x17,
+ 0x02, 0x7B, 0xE2, 0xE0, 0x01,
+ 0x09, 0xDA, 0x3C, 0xF9, 0xB1,
+ 0x03, 0x72, 0x9A, 0xB8, 0x98,
+ 0x08, 0x04, 0x23, 0x09, 0xCA,
+ 0x08, 0xD6, 0x1F, 0x97, 0x82,
+ 0x0C, 0xF4, 0x12, 0x5D, 0x72,
+ 0x02, 0xE4, 0x03, 0x19, 0x86,
+ 0x0D, 0xF7, 0x51, 0xEB, 0x24,
+ 0x09, 0xF7, 0xC1, 0xAD, 0x7B,
+ 0x0D, 0x2D, 0xAE, 0x83, 0xCA,
+ 0x08, 0xED, 0x0C, 0x3A, 0x47,
+ 0x0D, 0x44, 0x82, 0x70, 0xBD,
+ 0x03, 0x43, 0xB0, 0x3F, 0xE0,
+ 0x05, 0xC5, 0xC8, 0x84, 0x13,
+ 0x0C, 0xF9, 0x53, 0x60, 0x24,
+ 0x01, 0x34, 0xD1, 0x31, 0x10,
+ 0x08, 0x46, 0x13, 0x95, 0x61,
+ 0x0D, 0x37, 0x22, 0x83, 0x5B,
+ 0x0B, 0x24, 0xB5, 0xE2, 0x9E,
+ 0x07, 0x06, 0x32, 0x8B, 0x5C,
+ 0x01, 0x31, 0x36, 0x64, 0x23,
+ 0x00, 0x03, 0x96, 0x76, 0x0B,
+ 0x07, 0x50, 0x80, 0x98, 0x36,
+ 0x0C, 0x0E, 0x74, 0x80, 0xA7,
+ 0x09, 0x0C, 0xE1, 0x3F, 0x72,
+ 0x0F, 0x40, 0xFB, 0xF1, 0x2F,
+ 0x02, 0x98, 0x84, 0x87, 0xE8,
+ 0x0B, 0x67, 0x45, 0x48, 0x63,
+ 0x0A, 0xE2, 0x62, 0x20, 0x19,
+ 0x0C, 0x27, 0x2E, 0x45, 0xF0,
+ 0x0C, 0x45, 0x0E, 0x55, 0xBC,
+ 0x0B, 0x6F, 0xC9, 0xAF, 0xD8,
+ 0x0C, 0x65, 0x9A, 0x5B, 0x12,
+ 0x03, 0x5C, 0x13, 0xC7, 0xDD,
+ 0x0A, 0xB6, 0xCC, 0x16, 0x8F,
+ 0x03, 0x87, 0x6B, 0xCD, 0xB8,
+ 0x06, 0xEA, 0x2A, 0xF5, 0x1A,
+ 0x00, 0xC2, 0x36, 0xCB, 0x0E,
+ 0x09, 0x7D, 0xC3, 0xD9, 0x57,
+ 0x08, 0x0A, 0x57, 0xD1, 0xE5,
+ 0x04, 0x8A, 0x51, 0xC0, 0x95,
+ 0x08, 0xF4, 0x40, 0x21, 0x2A,
+ 0x0C, 0x55, 0x86, 0xF4, 0x5C,
+ 0x08, 0x15, 0xA0, 0x6A, 0x18,
+ 0x0E, 0x92, 0x93, 0x30, 0x18,
+ 0x0B, 0x36, 0xFF, 0xA2, 0xC7,
+ 0x00, 0xE5, 0xCF, 0xBC, 0x0D,
+ 0x07, 0xDB, 0x30, 0x7D, 0x5C,
+ 0x03, 0x57, 0x57, 0x76, 0x39,
+ 0x0B, 0xF8, 0xAA, 0x22, 0x73,
+ 0x0F, 0xEE, 0x84, 0x9D, 0xE3,
+ 0x06, 0x07, 0x7E, 0x28, 0x24,
+ 0x0A, 0x1C, 0x63, 0xCD, 0x1B,
+ 0x0D, 0x23, 0x09, 0xAB, 0x49,
+ 0x01, 0x00, 0xA2, 0x30, 0x9C,
+ 0x0B, 0x0D, 0xE9, 0xBF, 0x4F,
+ 0x0B, 0x4F, 0xD9, 0x22, 0x25,
+ 0x0C, 0x66, 0x69, 0xB7, 0xD7,
+ 0x09, 0x7F, 0x45, 0x8E, 0xB2,
+ 0x07, 0x9D, 0x74, 0x1B, 0x5B,
+ 0x0A, 0x59, 0xD9, 0x28, 0x1C,
+ 0x07, 0x2E, 0x60, 0x72, 0x24,
+ 0x0D, 0x54, 0xEB, 0xE5, 0x8B,
+ 0x02, 0x36, 0x1B, 0xCF, 0xBE,
+ 0x05, 0x7F, 0x7A, 0xC8, 0x2D,
+ 0x03, 0xB7, 0x3F, 0x30, 0x6A,
+ 0x0D, 0x18, 0x7F, 0x13, 0x10,
+ 0x00, 0x84, 0x61, 0x3D, 0x1D,
+ 0x02, 0x53, 0x92, 0x29, 0x81,
+ 0x06, 0x33, 0xAB, 0x72, 0xCD,
+ 0x04, 0x68, 0xC3, 0x2E, 0x92,
+ 0x0E, 0x8B, 0x1C, 0x61, 0x49,
+ 0x0A, 0xE8, 0x35, 0xB1, 0x60,
+ 0x0C, 0xDD, 0x90, 0x2B, 0xDE,
+ 0x0C, 0x40, 0x03, 0x49, 0x32,
+ 0x08, 0x90, 0xCE, 0x11, 0xED,
+ 0x08, 0x77, 0x87, 0xFB, 0x84,
+ 0x08, 0xB9, 0x90, 0x6C, 0xB4,
+ 0x05, 0xFE, 0x65, 0xD2, 0xD6,
+ 0x06, 0xAE, 0x26, 0x23, 0x8B,
+ 0x0C, 0xC2, 0x72, 0xEA, 0x37,
+ 0x0E, 0xDC, 0xD4, 0xAD, 0xFF,
+ 0x04, 0xBF, 0x78, 0x9A, 0x99,
+ 0x0B, 0x44, 0xC7, 0x25, 0x0C,
+ 0x0E, 0x3B, 0x4F, 0x3C, 0xBD,
+ 0x09, 0xEB, 0x8E, 0xC1, 0x2B,
+ 0x03, 0x22, 0x32, 0xB0, 0xBB,
+ 0x01, 0xCE, 0x93, 0x81, 0x53,
+ 0x01, 0x9C, 0x2D, 0x3C, 0xD0,
+ 0x05, 0x0C, 0xF7, 0x3D, 0xE1,
+ 0x08, 0x20, 0x94, 0xED, 0x1E,
+ 0x00, 0xD8, 0xA9, 0xDC, 0x5B,
+ 0x00, 0x4C, 0x47, 0x42, 0x12,
+ 0x0D, 0xE5, 0x98, 0x61, 0x50,
+ 0x01, 0xA0, 0x9E, 0x7E, 0x89,
+ 0x05, 0x79, 0x91, 0x33, 0xC1,
+ 0x04, 0xA3, 0xCF, 0xFA, 0xEC,
+ 0x0D, 0x97, 0xF8, 0xF6, 0xA0,
+ 0x06, 0xDD, 0x82, 0xD7, 0xE7,
+ 0x00, 0xA5, 0x7B, 0x73, 0x37,
+ 0x0D, 0x27, 0xAC, 0xA6, 0x30,
+ 0x08, 0x5E, 0xD9, 0xA5, 0x43,
+ 0x0F, 0xF0, 0x7B, 0xE6, 0x5D,
+ 0x08, 0xA9, 0x3A, 0x3C, 0x39,
+ 0x09, 0x52, 0xB8, 0xDA, 0xB8,
+ 0x06, 0x08, 0xC9, 0x23, 0x09,
+ 0x0A, 0xB0, 0xDE, 0x95, 0x8C,
+ 0x0A, 0x34, 0x5B, 0x9F, 0x52,
+ 0x0A, 0xEB, 0xC2, 0x0F, 0x19,
+ 0x0F, 0x9F, 0x30, 0x5A, 0x6B,
+ 0x05, 0xF8, 0x37, 0x41, 0x6D,
+ 0x03, 0x05, 0xAF, 0xAE, 0xF5,
+ 0x0A, 0xF2, 0xEE, 0x07, 0x3A,
+ 0x09, 0x5D, 0x44, 0x80, 0xF0,
+ 0x04, 0xA6, 0x83, 0xBC, 0xFF,
+ 0x01, 0xF6, 0x0D, 0xC2, 0x5C,
+ 0x03, 0xB4, 0x7D, 0xF7, 0x16,
+ 0x08, 0x71, 0xB4, 0x31, 0x3F,
+ 0x02, 0x08, 0x4E, 0x15, 0x15,
+ 0x0D, 0x87, 0x37, 0x22, 0x9C,
+ 0x09, 0xD2, 0xA4, 0xB7, 0xE4,
+ 0x0D, 0x4E, 0x64, 0x3E, 0x8D,
+ 0x05, 0xEB, 0x88, 0xD6, 0x49,
+ 0x0A, 0xEE, 0x4B, 0x55, 0xB6,
+ 0x07, 0x60, 0xAA, 0xC2, 0x85,
+ 0x07, 0xDC, 0x06, 0x72, 0x9E,
+ 0x02, 0x89, 0x80, 0xED, 0xFB,
+ 0x06, 0xE6, 0xFA, 0x72, 0x08,
+ 0x06, 0x8A, 0x5D, 0x09, 0x27,
+ 0x00, 0x71, 0x46, 0xC9, 0x88,
+ 0x03, 0x6A, 0xE2, 0x64, 0x12,
+ 0x0A, 0x8F, 0x11, 0xAA, 0xD3,
+ 0x0A, 0x6E, 0x41, 0x0A, 0xD3,
+ 0x0E, 0x48, 0xFB, 0x49, 0x69,
+ 0x00, 0x8E, 0x65, 0x1A, 0xAD,
+ 0x0B, 0x60, 0xE5, 0xB3, 0xC5,
+ 0x05, 0x06, 0x36, 0xE0, 0x96,
+ 0x06, 0xA8, 0x05, 0x29, 0x4B,
+ 0x02, 0x1F, 0xA2, 0x3D, 0x7D,
+ 0x02, 0x19, 0xC6, 0xF6, 0xCD,
+ 0x0E, 0xF0, 0xF3, 0x83, 0xDF,
+ 0x05, 0x32, 0x09, 0x48, 0xD1,
+ 0x0F, 0xCD, 0x0A, 0x93, 0x46,
+ 0x05, 0xC5, 0x44, 0x40, 0x21,
+ 0x08, 0x4E, 0x55, 0x86, 0xF4,
+ 0x0C, 0x8A, 0x15, 0xA7, 0xEC,
+ 0x02, 0xDF, 0x91, 0x55, 0x3A,
+ 0x03, 0xCA, 0x34, 0xBF, 0xA2,
+ 0x07, 0x59, 0x67, 0x83, 0xFE,
+ 0x0D, 0x6D, 0xD8, 0x31, 0xF8,
+ 0x0C, 0x0A, 0xD7, 0xB9, 0x6D,
+ 0x01, 0x83, 0xFE, 0xC6, 0x24,
+ 0x03, 0x85, 0xE9, 0x9A, 0xE4,
+ 0x01, 0xFF, 0x03, 0xBA, 0x16,
+ 0x0C, 0x12, 0x19, 0xAE, 0x0F,
+ 0x03, 0x90, 0x83, 0x80, 0x6B,
+ 0x01, 0x8A, 0x80, 0x4E, 0x30,
+ 0x04, 0x29, 0x2D, 0xE5, 0xB9,
+ 0x04, 0x2B, 0x4F, 0xDD, 0x1F,
+ 0x0F, 0x26, 0xA6, 0x64, 0x4A,
+ 0x04, 0x69, 0x7F, 0x45, 0x79,
+ 0x0B, 0x07, 0xFF, 0x78, 0x1A,
+ 0x05, 0x30, 0x97, 0xFA, 0xA8,
+ 0x04, 0xAF, 0x2E, 0xEE, 0xE0,
+ 0x04, 0xF5, 0xD4, 0x46, 0xB3,
+ 0x03, 0xDA, 0xD4, 0x36, 0x83,
+ 0x07, 0xC6, 0x9C, 0x50, 0xC8,
+ 0x05, 0x3B, 0x47, 0x8B, 0x2B,
+ 0x02, 0x47, 0x1F, 0x1A, 0xCA,
+ 0x03, 0x00, 0x88, 0x71, 0xB9,
+ 0x04, 0x1B, 0xD7, 0x22, 0xA8,
+ 0x04, 0xB7, 0x32, 0x5B, 0xFE,
+ 0x0F, 0x66, 0xCC, 0x23, 0xA8,
+ 0x00, 0xD7, 0x0F, 0x0D, 0xE5,
+ 0x0C, 0x17, 0x64, 0x65, 0x37,
+ 0x02, 0x1D, 0x55, 0x40, 0xA9,
+ 0x0C, 0xF4, 0x64, 0xA7, 0xC9,
+ 0x09, 0x02, 0xBC, 0xDE, 0x97,
+ 0x04, 0xC1, 0xD3, 0xD7, 0x7C,
+ 0x0D, 0xD0, 0x79, 0x80, 0xCA,
+ 0x05, 0xA6, 0xF2, 0x6C, 0xD4,
+ 0x0D, 0x1F, 0x6E, 0x66, 0xA2,
+ 0x00, 0x22, 0x86, 0x64, 0xAF,
+ 0x05, 0x8E, 0x68, 0x00, 0x2D,
+ 0x0D, 0x61, 0x16, 0xEC, 0x1A,
+ 0x0B, 0xA9, 0x46, 0x71, 0x25,
+ 0x0D, 0x3F, 0xBA, 0xDB, 0x3C,
+ 0x0D, 0xF9, 0xEB, 0x7E, 0x83,
+ 0x0B, 0xEA, 0xA0, 0x14, 0xFE,
+ 0x0B, 0x81, 0xCE, 0x85, 0x55,
+ 0x01, 0x21, 0x9C, 0x79, 0x6E,
+ 0x09, 0xA5, 0x6F, 0xD6, 0x7D,
+ 0x0B, 0x70, 0x75, 0x14, 0xE9,
+ 0x02, 0x63, 0x27, 0x55, 0x29,
+ 0x0D, 0x5C, 0x4C, 0x4A, 0x1F,
+ 0x01, 0x84, 0xE1, 0x54, 0xEB,
+ 0x0D, 0xC8, 0xA5, 0x76, 0xBB,
+ 0x09, 0x2D, 0xFD, 0x15, 0xC4,
+ 0x01, 0x8C, 0xA3, 0x6B, 0x0B,
+ 0x0C, 0x75, 0x96, 0x58, 0x09,
+ 0x09, 0x56, 0x3D, 0x8E, 0xD7,
+ 0x0B, 0xC0, 0x68, 0x79, 0x77,
+ 0x03, 0x9D, 0x27, 0xB0, 0x31,
+ 0x03, 0x38, 0x5E, 0xE7, 0x75,
+ 0x0E, 0x1F, 0xF0, 0x6B, 0x5A,
+ 0x06, 0x41, 0x29, 0x9A, 0xBF,
+ 0x0F, 0xB1, 0x52, 0x28, 0x5A,
+ 0x0E, 0x98, 0x88, 0x54, 0xA3,
+ 0x0F, 0x4A, 0x10, 0xCE, 0x1B,
+ 0x07, 0xC3, 0x14, 0xDD, 0x12,
+ 0x0A, 0xF0, 0x4A, 0x78, 0x01,
+ 0x08, 0x44, 0xD7, 0xD4, 0x1A,
+ 0x03, 0x2C, 0x71, 0xFA, 0x01,
+ 0x05, 0x39, 0x25, 0xAF, 0xAA,
+ 0x0B, 0x49, 0x84, 0x6E, 0x27,
+ 0x02, 0x4F, 0xDD, 0x44, 0x86,
+ 0x08, 0x04, 0x13, 0x4F, 0xFC,
+ 0x06, 0xE2, 0xB7, 0xC5, 0xCC,
+ 0x08, 0x50, 0xC2, 0xF9, 0xF1,
+ 0x02, 0xA4, 0x71, 0xB3, 0x2A,
+ 0x01, 0x10, 0x08, 0x41, 0x89,
+ 0x0C, 0x60, 0x5D, 0x3A, 0xA2,
+ 0x0F, 0xA9, 0xF2, 0xA2, 0x5F,
+ 0x0C, 0xD4, 0x4C, 0x07, 0xB2,
+ 0x06, 0xAD, 0x42, 0xB5, 0x4B,
+ 0x0B, 0xE3, 0xEE, 0x85, 0x5B,
+ 0x06, 0x0B, 0x5F, 0x58, 0xDB,
+ 0x05, 0xCD, 0x5C, 0x0E, 0x74,
+ 0x07, 0xB8, 0x89, 0x00, 0x61,
+ 0x01, 0x65, 0xFF, 0x78, 0x77,
+ 0x09, 0xEF, 0x0B, 0x95, 0x84,
+ 0x0F, 0xE9, 0x13, 0xEB, 0xC5,
+ 0x01, 0x62, 0x8A, 0xEE, 0x62,
+ 0x09, 0x12, 0xEC, 0x29, 0x6A,
+ 0x03, 0x7A, 0x6C, 0x41, 0x43,
+ 0x03, 0xF6, 0x4B, 0x69, 0xC3,
+ 0x03, 0x9B, 0x65, 0x65, 0x1E,
+ 0x0F, 0xD1, 0x63, 0xA0, 0x77,
+ 0x07, 0xDD, 0x04, 0xBB, 0xE5,
+ 0x06, 0xBE, 0xA8, 0x05, 0x21,
+ 0x0B, 0xB8, 0x1C, 0xF9, 0x3F,
+ 0x0E, 0x12, 0x19, 0xC2, 0xF4,
+ 0x04, 0x0E, 0x30, 0xF2, 0x83,
+ 0x06, 0x97, 0xD2, 0x04, 0x8E,
+ 0x08, 0x2D, 0xAD, 0x86, 0x91,
+ 0x08, 0x55, 0x09, 0xC4, 0x40,
+ 0x01, 0x18, 0x4C, 0x41, 0x0F,
+ 0x0D, 0xDD, 0x4A, 0x39, 0xA7,
+ 0x08, 0x92, 0xDF, 0x93, 0xD3,
+ 0x04, 0x18, 0xCA, 0x34, 0x3F,
+ 0x02, 0xC7, 0xD9, 0x67, 0x8F,
+ 0x0A, 0x8D, 0xCD, 0xD8, 0x2D,
+ 0x04, 0xD6, 0x6A, 0x5B, 0x97,
+ 0x00, 0x39, 0xD2, 0x6C, 0xE8,
+ 0x04, 0x33, 0x87, 0xCB, 0xD8,
+ 0x07, 0xE2, 0x80, 0x07, 0xAE,
+ 0x05, 0x64, 0x12, 0x9D, 0xA3,
+ 0x0F, 0x9B, 0x15, 0x2E, 0x09,
+ 0x0B, 0x89, 0x88, 0x8D, 0x07,
+ 0x0A, 0x7C, 0xB0, 0x8A, 0xE6,
+ 0x09, 0x14, 0x2B, 0x6F, 0xD9,
+ 0x05, 0xBF, 0x26, 0x86, 0xE2,
+ 0x01, 0x94, 0x69, 0x7C, 0x30,
+ 0x06, 0x32, 0x6F, 0x11, 0x69,
+ 0x02, 0xDB, 0x30, 0x54, 0x7A,
+ 0x00, 0x16, 0xAF, 0x2E, 0x20,
+ 0x0B, 0x7D, 0x55, 0xD8, 0x48,
+ 0x07, 0x0B, 0xDB, 0x30, 0x01,
+ 0x03, 0xFE, 0x0F, 0x78, 0x2F,
+ 0x06, 0xA5, 0xF6, 0x47, 0x9F,
+ 0x0A, 0x1E, 0x47, 0x1B, 0x4E,
+ 0x0F, 0x25, 0x00, 0x84, 0x76,
+ 0x09, 0x56, 0x1B, 0xDD, 0xB6,
+ 0x08, 0x56, 0x9F, 0xBC, 0xCE,
+ 0x0E, 0x4D, 0x4C, 0xCE, 0x7E,
+ 0x08, 0xD2, 0xF6, 0x87, 0xC3,
+ 0x0C, 0x16, 0xD2, 0xC8, 0xC4,
+ 0x0E, 0xA9, 0x55, 0xE9, 0x41,
+ 0x01, 0x5E, 0xDD, 0xC0, 0x67,
+ 0x09, 0xEB, 0xA8, 0x90, 0x4D,
+ 0x07, 0xB6, 0x68, 0x74, 0xFD,
+ 0x06, 0xFE, 0xE0, 0x3E, 0xB3,
+ 0x08, 0x24, 0x8B, 0x2E, 0xEC,
+ 0x06, 0xDC, 0x32, 0x9E, 0xA6,
+ 0x00, 0x53, 0x00, 0xE2, 0xF1,
+ 0x0C, 0x65, 0xA6, 0xE7, 0x6B,
+ 0x0D, 0x6D, 0x64, 0x98, 0x79,
+ 0x02, 0x1A, 0xA0, 0xCB, 0x15,
+ 0x0C, 0xFE, 0x56, 0x37, 0x4F,
+ 0x0C, 0x7D, 0xD0, 0x6D, 0x6C,
+ 0x01, 0x6B, 0xEA, 0xA6, 0x50,
+ 0x0C, 0xBB, 0x81, 0xCA, 0xE6,
+ 0x07, 0x51, 0x21, 0x98, 0x99,
+ 0x0C, 0xD0, 0xED, 0x21, 0xB1,
+ 0x0D, 0xF1, 0x73, 0x14, 0x65,
+ 0x05, 0x9E, 0xDC, 0xDA, 0x29,
+ 0x0A, 0x6D, 0x5C, 0x4C, 0x04,
+ 0x04, 0x11, 0x84, 0xE5, 0x18,
+ 0x0F, 0xE4, 0x68, 0xA1, 0xD9,
+ 0x0E, 0x63, 0x09, 0xFA, 0x71,
+ 0x0A, 0x28, 0x28, 0xA3, 0x8B,
+ 0x03, 0x84, 0x95, 0x96, 0xB8,
+ 0x0B, 0xA0, 0xD6, 0x5B, 0xC8,
+ 0x07, 0xD5, 0x40, 0xA3, 0xE2,
+ 0x07, 0x03, 0x9D, 0x20, 0x74,
+ 0x0A, 0xC0, 0x18, 0x5C, 0x59,
+ 0x08, 0xDC, 0x3B, 0xF0, 0xBB,
+ 0x08, 0xE5, 0xDE, 0xA9, 0xD8,
+ 0x04, 0x79, 0x11, 0xD2, 0x38,
+ 0x0A, 0xB8, 0x9B, 0x04, 0x0E,
+ 0x03, 0x09, 0xCA, 0x34, 0x94,
+ 0x03, 0x11, 0xE2, 0xB9, 0xFD,
+ 0x08, 0x58, 0x5C, 0x6A, 0x46,
+ 0x03, 0x19, 0x46, 0x17, 0xF4,
+ 0x00, 0x6B, 0x8C, 0x73, 0x77,
+ 0x01, 0xAD, 0xBB, 0x07, 0x25,
+ 0x00, 0x82, 0xEC, 0xF2, 0xCE,
+ 0x0D, 0xFA, 0x4E, 0x5A, 0x03,
+ 0x06, 0x70, 0xBD, 0xB3, 0x43,
+ 0x0C, 0x3F, 0xE3, 0xF7, 0xC5,
+ 0x0C, 0x82, 0x53, 0x34, 0x73,
+ 0x03, 0x62, 0xA4, 0xF0, 0x3F,
+ 0x01, 0x31, 0x10, 0x09, 0xCC,
+ 0x07, 0x95, 0x61, 0x3B, 0x37,
+ 0x0E, 0x95, 0x69, 0xFB, 0x27,
+ 0x07, 0xE4, 0x57, 0x4C, 0x4C,
+ 0x0E, 0x8D, 0x2F, 0xEC, 0xB2,
+ 0x0F, 0xD1, 0x03, 0xEE, 0xC3,
+ 0x02, 0x76, 0xCB, 0x53, 0x8B,
+ 0x0B, 0xC7, 0xA5, 0xD0, 0x0E,
+ 0x04, 0x9E, 0xBA, 0x8F, 0x06,
+ 0x01, 0x7B, 0x66, 0x83, 0xE5,
+ 0x07, 0xC1, 0x6F, 0x8B, 0x9B,
+ 0x0C, 0x27, 0xC8, 0xF3, 0xE6,
+ 0x0F, 0xA8, 0xFB, 0xED, 0xB9,
+ 0x02, 0xE9, 0xF8, 0x18, 0x78,
+ 0x0E, 0x52, 0xD1, 0xEE, 0xC5,
+ 0x0A, 0x9A, 0x1E, 0xDD, 0x70,
+ 0x0D, 0xB8, 0x13, 0x8C, 0xE5,
+ 0x03, 0x5F, 0x11, 0x6E, 0x6C,
+ 0x0A, 0xC5, 0x9D, 0x2A, 0xB6,
+ 0x0C, 0x16, 0xBE, 0xAA, 0x47,
+ 0x0B, 0xCB, 0xBA, 0x18, 0x5E,
+ 0x07, 0x76, 0x99, 0x19, 0xD2,
+ 0x0D, 0xCD, 0x0E, 0xF0, 0xFF,
+ 0x03, 0xDF, 0x17, 0x3C, 0x14,
+ 0x06, 0xD1, 0x61, 0xC3, 0xCA,
+ 0x09, 0xC7, 0x55, 0xC4, 0x3E,
+ 0x08, 0x23, 0x18, 0x4E, 0x95,
+ 0x0F, 0xF4, 0x1C, 0x8A, 0x15,
+ 0x07, 0xEC, 0x92, 0xDB, 0x9A,
+ 0x0B, 0x30, 0x1B, 0x47, 0x70,
+ 0x0F, 0xA2, 0xC7, 0x54, 0xE2,
+ 0x0F, 0xBA, 0x09, 0x6F, 0x5B,
+ 0x07, 0x9D, 0x55, 0x8D, 0x24,
+ 0x05, 0x70, 0x39, 0xD6, 0xFA,
+ 0x0A, 0x24, 0x33, 0x85, 0xED,
+ 0x0B, 0xE5, 0x01, 0xF9, 0xCD,
+ 0x07, 0x2F, 0xA4, 0x9E, 0x9D,
+ 0x03, 0xCF, 0x9B, 0x15, 0x23,
+ 0x09, 0xAB, 0x89, 0x8E, 0x40,
+ 0x0B, 0xB1, 0x7C, 0xA9, 0x8D,
+ 0x08, 0x3B, 0x74, 0x2B, 0x4F,
+ 0x09, 0x25, 0xBF, 0x06, 0xA6,
+ 0x00, 0x31, 0x94, 0x49, 0x7D,
+ 0x05, 0x8E, 0xB2, 0xC9, 0xD5,
+ 0x04, 0x1A, 0xDB, 0x94, 0x53,
+ 0x0A, 0xA8, 0x13, 0x0F, 0x2C,
+ 0x00, 0x73, 0xA2, 0xF5, 0x9E,
+ 0x00, 0xE7, 0xAF, 0xDB, 0xCF,
+ 0x03, 0xC1, 0xDA, 0x03, 0x7C,
+ 0x04, 0x49, 0x81, 0x35, 0x07,
+ 0x05, 0xD6, 0x22, 0x40, 0x9A,
+ 0x07, 0x13, 0x11, 0x10, 0x84,
+ 0x01, 0x39, 0x56, 0x3B, 0xD3,
+ 0x02, 0x28, 0x56, 0x8F, 0xB0,
+ 0x0B, 0x7E, 0x4D, 0x6C, 0xC2,
+ 0x0A, 0xA8, 0x32, 0xFE, 0x4B,
+ 0x03, 0xE5, 0x53, 0x3E, 0xE8,
+ 0x0D, 0xB7, 0xE0, 0xBB, 0x75,
+ 0x08, 0x2B, 0x5E, 0x43, 0x00,
+ 0x07, 0x49, 0xEB, 0xBC, 0xD9,
+ 0x0E, 0x17, 0xB6, 0x68, 0xC6,
+ 0x07, 0xFC, 0x1C, 0xF8, 0x0B,
+ 0x0C, 0x55, 0x89, 0x73, 0x0A,
+ 0x06, 0xB4, 0x86, 0x31, 0x3A,
+ 0x0E, 0xA0, 0x61, 0x0A, 0x42,
+ 0x08, 0xAF, 0xF0, 0xA6, 0xEC,
+ 0x00, 0xAD, 0x3F, 0x69, 0x9C,
+ 0x08, 0x9A, 0x99, 0x1C, 0x86,
+ 0x05, 0xA5, 0xFD, 0x1A, 0xBA,
+ 0x0B, 0xBC, 0xDD, 0xD0, 0xDA,
+ 0x0F, 0xC1, 0xAB, 0xEA, 0x12,
+ 0x02, 0xBC, 0xBB, 0xA1, 0xCE,
+ 0x03, 0xD7, 0x51, 0x37, 0xDE,
+ 0x0F, 0x6C, 0xD0, 0xC9, 0x8D,
+ 0x08, 0x3D, 0xF3, 0x73, 0x20,
+ 0x0A, 0x6D, 0xD3, 0x7C, 0xD8,
+ 0x01, 0x14, 0xED, 0x61, 0x8C,
+ 0x0C, 0x00, 0x11, 0xBA, 0x65,
+ 0x02, 0x6C, 0x9C, 0xC8, 0xA3,
+ 0x00, 0x9E, 0xC1, 0x2A, 0x59,
+ 0x05, 0x33, 0x01, 0x9C, 0xA3,
+ 0x0B, 0xFA, 0x2C, 0x55, 0x96,
+ 0x08, 0xFB, 0xA0, 0xD6, 0x6C,
+ 0x02, 0xD7, 0xD5, 0x40, 0x17,
+ 0x09, 0x77, 0x03, 0x81, 0x65,
+ 0x0E, 0xA2, 0x43, 0x14, 0xDC,
+ 0x07, 0x21, 0x13, 0x1F, 0xF0,
+ 0x00, 0xE2, 0xE6, 0x41, 0x29,
+ 0x04, 0xBC, 0x34, 0xB1, 0x52,
+ 0x08, 0xDA, 0xB8, 0xB6, 0x95,
+ 0x04, 0x23, 0x0D, 0xEA, 0xB0,
+ 0x0C, 0x9B, 0x9D, 0x62, 0x34,
+ 0x0F, 0x92, 0x5F, 0xD2, 0xEA,
+ 0x04, 0x03, 0x95, 0x66, 0x17,
+ 0x06, 0x59, 0x6F, 0x0C, 0x71,
+ 0x05, 0xC1, 0x01, 0x9B, 0x85,
+ 0x0D, 0x2B, 0x25, 0x6A, 0x72,
+ 0x0D, 0x07, 0xF6, 0x7F, 0xDD,
+ 0x07, 0x87, 0xB0, 0x8D, 0x33,
+ 0x03, 0xBC, 0xBF, 0xD0, 0xF7,
+ 0x05, 0xCD, 0x02, 0x63, 0xB4,
+ 0x09, 0xF3, 0x62, 0xB2, 0x73,
+ 0x05, 0x71, 0x31, 0x06, 0x4A,
+ 0x06, 0x13, 0x95, 0x77, 0x3F,
+ 0x07, 0x22, 0x85, 0x7F, 0xF9,
+ 0x0D, 0x35, 0x84, 0xD8, 0xCC,
+ 0x0C, 0x31, 0x5C, 0xAF, 0xF8,
+ 0x0A, 0xD6, 0x59, 0xE3, 0xEE,
+ 0x03, 0x5B, 0x76, 0x05, 0x42,
+ 0x0C, 0x92, 0x75, 0xE8, 0x1C,
+ 0x07, 0x74, 0x5E, 0xBA, 0x49,
+ 0x02, 0x61, 0xB6, 0x66, 0x87,
+ 0x08, 0x7F, 0xC3, 0xFF, 0x82,
+ 0x09, 0x04, 0xA7, 0x5E, 0x79,
+ 0x0E, 0xC5, 0xC8, 0xF3, 0xEA,
+ 0x0A, 0xE2, 0x80, 0x30, 0x0C,
+ 0x03, 0x2A, 0xC3, 0x6A, 0xEE,
+ 0x01, 0x0A, 0xD3, 0xD6, 0xC9,
+ 0x0B, 0xCB, 0xA9, 0xA8, 0x8C,
+ 0x01, 0x98, 0x7F, 0xE1, 0xE3,
+ 0x0C, 0xB2, 0x47, 0xD3, 0x1B,
+ 0x06, 0x6D, 0xB2, 0xBE, 0xAA,
+ 0x05, 0x2B, 0xCB, 0xB8, 0x1C,
+ 0x0B, 0x3D, 0x75, 0x14, 0x19,
+ 0x00, 0xF6, 0xCD, 0x08, 0xB0,
+ 0x0F, 0x83, 0x5F, 0x17, 0x32,
+ 0x09, 0xCE, 0x71, 0xE7, 0xCD,
+ 0x03, 0x13, 0xA6, 0xD9, 0xC4,
+ 0x04, 0x40, 0x21, 0x0E, 0x4C,
+ 0x05, 0x86, 0xF6, 0xCA, 0xC8,
+ 0x0F, 0xA4, 0x31, 0x92, 0xCF,
+ 0x03, 0x53, 0x32, 0x38, 0xC3,
+ 0x0C, 0xBF, 0x22, 0xE7, 0xD9,
+ 0x03, 0x8F, 0xBA, 0x3D, 0xED,
+ 0x0C, 0x2D, 0x7D, 0x54, 0x8A,
+ 0x07, 0x95, 0x70, 0x39, 0xD2,
+ 0x0A, 0xEB, 0xA4, 0x3D, 0x98,
+ 0x0D, 0x9A, 0x19, 0xE1, 0xFF,
+ 0x07, 0xBE, 0x2E, 0x64, 0x12,
+ 0x0F, 0xA3, 0xCD, 0x9D, 0x15,
+ 0x03, 0x8D, 0xAB, 0x89, 0x88,
+ 0x00, 0x42, 0xB0, 0x9C, 0xAB,
+ 0x0D, 0xE9, 0xB9, 0x14, 0x2B,
+ 0x0F, 0xD9, 0x25, 0xBF, 0x26,
+ 0x0D, 0x60, 0x31, 0x92, 0x6B,
+ 0x06, 0xD5, 0x6E, 0xBF, 0x0F,
+ 0x01, 0xF4, 0xD7, 0xDB, 0xB0,
+ 0x0A, 0xFA, 0xA8, 0x0A, 0xB2,
+ 0x0E, 0xE0, 0x73, 0x84, 0xF5,
+ 0x06, 0x48, 0x67, 0x1B, 0x5B,
+ 0x06, 0x3B, 0xC3, 0xFE, 0x8F,
+ 0x0E, 0x54, 0x48, 0x25, 0xBB,
+ 0x05, 0x17, 0x96, 0x1A, 0xC7,
+ 0x0B, 0x5D, 0x13, 0x01, 0x00,
+ 0x04, 0xEB, 0x19, 0x56, 0x1B,
+ 0x0B, 0x73, 0xA8, 0x56, 0x1F,
+ 0x0A, 0xCA, 0xDE, 0x4D, 0xCC,
+ 0x09, 0xE1, 0x48, 0xEE, 0xFE,
+ 0x0B, 0x1D, 0x65, 0x88, 0x3C,
+ 0x08, 0x35, 0xB7, 0x46, 0xF7,
+ 0x0F, 0x53, 0xC7, 0xDE, 0x4D,
+ 0x00, 0xE7, 0x49, 0xC5, 0xB5,
+ 0x00, 0xCE, 0x17, 0xB6, 0x68,
+ 0x05, 0x87, 0xFC, 0x1E, 0x78,
+ 0x0B, 0x90, 0x4A, 0x76, 0x0F,
+ 0x0E, 0x64, 0xD4, 0x8E, 0x36,
+ 0x0E, 0x2C, 0x22, 0x01, 0x08,
+ 0x0A, 0x73, 0x2C, 0x37, 0x26,
+ 0x04, 0x50, 0xAD, 0x3F, 0x64,
+ 0x06, 0xFC, 0x9A, 0x99, 0x80,
+ 0x06, 0x51, 0xA5, 0xDB, 0x14,
+ 0x01, 0xCB, 0x3C, 0x7D, 0xD0,
+ 0x02, 0x6E, 0x01, 0x65, 0xF7,
+ 0x08, 0x52, 0x38, 0xB7, 0x41,
+ 0x06, 0x13, 0x73, 0x51, 0xDB,
+ 0x05, 0xAD, 0x6C, 0xD0, 0x1E,
+ 0x05, 0xFC, 0x2D, 0xF1, 0x77,
+ 0x09, 0x16, 0xED, 0x1E, 0x8E,
+ 0x08, 0xA9, 0x1E, 0x63, 0x15,
+ 0x06, 0x40, 0x0E, 0x11, 0x8C,
+ 0x0C, 0xD8, 0x8F, 0x4F, 0x48,
+ 0x0B, 0x5E, 0x73, 0xC9, 0x3D,
+ 0x00, 0xB7, 0x37, 0x0D, 0x0C,
+ 0x09, 0x4F, 0xF8, 0x2C, 0x77,
+ 0x0E, 0x78, 0x7B, 0xAC, 0x56,
+ 0x04, 0x00, 0xD3, 0xD9, 0x00,
+ 0x0F, 0x7D, 0x74, 0x83, 0x95,
+ 0x0F, 0xAE, 0x22, 0x4F, 0x78,
+ 0x06, 0xDB, 0xA5, 0xD2, 0x9F,
+ 0x0C, 0x7B, 0xE1, 0xE6, 0x42,
+ 0x00, 0xDB, 0xF8, 0xF9, 0xF1,
+ 0x00, 0x38, 0xDE, 0xBE, 0x98,
+ 0x0A, 0x04, 0x23, 0x0F, 0xCA,
+ 0x00, 0xAE, 0x1B, 0x95, 0xF9,
+ 0x05, 0x0D, 0x72, 0x56, 0xB6,
+ 0x0A, 0x66, 0x03, 0x84, 0xC3,
+ 0x07, 0xF4, 0x58, 0x6D, 0x26,
+ 0x01, 0xF7, 0x43, 0xAB, 0x71,
+ 0x0E, 0x2B, 0xC2, 0x01, 0x4A,
+ 0x0A, 0x6E, 0xA7, 0x34, 0xCF,
+ 0x04, 0x44, 0x46, 0x7E, 0x7D,
+ 0x08, 0xC7, 0xD4, 0xBF, 0xE0,
+ 0x0E, 0xC5, 0x0C, 0x8C, 0x4E,
+ 0x04, 0x79, 0xF5, 0x6C, 0xED,
+ 0x09, 0xB5, 0xF5, 0x3D, 0xD0,
+ 0x01, 0xC6, 0xF3, 0x97, 0xE1,
+ 0x07, 0x33, 0x2F, 0x05, 0x6B,
+ 0x02, 0xA6, 0xD7, 0xE8, 0xD4,
+ 0x04, 0x84, 0x36, 0x8D, 0xEF,
+ 0x02, 0xB5, 0xD9, 0x59, 0xE7,
+ 0x07, 0x03, 0xBB, 0x76, 0xCB,
+ 0x03, 0x5D, 0x02, 0x95, 0xD7,
+ 0x0C, 0x0E, 0x7A, 0x9A, 0x70,
+ 0x01, 0x8C, 0x45, 0x76, 0x26,
+ 0x0F, 0xB1, 0xDB, 0xCC, 0x2F,
+ 0x03, 0x9B, 0x04, 0xAB, 0x28,
+ 0x09, 0xE2, 0xD3, 0x48, 0xEB,
+ 0x06, 0xF2, 0x62, 0x20, 0x22,
+ 0x0C, 0x27, 0x2A, 0xC7, 0x3E,
+ 0x07, 0x8D, 0xEA, 0xD3, 0x36,
+ 0x01, 0x6E, 0x29, 0xA4, 0x18,
+ 0x06, 0x85, 0x1B, 0xD7, 0xF8,
+ 0x03, 0xAC, 0xB3, 0xDB, 0x5F,
+ 0x06, 0xB6, 0xEC, 0x12, 0xBA,
+ 0x00, 0x01, 0x0C, 0xCB, 0xB9,
+ 0x05, 0xB0, 0xFD, 0x79, 0x12,
+ 0x00, 0x42, 0x16, 0xCD, 0xCE,
+ 0x08, 0xFE, 0x63, 0xD2, 0x92,
+ 0x02, 0x09, 0x4E, 0xD5, 0x5C,
+ 0x0D, 0x8A, 0x91, 0xC2, 0xD1,
+ 0x04, 0xC4, 0x40, 0x25, 0x69,
+ 0x00, 0xD5, 0x4B, 0xF4, 0xDC,
+ 0x06, 0x33, 0xA7, 0xEC, 0x85,
+ 0x0F, 0x93, 0x53, 0x3E, 0xC5,
+ 0x02, 0x64, 0x3F, 0x82, 0x47,
+ 0x01, 0x4E, 0x0F, 0x9A, 0xCD,
+ 0x04, 0xE0, 0xE9, 0x7D, 0x94,
+ 0x03, 0x56, 0x57, 0x70, 0xB9,
+ 0x02, 0x7A, 0xEA, 0x27, 0x30,
+ 0x05, 0xED, 0x9A, 0x1B, 0xFA,
+ 0x0F, 0x07, 0xBE, 0x29, 0xFE,
+ 0x02, 0x9D, 0xA3, 0xC3, 0xDF,
+ 0x0D, 0x6B, 0x0D, 0xA7, 0x09,
+ 0x00, 0x02, 0x26, 0x30, 0x5C,
+ 0x01, 0x09, 0xCD, 0x39, 0x04,
+ 0x01, 0x8F, 0xDE, 0xAD, 0xFE,
+ 0x0E, 0xA6, 0xE0, 0x30, 0x14,
+ 0x02, 0xFD, 0xEF, 0x8E, 0xB2,
+ 0x07, 0x9D, 0x70, 0x1A, 0x2A,
+ 0x0A, 0x5E, 0xD9, 0xA8, 0x1C,
+ 0x07, 0x2E, 0x60, 0x7F, 0xE4,
+ 0x0D, 0x56, 0x4C, 0x67, 0xFA,
+ 0x01, 0x30, 0x1F, 0x43, 0xFC,
+ 0x07, 0x7C, 0xDC, 0xC4, 0x65,
+ 0x02, 0xC5, 0xFF, 0x3A, 0x2A,
+ 0x07, 0x1B, 0x57, 0x07, 0x13,
+ 0x00, 0x84, 0x61, 0x3A, 0x67,
+ 0x0B, 0xD3, 0x72, 0x28, 0x12,
+ 0x05, 0xB6, 0x52, 0x7E, 0x5D,
+ 0x00, 0xC0, 0x66, 0xA8, 0xD1,
+ 0x0E, 0x8B, 0x1D, 0x66, 0x9B,
+ 0x0E, 0xE8, 0x35, 0xBA, 0x24,
+ 0x0D, 0x75, 0xF0, 0x27, 0xDE,
+ 0x04, 0xC0, 0x27, 0x47, 0xEB,
+ 0x01, 0x91, 0x0E, 0x17, 0xF6,
+ 0x04, 0x77, 0x86, 0xBC, 0x2F,
+ 0x03, 0x3B, 0xDA, 0xCE, 0xCD,
+ 0x07, 0xBE, 0xCC, 0x5A, 0x0E,
+ 0x0F, 0xAE, 0xE6, 0x2C, 0xC1,
+ 0x08, 0xC2, 0x72, 0xAF, 0x05,
+ 0x0D, 0x66, 0x1A, 0x2E, 0x4C,
+ 0x08, 0x96, 0xFE, 0x9A, 0x97,
+ 0x0C, 0xC6, 0x52, 0xA5, 0xFE,
+ 0x0F, 0xBA, 0x2B, 0x32, 0x60,
+ 0x09, 0xEA, 0x9A, 0xC1, 0x2B,
+ 0x0A, 0xA0, 0x52, 0xB0, 0x3E,
+ 0x01, 0xCE, 0x93, 0xD7, 0xA0,
+ 0x01, 0x9C, 0x2F, 0x68, 0x0D,
+ 0x0F, 0x0F, 0xFC, 0x39, 0x03,
+ 0x0B, 0xA0, 0x34, 0xED, 0xDE,
+ 0x05, 0x58, 0x49, 0x1C, 0xAD,
+ 0x07, 0xC8, 0x0C, 0x02, 0x11,
+ 0x04, 0xE5, 0x5A, 0x69, 0x47,
+ 0x08, 0xA1, 0x5A, 0x7A, 0x70,
+ 0x04, 0x7B, 0x55, 0x3F, 0x01,
+ 0x06, 0xA7, 0x79, 0xFA, 0x3C,
+ 0x0C, 0x16, 0x98, 0xE7, 0x3D,
+ 0x0E, 0x5F, 0xA6, 0xDB, 0xD5,
+ 0x0A, 0xA1, 0x48, 0xF7, 0x13,
+ 0x06, 0xA3, 0xCA, 0x22, 0x43,
+ 0x02, 0x5A, 0xE9, 0xA1, 0xCE,
+ 0x06, 0xF2, 0x3B, 0xEF, 0x26,
+ 0x01, 0x29, 0xDA, 0x3F, 0xBD,
+ 0x01, 0x52, 0x38, 0xDE, 0x01,
+ 0x08, 0x88, 0x04, 0x2F, 0xCC,
+ 0x06, 0xB0, 0xDF, 0x5B, 0x9F,
+ 0x0E, 0xB4, 0xFF, 0x12, 0x58,
+ 0x0E, 0x6A, 0x65, 0x03, 0x1A,
+ 0x0F, 0x17, 0x14, 0x56, 0xF6,
+ 0x05, 0x70, 0x17, 0x41, 0xED,
+ 0x03, 0x84, 0x4F, 0xAA, 0xC1,
+ 0x0A, 0xF2, 0xFA, 0x07, 0xC0,
+ 0x0F, 0x5D, 0x44, 0x82, 0x0B,
+ 0x0D, 0xB3, 0x43, 0xBC, 0xCC,
+ 0x00, 0xF7, 0xC5, 0xC8, 0x5F,
+ 0x03, 0xB4, 0x7D, 0xF7, 0x90,
+ 0x0C, 0xF1, 0x15, 0x71, 0xF1,
+ 0x09, 0x88, 0xA6, 0x13, 0x55,
+ 0x0A, 0x39, 0x7F, 0x22, 0x85,
+ 0x0D, 0xFB, 0x24, 0xB1, 0xE4,
+ 0x04, 0xCC, 0x06, 0x32, 0x8D,
+ 0x0E, 0xE8, 0x71, 0xD2, 0xE0,
+ 0x0B, 0xD4, 0xC3, 0x57, 0xB6,
+ 0x01, 0x5B, 0x16, 0x82, 0x9D,
+ 0x0C, 0xE4, 0xCE, 0x78, 0x5E,
+ 0x0A, 0x89, 0x0C, 0xE1, 0x7B,
+ 0x0F, 0x05, 0x18, 0x73, 0xC1,
+ 0x0F, 0x8B, 0x9B, 0x02, 0x2D,
+ 0x02, 0xF7, 0xD9, 0x45, 0x58,
+ 0x0A, 0xEA, 0x02, 0x7E, 0xBD,
+ 0x08, 0x0E, 0x03, 0x26, 0xC3,
+ 0x00, 0x6A, 0x7A, 0x0A, 0xC3,
+ 0x0D, 0xCD, 0x0B, 0x49, 0xA9,
+ 0x02, 0x08, 0x58, 0x9A, 0x4F,
+ 0x0A, 0x63, 0xAC, 0xB3, 0xC7,
+ 0x03, 0x86, 0x7B, 0xEC, 0x16,
+ 0x06, 0xAF, 0x85, 0x26, 0x18,
+ 0x08, 0x1C, 0xE9, 0x33, 0xA8,
+ 0x02, 0x19, 0xC6, 0xD2, 0xD9,
+ 0x0E, 0xF0, 0xF9, 0xD3, 0xD6,
+ 0x07, 0x32, 0x0D, 0x4E, 0x5B,
+ 0x03, 0xCD, 0x88, 0x91, 0x46,
+ 0x0D, 0xFC, 0x44, 0x4C, 0x61,
+ 0x08, 0x07, 0xD5, 0x86, 0xF4,
+ 0x00, 0x8A, 0x35, 0xA7, 0xEF,
+ 0x0B, 0xDD, 0x93, 0x53, 0x70,
+ 0x02, 0xCE, 0x7B, 0x3F, 0xAA,
+ 0x0B, 0x59, 0x67, 0x8F, 0xAD,
+ 0x05, 0x1D, 0x58, 0x2B, 0x7D,
+ 0x0E, 0x0E, 0x05, 0x17, 0x71,
+ 0x05, 0xE2, 0x7A, 0xEA, 0x27,
+ 0x03, 0x85, 0xED, 0x9E, 0x16,
+ 0x08, 0xFF, 0xC7, 0xBF, 0xF9,
+ 0x0D, 0x13, 0x5D, 0xA3, 0x8F,
+ 0x03, 0x3D, 0xA3, 0x8B, 0xAB,
+ 0x09, 0x88, 0x80, 0x46, 0xA7,
+ 0x05, 0x93, 0xCD, 0xE5, 0xFA,
+ 0x04, 0x2B, 0x4F, 0xD9, 0x25,
+ 0x0F, 0x26, 0xA6, 0x60, 0x31,
+ 0x0D, 0x41, 0xBF, 0x43, 0x0E,
+ 0x0B, 0xE6, 0xDF, 0x34, 0x9A,
+ 0x09, 0xB0, 0x5E, 0xD7, 0xA8,
+ 0x04, 0xAF, 0x2E, 0xD6, 0x68,
+ 0x04, 0xAD, 0x54, 0x4F, 0xFD,
+ 0x02, 0xD9, 0x34, 0x3B, 0x03,
+ 0x0E, 0x0F, 0x7C, 0x5C, 0xC8,
+ 0x03, 0x3B, 0x47, 0x9B, 0xB6,
+ 0x0A, 0x47, 0x1B, 0x57, 0x13,
+ 0x01, 0xF0, 0x24, 0x65, 0x7A,
+ 0x0C, 0xDB, 0xD4, 0xFA, 0x9B,
+ 0x0F, 0x9F, 0x72, 0x4A, 0xFE,
+ 0x05, 0x4E, 0x80, 0x65, 0x19,
+ 0x08, 0xFA, 0xD0, 0x9D, 0x67,
+ 0x07, 0x3E, 0x28, 0x39, 0xF7,
+ 0x08, 0xB7, 0xB1, 0x50, 0xD8,
+ 0x04, 0x59, 0x9D, 0xE7, 0x41,
+ 0x02, 0xA8, 0x50, 0xC2, 0x57,
+ 0x0F, 0x6A, 0x37, 0x8B, 0xBC,
+ 0x0E, 0xF8, 0xB9, 0x90, 0x4A,
+ 0x00, 0x8F, 0x3E, 0x68, 0xD4,
+ 0x0E, 0x36, 0xAE, 0x26, 0x22,
+ 0x00, 0x78, 0x02, 0x72, 0xAC,
+ 0x07, 0xA6, 0xE4, 0x50, 0xAD,
+ 0x0F, 0x64, 0x96, 0xFA, 0xC1,
+ 0x09, 0x80, 0xC6, 0x56, 0x3F,
+ 0x07, 0xD6, 0x30, 0xC3, 0xFF,
+ 0x05, 0xD0, 0xEB, 0x6F, 0x41,
+ 0x00, 0x68, 0x0A, 0x52, 0xBC,
+ 0x02, 0x81, 0x0C, 0x9D, 0x9E,
+ 0x08, 0x20, 0x5C, 0xA3, 0x6C,
+ 0x08, 0x6F, 0xAF, 0xF8, 0x7D,
+ 0x0A, 0x73, 0x20, 0x94, 0x9C,
+ 0x02, 0x7C, 0xD9, 0xE9, 0x1F,
+ 0x04, 0x95, 0xAC, 0x48, 0x02,
+ 0x09, 0x04, 0x45, 0x56, 0xAF,
+ 0x05, 0xC8, 0x21, 0x54, 0xFE,
+ 0x01, 0xAC, 0x59, 0x35, 0x73,
+ 0x09, 0x8E, 0xA3, 0x47, 0xFA,
+ 0x0C, 0x75, 0x96, 0x7C, 0x80,
+ 0x0B, 0xD6, 0xDD, 0x86, 0xED,
+ 0x05, 0x40, 0xA5, 0x7D, 0xEA,
+ 0x0A, 0xD4, 0xE3, 0xA2, 0xA2,
+ 0x0B, 0x38, 0xDA, 0xD9, 0x61,
+ 0x0E, 0x1F, 0xF0, 0x7B, 0x10,
+ 0x08, 0xC1, 0xE4, 0xDA, 0x3C,
+ 0x00, 0x31, 0xB2, 0x08, 0xDA,
+ 0x02, 0x78, 0x91, 0x0C, 0xF9,
+ 0x09, 0xCA, 0xB0, 0xCE, 0x9B,
+ 0x01, 0x42, 0xB4, 0xFD, 0x92,
+ 0x02, 0x73, 0x8A, 0x66, 0x83,
+ 0x09, 0x46, 0x95, 0xDA, 0x11,
+ 0x0B, 0x2C, 0xF1, 0xF7, 0x41,
+ 0x0D, 0xBB, 0x05, 0xAF, 0xAA,
+ 0x08, 0xC8, 0x92, 0x6E, 0x87,
+ 0x00, 0x4B, 0x2C, 0x44, 0x82,
+ 0x00, 0xBD, 0xB3, 0xC3, 0xBC,
+ 0x0F, 0xE0, 0xF4, 0x45, 0xCC,
+ 0x06, 0x53, 0xB6, 0x7F, 0x33,
+ 0x0B, 0x24, 0x91, 0xB5, 0xF1,
+ 0x00, 0x91, 0xE8, 0x46, 0x13,
+ 0x05, 0x61, 0xBD, 0x37, 0x22,
+ 0x0D, 0x6B, 0xFB, 0x28, 0xB7,
+ 0x04, 0xD4, 0xCC, 0x20, 0xF0,
+ 0x07, 0x2B, 0x82, 0x31, 0xC6,
+ 0x01, 0x61, 0xCE, 0x8F, 0x5B,
+ 0x0C, 0x0F, 0x37, 0xD5, 0x12,
+ 0x0E, 0xE5, 0xDC, 0x0E, 0x74,
+ 0x02, 0xBA, 0x8A, 0x0C, 0xE2,
+ 0x02, 0x66, 0x47, 0x76, 0x62,
+ 0x08, 0xEE, 0x4F, 0x99, 0x44,
+ 0x0F, 0xE8, 0x57, 0xE6, 0x3F,
+ 0x00, 0xE3, 0xEE, 0xEC, 0x22,
+ 0x09, 0x92, 0x8C, 0x27, 0xDB,
+ 0x03, 0x7A, 0x6C, 0x48, 0x43,
+ 0x09, 0xF2, 0xC2, 0x6F, 0xC1,
+ 0x00, 0x18, 0xEC, 0x67, 0x9A,
+ 0x05, 0xD5, 0xEF, 0xAC, 0xA3,
+ 0x0E, 0x5F, 0x06, 0x36, 0x1E,
+ 0x0C, 0xBA, 0xD6, 0x85, 0x23,
+ 0x03, 0xB8, 0x9C, 0xE5, 0xBD,
+ 0x0C, 0x90, 0x19, 0xCE, 0xB6,
+ 0x07, 0x0A, 0x8E, 0xFF, 0x81,
+ 0x07, 0x17, 0xB2, 0x05, 0x0E,
+ 0x08, 0x65, 0xCD, 0x86, 0xD1,
+ 0x06, 0xD5, 0xC4, 0xC0, 0xFB,
+ 0x0D, 0x18, 0x4F, 0x95, 0xB7,
+ 0x04, 0xDC, 0x88, 0x13, 0x6D,
+ 0x0C, 0x92, 0xDF, 0x9F, 0x97,
+ 0x0B, 0x9A, 0x80, 0xB9, 0xBA,
+ 0x0A, 0x47, 0xF9, 0x69, 0x0F,
+ 0x03, 0x0D, 0xAD, 0xD6, 0xED,
+ 0x06, 0xD6, 0x40, 0xDA, 0xE1,
+ 0x00, 0x39, 0xD0, 0x77, 0xA3,
+ 0x04, 0x33, 0x85, 0x63, 0x87,
+ 0x01, 0xE1, 0xFE, 0x47, 0xB0,
+ 0x08, 0x64, 0x04, 0x9F, 0x23,
+ 0x03, 0x91, 0x15, 0x23, 0x94,
+ 0x0A, 0x21, 0x68, 0x80, 0x42,
+ 0x08, 0x9C, 0x2B, 0x00, 0xEC,
+ 0x01, 0x15, 0xAB, 0x42, 0x19,
+ 0x07, 0xBF, 0x26, 0xA0, 0xA0,
+ 0x01, 0x94, 0x69, 0x7B, 0x41,
+ 0x0F, 0x32, 0x2F, 0x1F, 0x74,
+ 0x02, 0x5B, 0x10, 0x54, 0x7A,
+ 0x01, 0x14, 0x6F, 0x20, 0x20,
+ 0x08, 0x20, 0x5A, 0x52, 0xB2,
+ 0x07, 0x0B, 0xDF, 0x34, 0xCA,
+ 0x03, 0xFE, 0x0D, 0x71, 0x15,
+ 0x00, 0x25, 0xBB, 0x49, 0xDF,
+ 0x0F, 0xAA, 0xA7, 0x19, 0xD7,
+ 0x09, 0x15, 0x8C, 0x04, 0x63,
+ 0x00, 0xD4, 0x7B, 0xDF, 0x72,
+ 0x01, 0x54, 0x9B, 0xBE, 0x0B,
+ 0x04, 0x49, 0xC2, 0xC0, 0x67,
+ 0x01, 0x52, 0x1E, 0x8B, 0xDD,
+ 0x09, 0x9E, 0x3D, 0xE8, 0x36,
+ 0x07, 0x60, 0xB7, 0xF1, 0x9A,
+ 0x00, 0x5E, 0x9D, 0xCE, 0xFA,
+ 0x00, 0xEA, 0x68, 0x90, 0x8E,
+ 0x0F, 0x36, 0xC8, 0x77, 0x47,
+ 0x04, 0x1E, 0x78, 0xB5, 0x50,
+ 0x03, 0xF6, 0x6F, 0x33, 0x6C,
+ 0x0C, 0x8F, 0xB6, 0xA3, 0xE6,
+ 0x0B, 0x80, 0xE8, 0xCF, 0xB2,
+ 0x0C, 0x37, 0xA6, 0xE0, 0x54,
+ 0x0D, 0x3F, 0x64, 0x92, 0x39,
+ 0x06, 0x99, 0x81, 0x06, 0x60,
+ 0x05, 0xFD, 0x16, 0x3E, 0x56,
+ 0x0C, 0x7D, 0xD0, 0x6F, 0xD5,
+ 0x09, 0x6B, 0x6A, 0xA0, 0x92,
+ 0x02, 0x3B, 0x4C, 0xCE, 0x93,
+ 0x0E, 0x51, 0xE3, 0x91, 0x66,
+ 0x05, 0xD1, 0x2E, 0x23, 0xF8,
+ 0x01, 0xF1, 0x71, 0x60, 0x9A,
+ 0x09, 0x1E, 0x7C, 0xD8, 0x29,
+ 0x08, 0x6D, 0x5E, 0x4C, 0xC4,
+ 0x03, 0xF1, 0x64, 0xEB, 0x45,
+ 0x0E, 0x2D, 0x1C, 0xA5, 0xEF,
+ 0x02, 0xC9, 0x2C, 0xB9, 0x3B,
+ 0x03, 0x01, 0x84, 0xAD, 0x95,
+ 0x08, 0x2C, 0x61, 0x90, 0xF8,
+ 0x0B, 0xA0, 0xD6, 0xD0, 0x51,
+ 0x06, 0x57, 0x20, 0xE6, 0x3A,
+ 0x0D, 0x07, 0x00, 0x27, 0xA6,
+ 0x0B, 0xC3, 0xD8, 0x5E, 0xD9,
+ 0x08, 0xDC, 0x7F, 0xF0, 0xFB,
+ 0x08, 0xE2, 0xDE, 0x29, 0xD2,
+ 0x0C, 0xF9, 0xB5, 0x52, 0x38,
+ 0x0A, 0xB8, 0x94, 0x88, 0x04,
+ 0x01, 0x09, 0xC2, 0xB6, 0x5E,
+ 0x02, 0x91, 0x82, 0xB4, 0x7D,
+ 0x03, 0x5A, 0x32, 0x6A, 0x66,
+ 0x0B, 0x1B, 0x46, 0x9B, 0xF4,
+ 0x08, 0xEB, 0x2C, 0xF1, 0xB2,
+ 0x01, 0xAD, 0xBB, 0x23, 0x2D,
+ 0x00, 0x85, 0xDF, 0x72, 0xFE,
+ 0x0E, 0x3A, 0x8F, 0x53, 0x84,
+ 0x0F, 0x71, 0x7D, 0xBF, 0x03,
+ 0x04, 0xBD, 0xC0, 0xFB, 0xC5,
+ 0x06, 0x86, 0xC7, 0xB4, 0x69,
+ 0x03, 0x62, 0xA4, 0x7D, 0x71,
+ 0x09, 0x31, 0x90, 0x45, 0x86,
+ 0x03, 0x95, 0x61, 0xBD, 0x35,
+ 0x0C, 0x05, 0xA4, 0xFB, 0x24,
+ 0x0B, 0xE4, 0xD6, 0x4C, 0x08,
+ 0x0B, 0xC0, 0xEF, 0xC5, 0x62,
+ 0x06, 0x59, 0xE3, 0xF0, 0x9E,
+ 0x0B, 0x76, 0x0B, 0x4B, 0xC1,
+ 0x0B, 0x85, 0x25, 0xEC, 0x8E,
+ 0x0D, 0x9F, 0x7A, 0xD9, 0x8C,
+ 0x08, 0x6A, 0xB2, 0xB7, 0xF8,
+ 0x0F, 0xC1, 0xEB, 0xCB, 0x99,
+ 0x06, 0xA7, 0x6C, 0xB3, 0x66,
+ 0x07, 0x48, 0xE3, 0x4C, 0x62,
+ 0x03, 0x20, 0xD0, 0x8C, 0x27,
+ 0x0B, 0xA2, 0xBA, 0x6E, 0x45,
+ 0x02, 0xD1, 0xF6, 0x45, 0x6F,
+ 0x01, 0x63, 0x98, 0x00, 0x65,
+ 0x0A, 0x5F, 0xD1, 0x65, 0x2E,
+ 0x09, 0xC3, 0x7B, 0x06, 0xA6,
+ 0x0C, 0x16, 0xBE, 0xBA, 0x05,
+ 0x00, 0xCB, 0xB8, 0x1C, 0xEB,
+ 0x0D, 0x75, 0x12, 0x1D, 0x5F,
+ 0x0A, 0xCF, 0x0E, 0xF0, 0xC4,
+ 0x0B, 0xDF, 0x97, 0x32, 0xC9,
+ 0x00, 0x51, 0x2A, 0xCD, 0x8A,
+ 0x0D, 0xC6, 0xD4, 0x44, 0xCA,
+ 0x00, 0x21, 0x18, 0x40, 0x48,
+ 0x06, 0xF4, 0xC8, 0x8E, 0x8B,
+ 0x07, 0xEC, 0x92, 0xDB, 0x10,
+ 0x0A, 0x30, 0xD8, 0xEA, 0xB4,
+ 0x06, 0x9B, 0x07, 0x59, 0xA7,
+ 0x06, 0x38, 0x4D, 0x63, 0x18,
+ 0x07, 0x79, 0xE3, 0x0A, 0x5F,
+ 0x0B, 0x70, 0x39, 0xD2, 0x6D,
+ 0x03, 0x44, 0xF3, 0x83, 0x6D,
+ 0x00, 0x19, 0x5B, 0xFF, 0x06,
+ 0x02, 0x16, 0x64, 0x12, 0x9E,
+ 0x03, 0xCF, 0x9B, 0x11, 0xA8,
+ 0x04, 0x2B, 0x69, 0x89, 0x57,
+ 0x0B, 0xB1, 0x7C, 0xAB, 0x4D,
+ 0x00, 0x91, 0xD4, 0x2D, 0xCF,
+ 0x09, 0x25, 0xBF, 0x22, 0x71,
+ 0x09, 0x89, 0x7C, 0x69, 0xBF,
+ 0x05, 0x8E, 0xB2, 0xCB, 0x5C,
+ 0x0C, 0x9A, 0x79, 0xBD, 0xD3,
+ 0x03, 0x00, 0xF4, 0x29, 0xEE,
+ 0x09, 0xDA, 0x44, 0x55, 0x54,
+ 0x00, 0xE6, 0xAF, 0xD7, 0x34,
+ 0x0B, 0xC3, 0xFA, 0x09, 0xE7,
+ 0x0C, 0xC8, 0x21, 0x3C, 0x9D,
+ 0x05, 0xF6, 0x20, 0x4E, 0x66,
+ 0x0E, 0x13, 0xD1, 0x01, 0x04,
+ 0x08, 0xBB, 0x12, 0x1B, 0x21,
+ 0x08, 0x2C, 0x96, 0x1F, 0xB0,
+ 0x02, 0x7E, 0x8D, 0x40, 0x40,
+ 0x0A, 0xAA, 0x9A, 0xFE, 0x79,
+ 0x07, 0x61, 0x5C, 0x3E, 0xE0,
+ 0x0C, 0xB7, 0xA0, 0xB9, 0x75,
+ 0x09, 0x2B, 0x1E, 0x5F, 0x40,
+ 0x0D, 0x4D, 0x2F, 0xA8, 0x98,
+ 0x0E, 0x17, 0xB2, 0x68, 0x77,
+ 0x07, 0xFC, 0x12, 0xF8, 0xB9,
+ 0x02, 0x4A, 0x7A, 0x89, 0xBE,
+ 0x05, 0xD4, 0x62, 0x34, 0x2E,
+ 0x07, 0x22, 0xCD, 0x06, 0x48,
+ 0x02, 0xAC, 0x3B, 0xA2, 0x92,
+ 0x08, 0x2D, 0x93, 0x64, 0xD6,
+ 0x08, 0x9A, 0x99, 0x86, 0x46,
+ 0x0D, 0xAF, 0xFD, 0x16, 0x23,
+ 0x0A, 0x95, 0x9D, 0xD0, 0x6B,
+ 0x07, 0xC1, 0xAB, 0xEA, 0xE0,
+ 0x0A, 0xBE, 0xBB, 0x8D, 0xCE,
+ 0x03, 0xD7, 0x53, 0x27, 0x56,
+ 0x05, 0x68, 0x61, 0xEF, 0x1F,
+ 0x01, 0x3C, 0x31, 0x7F, 0x60,
+ 0x0C, 0x6F, 0x3E, 0x70, 0xD8,
+ 0x03, 0x18, 0xC2, 0xDC, 0x5C,
+ 0x0F, 0x02, 0x11, 0x84, 0xE5,
+ 0x00, 0x6F, 0xCD, 0xC6, 0xBC,
+ 0x02, 0x27, 0x4D, 0x21, 0xE8,
+ 0x0D, 0xB0, 0x27, 0x81, 0xAA,
+ 0x0B, 0xFA, 0x2A, 0x75, 0x9C,
+ 0x08, 0xFB, 0xA4, 0xD2, 0xA9,
+ 0x02, 0xD7, 0xD1, 0x4C, 0x61,
+ 0x09, 0x77, 0x03, 0xB1, 0xA2,
+ 0x0E, 0xA2, 0x43, 0x18, 0xA4,
+ 0x09, 0xA1, 0xDE, 0x1B, 0xED,
+ 0x0B, 0xE2, 0xE6, 0x45, 0x12,
+ 0x03, 0xBC, 0x19, 0xB1, 0x92,
+ 0x06, 0x5A, 0x75, 0x98, 0x88,
+ 0x04, 0x23, 0x0B, 0xE4, 0xAD,
+ 0x06, 0x9B, 0x91, 0x4C, 0x6A,
+ 0x05, 0x2A, 0xFF, 0xF2, 0xAA,
+ 0x0E, 0x82, 0xB9, 0x66, 0x17,
+ 0x04, 0x58, 0xEB, 0x2C, 0xF1,
+ 0x0F, 0x41, 0x29, 0xB6, 0xC5,
+ 0x0D, 0xAA, 0x89, 0x4C, 0xB2,
+ 0x0C, 0x07, 0x3E, 0x49, 0x1D,
+ 0x04, 0x4E, 0xD8, 0xBD, 0xBA,
+ 0x02, 0xF4, 0xF7, 0xE0, 0x3D,
+ 0x0D, 0xCE, 0x82, 0x53, 0x74,
+ 0x03, 0xF7, 0xBB, 0xA4, 0x75,
+ 0x0D, 0xF1, 0x91, 0x16, 0x88,
+ 0x06, 0x13, 0x95, 0x61, 0x77,
+ 0x07, 0x22, 0x81, 0x5A, 0xF8,
+ 0x04, 0xB7, 0xE4, 0xD4, 0xCC,
+ 0x04, 0x32, 0x85, 0x29, 0xA8,
+ 0x01, 0xD6, 0x59, 0xE3, 0xEE,
+ 0x03, 0xBB, 0xD6, 0x0B, 0x5F,
+ 0x05, 0x02, 0x95, 0xE5, 0xDC,
+ 0x0E, 0x74, 0x9E, 0xBA, 0x89,
+ 0x0E, 0xE1, 0x73, 0x60, 0xC7,
+ 0x01, 0x7F, 0x01, 0xEF, 0x0B,
+ 0x09, 0x24, 0x27, 0x65, 0xB7,
+ 0x06, 0xC5, 0x48, 0xF3, 0x6A,
+ 0x0B, 0x60, 0x60, 0x16, 0xCC,
+ 0x0F, 0x28, 0x83, 0x7C, 0x5C,
+ 0x0F, 0x0E, 0x32, 0xF6, 0x59,
+ 0x06, 0xC9, 0x69, 0x94, 0x8C,
+ 0x05, 0x1A, 0x5F, 0xD1, 0x63,
+ 0x0E, 0xB3, 0xC7, 0xDD, 0x86,
+ 0x04, 0xEC, 0x12, 0xB8, 0x2A,
+ 0x04, 0x2A, 0x0B, 0xBB, 0x29,
+ 0x08, 0x3F, 0x35, 0x1E, 0x08,
+ 0x06, 0xF6, 0xCD, 0x08, 0xB0,
+ 0x07, 0x80, 0xDF, 0x1A, 0x3B,
+ 0x09, 0x87, 0x11, 0xE7, 0x89,
+ 0x0A, 0x91, 0xC6, 0xD1, 0xF0,
+ 0x06, 0x40, 0x29, 0x14, 0x0E,
+ 0x05, 0x86, 0xF0, 0xDA, 0xD1,
+ 0x05, 0x47, 0x4C, 0x95, 0x45,
+ 0x09, 0x93, 0x3A, 0x11, 0x04,
+ 0x0C, 0xBF, 0x22, 0xC6, 0xD9,
+ 0x0C, 0x0D, 0x10, 0x0B, 0x27,
+ 0x08, 0x2D, 0x79, 0x54, 0x0A,
+ 0x05, 0x97, 0x74, 0x38, 0x52,
+ 0x08, 0xEA, 0x24, 0x35, 0x85,
+ 0x0D, 0x9A, 0x9D, 0xE1, 0xFF,
+ 0x07, 0xBF, 0xAE, 0x64, 0x12,
+ 0x05, 0x21, 0xCF, 0x99, 0x95,
+ 0x09, 0x89, 0x47, 0x89, 0x8A,
+ 0x00, 0x42, 0x30, 0x9A, 0xA1,
+ 0x04, 0x6B, 0xDB, 0x18, 0x2B,
+ 0x05, 0xDD, 0xF4, 0x3F, 0x36,
+ 0x0E, 0x60, 0xB1, 0x9A, 0xA9,
+ 0x07, 0x1C, 0x0E, 0xBE, 0xCF,
+ 0x07, 0xF4, 0xBA, 0xD5, 0x30,
+ 0x02, 0x78, 0x88, 0x18, 0xAF,
+ 0x0E, 0xE0, 0x73, 0xA0, 0xCE,
+ 0x04, 0x48, 0x67, 0x0F, 0xA1,
+ 0x04, 0x3B, 0xC1, 0xF0, 0xD2,
+ 0x0C, 0x5C, 0xCA, 0x25, 0x31,
+ 0x0D, 0x9B, 0xE7, 0x2A, 0x57,
+ 0x07, 0x57, 0x07, 0x11, 0x03,
+ 0x0C, 0x61, 0xB9, 0x58, 0x1B,
+ 0x0B, 0x73, 0xA8, 0x56, 0xDF,
+ 0x0E, 0x54, 0x81, 0xB1, 0x7E,
+ 0x00, 0x63, 0x2A, 0xD6, 0xE3,
+ 0x03, 0x0D, 0xE1, 0x90, 0x7E,
+ 0x08, 0x35, 0xB7, 0x60, 0x76,
+ 0x0D, 0x52, 0x29, 0x5E, 0x9D,
+ 0x0A, 0xE3, 0xBE, 0xEB, 0xAA,
+ 0x08, 0xCE, 0x97, 0xBA, 0xE8,
+ 0x0D, 0x82, 0xF8, 0x9E, 0xF9,
+ 0x01, 0x98, 0xCA, 0x78, 0xCF,
+ 0x06, 0x6E, 0x50, 0x8E, 0xC4,
+ 0x04, 0x22, 0xD9, 0x81, 0x0A,
+ 0x0A, 0x72, 0x28, 0x35, 0x26,
+ 0x0C, 0x51, 0x2D, 0x3F, 0xA4,
+ 0x0E, 0x7E, 0x9A, 0x99, 0x40,
+ 0x0C, 0x55, 0x5E, 0xFD, 0x1E,
+ 0x02, 0xCB, 0xBC, 0x7D, 0x10,
+ 0x01, 0x6B, 0xC5, 0xEB, 0xEB,
+ 0x08, 0x52, 0x3C, 0xB5, 0xC1,
+ 0x06, 0x91, 0xD7, 0x5D, 0xA1,
+ 0x06, 0x2A, 0x6C, 0x50, 0xED,
+ 0x07, 0xF8, 0xB9, 0xF3, 0xF3,
+ 0x08, 0x9D, 0x69, 0x1E, 0xBC,
+ 0x08, 0xA9, 0x1C, 0x6D, 0x5C,
+ 0x04, 0xC6, 0x02, 0x11, 0x44,
+ 0x0F, 0x5D, 0x6F, 0x4D, 0xC0,
+ 0x09, 0x5A, 0xFE, 0xC9, 0xED,
+ 0x03, 0x30, 0x37, 0x81, 0x8D,
+ 0x0F, 0x7F, 0xFA, 0x2C, 0x62,
+ 0x0E, 0x78, 0x7B, 0xAE, 0x96,
+ 0x05, 0xA8, 0xD7, 0xD9, 0xC0,
+ 0x0F, 0x7C, 0x73, 0x03, 0x95,
+ 0x0F, 0xAE, 0x22, 0x41, 0xB8,
+ 0x06, 0xCB, 0xA1, 0xDE, 0xDF,
+ 0x0A, 0x7E, 0xE6, 0x66, 0x40,
+ 0x01, 0xDA, 0xBC, 0xFB, 0x31,
+ 0x0A, 0xBA, 0xDA, 0xB8, 0xD2,
+ 0x02, 0x01, 0x25, 0x09, 0xC8,
+ 0x00, 0xDE, 0x9B, 0x97, 0x48,
+ 0x04, 0xFD, 0x90, 0x5B, 0xF2,
+ 0x01, 0x66, 0x03, 0x1B, 0xFC,
+ 0x07, 0xF4, 0x58, 0xE6, 0xA8,
+ 0x01, 0xF7, 0x41, 0x81, 0xFE,
+ 0x0D, 0x2F, 0x0A, 0xAD, 0x8A,
+ 0x0A, 0x6F, 0xA7, 0x16, 0x5E,
+ 0x04, 0x47, 0xC6, 0x5D, 0xBD,
+ 0x03, 0x43, 0xBC, 0x3B, 0x93,
+ 0x0E, 0x45, 0x2C, 0x8F, 0x93,
+ 0x0D, 0xB3, 0x93, 0x6E, 0xA4,
+ 0x0F, 0x35, 0xBC, 0x31, 0x10,
+ 0x08, 0x46, 0x11, 0x81, 0xE8,
+ 0x04, 0x36, 0xE2, 0xA9, 0x69,
+ 0x0F, 0x24, 0xB7, 0xE4, 0x54,
+ 0x08, 0x06, 0x32, 0x8D, 0xAF,
+ 0x0E, 0xB1, 0x56, 0x5B, 0x63,
+ 0x0E, 0x03, 0xFB, 0x75, 0x08,
+ 0x0F, 0x55, 0x82, 0x99, 0x21,
+ 0x0C, 0x0E, 0x74, 0x88, 0xB8,
+ 0x09, 0x0C, 0xE1, 0x5D, 0x24,
+ 0x07, 0x78, 0x7D, 0xC1, 0xE7,
+ 0x0B, 0x99, 0x04, 0xA1, 0x62,
+ 0x07, 0xE6, 0xC5, 0x58, 0x63,
+ 0x0A, 0xE2, 0x62, 0x20, 0x10,
+ 0x0C, 0x27, 0xAA, 0xC0, 0x49,
+ 0x0E, 0x45, 0x0A, 0xDE, 0xB2,
+ 0x00, 0xED, 0xA9, 0xB5, 0x98,
+ 0x0C, 0x65, 0x1A, 0x59, 0xD3,
+ 0x03, 0xAC, 0xB3, 0xC4, 0xE8,
+ 0x06, 0xB6, 0xEC, 0x16, 0xFA,
+ 0x00, 0x00, 0x20, 0xCB, 0xA8,
+ 0x07, 0xE9, 0x3D, 0x75, 0x12,
+ 0x09, 0xC2, 0xF6, 0xC3, 0x13,
+ 0x00, 0xFF, 0x83, 0xD2, 0x93,
+ 0x02, 0x09, 0x4E, 0xDC, 0xE2,
+ 0x07, 0x6A, 0x90, 0x4C, 0xE4,
+ 0x0D, 0xC4, 0x80, 0x01, 0x1A,
+ 0x0E, 0x55, 0x86, 0xD4, 0xDC,
+ 0x02, 0x15, 0x23, 0xC1, 0x52,
+ 0x07, 0x91, 0x57, 0x10, 0xE3,
+ 0x0A, 0x34, 0xBF, 0x92, 0x1B,
+ 0x09, 0x67, 0x8F, 0x8A, 0xBF,
+ 0x07, 0x38, 0x25, 0x77, 0x14,
+ 0x02, 0x57, 0x93, 0x56, 0xBB,
+ 0x0A, 0xB8, 0xAA, 0x28, 0xB3,
+ 0x0F, 0xE8, 0x84, 0x1D, 0xF1,
+ 0x0F, 0x07, 0xB2, 0x2E, 0x64,
+ 0x02, 0x9D, 0xA7, 0xCF, 0x9B,
+ 0x07, 0x23, 0x8D, 0x8D, 0xC9,
+ 0x08, 0x80, 0x4E, 0x30, 0x2E,
+ 0x0A, 0x0F, 0xA9, 0xB9, 0x14,
+ 0x0B, 0x4F, 0xD9, 0x25, 0xBF,
+ 0x06, 0xA6, 0x60, 0x31, 0x94,
+ 0x09, 0x7F, 0x45, 0x88, 0x30,
+ 0x01, 0x9F, 0xB9, 0x1A, 0xDB,
+ 0x00, 0x5A, 0xFA, 0xA5, 0x50,
+ 0x0F, 0x2E, 0xE0, 0x7E, 0x21,
+ 0x0F, 0x34, 0x55, 0xED, 0x4C,
+ 0x0B, 0x34, 0x3B, 0xED, 0xE3,
+ 0x06, 0x7C, 0x9C, 0xE8, 0x25,
+ 0x0B, 0x47, 0x9B, 0x16, 0x2A,
+ 0x07, 0x1B, 0x53, 0x33, 0x11,
+ 0x00, 0x84, 0x65, 0x09, 0xE4,
+ 0x0B, 0xD3, 0x76, 0x18, 0xE0,
+ 0x05, 0x52, 0x43, 0x74, 0x1A,
+ 0x0C, 0xC0, 0x63, 0x2E, 0x50,
+ 0x06, 0x0B, 0xB9, 0x79, 0x1E,
+ 0x07, 0xEA, 0x15, 0x9A, 0xE0,
+ 0x0F, 0xF0, 0x79, 0xA9, 0x4E,
+ 0x0D, 0xC0, 0xEB, 0x49, 0xEB,
+ 0x08, 0x90, 0xCA, 0x17, 0xB6,
+ 0x0A, 0x77, 0x87, 0xDA, 0x9E,
+ 0x08, 0xB9, 0x9C, 0x7A, 0xC0,
+ 0x0E, 0x3C, 0x4C, 0x54, 0x8E,
+ 0x06, 0xAE, 0x26, 0x22, 0xB3,
+ 0x08, 0xC2, 0x72, 0xAC, 0x37,
+ 0x0D, 0xE4, 0x50, 0xAB, 0xBD,
+ 0x0C, 0x96, 0x7C, 0x94, 0x84,
+ 0x08, 0x9F, 0xD5, 0xA9, 0xFD,
+ 0x06, 0x3A, 0xCF, 0x30, 0xB9,
+ 0x00, 0x6B, 0x6A, 0xCC, 0x6E,
+ 0x0A, 0xA0, 0x52, 0xB1, 0x48,
+ 0x09, 0x4E, 0x37, 0xD9, 0x11,
+ 0x09, 0x1E, 0x0B, 0x6C, 0x10,
+ 0x03, 0x0F, 0xF9, 0xBD, 0xC8,
+ 0x09, 0x25, 0xA5, 0x6D, 0x1A,
+ 0x00, 0xD8, 0xA8, 0xDC, 0x54,
+ 0x04, 0xCC, 0xE4, 0x02, 0xD1,
+ 0x04, 0xE5, 0x58, 0x6B, 0x50,
+ 0x08, 0xA1, 0x5A, 0x70, 0x87,
+ 0x05, 0xA0, 0xA1, 0x3F, 0x01,
+ 0x05, 0x23, 0xAB, 0xFA, 0xEC,
+ 0x07, 0x96, 0x78, 0xF7, 0xE0,
+ 0x06, 0xDD, 0x82, 0xD3, 0xD6,
+ 0x01, 0xC5, 0xB9, 0x77, 0x03,
+ 0x0D, 0x27, 0xAE, 0xA2, 0x43,
+ 0x08, 0x5E, 0xD9, 0xA5, 0x6A,
+ 0x01, 0x70, 0xB6, 0xE2, 0xE6,
+ 0x01, 0x29, 0xD8, 0x12, 0xE4,
+ 0x01, 0x52, 0x38, 0xF9, 0xBB,
+ 0x08, 0x88, 0x04, 0x00, 0x4A,
+ 0x0A, 0xB0, 0xDE, 0xB6, 0xD5,
+ 0x0A, 0xB4, 0x7D, 0x82, 0xDB,
+ 0x0A, 0x68, 0x66, 0x03, 0x99,
+ 0x0F, 0xAD, 0xF4, 0x58, 0x2B,
+ 0x06, 0xF4, 0xCC, 0xC1, 0xA5,
+ 0x03, 0x3D, 0x2F, 0xAA, 0x41,
+ 0x03, 0xF2, 0x2E, 0x07, 0xBA,
+ 0x0F, 0x5D, 0x44, 0x85, 0x45,
+ 0x0D, 0xB3, 0x43, 0xBA, 0x24,
+ 0x00, 0xF7, 0xC5, 0xCB, 0x18,
+ 0x03, 0xB4, 0x79, 0xFE, 0xE6,
+ 0x04, 0x71, 0xB5, 0x5D, 0xF4,
+ 0x08, 0x08, 0xC6, 0x1F, 0x1C,
+ 0x09, 0xBC, 0xB7, 0xAE, 0x85,
+ 0x03, 0x3B, 0x23, 0x3D, 0x64,
+ 0x04, 0xCC, 0x06, 0x36, 0xBF,
+ 0x07, 0xE8, 0x31, 0xF7, 0xD9,
+ 0x08, 0x6C, 0x29, 0x5F, 0x35,
+ 0x03, 0x5E, 0xD5, 0x2F, 0x95,
+ 0x0C, 0xDE, 0x0E, 0x56, 0x1E,
+ 0x00, 0x8C, 0x4F, 0x61, 0x7F,
+ 0x06, 0x87, 0x78, 0x79, 0xCB,
+ 0x0B, 0x8B, 0x99, 0x0A, 0x27,
+ 0x00, 0x73, 0x46, 0xC5, 0x08,
+ 0x03, 0x6A, 0x62, 0x62, 0x20,
+ 0x00, 0x8C, 0x27, 0x2A, 0xC3,
+ 0x0A, 0x6E, 0x45, 0x1A, 0xD3,
+ 0x06, 0x49, 0x6F, 0xFF, 0xA3,
+ 0x0C, 0x0C, 0x65, 0x1A, 0xDF,
+ 0x05, 0x63, 0xAC, 0xB3, 0x47,
+ 0x0D, 0x06, 0x36, 0xEF, 0x20,
+ 0x0F, 0xAA, 0xC5, 0x38, 0xB8,
+ 0x01, 0x9E, 0x89, 0x11, 0x75,
+ 0x02, 0x19, 0xC2, 0xE0, 0xCF,
+ 0x0E, 0xF0, 0xFD, 0xA5, 0x5D,
+ 0x07, 0x32, 0x09, 0x4E, 0x94,
+ 0x07, 0xCD, 0x8A, 0x91, 0x82,
+ 0x0F, 0xC1, 0xF2, 0xC0, 0x31,
+ 0x00, 0x4E, 0xD5, 0x86, 0xA9,
+ 0x04, 0x08, 0x35, 0xAB, 0xEC,
+ 0x08, 0xDA, 0xA1, 0xD3, 0x20,
+ 0x08, 0xCA, 0x34, 0xB2, 0x66,
+ 0x0D, 0xB9, 0x7A, 0x05, 0x27,
+ 0x0D, 0x6D, 0xD8, 0x3D, 0x7F,
+ 0x04, 0x0A, 0x57, 0x87, 0x72,
+ 0x02, 0xD2, 0x7A, 0xEA, 0x24,
+ 0x03, 0x85, 0xEF, 0x9A, 0x1D,
+ 0x08, 0xDF, 0xC3, 0x38, 0x2E,
+ 0x04, 0x12, 0x99, 0x23, 0xCF,
+ 0x0B, 0x15, 0x27, 0x0F, 0x28,
+ 0x09, 0xC0, 0x04, 0x42, 0x30,
+ 0x0C, 0xE2, 0x89, 0xEB, 0x3A,
+ 0x06, 0x62, 0xCC, 0x5F, 0xA5,
+ 0x0F, 0x6F, 0x25, 0xE0, 0x7B,
+ 0x04, 0x20, 0xFC, 0xC3, 0x04,
+ 0x02, 0xCF, 0x1E, 0xF4, 0x50,
+ 0x0B, 0xB0, 0x5A, 0xFA, 0xA8,
+ 0x0C, 0xCF, 0xAC, 0xE6, 0x79,
+ 0x0F, 0xF5, 0xD4, 0x48, 0x67,
+ 0x07, 0xDA, 0xCB, 0xFB, 0xF2,
+ 0x02, 0x03, 0x7C, 0x5C, 0xFA,
+ 0x09, 0x13, 0x47, 0x9F, 0x2A,
+ 0x06, 0x51, 0x1B, 0x57, 0x04,
+ 0x01, 0x00, 0x80, 0x61, 0x39,
+ 0x0E, 0xB3, 0x77, 0x72, 0xE8,
+ 0x0E, 0x9F, 0x32, 0x4B, 0xBE,
+ 0x06, 0xC9, 0x9D, 0x67, 0x7F,
+ 0x0E, 0xE8, 0x8B, 0x1D, 0x72,
+ 0x0E, 0x3E, 0xEC, 0x31, 0x97,
+ 0x08, 0x1D, 0x51, 0x50, 0xE9,
+ 0x06, 0x5D, 0x40, 0xE7, 0x89,
+ 0x00, 0x2D, 0xCD, 0xCA, 0x40,
+ 0x0D, 0x68, 0x77, 0x83, 0xDD,
+ 0x07, 0xFE, 0x39, 0x9C, 0xCA,
+ 0x0E, 0x09, 0xBE, 0x60, 0x14,
+ 0x07, 0x76, 0x6E, 0x22, 0xA2,
+ 0x0B, 0x0D, 0xA3, 0xF2, 0xEC,
+ 0x0D, 0xA3, 0x87, 0xD0, 0xED,
+ 0x0F, 0x64, 0x9E, 0xF8, 0xC4,
+ 0x09, 0x80, 0xCE, 0x51, 0xA5,
+ 0x05, 0x16, 0xB6, 0xCB, 0xFC,
+ 0x07, 0xD5, 0x0E, 0xEE, 0xC0,
+ 0x02, 0xE8, 0xE0, 0x5E, 0xBC,
+ 0x01, 0x84, 0xAD, 0x13, 0xC7,
+ 0x01, 0x21, 0x9C, 0x2B, 0x24,
+ 0x0A, 0xEA, 0x6B, 0x78, 0x3C,
+ 0x01, 0x73, 0x22, 0x90, 0xA4,
+ 0x0E, 0x7C, 0xDA, 0xA9, 0x1C,
+ 0x05, 0x5C, 0xCC, 0x46, 0x82,
+ 0x01, 0x84, 0xE5, 0x58, 0x6F,
+ 0x05, 0xE0, 0x21, 0x5E, 0x7E,
+ 0x02, 0x2D, 0xF9, 0x35, 0x33,
+ 0x08, 0x8C, 0x63, 0x4B, 0xF0,
+ 0x04, 0xF5, 0x36, 0x74, 0x7B,
+ 0x08, 0x5F, 0x7D, 0x82, 0x17,
+ 0x0F, 0xA0, 0xA4, 0xF3, 0xA6,
+ 0x02, 0x9C, 0xE3, 0x2E, 0xA2,
+ 0x02, 0x39, 0x9A, 0x5F, 0xAB,
+ 0x0F, 0x1E, 0x30, 0x7F, 0xAA,
+ 0x07, 0x40, 0xE9, 0x5A, 0x3C,
+ 0x08, 0xB0, 0x92, 0x38, 0xDA,
+ 0x00, 0x18, 0x28, 0x06, 0xA3,
+ 0x02, 0xCA, 0xB0, 0xDE, 0x9B,
+ 0x01, 0x42, 0xB6, 0xFD, 0x92,
+ 0x03, 0x52, 0xCE, 0xEA, 0x83,
+ 0x09, 0x46, 0x93, 0x74, 0x58,
+ 0x0B, 0x2C, 0xF5, 0x75, 0xC2,
+ 0x0D, 0xF3, 0x81, 0xAF, 0xAA,
+ 0x01, 0x03, 0x76, 0xEC, 0x84,
+ 0x08, 0x06, 0xDE, 0xC2, 0xC6,
+ 0x00, 0xF4, 0x30, 0xC3, 0xF6,
+ 0x0F, 0xA9, 0x74, 0x43, 0x86,
+ 0x02, 0x53, 0xB5, 0xF9, 0xB9,
+ 0x02, 0xA4, 0x71, 0xB5, 0x71,
+ 0x09, 0x70, 0x8A, 0x40, 0x19,
+ 0x0E, 0x61, 0xBD, 0x37, 0x22,
+ 0x0D, 0x69, 0x7B, 0x24, 0xB7,
+ 0x0E, 0x14, 0xC8, 0x0C, 0xD5,
+ 0x0F, 0x2E, 0x6C, 0x91, 0x56,
+ 0x0B, 0xE2, 0x6E, 0xBF, 0xDB,
+ 0x06, 0x0A, 0xDF, 0x59, 0x80,
+ 0x05, 0xE4, 0x5C, 0x0E, 0x74,
+ 0x05, 0xBA, 0x89, 0x0C, 0xE1,
+ 0x02, 0x66, 0x47, 0x78, 0x7F,
+ 0x09, 0x6F, 0x2B, 0x99, 0x04,
+ 0x0D, 0xA8, 0xE3, 0x6C, 0x35,
+ 0x09, 0xAA, 0xAE, 0x62, 0x62,
+ 0x00, 0xD9, 0x28, 0x27, 0x2A,
+ 0x00, 0x33, 0xAE, 0xC3, 0x00,
+ 0x03, 0x3F, 0xE9, 0x6F, 0xC9,
+ 0x08, 0xD1, 0xCC, 0x65, 0x1A,
+ 0x04, 0xD1, 0x63, 0xAC, 0xB3,
+ 0x0F, 0xDD, 0x86, 0xB6, 0xEC,
+ 0x0C, 0x7E, 0x8A, 0x8F, 0xDC,
+ 0x09, 0xB9, 0x98, 0xC9, 0xBD,
+ 0x07, 0x13, 0x9D, 0xF4, 0xB6,
+ 0x0F, 0x0F, 0x70, 0xF9, 0x03,
+ 0x0F, 0x16, 0xB2, 0x2F, 0x0C,
+ 0x01, 0xE6, 0x4D, 0xBA, 0x91,
+ 0x0D, 0xD5, 0xC4, 0xC2, 0xC2,
+ 0x08, 0x98, 0xAE, 0x59, 0xC6,
+ 0x0E, 0xD9, 0x1F, 0x95, 0x87,
+ 0x04, 0x11, 0x79, 0x95, 0x53,
+ 0x00, 0x18, 0xCE, 0x34, 0xBF,
+ 0x02, 0xC7, 0x5D, 0xE7, 0x8F,
+ 0x08, 0x0D, 0x69, 0xDE, 0x6D,
+ 0x0C, 0x54, 0xCD, 0xD7, 0x97,
+ 0x03, 0x38, 0x12, 0x7C, 0xAA,
+ 0x05, 0xB3, 0x65, 0xED, 0x9A,
+ 0x0C, 0x60, 0x1F, 0x07, 0xBE,
+ 0x07, 0x66, 0x72, 0x1B, 0x29,
+ 0x0E, 0x98, 0xD5, 0x23, 0x8D,
+ 0x02, 0x88, 0x48, 0x06, 0x88,
+ 0x00, 0x9C, 0xAE, 0x0D, 0xE9,
+ 0x09, 0x14, 0x2F, 0x43, 0xC8,
+ 0x07, 0xBF, 0x22, 0xA0, 0xE0,
+ 0x00, 0x94, 0xAD, 0x7F, 0xB6,
+ 0x0F, 0xB3, 0x0F, 0x1F, 0x80,
+ 0x03, 0x59, 0xF0, 0x5C, 0x0F,
+ 0x00, 0x94, 0x0C, 0x2C, 0x60,
+ 0x03, 0xA4, 0xF5, 0x52, 0xC2,
+ 0x0E, 0x09, 0xFB, 0x39, 0x7B,
+ 0x01, 0xFE, 0x0B, 0x7A, 0x9C,
+ 0x01, 0xA6, 0x5B, 0xC5, 0x1F,
+ 0x07, 0x28, 0x07, 0x1B, 0x65,
+ 0x09, 0x14, 0x90, 0x84, 0x63,
+ 0x00, 0xD6, 0xFC, 0xD3, 0x72,
+ 0x08, 0x56, 0x9A, 0xB2, 0x4B,
+ 0x0E, 0x4D, 0x4C, 0xC0, 0x63,
+ 0x08, 0x52, 0x5E, 0x8B, 0x1D,
+ 0x05, 0x1F, 0x9E, 0xE8, 0x35,
+ 0x0E, 0x62, 0x95, 0xF5, 0x90,
+ 0x03, 0x5B, 0xD2, 0x40, 0xEF,
+ 0x01, 0x6B, 0x08, 0x90, 0x0E,
+ 0x0D, 0xB3, 0xFA, 0xF7, 0x86,
+ 0x05, 0x1C, 0x98, 0xB5, 0x50,
+ 0x00, 0x73, 0x1D, 0xBE, 0x68,
+ 0x00, 0x8E, 0x36, 0xA3, 0x26,
+ 0x02, 0x01, 0x08, 0xC2, 0x72,
+ 0x0C, 0xFF, 0x06, 0xE4, 0x50,
+ 0x04, 0x3D, 0x47, 0x1B, 0xBC,
+ 0x0A, 0x99, 0x80, 0x42, 0x9B,
+ 0x0F, 0xF8, 0x82, 0xBA, 0xC3,
+ 0x0C, 0x7D, 0xD0, 0x67, 0x5C,
+ 0x01, 0x6B, 0xE8, 0xA6, 0x18,
+ 0x07, 0xBB, 0x81, 0xCE, 0x93,
+ 0x0F, 0xD1, 0x83, 0x9C, 0x1D,
+ 0x0C, 0xD0, 0xEF, 0x8F, 0xF2,
+ 0x0D, 0xF1, 0x73, 0xA0, 0x9E,
+ 0x0D, 0x1E, 0x7C, 0x58, 0xA3,
+ 0x0C, 0x6D, 0x5C, 0xCC, 0x4E,
+ 0x02, 0x11, 0x86, 0xE5, 0x92,
+ 0x04, 0x4D, 0xC8, 0xA1, 0x5A,
+ 0x07, 0x49, 0xCD, 0xF5, 0x75,
+ 0x09, 0x04, 0x36, 0x23, 0x6B,
+ 0x02, 0x2F, 0xF7, 0xB2, 0x7A,
+ 0x0B, 0xA0, 0xD6, 0x5D, 0x82,
+ 0x0D, 0x15, 0x41, 0x2E, 0x42,
+ 0x07, 0x03, 0x99, 0x27, 0xAE,
+ 0x02, 0x43, 0x37, 0xDE, 0xD9,
+ 0x03, 0xDE, 0x1E, 0xF6, 0x71,
+ 0x02, 0xE6, 0xC1, 0x29, 0xDA,
+ 0x0C, 0xF8, 0x31, 0x52, 0x38,
+ 0x06, 0xB8, 0x18, 0x88, 0x07,
+ 0x0A, 0x89, 0x2D, 0x32, 0x5E,
+ 0x02, 0x93, 0x26, 0xB4, 0xBD,
+ 0x0E, 0x5B, 0xF2, 0xAA, 0x69,
+ 0x03, 0x19, 0x42, 0x97, 0x06,
+ 0x02, 0xEE, 0x8D, 0x71, 0xE7,
+ 0x01, 0xAD, 0xBB, 0x05, 0x5D,
+ 0x0A, 0x81, 0x4E, 0xF2, 0xEE,
+ 0x07, 0x3A, 0x4B, 0x5D, 0x44,
+ 0x04, 0x70, 0xBD, 0xB5, 0x03,
+ 0x00, 0x33, 0xE0, 0xF7, 0xDC,
+ 0x0D, 0xA8, 0x53, 0xB2, 0x73,
+ 0x09, 0x67, 0x0C, 0xF1, 0xB1,
+ 0x08, 0x33, 0x10, 0x08, 0x86,
+ 0x09, 0x90, 0xC9, 0x3D, 0x33,
+ 0x02, 0x85, 0x6D, 0xFB, 0x2B,
+ 0x03, 0xE4, 0xD0, 0xC8, 0xC6,
+ 0x0B, 0x8D, 0xEB, 0xE8, 0x71,
+ 0x07, 0x73, 0xA3, 0xEE, 0x71,
+ 0x01, 0x73, 0xA3, 0xDF, 0x51,
+ 0x02, 0x95, 0xE5, 0xDC, 0xFC,
+ 0x04, 0x9E, 0xA2, 0x09, 0x0C,
+ 0x01, 0x7B, 0x62, 0x87, 0x78,
+ 0x0B, 0xC1, 0xEF, 0x87, 0x19,
+ 0x04, 0xA7, 0x68, 0xF3, 0xE6,
+ 0x04, 0x80, 0x03, 0x6A, 0xE2,
+ 0x0B, 0x22, 0x74, 0x8C, 0xD5,
+ 0x00, 0xC6, 0xD6, 0xEE, 0x4D,
+ 0x03, 0x53, 0x16, 0x45, 0xEF,
+ 0x00, 0xAB, 0xFC, 0x0C, 0x97,
+ 0x00, 0x5A, 0x7F, 0x63, 0xAE,
+ 0x0A, 0x47, 0x3D, 0x0A, 0x36,
+ 0x0C, 0x16, 0xBA, 0xAA, 0x05,
+ 0x0B, 0xCB, 0xBC, 0x1C, 0x1B,
+ 0x0D, 0x75, 0x12, 0x19, 0x31,
+ 0x06, 0xCD, 0x0E, 0xF6, 0x35,
+ 0x07, 0xDF, 0x17, 0x92, 0x89,
+ 0x0C, 0xD1, 0xE3, 0xCB, 0xCA,
+ 0x01, 0x6E, 0x75, 0xC4, 0xC4,
+ 0x01, 0x0B, 0x18, 0x4E, 0x55,
+ 0x0C, 0xF1, 0x68, 0x8A, 0x11,
+ 0x0E, 0xEE, 0x92, 0xDF, 0x53,
+ 0x09, 0x35, 0xAC, 0xCA, 0x30,
+ 0x0F, 0xA2, 0xC7, 0x55, 0x95,
+ 0x0B, 0xBA, 0x09, 0x61, 0x58,
+ 0x0D, 0x7D, 0x54, 0x0A, 0x57,
+ 0x06, 0xB8, 0xD9, 0xD2, 0x7A,
+ 0x03, 0x26, 0x53, 0x85, 0x2D,
+ 0x00, 0x18, 0x59, 0xFF, 0x0F,
+ 0x07, 0xAE, 0x84, 0x12, 0x5D,
+ 0x03, 0xCF, 0x9B, 0x15, 0x23,
+ 0x0D, 0xAB, 0x89, 0x88, 0x80,
+ 0x02, 0x30, 0x9C, 0xAD, 0xC7,
+ 0x0D, 0xB9, 0x14, 0x2F, 0x0F,
+ 0x09, 0x25, 0xBF, 0x26, 0xA6,
+ 0x00, 0x31, 0x16, 0x69, 0x7F,
+ 0x0E, 0x8E, 0xB2, 0xCF, 0x1F,
+ 0x08, 0x05, 0x24, 0x4C, 0x59,
+ 0x06, 0xA8, 0x94, 0xAF, 0x2D,
+ 0x00, 0x73, 0xA6, 0xF5, 0xD4,
+ 0x08, 0x67, 0x0B, 0x5B, 0x3E,
+ 0x0B, 0xC3, 0xFE, 0x8F, 0x76,
+ 0x0C, 0xC8, 0x25, 0xBB, 0x4D,
+ 0x0F, 0x36, 0x2A, 0xC7, 0x11,
+ 0x07, 0x13, 0x11, 0x80, 0xCE,
+ 0x01, 0x39, 0x54, 0x1B, 0x99,
+ 0x09, 0x28, 0x56, 0x9F, 0xB2,
+ 0x0B, 0x7E, 0x4B, 0x4C, 0x33,
+ 0x0A, 0xA8, 0x32, 0xFE, 0x8B,
+ 0x05, 0xE5, 0x3E, 0x32, 0xF9,
+ 0x0D, 0x31, 0xC0, 0xB9, 0xB5,
+ 0x0A, 0x2C, 0x96, 0x5D, 0xE0,
+ 0x0F, 0x99, 0x4B, 0xA4, 0x90,
+ 0x06, 0x91, 0x16, 0x64, 0x37,
+ 0x0D, 0xF9, 0xD6, 0xF8, 0xF9,
+ 0x08, 0xCA, 0xD6, 0x82, 0x3E,
+ 0x06, 0x51, 0x4B, 0xB6, 0xEE,
+ 0x0E, 0xA2, 0xA1, 0x04, 0x42,
+ 0x08, 0xA9, 0xFF, 0xA6, 0xA4,
+ 0x00, 0xAD, 0x3B, 0x64, 0x65,
+ 0x05, 0x19, 0xF5, 0x82, 0x46,
+ 0x08, 0xA7, 0x9D, 0x16, 0xFA,
+ 0x01, 0x39, 0xB5, 0xD0, 0x7B,
+ 0x02, 0xD1, 0x6B, 0xEA, 0x93,
+ 0x02, 0xBC, 0xBB, 0x05, 0x04,
+ 0x03, 0xD7, 0x51, 0x21, 0x9C,
+ 0x0B, 0x6C, 0xD4, 0xE3, 0xCF,
+ 0x08, 0x3D, 0xF5, 0x73, 0x20,
+ 0x04, 0x25, 0xBE, 0x7C, 0xD8,
+ 0x00, 0x1E, 0x4D, 0x5C, 0xBF,
+ 0x0E, 0x07, 0xDD, 0x84, 0xED,
+ 0x00, 0xEF, 0xED, 0xC4, 0x61,
+ 0x0A, 0x7E, 0xC9, 0x2B, 0xF3,
+ 0x01, 0x33, 0x01, 0x88, 0xE9,
+ 0x0B, 0xFA, 0x2C, 0x75, 0x96,
+ 0x08, 0xFB, 0x22, 0xD6, 0xDD,
+ 0x09, 0xD7, 0xD5, 0x44, 0xD6,
+ 0x05, 0x77, 0x03, 0x5D, 0x28,
+ 0x0E, 0xA2, 0x59, 0x38, 0x5E,
+ 0x09, 0xA1, 0xDE, 0x9F, 0xFA,
+ 0x0B, 0xE2, 0xE4, 0x41, 0xE3,
+ 0x01, 0x3C, 0xF9, 0xB1, 0xA1,
+ 0x00, 0xDA, 0x38, 0x94, 0x88,
+ 0x0C, 0x25, 0x89, 0xC6, 0xF0,
+ 0x04, 0x9E, 0x4B, 0xC2, 0x94,
+ 0x0D, 0x92, 0x5F, 0xF2, 0xA2,
+ 0x06, 0x03, 0x19, 0x48, 0x39,
+ 0x0C, 0x58, 0x6B, 0x22, 0x1F,
+ 0x07, 0x41, 0xA9, 0xBB, 0xEB,
+ 0x05, 0x2F, 0x6F, 0x41, 0x11,
+ 0x04, 0x02, 0xE2, 0xCF, 0x1D,
+ 0x04, 0x86, 0x70, 0xB7, 0x0A,
+ 0x03, 0xBC, 0x3F, 0xEA, 0x4F,
+ 0x0F, 0x49, 0x70, 0x58, 0x5F,
+ 0x03, 0xF6, 0xBA, 0x24, 0x31,
+ 0x0D, 0x71, 0xB1, 0x1C, 0x88,
+ 0x0C, 0x16, 0x4C, 0xE1, 0xFD,
+ 0x0E, 0xA2, 0x65, 0x69, 0xFB,
+ 0x04, 0xB7, 0xE4, 0xD9, 0xC6,
+ 0x06, 0x32, 0x8D, 0x2B, 0x06,
+ 0x0A, 0xD6, 0x59, 0xE3, 0xC0,
+ 0x03, 0x5B, 0x72, 0x0B, 0x97,
+ 0x05, 0x02, 0x95, 0xE5, 0xF2,
+ 0x0E, 0x74, 0x9E, 0xBA, 0xA7,
+ 0x0C, 0xE1, 0x7B, 0x66, 0x69,
+ 0x00, 0x07, 0x41, 0xE3, 0xA5,
+ 0x03, 0xC4, 0xA5, 0xE3, 0x48,
+ 0x06, 0xC5, 0x48, 0x63, 0x60,
+ 0x02, 0x62, 0x20, 0x15, 0xA2,
+ 0x07, 0x2A, 0xC3, 0x74, 0x97,
+ 0x0E, 0x0A, 0xD3, 0xF6, 0x71,
+ 0x07, 0xC9, 0x29, 0x94, 0x0C,
+ 0x0D, 0x1C, 0xDF, 0xDD, 0x23,
+ 0x06, 0xB6, 0x2E, 0xDD, 0x26,
+ 0x06, 0xEC, 0x12, 0xBE, 0x62,
+ 0x05, 0x2B, 0xCB, 0xB6, 0xB3,
+ 0x01, 0x3D, 0xF5, 0x1C, 0xF6,
+ 0x02, 0xF6, 0xC9, 0x0E, 0x1F,
+ 0x05, 0x06, 0x31, 0x1C, 0xD1,
+ 0x03, 0x4B, 0x36, 0xE7, 0x8D,
+ 0x0A, 0x91, 0xC6, 0xDF, 0x3D,
+ 0x04, 0x40, 0x21, 0x12, 0xB6,
+ 0x0F, 0x03, 0x06, 0xD7, 0x61,
+ 0x0F, 0xA2, 0x0B, 0x92, 0x9F,
+ 0x0B, 0x53, 0xB0, 0x14, 0x4A,
+ 0x0E, 0xBA, 0x4A, 0xC7, 0x19,
+ 0x0E, 0x0F, 0x5A, 0x0D, 0x6D,
+ 0x08, 0x2D, 0x7D, 0x59, 0x00,
+ 0x07, 0x97, 0x70, 0x3D, 0x3D,
+ 0x01, 0xEA, 0x24, 0x33, 0xAA,
+ 0x0D, 0x9A, 0x19, 0xE1, 0x37,
+ 0x07, 0xBE, 0x2E, 0x64, 0x3D,
+ 0x0D, 0xA3, 0xCF, 0x9B, 0x3A,
+ 0x03, 0x8D, 0xAB, 0x89, 0x67,
+ 0x08, 0x3A, 0xB0, 0x90, 0x84,
+ 0x07, 0x29, 0xBB, 0x9F, 0xF3,
+ 0x0F, 0xD9, 0x25, 0x3F, 0x2C,
+ 0x06, 0x60, 0x31, 0x91, 0x46,
+ 0x0F, 0x45, 0x8E, 0xBC, 0x36,
+ 0x04, 0x74, 0x1A, 0xDB, 0x88,
+ 0x0A, 0xFA, 0xA9, 0x16, 0x16,
+ 0x0E, 0xE0, 0x77, 0x20, 0xFF,
+ 0x0D, 0xC8, 0x87, 0x0B, 0x1B,
+ 0x0C, 0xB8, 0xE3, 0x7C, 0xBB,
+ 0x0C, 0x5C, 0xC8, 0x25, 0x03,
+ 0x07, 0x9F, 0x36, 0x2E, 0x0D,
+ 0x03, 0x07, 0x93, 0x1D, 0x00,
+ 0x0C, 0x67, 0xB9, 0x5A, 0x5B,
+ 0x03, 0x72, 0x2C, 0x56, 0x48,
+ 0x0B, 0x4B, 0xBE, 0x41, 0x8C,
+ 0x0A, 0x66, 0xDD, 0xD2, 0xBE,
+ 0x02, 0x1F, 0x45, 0x9E, 0xFE,
+ 0x02, 0x30, 0x42, 0x60, 0xB7,
+ 0x0C, 0xF8, 0xC9, 0x5A, 0x9D,
+ 0x08, 0xBF, 0xC9, 0xE7, 0xA8,
+ 0x08, 0xC8, 0x97, 0xBA, 0x28,
+ 0x0F, 0x87, 0x7C, 0x12, 0xF8,
+ 0x01, 0x96, 0xCA, 0x7A, 0xCF,
+ 0x04, 0x6A, 0x44, 0x8E, 0x16,
+ 0x06, 0x25, 0xA2, 0x0F, 0x88,
+ 0x0A, 0xF1, 0x0E, 0x39, 0x66,
+ 0x0D, 0x53, 0x69, 0x31, 0x24,
+ 0x06, 0xFC, 0x96, 0x19, 0xB3,
+ 0x04, 0x51, 0xA1, 0xFB, 0x16,
+ 0x0A, 0xCB, 0xB0, 0xFD, 0xD0,
+ 0x09, 0x6F, 0x45, 0x6D, 0xAA,
+ 0x00, 0xD2, 0x1B, 0xBB, 0x81,
+ 0x0C, 0x12, 0x7B, 0x57, 0xA1,
+ 0x0F, 0x2F, 0xAC, 0xDC, 0x6F,
+ 0x0E, 0xF9, 0xFD, 0x77, 0x79,
+ 0x01, 0x76, 0xED, 0x98, 0x36,
+ 0x02, 0xAC, 0xE3, 0x6D, 0x4C,
+ 0x0C, 0x44, 0x00, 0x17, 0x0E,
+ 0x0E, 0x58, 0x6F, 0x4D, 0xFA,
+ 0x0A, 0xDC, 0xC9, 0xCF, 0xA7,
+ 0x01, 0xB5, 0x90, 0x03, 0x0C,
+ 0x08, 0xCD, 0x4D, 0x2A, 0x00,
+ 0x0F, 0x7A, 0xDB, 0xAD, 0x96,
+ 0x04, 0x80, 0x97, 0xD5, 0x80,
+ 0x0F, 0x7F, 0x75, 0x83, 0x99,
+ 0x07, 0xAE, 0xA2, 0x4F, 0x0B,
+ 0x06, 0x59, 0x00, 0x5C, 0x9F,
+ 0x0B, 0xFD, 0x55, 0xE0, 0x37,
+ 0x01, 0x58, 0x1C, 0xF4, 0x31,
+ 0x0A, 0x38, 0x5E, 0x3A, 0x18,
+ 0x01, 0x06, 0x23, 0x09, 0x0A,
+ 0x09, 0xDC, 0xD8, 0x17, 0x08,
+ 0x0E, 0xFB, 0x9A, 0x5B, 0xF6,
+ 0x08, 0x66, 0x07, 0x1F, 0xC6,
+ 0x07, 0xF4, 0x5C, 0xE7, 0xDE,
+ 0x01, 0x75, 0x45, 0xAD, 0xBB,
+ 0x0F, 0xA9, 0xA1, 0x81, 0x4B,
+ 0x02, 0xEE, 0x03, 0x36, 0x7D,
+ 0x0D, 0x44, 0x82, 0xF0, 0xBD,
+ 0x03, 0x43, 0xBB, 0xBF, 0xE0,
+ 0x07, 0xC5, 0xCC, 0x82, 0x53,
+ 0x04, 0xF9, 0x53, 0x62, 0xA4,
+ 0x01, 0x34, 0xD1, 0x31, 0x10,
+ 0x01, 0xC4, 0x37, 0x95, 0x95,
+ 0x07, 0x31, 0x2E, 0x05, 0x6B,
+ 0x03, 0xA4, 0x17, 0xE9, 0xD4,
+ 0x05, 0x84, 0x16, 0x8D, 0xDB,
+ 0x02, 0xB7, 0xD8, 0x59, 0xEB,
+ 0x06, 0x03, 0xFB, 0x7B, 0x0B,
+ 0x0F, 0x55, 0x03, 0x95, 0xE5,
+ 0x0C, 0x0E, 0x77, 0x9A, 0x30,
+ 0x09, 0x0C, 0xE3, 0x7D, 0x2C,
+ 0x0C, 0x78, 0x7F, 0xC1, 0xEF,
+ 0x07, 0x99, 0x06, 0xE7, 0x67,
+ 0x03, 0xE6, 0xDF, 0x48, 0xD1,
+ 0x0A, 0xE2, 0x62, 0xA0, 0x1A,
+ 0x0C, 0x27, 0x2A, 0x43, 0x70,
+ 0x0E, 0x45, 0x0A, 0x53, 0xFC,
+ 0x09, 0x6F, 0xC9, 0x29, 0x52,
+ 0x0C, 0x65, 0x1A, 0xDF, 0xDB,
+ 0x03, 0xAC, 0xB1, 0xC7, 0xD7,
+ 0x0D, 0xB6, 0xEC, 0x16, 0x8D,
+ 0x0A, 0x05, 0x2B, 0xC5, 0xA5,
+ 0x0C, 0xE9, 0x39, 0x75, 0x12,
+ 0x09, 0xC2, 0xF2, 0xCD, 0xCA,
+ 0x00, 0xFF, 0x87, 0xDF, 0xE3,
+ 0x02, 0x09, 0x4A, 0xD1, 0x12,
+ 0x0D, 0x8A, 0x91, 0xC6, 0x22,
+ 0x0F, 0x42, 0xD9, 0xAC, 0x1D,
+ 0x0E, 0x55, 0x86, 0xF9, 0xD8,
+ 0x06, 0x15, 0xA7, 0xE8, 0x91,
+ 0x07, 0x2B, 0xF3, 0x30, 0x58,
+ 0x03, 0xB4, 0x5F, 0xA2, 0xC7,
+ 0x07, 0xE7, 0x42, 0xBA, 0x0D,
+ 0x04, 0x59, 0xCD, 0x71, 0x54,
+ 0x03, 0x55, 0xB7, 0x70, 0xB9,
+ 0x08, 0x7C, 0xF6, 0xA4, 0x31,
+ 0x05, 0xED, 0x9A, 0x1B, 0xA3,
+ 0x06, 0x0D, 0xDE, 0x33, 0xA4,
+ 0x08, 0x9B, 0xB9, 0xCF, 0x9F,
+ 0x09, 0x23, 0x8C, 0xAB, 0x87,
+ 0x08, 0x80, 0x42, 0x3E, 0x81,
+ 0x0B, 0x0D, 0xFD, 0xB5, 0x05,
+ 0x07, 0x4F, 0xD8, 0xA5, 0x8C,
+ 0x06, 0xA6, 0x66, 0x31, 0x5D,
+ 0x02, 0xF9, 0xE6, 0x83, 0xB6,
+ 0x0F, 0x1F, 0x74, 0x17, 0x9F,
+ 0x08, 0xD9, 0xDA, 0xAA, 0x87,
+ 0x06, 0x2C, 0xCC, 0x33, 0x57,
+ 0x0F, 0xD2, 0x6B, 0x67, 0x0F,
+ 0x03, 0xB4, 0x9B, 0xC3, 0xFE,
+ 0x0F, 0x7C, 0x5C, 0xC5, 0x61,
+ 0x0B, 0x47, 0x9F, 0x30, 0x28,
+ 0x07, 0x1B, 0x55, 0x16, 0x5B,
+ 0x00, 0x84, 0x61, 0x39, 0xA7,
+ 0x03, 0x53, 0xD2, 0x38, 0xD6,
+ 0x06, 0x32, 0xAB, 0x72, 0x4D,
+ 0x02, 0x40, 0xAE, 0x28, 0xD2,
+ 0x07, 0x0A, 0xFD, 0x69, 0x9E,
+ 0x07, 0xEA, 0x15, 0xA7, 0xD2,
+ 0x0F, 0xF3, 0x78, 0xA9, 0x5C,
+ 0x05, 0x40, 0x47, 0x45, 0x6B,
+ 0x01, 0x92, 0xAE, 0x1B, 0x76,
+ 0x02, 0x71, 0xA1, 0xFC, 0x1A,
+ 0x04, 0xB9, 0x91, 0xCA, 0x78,
+ 0x0F, 0x3E, 0x6C, 0x5A, 0x93,
+ 0x0E, 0x46, 0x92, 0x24, 0x42,
+ 0x03, 0x44, 0xD5, 0xAF, 0x02,
+ 0x06, 0xE4, 0x50, 0xA9, 0x85,
+ 0x0D, 0x14, 0xB8, 0x9A, 0x6B,
+ 0x0A, 0xC0, 0x7C, 0x25, 0xFF,
+ 0x0F, 0x3A, 0x0B, 0x30, 0xFD,
+ 0x09, 0xE9, 0x2A, 0xC1, 0x99,
+ 0x00, 0xA6, 0x7D, 0xBC, 0xB3,
+ 0x08, 0xCE, 0x53, 0xDB, 0xD1,
+ 0x08, 0x1E, 0x6F, 0x60, 0x50,
+ 0x07, 0x8F, 0x58, 0x3D, 0xB1,
+ 0x01, 0x20, 0x90, 0xE9, 0xDE,
+ 0x05, 0xD8, 0x69, 0x1F, 0x68,
+ 0x0D, 0xCC, 0xA4, 0x0F, 0x15,
+ 0x0D, 0xEC, 0x98, 0x62, 0x8D,
+ 0x08, 0xA1, 0x5A, 0x7A, 0x30,
+ 0x0F, 0xF9, 0x31, 0x35, 0x01,
+ 0x05, 0x23, 0xAB, 0xFA, 0x1E,
+ 0x05, 0x14, 0x58, 0xFE, 0x16,
+ 0x0C, 0xDB, 0xC2, 0xD7, 0xC5,
+ 0x0E, 0x25, 0xB4, 0x77, 0x03,
+ 0x01, 0x27, 0xAC, 0xE2, 0x4D,
+ 0x08, 0x5E, 0xD9, 0xBF, 0xC3,
+ 0x06, 0x71, 0x8F, 0xCE, 0xE6,
+ 0x09, 0x29, 0x4E, 0x2C, 0x79,
+ 0x09, 0xD2, 0x98, 0xDA, 0x38,
+ 0x00, 0x8A, 0x04, 0x23, 0x89,
+ 0x00, 0xB6, 0xE7, 0x9B, 0x95,
+ 0x0A, 0xB4, 0x7D, 0x92, 0x5B,
+ 0x0A, 0xE8, 0x46, 0x33, 0x99,
+ 0x0C, 0x91, 0xCE, 0xD8, 0xEF,
+ 0x04, 0x71, 0x57, 0x41, 0xAD,
+ 0x09, 0x05, 0xAF, 0xAC, 0x81,
+ 0x02, 0xF2, 0x6E, 0x17, 0xBA,
+ 0x0F, 0x5C, 0xC4, 0x86, 0x70,
+ 0x0F, 0xB3, 0x43, 0xBA, 0x7F,
+ 0x08, 0x77, 0x65, 0xFC, 0x02,
+ 0x03, 0x35, 0xD9, 0xF3, 0x62,
+ 0x0D, 0x63, 0xD5, 0x7C, 0xF1,
+ 0x00, 0x08, 0x46, 0x05, 0x97,
+ 0x01, 0xBD, 0x37, 0x04, 0xC7,
+ 0x03, 0xFD, 0x10, 0x37, 0xE0,
+ 0x0E, 0xCA, 0x4D, 0xB2, 0x8C,
+ 0x01, 0x68, 0x7C, 0xD6, 0x59,
+ 0x03, 0xEE, 0x81, 0x47, 0x3F,
+ 0x02, 0xDE, 0xB4, 0xAE, 0x95,
+ 0x0D, 0xDC, 0x8F, 0xF4, 0x1E,
+ 0x02, 0x09, 0xAC, 0xE1, 0xFB,
+ 0x0E, 0x85, 0x78, 0x7F, 0x41,
+ 0x05, 0x8D, 0xDD, 0x84, 0xA3,
+ 0x08, 0xF3, 0xE6, 0x45, 0x48,
+ 0x03, 0x6A, 0xE1, 0xE2, 0x20,
+ 0x04, 0x8C, 0x27, 0x3C, 0xC3,
+ 0x02, 0x6E, 0xC5, 0x0A, 0x53,
+ 0x06, 0x48, 0xEF, 0xC9, 0xA9,
+ 0x00, 0x8E, 0x45, 0x1A, 0xDF,
+ 0x0B, 0x65, 0xE4, 0xB3, 0xC3,
+ 0x0D, 0x06, 0xB6, 0x6C, 0x16,
+ 0x0E, 0xAA, 0x06, 0xAB, 0xCB,
+ 0x0C, 0x1C, 0xE9, 0x3B, 0x35,
+ 0x0A, 0x99, 0x62, 0xC6, 0x4D,
+ 0x0E, 0x71, 0x5F, 0x83, 0xDF,
+ 0x0E, 0x20, 0x69, 0x43, 0x11,
+ 0x07, 0xCD, 0x8A, 0x87, 0xC4,
+ 0x05, 0xC4, 0xC6, 0x66, 0x63,
+ 0x02, 0x48, 0x15, 0x86, 0xF0,
+ 0x04, 0x8A, 0x95, 0xAB, 0xEC,
+ 0x0A, 0xD9, 0x13, 0x5D, 0xF0,
+ 0x02, 0xCC, 0xB6, 0xBF, 0x82,
+ 0x07, 0x59, 0x67, 0x81, 0xA7,
+ 0x05, 0x6D, 0x58, 0x2D, 0x4E,
+ 0x04, 0x0A, 0x57, 0x97, 0xB5,
+ 0x09, 0xD2, 0x7A, 0xE4, 0x39,
+ 0x0F, 0x85, 0xEC, 0x1A, 0x13,
+ 0x09, 0x7E, 0x81, 0xB3, 0x2E,
+ 0x0D, 0x13, 0x19, 0xAE, 0x8F,
+ 0x02, 0x94, 0xA7, 0x80, 0x2B,
+ 0x09, 0x88, 0x84, 0x47, 0x74,
+ 0x0C, 0xAB, 0x19, 0xEC, 0x3D,
+ 0x04, 0x2B, 0x4F, 0xD9, 0xEC,
+ 0x0F, 0x26, 0xA6, 0xE5, 0xF5,
+ 0x0D, 0x69, 0xBF, 0xC5, 0x04,
+ 0x00, 0xCF, 0x1F, 0x74, 0x9A,
+ 0x09, 0xB0, 0x5E, 0xFA, 0x28,
+ 0x05, 0x4F, 0xCE, 0xEC, 0x62,
+ 0x05, 0x97, 0x94, 0x48, 0x67,
+ 0x01, 0xDD, 0x62, 0xBB, 0xCB,
+ 0x07, 0x0F, 0xBC, 0x5C, 0xC8,
+ 0x05, 0x3B, 0x47, 0x19, 0xFC,
+ 0x06, 0x67, 0x1B, 0x57, 0x22,
+ 0x08, 0x80, 0x64, 0x63, 0xB9,
+ 0x0F, 0x9A, 0x33, 0xFE, 0x68,
+ 0x07, 0x1A, 0x51, 0xCD, 0xF4,
+ 0x05, 0xCC, 0x60, 0xEF, 0xE8,
+ 0x06, 0xFE, 0x88, 0x1D, 0xE5,
+ 0x0A, 0x3E, 0xE8, 0x33, 0x77,
+ 0x01, 0xB5, 0x31, 0x50, 0xFE,
+ 0x0F, 0x5C, 0x03, 0x67, 0x49,
+ 0x02, 0x29, 0x50, 0xCC, 0x97,
+ 0x06, 0x68, 0x77, 0x87, 0xFC,
+ 0x0E, 0xF8, 0xB9, 0x90, 0x4A,
+ 0x06, 0x8F, 0x3E, 0x6A, 0x8F,
+ 0x0E, 0x36, 0xAE, 0x21, 0xB8,
+ 0x0B, 0xC8, 0xCB, 0xFE, 0x11,
+ 0x07, 0xA6, 0xE4, 0x50, 0xAD,
+ 0x07, 0xCD, 0x36, 0x7D, 0x19,
+ 0x0D, 0x80, 0xC2, 0x50, 0x25,
+ 0x0D, 0x16, 0x3E, 0xCB, 0x3C,
+ 0x0C, 0xD0, 0xAB, 0x68, 0xB2,
+ 0x0A, 0x68, 0xE0, 0x52, 0xBC,
+ 0x01, 0x87, 0xAA, 0x13, 0xD3,
+ 0x09, 0xA1, 0x3B, 0xAE, 0xEC,
+ 0x00, 0xEF, 0x0E, 0x78, 0x3D,
+ 0x08, 0xF3, 0xC0, 0x96, 0x6D,
+ 0x0F, 0x7C, 0x18, 0xA9, 0x1C,
+ 0x07, 0x5A, 0x23, 0x44, 0x03,
+ 0x08, 0x04, 0x0A, 0xDA, 0xEF,
+ 0x01, 0xC8, 0xAE, 0x9A, 0x4F,
+ 0x05, 0x2C, 0x17, 0xF5, 0x30,
+ 0x01, 0x8C, 0xA3, 0x4D, 0x21,
+ 0x0C, 0x75, 0x96, 0x7F, 0x61,
+ 0x0A, 0x16, 0xD4, 0x0E, 0x18,
+ 0x05, 0x40, 0xA5, 0x79, 0x77,
+ 0x01, 0x9D, 0x23, 0xAF, 0x22,
+ 0x0A, 0xB8, 0xBE, 0x5B, 0x21,
+ 0x0F, 0x1F, 0x30, 0x7B, 0xE2,
+ 0x0E, 0xC3, 0x69, 0xD6, 0x7C,
+ 0x03, 0xB7, 0x39, 0x38, 0xD8,
+ 0x01, 0x98, 0x48, 0x08, 0x63,
+ 0x00, 0xCB, 0x78, 0xDE, 0xDB,
+ 0x01, 0x42, 0xB4, 0xFD, 0x92,
+ 0x0B, 0xF2, 0x6A, 0x63, 0x9D,
+ 0x09, 0x46, 0x97, 0xF4, 0x58,
+ 0x0B, 0x2C, 0xF8, 0xF7, 0x41,
+ 0x0D, 0xBB, 0x05, 0xAF, 0xAA,
+ 0x00, 0x4A, 0x32, 0xEE, 0x07,
+ 0x02, 0xCF, 0xFD, 0x44, 0x86,
+ 0x00, 0xBD, 0xB3, 0x45, 0x67,
+ 0x0F, 0xE0, 0xF7, 0xC2, 0x56,
+ 0x08, 0x93, 0xBD, 0xF5, 0x12,
+ 0x02, 0xA4, 0x71, 0xB5, 0x71,
+ 0x08, 0x11, 0xA8, 0x47, 0x93,
+ 0x0C, 0xE3, 0xFD, 0xB7, 0x62,
+ 0x09, 0x69, 0xFA, 0xA4, 0xB9,
+ 0x0D, 0x54, 0x28, 0x06, 0xF2,
+ 0x09, 0x2F, 0xEC, 0xB7, 0x16,
+ 0x01, 0x60, 0xD9, 0x0F, 0xD4,
+ 0x07, 0x09, 0x07, 0x5B, 0x48,
+ 0x05, 0xE5, 0xDC, 0x0E, 0x74,
+ 0x07, 0x38, 0xE9, 0x0C, 0x21,
+ 0x01, 0x60, 0xF1, 0xF8, 0x77,
+ 0x08, 0x6F, 0x6B, 0x99, 0x04,
+ 0x0B, 0x64, 0xF3, 0xE6, 0xDC,
+ 0x0C, 0xE3, 0x6A, 0xE6, 0xA2,
+ 0x09, 0x90, 0x6C, 0x27, 0xEA,
+ 0x02, 0xD3, 0x8E, 0x45, 0x0A,
+ 0x03, 0xF6, 0x49, 0x6F, 0xC9,
+ 0x00, 0x1A, 0x58, 0x61, 0xEB,
+ 0x05, 0xD7, 0x19, 0x2C, 0xBB,
+ 0x0E, 0xDD, 0xC6, 0xBA, 0xAC,
+ 0x0F, 0x3C, 0xAA, 0x25, 0xEB,
+ 0x01, 0xBE, 0x60, 0xE9, 0x7D,
+ 0x05, 0x12, 0x19, 0xC7, 0x84,
+ 0x0D, 0x0E, 0xF0, 0xEF, 0x83,
+ 0x0F, 0x17, 0x32, 0x3F, 0xC4,
+ 0x05, 0xE7, 0xCD, 0x8A, 0x11,
+ 0x02, 0xD5, 0xC4, 0xC4, 0xC0,
+ 0x00, 0x18, 0x8E, 0x55, 0x86,
+ 0x05, 0x5C, 0x6A, 0x15, 0xA7,
+ 0x04, 0x93, 0x5F, 0x9F, 0x53,
+ 0x00, 0x18, 0xCA, 0x22, 0x3D,
+ 0x02, 0xC7, 0x5B, 0x41, 0x4D,
+ 0x04, 0x8D, 0xA0, 0xD8, 0x2D,
+ 0x04, 0x5E, 0x0A, 0x5A, 0x57,
+ 0x0A, 0x3F, 0x9C, 0xFA, 0xEE,
+ 0x04, 0x33, 0x85, 0xE3, 0x87,
+ 0x01, 0xC1, 0xFF, 0x07, 0x8F,
+ 0x0E, 0x64, 0x12, 0x9D, 0x67,
+ 0x04, 0x1D, 0x8C, 0xAE, 0x08,
+ 0x0B, 0x89, 0x88, 0x8E, 0x5F,
+ 0x08, 0x1C, 0x0B, 0x01, 0x29,
+ 0x02, 0x92, 0x8C, 0x4F, 0x1D,
+ 0x09, 0xBF, 0x27, 0xA6, 0x6E,
+ 0x0D, 0x94, 0x6A, 0x7F, 0x4A,
+ 0x06, 0x7A, 0x7B, 0x19, 0xF4,
+ 0x02, 0x5A, 0x10, 0x56, 0xBA,
+ 0x08, 0x91, 0x15, 0x2E, 0x29,
+ 0x09, 0xA2, 0x7C, 0xD4, 0x58,
+ 0x0F, 0x8B, 0x7B, 0x34, 0x3B,
+ 0x0A, 0xFE, 0xCA, 0x7C, 0x9C,
+ 0x01, 0xA4, 0xFA, 0x4B, 0xDF,
+ 0x06, 0x2A, 0x47, 0x1D, 0x1D,
+ 0x07, 0x11, 0x04, 0x80, 0xA1,
+ 0x09, 0x56, 0x1F, 0xD3, 0x72,
+ 0x09, 0x54, 0xDF, 0xA2, 0x49,
+ 0x0F, 0xCD, 0xAF, 0x70, 0x61,
+ 0x08, 0xD2, 0xFF, 0x8F, 0x97,
+ 0x05, 0x9E, 0x39, 0x6C, 0xFF,
+ 0x0F, 0x60, 0x31, 0xF5, 0x90,
+ 0x01, 0xDC, 0x59, 0xC0, 0x27,
+ 0x00, 0xEB, 0x6C, 0x90, 0x0E,
+ 0x0E, 0xB4, 0x28, 0x77, 0x44,
+ 0x08, 0x1E, 0xF8, 0xBD, 0xD0,
+ 0x0E, 0x76, 0x8F, 0x3A, 0xEC,
+ 0x04, 0x8C, 0x36, 0xAE, 0x26,
+ 0x03, 0x01, 0xC8, 0xC2, 0x72,
+ 0x05, 0x36, 0x67, 0xE4, 0x10,
+ 0x0D, 0x3F, 0x64, 0x12, 0xF6,
+ 0x0A, 0x99, 0x82, 0xC2, 0xDB,
+ 0x0B, 0x7D, 0xDB, 0x3A, 0xCB,
+ 0x07, 0x7D, 0xD0, 0x6B, 0x6E,
+ 0x0D, 0x6B, 0xE8, 0xA0, 0x5C,
+ 0x0C, 0xBB, 0x97, 0xCE, 0x93,
+ 0x07, 0x51, 0x35, 0x1C, 0x25,
+ 0x0C, 0xD0, 0xEA, 0x0F, 0xF2,
+ 0x0D, 0xF1, 0x74, 0xA0, 0x5E,
+ 0x0D, 0x1E, 0x79, 0xD8, 0xA3,
+ 0x0C, 0x6D, 0x58, 0xCC, 0x4E,
+ 0x02, 0x11, 0x80, 0x65, 0x52,
+ 0x0F, 0x4D, 0xC8, 0x21, 0x90,
+ 0x0E, 0xC9, 0x2F, 0xF9, 0xFF,
+ 0x08, 0x01, 0x8C, 0xA3, 0x4B,
+ 0x03, 0xAC, 0x95, 0x96, 0x78,
+ 0x02, 0x21, 0x36, 0xC1, 0x82,
+ 0x07, 0xD5, 0x40, 0xB5, 0x79,
+ 0x01, 0x03, 0x9D, 0x37, 0x2E,
+ 0x04, 0x43, 0x38, 0x4E, 0x59,
+ 0x07, 0xAE, 0x9F, 0xE0, 0xFB,
+ 0x04, 0x97, 0xC1, 0x39, 0x5A,
+ 0x0A, 0x09, 0x11, 0x42, 0xB8,
+ 0x0C, 0x49, 0x38, 0xA8, 0x84,
+ 0x04, 0x79, 0x0A, 0xB0, 0x5E,
+ 0x0C, 0xE0, 0x82, 0xB4, 0x7D,
+ 0x02, 0x2B, 0x72, 0x7C, 0x64,
+ 0x03, 0x68, 0xC6, 0x81, 0xB6,
+ 0x08, 0xEB, 0x2C, 0xE7, 0x75,
+ 0x08, 0xB7, 0xDB, 0x08, 0x6F,
+ 0x0A, 0x81, 0x4A, 0xD4, 0xEC,
+ 0x0D, 0x3C, 0xD5, 0x5D, 0x40,
+ 0x08, 0xF0, 0x70, 0xB3, 0x43,
+ 0x07, 0x3F, 0xE0, 0xF7, 0xC5,
+ 0x05, 0x02, 0xB3, 0xB8, 0xAA,
+ 0x0B, 0x62, 0x24, 0x31, 0xB5,
+ 0x01, 0x31, 0x10, 0x08, 0x46,
+ 0x0A, 0x14, 0x81, 0xB1, 0x37,
+ 0x0A, 0xB4, 0xE9, 0xEB, 0xA4,
+ 0x0E, 0xEE, 0xB4, 0xC1, 0xC6,
+ 0x08, 0x8B, 0x8B, 0x68, 0xB5,
+ 0x0D, 0x59, 0xE3, 0xEE, 0x83,
+ 0x07, 0x77, 0xE7, 0x5F, 0x4B,
+ 0x02, 0x95, 0xE9, 0xDE, 0x8D,
+ 0x0D, 0x1C, 0x92, 0x85, 0x10,
+ 0x0B, 0x7D, 0xCC, 0x07, 0x70,
+ 0x03, 0xDD, 0xEF, 0x8B, 0x8E,
+ 0x0C, 0x0F, 0xC8, 0xF5, 0xA6,
+ 0x09, 0x7A, 0xE3, 0x6A, 0xFE,
+ 0x0A, 0x20, 0x14, 0x88, 0x6C,
+ 0x03, 0x43, 0x9A, 0x6E, 0x85,
+ 0x03, 0x5D, 0x16, 0x48, 0xB8,
+ 0x01, 0x01, 0x3C, 0x0A, 0x25,
+ 0x02, 0xDD, 0xF5, 0x63, 0x6C,
+ 0x0A, 0xC7, 0x1D, 0x06, 0x76,
+ 0x0D, 0x93, 0x5E, 0xAE, 0x4F,
+ 0x01, 0x0B, 0xBA, 0x91, 0x89,
+ 0x09, 0x75, 0x12, 0x1D, 0x82,
+ 0x04, 0xCD, 0x0A, 0xF4, 0xBF,
+ 0x03, 0x5F, 0xB7, 0x32, 0x09,
+ 0x0F, 0xD0, 0x27, 0xCD, 0x8A,
+ 0x03, 0xC6, 0xD1, 0xC0, 0x84,
+ 0x00, 0x21, 0x18, 0x4E, 0x55,
+ 0x07, 0xF5, 0x1C, 0x8E, 0xC2,
+ 0x0E, 0x6C, 0x72, 0xDE, 0x53,
+ 0x0A, 0x18, 0xD8, 0xCE, 0xB4,
+ 0x06, 0x24, 0x23, 0x59, 0xA7,
+ 0x05, 0xBC, 0xB8, 0xED, 0xF8,
+ 0x0F, 0x7D, 0x54, 0x0E, 0xD7,
+ 0x07, 0x70, 0x39, 0xD2, 0x7A,
+ 0x0B, 0x24, 0xF3, 0x85, 0xED,
+ 0x0A, 0x1D, 0xE1, 0xFF, 0x4D,
+ 0x07, 0x6E, 0xAC, 0x16, 0x1D,
+ 0x08, 0xCF, 0x9B, 0x15, 0x23,
+ 0x01, 0xAA, 0x63, 0x48, 0x9E,
+ 0x0A, 0x30, 0x94, 0xAF, 0x46,
+ 0x01, 0xB9, 0x14, 0x2A, 0x98,
+ 0x01, 0x8D, 0x1F, 0x20, 0xE6,
+ 0x0C, 0x21, 0x94, 0x69, 0x7C,
+ 0x03, 0x8E, 0xB6, 0xCB, 0x5F,
+ 0x0C, 0x1A, 0xDF, 0xB0, 0x5A,
+ 0x09, 0x28, 0xF0, 0xAB, 0x6E,
+ 0x09, 0x63, 0x64, 0xF5, 0x14,
+ 0x0B, 0x76, 0xCB, 0xDF, 0xF4,
+ 0x03, 0x41, 0xBE, 0x0E, 0xBC,
+ 0x0C, 0x59, 0x81, 0x3B, 0x47,
+ 0x0F, 0x36, 0x2A, 0x47, 0x1B,
+ 0x07, 0x13, 0x11, 0x00, 0x84,
+ 0x03, 0x39, 0x56, 0x1D, 0x93,
+ 0x0A, 0xE0, 0xF6, 0x9F, 0xF2,
+ 0x0B, 0xFF, 0xE5, 0x4C, 0xC0,
+ 0x08, 0x28, 0xD2, 0xFE, 0x8B,
+ 0x05, 0x65, 0x1E, 0x30, 0x28,
+ 0x0D, 0x31, 0xE2, 0xB9, 0xF5,
+ 0x0A, 0x2E, 0x14, 0x5D, 0xE0,
+ 0x0B, 0x49, 0xEA, 0x28, 0x93,
+ 0x06, 0x91, 0x36, 0x68, 0x37,
+ 0x0D, 0xFB, 0x55, 0xF8, 0xF9,
+ 0x08, 0xCA, 0xD4, 0x82, 0x7E,
+ 0x04, 0xD5, 0x2E, 0x3B, 0x6E,
+ 0x0E, 0xAB, 0xA1, 0x05, 0x02,
+ 0x02, 0xAC, 0x37, 0xAB, 0xE0,
+ 0x00, 0xAD, 0x3F, 0x60, 0xD3,
+ 0x07, 0x1D, 0xD7, 0x84, 0xBD,
+ 0x0A, 0x23, 0x5A, 0x1B, 0x7E,
+ 0x00, 0xBB, 0x33, 0xD6, 0xE8,
+ 0x05, 0x47, 0xCC, 0xE4, 0xBD,
+ 0x02, 0xBC, 0xBD, 0x8F, 0x87,
+ 0x03, 0xD7, 0x51, 0xA1, 0xD6,
+ 0x0F, 0x6C, 0xD0, 0x69, 0x85,
+ 0x08, 0x3D, 0xF1, 0x70, 0x64,
+ 0x0C, 0x6E, 0x3D, 0x7E, 0x4B,
+ 0x01, 0x1E, 0x4D, 0x1C, 0x98,
+ 0x0E, 0x04, 0xDA, 0x04, 0xE1,
+ 0x00, 0xEF, 0xED, 0xC8, 0xA1,
+ 0x0A, 0x7E, 0xC9, 0xAD, 0x0B,
+ 0x05, 0x33, 0x01, 0x5E, 0x21,
+ 0x0B, 0xFA, 0x2C, 0x77, 0x14,
+ 0x08, 0xFB, 0xA0, 0xD5, 0x99,
+ 0x09, 0x50, 0x82, 0xC4, 0xEF,
+ 0x02, 0xF0, 0x54, 0x1B, 0x54,
+ 0x0E, 0xA2, 0x47, 0x36, 0x17,
+ 0x09, 0xA1, 0xDB, 0x9C, 0xF5,
+ 0x00, 0x65, 0xBB, 0x4F, 0xED,
+ 0x0A, 0x3C, 0xF5, 0x37, 0x98,
+ 0x03, 0x5D, 0xE5, 0x9E, 0xFB,
+ 0x04, 0x23, 0x0E, 0x4C, 0x7A,
+ 0x0C, 0x9B, 0x94, 0xC4, 0x74,
+ 0x0D, 0x92, 0x5B, 0xF1, 0x29,
+ 0x06, 0x63, 0x99, 0x4A, 0xAD,
+ 0x04, 0xB8, 0x4B, 0x2C, 0xC3,
+ 0x0E, 0xC2, 0xCD, 0x39, 0x85,
+ 0x06, 0xA8, 0x81, 0x4C, 0x72,
+ 0x04, 0x01, 0xEC, 0xCF, 0x55,
+ 0x04, 0x86, 0x77, 0x3D, 0xB9,
+ 0x03, 0xBC, 0x3F, 0xE4, 0x3D,
+ 0x0F, 0xCA, 0x5B, 0xD3, 0xB5,
+ 0x00, 0x70, 0x02, 0x26, 0xF1,
+ 0x0C, 0x73, 0x55, 0x10, 0xC8,
+ 0x06, 0x13, 0x96, 0xE3, 0x07,
+ 0x07, 0x22, 0x86, 0xED, 0x31,
+ 0x0E, 0xB1, 0x3D, 0x54, 0xCE,
+ 0x06, 0x32, 0x8D, 0x2F, 0xD2,
+ 0x08, 0xD6, 0x98, 0xE1, 0x6E,
+ 0x0A, 0xD9, 0x32, 0x0B, 0x9F,
+ 0x0F, 0x04, 0x4E, 0x65, 0xCC,
+ 0x0E, 0x74, 0x9E, 0xB6, 0xBB,
+ 0x0C, 0xE1, 0x7A, 0xE8, 0x0D,
+ 0x08, 0x7F, 0xC1, 0xE1, 0xC2,
+ 0x09, 0x04, 0xA7, 0x6A, 0x40,
+ 0x0F, 0x45, 0xAC, 0xE3, 0x5B,
+ 0x0B, 0x60, 0x06, 0x12, 0x0C,
+ 0x0D, 0x2C, 0x22, 0x7A, 0x6C,
+ 0x0C, 0x0A, 0x13, 0xF8, 0xC9,
+ 0x05, 0xCF, 0x48, 0x98, 0x4C,
+ 0x0C, 0x1A, 0x9F, 0xDD, 0xA3,
+ 0x06, 0xB5, 0x26, 0xDD, 0x46,
+ 0x06, 0xEC, 0x16, 0xB2, 0x9B,
+ 0x0B, 0xAB, 0x06, 0xB8, 0x1C,
+ 0x09, 0x3D, 0x75, 0x3C, 0x04,
+ 0x0E, 0xF6, 0xCC, 0xCE, 0xFE,
+ 0x07, 0x03, 0x6B, 0x17, 0xB2,
+ 0x01, 0xCC, 0xF1, 0xE7, 0x4D,
+ 0x00, 0x97, 0x20, 0x55, 0xC0,
+ 0x0D, 0x40, 0xE1, 0x14, 0x0E,
+ 0x0F, 0x80, 0x11, 0x5C, 0xCA,
+ 0x0D, 0x27, 0x4C, 0x92, 0xDF,
+ 0x03, 0x53, 0x34, 0x18, 0xCA,
+ 0x04, 0xBF, 0xAE, 0xC7, 0x59,
+ 0x05, 0x8F, 0xBE, 0x0B, 0x2D,
+ 0x00, 0xAD, 0xD9, 0x54, 0x8A,
+ 0x07, 0x06, 0xD0, 0x37, 0x9B,
+ 0x03, 0x6B, 0xC4, 0x3F, 0x85,
+ 0x04, 0x90, 0x7D, 0xEC, 0x3F,
+ 0x07, 0xBE, 0x2E, 0x42, 0x50,
+ 0x07, 0xA5, 0x2E, 0x9B, 0x11,
+ 0x03, 0x8D, 0xAB, 0x87, 0x4C,
+ 0x00, 0x42, 0x32, 0x9C, 0xEE,
+ 0x06, 0x6E, 0xD9, 0x99, 0xA8,
+ 0x07, 0xD9, 0xA4, 0x33, 0xA6,
+ 0x0C, 0x66, 0xDC, 0x94, 0x49,
+ 0x06, 0x45, 0x4E, 0xB2, 0x0F,
+ 0x07, 0xF4, 0xBF, 0xD9, 0x30,
+ 0x01, 0x7D, 0xC8, 0x90, 0x25,
+ 0x0E, 0xE0, 0x73, 0xA2, 0x46,
+ 0x02, 0x48, 0x65, 0x09, 0x5B,
+ 0x0C, 0x33, 0x43, 0xF3, 0xCF,
+ 0x0D, 0x04, 0x08, 0x25, 0xC9,
+ 0x07, 0x9F, 0x36, 0x2E, 0x76,
+ 0x05, 0xD7, 0xDE, 0x11, 0x00,
+ 0x04, 0x61, 0x3B, 0x76, 0x12,
+ 0x03, 0x72, 0x28, 0x7A, 0xCC,
+ 0x0A, 0xCB, 0xDE, 0x4D, 0xC6,
+ 0x09, 0xE3, 0xC8, 0xD2, 0x7E,
+ 0x0B, 0x1D, 0x65, 0xAD, 0x3D,
+ 0x08, 0x35, 0xB7, 0x26, 0xEE,
+ 0x05, 0x50, 0x29, 0x59, 0x87,
+ 0x0C, 0xF8, 0xB6, 0x17, 0xAB,
+ 0x09, 0xCE, 0xD7, 0xB6, 0x28,
+ 0x03, 0x87, 0xFC, 0x18, 0x7B,
+ 0x01, 0x10, 0xEA, 0x76, 0x0F,
+ 0x0E, 0xB6, 0x74, 0x83, 0xB2,
+ 0x04, 0x20, 0xDC, 0x81, 0x0A,
+ 0x0A, 0xF2, 0x0C, 0x39, 0x26,
+ 0x0E, 0x56, 0x53, 0xBF, 0x44,
+ 0x0E, 0x7E, 0xFA, 0x9B, 0x00,
+ 0x0C, 0x57, 0x5E, 0xFD, 0x1E,
+ 0x00, 0x0B, 0x3F, 0xF0, 0x24,
+ 0x03, 0xEE, 0x61, 0x6A, 0x6A,
+ 0x0B, 0xD4, 0x1B, 0xBB, 0x81,
+ 0x0E, 0x93, 0xD7, 0x5D, 0xAB,
+ 0x08, 0x2F, 0x6C, 0xD6, 0x6F,
+ 0x0F, 0xF8, 0x3D, 0xF1, 0x73,
+ 0x01, 0x94, 0x2D, 0x1E, 0x7C,
+ 0x00, 0x2B, 0x5C, 0x61, 0x9C,
+ 0x06, 0x42, 0xFC, 0x91, 0x8C,
+ 0x0C, 0x58, 0xAF, 0x41, 0x08,
+ 0x08, 0x5A, 0xBE, 0xC9, 0x6D,
+ 0x01, 0x37, 0x33, 0x0D, 0x8C,
+ 0x03, 0x4B, 0xFA, 0x3A, 0xF7,
+ 0x06, 0x78, 0xFB, 0xA3, 0xE0,
+ 0x0D, 0x82, 0xD5, 0xD5, 0x04,
+ 0x0F, 0x7F, 0x87, 0x83, 0x8D,
+ 0x0B, 0xAE, 0xA3, 0xC3, 0x09,
+ 0x06, 0xD1, 0x21, 0xD3, 0xDF,
+ 0x08, 0x79, 0xE2, 0xEA, 0x01,
+ 0x05, 0xDA, 0x39, 0xB9, 0xB2,
+ 0x0A, 0xB8, 0x7A, 0xB6, 0x98,
+ 0x00, 0x85, 0x83, 0x09, 0x8A,
+ 0x00, 0xDE, 0x9B, 0x91, 0x06,
+ 0x04, 0xFD, 0x92, 0x58, 0x81,
+ 0x01, 0xE1, 0x64, 0x94, 0xC3,
+ 0x09, 0x74, 0x95, 0xEB, 0x2C,
+ 0x01, 0xF7, 0x41, 0x99, 0xE6,
+ 0x05, 0xAF, 0xAE, 0xBD, 0x19,
+ 0x00, 0xEE, 0x03, 0x0A, 0xCF,
+ 0x0F, 0x44, 0x82, 0x30, 0x3D,
+ 0x00, 0x43, 0x7C, 0x0F, 0x60,
+ 0x04, 0xC4, 0x00, 0xB2, 0xD3,
+ 0x07, 0x78, 0x3F, 0x52, 0x24,
+ 0x02, 0xB4, 0xBD, 0x11, 0x90,
+ 0x0B, 0x47, 0xD3, 0x95, 0xE1,
+ 0x0C, 0x36, 0xE2, 0x85, 0x69,
+ 0x0A, 0x25, 0x77, 0xE4, 0xD4,
+ 0x05, 0xD7, 0x92, 0x81, 0x2F,
+ 0x00, 0xB3, 0xD6, 0x55, 0xE3,
+ 0x0E, 0x83, 0x5B, 0x50, 0x89,
+ 0x05, 0x52, 0x04, 0x95, 0xF5,
+ 0x07, 0x89, 0x13, 0x1A, 0x79,
+ 0x09, 0x0C, 0xE1, 0x78, 0x54,
+ 0x07, 0x78, 0x7F, 0xCC, 0xEA,
+ 0x03, 0x99, 0x84, 0xA7, 0x68,
+ 0x0B, 0x66, 0x65, 0x48, 0xE3,
+ 0x04, 0x62, 0xAF, 0x20, 0x10,
+ 0x0C, 0x27, 0x28, 0xED, 0x67,
+ 0x06, 0x44, 0x8A, 0xCF, 0xF6,
+ 0x0F, 0x6F, 0xC9, 0x89, 0x18,
+ 0x0A, 0x65, 0x1A, 0x5F, 0x51,
+ 0x04, 0xAC, 0x73, 0xC7, 0x5D,
+ 0x07, 0xB6, 0x2C, 0x12, 0xBD,
+ 0x0B, 0x85, 0xCB, 0xCB, 0xB1,
+ 0x0C, 0xE9, 0x3D, 0x73, 0x98,
+ 0x01, 0xC0, 0xF6, 0xCD, 0xCE,
+ 0x0A, 0xF8, 0x9B, 0xDF, 0x15,
+ 0x06, 0x09, 0x4E, 0xD7, 0x67,
+ 0x09, 0x8A, 0x91, 0xC0, 0x15,
+ 0x04, 0x45, 0xE0, 0x2F, 0x51,
+ 0x0E, 0xD4, 0x27, 0x74, 0xDC,
+ 0x02, 0x15, 0x26, 0x6C, 0xD2,
+ 0x06, 0x99, 0x51, 0x3D, 0xD8,
+ 0x00, 0x33, 0xAF, 0x22, 0xC3,
+ 0x02, 0xE1, 0x28, 0xB6, 0x89,
+ 0x0D, 0xD8, 0x2F, 0x7D, 0x09,
+ 0x02, 0x5F, 0x12, 0x7D, 0xF9,
+ 0x00, 0x7A, 0xEC, 0xA2, 0xB3,
+ 0x05, 0xED, 0x98, 0x9D, 0xE1,
+ 0x0E, 0x07, 0x7B, 0xAE, 0x64,
+ 0x03, 0x9C, 0x66, 0x4F, 0xA0,
+ 0x0D, 0xA1, 0xCD, 0xAB, 0x49,
+ 0x08, 0x62, 0x62, 0x30, 0x6D,
+ 0x0B, 0x0D, 0xE9, 0x3F, 0x9E,
+ 0x0B, 0x4F, 0xDB, 0x21, 0xF5,
+ 0x0C, 0xA1, 0x44, 0x31, 0x96,
+ 0x09, 0x7F, 0x45, 0x82, 0x89,
+ 0x01, 0x9F, 0xB9, 0x1A, 0xDB,
+ 0x09, 0xDA, 0x1A, 0xA8, 0x94,
+ 0x06, 0x2C, 0x80, 0x7F, 0xE4,
+ 0x0F, 0xD3, 0x6A, 0xE7, 0x03,
+ 0x0B, 0x34, 0x3B, 0xCF, 0xBC,
+ 0x07, 0x7E, 0x5C, 0xD4, 0x25,
+ 0x01, 0x40, 0xBF, 0x36, 0x3A,
+ 0x0F, 0x13, 0xD7, 0x1E, 0xD1,
+ 0x0C, 0x84, 0x66, 0xB9, 0x55,
+ 0x02, 0x53, 0x92, 0x26, 0x56,
+ 0x06, 0x33, 0xAB, 0x7E, 0x0D,
+ 0x05, 0xC0, 0xA3, 0x24, 0x17,
+ 0x07, 0x81, 0x5D, 0x68, 0x5E,
+ 0x0E, 0xE8, 0x35, 0xBB, 0xE4,
+ 0x05, 0xF5, 0x50, 0x2D, 0xEC,
+ 0x03, 0x40, 0x2A, 0x49, 0xEB,
+ 0x08, 0x90, 0xCE, 0x33, 0x6B,
+ 0x00, 0xF7, 0x27, 0xFC, 0x9E,
+ 0x08, 0xB9, 0x94, 0x4A, 0x87,
+ 0x07, 0xBC, 0x48, 0x54, 0x0E,
+ 0x0F, 0xAE, 0xE6, 0x2C, 0xC1,
+ 0x02, 0xC5, 0x18, 0x2C, 0x77,
+ 0x0F, 0xE4, 0x94, 0xAB, 0x7F,
+ 0x0E, 0x91, 0x96, 0x1A, 0x9B,
+ 0x09, 0xC6, 0x95, 0xAB, 0x7D,
+ 0x0C, 0x3D, 0xA1, 0xBC, 0x5D,
+ 0x00, 0x6B, 0x6A, 0xC1, 0x6B,
+ 0x00, 0xA7, 0x38, 0x3C, 0xBA,
+ 0x09, 0xCC, 0x93, 0xDB, 0x51,
+ 0x01, 0x9C, 0x2B, 0x4A, 0x92,
+ 0x05, 0x08, 0xDF, 0xBD, 0xE1,
+ 0x03, 0x20, 0x94, 0xE1, 0xDA,
+ 0x0C, 0xD8, 0xA9, 0x11, 0x68,
+ 0x0C, 0x4C, 0x44, 0x02, 0xE2,
+ 0x0D, 0x65, 0xB8, 0x6F, 0x4D,
+ 0x00, 0xA9, 0xDA, 0x73, 0x09,
+ 0x03, 0x79, 0xF8, 0x33, 0x01,
+ 0x0C, 0xA3, 0x49, 0xDA, 0x25,
+ 0x05, 0x96, 0x78, 0xE7, 0xF7,
+ 0x0F, 0x74, 0x62, 0xE7, 0x5F,
+ 0x04, 0xA5, 0x79, 0x77, 0x83,
+ 0x09, 0x27, 0xAE, 0xA2, 0xC3,
+ 0x08, 0xDE, 0x79, 0xAF, 0x97,
+ 0x0E, 0xF0, 0xBA, 0x62, 0xE6,
+ 0x09, 0x2B, 0xDB, 0xB0, 0xF9,
+ 0x01, 0x52, 0x39, 0x4C, 0xFA,
+ 0x08, 0x88, 0x06, 0x05, 0x8B,
+ 0x00, 0xB7, 0xEC, 0x9B, 0x81,
+ 0x02, 0xB4, 0xFF, 0x9E, 0xDF,
+ 0x0A, 0xE8, 0x06, 0x8F, 0xD9,
+ 0x06, 0x97, 0xF4, 0xD6, 0x21,
+ 0x0C, 0xF1, 0xF5, 0x45, 0x67,
+ 0x01, 0x02, 0xE3, 0xAA, 0x89,
+ 0x0A, 0xF2, 0xEE, 0x0A, 0x7F,
+ 0x07, 0x4D, 0xC4, 0x8B, 0xB0,
+ 0x03, 0x33, 0x8E, 0xBC, 0x3F,
+ 0x08, 0x77, 0x65, 0xDC, 0x02,
+ 0x08, 0x32, 0xDE, 0xF3, 0x6E,
+ 0x0C, 0xF1, 0x15, 0x51, 0xB1,
+ 0x0B, 0x8E, 0xE1, 0x15, 0x24,
+ 0x01, 0xBD, 0x27, 0x20, 0x48,
+ 0x05, 0xC1, 0x24, 0xB7, 0xFD,
+ 0x04, 0xCC, 0x0E, 0x30, 0x40,
+ 0x0F, 0xE8, 0xB9, 0xD6, 0x59,
+ 0x01, 0xEE, 0x8B, 0x57, 0x36,
+ 0x09, 0x5F, 0x5D, 0x0E, 0xD5,
+ 0x07, 0x74, 0xBE, 0x72, 0x1E,
+ 0x09, 0xA1, 0xCC, 0xE7, 0xFB,
+ 0x07, 0x2F, 0x98, 0x7F, 0xC1,
+ 0x0F, 0x23, 0x39, 0x12, 0xE5,
+ 0x08, 0xF3, 0xE6, 0xD3, 0xCA,
+ 0x03, 0x6A, 0xE2, 0x74, 0xE2,
+ 0x00, 0x8C, 0x27, 0x0C, 0x81,
+ 0x02, 0x6C, 0x45, 0x06, 0xD3,
+ 0x0C, 0x4E, 0x54, 0x49, 0xB9,
+ 0x03, 0x0C, 0x65, 0x1A, 0x5F,
+ 0x0D, 0x7C, 0x53, 0x4F, 0xF6,
+ 0x01, 0x03, 0x66, 0xEC, 0x12,
+ 0x04, 0x6A, 0x85, 0x25, 0x44,
+ 0x08, 0x1C, 0xE9, 0x21, 0x37,
+ 0x0E, 0x1F, 0xF2, 0xF6, 0xC9,
+ 0x04, 0x30, 0xBF, 0x8D, 0x4D,
+ 0x07, 0x32, 0x09, 0x52, 0x93,
+ 0x0C, 0xCD, 0x8A, 0x91, 0xC6,
+ 0x09, 0xC4, 0x2D, 0xC0, 0x28,
+ 0x08, 0x4E, 0x55, 0x86, 0xFE,
+ 0x00, 0x8A, 0xFF, 0x67, 0xE5,
+ 0x02, 0xDF, 0x91, 0x53, 0x3A,
+ 0x08, 0xCA, 0x34, 0xB2, 0xE6,
+ 0x0D, 0xB9, 0x7C, 0x01, 0x20,
+ 0x0D, 0x6D, 0xD8, 0x3D, 0x7F,
+ 0x0F, 0x0A, 0x57, 0x97, 0x70,
+ 0x01, 0x52, 0xDA, 0xEA, 0x24,
+ 0x0A, 0x05, 0x0D, 0x9A, 0x1D,
+ 0x0F, 0x7F, 0xCA, 0xBE, 0x2E,
+ 0x04, 0x12, 0x9D, 0xBD, 0xD2,
+ 0x02, 0x94, 0xC3, 0xA1, 0xBA,
+ 0x0F, 0x88, 0x80, 0x42, 0xB0,
+ 0x0A, 0xAB, 0x0D, 0xE9, 0x39,
+ 0x04, 0x5B, 0xCF, 0xD9, 0x25,
+ 0x0F, 0x57, 0x26, 0x60, 0x31,
+ 0x0D, 0x6B, 0x1F, 0x45, 0x4E,
+ 0x08, 0xC8, 0x4B, 0x74, 0x18,
+ 0x03, 0x01, 0xFA, 0xFC, 0xA8,
+ 0x0C, 0xA7, 0xAE, 0xE6, 0x73,
+ 0x0C, 0xFC, 0x54, 0x48, 0xE7,
+ 0x02, 0xD1, 0x54, 0x36, 0x03,
+ 0x0E, 0x0F, 0x7C, 0x5C, 0xC8,
+ 0x05, 0x3B, 0x47, 0xB9, 0x34,
+ 0x00, 0x40, 0x54, 0x57, 0x17,
+ 0x0A, 0x00, 0x84, 0x61, 0x39,
+ 0x0F, 0x9B, 0x31, 0x7E, 0x28,
+ 0x0E, 0x1F, 0x12, 0x5B, 0xFE,
+ 0x03, 0xCC, 0x0D, 0x63, 0x28,
+ 0x0B, 0x7F, 0x6B, 0x11, 0x65,
+ 0x06, 0x3C, 0xC8, 0x25, 0x06,
+ 0x0A, 0xB2, 0xAE, 0x50, 0x2B,
+ 0x06, 0xDD, 0x60, 0xEB, 0x09,
+ 0x03, 0xAA, 0xF0, 0xC2, 0x97,
+ 0x0C, 0x6F, 0x2F, 0x07, 0xF8,
+ 0x0E, 0xF8, 0xBB, 0x90, 0x4A,
+ 0x0D, 0x8F, 0x3E, 0x62, 0x49,
+ 0x0C, 0x36, 0xAE, 0x2A, 0xE2,
+ 0x08, 0x88, 0x26, 0x7E, 0x6C,
+ 0x07, 0x86, 0x64, 0x50, 0xAD,
+ 0x0F, 0x46, 0x96, 0xFC, 0x9A,
+ 0x03, 0x87, 0xA6, 0x51, 0xA7,
+ 0x04, 0x97, 0xBA, 0xC9, 0xBC,
+ 0x06, 0xD0, 0x6B, 0x62, 0xD0,
+ 0x02, 0xE8, 0x84, 0x52, 0x4D,
+ 0x01, 0x86, 0xAC, 0x93, 0xDF,
+ 0x09, 0xA1, 0x3C, 0x23, 0x2C,
+ 0x09, 0xED, 0x2B, 0xF8, 0xCC,
+ 0x0B, 0x74, 0x43, 0x14, 0xEF,
+ 0x06, 0xFC, 0x78, 0xA5, 0x5C,
+ 0x05, 0xDE, 0x68, 0x48, 0x42,
+ 0x08, 0x84, 0x21, 0x58, 0xAF,
+ 0x0F, 0xC8, 0xA5, 0x5E, 0x3E,
+ 0x09, 0x2D, 0xF9, 0x35, 0xEA,
+ 0x00, 0xA5, 0x63, 0x4B, 0xFA,
+ 0x06, 0x72, 0xF1, 0x78, 0xF3,
+ 0x09, 0xD6, 0x1D, 0x82, 0xD7,
+ 0x0E, 0x40, 0xA5, 0x79, 0x77,
+ 0x09, 0x5D, 0x26, 0x20, 0x71,
+ 0x03, 0x38, 0x5E, 0xF9, 0x22,
+ 0x0E, 0x1F, 0xF0, 0x5B, 0xA0,
+ 0x06, 0x41, 0x29, 0xDA, 0x3C,
+ 0x09, 0xB1, 0x52, 0x38, 0xDA,
+ 0x03, 0x98, 0x88, 0x04, 0x23,
+ 0x0B, 0xCA, 0xB0, 0xD8, 0xDB,
+ 0x09, 0xC2, 0x14, 0xFD, 0x12,
+ 0x0B, 0x73, 0xCA, 0x62, 0xDE,
+ 0x03, 0x41, 0xB9, 0xF4, 0x59
+};
+
+static unsigned char ak77dspPRAM[] = {
+ 0x0C, 0x94, 0xED, 0x1E, 0x74,
+ 0x04, 0xA8, 0x9C, 0x6D, 0x55,
+ 0x00, 0x44, 0x02, 0x11, 0x99,
+ 0x09, 0x58, 0x6F, 0x4D, 0xD0,
+ 0x01, 0x5A, 0x7C, 0xC9, 0x27,
+ 0x09, 0x35, 0x31, 0x01, 0x86,
+ 0x03, 0x4B, 0xFA, 0x2C, 0x75,
+ 0x06, 0x78, 0xFB, 0xA8, 0xF4,
+ 0x0D, 0x82, 0xD7, 0xDD, 0xE0,
+ 0x05, 0x79, 0x77, 0x0B, 0x3C,
+ 0x08, 0xAE, 0xA2, 0x43, 0x38
+};
+
+u8 cram_data[] = {
+ 0x7F, 0xFF, 0xF0,
+ 0x7F, 0xFD, 0x90,
+ 0x7F, 0xF6, 0x20,
+ 0x7F, 0xE9, 0xD0,
+ 0x7F, 0xD8, 0x80,
+ 0x7F, 0xC2, 0x50,
+ 0x7F, 0xA7, 0x30,
+ 0x7F, 0x87, 0x30,
+ 0x7F, 0x62, 0x30,
+ 0x7F, 0x38, 0x50,
+ 0x7F, 0x09, 0x90,
+ 0x7E, 0xD5, 0xE0,
+ 0x7E, 0x9D, 0x50,
+ 0x7E, 0x5F, 0xE0,
+ 0x7E, 0x1D, 0x90,
+ 0x7D, 0xD6, 0x60,
+ 0x7D, 0x8A, 0x60,
+ 0x7D, 0x39, 0x80,
+ 0x7C, 0xE3, 0xD0,
+ 0x7C, 0x89, 0x50,
+ 0x7C, 0x2A, 0x00,
+ 0x7B, 0xC5, 0xE0,
+ 0x7B, 0x5D, 0x00,
+ 0x7A, 0xEF, 0x60,
+ 0x7A, 0x7D, 0x00,
+ 0x7A, 0x05, 0xF0,
+ 0x79, 0x8A, 0x20,
+ 0x79, 0x09, 0xB0,
+ 0x78, 0x84, 0x80,
+ 0x77, 0xFA, 0xC0,
+ 0x77, 0x6C, 0x50,
+ 0x76, 0xD9, 0x50,
+ 0x76, 0x41, 0xB0,
+ 0x75, 0xA5, 0x80,
+ 0x75, 0x04, 0xD0,
+ 0x74, 0x5F, 0xA0,
+ 0x73, 0xB5, 0xF0,
+ 0x73, 0x07, 0xC0,
+ 0x72, 0x55, 0x30,
+ 0x71, 0x9E, 0x30,
+ 0x70, 0xE2, 0xD0,
+ 0x70, 0x23, 0x10,
+ 0x6F, 0x5F, 0x00,
+ 0x6E, 0x96, 0xB0,
+ 0x6D, 0xCA, 0x10,
+ 0x6C, 0xF9, 0x30,
+ 0x6C, 0x24, 0x30,
+ 0x6B, 0x4A, 0xF0,
+ 0x6A, 0x6D, 0xA0,
+ 0x69, 0x8C, 0x20,
+ 0x68, 0xA6, 0xA0,
+ 0x67, 0xBD, 0x10,
+ 0x66, 0xCF, 0x80,
+ 0x65, 0xDE, 0x00,
+ 0x64, 0xE8, 0x90,
+ 0x63, 0xEF, 0x30,
+ 0x62, 0xF2, 0x00,
+ 0x61, 0xF1, 0x00,
+ 0x60, 0xEC, 0x40,
+ 0x5F, 0xE3, 0xB0,
+ 0x5E, 0xD7, 0x80,
+ 0x5D, 0xC7, 0xA0,
+ 0x5C, 0xB4, 0x20,
+ 0x5B, 0x9D, 0x10,
+ 0x5A, 0x82, 0x80,
+ 0x59, 0x64, 0x60,
+ 0x58, 0x42, 0xE0,
+ 0x57, 0x1D, 0xF0,
+ 0x55, 0xF5, 0xA0,
+ 0x54, 0xCA, 0x10,
+ 0x53, 0x9B, 0x30,
+ 0x52, 0x69, 0x10,
+ 0x51, 0x33, 0xD0,
+ 0x4F, 0xFB, 0x60,
+ 0x4E, 0xBF, 0xF0,
+ 0x4D, 0x81, 0x60,
+ 0x4C, 0x3F, 0xE0,
+ 0x4A, 0xFB, 0x70,
+ 0x49, 0xB4, 0x10,
+ 0x48, 0x69, 0xE0,
+ 0x47, 0x1C, 0xF0,
+ 0x45, 0xCD, 0x30,
+ 0x44, 0x7A, 0xD0,
+ 0x43, 0x25, 0xC0,
+ 0x41, 0xCE, 0x20,
+ 0x40, 0x73, 0xF0,
+ 0x3F, 0x17, 0x50,
+ 0x3D, 0xB8, 0x30,
+ 0x3C, 0x56, 0xC0,
+ 0x3A, 0xF2, 0xF0,
+ 0x39, 0x8C, 0xE0,
+ 0x38, 0x24, 0x90,
+ 0x36, 0xBA, 0x20,
+ 0x35, 0x4D, 0x90,
+ 0x33, 0xDE, 0xF0,
+ 0x32, 0x6E, 0x50,
+ 0x30, 0xFB, 0xC0,
+ 0x2F, 0x87, 0x50,
+ 0x2E, 0x11, 0x10,
+ 0x2C, 0x99, 0x00,
+ 0x2B, 0x1F, 0x30,
+ 0x29, 0xA3, 0xC0,
+ 0x28, 0x26, 0xC0,
+ 0x26, 0xA8, 0x20,
+ 0x25, 0x28, 0x10,
+ 0x23, 0xA6, 0x90,
+ 0x22, 0x23, 0xA0,
+ 0x20, 0x9F, 0x70,
+ 0x1F, 0x1A, 0x00,
+ 0x1D, 0x93, 0x50,
+ 0x1C, 0x0B, 0x80,
+ 0x1A, 0x82, 0xA0,
+ 0x18, 0xF8, 0xC0,
+ 0x17, 0x6D, 0xE0,
+ 0x15, 0xE2, 0x10,
+ 0x14, 0x55, 0x70,
+ 0x12, 0xC8, 0x10,
+ 0x11, 0x39, 0xF0,
+ 0x0F, 0xAB, 0x20,
+ 0x0E, 0x1B, 0xC0,
+ 0x0C, 0x8B, 0xD0,
+ 0x0A, 0xFB, 0x70,
+ 0x09, 0x6A, 0x90,
+ 0x07, 0xD9, 0x60,
+ 0x06, 0x47, 0xE0,
+ 0x04, 0xB6, 0x20,
+ 0x03, 0x24, 0x30,
+ 0x01, 0x92, 0x20,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x7F, 0xFF, 0xF0,
+ 0x40, 0x00, 0x00,
+ 0x6C, 0xCC, 0xD0,
+ 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x60,
+ 0x40, 0x00, 0x00,
+ 0x3C, 0x00, 0x00,
+ 0x03, 0x33, 0x30,
+ 0x14, 0x7A, 0xE0,
+ 0x00, 0x09, 0x00,
+ 0x68, 0x00, 0x00,
+ 0x18, 0x00, 0x00,
+ 0x00, 0x06, 0x00,
+ 0x41, 0xE3, 0x50,
+ 0x40, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x7E, 0x14, 0x80,
+ 0x0E, 0xB8, 0x50,
+ 0x08, 0x29, 0x60,
+ 0x08, 0x29, 0x60,
+ 0x00, 0x06, 0x00,
+ 0x43, 0xC8, 0x50,
+ 0x40, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x7D, 0xF3, 0xB0,
+ 0x10, 0x00, 0x00,
+ 0x09, 0xDA, 0xF0,
+ 0x09, 0xDA, 0xF0,
+ 0x00, 0x07, 0x00,
+ 0x43, 0xC8, 0x50,
+ 0x40, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x7D, 0xF3, 0xB0,
+ 0x11, 0x68, 0x70,
+ 0x0A, 0xB9, 0xA0,
+ 0x0A, 0xB9, 0xA0,
+ 0x00, 0x13, 0x00,
+ 0x43, 0xC8, 0x50,
+ 0x40, 0x00, 0x00,
+ 0x0A, 0xCC, 0xD0,
+ 0x7D, 0xD2, 0xF0,
+ 0x0D, 0x70, 0xA0,
+ 0x08, 0x46, 0xF0,
+ 0x08, 0x46, 0xF0,
+ 0x00, 0x13, 0x00,
+ 0x43, 0xC8, 0x50,
+ 0x40, 0x00, 0x00,
+ 0x0E, 0x66, 0x60,
+ 0x7D, 0xB2, 0x30,
+ 0x0C, 0x49, 0xC0,
+ 0x07, 0xF8, 0x00,
+ 0x07, 0xF8, 0x00,
+ 0x00, 0x13, 0x00,
+ 0x43, 0xC8, 0x50,
+ 0x40, 0x00, 0x00,
+ 0x12, 0x00, 0x00,
+ 0x7B, 0xE7, 0x70,
+ 0x0B, 0x43, 0x90,
+ 0x07, 0x7F, 0xC0,
+ 0x07, 0x7F, 0xC0,
+ 0x00, 0x33, 0x00,
+ 0x49, 0x75, 0x90,
+ 0x40, 0x00, 0x00,
+ 0x15, 0x99, 0xA0,
+ 0x76, 0x66, 0x60,
+ 0x0A, 0x5E, 0x30,
+ 0x07, 0x55, 0x70,
+ 0x07, 0x55, 0x70,
+ 0x00, 0x51, 0x00,
+ 0x49, 0x75, 0x90,
+ 0x40, 0x00, 0x00,
+ 0x19, 0x33, 0x30,
+ 0x76, 0x66, 0x60,
+ 0x0A, 0x5E, 0x30,
+ 0x07, 0x55, 0x70,
+ 0x07, 0x55, 0x70,
+ 0x00, 0x2F, 0x00,
+ 0x49, 0x75, 0x90,
+ 0x40, 0x00, 0x00,
+ 0x1C, 0xCC, 0xD0,
+ 0x76, 0x66, 0x60,
+ 0x09, 0x16, 0x80,
+ 0x06, 0x6D, 0xB0,
+ 0x06, 0x6D, 0xB0,
+ 0x7F, 0xFF, 0xF0,
+ 0x01, 0x66, 0x60,
+ 0x09, 0x99, 0xA0,
+ 0x30, 0x00, 0x00,
+ 0x19, 0x99, 0xA0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00,
+ 0xC8, 0x00, 0x00,
+ 0x39, 0x99, 0xA0,
+ 0x2C, 0xCC, 0xD0,
+ 0x7F, 0xBE, 0x70,
+ 0x7F, 0x5C, 0x30,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x32, 0x00,
+ 0x00, 0x14, 0x00,
+ 0x06, 0x66, 0x60,
+ 0x00, 0x03, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x20, 0x00, 0x00,
+ 0x00, 0x1D, 0xB0,
+ 0x40, 0x26, 0xE0,
+ 0x00, 0x00, 0x00,
+ 0x40, 0x26, 0xE0,
+ 0x00, 0x05, 0x00,
+ 0xF4, 0x00, 0x00,
+ 0xFF, 0x00, 0x00,
+ 0x00, 0x05, 0x00,
+ 0x00, 0x30, 0x00,
+ 0xFA, 0x2E, 0x90,
+ 0xFE, 0x8B, 0xA0,
+ 0x00, 0x20, 0xC0,
+ 0x00, 0x00, 0x60,
+ 0x00, 0x2D, 0x00,
+ 0x28, 0x61, 0xA0,
+ 0x65, 0x6E, 0xE0,
+ 0x00, 0x0B, 0x00,
+ 0x00, 0x03, 0x00,
+ 0x00, 0x09, 0x00,
+ 0x00, 0x04, 0x00,
+ 0x00, 0x0A, 0x00,
+ 0x00, 0x06, 0x00,
+ 0x00, 0x08, 0x00,
+ 0x00, 0x06, 0x00,
+ 0x00, 0x0A, 0x00,
+ 0x00, 0x08, 0x00,
+ 0x00, 0x19, 0x00,
+ 0x7F, 0xFF, 0xF0,
+ 0x4C, 0xCC, 0xD0,
+ 0x00, 0xC0, 0x00,
+ 0x00, 0x60, 0x00,
+ 0x00, 0x2D, 0x00,
+ 0x7F, 0xFF, 0xF0,
+ 0x4C, 0xCC, 0xD0,
+ 0x00, 0xC0, 0x00,
+ 0x00, 0x60, 0x00,
+ 0x00, 0x3B, 0x00,
+ 0x7F, 0xFF, 0xF0,
+ 0x4C, 0xCC, 0xD0,
+ 0x00, 0xC0, 0x00,
+ 0x00, 0x60, 0x00,
+ 0x00, 0x50, 0x00,
+ 0x7F, 0xFF, 0xF0,
+ 0x4C, 0xCC, 0xD0,
+ 0x00, 0xC0, 0x00,
+ 0x00, 0x60, 0x00,
+ 0x00, 0x30, 0x00,
+ 0x7F, 0xFF, 0xF0,
+ 0x4C, 0xCC, 0xD0,
+ 0x00, 0xC0, 0x00,
+ 0x00, 0x60, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x05, 0x00,
+ 0x1C, 0xF6, 0x90,
+ 0x00, 0x00, 0x00,
+ 0xF4, 0x00, 0x00,
+ 0x00, 0x04, 0x00,
+ 0x0E, 0x38, 0xE0,
+ 0x00, 0x03, 0xB0,
+ 0x07, 0x08, 0x00,
+ 0x19, 0x00, 0x00,
+ 0x70, 0x00, 0x00,
+ 0x70, 0x00, 0x00,
+ 0x07, 0x00, 0x00,
+ 0x00, 0x10, 0x00,
+ 0x03, 0x20, 0x00,
+ 0x03, 0xE8, 0x00,
+ 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x7F, 0xFF, 0xF0,
+ 0x6E, 0x14, 0x80,
+ 0x00, 0x20, 0x00,
+ 0x03, 0xA9, 0x80,
+ 0x04, 0x4C, 0x00,
+ 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x7F, 0xFF, 0xF0,
+ 0x6F, 0x5C, 0x30,
+ 0x00, 0x51, 0x00,
+ 0x03, 0xF4, 0x80,
+ 0x04, 0xB0, 0x00,
+ 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x7F, 0xFF, 0xF0,
+ 0x70, 0xA3, 0xD0,
+ 0x00, 0x50, 0x00,
+ 0x04, 0x3F, 0x80,
+ 0x05, 0x91, 0x00,
+ 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x7F, 0xFF, 0xF0,
+ 0x73, 0x33, 0x30,
+ 0x00, 0x30, 0x00,
+ 0x04, 0x8A, 0x80,
+ 0x05, 0xF5, 0x00,
+ 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x7F, 0xFF, 0xF0,
+ 0x75, 0xC2, 0x90,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00,
+ 0x01, 0x00, 0x00,
+ 0x18, 0x00, 0x00,
+ 0x18, 0x00, 0x00,
+ 0x03, 0x00, 0x00,
+ 0x01, 0xEB, 0x80,
+ 0x01, 0xEB, 0x80,
+ 0x02, 0x8F, 0x60,
+ 0x73, 0x33, 0x30,
+ 0x02, 0x8F, 0x60,
+ 0x01, 0xEB, 0x80,
+ 0x01, 0xEB, 0x80,
+ 0x10, 0x00, 0x00,
+ 0x03, 0x00, 0x00,
+ 0x08, 0xF5, 0xC0,
+ 0x0C, 0xCC, 0xD0,
+ 0x14, 0x7A, 0xE0,
+ 0x2B, 0x85, 0x20,
+ 0x14, 0x7A, 0xE0,
+ 0x0C, 0xCC, 0xD0,
+ 0x08, 0xF5, 0xC0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x60,
+ 0x07, 0x5C, 0x30,
+ 0x32, 0x00, 0x00,
+ 0x7E, 0x14, 0x80,
+ 0x06, 0xF5, 0xB0,
+ 0xD0, 0x00, 0x00,
+ 0x00, 0x00, 0x30,
+ 0x00, 0x10, 0x00,
+ 0x12, 0x66, 0x60,
+ 0x00, 0x08, 0x00,
+ 0x00, 0x18, 0x00,
+ 0x00, 0xE1, 0x00,
+ 0x05, 0x55, 0x50,
+ 0x00, 0x83, 0xA0,
+ 0x00, 0x28, 0x00,
+ 0x01, 0x99, 0xA0,
+ 0x0C, 0xCC, 0xD0,
+ 0x07, 0x33, 0x30,
+ 0x03, 0x99, 0xA0,
+ 0x04, 0x66, 0x60,
+ 0x40, 0x00, 0x00,
+ 0x49, 0x99, 0xA0,
+ 0xF6, 0x66, 0x60,
+ 0x73, 0x33, 0x30,
+ 0x19, 0x99, 0xA0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x00,
+ 0x00, 0x08, 0x00,
+ 0x06, 0x66, 0x60,
+ 0x00, 0x51, 0xF0,
+ 0x05, 0x33, 0x30,
+ 0xFD, 0x99, 0xA0,
+ 0x02, 0xCC, 0xD0,
+ 0x7D, 0x70, 0xA0,
+ 0x02, 0xB0, 0x20,
+ 0x00, 0x80, 0x00,
+ 0x04, 0x00, 0x00,
+ 0x10, 0xA3, 0xD0,
+ 0x01, 0xBA, 0x60,
+ 0x00, 0x11, 0x00,
+ 0x07, 0x87, 0x80,
+ 0x29, 0x99, 0xA0,
+ 0x00, 0x2D, 0x00,
+ 0x02, 0xD8, 0x30,
+ 0x0E, 0x66, 0x60,
+ 0x00, 0x3A, 0x00,
+ 0x02, 0x34, 0xF0,
+ 0x10, 0x00, 0x00,
+ 0x00, 0x51, 0x00,
+ 0x01, 0x94, 0x90,
+ 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x00,
+ 0x10, 0x00, 0x00,
+ 0x0C, 0xCC, 0xD0,
+ 0x00, 0x04, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x00,
+ 0x10, 0x00, 0x00,
+ 0x0C, 0xCC, 0xD0,
+ 0x00, 0x04, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x30, 0x00,
+ 0x0C, 0xCC, 0xD0,
+ 0x06, 0x66, 0x60,
+ 0x00, 0x04, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0xFF, 0x15, 0xC0,
+ 0x00, 0xF5, 0xC0,
+ 0xFE, 0xFD, 0xA0,
+ 0x01, 0x10, 0x70,
+ 0xFE, 0xDF, 0xF0,
+ 0x01, 0x31, 0xA0,
+ 0xFE, 0xBA, 0x80,
+ 0x01, 0x5C, 0x10,
+ 0xFE, 0x8A, 0x00,
+ 0x01, 0x94, 0x20,
+ 0xFE, 0x48, 0x70,
+ 0x01, 0xE1, 0xC0,
+ 0xFD, 0xEB, 0x10,
+ 0x02, 0x54, 0x50,
+ 0xFD, 0x5B, 0x40,
+ 0x03, 0x0E, 0x50,
+ 0xFC, 0x61, 0x20,
+ 0x04, 0x71, 0x00,
+ 0xFA, 0x41, 0xC0,
+ 0x08, 0x1F, 0xE0,
+ 0xF2, 0x1E, 0xF0,
+ 0x2F, 0x95, 0xF0,
+ 0x21, 0x4F, 0x60,
+ 0xF3, 0xA9, 0xB0,
+ 0x07, 0x92, 0x10,
+ 0xFA, 0x8A, 0x10,
+ 0x04, 0x45, 0x40,
+ 0xFC, 0x7E, 0x60,
+ 0x02, 0xF9, 0x60,
+ 0xFD, 0x6A, 0xF0,
+ 0x02, 0x48, 0x10,
+ 0xFD, 0xF4, 0xE0,
+ 0x01, 0xD9, 0xC0,
+ 0xFE, 0x4F, 0x20,
+ 0x01, 0x8E, 0x80,
+ 0xFE, 0x8E, 0xE0,
+ 0x01, 0x57, 0xE0,
+ 0xFE, 0xBE, 0x30,
+ 0x01, 0x2E, 0x60,
+ 0xFE, 0xE2, 0xD0,
+ 0x01, 0x0D, 0xE0,
+ 0xFE, 0xFF, 0xF0,
+ 0x00, 0xF3, 0xA0,
+ 0xFF, 0x17, 0xA0,
+ 0x00, 0xDE, 0x10,
+ 0xFF, 0x2B, 0x60,
+ 0x00, 0xCC, 0x00,
+ 0xFF, 0x3B, 0xF0,
+ 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x70, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x00, 0x33, 0x30,
+ 0xFF, 0xCC, 0xD0,
+ 0x00, 0x00, 0x00,
+ 0x03, 0x92, 0xD0,
+ 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x16, 0xCC, 0xD0,
+ 0x18, 0x00, 0x00,
+ 0x16, 0x66, 0x60,
+ 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00,
+ 0xF9, 0x09, 0x90,
+ 0x1B, 0xB7, 0x80,
+ 0xC4, 0x74, 0xF0,
+ 0x7F, 0x83, 0x00,
+ 0x58, 0xB9, 0x10,
+ 0x08, 0x00, 0x00,
+ 0xC8, 0x00, 0x00,
+ 0xEB, 0xD8, 0x60,
+ 0x42, 0xCD, 0xA0,
+ 0xA2, 0x68, 0x10,
+ 0x62, 0xB9, 0xF0,
+ 0x0C, 0x35, 0x90,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x2F, 0x4D, 0xF0,
+ 0x18, 0xAD, 0xE0,
+ 0x02, 0x35, 0xE0,
+ 0x9D, 0x9A, 0x10,
+ 0x04, 0x5B, 0x30,
+ 0x9F, 0x16, 0x10,
+ 0x06, 0x62, 0x10,
+ 0xA1, 0x68, 0xD0,
+ 0x08, 0x40, 0xC0,
+ 0xA4, 0x62, 0x10,
+ 0x09, 0xF2, 0x40,
+ 0xA7, 0xCD, 0x20,
+ 0x0B, 0x75, 0xD0,
+ 0xAB, 0x78, 0x90,
+ 0x0C, 0xCD, 0xC0,
+ 0xAF, 0x3B, 0x30,
+ 0x0D, 0xFE, 0x40,
+ 0xB2, 0xF5, 0xA0,
+ 0x0F, 0x0C, 0x60,
+ 0xB6, 0x91, 0xE0,
+ 0x0F, 0xFD, 0x60,
+ 0xBA, 0x01, 0xF0,
+ 0x10, 0xD6, 0x40,
+ 0xBD, 0x3D, 0xE0,
+ 0x11, 0x9B, 0x90,
+ 0xC0, 0x42, 0x10,
+ 0x12, 0x51, 0x60,
+ 0xC3, 0x0E, 0x00,
+ 0x12, 0xFB, 0x20,
+ 0xC5, 0xA3, 0x00,
+ 0x13, 0x9B, 0xE0,
+ 0xC8, 0x03, 0x80,
+ 0x14, 0x36, 0x20,
+ 0xCA, 0x32, 0xB0,
+ 0x14, 0xCC, 0x20,
+ 0xCC, 0x33, 0xE0,
+ 0x15, 0x5F, 0xD0,
+ 0xCE, 0x0A, 0x80,
+ 0x15, 0xF2, 0xE0,
+ 0xCF, 0xB9, 0xD0,
+ 0x16, 0x86, 0xD0,
+ 0xD1, 0x45, 0x10,
+ 0x17, 0x1D, 0x00,
+ 0xD2, 0xAF, 0x00,
+ 0x17, 0xB6, 0xA0,
+ 0xD3, 0xFA, 0x70,
+ 0x18, 0x55, 0x00,
+ 0xD5, 0x29, 0xB0,
+ 0x18, 0xF9, 0x30,
+ 0xD6, 0x3E, 0xF0,
+ 0x19, 0xA4, 0x60,
+ 0xD7, 0x3C, 0x20,
+ 0x1A, 0x57, 0xA0,
+ 0xD8, 0x23, 0x20,
+ 0x1B, 0x14, 0x10,
+ 0xD8, 0xF5, 0x60,
+ 0x1B, 0xDB, 0x00,
+ 0xD9, 0xB4, 0x50,
+ 0x1C, 0xAD, 0x80,
+ 0xDA, 0x61, 0x30,
+ 0x1D, 0x8D, 0x10,
+ 0xDA, 0xFD, 0x20,
+ 0x1E, 0x7A, 0xF0,
+ 0xDB, 0x89, 0x00,
+ 0x1F, 0x78, 0xD0,
+ 0xDC, 0x05, 0xD0,
+ 0x20, 0x88, 0x40,
+ 0xDC, 0x74, 0x40,
+ 0x21, 0xAB, 0x30,
+ 0xDC, 0xD5, 0x00,
+ 0x22, 0xE3, 0x80,
+ 0xDD, 0x28, 0xB0,
+ 0x24, 0x33, 0x70,
+ 0xDD, 0x6F, 0xE0,
+ 0x25, 0x9D, 0x70,
+ 0xDD, 0xAB, 0x10,
+ 0x27, 0x24, 0x20,
+ 0xDD, 0xDA, 0xC0,
+ 0x28, 0xCA, 0x80,
+ 0xDD, 0xFF, 0x70,
+ 0x2A, 0x93, 0xA0,
+ 0xDE, 0x19, 0xC0,
+ 0x2C, 0x83, 0x00,
+ 0xDE, 0x2A, 0x30,
+ 0x2E, 0x9C, 0x30,
+ 0xDE, 0x31, 0xA0,
+ 0x30, 0xE3, 0x20,
+ 0xDE, 0x31, 0x00,
+ 0x33, 0x5B, 0x90,
+ 0xDE, 0x29, 0x80,
+ 0x36, 0x09, 0x30,
+ 0xDE, 0x1C, 0xF0,
+ 0x38, 0xEF, 0x30,
+ 0xDE, 0x0D, 0x70,
+ 0x3C, 0x0F, 0xA0,
+ 0xDD, 0xFE, 0x30,
+ 0x3F, 0x6A, 0xF0,
+ 0xDD, 0xF3, 0x30,
+ 0x42, 0xFE, 0xA0,
+ 0xDD, 0xF1, 0xF0,
+ 0x46, 0xC4, 0x30,
+ 0xDE, 0x01, 0x70,
+ 0x4A, 0xAF, 0x00,
+ 0xDE, 0x2A, 0xA0,
+ 0x4E, 0xAA, 0xB0,
+ 0xDE, 0x78, 0x70,
+ 0x52, 0x99, 0xA0,
+ 0xDE, 0xF7, 0x30,
+ 0x56, 0x54, 0x10,
+ 0xDF, 0xB4, 0x30,
+ 0x59, 0xA9, 0xC0,
+ 0xE0, 0xBB, 0xC0,
+ 0x5C, 0x66, 0x80,
+ 0xE2, 0x16, 0xB0,
+ 0x5E, 0x59, 0xA0,
+ 0xE3, 0xC8, 0x40,
+ 0x5F, 0x5F, 0x60,
+ 0xE5, 0xCB, 0x70,
+ 0x5F, 0x68, 0xC0,
+ 0xE8, 0x13, 0x60,
+ 0x5E, 0x7E, 0xC0,
+ 0xEA, 0x8C, 0x60,
+ 0x5C, 0xBF, 0xF0,
+ 0xED, 0x1F, 0xD0,
+ 0x5A, 0x58, 0xD0,
+ 0xEF, 0xB7, 0x90,
+ 0x57, 0x7B, 0x00,
+ 0xF2, 0x41, 0x20,
+ 0x54, 0x55, 0x90,
+ 0xF4, 0xAE, 0xE0,
+ 0x51, 0x10, 0x40,
+ 0xF6, 0xF8, 0x60,
+ 0x4D, 0xCA, 0x00,
+ 0xF9, 0x19, 0x80,
+ 0x4A, 0x98, 0xD0,
+ 0xFB, 0x11, 0x80,
+ 0x47, 0x8B, 0x20,
+ 0xFC, 0xE1, 0xC0,
+ 0x44, 0xA9, 0xA0,
+ 0xFE, 0x8D, 0x20,
+ 0xBE, 0x07, 0x20,
+ 0xFF, 0xE9, 0x00,
+ 0xC0, 0x85, 0xD0,
+ 0xFE, 0x7C, 0xD0,
+ 0xC2, 0xD2, 0xC0,
+ 0xFD, 0x2A, 0xA0,
+ 0xC4, 0xEF, 0xB0,
+ 0xFB, 0xEE, 0xF0,
+ 0xC6, 0xDE, 0xE0,
+ 0xFA, 0xC6, 0x70,
+ 0xC8, 0xA3, 0x10,
+ 0xF9, 0xAE, 0x20,
+ 0xCA, 0x3F, 0x10,
+ 0xF8, 0xA3, 0x30,
+ 0xCB, 0xB5, 0x80,
+ 0xF7, 0xA3, 0x30,
+ 0xCD, 0x09, 0x00,
+ 0xF6, 0xAB, 0xD0,
+ 0xCE, 0x3C, 0x00,
+ 0xF5, 0xBB, 0x10,
+ 0xCF, 0x50, 0xC0,
+ 0xF4, 0xCE, 0xF0,
+ 0xD0, 0x49, 0x40,
+ 0xF3, 0xE5, 0xA0,
+ 0xD1, 0x27, 0x30,
+ 0xF2, 0xFD, 0x90,
+ 0xD1, 0xEC, 0x40,
+ 0xF2, 0x15, 0x20,
+ 0xD2, 0x99, 0xC0,
+ 0xF1, 0x2A, 0xB0,
+ 0xD3, 0x30, 0xF0,
+ 0xF0, 0x3C, 0xC0,
+ 0xD3, 0xB2, 0xD0,
+ 0xEF, 0x49, 0xE0,
+ 0xD4, 0x20, 0x30,
+ 0xEE, 0x50, 0x80,
+ 0xD4, 0x79, 0xC0,
+ 0xED, 0x4F, 0x00,
+ 0xD4, 0xC0, 0x20,
+ 0xEC, 0x43, 0xC0,
+ 0xD4, 0xF3, 0xB0,
+ 0xEB, 0x2D, 0x10,
+ 0xD5, 0x14, 0xC0,
+ 0xEA, 0x09, 0x30,
+ 0xD5, 0x23, 0x70,
+ 0xE8, 0xD6, 0x10,
+ 0xD5, 0x1F, 0xE0,
+ 0xE7, 0x91, 0xA0,
+ 0xD5, 0x09, 0xE0,
+ 0xE6, 0x39, 0x90,
+ 0xD4, 0xE1, 0x70,
+ 0xE4, 0xCB, 0x80,
+ 0xD4, 0xA6, 0x40,
+ 0xE3, 0x44, 0xA0,
+ 0xD4, 0x58, 0x00,
+ 0xE1, 0xA2, 0x00,
+ 0xD3, 0xF6, 0x80,
+ 0xDF, 0xE0, 0x60,
+ 0xD3, 0x81, 0x40,
+ 0xDD, 0xFC, 0x50,
+ 0xD2, 0xF8, 0x30,
+ 0xDB, 0xF2, 0x10,
+ 0xD2, 0x5B, 0x20,
+ 0xD9, 0xBD, 0xB0,
+ 0xD1, 0xAA, 0x60,
+ 0xD7, 0x5B, 0x30,
+ 0xD0, 0xE6, 0x90,
+ 0xD4, 0xC6, 0x90,
+ 0xD0, 0x11, 0x10,
+ 0xD1, 0xFC, 0x20,
+ 0xCF, 0x2C, 0x70,
+ 0xCE, 0xF9, 0x30,
+ 0xCE, 0x3C, 0x80,
+ 0xCB, 0xBC, 0x50,
+ 0xCD, 0x47, 0x60,
+ 0xC8, 0x46, 0xA0,
+ 0xCC, 0x55, 0xC0,
+ 0xC4, 0x9C, 0xF0,
+ 0xCB, 0x73, 0xE0,
+ 0xC0, 0xC9, 0x30,
+ 0xCA, 0xB1, 0xC0,
+ 0xBC, 0xDC, 0xC0,
+ 0xCA, 0x23, 0xA0,
+ 0xB8, 0xF1, 0x60,
+ 0xC9, 0xE1, 0x00,
+ 0xB5, 0x2A, 0x70,
+ 0xCA, 0x02, 0x60,
+ 0xB1, 0xB3, 0x90,
+ 0xCA, 0x9E, 0x30,
+ 0xAE, 0xBC, 0xE0,
+ 0xCB, 0xC3, 0xC0,
+ 0xAC, 0x73, 0xF0,
+ 0xCD, 0x77, 0x20,
+ 0xAA, 0xFB, 0xC0,
+ 0xCF, 0xAE, 0xF0,
+ 0xAA, 0x64, 0xF0,
+ 0xD2, 0x55, 0x40,
+ 0xAA, 0xAA, 0xC0,
+ 0xD5, 0x4B, 0xC0,
+ 0xAB, 0xB4, 0xC0,
+ 0xD8, 0x71, 0x50,
+ 0xAD, 0x5D, 0x50,
+ 0xDB, 0xA7, 0x00,
+ 0xAF, 0x79, 0x70,
+ 0xDE, 0xD3, 0xA0,
+ 0xB1, 0xDF, 0xB0,
+ 0xE1, 0xE4, 0xD0,
+ 0xB4, 0x6C, 0x40,
+ 0xE4, 0xCE, 0xE0,
+ 0xB7, 0x03, 0x10,
+ 0xE7, 0x8B, 0x70,
+ 0xB9, 0x8F, 0x90,
+ 0xEA, 0x18, 0x30,
+ 0xBC, 0x03, 0xA0,
+ 0xEC, 0x75, 0xA0,
+ 0xBE, 0x56, 0x80,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x33, 0x40,
+ 0x0A, 0x6A, 0x40,
+ 0x0B, 0x65, 0x90,
+ 0x0C, 0x27, 0xE0,
+ 0x0C, 0xE2, 0xD0,
+ 0x0D, 0xA4, 0xC0,
+ 0x0E, 0x72, 0x50,
+ 0x0D, 0x4D, 0xB0,
+ 0x0C, 0x76, 0x10,
+ 0x0B, 0xD2, 0xF0,
+ 0x0B, 0x54, 0xE0,
+ 0x0A, 0xF1, 0xD0,
+ 0x0A, 0xA2, 0xE0,
+ 0x0A, 0x63, 0x50,
+ 0x0A, 0x2F, 0xA0,
+ 0x0A, 0x05, 0x60,
+ 0x09, 0xE2, 0xB0,
+ 0x09, 0xC6, 0x30,
+ 0x09, 0xAE, 0xE0,
+ 0x09, 0x9B, 0xE0,
+ 0x09, 0x8C, 0x90,
+ 0x09, 0x80, 0x80,
+ 0x09, 0x77, 0x60,
+ 0x09, 0x70, 0xE0,
+ 0x09, 0x6C, 0xD0,
+ 0x09, 0x6B, 0x10,
+ 0x09, 0x6B, 0xA0,
+ 0x09, 0x6E, 0x70,
+ 0x09, 0x73, 0x80,
+ 0x09, 0x7B, 0x10,
+ 0x09, 0x85, 0x30,
+ 0x09, 0x92, 0x20,
+ 0x09, 0xA2, 0x40,
+ 0x09, 0xB6, 0x00,
+ 0x09, 0xCE, 0x00,
+ 0x09, 0xEA, 0xF0,
+ 0x0A, 0x0D, 0xF0,
+ 0x0A, 0x38, 0x40,
+ 0x0A, 0x6B, 0xD0,
+ 0x0A, 0xAB, 0x30,
+ 0x0A, 0xFA, 0x10,
+ 0x0B, 0x5D, 0xE0,
+ 0x0B, 0xDE, 0xE0,
+ 0x0C, 0x8A, 0xE0,
+ 0x0D, 0x79, 0xC0,
+ 0x0E, 0xDA, 0xD0,
+ 0x11, 0x1B, 0xD0,
+ 0x15, 0x96, 0x30,
+ 0x25, 0x8B, 0x20,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x7F, 0x54, 0xB0,
+ 0x1F, 0x6B, 0x10,
+ 0x17, 0x41, 0x50,
+ 0x13, 0xB0, 0x40,
+ 0x11, 0xA3, 0x10,
+ 0x10, 0x4C, 0xF0,
+ 0x0F, 0x5E, 0x20,
+ 0x0E, 0xB0, 0x60,
+ 0x0E, 0x2E, 0xF0,
+ 0x0D, 0xCD, 0x90,
+ 0x0D, 0x84, 0xA0,
+ 0x0D, 0x4F, 0x20,
+ 0x0D, 0x29, 0xD0,
+ 0x0D, 0x12, 0xA0,
+ 0x0D, 0x08, 0x50,
+ 0x0D, 0x0A, 0x50,
+ 0x0D, 0x18, 0xA0,
+ 0x0D, 0x33, 0xF0,
+ 0x0D, 0x5D, 0x90,
+ 0x0D, 0x97, 0xC0,
+ 0x0D, 0xE5, 0xD0,
+ 0x0E, 0x4D, 0x10,
+ 0x0E, 0xD5, 0xA0,
+ 0x0F, 0x8C, 0x70,
+ 0x10, 0x87, 0xE0,
+ 0x11, 0xF1, 0xE0,
+ 0x14, 0x24, 0x10,
+ 0x18, 0x0F, 0x60,
+ 0x21, 0xB8, 0x80,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x00, 0x64, 0x80,
+ 0x01, 0x2D, 0x90,
+ 0x01, 0xF6, 0xA0,
+ 0x02, 0xBF, 0xB0,
+ 0x03, 0x88, 0xB0,
+ 0x04, 0x51, 0xA0,
+ 0x05, 0x1A, 0x90,
+ 0x05, 0xE3, 0x70,
+ 0x06, 0xAC, 0x40,
+ 0x07, 0x75, 0x00,
+ 0x08, 0x3D, 0xB0,
+ 0x09, 0x06, 0x50,
+ 0x09, 0xCE, 0xD0,
+ 0x0A, 0x97, 0x40,
+ 0x0B, 0x5F, 0x90,
+ 0x0C, 0x27, 0xC0,
+ 0x0C, 0xEF, 0xE0,
+ 0x0D, 0xB7, 0xD0,
+ 0x0E, 0x7F, 0xB0,
+ 0x0F, 0x47, 0x60,
+ 0x10, 0x0E, 0xF0,
+ 0x10, 0xD6, 0x50,
+ 0x11, 0x9D, 0x90,
+ 0x12, 0x64, 0xA0,
+ 0x13, 0x2B, 0x80,
+ 0x13, 0xF2, 0x30,
+ 0x14, 0xB8, 0xB0,
+ 0x15, 0x7F, 0x00,
+ 0x16, 0x45, 0x20,
+ 0x17, 0x0B, 0x00,
+ 0x17, 0xD0, 0xA0,
+ 0x18, 0x96, 0x10,
+ 0x19, 0x5B, 0x50,
+ 0x1A, 0x20, 0x40,
+ 0x1A, 0xE4, 0xF0,
+ 0x1B, 0xA9, 0x60,
+ 0x1C, 0x6D, 0x90,
+ 0x1D, 0x31, 0x70,
+ 0x1D, 0xF5, 0x10,
+ 0x1E, 0xB8, 0x70,
+ 0x1F, 0x7B, 0x70,
+ 0x20, 0x3E, 0x30,
+ 0x21, 0x00, 0xA0,
+ 0x21, 0xC2, 0xB0,
+ 0x22, 0x84, 0x80,
+ 0x23, 0x45, 0xF0,
+ 0x24, 0x07, 0x10,
+ 0x24, 0xC7, 0xD0,
+ 0x25, 0x88, 0x30,
+ 0x26, 0x48, 0x40,
+ 0x27, 0x07, 0xF0,
+ 0x27, 0xC7, 0x30,
+ 0x28, 0x86, 0x20,
+ 0x29, 0x44, 0xA0,
+ 0x2A, 0x02, 0xC0,
+ 0x2A, 0xC0, 0x80,
+ 0x2B, 0x7D, 0xD0,
+ 0x2C, 0x3A, 0xB0,
+ 0x2C, 0xF7, 0x30,
+ 0x2D, 0xB3, 0x30,
+ 0x2E, 0x6E, 0xC0,
+ 0x2F, 0x29, 0xF0,
+ 0x2F, 0xE4, 0xA0,
+ 0x30, 0x9E, 0xD0,
+ 0x31, 0x58, 0x90,
+ 0x32, 0x11, 0xE0,
+ 0x32, 0xCA, 0xB0,
+ 0x33, 0x83, 0x00,
+ 0x34, 0x3A, 0xD0,
+ 0x34, 0xF2, 0x20,
+ 0x35, 0xA8, 0xE0,
+ 0x36, 0x5F, 0x30,
+ 0x37, 0x14, 0xF0,
+ 0x37, 0xCA, 0x30,
+ 0x38, 0x7E, 0xE0,
+ 0x39, 0x33, 0x00,
+ 0x39, 0xE6, 0x90,
+ 0x3A, 0x99, 0xA0,
+ 0x3B, 0x4C, 0x20,
+ 0x3B, 0xFE, 0x00,
+ 0x3C, 0xAF, 0x50,
+ 0x3D, 0x60, 0x10,
+ 0x3E, 0x10, 0x30,
+ 0x3E, 0xBF, 0xC0,
+ 0x3F, 0x6E, 0xB0,
+ 0x40, 0x1D, 0x00,
+ 0x40, 0xCA, 0xC0,
+ 0x41, 0x77, 0xD0,
+ 0x42, 0x24, 0x40,
+ 0x42, 0xD0, 0x10,
+ 0x43, 0x7B, 0x40,
+ 0x44, 0x25, 0xD0,
+ 0x44, 0xCF, 0xA0,
+ 0x45, 0x78, 0xE0,
+ 0x46, 0x21, 0x60,
+ 0x46, 0xC9, 0x40,
+ 0x47, 0x70, 0x70,
+ 0x48, 0x16, 0xF0,
+ 0x48, 0xBC, 0xB0,
+ 0x49, 0x61, 0xD0,
+ 0x4A, 0x06, 0x30,
+ 0x4A, 0xA9, 0xE0,
+ 0x4B, 0x4C, 0xD0,
+ 0x4B, 0xEF, 0x10,
+ 0x4C, 0x90, 0x80,
+ 0x4D, 0x31, 0x50,
+ 0x4D, 0xD1, 0x50,
+ 0x4E, 0x70, 0x90,
+ 0x4F, 0x0F, 0x10,
+ 0x4F, 0xAC, 0xD0,
+ 0x50, 0x49, 0xD0,
+ 0x50, 0xE6, 0x00,
+ 0x51, 0x81, 0x70,
+ 0x52, 0x1C, 0x10,
+ 0x52, 0xB5, 0xE0,
+ 0x53, 0x4E, 0xF0,
+ 0x53, 0xE7, 0x30,
+ 0x54, 0x7E, 0xA0,
+ 0x55, 0x15, 0x40,
+ 0x55, 0xAB, 0x10,
+ 0x56, 0x40, 0x00,
+ 0x56, 0xD4, 0x30,
+ 0x57, 0x67, 0x80,
+ 0x57, 0xF9, 0xF0,
+ 0x58, 0x8B, 0x90,
+ 0x59, 0x1C, 0x50,
+ 0x59, 0xAC, 0x40,
+ 0x5A, 0x3B, 0x40,
+ 0x5A, 0xC9, 0x70,
+ 0x5B, 0x56, 0xC0,
+ 0x5B, 0xE3, 0x30,
+ 0x5C, 0x6E, 0xB0,
+ 0x5C, 0xF9, 0x50,
+ 0x5D, 0x83, 0x10,
+ 0x5E, 0x0B, 0xF0,
+ 0x5E, 0x93, 0xE0,
+ 0x5F, 0x1A, 0xE0,
+ 0x5F, 0xA1, 0x00,
+ 0x60, 0x26, 0x30,
+ 0x60, 0xAA, 0x70,
+ 0x61, 0x2D, 0xC0,
+ 0x61, 0xB0, 0x30,
+ 0x62, 0x31, 0xA0,
+ 0x62, 0xB2, 0x20,
+ 0x63, 0x31, 0xB0,
+ 0x63, 0xB0, 0x40,
+ 0x64, 0x2D, 0xE0,
+ 0x64, 0xAA, 0x90,
+ 0x65, 0x26, 0x40,
+ 0x65, 0xA1, 0x00,
+ 0x66, 0x1A, 0xC0,
+ 0x66, 0x93, 0x80,
+ 0x67, 0x0B, 0x40,
+ 0x67, 0x82, 0x10,
+ 0x67, 0xF7, 0xD0,
+ 0x68, 0x6C, 0xA0,
+ 0x68, 0xE0, 0x60,
+ 0x69, 0x53, 0x20,
+ 0x69, 0xC4, 0xE0,
+ 0x6A, 0x35, 0xA0,
+ 0x6A, 0xA5, 0x50,
+ 0x6B, 0x14, 0x00,
+ 0x6B, 0x81, 0xA0,
+ 0x6B, 0xEE, 0x40,
+ 0x6C, 0x59, 0xD0,
+ 0x6C, 0xC4, 0x50,
+ 0x6D, 0x2D, 0xD0,
+ 0x6D, 0x96, 0x40,
+ 0x6D, 0xFD, 0xA0,
+ 0x6E, 0x63, 0xF0,
+ 0x6E, 0xC9, 0x20,
+ 0x6F, 0x2D, 0x50,
+ 0x6F, 0x90, 0x70,
+ 0x6F, 0xF2, 0x70,
+ 0x70, 0x53, 0x60,
+ 0x70, 0xB3, 0x40,
+ 0x71, 0x12, 0x10,
+ 0x71, 0x6F, 0xC0,
+ 0x71, 0xCC, 0x50,
+ 0x72, 0x27, 0xD0,
+ 0x72, 0x82, 0x40,
+ 0x72, 0xDB, 0x90,
+ 0x73, 0x33, 0xC0,
+ 0x73, 0x8A, 0xD0,
+ 0x73, 0xE0, 0xC0,
+ 0x74, 0x35, 0xA0,
+ 0x74, 0x89, 0x50,
+ 0x74, 0xDB, 0xF0,
+ 0x75, 0x2D, 0x70,
+ 0x75, 0x7D, 0xC0,
+ 0x75, 0xCD, 0x00,
+ 0x76, 0x1B, 0x10,
+ 0x76, 0x68, 0x00,
+ 0x76, 0xB3, 0xD0,
+ 0x76, 0xFE, 0x80,
+ 0x77, 0x48, 0x00,
+ 0x77, 0x90, 0x60,
+ 0x77, 0xD7, 0x90,
+ 0x78, 0x1D, 0xA0,
+ 0x78, 0x62, 0x80,
+ 0x78, 0xA6, 0x40,
+ 0x78, 0xE8, 0xD0,
+ 0x79, 0x2A, 0x30,
+ 0x79, 0x6A, 0x70,
+ 0x79, 0xA9, 0x80,
+ 0x79, 0xE7, 0x70,
+ 0x7A, 0x24, 0x20,
+ 0x7A, 0x5F, 0xB0,
+ 0x7A, 0x9A, 0x10,
+ 0x7A, 0xD3, 0x40,
+ 0x7B, 0x0B, 0x40,
+ 0x7B, 0x42, 0x10,
+ 0x7B, 0x77, 0xB0,
+ 0x7B, 0xAC, 0x20,
+ 0x7B, 0xDF, 0x60,
+ 0x7C, 0x11, 0x70,
+ 0x7C, 0x42, 0x40,
+ 0x7C, 0x71, 0xF0,
+ 0x7C, 0xA0, 0x60,
+ 0x7C, 0xCD, 0xA0,
+ 0x7C, 0xF9, 0xB0,
+ 0x7D, 0x24, 0x90,
+ 0x7D, 0x4E, 0x30,
+ 0x7D, 0x76, 0xA0,
+ 0x7D, 0x9D, 0xD0,
+ 0x7D, 0xC3, 0xE0,
+ 0x7D, 0xE8, 0xA0,
+ 0x7E, 0x0C, 0x40,
+ 0x7E, 0x2E, 0xA0,
+ 0x7E, 0x4F, 0xC0,
+ 0x7E, 0x6F, 0xB0,
+ 0x7E, 0x8E, 0x70,
+ 0x7E, 0xAB, 0xF0,
+ 0x7E, 0xC8, 0x30,
+ 0x7E, 0xE3, 0x40,
+ 0x7E, 0xFD, 0x20,
+ 0x7F, 0x15, 0xC0,
+ 0x7F, 0x2D, 0x20,
+ 0x7F, 0x43, 0x40,
+ 0x7F, 0x58, 0x30,
+ 0x7F, 0x6B, 0xF0,
+ 0x7F, 0x7E, 0x60,
+ 0x7F, 0x8F, 0xA0,
+ 0x7F, 0x9F, 0xB0,
+ 0x7F, 0xAE, 0x70,
+ 0x7F, 0xBC, 0x00,
+ 0x7F, 0xC8, 0x60,
+ 0x7F, 0xD3, 0x70,
+ 0x7F, 0xDD, 0x50,
+ 0x7F, 0xE5, 0xF0,
+ 0x7F, 0xED, 0x50,
+ 0x7F, 0xF3, 0x80,
+ 0x7F, 0xF8, 0x70,
+ 0x7F, 0xFC, 0x20,
+ 0x7F, 0xFE, 0xA0,
+ 0x7F, 0xFF, 0xE0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0xFF, 0x87, 0x50,
+ 0xFE, 0x8C, 0x50,
+ 0xFD, 0xE9, 0x70,
+ 0x00, 0x00, 0x00,
+ 0x06, 0xD8, 0xD0,
+ 0x11, 0x8D, 0x30,
+ 0x1B, 0xAE, 0x90,
+ 0x1F, 0xDC, 0xD0,
+ 0x1B, 0xAE, 0x90,
+ 0x11, 0x8D, 0x30,
+ 0x06, 0xD8, 0xD0,
+ 0x00, 0x00, 0x00,
+ 0xFD, 0xE9, 0x70,
+ 0xFE, 0x8C, 0x50,
+ 0xFF, 0x87, 0x50,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x00,
+ 0x07, 0x87, 0x80,
+ 0x78, 0x78, 0x80,
+ 0x00, 0x09, 0x00,
+ 0x2D, 0x38, 0x80,
+ 0x52, 0xC7, 0x80,
+ 0x00, 0x0B, 0x00,
+ 0x24, 0x73, 0x10,
+ 0x5B, 0x8C, 0xF0,
+ 0x00, 0x0F, 0x00,
+ 0x7F, 0x42, 0x50,
+ 0x00, 0xBD, 0xB0,
+ 0x00, 0x13, 0x00,
+ 0x5A, 0x5A, 0x60,
+ 0x25, 0xA5, 0xA0,
+ 0x00, 0x18, 0x00,
+ 0x5B, 0x23, 0x60,
+ 0x24, 0xDC, 0xA0,
+ 0x00, 0x1D, 0x00,
+ 0x2D, 0x2D, 0x30,
+ 0x52, 0xD2, 0xD0,
+ 0x00, 0x23, 0x00,
+ 0x7F, 0x36, 0xF0,
+ 0x00, 0xC9, 0x10,
+ 0x00, 0x24, 0x00,
+ 0x22, 0xB3, 0xD0,
+ 0x5D, 0x4C, 0x30,
+ 0x00, 0x2A, 0x00,
+ 0x05, 0x90, 0x00,
+ 0x7A, 0x70, 0x00,
+ 0x00, 0x2E, 0x00,
+ 0x32, 0x22, 0x70,
+ 0x4D, 0xDD, 0x90,
+ 0x00, 0x31, 0x00,
+ 0x72, 0xA8, 0xD0,
+ 0x0D, 0x57, 0x30,
+ 0x00, 0x32, 0x00,
+ 0x5C, 0xE8, 0xB0,
+ 0x23, 0x17, 0x50,
+ 0x2C, 0xCC, 0xD0,
+ 0x00, 0x04, 0x00,
+ 0x20, 0x00, 0x00,
+ 0x00, 0x03, 0x00,
+ 0x2A, 0xAA, 0xB0,
+ 0x40, 0x00, 0x00,
+ 0x0C, 0xCC, 0xD0,
+ 0x18, 0x00, 0x00,
+ 0x00, 0x41, 0x90,
+ 0xFF, 0x33, 0x30,
+ 0x03, 0xEE, 0xA0,
+ 0x08, 0x00, 0x00,
+ 0x18, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x03, 0x33, 0x30,
+ 0x20, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x20, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x00,
+ 0xFE, 0x80, 0x00,
+ 0x0A, 0x80, 0x00,
+ 0xDD, 0x00, 0x00,
+ 0x68, 0xFF, 0x80,
+ 0x34, 0x7F, 0x00,
+ 0xFC, 0x80, 0x80,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x3F, 0xF0,
+ 0x08, 0x5F, 0xB0,
+ 0xEA, 0x91, 0x40,
+ 0xF7, 0xA0, 0x50,
+ 0x55, 0x2E, 0xD0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x51, 0x20,
+ 0xF8, 0x3B, 0xA0,
+ 0x19, 0x90, 0xF0,
+ 0x5C, 0x00, 0x00,
+ 0x19, 0x90, 0xF0,
+ 0xF8, 0x3B, 0xA0,
+ 0x00, 0x51, 0x20,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0xFF, 0xFE, 0x40,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x0A, 0x30,
+ 0x00, 0x00, 0x00,
+ 0xFF, 0xE5, 0x50,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x34, 0x70,
+ 0x00, 0x00, 0x00,
+ 0xFF, 0xA6, 0xF0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x8A, 0x40,
+ 0x00, 0x00, 0x00,
+ 0xFF, 0x35, 0xA0,
+ 0x00, 0x00, 0x00,
+ 0x01, 0x1C, 0x90,
+ 0x00, 0x00, 0x00,
+ 0xFE, 0x7A, 0x70,
+ 0x00, 0x00, 0x00,
+ 0x02, 0x0D, 0x20,
+ 0x00, 0x00, 0x00,
+ 0xFD, 0x3F, 0x80,
+ 0x00, 0x00, 0x00,
+ 0x03, 0xB9, 0x20,
+ 0x00, 0x00, 0x00,
+ 0xFA, 0xD2, 0x20,
+ 0x00, 0x00, 0x00,
+ 0x07, 0xAE, 0xA0,
+ 0x00, 0x00, 0x00,
+ 0xF2, 0xB3, 0xD0,
+ 0x00, 0x00, 0x00,
+ 0x28, 0xA6, 0x10,
+ 0x40, 0x00, 0x00,
+ 0x28, 0xA6, 0x10,
+ 0x00, 0x00, 0x00,
+ 0xF2, 0xB3, 0xD0,
+ 0x00, 0x00, 0x00,
+ 0x07, 0xAE, 0xA0,
+ 0x00, 0x00, 0x00,
+ 0xFA, 0xD2, 0x20,
+ 0x00, 0x00, 0x00,
+ 0x03, 0xB9, 0x20,
+ 0x00, 0x00, 0x00,
+ 0xFD, 0x3F, 0x80,
+ 0x00, 0x00, 0x00,
+ 0x02, 0x0D, 0x20,
+ 0x00, 0x00, 0x00,
+ 0xFE, 0x7A, 0x70,
+ 0x00, 0x00, 0x00,
+ 0x01, 0x1C, 0x90,
+ 0x00, 0x00, 0x00,
+ 0xFF, 0x35, 0xA0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x8A, 0x40,
+ 0x00, 0x00, 0x00,
+ 0xFF, 0xA6, 0xF0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x34, 0x70,
+ 0x00, 0x00, 0x00,
+ 0xFF, 0xE5, 0x50,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x0A, 0x30,
+ 0x00, 0x00, 0x00,
+ 0xFF, 0xFE, 0x40,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00,
+ 0x00, 0x01, 0x00,
+ 0x00, 0x12, 0x00,
+ 0x00, 0x11, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x07, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x5B, 0x00,
+ 0x00, 0x80, 0x00,
+ 0x00, 0x65, 0x00,
+ 0x00, 0x80, 0x00,
+ 0x00, 0x80, 0x00,
+ 0x02, 0x00, 0x00,
+ 0x00, 0x80, 0x00,
+ 0x00, 0xB0, 0x00,
+ 0x00, 0x80, 0x00,
+ 0x00, 0xB1, 0x00,
+ 0x02, 0x58, 0x00,
+ 0x02, 0x58, 0x00,
+ 0x03, 0xFF, 0x00,
+ 0x09, 0x7F, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x51, 0x00,
+ 0x03, 0xFF, 0x00,
+ 0x7F, 0xFF, 0xF0,
+ 0xF0, 0x00, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x7E, 0x00, 0x00,
+ 0x02, 0x00, 0x00,
+ 0x01, 0x4A, 0xA0,
+ 0x06, 0x57, 0xF0,
+ 0x06, 0x57, 0xF0,
+ 0x00, 0x04, 0x00,
+ 0x7F, 0xF0, 0x00,
+ 0x00, 0x10, 0x00,
+ 0x1D, 0x9A, 0x50,
+ 0xF9, 0xA8, 0x10,
+ 0x00, 0x56, 0x00,
+ 0x01, 0x00, 0x00,
+ 0x20, 0x00, 0x00,
+ 0xF0, 0x00, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x7E, 0x00, 0x00,
+ 0x02, 0x00, 0x00,
+ 0x01, 0x4A, 0xA0,
+ 0x06, 0x57, 0xF0,
+ 0x06, 0x57, 0xF0,
+ 0x00, 0x04, 0x00,
+ 0x7F, 0xF0, 0x00,
+ 0x00, 0x10, 0x00,
+ 0x32, 0xBF, 0x60,
+ 0xF9, 0xA8, 0x10,
+ 0x40, 0x3B, 0x00,
+ 0x3F, 0xFC, 0x30,
+ 0x10, 0x00, 0x00,
+ 0x40, 0x26, 0xE0,
+ 0x01, 0x00, 0x00,
+ 0x7C, 0x00, 0x00,
+ 0x04, 0x00, 0x00,
+ 0x7F, 0xC0, 0x00,
+ 0x00, 0x40, 0x00,
+ 0x7C, 0x00, 0x00,
+ 0x04, 0x00, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x40, 0x00, 0x60,
+ 0x20, 0x00, 0x00,
+ 0x7F, 0xC0, 0x00,
+ 0x00, 0x40, 0x00,
+ 0x00, 0x0D, 0x30,
+ 0x78, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x3F, 0xFF, 0xF0,
+ 0x40, 0x00, 0x10,
+ 0x03, 0x2B, 0x70,
+ 0x00, 0xA5, 0xB0,
+ 0x0E, 0x7D, 0xA0,
+ 0x3F, 0x15, 0xE0,
+ 0x40, 0x01, 0xE0,
+ 0x00, 0x20, 0x50,
+ 0x0F, 0xE2, 0xF0,
+ 0x3F, 0xFE, 0x20,
+ 0x40, 0x5E, 0x90,
+ 0x03, 0x2B, 0x70,
+ 0x00, 0xA5, 0xB0,
+ 0x50, 0xC3, 0x30,
+ 0x01, 0x00, 0x00,
+ 0x7C, 0x00, 0x00,
+ 0x04, 0x00, 0x00,
+ 0x7F, 0xC0, 0x00,
+ 0x00, 0x40, 0x00,
+ 0x7C, 0x00, 0x00,
+ 0x04, 0x00, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x40, 0x00, 0x60,
+ 0x20, 0x00, 0x00,
+ 0x7F, 0xC0, 0x00,
+ 0x00, 0x40, 0x00,
+ 0x00, 0x0D, 0x30,
+ 0x78, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x3F, 0xFF, 0xF0,
+ 0x40, 0x00, 0x10,
+ 0x03, 0x2B, 0x70,
+ 0x00, 0xA5, 0xB0,
+ 0x0E, 0x7D, 0xA0,
+ 0x3F, 0x15, 0xE0,
+ 0x40, 0x01, 0xE0,
+ 0x01, 0x00, 0xA0,
+ 0x0F, 0xE2, 0xF0,
+ 0x3F, 0xFE, 0x20,
+ 0x40, 0x5E, 0x90,
+ 0x03, 0x2B, 0x70,
+ 0x00, 0xA5, 0xB0,
+ 0x50, 0xC3, 0x30,
+ 0x37, 0x00, 0x80,
+ 0x91, 0xFF, 0x10,
+ 0xD1, 0x50, 0xA0,
+ 0x6D, 0x52, 0x80,
+ 0x37, 0x00, 0x80,
+ 0x10, 0xAC, 0x30,
+ 0x21, 0x58, 0x60,
+ 0xED, 0x25, 0x50,
+ 0x10, 0x2A, 0x00,
+ 0x10, 0xAC, 0x30,
+ 0x3D, 0x8F, 0x00,
+ 0x84, 0xE2, 0x00,
+ 0xC4, 0xD5, 0xE0,
+ 0x7B, 0x11, 0xD0,
+ 0x3D, 0x8F, 0x00,
+ 0x23, 0xF1, 0xA0,
+ 0x47, 0xE3, 0x50,
+ 0xD8, 0x04, 0x50,
+ 0xD8, 0x35, 0x20,
+ 0x23, 0xF1, 0xA0,
+ 0x33, 0x2B, 0xA0,
+ 0x99, 0xA8, 0xC0,
+ 0xD8, 0x39, 0xC0,
+ 0x64, 0xE8, 0x30,
+ 0x33, 0x2B, 0xA0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x11, 0x48, 0x30,
+ 0x22, 0x90, 0x70,
+ 0xEA, 0x1D, 0xE0,
+ 0x10, 0xC1, 0x50,
+ 0x11, 0x48, 0x30,
+ 0x39, 0xC0, 0x70,
+ 0x8C, 0x7F, 0x20,
+ 0xCB, 0x60, 0x40,
+ 0x72, 0x62, 0x10,
+ 0x39, 0xC0, 0x70,
+ 0x39, 0x12, 0x00,
+ 0x8D, 0xDC, 0x00,
+ 0xCD, 0x76, 0x60,
+ 0x71, 0xBE, 0x60,
+ 0x39, 0x12, 0x00,
+ 0x15, 0x55, 0x50,
+ 0x2A, 0xAA, 0xB0,
+ 0xEA, 0xAA, 0xB0,
+ 0x00, 0x00, 0x00,
+ 0x15, 0x55, 0x50,
+ 0x1E, 0x12, 0x40,
+ 0x3C, 0x24, 0x80,
+ 0xE9, 0x01, 0x90,
+ 0xDE, 0xB5, 0x80,
+ 0x1E, 0x12, 0x40,
+ 0x0E, 0x26, 0x00,
+ 0x1F, 0xA7, 0xF0,
+ 0xEB, 0x0E, 0x10,
+ 0x09, 0xB7, 0x50,
+ 0x1D, 0x6C, 0xC0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x40, 0x00,
+ 0x05, 0x80, 0x00,
+ 0x20, 0xC0, 0x00,
+ 0x02, 0x00, 0x00,
+ 0x03, 0x90, 0x00,
+ 0x00, 0x40, 0x00,
+ 0x28, 0xF5, 0x00,
+ 0x0A, 0x3D, 0x00,
+ 0x08, 0x55, 0x60,
+ 0x33, 0x33, 0x30,
+ 0x14, 0x00, 0x00,
+ 0xB8, 0x00, 0x00,
+ 0x10, 0x00, 0x00,
+ 0x02, 0x00, 0x00,
+ 0x19, 0x99, 0x90,
+ 0x00, 0x00, 0x00,
+ 0x74, 0x7A, 0xE0,
+ 0x40, 0x00, 0x00,
+ 0x01, 0x47, 0xA0,
+ 0x05, 0x1E, 0xB0,
+ 0x02, 0x8F, 0x50,
+ 0x05, 0x1E, 0xB0,
+ 0x02, 0x8F, 0x50,
+ 0x1C, 0xA7, 0xD0,
+ 0x1C, 0xA7, 0xD0,
+ 0x1C, 0xA7, 0xD0,
+ 0x1C, 0xA7, 0xD0,
+ 0x1C, 0xA7, 0xD0,
+ 0x1C, 0xA7, 0xD0,
+ 0x00, 0x10, 0x00,
+ 0x00, 0x20, 0x00,
+ 0x00, 0x50, 0x00,
+ 0x00, 0x80, 0x00,
+ 0x00, 0xB0, 0x00,
+ 0x00, 0xFF, 0x00,
+ 0x23, 0x00, 0x00,
+ 0x05, 0x80, 0x00,
+ 0x26, 0x00, 0x00,
+ 0x02, 0x00, 0x00,
+ 0x03, 0x98, 0x00,
+ 0x00, 0x40, 0x00,
+ 0x28, 0xF5, 0x00,
+ 0x0A, 0x3D, 0x00,
+ 0x08, 0x55, 0x60,
+ 0x33, 0x33, 0x30,
+ 0x14, 0x00, 0x00,
+ 0xB8, 0x00, 0x00,
+ 0x10, 0x00, 0x00,
+ 0x02, 0x00, 0x00,
+ 0x19, 0x99, 0x90,
+ 0x00, 0x00, 0x00,
+ 0x74, 0x7A, 0xE0,
+ 0x40, 0x00, 0x00,
+ 0x01, 0x47, 0xA0,
+ 0x05, 0x1E, 0xB0,
+ 0x02, 0x8F, 0x50,
+ 0x05, 0x1E, 0xB0,
+ 0x02, 0x8F, 0x50,
+ 0x2D, 0x6A, 0x80,
+ 0x2D, 0x6A, 0x80,
+ 0x2D, 0x6A, 0x80,
+ 0x2D, 0x6A, 0x80,
+ 0x2D, 0x6A, 0x80,
+ 0x2D, 0x6A, 0x80,
+ 0x00, 0x10, 0x00,
+ 0x00, 0x20, 0x00,
+ 0x00, 0x50, 0x00,
+ 0x00, 0x80, 0x00,
+ 0x00, 0xB0, 0x00,
+ 0x00, 0xFF, 0x00,
+ 0x00, 0x03, 0x00,
+ 0x00, 0x60, 0x00,
+ 0x02, 0x0C, 0x50,
+ 0x20, 0x00, 0x00,
+ 0x14, 0x00, 0x00,
+ 0x00, 0x06, 0x00,
+ 0x01, 0x00, 0x00,
+ 0x19, 0x99, 0xA0,
+ 0x01, 0x47, 0xB0,
+ 0x0C, 0xCC, 0xD0,
+ 0x20, 0x00, 0x00,
+ 0x04, 0x80, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x28, 0xF0,
+ 0x01, 0x47, 0xB0,
+ 0x05, 0x1E, 0xC0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x0C, 0xCC, 0xD0,
+ 0x2B, 0x85, 0x20,
+ 0x14, 0x7A, 0xE0,
+ 0x0C, 0xCC, 0xD0,
+ 0x08, 0xF5, 0xC0,
+ 0x10, 0x00, 0x00,
+ 0x70, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0xA3, 0x00,
+ 0x00, 0x00, 0x00,
+ 0xC0, 0x00, 0x00,
+ 0x40, 0x26, 0xE0,
+ 0x2C, 0xCC, 0xD0,
+ 0x7F, 0xFF, 0xF0,
+ 0x7F, 0xFF, 0xF0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x02, 0x02, 0x70,
+ 0x02, 0xD6, 0xB0,
+ 0x04, 0x02, 0x70,
+ 0x05, 0xA9, 0xE0,
+ 0x08, 0x00, 0x00,
+ 0x0B, 0x4C, 0xE0,
+ 0x0F, 0xF6, 0x50,
+ 0x16, 0x8C, 0x10,
+ 0x1F, 0xD9, 0x40,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x23, 0x64, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x23, 0x64, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x7F, 0x8A, 0xD0,
+ 0xAA, 0xD1, 0xB0,
+ 0xD5, 0xA3, 0x70,
+ 0x65, 0xD8, 0x00,
+ 0xF8, 0x00, 0x00,
+ 0x60, 0x00, 0x00,
+ 0x6E, 0xD9, 0xF0,
+ 0x49, 0xE6, 0xA0,
+ 0xE7, 0x5D, 0xD0,
+ 0x10, 0x6C, 0x20,
+ 0xF2, 0x50, 0x90,
+ 0x0C, 0xC5, 0xE0,
+ 0xF3, 0x3A, 0x20,
+ 0x08, 0x00, 0x00,
+ 0x5A, 0x82, 0x80,
+ 0x00, 0x00, 0x00,
+ 0x05, 0x05, 0x00,
+ 0x07, 0x1B, 0x00,
+ 0x08, 0xB5, 0x00,
+ 0x0A, 0x11, 0x00,
+ 0x0B, 0x44, 0x00,
+ 0x0C, 0x5A, 0x00,
+ 0x0D, 0x5B, 0x00,
+ 0x0E, 0x4A, 0x00,
+ 0x0F, 0x2C, 0x00,
+ 0x10, 0x02, 0x00,
+ 0x10, 0xCE, 0x00,
+ 0x11, 0x91, 0x00,
+ 0x12, 0x4E, 0x00,
+ 0x13, 0x03, 0x00,
+ 0x13, 0xB3, 0x00,
+ 0x14, 0x5D, 0x00,
+ 0x15, 0x02, 0x00,
+ 0x15, 0xA3, 0x00,
+ 0x16, 0x41, 0x00,
+ 0x16, 0xDA, 0x00,
+ 0x17, 0x70, 0x00,
+ 0x18, 0x03, 0x00,
+ 0x18, 0x93, 0x00,
+ 0x19, 0x20, 0x00,
+ 0x19, 0xAB, 0x00,
+ 0x1A, 0x33, 0x00,
+ 0x1A, 0xB9, 0x00,
+ 0x1B, 0x3D, 0x00,
+ 0x1B, 0xBF, 0x00,
+ 0x1C, 0x3F, 0x00,
+ 0x1C, 0xBD, 0x00,
+ 0x1D, 0x39, 0x00,
+ 0x1D, 0xB4, 0x00,
+ 0x1E, 0x2E, 0x00,
+ 0x1E, 0xA5, 0x00,
+ 0x1F, 0x1C, 0x00,
+ 0x1F, 0x91, 0x00,
+ 0x20, 0x05, 0x00,
+ 0x20, 0x77, 0x00,
+ 0x20, 0xE8, 0x00,
+ 0x21, 0x59, 0x00,
+ 0x21, 0xC8, 0x00,
+ 0x22, 0x36, 0x00,
+ 0x22, 0xA3, 0x00,
+ 0x23, 0x0F, 0x00,
+ 0x23, 0x7A, 0x00,
+ 0x23, 0xE4, 0x00,
+ 0x24, 0x4D, 0x00,
+ 0x24, 0xB6, 0x00,
+ 0x25, 0x1D, 0x00,
+ 0x25, 0x84, 0x00,
+ 0x25, 0xEA, 0x00,
+ 0x26, 0x50, 0x00,
+ 0x26, 0xB4, 0x00,
+ 0x27, 0x18, 0x00,
+ 0x27, 0x7B, 0x00,
+ 0x27, 0xDE, 0x00,
+ 0x28, 0x3F, 0x00,
+ 0x28, 0xA1, 0x00,
+ 0x29, 0x01, 0x00,
+ 0x29, 0x61, 0x00,
+ 0x29, 0xC1, 0x00,
+ 0x2A, 0x1F, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00
+};
+
+u8 pram_data_bak[] = {
+ 0x0C, 0xB4, 0xED, 0x1E, 0x42,
+ 0x04, 0xA9, 0x1C, 0x6D, 0x49,
+ 0x04, 0x44, 0x82, 0x1A, 0x44,
+ 0x0F, 0x58, 0x7E, 0x4D, 0x88,
+ 0x0D, 0x5A, 0x7E, 0x89, 0x1D,
+ 0x03, 0x35, 0x1C, 0x03, 0x8C,
+ 0x0F, 0x4A, 0x05, 0x6C, 0x68,
+ 0x0A, 0x70, 0xFF, 0x60, 0xE7,
+ 0x01, 0x83, 0x9B, 0x95, 0x72,
+ 0x09, 0x79, 0x72, 0x83, 0xAE,
+ 0x07, 0xAE, 0xA6, 0x4F, 0x67,
+ 0x0E, 0xD9, 0xA5, 0xD2, 0x80,
+ 0x00, 0x7B, 0xE2, 0xEA, 0x9E,
+ 0x05, 0xDB, 0xB3, 0xF9, 0xAC,
+ 0x0E, 0x38, 0x0C, 0xB8, 0x91,
+ 0x03, 0x81, 0xB6, 0x89, 0xCA,
+ 0x0C, 0xDF, 0x09, 0xD1, 0x5F,
+ 0x0F, 0x78, 0x28, 0xDB, 0xF2,
+ 0x06, 0x67, 0x95, 0x59, 0x5B,
+ 0x0B, 0xF4, 0x98, 0x6B, 0x25,
+ 0x0A, 0x72, 0xD4, 0x2D, 0xBB,
+ 0x09, 0xAE, 0x33, 0x01, 0x57,
+ 0x09, 0x6B, 0xBD, 0xBA, 0x4F,
+ 0x01, 0x54, 0x86, 0x70, 0xBB,
+ 0x0F, 0x53, 0xBC, 0x3F, 0xE7,
+ 0x0B, 0xC4, 0x7B, 0x42, 0x4E,
+ 0x08, 0x79, 0x17, 0x62, 0xAD,
+ 0x0A, 0x33, 0xE5, 0x31, 0x10,
+ 0x04, 0x47, 0xD3, 0x15, 0x7C,
+ 0x01, 0x37, 0xC4, 0x85, 0x60,
+ 0x00, 0xA2, 0x23, 0xE4, 0xD4,
+ 0x07, 0x81, 0x74, 0x8D, 0x2F,
+ 0x03, 0x31, 0xCD, 0x59, 0xE3,
+ 0x02, 0x83, 0x5B, 0x76, 0x35,
+ 0x00, 0xD5, 0x02, 0x95, 0xE5,
+ 0x00, 0x0E, 0x1C, 0xDE, 0xA7,
+ 0x03, 0xCC, 0xE5, 0x7B, 0x43,
+ 0x07, 0x78, 0x7B, 0xC1, 0xF0,
+ 0x07, 0x99, 0x68, 0x27, 0x75,
+ 0x09, 0x26, 0xC9, 0x48, 0xCB,
+ 0x0A, 0xE2, 0x66, 0x20, 0x0F,
+ 0x00, 0x27, 0x5E, 0x03, 0x67,
+ 0x04, 0x85, 0x12, 0xD3, 0xDD,
+ 0x09, 0x6F, 0xCD, 0xA9, 0x87,
+ 0x0C, 0x65, 0x18, 0x5F, 0xD1,
+ 0x0F, 0xAC, 0xB4, 0x47, 0xD4,
+ 0x0C, 0x76, 0x67, 0x16, 0x91,
+ 0x0A, 0x05, 0x2B, 0x4B, 0xB2,
+ 0x0C, 0xE9, 0x3F, 0x75, 0x12,
+ 0x05, 0xC6, 0x96, 0xCD, 0x0A,
+ 0x0A, 0x3C, 0x32, 0xDF, 0x24,
+ 0x02, 0x09, 0x4E, 0xC1, 0xE5,
+ 0x07, 0x49, 0x92, 0xC6, 0xE0,
+ 0x04, 0xC4, 0x40, 0x31, 0x1A,
+ 0x02, 0x55, 0x86, 0x34, 0xDF,
+ 0x06, 0x15, 0xA2, 0xAC, 0x9B,
+ 0x0F, 0x93, 0x51, 0x30, 0x18,
+ 0x0A, 0x34, 0xBD, 0xA2, 0x8D,
+ 0x05, 0x67, 0xD6, 0xFA, 0x10,
+ 0x06, 0x58, 0x09, 0x7D, 0x54,
+ 0x06, 0x51, 0x2E, 0x70, 0x0F,
+ 0x0E, 0x7A, 0xAA, 0x64, 0x04,
+ 0x09, 0xED, 0xDD, 0xDD, 0xD9,
+ 0x03, 0x07, 0xB2, 0x2E, 0x5D,
+ 0x09, 0x1D, 0x88, 0xCF, 0x9B,
+ 0x09, 0x3C, 0x72, 0x57, 0xB8,
+ 0x04, 0x80, 0xCF, 0x70, 0x95,
+ 0x0B, 0x0D, 0xEB, 0xB9, 0x14,
+ 0x0B, 0x4F, 0xD9, 0x29, 0xF5,
+ 0x0A, 0xA6, 0xEE, 0xB1, 0x9D,
+ 0x09, 0x7F, 0x47, 0x8E, 0xB8,
+ 0x04, 0x1F, 0x74, 0x1A, 0xDB,
+ 0x0C, 0x5A, 0xF9, 0x28, 0x1A,
+ 0x07, 0x2E, 0x76, 0x7F, 0xA4,
+ 0x09, 0xEA, 0x48, 0x67, 0x3A,
+ 0x03, 0x35, 0xBB, 0xC3, 0x3E,
+ 0x03, 0x7F, 0x5C, 0xC8, 0x17,
+ 0x0B, 0x47, 0x9F, 0xB2, 0x20,
+ 0x07, 0x1B, 0x57, 0x9F, 0x5B,
+ 0x00, 0x84, 0x61, 0xB5, 0x1C,
+ 0x0B, 0xD3, 0x72, 0xA4, 0x1C,
+ 0x0F, 0xB2, 0x4B, 0xF2, 0x07,
+ 0x0C, 0xC0, 0x63, 0xA4, 0x58,
+ 0x0E, 0x8B, 0x1D, 0xE9, 0x14,
+ 0x0E, 0xE8, 0x37, 0xBB, 0x2A,
+ 0x0E, 0xF5, 0x50, 0x29, 0x5E,
+ 0x0D, 0xC0, 0xE7, 0x47, 0xF6,
+ 0x08, 0x90, 0xCA, 0x1A, 0x32,
+ 0x08, 0x77, 0x85, 0xF2, 0x57,
+ 0x00, 0x81, 0x10, 0x4A, 0xB6,
+ 0x0F, 0x3E, 0x6E, 0x54, 0x84,
+ 0x0C, 0x4E, 0x3D, 0xA2, 0x5D,
+ 0x08, 0xC2, 0x72, 0xBA, 0x35,
+ 0x0D, 0xE4, 0x50, 0xAD, 0x3F,
+ 0x08, 0x96, 0xFC, 0x9A, 0x9F,
+ 0x0C, 0xC6, 0x51, 0xA5, 0xFA,
+ 0x0A, 0x25, 0x34, 0xC0, 0x4E,
+ 0x08, 0x6B, 0xEE, 0xC8, 0x6B,
+ 0x06, 0xA1, 0xD0, 0x3C, 0xA6,
+ 0x08, 0x06, 0x73, 0xDB, 0x51,
+ 0x08, 0x1A, 0xCB, 0x6C, 0x10,
+ 0x05, 0x0F, 0xB8, 0xBD, 0xB1,
+ 0x01, 0x20, 0x94, 0xE5, 0x1E,
+ 0x00, 0xD8, 0x69, 0x1C, 0x64,
+ 0x0C, 0x3C, 0xC4, 0x02, 0x11,
+ 0x08, 0xE4, 0x87, 0xAF, 0x49,
+ 0x04, 0xA0, 0xBA, 0x7E, 0xCD,
+ 0x0D, 0xF9, 0x37, 0x35, 0x03,
+ 0x0C, 0xA3, 0x49, 0xFE, 0x26,
+ 0x09, 0x97, 0xF8, 0x3B, 0xBD,
+ 0x0F, 0x5D, 0x62, 0xDB, 0xD5,
+ 0x09, 0x03, 0x9B, 0x77, 0xC3,
+ 0x05, 0x27, 0x2C, 0xA2, 0xC9,
+ 0x04, 0x5F, 0x4F, 0xE1, 0xC3,
+ 0x04, 0x75, 0x05, 0x66, 0x17,
+ 0x0D, 0x28, 0x43, 0xBC, 0xE4,
+ 0x0D, 0x51, 0x57, 0x1A, 0xBC,
+ 0x04, 0x8B, 0x4C, 0x23, 0x0C,
+ 0x01, 0x35, 0x47, 0x9B, 0x91,
+ 0x02, 0xB4, 0xFF, 0x92, 0x5B,
+ 0x02, 0x6A, 0x66, 0x07, 0x13,
+ 0x0A, 0x97, 0x3D, 0x18, 0xE2,
+ 0x00, 0xF1, 0x1D, 0x81, 0xA4,
+ 0x0B, 0x05, 0xAF, 0xA8, 0x33,
+ 0x0A, 0xF2, 0xEC, 0x05, 0x8E,
+ 0x03, 0x5D, 0x87, 0x06, 0x79,
+ 0x01, 0xB2, 0xC3, 0xBC, 0x22,
+ 0x0C, 0xF6, 0x4B, 0xCC, 0x9F,
+ 0x08, 0x31, 0xC6, 0x73, 0x93,
+ 0x08, 0x70, 0x37, 0x31, 0x2C,
+ 0x0C, 0x09, 0xA3, 0xD3, 0x96,
+ 0x08, 0x3D, 0xD7, 0x22, 0x45,
+ 0x00, 0x7A, 0xC4, 0xB7, 0xA4,
+ 0x08, 0xCC, 0xC2, 0x32, 0x84,
+ 0x0F, 0xE8, 0xBB, 0xD2, 0x87,
+ 0x03, 0xEE, 0x81, 0x5F, 0x7C,
+ 0x09, 0x5F, 0x5D, 0x0E, 0x55,
+ 0x07, 0xDC, 0x0E, 0x72, 0xAD,
+ 0x0A, 0x09, 0xAC, 0xE1, 0x7B,
+ 0x06, 0xE7, 0xFA, 0x7F, 0xC1,
+ 0x03, 0x8B, 0x53, 0x44, 0xAE,
+ 0x08, 0xF3, 0xE6, 0xC3, 0x02,
+ 0x0F, 0x6A, 0x33, 0xA2, 0x29,
+ 0x00, 0x8C, 0x25, 0x2C, 0x89,
+ 0x03, 0xBE, 0xA5, 0x06, 0xD3,
+ 0x0F, 0xCF, 0x8F, 0xC9, 0x69,
+ 0x02, 0x0C, 0x2F, 0x1A, 0x1F,
+ 0x01, 0x63, 0xAC, 0xB5, 0xF4,
+ 0x04, 0xDE, 0x52, 0xE0, 0x16,
+ 0x07, 0x2C, 0xE1, 0x2B, 0x08,
+ 0x02, 0x1C, 0xA4, 0x3D, 0x55,
+ 0x0A, 0x19, 0x42, 0xFF, 0x4D,
+ 0x0E, 0xF0, 0xFF, 0x83, 0xDF,
+ 0x07, 0x32, 0x09, 0x4E, 0xD1,
+ 0x05, 0xCD, 0x8A, 0x97, 0xC6,
+ 0x09, 0xC5, 0x66, 0xC0, 0x3C,
+ 0x08, 0x3E, 0xD7, 0x86, 0xF4,
+ 0x00, 0x8A, 0xD1, 0xE7, 0xE5,
+ 0x02, 0xDF, 0x91, 0x57, 0x3A,
+ 0x03, 0x4F, 0x7B, 0x3F, 0xA2,
+ 0x0C, 0xDC, 0x28, 0x0F, 0xBA,
+ 0x01, 0x6D, 0x4A, 0x6D, 0x60,
+ 0x08, 0x0A, 0x44, 0x57, 0x78,
+ 0x02, 0x50, 0x3F, 0x6A, 0x24,
+ 0x0F, 0x84, 0x68, 0x9A, 0x00,
+ 0x0D, 0xFF, 0xDE, 0xBE, 0x27,
+ 0x04, 0x12, 0x9D, 0xA3, 0x07,
+ 0x0B, 0x15, 0x23, 0x89, 0xA1,
+ 0x00, 0x68, 0x60, 0x4E, 0x30,
+ 0x05, 0x2D, 0xEF, 0xE9, 0xF9,
+ 0x0E, 0x2B, 0x19, 0x59, 0x05,
+ 0x07, 0x26, 0x24, 0x62, 0xB1,
+ 0x0E, 0x69, 0x17, 0xC5, 0x8F,
+ 0x0A, 0xCF, 0x9D, 0x78, 0xDA,
+ 0x07, 0xB1, 0xFD, 0x7A, 0xB5,
+ 0x0F, 0x2A, 0x61, 0x60, 0x73,
+ 0x0F, 0x70, 0x9B, 0xC8, 0x67,
+ 0x07, 0xDA, 0xB7, 0x7B, 0xDE,
+ 0x02, 0x0E, 0xFE, 0x5C, 0xD5,
+ 0x07, 0x3B, 0x47, 0x99, 0x36,
+ 0x06, 0x47, 0x04, 0x17, 0x21,
+ 0x01, 0x70, 0x04, 0x61, 0x39,
+ 0x06, 0x1B, 0xD1, 0x72, 0x28,
+ 0x06, 0x9F, 0xB0, 0x4F, 0x74,
+ 0x04, 0xCC, 0x2C, 0x63, 0xE8,
+ 0x08, 0xFE, 0xE3, 0x9D, 0x45,
+ 0x07, 0xBE, 0x08, 0x35, 0x77,
+ 0x0A, 0xB5, 0x90, 0xD0, 0x09,
+ 0x02, 0x5C, 0xA0, 0xE7, 0x54,
+ 0x00, 0x2D, 0xF6, 0x42, 0x9F,
+ 0x0A, 0x69, 0x13, 0xC7, 0xE1,
+ 0x05, 0x7D, 0xD5, 0x96, 0x38,
+ 0x0A, 0x8E, 0xD6, 0xEC, 0x50,
+ 0x02, 0x37, 0x47, 0xA6, 0x27,
+ 0x0A, 0x8D, 0xB0, 0xF4, 0x9E,
+ 0x07, 0xA6, 0xE4, 0x54, 0x8F
+};
+
+static int ak7719_read_reg(struct ak7719_data *ak7719, u8 reg)
+{
+ int ret = i2c_smbus_read_byte_data(ak7719->client, reg);
+ if (ret > 0)
+ ret &= 0xff;
+
+ return ret;
+}
+
+static int ak7719_write_reg(struct ak7719_data *ak7719,
+ u8 reg, u8 value)
+{
+ return i2c_smbus_write_byte_data(ak7719->client, reg, value);
+}
+
+/*used to calculate the crc value for PRAM or CRAM binary*/
+unsigned short calc_crc(const char *str, unsigned short length)
+{
+ unsigned short crc = 0x0000;
+ int i, j;
+ for(i = 0; i < length; i++){
+ crc ^= *str++ << 8;
+ for(j = 0; j < 8; j++){
+ if(crc & 0x8000){
+ crc <<= 1;
+ crc ^= CRC16_CCITT;
+ } else {
+ crc <<= 1;
+ }
+ }
+ }
+
+ return crc;
+}
+
+static int ak7719_write_command(struct ak7719_data *ak7719, u8 cmdvalue,
+ u32 subaddr, u8 *pbuf, unsigned int length, u16 *crc_val)
+{
+ int ret;
+ u8 *bufcmd = NULL;
+ struct i2c_msg msg[1];
+ struct i2c_client *client;
+ client = ak7719->client;
+
+ bufcmd = kmalloc(length+3, GFP_KERNEL);
+ if (!bufcmd) {
+ return -ENOMEM;
+ }
+ bufcmd[0] = cmdvalue;
+ bufcmd[1] = (subaddr & 0xff00) >> 8;
+ bufcmd[2] = subaddr & 0xff;
+ memcpy(bufcmd + 3, pbuf, length);
+
+ /*calculate the crc value for the writing data*/
+ if(*crc_val == 0)
+ *crc_val = calc_crc(bufcmd, length+3);
+
+ /*begin to encapsulate the message for i2c*/
+ msg[0].addr = client->addr;
+ msg[0].len = length +3;
+ msg[0].flags = 0;
+ msg[0].buf = bufcmd;
+
+ ret = i2c_transfer(client->adapter, msg, 1);
+ udelay(100);
+
+ kfree(bufcmd);
+ if (ret < 0) {
+ dev_err(&client->dev, "Failed writing cmd 0x%02x!\n", cmdvalue);
+ return ret;
+ }
+ return 0;
+}
+
+unsigned short ak7719_ram_read(struct ak7719_data *ak7719, char *sbuf, u8 slen, char *rbuf, u8 rlen){
+ int ret;
+
+ ret = i2c_smbus_read_i2c_block_data(ak7719->client, sbuf[0], rlen, rbuf);
+
+ return 0;
+}
+
+static int ak7719_ram_download_crc(struct ak7719_data *ak7719, u8 cmd, u8 *data, int len ,u16 crc_value)
+{
+ u16 crc_val = crc_value;
+ u16 crc_flag = 1;
+ char crc_tx[1] = { 0x72 };
+ char crc_rx[2];
+ int ret, ret1, timeout = crc_timeout; //timeout = 3; chane 3 times to 10 times
+
+ do { /*write PRAM or CRAM and get crc value*/
+ ret1 = ak7719_write_command(ak7719, cmd, 0, data, len, &crc_val);
+ if (ret1 != 0) {
+ pr_err(" write ram error in function %s\n ",__FUNCTION__);
+ continue;
+ }
+
+ /*get the crc value by command 0x72*/
+ do {
+ ret = ak7719_ram_read(ak7719, crc_tx, 1, crc_rx, 2);
+ if(ret != 0)
+ pr_err("%s: read crc err\n",__FUNCTION__);
+ } while (ret != 0);
+
+ ret = (crc_rx[0] << 8) + crc_rx[1];
+ akdbgprt("pram : crc flag ret=%x \n" ,ret);
+ crc_flag = (crc_val == ret);
+ timeout--;
+ udelay(10);
+ } while (crc_flag == 0 && timeout > 0);
+
+ akdbgprt("crc_flag = %d timeout = %d\n", crc_flag, timeout);
+ if(timeout == 0)
+ return -1;
+ return 0;
+}
+
+static void ak7719_download_dsp_pro(struct ak7719_data *ak7719)
+{
+ int ret;
+
+ if(aec == 1) {
+ /* pram data is ak7719 dsp binary */
+ ret = ak7719_ram_download_crc(ak7719, 0xB8, pram_data, ARRAY_SIZE(pram_data), 0xc4a9);
+ if(ret < 0) {
+ printk("ak7719:write dsp binary failed!!!\n");
+ }
+ } else if(aec == 0) {
+ /* ak77dspPRAM is ak7719 bypass dsp binary */
+ ak7719_ram_download_crc(ak7719, 0xB8, ak77dspPRAM, ARRAY_SIZE(ak77dspPRAM), 0x5bf4);
+ }
+
+ ret = ak7719_ram_download_crc(ak7719, 0xB4, cram_data, ARRAY_SIZE(cram_data), 0x50df);
+ if(ret < 0)
+ printk("ak7719:write cram data failed\n");
+
+ ak7719_write_reg(ak7719, 0xc6, 0x0);
+ ak7719_write_reg(ak7719, 0xc6, 0x4);
+
+}
+
+static void ak7719_download_work(struct work_struct *work){
+ struct ak7719_workqueue *ak7719_work = container_of(work,struct ak7719_workqueue, download_binary);
+ ak7719_download_dsp_pro(ak7719_work->data);
+}
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static int ak7719_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ int rval = 0;
+ enum of_gpio_flags flags;
+ struct device_node *np = i2c->dev.of_node;
+ struct ak7719_data *ak7719 = NULL;
+ int rst_pin;
+
+ ak7719 = devm_kzalloc(&i2c->dev, sizeof(struct ak7719_data), GFP_KERNEL);
+ if (ak7719 == NULL) {
+ printk("kzalloc for ak7719 is failed\n");
+ return -ENOMEM;
+ }
+
+ rst_pin = of_get_gpio_flags(np, 0, &flags);
+ if (rst_pin < 0 || !gpio_is_valid(rst_pin)) {
+ printk("ak7719 rst pin is not working");
+ rval = -ENXIO;
+ goto out;
+ }
+
+ ak7719->rst_pin = rst_pin;
+ ak7719->rst_active = !!(flags & OF_GPIO_ACTIVE_LOW);
+
+ ak7719->client = i2c;
+ i2c_set_clientdata(i2c, ak7719);
+#if 1
+ rval = devm_gpio_request(&i2c->dev, ak7719->rst_pin, "ak7719 reset");
+ if (rval < 0){
+ dev_err(&i2c->dev, "Failed to request rst_pin: %d\n", rval);
+ goto out;
+ }
+
+ /* Reset AK7719 dsp */
+ gpio_direction_output(ak7719->rst_pin, ak7719->rst_active);
+ msleep(10);
+ gpio_direction_output(ak7719->rst_pin, !ak7719->rst_active);
+ msleep(10);
+#endif
+ ak7719_read_reg(ak7719, 0x50);
+ ak7719_read_reg(ak7719, 0x51);
+ ak7719_write_reg(ak7719, 0xd0, 0x1);
+ ak7719_write_reg(ak7719, 0xd1, 0x1);
+ ak7719_write_reg(ak7719, 0xc0, 0x20);
+ ak7719_write_reg(ak7719, 0xc1, 0x30);
+ ak7719_write_reg(ak7719, 0xc2, 0x64);
+ ak7719_write_reg(ak7719, 0xc3, 0xb2);
+ ak7719_write_reg(ak7719, 0xc4, 0xf0);
+ ak7719_write_reg(ak7719, 0xc5, 0x0);
+ ak7719_write_reg(ak7719, 0xc6, 0x0);
+ //ak7719_write_reg(ak7719, 0xc7, 0x0);
+ ak7719_write_reg(ak7719, 0xc8, 0x80);
+// ak7719_read_reg(ak7719, 0x50);
+// ak7719_read_reg(ak7719, 0x51);
+// ak7719_read_reg(ak7719, 0x47);
+
+ ak7719_write_reg(ak7719, 0xc6, 0x20);
+ msleep(1);
+
+ ak7719_wq = create_workqueue("ak7719_workqueue");
+ ak7719_work.data = ak7719;
+ INIT_WORK(&(ak7719_work.download_binary), ak7719_download_work);
+ queue_work(ak7719_wq, &(ak7719_work.download_binary));
+
+ return 0;
+out:
+ devm_kfree(&i2c->dev, ak7719);
+ return rval;
+}
+
+static int ak7719_i2c_remove(struct i2c_client *client)
+{ struct ak7719_data *ak7719 = NULL;
+
+ destroy_workqueue(ak7719_wq);
+ ak7719_wq = NULL;
+ ak7719_work.data = NULL;
+ ak7719 = i2c_get_clientdata(client);
+ devm_gpio_free(&client->dev, ak7719->rst_pin);
+ devm_kfree(&client->dev, ak7719);
+
+ return 0;
+}
+
+static const struct of_device_id ak7719_dt_ids[] = {
+ { .compatible = "ambarella,ak7719",},
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, ak7719_dt_ids);
+
+static const struct i2c_device_id ak7719_i2c_id[] = {
+ { "ak7719", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ak7719_i2c_id);
+
+static struct i2c_driver ak7719_i2c_driver = {
+ .driver = {
+ .name = "DRIVER_NAME",
+ .owner = THIS_MODULE,
+ .of_match_table = ak7719_dt_ids,
+ },
+ .probe = ak7719_i2c_probe,
+ .remove = ak7719_i2c_remove,
+ .id_table = ak7719_i2c_id,
+};
+#endif
+
+static int __init ak7719_modinit(void)
+{
+ int ret;
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ ret = i2c_add_driver(&ak7719_i2c_driver);
+ if (ret != 0)
+ pr_err("Failed to register AK7719 I2C driver: %d\n", ret);
+#endif
+ return ret;
+}
+module_init(ak7719_modinit);
+static void __exit ak7719_exit(void)
+{
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ i2c_del_driver(&ak7719_i2c_driver);
+#endif
+}
+module_exit(ak7719_exit);
+
+MODULE_DESCRIPTION("Amabrella Board AK7719 DSP for Audio Codec");
+MODULE_AUTHOR("Ken He <jianhe@ambarella.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:"DRIVER_NAME);
diff --git a/sound/soc/codecs/ak7755.c b/sound/soc/codecs/ak7755.c
new file mode 100644
index 00000000..d74d5fc0
--- /dev/null
+++ b/sound/soc/codecs/ak7755.c
@@ -0,0 +1,2720 @@
+/*
+ * ak7755.c -- audio driver for AK7755
+ *
+ * Copyright (C) 2014 Asahi Kasei Microdevices Corporation
+ * Author Date Revision
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * 14/04/22 1.0
+ * 15/06/15 1.1
+ * 16/01/13 2.01 kernel 3.10.94
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+#include <sound/pcm_params.h>
+#include <linux/ioctl.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/spi/spi.h>
+#include <plat/spi.h>
+
+
+#include <linux/of_gpio.h> // '16/01/13
+
+#include <linux/mutex.h>
+#include <linux/firmware.h>
+#include <linux/vmalloc.h>
+
+#include <sound/ak7755_pdata.h> // '15/06/15
+#include "ak7755.h"
+#include "ak7755_dsp_code.h"
+#include <linux/types.h>
+
+//#define AK7755_PD_SUSPEND // '15/06/15
+
+//#define AK7755_DEBUG //used at debug mode
+#define AK7755_CONTIF_DEBUG //used at debug mode
+
+#ifdef AK7755_DEBUG
+#define akdbgprt printk
+#else
+#define akdbgprt(format, arg...) do {} while (0)
+#endif
+static int fast_boot = 0;
+module_param(fast_boot, uint, 0664);
+static int aec = 1;
+module_param(aec, uint, 0664);
+static int RAM_FLAG = 1;
+
+/* AK7755 Codec Private Data */
+struct ak7755_priv {
+ enum snd_soc_control_type control_type;
+ struct snd_soc_codec *codec;
+ struct spi_device *spi;
+ struct i2c_client *i2c;
+ int fs;
+ int rclk; //Master Clock
+ int lign; //LIGN3-0(LineIn Volume)
+ int selmix; //SELMIX2-0
+ int status;
+ int MIRNo;
+ int bickfs; // '15/06/15 0:64fs, 1:48fs, 2:32fs, 3:256fs
+ int pdn_gpio; // '15/06/15
+ unsigned int pdn_active;
+ int power_gpio;
+ unsigned int power_active;
+ int amp_gpio;
+ unsigned int amp_active;
+ unsigned int fmt;
+ u8 reg_cache[AK7755_MAX_REGNUM];
+
+ u16 DSPPramMode;
+ u16 DSPCramMode;
+ u16 DSPOfregMode;
+ u16 DSPAcramMode;
+ int EQLevel[5];
+ int HPFfc[2];
+ int LimRel;
+ int LimVol;
+};
+
+struct _ak7755_pd_handler {
+ int ref_count;
+ struct mutex lock;
+ struct ak7755_priv *data;
+} ak7755_pd_handler = {
+ .ref_count = -1,
+ .data = NULL,
+};
+
+
+static int ak7755_reads(u8 *, size_t, u8 *, size_t);
+static int ak7755_writes(const u8 *tx, size_t wlen);
+static unsigned int ak7755_i2c_read(u8 *reg,int reglen,u8 *data,int datalen);
+
+
+static struct ak7755_priv *ak7755_data;
+/* ak7755 register cache & default register settings */
+static u8 ak7755_reg[AK7755_MAX_REGISTERS];
+
+static const u8 ak7755_reg2[] = {
+ 0x00, /* 0xC0 AK7755_C0_CLOCK_SETTING1 */
+ 0x00, /* 0xC1 AK7755_C1_CLOCK_SETTING2 */
+ 0x00, /* 0xC2 AK7755_C2_SERIAL_DATA_FORMAT */
+ 0x00, /* 0xC3 AK7755_C3_DELAY_RAM_DSP_IO */
+ 0x00, /* 0xC4 AK7755_C4_DATARAM_CRAM_SETTING */
+ 0x00, /* 0xC5 AK7755_C5_ACCELARETOR_SETTING */
+ 0x00, /* 0xC6 AK7755_C6_DAC_DEM_SETTING */
+ 0x00, /* 0xC7 AK7755_C7_DSP_OUT_SETTING */
+ 0x00, /* 0xC8 AK7755_C8_DAC_IN_SETTING */
+ 0x00, /* 0xC9 AK7755_C9_ANALOG_IO_SETTING */
+ 0x00, /* 0xCA AK7755_CA_CLK_SDOUT_SETTING */
+ 0x00, /* 0xCB AK7755_CB_TEST_SETTING */
+ 0x00, /* 0xCC AK7755_CC_VOLUME_TRANSITION */
+ 0x80, /* 0xCD AK7755_CD_STO_DLS_SETTING */
+ 0x00, /* 0xCE AK7755_CE_POWER_MANAGEMENT */
+ 0x00, /* 0xCF AK7755_CF_RESET_POWER_SETTING */
+ 0x00, /* 0xD0 AK7755_D0_FUNCTION_SETTING */
+ 0x00, /* 0xD1 AK7755_D1_DSPMCLK_SETTING */
+ 0x00, /* 0xD2 AK7755_D2_MIC_GAIN_SETTING */
+ 0x00, /* 0xD3 AK7755_D3_LIN_LO3_VOLUME_SETTING */
+ 0x00, /* 0xD4 AK7755_D4_LO1_LO2_VOLUME_SETTING */
+ 0x30, /* 0xD5 AK7755_D5_ADC_DVOLUME_SETTING1 */
+ 0x30, /* 0xD6 AK7755_D6_ADC_DVOLUME_SETTING2 */
+ 0x30, /* 0xD7 AK7755_D7_ADC2_DVOLUME_SETTING1 */
+ 0x18, /* 0xD8 AK7755_D8_DAC_DVOLUME_SETTING1 */
+ 0x18, /* 0xD9 AK7755_D9_DAC_DVOLUME_SETTING2 */
+ 0x00, /* 0xDA AK7755_DA_MUTE_ADRC_ZEROCROSS_SET */
+ 0x00, /* 0xDB AK7755_DB_ADRC_MIC_GAIN_READ */
+ 0x00, /* 0xDC AK7755_DC_TEST_SETTING */
+ 0x30, /* 0xDD AK7755_DD_ADC2_DVOLUME_SETTING2 */
+ 0x00, /* 0xDE AK7755_DE_DMIC_IF_SETTING */
+};
+
+static struct {
+ int readable; /* Mask of readable bits */
+ int writable; /* Mask of writable bits */
+} ak7755_access_masks[AK7755_MAX_REGISTERS];
+
+static const struct {
+ int readable; /* Mask of readable bits */
+ int writable; /* Mask of writable bits */
+} ak7755_access_masks2[] = {
+ { 0xFF, 0x7F }, //0xC0
+ { 0xFF, 0xFF }, //0xC1
+ { 0xFF, 0xFF }, //0xC2
+ { 0xFF, 0xFF }, //0xC3
+ { 0xFF, 0xFB }, //0xC4
+ { 0xFF, 0xFF }, //0xC5
+ { 0xFF, 0xF7 }, //0xC6
+ { 0xFF, 0xF7 }, //0xC7
+ { 0xFF, 0xFF }, //0xC8
+ { 0xFF, 0xFF }, //0xC9
+ { 0xFF, 0xE7 }, //0xCA
+ { 0xFF, 0x00 }, //0xCB
+ { 0xFF, 0xB7 }, //0xCC
+ { 0xFF, 0x81 }, //0xCD
+ { 0xFF, 0xFF }, //0xCE
+ { 0xFF, 0x3F }, //0xCF
+ { 0xFF, 0xF9 }, //0xD0
+ { 0xFF, 0xFF }, //0xD1
+ { 0xFF, 0xFF }, //0xD2
+ { 0xFF, 0xFF }, //0xD3
+ { 0xFF, 0xFF }, //0xD4
+ { 0xFF, 0xFF }, //0xD5
+ { 0xFF, 0xFF }, //0xD6
+ { 0xFF, 0xFF }, //0xD7
+ { 0xFF, 0xFF }, //0xD8
+ { 0xFF, 0xFF }, //0xD9
+ { 0xFF, 0xFF }, //0xDA
+ { 0xFF, 0x00 }, //0xDB
+ { 0xFF, 0x00 }, //0xDC
+ { 0xFF, 0xFF }, //0xDD
+ { 0xFF, 0xFC }, //0xDE
+};
+
+/* MIC Input Volume control:
+ * from 0 to 36 dB (quantity of each step is various) */
+static DECLARE_TLV_DB_MINMAX(mgnl_tlv, 0, 3600);
+static DECLARE_TLV_DB_MINMAX(mgnr_tlv, 0, 3600);
+
+/* Line-out Volume control:
+ * from -30 to 0 dB in 2 dB steps (mute instead of -30 dB) */
+static DECLARE_TLV_DB_SCALE(lovol1_tlv, -3000, 200, 0);
+static DECLARE_TLV_DB_SCALE(lovol2_tlv, -3000, 200, 0);
+static DECLARE_TLV_DB_SCALE(lovol3_tlv, -3000, 200, 0);
+
+static const char *line_in_texts[] =
+{
+ "-21dB","-18dB","-15dB","-12dB","-9dB","-6dB","-3dB",
+ "0dB","+3dB","+6dB","+9dB","+12dB","+15dB","+18dB","+21dB",
+};
+
+static const struct soc_enum ak7755_linein_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(line_in_texts), line_in_texts),
+};
+
+/* ADC, ADC2 Digital Volume control:
+ * from -103.5 to 24 dB in 0.5 dB steps (mute instead of -103.5 dB) */
+static DECLARE_TLV_DB_SCALE(voladl_tlv, -10350, 50, 0);
+static DECLARE_TLV_DB_SCALE(voladr_tlv, -10350, 50, 0);
+static DECLARE_TLV_DB_SCALE(volad2l_tlv, -10350, 50, 0);
+static DECLARE_TLV_DB_SCALE(volad2r_tlv, -10350, 50, 0);
+
+/* DAC Digital Volume control:
+ * from -115.5 to 12 dB in 0.5 dB steps (mute instead of -115.5 dB) */
+static DECLARE_TLV_DB_SCALE(voldal_tlv, -11550, 50, 0);
+static DECLARE_TLV_DB_SCALE(voldar_tlv, -11550, 50, 0);
+
+
+static const char *ak7755_bank_select_texts[] =
+ {"0:8192", "1024:7168","2048:6144","3072:5120","4096:4096",
+ "5120:3072","6144:2048","7168:1024","8192:0"};
+static const char *ak7755_drms_select_texts[] =
+ {"512:1536", "1024:1024", "1536:512"};
+static const char *ak7755_dram_select_texts[] =
+ {"Ring:Ring", "Ring:Linear", "Linear:Ring", "Linear:Linear"};
+static const char *ak7755_pomode_select_texts[] = {"DBUS Immediate", "OFREG"};
+static const char *ak7755_wavp_select_texts[] =
+ {"33 word", "65 word", "129 word", "257 word"};
+static const char *ak7755_filmode1_select_texts[] = {"Adaptive Filter", "FIR Filter"};
+static const char *ak7755_filmode2_select_texts[] = {"Adaptive Filter", "FIR Filter"};
+static const char *ak7755_submode1_select_texts[] = {"Fullband", "Subband"};
+static const char *ak7755_submode2_select_texts[] = {"Fullband", "Subband"};
+static const char *ak7755_memdiv_select_texts[] =
+ {"2048:-", "1792:256", "1536:512", "1024:1024"};
+static const char *ak7755_dem_select_texts[] = {"Off", "48kHz", "44.1kHz", "32kHz"};
+static const char *ak7755_clkoe_select_texts[] = {"CLKO=L", "CLKO Out Enable"};
+static const char *ak7755_clks_select_texts[] =
+ {"12.288MHz", "6.144MHz", "3.072MHz", "8.192MHz",
+ "4.096MHz", "2.048MHz", "256fs", "XTI or BICK"};
+
+static const struct soc_enum ak7755_set_enum[] = {
+ SOC_ENUM_SINGLE(AK7755_C3_DELAY_RAM_DSP_IO, 0,
+ ARRAY_SIZE(ak7755_bank_select_texts), ak7755_bank_select_texts),
+ SOC_ENUM_SINGLE(AK7755_C4_DATARAM_CRAM_SETTING, 6,
+ ARRAY_SIZE(ak7755_drms_select_texts), ak7755_drms_select_texts),
+ SOC_ENUM_SINGLE(AK7755_C4_DATARAM_CRAM_SETTING, 4,
+ ARRAY_SIZE(ak7755_dram_select_texts), ak7755_dram_select_texts),
+ SOC_ENUM_SINGLE(AK7755_C4_DATARAM_CRAM_SETTING, 3,
+ ARRAY_SIZE(ak7755_pomode_select_texts), ak7755_pomode_select_texts),
+ SOC_ENUM_SINGLE(AK7755_C4_DATARAM_CRAM_SETTING, 0,
+ ARRAY_SIZE(ak7755_wavp_select_texts), ak7755_wavp_select_texts),
+ SOC_ENUM_SINGLE(AK7755_C5_ACCELARETOR_SETTING, 5,
+ ARRAY_SIZE(ak7755_filmode1_select_texts), ak7755_filmode1_select_texts),
+ SOC_ENUM_SINGLE(AK7755_C5_ACCELARETOR_SETTING, 4,
+ ARRAY_SIZE(ak7755_filmode2_select_texts), ak7755_filmode2_select_texts),
+ SOC_ENUM_SINGLE(AK7755_C5_ACCELARETOR_SETTING, 3,
+ ARRAY_SIZE(ak7755_submode1_select_texts), ak7755_submode1_select_texts),
+ SOC_ENUM_SINGLE(AK7755_C5_ACCELARETOR_SETTING, 2,
+ ARRAY_SIZE(ak7755_submode2_select_texts), ak7755_submode2_select_texts),
+ SOC_ENUM_SINGLE(AK7755_C5_ACCELARETOR_SETTING, 0,
+ ARRAY_SIZE(ak7755_memdiv_select_texts), ak7755_memdiv_select_texts),
+ SOC_ENUM_SINGLE(AK7755_C6_DAC_DEM_SETTING, 6,
+ ARRAY_SIZE(ak7755_dem_select_texts), ak7755_dem_select_texts),
+ SOC_ENUM_SINGLE(AK7755_CA_CLK_SDOUT_SETTING, 7,
+ ARRAY_SIZE(ak7755_clkoe_select_texts), ak7755_clkoe_select_texts),
+ SOC_ENUM_SINGLE(AK7755_C1_CLOCK_SETTING2, 1,
+ ARRAY_SIZE(ak7755_clks_select_texts), ak7755_clks_select_texts),
+};
+
+// '15/06/15
+static const char *ak7755_bick_select_texts[] =
+ {"64fs", "48fs", "32fs", "TDM" };
+
+static const struct soc_enum ak7755_bick_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ak7755_bick_select_texts), ak7755_bick_select_texts)
+};
+
+static int get_bickfs(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = ak7755->bickfs;
+
+ return 0;
+}
+
+static int set_bickfs(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);
+
+ ak7755->bickfs = ucontrol->value.enumerated.item[0];
+ return 0;
+}
+// '15/06/15
+
+static const char *selmix_set_texts[] =
+{
+ "SDOUTAD", "ADL_AD2L/ADR", "ADL/ADR_AD2R", "SDOUTAD2",
+ "DSPL/AD2R", "AD2L/DSPR", "DSPL/ADR", "ADL/DSPR",
+};
+
+static const struct soc_enum ak7755_selmix_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(selmix_set_texts), selmix_set_texts),
+};
+
+// Added for AK7755
+static const struct soc_enum ak7755_firmware_enum[] =
+{
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ak7755_firmware_pram), ak7755_firmware_pram),
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ak7755_firmware_cram), ak7755_firmware_cram),
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ak7755_firmware_ofreg), ak7755_firmware_ofreg),
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ak7755_firmware_acram), ak7755_firmware_acram),
+};
+
+static inline u32 ak7755_read_reg_cache(struct snd_soc_codec *, u16);
+static int ak7755_firmware_write_ram(u16 mode, u16 cmd);
+static int ak7755_set_status(enum ak7755_status status);
+static int ak7755_write_cram(int addr, int len, unsigned char *cram_data);
+
+static int get_linein(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = ak7755->lign;
+
+ return 0;
+}
+
+static int set_linein(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);
+
+ ak7755->lign = ucontrol->value.enumerated.item[0];
+
+ if ( ak7755->lign <= 7) {
+ snd_soc_update_bits(codec, AK7755_D3_LIN_LO3_VOLUME_SETTING, 0xF0, ((7 - ak7755->lign) << 4) );
+ }
+ else {
+ snd_soc_update_bits(codec, AK7755_D3_LIN_LO3_VOLUME_SETTING, 0xF0, ((ak7755->lign + 1) << 4) );
+ }
+
+ return 0;
+}
+
+static int get_selmix(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = ak7755->selmix;
+
+ return 0;
+}
+
+static int set_selmix(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);
+
+ ak7755->selmix = ucontrol->value.enumerated.item[0];
+
+ if ( ak7755->selmix < 4) { //SELMIX2=0, SELMIX1-0=selmix
+ snd_soc_update_bits(codec, AK7755_C9_ANALOG_IO_SETTING, 0x01, 0x00);
+ snd_soc_update_bits(codec, AK7755_C8_DAC_IN_SETTING, 0x03, ak7755->selmix);
+ }
+ else { //SELMIX2=1, SELMIX1-0=(selmix & 0x03)
+ snd_soc_update_bits(codec, AK7755_C9_ANALOG_IO_SETTING, 0x01, 0x01);
+ snd_soc_update_bits(codec, AK7755_C8_DAC_IN_SETTING, 0x03, (ak7755->selmix & 0x03));
+ }
+
+ return 0;
+}
+
+static int get_DSP_write_pram(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ /* Get the current output routing */
+ ucontrol->value.enumerated.item[0] = ak7755_data->DSPPramMode;
+
+ return 0;
+
+}
+
+static int set_DSP_write_pram(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ u32 currMode = ucontrol->value.enumerated.item[0];
+ int ret;
+ akdbgprt("set_DSP_write_pram start ...\n");
+
+/*
+ if ( currMode == ak7755_data->DSPPramMode ) {
+ akdbgprt("\t%s Same PRAM mode =%d\n",__FUNCTION__, currMode);
+ return(0);
+ }
+*/
+ if (RAM_FLAG ==1 ){
+ akdbgprt("\t%s PRAM mode =%d\n",__FUNCTION__, currMode);
+
+ ret = ak7755_firmware_write_ram(RAMTYPE_PRAM, currMode);
+ if ( ret != 0 ) return(-1);
+
+ ak7755_data->DSPPramMode = currMode;
+ }
+ akdbgprt("set_DSP_write_pram done ...\n");
+ return(0);
+}
+
+static int get_DSP_write_cram(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ /* Get the current output routing */
+ ucontrol->value.enumerated.item[0] = ak7755_data->DSPCramMode;
+
+ return 0;
+
+}
+
+static int set_DSP_write_cram(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ u32 currMode = ucontrol->value.enumerated.item[0];
+ int ret;
+ akdbgprt("set_DSP_write_cram start ...\n");
+
+/*
+ if ( currMode == ak7755_data->DSPCramMode ) {
+ akdbgprt("\t%s Same CRAM mode =%d\n",__FUNCTION__, currMode);
+ return(0);
+ }
+*/
+ if (RAM_FLAG ==1){
+ RAM_FLAG = 0 ;
+ akdbgprt("\t%s CRAM mode =%d\n",__FUNCTION__, currMode);
+
+ ret = ak7755_firmware_write_ram(RAMTYPE_CRAM, currMode);
+ if ( ret != 0 ) return(-1);
+
+ ak7755_data->DSPCramMode =currMode;
+ }
+ akdbgprt("set_DSP_write_cram done ...\n");
+ return(0);
+}
+
+static int get_DSP_write_ofreg(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ /* Get the current output routing */
+ ucontrol->value.enumerated.item[0] = ak7755_data->DSPOfregMode;
+
+ return 0;
+
+}
+
+static int set_DSP_write_ofreg(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ u32 currMode = ucontrol->value.enumerated.item[0];
+ int ret;
+
+/*
+ if ( currMode == ak7755_data->DSPOfregMode ) {
+ akdbgprt("\t%s Same CRAM mode =%d\n",__FUNCTION__, currMode);
+ return(0);
+ }
+ akdbgprt("\t%s OFREG mode =%d\n",__FUNCTION__, currMode);
+*/
+ ret = ak7755_firmware_write_ram(RAMTYPE_OFREG, currMode);
+ if ( ret != 0 ) return(-1);
+
+ ak7755_data->DSPOfregMode =currMode;
+
+ return(0);
+}
+
+static int get_DSP_write_acram(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ /* Get the current output routing */
+ ucontrol->value.enumerated.item[0] = ak7755_data->DSPAcramMode;
+
+ return 0;
+
+}
+
+static int set_DSP_write_acram(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ u32 currMode = ucontrol->value.enumerated.item[0];
+ int ret;
+
+/*
+ if ( currMode == ak7755_data->DSPAcramMode ) {
+ akdbgprt("\t%s Same CRAM mode =%d\n",__FUNCTION__, currMode);
+ return(0);
+ }
+*/
+ akdbgprt("\t%s ACRAM mode =%d\n",__FUNCTION__, currMode);
+
+ ret = ak7755_firmware_write_ram(RAMTYPE_ACRAM, currMode);
+ if ( ret != 0 ) return(-1);
+
+ ak7755_data->DSPAcramMode =currMode;
+
+ return(0);
+}
+
+#ifdef AK7755_DEBUG
+
+static int test_read_ram(int mode)
+{
+ u8 tx[3], rx[512];
+ int i, n, plen, clen;
+
+ akdbgprt("*****[AK7755] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ snd_soc_update_bits(ak7755_data->codec, AK7755_CF_RESET_POWER_SETTING, 0x1, 0x1); // DLRDY bit = 1
+ mdelay(1);
+ if ( mode == 1 ) {
+ plen = 10;
+ for ( n = 0 ; n < (5 * plen) ; n++ ) rx[n] = 0;
+ tx[0] = 0x38;
+ tx[1] = 0x0;
+ tx[2] = 0x0;
+ ak7755_reads(tx, 3, rx, 5 * plen);
+ printk("*****%s PRAM LEN = %d *******\n", __func__, plen);
+ n = 0;
+ for ( i = 0 ; i < plen ; i ++ ) {
+ printk("PAddr=%x %x %x %x %x %x\n", i,(int)rx[n], (int)rx[n+1], (int)rx[n+2], (int)rx[n+3], (int)rx[n+4]);
+ n += 5;
+ }
+ }
+ else if ( mode < 5 ) {
+ clen = 80;
+ for ( n = 0 ; n < (3 * clen) ; n++ ) rx[n] = 0;
+ if ( mode == 2 ) tx[0] = 0x34;
+ else if ( mode == 3 ) {
+ tx[0] = 0x32;
+ clen = 16;
+ }
+ else tx[0] = 0x3B;
+ tx[1] = 0x0;
+ tx[2] = 0x0;
+ ak7755_reads(tx, 3, rx, 3 * clen);
+ printk("*****%s RAM CMD=%d, LEN = %d*******\n", __func__, (int)tx[0], clen);
+ n = 0;
+ for ( i = 0 ; i < clen ; i ++ ) {
+ printk("CAddr=%x %x %x %x\n", i,(int)rx[n], (int)rx[n+1], (int)rx[n+2]);
+ n += 3;
+ }
+ }
+ mdelay(1);
+ snd_soc_update_bits(ak7755_data->codec, AK7755_CF_RESET_POWER_SETTING, 0x1, 0x0); // DLRDY bit = 0
+
+ return(0);
+
+}
+
+static const char *test_reg_select[] =
+{
+ "read AK7755 Reg 00:24",
+ "read PRAM",
+ "read CRAM",
+ "read OFREG",
+ "read ACRAM",
+};
+
+static const struct soc_enum ak7755_enum[] =
+{
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(test_reg_select), test_reg_select),
+};
+
+static int nTestRegNo = 0;
+
+
+static int get_test_reg(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ /* Get the current output routing */
+ ucontrol->value.enumerated.item[0] = nTestRegNo;
+
+ return 0;
+}
+
+static int set_test_reg(
+struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ u32 currMode = ucontrol->value.enumerated.item[0];
+ int i, value;
+ int regs, rege;
+
+ nTestRegNo = currMode;
+
+ if ( currMode == 0 ) {
+ regs = 0xC0;
+ rege = 0xDE;
+
+ for ( i = regs ; i <= rege ; i++ ){
+ value = snd_soc_read(codec, i);
+ printk("***AK7755 Addr,Reg=(%x, %x)\n", i, value);
+ }
+ }
+ else if ( currMode < 5 ) {
+ test_read_ram(currMode);
+ }
+
+ return 0;
+
+}
+#endif
+
+static const struct snd_kcontrol_new ak7755_snd_controls[] = {
+ SOC_SINGLE_TLV("MIC Input Volume L",
+ AK7755_D2_MIC_GAIN_SETTING, 0, 0x0F, 0, mgnl_tlv),
+ SOC_SINGLE_TLV("MIC Input Volume R",
+ AK7755_D2_MIC_GAIN_SETTING, 4, 0x0F, 0, mgnr_tlv),
+ SOC_SINGLE_TLV("Line Out Volume 1",
+ AK7755_D4_LO1_LO2_VOLUME_SETTING, 0, 0x0F, 0, lovol1_tlv),
+ SOC_SINGLE_TLV("Line Out Volume 2",
+ AK7755_D4_LO1_LO2_VOLUME_SETTING, 4, 0x0F, 0, lovol2_tlv),
+ SOC_SINGLE_TLV("Line Out Volume 3",
+ AK7755_D3_LIN_LO3_VOLUME_SETTING, 0, 0x0F, 0, lovol3_tlv),
+ SOC_ENUM_EXT("Line Input Volume", ak7755_linein_enum[0], get_linein, set_linein),
+ SOC_SINGLE_TLV("ADC Digital Volume L",
+ AK7755_D5_ADC_DVOLUME_SETTING1, 0, 0xFF, 1, voladl_tlv),
+ SOC_SINGLE_TLV("ADC Digital Volume R",
+ AK7755_D6_ADC_DVOLUME_SETTING2, 0, 0xFF, 1, voladr_tlv),
+ SOC_SINGLE_TLV("ADC2 Digital Volume L",
+ AK7755_D7_ADC2_DVOLUME_SETTING1, 0, 0xFF, 1, volad2l_tlv),
+ SOC_SINGLE_TLV("ADC2 Digital Volume R",
+ AK7755_DD_ADC2_DVOLUME_SETTING2, 0, 0xFF, 1, volad2r_tlv),
+ SOC_SINGLE_TLV("DAC Digital Volume L",
+ AK7755_D8_DAC_DVOLUME_SETTING1, 0, 0xFF, 1, voldal_tlv),
+ SOC_SINGLE_TLV("DAC Digital Volume R",
+ AK7755_D9_DAC_DVOLUME_SETTING2, 0, 0xFF, 1, voldar_tlv),
+
+ SOC_SINGLE("ADC Mute", AK7755_DA_MUTE_ADRC_ZEROCROSS_SET, 7, 1, 0),
+ SOC_SINGLE("ADC2 Mute", AK7755_DA_MUTE_ADRC_ZEROCROSS_SET, 6, 1, 0),
+ SOC_SINGLE("DAC Mute", AK7755_DA_MUTE_ADRC_ZEROCROSS_SET, 5, 1, 0),
+ SOC_SINGLE("Analog DRC Lch", AK7755_DA_MUTE_ADRC_ZEROCROSS_SET, 2, 1, 0),
+ SOC_SINGLE("Analog DRC Rch", AK7755_DA_MUTE_ADRC_ZEROCROSS_SET, 3, 1, 0),
+ SOC_SINGLE("MICGAIN Lch Zero-cross", AK7755_DA_MUTE_ADRC_ZEROCROSS_SET, 0, 1, 0),
+ SOC_SINGLE("MICGAIN Rch Zero-cross", AK7755_DA_MUTE_ADRC_ZEROCROSS_SET, 1, 1, 0),
+
+ SOC_ENUM("DAC De-emphasis", ak7755_set_enum[10]),
+
+ SOC_SINGLE("JX0 Enable", AK7755_C2_SERIAL_DATA_FORMAT, 0, 1, 0),
+ SOC_SINGLE("JX1 Enable", AK7755_C2_SERIAL_DATA_FORMAT, 1, 1, 0),
+ SOC_SINGLE("JX2 Enable", AK7755_C1_CLOCK_SETTING2, 7, 1, 0),
+ SOC_SINGLE("JX3 Enable", AK7755_C5_ACCELARETOR_SETTING, 6, 1, 0),
+
+ SOC_ENUM("DLRAM Mode(Bank1:Bank0)", ak7755_set_enum[0]),
+ SOC_ENUM("DRAM Size(Bank1:Bank0)", ak7755_set_enum[1]),
+ SOC_ENUM("DRAM Addressing Mode(Bank1:Bank0)", ak7755_set_enum[2]),
+ SOC_ENUM("POMODE DLRAM Pointer 0", ak7755_set_enum[3]),
+ SOC_ENUM("CRAM Memory Assignment", ak7755_set_enum[4]),
+ SOC_ENUM("FIRMODE1 Accelerator Ch1", ak7755_set_enum[5]),
+ SOC_ENUM("FIRMODE2 Accelerator Ch2", ak7755_set_enum[6]),
+ SOC_ENUM("SUBMODE1 Accelerator Ch1", ak7755_set_enum[7]),
+ SOC_ENUM("SUBMODE2 Accelerator Ch2", ak7755_set_enum[8]),
+ SOC_ENUM("Accelerator Memory(ch1:ch2)", ak7755_set_enum[9]),
+ SOC_ENUM("CLKO pin", ak7755_set_enum[11]),
+ SOC_ENUM("CLKO Output Clock", ak7755_set_enum[12]),
+
+ SOC_ENUM_EXT("BICK fs", ak7755_bick_enum[0], get_bickfs, set_bickfs), // '15/06/15
+
+// Added for AK7755
+ SOC_ENUM_EXT("DSP Firmware PRAM", ak7755_firmware_enum[0], get_DSP_write_pram, set_DSP_write_pram),
+ SOC_ENUM_EXT("DSP Firmware CRAM", ak7755_firmware_enum[1], get_DSP_write_cram, set_DSP_write_cram),
+ SOC_ENUM_EXT("DSP Firmware OFREG", ak7755_firmware_enum[2], get_DSP_write_ofreg, set_DSP_write_ofreg),
+ SOC_ENUM_EXT("DSP Firmware ACRAM", ak7755_firmware_enum[3], get_DSP_write_acram, set_DSP_write_acram),
+#if 0
+#ifdef AK7755_CRAM_BASIC_COTROL
+ SOC_ENUM_EXT("CRAM EQ1 Level", ak7755_cram_write_enum[0], get_cram_write_eq1, set_cram_write_eq1),
+ SOC_ENUM_EXT("CRAM EQ2 Level", ak7755_cram_write_enum[0], get_cram_write_eq2, set_cram_write_eq2),
+ SOC_ENUM_EXT("CRAM EQ3 Level", ak7755_cram_write_enum[0], get_cram_write_eq3, set_cram_write_eq3),
+ SOC_ENUM_EXT("CRAM EQ4 Level", ak7755_cram_write_enum[0], get_cram_write_eq4, set_cram_write_eq4),
+ SOC_ENUM_EXT("CRAM EQ5 Level", ak7755_cram_write_enum[0], get_cram_write_eq5, set_cram_write_eq5),
+ SOC_ENUM_EXT("CRAM HPF1 fc", ak7755_cram_write_enum[1], get_cram_write_hpf1fc, set_cram_write_hpf1fc),
+ SOC_ENUM_EXT("CRAM HPF2 fc", ak7755_cram_write_enum[1], get_cram_write_hpf2fc, set_cram_write_hpf2fc),
+ SOC_ENUM_EXT("CRAM Limiter Release Time", ak7755_cram_write_enum[2], get_cram_write_limrel, set_cram_write_limrel),
+ SOC_ENUM_EXT("CRAM Limiter Volume", ak7755_cram_write_enum[3], get_cram_write_limvol, set_cram_write_limvol),
+#endif
+#endif
+#ifdef AK7755_DEBUG
+ SOC_ENUM_EXT("Reg Read", ak7755_enum[0], get_test_reg, set_test_reg),
+#endif
+
+ SOC_ENUM_EXT("SELMIX2-0", ak7755_selmix_enum[0], get_selmix, set_selmix), //SELMIX2-0 bit setting
+
+};
+
+
+/* Clock Event for DAC, ADC */
+static int ak7755_clkset_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ akdbgprt("\t[AK7755] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU: /* after widget power up */
+ snd_soc_update_bits(codec, AK7755_CF_RESET_POWER_SETTING, 0x08,0x08); //CRESETN(CODEC ResetN)=1
+ break;
+ }
+
+ return 0;
+}
+
+/* Clock Event */
+static int ak7755_clock_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event) //CONFIG_LINF
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ akdbgprt("\t[AK7755] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU: /* after widget power up */
+ akdbgprt("\t[AK7755] %s wait=10msec\n",__FUNCTION__);
+ mdelay(10);
+ break;
+ case SND_SOC_DAPM_PRE_PMD: /* before widget power down */
+ snd_soc_update_bits(codec, AK7755_CF_RESET_POWER_SETTING, 0x08,0x00); //CODEC Reset
+ break;
+ }
+
+ return 0;
+}
+
+/* SDOUT 1 switch */
+static const struct snd_kcontrol_new ak7755_out1e_control =
+ SOC_DAPM_SINGLE("Switch", AK7755_CA_CLK_SDOUT_SETTING, 0, 1, 0);
+
+/* SDOUT 2 switch */
+static const struct snd_kcontrol_new ak7755_out2e_control =
+ SOC_DAPM_SINGLE("Switch", AK7755_CA_CLK_SDOUT_SETTING, 1, 1, 0);
+
+/* SDOUT 3 switch */
+static const struct snd_kcontrol_new ak7755_out3e_control =
+ SOC_DAPM_SINGLE("Switch", AK7755_CA_CLK_SDOUT_SETTING, 2, 1, 0);
+
+/* LineOut1 Switch */
+static const char *ak7755_pmlo1_select_texts[] =
+ {"Off", "On"};
+
+static const struct soc_enum ak7755_pmlo1_mux_enum =
+ SOC_ENUM_SINGLE(AK7755_CE_POWER_MANAGEMENT, 2,
+ ARRAY_SIZE(ak7755_pmlo1_select_texts), ak7755_pmlo1_select_texts);
+// SOC_ENUM_SINGLE(0, 0,
+// ARRAY_SIZE(ak7755_pmlo1_select_texts), ak7755_pmlo1_select_texts);
+
+static const struct snd_kcontrol_new ak7755_pmlo1_mux_control =
+ SOC_DAPM_ENUM("OUT1 SW", ak7755_pmlo1_mux_enum);
+ //SOC_DAPM_ENUM_VIRT("OUT1 SW", ak7755_pmlo1_mux_enum);
+
+/* LineOut2 Switch */
+static const char *ak7755_pmlo2_select_texts[] =
+ {"Off", "On"};
+
+static const struct soc_enum ak7755_pmlo2_mux_enum =
+ SOC_ENUM_SINGLE(AK7755_CE_POWER_MANAGEMENT, 3,
+ ARRAY_SIZE(ak7755_pmlo2_select_texts), ak7755_pmlo2_select_texts);
+// SOC_ENUM_SINGLE(0, 0,
+// ARRAY_SIZE(ak7755_pmlo2_select_texts), ak7755_pmlo2_select_texts);
+
+static const struct snd_kcontrol_new ak7755_pmlo2_mux_control =
+ SOC_DAPM_ENUM("OUT2 SW", ak7755_pmlo2_mux_enum);
+// SOC_DAPM_ENUM_VIRT("OUT2 SW", ak7755_pmlo2_mux_enum);
+
+/* LineOut3 Mixer */
+static const struct snd_kcontrol_new ak7755_lo3sw_mixer_controls[] = {
+ SOC_DAPM_SINGLE("LOSW1", AK7755_C9_ANALOG_IO_SETTING, 1, 1, 0),
+ SOC_DAPM_SINGLE("LOSW2", AK7755_C9_ANALOG_IO_SETTING, 2, 1, 0),
+#ifndef DIGITAL_MIC //LOSW3 used only Analog MIC
+ SOC_DAPM_SINGLE("LOSW3", AK7755_C9_ANALOG_IO_SETTING, 3, 1, 0),
+#endif
+};
+
+/* DSPIn Virt SWITCH */
+static const char *ak7755_dspinad_texts[] =
+ {"Off", "On"};
+
+static const struct soc_enum ak7755_dspinad_enum =
+ SOC_ENUM_SINGLE(0, 0,
+ ARRAY_SIZE(ak7755_dspinad_texts), ak7755_dspinad_texts);
+
+static const struct soc_enum ak7755_dspinad2_enum =
+ SOC_ENUM_SINGLE(0, 0,
+ ARRAY_SIZE(ak7755_dspinad_texts), ak7755_dspinad_texts);
+
+static const struct snd_kcontrol_new ak7755_dspinad_control =
+ SOC_DAPM_ENUM_VIRT("DSPINAD Switch", ak7755_dspinad_enum);
+
+static const struct snd_kcontrol_new ak7755_dspinad2_control =
+ SOC_DAPM_ENUM_VIRT("DSPINAD2 Switch", ak7755_dspinad2_enum);
+
+/* LIN MUX */
+static const char *ak7755_lin_select_texts[] =
+ {"IN1", "IN2", "INPN1"};
+
+static const struct soc_enum ak7755_lin_mux_enum =
+ SOC_ENUM_SINGLE(AK7755_C9_ANALOG_IO_SETTING, 4,
+ ARRAY_SIZE(ak7755_lin_select_texts), ak7755_lin_select_texts);
+
+static const struct snd_kcontrol_new ak7755_lin_mux_control =
+ SOC_DAPM_ENUM("LIN Select", ak7755_lin_mux_enum);
+
+/* RIN MUX */
+static const char *ak7755_rin_select_texts[] =
+ {"IN3", "IN4", "INPN2"};
+
+static const struct soc_enum ak7755_rin_mux_enum =
+ SOC_ENUM_SINGLE(AK7755_C9_ANALOG_IO_SETTING, 6,
+ ARRAY_SIZE(ak7755_rin_select_texts), ak7755_rin_select_texts);
+
+static const struct snd_kcontrol_new ak7755_rin_mux_control =
+ SOC_DAPM_ENUM("RIN Select", ak7755_rin_mux_enum);
+
+/* DAC MUX */
+static const char *ak7755_seldai_select_texts[] =
+ {"DSP", "MIXOUT", "SDIN2", "SDIN1"};
+
+static const struct soc_enum ak7755_seldai_mux_enum =
+ SOC_ENUM_SINGLE(AK7755_C8_DAC_IN_SETTING, 6,
+ ARRAY_SIZE(ak7755_seldai_select_texts), ak7755_seldai_select_texts);
+
+static const struct snd_kcontrol_new ak7755_seldai_mux_control =
+ SOC_DAPM_ENUM("SELDAI Select", ak7755_seldai_mux_enum);
+
+/* SDOUT1 MUX */
+static const char *ak7755_seldo1_select_texts[] =
+ {"DSP", "DSP GP0", "SDIN1", "SDOUTAD", "EEST", "SDOUTAD2"};
+
+static const struct soc_enum ak7755_seldo1_mux_enum =
+ SOC_ENUM_SINGLE(AK7755_CC_VOLUME_TRANSITION, 0,
+ ARRAY_SIZE(ak7755_seldo1_select_texts), ak7755_seldo1_select_texts);
+
+static const struct snd_kcontrol_new ak7755_seldo1_mux_control =
+ SOC_DAPM_ENUM("SELDO1 Select", ak7755_seldo1_mux_enum);
+
+/* SDOUT2 MUX */
+static const char *ak7755_seldo2_select_texts[] =
+ {"DSP", "DSP GP1", "SDIN2", "SDOUTAD2"};
+
+static const struct soc_enum ak7755_seldo2_mux_enum =
+ SOC_ENUM_SINGLE(AK7755_C8_DAC_IN_SETTING, 2,
+ ARRAY_SIZE(ak7755_seldo2_select_texts), ak7755_seldo2_select_texts);
+
+static const struct snd_kcontrol_new ak7755_seldo2_mux_control =
+ SOC_DAPM_ENUM("SELDO2 Select", ak7755_seldo2_mux_enum);
+
+/* SDOUT3 MUX */
+static const char *ak7755_seldo3_select_texts[] =
+ {"DSP DOUT3", "MIXOUT", "DSP DOUT4", "SDOUTAD2"};
+
+static const struct soc_enum ak7755_seldo3_mux_enum =
+ SOC_ENUM_SINGLE(AK7755_C8_DAC_IN_SETTING, 4,
+ ARRAY_SIZE(ak7755_seldo3_select_texts), ak7755_seldo3_select_texts);
+
+static const struct snd_kcontrol_new ak7755_seldo3_mux_control =
+ SOC_DAPM_ENUM("SELDO3 Select", ak7755_seldo3_mux_enum);
+
+/* SELMIX Virt SWITCH */
+static const char *ak7755_selmix_select_texts[] =
+ {"Off", "On"};
+
+static const struct soc_enum ak7755_sdoutad_selmix_enum =
+ SOC_ENUM_SINGLE(0, 0,
+ ARRAY_SIZE(ak7755_selmix_select_texts), ak7755_selmix_select_texts);
+
+static const struct soc_enum ak7755_sdoutad2_selmix_enum =
+ SOC_ENUM_SINGLE(0, 0,
+ ARRAY_SIZE(ak7755_selmix_select_texts), ak7755_selmix_select_texts);
+
+static const struct soc_enum ak7755_dsp_selmix_enum =
+ SOC_ENUM_SINGLE(0, 0,
+ ARRAY_SIZE(ak7755_selmix_select_texts), ak7755_selmix_select_texts);
+
+static const struct snd_kcontrol_new ak7755_sdoutad_selmix_control =
+ SOC_DAPM_ENUM_VIRT("SELMIX Switch", ak7755_sdoutad_selmix_enum);
+
+static const struct snd_kcontrol_new ak7755_sdoutad2_selmix_control =
+ SOC_DAPM_ENUM_VIRT("SELMIX Switch", ak7755_sdoutad2_selmix_enum);
+
+static const struct snd_kcontrol_new ak7755_dsp_selmix_control =
+ SOC_DAPM_ENUM_VIRT("SELMIX Switch", ak7755_dsp_selmix_enum);
+
+
+
+/* ak7755 dapm widgets */
+static const struct snd_soc_dapm_widget ak7755_dapm_widgets[] = {
+
+// ADC, DAC
+#ifdef DIGITAL_MIC
+ SND_SOC_DAPM_INPUT("DMICIN1"),
+ SND_SOC_DAPM_INPUT("DMICIN2"),
+ SND_SOC_DAPM_ADC_E("DMIC1 Left", "NULL", AK7755_CE_POWER_MANAGEMENT, 6, 0,
+ ak7755_clkset_event, SND_SOC_DAPM_POST_PMU ),
+ SND_SOC_DAPM_ADC_E("DMIC1 Right", "NULL", AK7755_CE_POWER_MANAGEMENT, 7, 0,
+ ak7755_clkset_event, SND_SOC_DAPM_POST_PMU ),
+ SND_SOC_DAPM_ADC_E("DMIC2 Left", "NULL", AK7755_CE_POWER_MANAGEMENT, 5, 0,
+ ak7755_clkset_event, SND_SOC_DAPM_POST_PMU ),
+ SND_SOC_DAPM_ADC_E("DMIC2 Right", "NULL", AK7755_CF_RESET_POWER_SETTING, 1, 0,
+ ak7755_clkset_event, SND_SOC_DAPM_POST_PMU ),
+ SND_SOC_DAPM_SUPPLY("DMIC1 CLK", AK7755_DE_DMIC_IF_SETTING, 5, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("DMIC2 CLK", AK7755_DE_DMIC_IF_SETTING, 2, 0, NULL, 0),
+#else
+ SND_SOC_DAPM_ADC_E("ADC Left", "NULL", AK7755_CE_POWER_MANAGEMENT, 6, 0,
+ ak7755_clkset_event, SND_SOC_DAPM_POST_PMU ),
+ SND_SOC_DAPM_ADC_E("ADC Right", "NULL", AK7755_CE_POWER_MANAGEMENT, 7, 0,
+ ak7755_clkset_event, SND_SOC_DAPM_POST_PMU ),
+ SND_SOC_DAPM_ADC_E("ADC2 Left", "NULL", AK7755_CE_POWER_MANAGEMENT, 5, 0,
+ ak7755_clkset_event, SND_SOC_DAPM_POST_PMU ),
+#endif
+ SND_SOC_DAPM_DAC_E("DAC Left", "NULL", AK7755_CE_POWER_MANAGEMENT, 0, 0,
+ ak7755_clkset_event, SND_SOC_DAPM_POST_PMU ),
+ SND_SOC_DAPM_DAC_E("DAC Right", "NULL", AK7755_CE_POWER_MANAGEMENT, 1, 0,
+ ak7755_clkset_event, SND_SOC_DAPM_POST_PMU ),
+ SND_SOC_DAPM_SUPPLY("CLOCK", AK7755_C1_CLOCK_SETTING2, 0, 0,
+ ak7755_clock_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+
+// Analog Output
+ SND_SOC_DAPM_OUTPUT("Line Out1"),
+ SND_SOC_DAPM_OUTPUT("Line Out2"),
+ SND_SOC_DAPM_OUTPUT("Line Out3"),
+
+ SND_SOC_DAPM_MIXER("LineOut Amp3 Mixer", AK7755_CE_POWER_MANAGEMENT, 4, 0,
+ &ak7755_lo3sw_mixer_controls[0], ARRAY_SIZE(ak7755_lo3sw_mixer_controls)),
+// SND_SOC_DAPM_MUX("LineOut Amp2", AK7755_CE_POWER_MANAGEMENT, 3, 0, &ak7755_pmlo2_mux_control),
+// SND_SOC_DAPM_MUX("LineOut Amp1", AK7755_CE_POWER_MANAGEMENT, 2, 0, &ak7755_pmlo1_mux_control),
+
+ SND_SOC_DAPM_MUX("LineOut Amp1", SND_SOC_NOPM, 0, 0, &ak7755_pmlo1_mux_control),
+ SND_SOC_DAPM_MUX("LineOut Amp2", SND_SOC_NOPM, 0, 0, &ak7755_pmlo2_mux_control),
+
+// Analog Input
+ SND_SOC_DAPM_INPUT("LIN"),
+ SND_SOC_DAPM_INPUT("IN1"),
+ SND_SOC_DAPM_INPUT("IN2"),
+ SND_SOC_DAPM_INPUT("IN3"),
+ SND_SOC_DAPM_INPUT("IN4"),
+ SND_SOC_DAPM_INPUT("INPN1"),
+ SND_SOC_DAPM_INPUT("INPN2"),
+
+ SND_SOC_DAPM_PGA("LineIn Amp", AK7755_CF_RESET_POWER_SETTING, 5, 0, NULL, 0),
+ SND_SOC_DAPM_MUX("RIN MUX", SND_SOC_NOPM, 0, 0, &ak7755_rin_mux_control),
+ SND_SOC_DAPM_MUX("LIN MUX", SND_SOC_NOPM, 0, 0, &ak7755_lin_mux_control),
+ SND_SOC_DAPM_VIRT_MUX("DSPIN SDOUTAD2", SND_SOC_NOPM, 0, 0, &ak7755_dspinad2_control),
+ SND_SOC_DAPM_VIRT_MUX("DSPIN SDOUTAD", SND_SOC_NOPM, 0, 0, &ak7755_dspinad_control),
+
+// Digital Input/Output
+ SND_SOC_DAPM_AIF_IN("SDIN1", "Playback", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("SDIN2", "Playback", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("SDOUT1", "Capture", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("SDOUT2", "Capture", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("SDOUT3", "Capture", 0, SND_SOC_NOPM, 0, 0),
+
+ SND_SOC_DAPM_SWITCH("SDOUT3 Enable", SND_SOC_NOPM, 0, 0,
+ &ak7755_out3e_control),
+ SND_SOC_DAPM_SWITCH("SDOUT2 Enable", SND_SOC_NOPM, 0, 0,
+ &ak7755_out2e_control),
+ SND_SOC_DAPM_SWITCH("SDOUT1 Enable", SND_SOC_NOPM, 0, 0,
+ &ak7755_out1e_control),
+
+ SND_SOC_DAPM_PGA("SDOUTAD", SND_SOC_NOPM, 0, 0, NULL, 0), //ADC's Output
+ SND_SOC_DAPM_PGA("SDOUTAD2", SND_SOC_NOPM, 0, 0, NULL, 0), //ADC2's Output
+ SND_SOC_DAPM_PGA("DSP", AK7755_CF_RESET_POWER_SETTING, 2, 0, NULL, 0),
+
+ SND_SOC_DAPM_AIF_IN("DSP GP0", NULL, 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("DSP GP1", NULL, 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("EEST", NULL, 0, SND_SOC_NOPM, 0, 0),
+
+// Multiplexer (selects 1 analog signal from many inputs) & Mixer
+ SND_SOC_DAPM_MUX("SDOUT3 MUX", SND_SOC_NOPM, 0, 0, &ak7755_seldo3_mux_control),
+ SND_SOC_DAPM_MUX("SDOUT2 MUX", SND_SOC_NOPM, 0, 0, &ak7755_seldo2_mux_control),
+ SND_SOC_DAPM_MUX("SDOUT1 MUX", SND_SOC_NOPM, 0, 0, &ak7755_seldo1_mux_control),
+ SND_SOC_DAPM_MUX("DAC MUX", SND_SOC_NOPM, 0, 0, &ak7755_seldai_mux_control),
+ SND_SOC_DAPM_VIRT_MUX("SELMIX DSP", SND_SOC_NOPM, 0, 0, &ak7755_dsp_selmix_control),
+ SND_SOC_DAPM_VIRT_MUX("SELMIX AD2", SND_SOC_NOPM, 0, 0, &ak7755_sdoutad2_selmix_control),
+ SND_SOC_DAPM_VIRT_MUX("SELMIX AD", SND_SOC_NOPM, 0, 0, &ak7755_sdoutad_selmix_control),
+ SND_SOC_DAPM_PGA("SELMIX Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+};
+
+static const struct snd_soc_dapm_route ak7755_intercon[] =
+{
+
+#ifdef DIGITAL_MIC
+ {"DMIC1 Left", "NULL", "CLOCK"},
+ {"DMIC1 Right", "NULL", "CLOCK"},
+ {"DMIC2 Left", "NULL", "CLOCK"},
+ {"DMIC2 Right", "NULL", "CLOCK"},
+
+ {"DMICIN1", "NULL", "DMIC1 CLK"},
+ {"DMICIN2", "NULL", "DMIC2 CLK"},
+ {"DMIC1 Left", "NULL", "DMICIN1"},
+ {"DMIC1 Right", "NULL", "DMICIN1"},
+ {"DMIC2 Left", "NULL", "DMICIN2"},
+ {"DMIC2 Right", "NULL", "DMICIN2"},
+ {"SDOUTAD", "NULL", "DMIC1 Left"},
+ {"SDOUTAD", "NULL", "DMIC1 Right"},
+ {"SDOUTAD2", "NULL", "DMIC2 Left"},
+ {"SDOUTAD2", "NULL", "DMIC2 Right"},
+#else
+ {"ADC Left", "NULL", "CLOCK"},
+ {"ADC Right", "NULL", "CLOCK"},
+ {"ADC2 Left", "NULL", "CLOCK"},
+
+ {"LineIn Amp", "NULL", "LIN"},
+ {"ADC2 Left", "NULL", "LineIn Amp"},
+ {"SDOUTAD2", "NULL", "ADC2 Left"},
+
+ {"LIN MUX", "IN1", "IN1"},
+ {"LIN MUX", "IN2", "IN2"},
+ {"LIN MUX", "INPN1", "INPN1"},
+ {"RIN MUX", "IN3", "IN3"},
+ {"RIN MUX", "IN4", "IN4"},
+ {"RIN MUX", "INPN2", "INPN2"},
+ {"ADC Left", "NULL", "LIN MUX"},
+ {"ADC Right", "NULL", "RIN MUX"},
+ {"SDOUTAD", "NULL", "ADC Left"},
+ {"SDOUTAD", "NULL", "ADC Right"},
+#endif
+
+ {"DAC Left", "NULL", "CLOCK"},
+ {"DAC Right", "NULL", "CLOCK"},
+ {"DSP", "NULL", "CLOCK"},
+
+ {"DSP", "NULL", "SDIN1"},
+ {"DSP", "NULL", "SDIN2"},
+
+ {"DSPIN SDOUTAD", "On", "SDOUTAD"},
+ {"DSPIN SDOUTAD2", "On", "SDOUTAD2"},
+ {"DSP", "NULL", "DSPIN SDOUTAD"},
+ {"DSP", "NULL", "DSPIN SDOUTAD2"},
+
+ {"SELMIX AD", "On", "SDOUTAD"},
+ {"SELMIX AD2", "On", "SDOUTAD2"},
+ {"SELMIX DSP", "On", "DSP"},
+ {"SELMIX Mixer", "NULL", "SELMIX AD"},
+ {"SELMIX Mixer", "NULL", "SELMIX AD2"},
+ {"SELMIX Mixer", "NULL", "SELMIX DSP"},
+ {"DAC MUX", "MIXOUT", "SELMIX Mixer"},
+ {"DAC MUX", "DSP", "DSP"},
+ {"DAC MUX", "SDIN2", "SDIN2"},
+ {"DAC MUX", "SDIN1", "SDIN1"},
+
+ {"DAC Left", "NULL", "DAC MUX"},
+ {"DAC Right", "NULL", "DAC MUX"},
+
+ {"LineOut Amp1", "On", "DAC Left"},
+ {"LineOut Amp2", "On", "DAC Right"},
+ {"Line Out1", "NULL", "LineOut Amp1"},
+ {"Line Out2", "NULL", "LineOut Amp2"},
+ {"LineOut Amp3 Mixer", "LOSW1", "DAC Left"},
+ {"LineOut Amp3 Mixer", "LOSW2", "DAC Right"},
+#ifndef DIGITAL_MIC //LOSW3 used only Analog MIC
+ {"LineOut Amp3 Mixer", "LOSW3", "LineIn Amp"},
+#endif
+ {"Line Out3", "NULL", "LineOut Amp3 Mixer"},
+
+ {"SDOUT1 MUX", "DSP", "DSP"},
+ {"SDOUT1 MUX", "DSP GP0", "DSP GP0"},
+ {"SDOUT1 MUX", "SDIN1", "SDIN1"},
+ {"SDOUT1 MUX", "SDOUTAD", "SDOUTAD"},
+ {"SDOUT1 MUX", "EEST", "EEST"},
+ {"SDOUT1 MUX", "SDOUTAD2", "SDOUTAD2"},
+
+ {"SDOUT2 MUX", "DSP", "DSP"},
+ {"SDOUT2 MUX", "DSP GP1", "DSP GP1"},
+ {"SDOUT2 MUX", "SDIN2", "SDIN2"},
+ {"SDOUT2 MUX", "SDOUTAD2", "SDOUTAD2"},
+
+ {"SDOUT3 MUX", "DSP DOUT3", "DSP"},
+ {"SDOUT3 MUX", "MIXOUT", "DAC MUX"},
+ {"SDOUT3 MUX", "DSP DOUT4", "DSP"},
+ {"SDOUT3 MUX", "SDOUTAD2", "SDOUTAD2"},
+
+ {"SDOUT1 Enable", "Switch", "SDOUT1 MUX"},
+ {"SDOUT2 Enable", "Switch", "SDOUT2 MUX"},
+ {"SDOUT3 Enable", "Switch", "SDOUT3 MUX"},
+
+ {"SDOUT1", "NULL", "SDOUT1 Enable"},
+ {"SDOUT2", "NULL", "SDOUT2 Enable"},
+ {"SDOUT3", "NULL", "SDOUT3 Enable"},
+
+};
+
+static int ak7755_hw_params_set(struct snd_soc_codec *codec, int nfs)
+{
+ u8 fs;
+
+ akdbgprt("\t[AK7755] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ fs = snd_soc_read(codec, AK7755_C0_CLOCK_SETTING1);
+ fs &= ~AK7755_FS;
+
+ switch (nfs) {
+ case 8000:
+ fs |= AK7755_FS_8KHZ;
+ break;
+ case 11025:
+ fs |= AK7755_FS_12KHZ;
+ break;
+ case 16000:
+ fs |= AK7755_FS_16KHZ;
+ break;
+ case 22050:
+ fs |= AK7755_FS_24KHZ;
+ break;
+ case 32000:
+ fs |= AK7755_FS_32KHZ;
+ break;
+ case 44100:
+ case 48000:
+ fs |= AK7755_FS_48KHZ;
+ break;
+ case 88200:
+ case 96000:
+ fs |= AK7755_FS_96KHZ;
+ break;
+ default:
+ return -EINVAL;
+ }
+ snd_soc_write(codec, AK7755_C0_CLOCK_SETTING1, fs);
+ ak7755_set_status(RUN);
+ if (aec == 1){
+ snd_soc_update_bits(codec, AK7755_CE_POWER_MANAGEMENT, 0x80, 0x0); //If aec is enable, only CH-L enable by DSP
+ }
+
+ return 0;
+}
+
+static int ak7755_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);
+ u8 format;
+
+ format = snd_soc_read(codec, AK7755_C2_SERIAL_DATA_FORMAT);
+ format &= ~AK7755_LRIF;
+ if (aec ==0){
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ ak7755->bickfs = (AK7755_AIF_BICK32 >> 4);
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ak7755->bickfs = (AK7755_AIF_BICK48 >> 4);
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ ak7755->bickfs = (AK7755_AIF_BICK64 >> 4);
+ break;
+ default:
+ dev_err(codec->dev, "Can not support the format");
+ return -EINVAL;
+ }
+ }else{
+ ak7755->bickfs = (AK7755_AIF_BICK64 >> 4);
+ }
+ ak7755->fs = params_rate(params);
+ ak7755_hw_params_set(codec, ak7755->fs);
+
+ snd_soc_update_bits(codec, AK7755_C1_CLOCK_SETTING2, 0x30, (ak7755->bickfs << 4));
+ if ( ak7755->bickfs < 3 ) {
+ format &= 0x7F;
+ } else {
+ format |= 0x80;
+ format &= 0xF3;
+ format |= AK7755_TDM_INPUT_SOURCE;
+ }
+
+ switch (ak7755->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ format |= AK7755_LRIF_I2S_MODE;
+ if ( ak7755->bickfs == 2 ) { // 32fs
+ snd_soc_update_bits(codec, AK7755_C3_DELAY_RAM_DSP_IO, 0xF0, 0xf0); // DIF2, DOF2
+ snd_soc_update_bits(codec, AK7755_C6_DAC_DEM_SETTING, 0x37, 0x33); //DIF, DIFDA
+ snd_soc_update_bits(codec, AK7755_C7_DSP_OUT_SETTING, 0xFF, 0xf3); //DOF
+ }else {
+ snd_soc_update_bits(codec, AK7755_C3_DELAY_RAM_DSP_IO, 0xF0, 0x0); // DIF2, DOF2
+ snd_soc_update_bits(codec, AK7755_C6_DAC_DEM_SETTING, 0x37, 0x0); //DIF, DIFDA
+ snd_soc_update_bits(codec, AK7755_C7_DSP_OUT_SETTING, 0xFF, 0x0); //DOF
+ }
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ format |= AK7755_LRIF_MSB_MODE;
+ if ( ak7755->bickfs == 2 ) { // 32fs
+ snd_soc_update_bits(codec, AK7755_C3_DELAY_RAM_DSP_IO, 0xF0, 0xF0); // DIF2, DOF2
+ snd_soc_update_bits(codec, AK7755_C6_DAC_DEM_SETTING, 0x37, 0x33); //DIF, DIFDA
+ snd_soc_update_bits(codec, AK7755_C7_DSP_OUT_SETTING, 0xFF, 0xF3); //DOF
+ }
+ else {
+ snd_soc_update_bits(codec, AK7755_C3_DELAY_RAM_DSP_IO, 0xF0, 0x0); // DIF2, DOF2
+ snd_soc_update_bits(codec, AK7755_C6_DAC_DEM_SETTING, 0x37, 0x0); //DIF, DIFDA
+ snd_soc_update_bits(codec, AK7755_C7_DSP_OUT_SETTING, 0xFF, 0x0); //DOF
+ }
+ break;
+/*
+ case SND_SOC_DAIFMT_PCM_SHORT:
+ format &= 0xBF; //BCKP Clear
+ format |= (AK7755_BCKP_BIT << 6); //BCKP set
+ format |= AK7755_LRIF_PCM_SHORT_MODE;
+ break;
+ case SND_SOC_DAIFMT_PCM_LONG:
+ format &= 0xBF; //BCKP lear
+ format |= (AK7755_BCKP_BIT << 6); //BCKP set
+ format |= AK7755_LRIF_PCM_LONG_MODE;
+ break;
+*/
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_write(codec, AK7755_C2_SERIAL_DATA_FORMAT, format);
+ return 0;
+}
+
+static int ak7755_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
+ unsigned int freq, int dir)
+{
+ akdbgprt("\t[AK7755] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ ak7755_data->rclk = freq;
+
+ return 0;
+}
+
+static int ak7755_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+
+ struct snd_soc_codec *codec = dai->codec;
+ struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec); // '15/06/15
+ u8 mode, mode2;
+
+ akdbgprt("\t[AK7755] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ /* set master/slave audio interface */
+ mode = snd_soc_read(codec, AK7755_C0_CLOCK_SETTING1);//CKM2-0(M/S)
+ mode &= ~AK7755_M_S;
+ mode2 = snd_soc_read(codec, AK7755_CA_CLK_SDOUT_SETTING);//BICKOE,LRCKOE
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ #ifdef CLOCK_MODE_BICK
+ mode |= AK7755_M_S_3;//CKM mode = 3(Slave, BICK)
+ #else
+ mode |= AK7755_M_S_2;//CKM mode = 2(Slave, XTI=12.288MHz)
+ #endif
+ mode2 &= ~AK7755_BICK_LRCK;//BICK = LRCK = 0
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+ #ifdef CLOCK_MODE_18_432
+ mode |= AK7755_M_S_1;//CKM mode = 1(Master, XTI=18.432MHz)
+ #else
+ mode |= AK7755_M_S_0;//CKM mode = 0(Master, XTI=12.288MHz)
+ #endif
+ mode2 |= AK7755_BICK_LRCK;//BICK = LRCK = 1
+ break;
+ case SND_SOC_DAIFMT_CBS_CFM:
+ case SND_SOC_DAIFMT_CBM_CFS:
+ default:
+ dev_err(codec->dev, "Clock mode unsupported");
+ return -EINVAL;
+ }
+
+ ak7755->fmt = fmt;
+ /* set mode */
+ snd_soc_write(codec, AK7755_C0_CLOCK_SETTING1, mode);
+ snd_soc_write(codec, AK7755_CA_CLK_SDOUT_SETTING, mode2);
+ return 0;
+}
+
+static int ak7755_volatile(struct snd_soc_codec *codec, unsigned int reg)
+{
+ int ret;
+
+ switch (reg) {
+// case :
+// ret = 1;
+ default:
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+
+static int ak7755_readable(struct snd_soc_codec *codec, unsigned int reg)
+{
+ return ak7755_access_masks[reg].readable != 0;
+
+}
+
+static int ak7755_reads(u8 *tx, size_t wlen, u8 *rx, size_t rlen)
+{
+ int ret;
+
+ //akdbgprt("*****[AK7755] %s tx[0]=%x, %d, %d\n",__FUNCTION__, tx[0],wlen,rlen);
+ if (ak7755_data->control_type == SND_SOC_SPI) {
+ ret = spi_write_then_read(ak7755_data->spi, tx, wlen, rx, rlen);
+ }
+ else {
+ ret = ak7755_i2c_read( tx, wlen, rx, rlen);
+ }
+
+ return ret;
+
+}
+
+static int ak7755_writes(const u8 *tx, size_t wlen)
+{
+ int rc;
+
+ akdbgprt("![AK7755W] %s tx[0]=%x tx[1]=%x, len=%d\n",__FUNCTION__, (int)tx[0], (int)tx[1], wlen);
+
+ if (ak7755_data->control_type == SND_SOC_SPI)
+ rc = spi_write_then_read(ak7755_data->spi, tx, wlen, NULL, 0);
+ else
+ rc = i2c_master_send(ak7755_data->i2c, tx, wlen);
+
+ if (rc < 0) {
+ akdbgprt("\t[AK7755] %s error rc = %d\n",__FUNCTION__, rc);
+ }
+
+ return rc;
+}
+
+#ifdef AK7755_CONTIF_DEBUG
+static inline void ak7755_write_reg_cache(struct snd_soc_codec *codec,u16 reg,u16 value)
+{
+ u8 *cache = codec->reg_cache;
+ //BUG_ON(reg_index > ARRAY_SIZE(ak7755_reg));
+
+ if (reg < ARRAY_SIZE(ak7755_reg))
+ cache[reg] = (u8)value;
+}
+
+/*
+* Read ak7755 register cache
+ */
+static inline u32 ak7755_read_reg_cache(struct snd_soc_codec *codec, u16 reg)
+{
+ u8 *cache = codec->reg_cache;
+ BUG_ON(reg > ARRAY_SIZE(ak7755_reg));
+ return (u32)cache[reg];
+}
+
+
+static unsigned int ak7755_i2c_read(
+u8 *reg,
+int reglen,
+u8 *data,
+int datalen)
+{
+ struct i2c_msg xfer[2];
+ int ret;
+ struct i2c_client *client = ak7755_data->i2c;
+
+ /* Write register */
+ xfer[0].addr = client->addr;
+ xfer[0].flags = 0;
+ xfer[0].len = reglen;
+ xfer[0].buf = reg;
+
+ /* Read data */
+ xfer[1].addr = client->addr;
+ xfer[1].flags = I2C_M_RD;
+ xfer[1].len = datalen;
+ xfer[1].buf = data;
+
+ ret = i2c_transfer(client->adapter, xfer, 2);
+
+// akdbgprt("*****[AK7755] %s (%x,%x)\n",__FUNCTION__, (int)reg[0], (int)data[0]);
+
+ if (ret == 2)
+ return 0;
+ else if (ret < 0)
+ return -ret;
+ else
+ return -EIO;
+}
+
+unsigned int ak7755_reg_read(struct snd_soc_codec *codec, unsigned int reg)
+{
+ unsigned char tx[1], rx[1];
+ int wlen, rlen;
+ int ret;
+ unsigned int rdata;
+
+ wlen = 1;
+ rlen = 1;
+ tx[0] = (unsigned char)(0x7F & reg);
+
+ //akdbgprt("*****[AK7755] %s reg = %0x, tx[0]=%0x, %d, %d\n",__FUNCTION__, reg, tx[0],wlen,rlen);
+
+ if (ak7755_data->control_type == SND_SOC_SPI) {
+ ret = spi_write_then_read(ak7755_data->spi, tx, wlen, rx, rlen);
+ }
+ else {
+ ret = ak7755_i2c_read(tx, wlen, rx, rlen);
+ }
+
+ if (ret < 0) {
+ akdbgprt("\t[AK7755] %s error ret = %d\n",__FUNCTION__, ret);
+ rdata = -EIO;
+ return rdata;
+ }
+ else {
+ rdata = (unsigned int)rx[0];
+ if (ak7755_read_reg_cache(codec, reg) != rdata)
+ ak7755_write_reg_cache(codec, reg, rdata);
+ }
+ akdbgprt("\t[AK7755] %s addr, read data =(%x, %x)\n",__FUNCTION__, reg, (int)rdata);
+
+ return rdata;
+}
+
+
+int ak7755_reg_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value)
+{
+ unsigned char tx[3];
+ int wlen;
+ int ret;
+
+ wlen = 2;
+ tx[0] = reg;
+ tx[1] = value;
+
+ ret = ak7755_writes(tx, wlen);
+
+ if (ret >=0) {
+ ak7755_write_reg_cache(codec, reg, value);
+ }
+
+ return ret;
+}
+
+
+/*
+ * Write with Mask to AK7755 register space
+ */
+// ak7755_writeMask() => snd_soc_update_bits() // '16/01/13
+
+#endif
+
+
+static int crc_read(void)
+{
+ int rc;
+ u8 tx[1], rx[2];
+
+ tx[0] = CRC_COMMAND_READ_RESULT;
+
+ rc = ak7755_reads(tx, 1, rx, 2);
+
+ return (rc < 0) ? rc : ((rx[0] << 8) + rx[1]);
+}
+
+static int ak7755_set_status(enum ak7755_status status)
+{
+
+ switch (status) {
+ case RUN:
+ snd_soc_update_bits(ak7755_data->codec, AK7755_C1_CLOCK_SETTING2, 0x1, 0x1); // CKRESETN bit = 1
+ mdelay(10);
+ snd_soc_update_bits(ak7755_data->codec, AK7755_CF_RESET_POWER_SETTING, 0xd, 0xc); // CRESETN bit = DSPRESETN = 1;
+ mdelay(10);
+ break;
+ case DOWNLOAD:
+ snd_soc_update_bits(ak7755_data->codec, AK7755_CF_RESET_POWER_SETTING, 0x1, 0x1); // DLRDY bit = 1
+ mdelay(10);
+ break;
+ case STANDBY:
+ snd_soc_update_bits(ak7755_data->codec, AK7755_C1_CLOCK_SETTING2, 0x1, 0x1); // CKRESETN bit = 1
+ mdelay(10);
+ snd_soc_update_bits(ak7755_data->codec, AK7755_CF_RESET_POWER_SETTING, 0xc, 0x0); // CRESETN bit = DSPRESETN = 0;
+ mdelay(10);
+ break;
+ case SUSPEND:
+ case POWERDOWN:
+ snd_soc_update_bits(ak7755_data->codec, AK7755_CF_RESET_POWER_SETTING, 0x3f, 0x0);
+ snd_soc_update_bits(ak7755_data->codec, AK7755_CE_POWER_MANAGEMENT, 0xFF, 0x0);
+ snd_soc_update_bits(ak7755_data->codec, AK7755_C1_CLOCK_SETTING2, 0x0, 0x0);
+ mdelay(10);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ak7755_data->status = status;
+
+ return 0;
+}
+
+static int ak7755_ram_download(const u8 *tx_ram, u64 num, u16 crc)
+{
+ int rc;
+ u16 read_crc;
+ u8 tx[2];
+
+ akdbgprt("\t[AK7755] %s num=%ld\n",__FUNCTION__, (long int)num);
+ if (fast_boot == 0)
+ ak7755_set_status(DOWNLOAD);
+
+ rc = ak7755_writes(tx_ram, num);
+ if (rc < 0) {
+ printk("%s: RAM Write Error! RAM size = %lld \n", __func__, num);
+ if ( fast_boot == 1 ) {
+ tx[0] = AK7755_CF_RESET_POWER_SETTING;
+ tx[1] = 0x0c;
+ ak7755_writes(tx, 2);
+ } else {
+ snd_soc_update_bits(ak7755_data->codec, AK7755_CF_RESET_POWER_SETTING, 0x0d,0x0c); // system rest release
+ }
+ return rc;
+ }
+
+ if ( ( crc != 0 ) && (rc >= 0) ) {
+ read_crc = crc_read();
+ akdbgprt("\t[AK7755] %s CRC Cal=%x Read=%x\n",__FUNCTION__, (int)crc,(int)read_crc);
+
+ if ( read_crc == crc ) rc = 0;
+ else rc = 1;
+ }
+ if ( fast_boot == 0 )
+ ak7755_set_status(STANDBY);
+
+ return rc;
+
+}
+
+static int calc_CRC(int length, u8 *data )
+{
+
+#define CRC16_CCITT (0x1021)
+
+ unsigned short crc = 0x0000;
+ int i, j;
+
+ for ( i = 0; i < length; i++ ) {
+ crc ^= *data++ << 8;
+ for ( j = 0; j < 8; j++) {
+ if ( crc & 0x8000) {
+ crc <<= 1;
+ crc ^= CRC16_CCITT;
+ }
+ else {
+ crc <<= 1;
+ }
+ }
+ }
+
+ akdbgprt("[AK7755] %s CRC=%x\n",__FUNCTION__, crc);
+
+ return crc;
+}
+
+static int ak7755_write_ram(
+int nPCRam, // 0 : PRAM, 1 : CRAM, 2: OFREG. 3: ACRAM
+u8 *upRam,
+int nWSize)
+{
+ int n, ret;
+ int wCRC;
+
+ switch(nPCRam) {
+ case RAMTYPE_PRAM:
+ if ( nWSize > TOTAL_NUM_OF_PRAM_MAX ) {
+ printk("%s: PRAM Write size is over! \n", __func__);
+ return(-1);
+ }
+ break;
+ case RAMTYPE_CRAM:
+ if ( nWSize > TOTAL_NUM_OF_CRAM_MAX ) {
+ printk("%s: CRAM Write size is over! \n", __func__);
+ return(-1);
+ }
+ break;
+ case RAMTYPE_OFREG:
+ if ( nWSize > TOTAL_NUM_OF_OFREG_MAX ) {
+ printk("%s: OFREG Write size is over! \n", __func__);
+ return(-1);
+ }
+ break;
+ case RAMTYPE_ACRAM:
+ if ( nWSize > TOTAL_NUM_OF_ACRAM_MAX ) {
+ printk("%s: ACRAM Write size is over! \n", __func__);
+ return(-1);
+ }
+ break;
+ default:
+ break;
+ }
+
+ wCRC = calc_CRC(nWSize, upRam);
+
+ n = MAX_LOOP_TIMES;
+ do {
+ ret = ak7755_ram_download(upRam, nWSize, wCRC);
+ if ( ret >= 0 ) break;
+ printk("%s: RAM Write Error! RAM No = %d \n", __func__, nPCRam);
+ n--;
+ } while ( n > 0 );
+
+ if ( ret < 0 ) {
+ printk("%s: RAM Write Error! RAM No = %d \n", __func__, nPCRam);
+ return(-1);
+ }
+
+ return(0);
+
+}
+
+static int ak7755_firmware_write_ram(u16 mode, u16 cmd)
+{
+ int ret = 0;
+ int nNumMode, nMaxLen;
+ int nRamSize;
+ u8 *ram_basic;
+ const struct firmware *fw;
+ u8 *fwdn;
+ char szFileName[32];
+
+ akdbgprt("[AK7755] %s mode=%d, cmd=%d\n",__FUNCTION__, mode, cmd);
+
+ switch(mode) {
+ case RAMTYPE_PRAM:
+ nNumMode = sizeof(ak7755_firmware_pram) / sizeof(ak7755_firmware_pram[0]);
+ break;
+ case RAMTYPE_CRAM:
+ nNumMode = sizeof(ak7755_firmware_cram) / sizeof(ak7755_firmware_cram[0]);
+ break;
+ case RAMTYPE_OFREG:
+ nNumMode = sizeof(ak7755_firmware_ofreg) / sizeof(ak7755_firmware_ofreg[0]);
+ break;
+ case RAMTYPE_ACRAM:
+ nNumMode = sizeof(ak7755_firmware_acram) / sizeof(ak7755_firmware_acram[0]);
+ break;
+ default:
+ akdbgprt("[AK7755] %s mode Error=%d\n",__FUNCTION__, mode);
+ return( -EINVAL);
+ }
+
+ if ( cmd == 0 ) return(0);
+
+ if ( cmd >= nNumMode ) {
+ pr_err("%s: invalid command %d\n", __func__, cmd);
+ return( -EINVAL);
+ }
+
+ if ( cmd == 1 ) {
+ switch(mode) {
+ case RAMTYPE_PRAM:
+ if (aec == 0){
+ ram_basic = ak7755_pram_basic;
+ nRamSize = sizeof(ak7755_pram_basic);
+ }else{
+ ram_basic = ak7755_pram_aec;
+ nRamSize = sizeof(ak7755_pram_aec);
+ }
+ break;
+ case RAMTYPE_CRAM:
+ if (aec == 0){
+ ram_basic = ak7755_cram_basic;
+ nRamSize = sizeof(ak7755_cram_basic);
+ }else{
+ ram_basic = ak7755_cram_aec;
+ nRamSize = sizeof(ak7755_cram_aec);
+ }
+ break;
+ case RAMTYPE_OFREG:
+ ram_basic = ak7755_ofreg_basic;
+ nRamSize = sizeof(ak7755_ofreg_basic);
+ break;
+ case RAMTYPE_ACRAM:
+ ram_basic = ak7755_acram_basic;
+ nRamSize = sizeof(ak7755_acram_basic);
+ break;
+ default:
+ return( -EINVAL);
+ }
+ ret = ak7755_write_ram((int)mode, ram_basic, nRamSize);
+ } else {
+ switch(mode) {
+ case RAMTYPE_PRAM:
+ sprintf(szFileName, "ak7755_pram_%s.bin", ak7755_firmware_pram[cmd]);
+ nMaxLen = TOTAL_NUM_OF_PRAM_MAX;
+ break;
+ case RAMTYPE_CRAM:
+ sprintf(szFileName, "ak7755_cram_%s.bin", ak7755_firmware_cram[cmd]);
+ nMaxLen = TOTAL_NUM_OF_CRAM_MAX;
+ break;
+ case RAMTYPE_OFREG:
+ sprintf(szFileName, "ak7755_ofreg_%s.bin", ak7755_firmware_cram[cmd]);
+ nMaxLen = TOTAL_NUM_OF_OFREG_MAX;
+ break;
+ case RAMTYPE_ACRAM:
+ sprintf(szFileName, "ak7755_acram_%s.bin", ak7755_firmware_cram[cmd]);
+ nMaxLen = TOTAL_NUM_OF_ACRAM_MAX;
+ break;
+ default:
+ return( -EINVAL);
+ }
+
+ if (ak7755_data->control_type == SND_SOC_SPI) {
+ ret = request_firmware(&fw, szFileName, &(ak7755_data->spi->dev));
+ }
+ else {
+ ret = request_firmware(&fw, szFileName, &(ak7755_data->i2c->dev));
+ }
+ if (ret) {
+ akdbgprt("[AK7755] %s could not load firmware=%d\n", szFileName, ret);
+ return -EINVAL;
+ }
+
+ //printk("[AK7755] %s name=%s size=%d\n",__FUNCTION__, szFileName, fw->size);
+ if ( fw->size > nMaxLen ) {
+ akdbgprt("[AK7755] %s RAM Size Error : %d\n",__FUNCTION__, fw->size);
+ return -ENOMEM;
+ }
+
+ fwdn = kmalloc((unsigned long)fw->size, GFP_KERNEL);
+ if (fwdn == NULL) {
+ printk(KERN_ERR "failed to buffer vmalloc: %d\n", fw->size);
+ return -ENOMEM;
+ }
+
+ memcpy((void *)fwdn, fw->data, fw->size);
+
+ ret = ak7755_write_ram((int)mode, (u8 *)fwdn, (fw->size));
+ //printk("ak7755 download ram is ok, ret = %d\n", ret);
+
+ kfree(fwdn);
+ }
+
+
+ return ret;
+}
+
+static int ak7755_write_cram(
+int addr,
+int len,
+unsigned char *cram_data)
+{
+ int i, n, ret;
+ int nDSPRun;
+ unsigned char tx[51];
+
+ akdbgprt("[AK7755] %s addr=%d, len=%d\n",__FUNCTION__, addr, len);
+
+ if ( len > 48 ) {
+ akdbgprt("[AK7755] %s Length over!\n",__FUNCTION__);
+ return(-1);
+ }
+
+ nDSPRun = snd_soc_read(ak7755_data->codec, AK7755_CF_RESET_POWER_SETTING);
+
+ if ( nDSPRun & 0x4 ) {
+ tx[0] = 0x80 + (unsigned char)((len / 3) - 1);
+ tx[1] = (unsigned char)(0xFF & (addr >> 8));
+ tx[2] = (unsigned char)(0xFF & addr);
+ }
+ else {
+ ak7755_set_status(DOWNLOAD);
+ tx[0] = 0xB4;
+ tx[1] = (unsigned char)(0xFF & (addr >> 8));
+ tx[2] = (unsigned char)(0xFF & addr);
+ }
+
+ n = 3;
+ for ( i = 0 ; i < len; i ++ ) {
+ tx[n++] = cram_data[i];
+ }
+
+ ret = ak7755_writes(tx, n);
+
+ if ( nDSPRun & 0x4 ) {
+ tx[0] = 0xA4;
+ tx[1] = 0;
+ tx[2] = 0;
+ ret = ak7755_writes(tx, 3);
+ }
+ else {
+ snd_soc_write(ak7755_data->codec, AK7755_CF_RESET_POWER_SETTING, nDSPRun);
+ }
+
+
+ return ret;
+
+}
+
+static unsigned long ak7755_readMIR(
+int nMIRNo)
+{
+ unsigned char tx[1];
+ unsigned char rx[4];
+ unsigned long dwMIRData;
+
+ if ( ( nMIRNo < 1 ) || ( nMIRNo > 4 ) ) return(-1);
+
+ tx[0] = (unsigned char)(0x74 + (2 * nMIRNo));
+
+ ak7755_reads(tx, 1, rx, 4);
+
+ dwMIRData = ((0xFF & (unsigned long)rx[0]) << 20) + ((0xFF & (unsigned long)rx[1]) << 12) +
+ ((0xFF & (unsigned long)rx[2]) << 4) + ((0xFF & (unsigned long)rx[3]) >> 4);
+
+
+ return(dwMIRData);
+
+}
+
+static int ak7755_reg_cmd(REG_CMD *reg_param, int len)
+{
+ int i;
+ int rc;
+ int addr, value;
+
+ akdbgprt("*****[AK7755] %s len = %d\n",__FUNCTION__, len);
+
+ rc = 0;
+ for (i = 0; i < len; i++) {
+ addr = (int)(reg_param[i].addr);
+ value = (int)(reg_param[i].data);
+
+ if ( addr != 0xFF ) {
+ rc = snd_soc_write(ak7755_data->codec, addr, value);
+ if (rc < 0) {
+ break;
+ }
+ }
+ else {
+ mdelay(value);
+ }
+ }
+
+ if (rc != 0 ) rc = 0;
+
+ return(rc);
+
+}
+
+#ifdef AK7755_IO_CONTROL
+static long ak7755_ioctl(struct file *file, unsigned int cmd, unsigned long args)
+{
+ struct ak7755_priv *ak7755 = (struct ak7755_priv*)file->private_data;
+ struct ak7755_wreg_handle ak7755_wreg;
+ struct ak7755_wcram_handle ak7755_wcram;
+ struct ak7755_loadram_handle ak7755_ram;
+ void __user *data = (void __user *)args;
+ int *val = (int *)args;
+ int i;
+ unsigned long dwMIRData;
+ int ret = 0;
+ REG_CMD regcmd[MAX_WREG];
+ unsigned char cram_data[MAX_WCRAM];
+
+ akdbgprt("*****[AK7755] %s cmd, val=%x, %x\n",__FUNCTION__, cmd, val[0]);
+
+ switch(cmd) {
+ case AK7755_IOCTL_WRITECRAM:
+ if (copy_from_user(&ak7755_wcram, data, sizeof(struct ak7755_wcram_handle)))
+ return -EFAULT;
+ if ( ( ak7755_wcram.len % 3 ) != 0 ) {
+ printk(KERN_ERR "[AK7755] %s CRAM len error\n",__FUNCTION__);
+ return -EFAULT;
+ }
+ if ( ( ak7755_wcram.len < 3 ) || ( ak7755_wcram.len > MAX_WCRAM ) ) {
+ printk(KERN_ERR "[AK7755] %s CRAM len error2\n",__FUNCTION__);
+ return -EFAULT;
+ }
+ for ( i = 0 ; i < ak7755_wcram.len ; i ++ ) {
+ cram_data[i] = ak7755_wcram.cram[i];
+ }
+ ret = ak7755_write_cram(ak7755_wcram.addr, ak7755_wcram.len, cram_data);
+ break;
+ case AK7755_IOCTL_WRITEREG:
+ if (copy_from_user(&ak7755_wreg, data, sizeof(struct ak7755_wreg_handle)))
+ return -EFAULT;
+ if ( ( ak7755_wreg.len < 1 ) || ( ak7755_wreg.len > MAX_WREG ) ) {
+ printk(KERN_ERR "MAXREG ERROR %d\n", ak7755_wreg.len );
+ return -EFAULT;
+ }
+ for ( i = 0 ; i < ak7755_wreg.len; i ++ ) {
+ regcmd[i].addr = ak7755_wreg.regcmd[i].addr;
+ regcmd[i].data = ak7755_wreg.regcmd[i].data;
+ }
+ ak7755_reg_cmd(regcmd, ak7755_wreg.len);
+ break;
+ case AK7755_IOCTL_LOADRAM:
+ if (copy_from_user(&ak7755_ram, data, sizeof(struct ak7755_loadram_handle)))
+ return -EFAULT;
+ ak7755_firmware_write_ram(ak7755_ram.ramtype, ak7755_ram.mode);
+ break;
+ case AK7755_IOCTL_SETSTATUS:
+ ret = ak7755_set_status(val[0]);
+ if (ret < 0) {
+ printk(KERN_ERR "ak7755: set_status error: \n");
+ return ret;
+ }
+ break;
+ case AK7755_IOCTL_GETSTATUS:
+ ret = copy_to_user(data, (const void*)&ak7755->status,
+ (unsigned long)sizeof(unsigned int));
+ if (ret < 0) {
+ printk(KERN_ERR "ak7755: get status error\n");
+ return -EFAULT;
+ }
+ break;
+ case AK7755_IOCTL_SETMIR:
+ ak7755->MIRNo = val[0];
+ if (ret < 0) {
+ printk(KERN_ERR "ak7755: set MIR error\n");
+ return -EFAULT;
+ }
+ break;
+ case AK7755_IOCTL_GETMIR:
+ dwMIRData = ak7755_readMIR(ak7755->MIRNo);
+ ret = copy_to_user(data, (const void*)&dwMIRData,
+ (unsigned long)sizeof(unsigned int));
+ if (ret < 0) {
+ printk(KERN_ERR "ak7755: get status error\n");
+ return -EFAULT;
+ }
+ break;
+
+ default:
+ printk(KERN_ERR "Unknown command required: %d\n", cmd);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static int init_ak7755_pd(struct ak7755_priv *data)
+{
+ struct _ak7755_pd_handler *ak7755 = &ak7755_pd_handler;
+
+ if (data == NULL)
+ return -EFAULT;
+
+ mutex_init(&ak7755->lock);
+
+ mutex_lock(&ak7755->lock);
+ ak7755->data = data;
+ mutex_unlock(&ak7755->lock);
+
+ printk("data:%p, ak7755->data:%p\n", data, ak7755->data);
+
+ return 0;
+}
+
+static struct ak7755_priv* get_ak7755_pd(void)
+{
+ struct _ak7755_pd_handler *ak7755 = &ak7755_pd_handler;
+
+ if (ak7755->data == NULL)
+ return NULL;
+
+ mutex_lock(&ak7755->lock);
+ ak7755->ref_count++;
+ mutex_unlock(&ak7755->lock);
+
+ return ak7755->data;
+}
+
+static int rel_ak7755_pd(struct ak7755_priv *data)
+{
+ struct _ak7755_pd_handler *ak7755 = &ak7755_pd_handler;
+
+ if (ak7755->data == NULL)
+ return -EFAULT;
+
+ mutex_lock(&ak7755->lock);
+ ak7755->ref_count--;
+ mutex_unlock(&ak7755->lock);
+
+ data = NULL;
+
+ return 0;
+}
+
+/* AK7755 Misc driver interfaces */
+static int ak7755_open(struct inode *inode, struct file *file)
+{
+ struct ak7755_priv *ak7755;
+
+ ak7755 = get_ak7755_pd();
+ file->private_data = ak7755;
+
+ return 0;
+}
+
+static int ak7755_close(struct inode *inode, struct file *file)
+{
+ struct ak7755_priv *ak7755 = (struct ak7755_priv*)file->private_data;
+
+ rel_ak7755_pd(ak7755);
+
+ return 0;
+}
+
+static const struct file_operations ak7755_fops = {
+ .owner = THIS_MODULE,
+ .open = ak7755_open,
+ .release = ak7755_close,
+ .unlocked_ioctl = ak7755_ioctl,
+};
+
+static struct miscdevice ak7755_misc = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "ak7755-dsp",
+ .fops = &ak7755_fops,
+};
+
+#endif
+
+/*********************************/
+
+// * for AK7755
+static int ak7755_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *codec_dai)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
+
+ if(ak7755->amp_gpio > 0) {
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ gpio_direction_output(ak7755->amp_gpio, ak7755->amp_active);
+ }
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
+ gpio_direction_output(ak7755->amp_gpio, !ak7755->amp_active);
+ }
+ break;
+ default:
+ break;
+ }
+
+ }
+
+ akdbgprt("\t[AK7755] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ return ret;
+}
+
+static int ak7755_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ akdbgprt("\t[AK7755] %s(%d) level : %d\n",__FUNCTION__,__LINE__, level);
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ case SND_SOC_BIAS_PREPARE:
+ ak7755_set_status(RUN);
+ break;
+ case SND_SOC_BIAS_STANDBY:
+ ak7755_set_status(STANDBY);
+ break;
+ case SND_SOC_BIAS_OFF:
+ ak7755_set_status(POWERDOWN);
+ break;
+ }
+ codec->dapm.bias_level = level;
+
+ return 0;
+}
+
+static int ak7755_set_dai_mute2(struct snd_soc_codec *codec, int mute)
+{
+ int ret = 0;
+ //int ndt;
+
+ //akdbgprt("\t[AK7755] %s mute[%s]\n",__FUNCTION__, mute ? "ON":"OFF");
+
+#if 0
+ if (mute) { //SMUTE: 1 , MUTE
+ ret = snd_soc_update_bits(codec, AK7755_DA_MUTE_ADRC_ZEROCROSS_SET, 0xE0, 0xE0);
+ }
+ else {
+ ak7755_set_status(RUN);
+ // SMUTE: 0 ,NORMAL operation
+ ret = snd_soc_update_bits(codec, AK7755_DA_MUTE_ADRC_ZEROCROSS_SET, 0xE0, 0x00);
+ }
+
+ ndt = 1021000 / ak7755_data->fs;
+ mdelay(ndt);
+#endif
+ return ret;
+}
+
+static int ak7755_set_dai_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec = dai->codec;
+
+ ak7755_set_dai_mute2(codec, mute);
+
+ return 0;
+}
+
+#define AK7755_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
+ SNDRV_PCM_RATE_96000)
+
+#define AK7755_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_ops ak7755_dai_ops = {
+ .hw_params = ak7755_hw_params,
+ .set_sysclk = ak7755_set_dai_sysclk,
+ .set_fmt = ak7755_set_dai_fmt,
+ .trigger = ak7755_trigger,
+ .digital_mute = ak7755_set_dai_mute,
+};
+
+struct snd_soc_dai_driver ak7755_dai[] = {
+ {
+ .name = "ak7755-AIF1",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = AK7755_RATES,
+ .formats = AK7755_FORMATS,
+ },
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 4,
+ .rates = AK7755_RATES,
+ .formats = AK7755_FORMATS,
+ },
+ .ops = &ak7755_dai_ops,
+ },
+};
+
+static int ak7755_init_reg(struct snd_soc_codec *codec)
+{
+ struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec); // '15/06/15
+
+ akdbgprt("\t[AK7755 bias] %s(%d)\n",__FUNCTION__,__LINE__);
+
+
+ if ( ak7755->power_gpio > 0 ) {
+ gpio_direction_output(ak7755->power_gpio, ak7755->power_active);
+ }
+
+ if ( ak7755->pdn_gpio > 0 ) {
+ gpio_direction_output(ak7755->pdn_gpio, ak7755->pdn_active);
+ msleep(10);
+ gpio_direction_output(ak7755->pdn_gpio, !ak7755->pdn_active);
+ }
+
+
+ ak7755_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ snd_soc_update_bits(codec, AK7755_D4_LO1_LO2_VOLUME_SETTING, 0xFF, 0xFF); //LOVOL1,2=F(0dB)
+ snd_soc_update_bits(codec, AK7755_D3_LIN_LO3_VOLUME_SETTING, 0x0F, 0x0F); //LOVOL3=F(0dB)
+ snd_soc_update_bits(codec, AK7755_D2_MIC_GAIN_SETTING, 0xFF, 0xCC);
+ snd_soc_update_bits(codec, AK7755_D0_FUNCTION_SETTING, 0x40, 0x40); //CRCE=1(CRC Enable)
+ snd_soc_update_bits(codec, AK7755_C2_SERIAL_DATA_FORMAT, 0x40, AK7755_BCKP_BIT); //BCKP bit
+ snd_soc_update_bits(codec, AK7755_D0_FUNCTION_SETTING, 0x10, AK7755_SOCFG_BIT); //SOFG bit
+#ifdef DIGITAL_MIC //Analog MIC Use
+ snd_soc_update_bits(codec, AK7755_DE_DMIC_IF_SETTING, 0x90, 0x90); //DMIC1=DMIC2=1(Digital MIC Use)
+ snd_soc_update_bits(codec, AK7755_DE_DMIC_IF_SETTING, 0x40, AK7755_DMCLKP1_BIT); //DMCLKP1 bit
+ snd_soc_update_bits(codec, AK7755_DE_DMIC_IF_SETTING, 0x08, AK7755_DMCLKP2_BIT); //DMCLKP2 bit
+ snd_soc_update_bits(codec, AK7755_C0_CLOCK_SETTING1, 0x08, 0x00);
+#else
+ snd_soc_update_bits(codec, AK7755_C0_CLOCK_SETTING1, 0x08, 0x08); //AINE=1(Analog MIC Use)
+#endif
+ snd_soc_write(codec, 0xCA, 0x01);
+ snd_soc_write(codec, 0xDA, 0x10);
+ snd_soc_write(codec, 0xCD, 0xC0);
+ snd_soc_write(codec, 0xE6, 0x01);
+ snd_soc_write(codec, 0xEA, 0x80);
+
+ if(aec == 1) {
+ /*Select DAC MUX as DSP DOUT4*/
+ snd_soc_update_bits(codec, AK7755_C8_DAC_IN_SETTING, 0xC0, 0x00);
+ /*Lineout1 power on*/
+ snd_soc_update_bits(codec, AK7755_CE_POWER_MANAGEMENT, 0xC7, 0xC7);
+
+ /*Select SDOUT1 MUX as DOUT1 Of DSP*/
+ snd_soc_update_bits(codec, AK7755_CC_VOLUME_TRANSITION, 0x07, 0x00);
+ } else {
+ /*Select DAC MUX as SDIN1*/
+ snd_soc_update_bits(codec, AK7755_C8_DAC_IN_SETTING, 0xC0, 0xC0);
+ /*Lineout1 power on*/
+ snd_soc_update_bits(codec, AK7755_CE_POWER_MANAGEMENT, 0xC7, 0xC7);
+
+ /*Select SDOUT1 MUX as SDOUTAD*/
+ snd_soc_update_bits(codec, AK7755_CC_VOLUME_TRANSITION, 0x07, 0x03);
+ }
+
+ return 0;
+}
+
+static int ak7755_parse_dt(struct ak7755_priv *ak7755)
+{
+ struct device *dev;
+ struct device_node *np;
+ enum of_gpio_flags flags;
+ int ret = 0;
+
+ if (ak7755->control_type == SND_SOC_SPI) {
+ dev = &(ak7755->spi->dev);
+ }
+ else {
+ dev = &(ak7755->i2c->dev);
+ }
+
+ np = dev->of_node;
+
+ if (!np)
+ return -1;
+
+ ak7755->pdn_gpio = of_get_named_gpio_flags(np, "ak7755,pdn-gpio", 0, &flags);
+ ak7755->pdn_active = !!(flags & OF_GPIO_ACTIVE_LOW);
+ if(ak7755->pdn_gpio < 0 || !gpio_is_valid(ak7755->pdn_gpio)) {
+ dev_err(dev, "ak7755 pdn pin(%u) is invalid\n", ret);
+ ak7755->pdn_gpio = -1;
+ return ret;
+ }
+ ret = devm_gpio_request(dev, ak7755->pdn_gpio, "ak7755 pdn_gpio");
+ if ( ret < 0 )
+ dev_err(dev, "Failed to request pdn_pin: %d\n", ret);
+
+
+ ak7755->power_gpio = of_get_named_gpio_flags(np, "ak7755,pwr-gpio", 0, &flags);
+ ak7755->power_active = !!(flags & OF_GPIO_ACTIVE_LOW);
+ if (ak7755->power_gpio < 0 || !gpio_is_valid(ak7755->power_gpio)) {
+ ak7755->power_gpio = -1;
+ dev_err(dev, "ak7755 power pin(%u) is invalid\n", ret);
+ return ret;
+ }
+ ret = devm_gpio_request(dev, ak7755->power_gpio, "ak7755 power_gpio");
+ if ( ret < 0 )
+ dev_err(dev, "Failed to request power_pin: %d\n", ret);
+
+
+ ak7755->amp_gpio = of_get_named_gpio_flags(np, "ak7755,amp-gpio", 0, &flags);
+ ak7755->amp_active = !!(flags & OF_GPIO_ACTIVE_LOW);
+ if (ak7755->amp_gpio < 0 || !gpio_is_valid(ak7755->amp_gpio)) {
+ ak7755->amp_gpio = -1;
+ dev_err(dev, "ak7755 amplifier pin(%u) is invalid\n", ret);
+ return ret;
+ }
+ ret = devm_gpio_request(dev, ak7755->amp_gpio, "ak7755 amp_gpio");
+ if ( ret < 0 )
+ dev_err(dev, "Failed to request amp_pin: %d\n", ret);
+
+ return 0;
+}
+
+static int ak7755_set_reg_table(void)
+{
+ int i;
+ int n;
+
+ n = 0;
+ do {
+ ak7755_reg[n] = 0;
+ ak7755_access_masks[n].readable = 0;
+ ak7755_access_masks[n].writable = 0;
+ n ++;
+ } while ( n < AK7755_C0_CLOCK_SETTING1 );
+
+ i = 0;
+ do {
+ ak7755_reg[n] = ak7755_reg2[i] ;
+ ak7755_access_masks[n].readable = ak7755_access_masks2[i].readable;
+ ak7755_access_masks[n].writable = ak7755_access_masks2[i].writable;
+ i++;
+ n++;
+ } while ( n < AK7755_MAX_REGISTERS);
+
+ return(0);
+
+}
+
+static int ak7755_probe(struct snd_soc_codec *codec)
+{
+ struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
+ int i;
+
+ akdbgprt("\t[AK7755] %s(%d)\n",__FUNCTION__,__LINE__);
+ ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak7755->control_type);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
+ }
+
+#ifdef AK7755_CONTIF_DEBUG
+ codec->read = ak7755_reg_read;
+ codec->write = ak7755_reg_write;
+
+#endif
+
+ akdbgprt("\t[AK7755] %s(%d) ak7755=%x\n",__FUNCTION__,__LINE__, (int)ak7755);
+ ak7755->codec = codec;
+ ret = ak7755_parse_dt(ak7755);
+ if ( ret != 0 ) {
+ dev_err(codec->dev, "Failed to parse devict tree: %d\n", ret);
+ return ret;
+ }
+
+ ak7755_set_reg_table();
+ ak7755_init_reg(codec);
+ akdbgprt("\t[AK7755 Effect] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ ak7755->fs = 48000;
+ ak7755->rclk = 0;
+ ak7755->lign = 7; //lign:7 = LIGN:0(0dB)
+ ak7755->selmix = 0; //SDOUTAD(L,R)
+ ak7755->MIRNo = 1;
+ ak7755->status = POWERDOWN;
+
+
+ ak7755->DSPPramMode = 0;
+ ak7755->DSPCramMode = 0;
+ ak7755->DSPOfregMode = 0;
+ ak7755->DSPAcramMode = 0;
+
+ for ( i = 0 ; i < 5 ; i ++ ) ak7755->EQLevel[i] = 24;
+ ak7755->HPFfc[0] = 0;
+ ak7755->HPFfc[1] = 0;
+ ak7755->LimRel = 2;
+ ak7755->LimVol = 0;
+
+ ak7755->bickfs = (AK7755_AUDIO_IF_MODE >> 4);
+
+ akdbgprt("\t[AK7755 init_ak7755_pd] %s(%d)\n",__FUNCTION__,__LINE__);
+
+#ifdef AK7755_IO_CONTROL
+ init_ak7755_pd(ak7755);
+#endif
+ return ret;
+}
+
+static int ak7755_remove(struct snd_soc_codec *codec)
+{
+ struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);
+
+ akdbgprt("\t[AK7755] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ ak7755_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+ if ( ak7755->pdn_gpio > 0 ) {
+ gpio_direction_output(ak7755->pdn_gpio, ak7755->pdn_active);
+ gpio_free(ak7755->pdn_gpio);
+ }
+
+ return 0;
+}
+
+static int ak7755_suspend(struct snd_soc_codec *codec)
+{
+ struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);
+ int i = 0;
+
+ for(i = 0; i < AK7755_MAX_REGNUM; i++) {
+ ak7755_data->reg_cache[i] = snd_soc_read(codec, i + 0xc0);
+ }
+ ak7755_data->reg_cache[1] &= 0xfe; //Make sure CKRESETN bit is reset
+
+ ak7755_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ if ( ak7755->amp_active > 0 ) {
+ gpio_direction_output(ak7755->amp_gpio, !ak7755->amp_active);
+ }
+ if ( ak7755->pdn_gpio > 0 ) {
+ gpio_direction_output(ak7755->pdn_gpio, ak7755->pdn_active);
+ }
+ if ( ak7755->power_gpio > 0 ) {
+ gpio_direction_output(ak7755->power_gpio, !ak7755->power_active);
+ }
+
+ return 0;
+}
+
+static int ak7755_resume(struct snd_soc_codec *codec)
+{
+ struct ak7755_priv *ak7755 = snd_soc_codec_get_drvdata(codec);
+ int i = 0;
+
+ if ( ak7755->pdn_gpio > 0 ) {
+ gpio_direction_output(ak7755->pdn_gpio, ak7755->pdn_active);
+ }
+
+ if ( ak7755->power_gpio > 0 ) {
+ gpio_direction_output(ak7755->power_gpio, ak7755->power_active);
+ mdelay(10);
+ }
+
+ if ( ak7755->pdn_gpio > 0 ) {
+ gpio_direction_output(ak7755->pdn_gpio, !ak7755->pdn_active);
+ mdelay(2);
+ }
+
+ snd_soc_write(codec,AK7755_C0_CLOCK_SETTING1,0x08);
+ snd_soc_write(codec,AK7755_C1_CLOCK_SETTING2,0x00);
+ for(i = 0; i < AK7755_MAX_REGNUM; i++) {
+ snd_soc_write(codec, i+0xc0, ak7755_data->reg_cache[i]);
+ }
+
+ snd_soc_update_bits(codec, AK7755_C1_CLOCK_SETTING2, 0x01, 0x01);
+ snd_soc_write(codec,AK7755_CF_RESET_POWER_SETTING,0x01);
+ snd_soc_write(codec,AK7755_DA_MUTE_ADRC_ZEROCROSS_SET,0x10);
+ mdelay(12);
+
+ ak7755_firmware_write_ram(RAMTYPE_PRAM, ak7755_data->DSPPramMode);
+ ak7755_firmware_write_ram(RAMTYPE_CRAM, ak7755_data->DSPCramMode);
+
+ //snd_soc_cache_sync(codec);
+ snd_soc_write(codec, 0xE6, 0x01);
+ snd_soc_write(codec, 0xEA, 0x80);
+
+ snd_soc_write(codec,AK7755_DA_MUTE_ADRC_ZEROCROSS_SET,0x00);
+
+ ak7755_set_bias_level(codec, SND_SOC_BIAS_ON);
+
+ return 0;
+}
+
+
+struct snd_soc_codec_driver soc_codec_dev_ak7755 = {
+ .probe = ak7755_probe,
+ .remove = ak7755_remove,
+ .suspend = ak7755_suspend,
+ .resume = ak7755_resume,
+
+ //.idle_bias_off = false,
+ .set_bias_level = ak7755_set_bias_level,
+ .reg_cache_size = ARRAY_SIZE(ak7755_reg),
+ .reg_word_size = sizeof(u8),
+ .reg_cache_default = ak7755_reg,
+ .readable_register = ak7755_readable,
+ .volatile_register = ak7755_volatile,
+
+ .controls = ak7755_snd_controls,
+ .num_controls = ARRAY_SIZE(ak7755_snd_controls),
+ .dapm_widgets = ak7755_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(ak7755_dapm_widgets),
+ .dapm_routes = ak7755_intercon,
+ .num_dapm_routes = ARRAY_SIZE(ak7755_intercon),
+};
+EXPORT_SYMBOL_GPL(soc_codec_dev_ak7755);
+
+#ifdef CONFIG_OF
+static struct of_device_id ak7755_if_dt_ids[] = {
+ { .compatible = "akm,ak7755"},
+ { }
+};
+MODULE_DEVICE_TABLE(of, ak7755_if_dt_ids);
+#endif
+
+#ifdef AK7755_I2C_IF
+static int ak7755_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct ak7755_priv *ak7755;
+ int ret=0;
+
+ akdbgprt("\t[AK7755] %s(%d)\n",__FUNCTION__,__LINE__);
+
+ ak7755 = kzalloc(sizeof(struct ak7755_priv), GFP_KERNEL);
+ if (ak7755 == NULL) return -ENOMEM;
+
+ i2c_set_clientdata(i2c, ak7755);
+
+ ak7755->control_type = SND_SOC_I2C;
+ ak7755->i2c = i2c;
+
+ ak7755_data = ak7755;
+
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_ak7755, &ak7755_dai[0], ARRAY_SIZE(ak7755_dai));
+ if (ret < 0){
+ kfree(ak7755);
+ akdbgprt("\t[AK7755 Error!] %s(%d)\n",__FUNCTION__,__LINE__);
+ }
+ return ret;
+}
+
+static int ak7755_i2c_remove(struct i2c_client *client)
+{
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
+ return 0;
+}
+
+static const struct i2c_device_id ak7755_i2c_id[] = {
+ { "ak7755", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ak7755_i2c_id);
+
+static struct i2c_driver ak7755_i2c_driver = {
+ .driver = {
+ .name = "ak7755",
+ .owner = THIS_MODULE,
+#ifdef CONFIG_OF
+ .of_match_table = of_match_ptr(ak7755_if_dt_ids),
+#endif
+ },
+ .probe = ak7755_i2c_probe,
+ .remove = ak7755_i2c_remove,
+ .id_table = ak7755_i2c_id,
+};
+
+#else
+
+static int ak7755_spi_probe(struct spi_device *spi)
+{
+ struct ak7755_priv *ak7755;
+ int ret;
+
+ akdbgprt("\t[AK7755] %s spi=%x\n",__FUNCTION__, (int)spi);
+
+ ak7755 = kzalloc(sizeof(struct ak7755_priv), GFP_KERNEL);
+ if (!ak7755)
+ return -ENOMEM;
+
+ ak7755->control_type = SND_SOC_SPI;
+ spi->bits_per_word = 8; // bits
+ spi->max_speed_hz = 7000000;
+ spi->mode = SPI_MODE_3;
+
+ akdbgprt("\t[AK7755] %s spi=%x, spi->chip_select = %d\n, cs_gpio = %d",__FUNCTION__, \
+ (int)spi, spi->chip_select, spi->cs_gpio);
+
+ ak7755->spi = spi;
+ ak7755_data = ak7755;
+
+ if ( 1 == fast_boot ) {
+ u8 reg[2],rx[1];
+ akdbgprt("Start loading AEC Firmware....\n");
+ reg[0] = AK7755_C1_CLOCK_SETTING2 & 0x7F;
+ ak7755_reads(reg,1,rx,1);
+ if (1 != (rx[0] & 0x1)) {
+ printk( "Fast audio setup error for ak7755: 0x%02X\n", rx[0]);
+ return -1;
+ }
+ reg[0] = AK7755_CF_RESET_POWER_SETTING;
+ reg[1] = 0x01;
+ ak7755_writes(reg,2);
+
+ msleep(1);
+ ret = ak7755_firmware_write_ram(RAMTYPE_PRAM, 1);
+ if ( ret < 0 ) {
+ printk( "Failed to RAMTYPE_PRAM %d\n", ret);
+ return ret;
+ }
+ ret = ak7755_firmware_write_ram(RAMTYPE_CRAM,1);
+ if ( ret < 0 ) {
+ printk( "Failed to RAMTYPE_CRAM: %d\n", ret);
+ return ret;
+ }
+ reg[0] = AK7755_CF_RESET_POWER_SETTING;
+ reg[1] = 0x0c;
+ ak7755_writes(reg,2);
+ akdbgprt("Loading AEC Firmware done\n");
+ reg[0] = AK7755_CC_VOLUME_TRANSITION; //change to DSP output
+ reg[1] = 0x00;
+ ak7755_writes(reg,2);
+ reg[0] = AK7755_D2_MIC_GAIN_SETTING; //change Mic Gain to 6dB
+ reg[1] = 0x03;
+ ak7755_writes(reg,2);
+ reg[0] = AK7755_C8_DAC_IN_SETTING; //change DAC out to DSP
+ reg[1] = 0x00;
+
+#ifdef AK7755_DEBUG
+ u32 i;
+ for(i = 0x40; i <= 0x5e; i++) {
+ reg[0] = i ;
+ ak7755_reads(reg,1,rx,1);
+ printk("0x%x: 0x%02x\n", i|0xc0, rx[0]);
+ }
+#endif
+ return 0;
+ } else {
+ spi_set_drvdata(spi, ak7755);
+ }
+
+ ret = snd_soc_register_codec(&spi->dev,
+ &soc_codec_dev_ak7755, &ak7755_dai[0], ARRAY_SIZE(ak7755_dai));
+ if (ret < 0)
+ kfree(ak7755);
+
+ ak7755_data = ak7755;
+
+ return 0;
+}
+
+static int ak7755_spi_remove(struct spi_device *spi)
+{
+ if ( ak7755_data->amp_active > 0 ) {
+ gpio_direction_output(ak7755_data->amp_gpio, !ak7755_data->amp_active);
+ devm_gpio_free(&spi->dev,ak7755_data->amp_active);
+ }
+ if ( ak7755_data->pdn_gpio > 0 ) {
+ gpio_direction_output(ak7755_data->pdn_gpio, ak7755_data->pdn_active);
+ devm_gpio_free(&spi->dev,ak7755_data->pdn_gpio);
+ }
+ if ( ak7755_data->power_gpio > 0 ) {
+ gpio_direction_output(ak7755_data->power_gpio, !ak7755_data->power_active);
+ devm_gpio_free(&spi->dev,ak7755_data->power_gpio);
+ akdbgprt("\t[AK7755] %s(%d) Release power_gpio ->>> %d\n",__FUNCTION__,__LINE__,ak7755_data->power_gpio);
+ }
+ snd_soc_unregister_codec(&spi->dev);
+ kfree(spi_get_drvdata(spi));
+ return 0;
+}
+
+static struct spi_driver ak7755_spi_driver = {
+ .driver = {
+ .name = "ak7755",
+ .owner = THIS_MODULE,
+#ifdef CONFIG_OF
+ .of_match_table = of_match_ptr(ak7755_if_dt_ids),
+#endif
+ },
+ .probe = ak7755_spi_probe,
+ .remove = ak7755_spi_remove,
+};
+#endif
+
+static int __init ak7755_modinit(void)
+{
+ int ret = 0;
+
+ akdbgprt("\t[AK7755] %s(%d)\n", __FUNCTION__,__LINE__);
+
+#ifdef AK7755_I2C_IF
+ ret = i2c_add_driver(&ak7755_i2c_driver);
+ if ( ret != 0 ) {
+ printk(KERN_ERR "Failed to register AK7755 I2C driver: %d\n", ret);
+
+ }
+#else
+ ret = spi_register_driver(&ak7755_spi_driver);
+ if ( ret != 0 ) {
+ printk(KERN_ERR "Failed to register AK7755 SPI driver: %d\n", ret);
+
+ }
+#endif
+
+#ifdef AK7755_IO_CONTROL
+ ret = misc_register(&ak7755_misc);
+ if (ret < 0) {
+ printk(KERN_ERR "Failed to register AK7755 MISC driver: %d\n", ret);
+ }
+#endif
+
+ return ret;
+}
+
+module_init(ak7755_modinit);
+
+static void __exit ak7755_exit(void)
+{
+#ifdef AK7755_I2C_IF
+ i2c_del_driver(&ak7755_i2c_driver);
+#else
+ spi_unregister_driver(&ak7755_spi_driver);
+#endif
+
+#ifdef AK7755_IO_CONTROL
+ misc_deregister(&ak7755_misc);
+#endif
+
+}
+module_exit(ak7755_exit);
+
+MODULE_AUTHOR("Junichi Wakasugi <wakasugi.jb@om.asahi-kasei.co.jp>");
+MODULE_DESCRIPTION("ASoC ak7755 codec driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ak7755.h b/sound/soc/codecs/ak7755.h
new file mode 100644
index 00000000..f320c39d
--- /dev/null
+++ b/sound/soc/codecs/ak7755.h
@@ -0,0 +1,172 @@
+/*
+ * ak7755.h -- audio driver for ak7755
+ *
+ * Copyright (C) 2014 Asahi Kasei Microdevices Corporation
+ * Author Date Revision
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * 14/04/22 1.0
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifndef _AK7755_H
+#define _AK7755_H
+
+//#define AK7755_I2C_IF
+#define AK7755_IO_CONTROL
+
+
+/* AK7755_C1_CLOCK_SETTING2 (0xC1) Fields */
+#define AK7755_AIF_BICK32 (2 << 4)
+#define AK7755_AIF_BICK48 (1 << 4)
+#define AK7755_AIF_BICK64 (0 << 4)
+#define AK7755_AIF_TDM (3 << 4) //TDM256 bit is set "1" at initialization.
+
+/* TDMMODE Input Source */
+#define AK7755_TDM_DSP (0 << 2)
+#define AK7755_TDM_DSP_AD1 (1 << 2)
+#define AK7755_TDM_DSP_AD1_AD2 (2 << 2)
+
+/* User Setting */
+//#define DIGITAL_MIC
+//#define CLOCK_MODE_BICK
+//#define CLOCK_MODE_18_432
+#define AK7755_AUDIO_IF_MODE AK7755_AIF_BICK32 //32fs, 48fs, 64fs, 256fs(TDM)
+#define AK7755_TDM_INPUT_SOURCE AK7755_TDM_DSP //Effective only in TDM mode
+#define AK7755_BCKP_BIT (0 << 6) //BICK Edge Setting
+#define AK7755_SOCFG_BIT (0 << 4) //SO pin Hi-z Setting
+#define AK7755_DMCLKP1_BIT (0 << 6) //DigitalMIC 1 Channnel Setting
+#define AK7755_DMCLKP2_BIT (0 << 3) //DigitalMIC 1 Channnel Setting
+/* User Setting */
+
+#define AK7755_C0_CLOCK_SETTING1 0xC0
+#define AK7755_C1_CLOCK_SETTING2 0xC1
+#define AK7755_C2_SERIAL_DATA_FORMAT 0xC2
+#define AK7755_C3_DELAY_RAM_DSP_IO 0xC3
+#define AK7755_C4_DATARAM_CRAM_SETTING 0xC4
+#define AK7755_C5_ACCELARETOR_SETTING 0xC5
+#define AK7755_C6_DAC_DEM_SETTING 0xC6
+#define AK7755_C7_DSP_OUT_SETTING 0xC7
+#define AK7755_C8_DAC_IN_SETTING 0xC8
+#define AK7755_C9_ANALOG_IO_SETTING 0xC9
+#define AK7755_CA_CLK_SDOUT_SETTING 0xCA
+#define AK7755_CB_TEST_SETTING 0xCB
+#define AK7755_CC_VOLUME_TRANSITION 0xCC
+#define AK7755_CD_STO_DLS_SETTING 0xCD
+#define AK7755_CE_POWER_MANAGEMENT 0xCE
+#define AK7755_CF_RESET_POWER_SETTING 0xCF
+#define AK7755_D0_FUNCTION_SETTING 0xD0
+#define AK7755_D1_DSPMCLK_SETTING 0xD1
+#define AK7755_D2_MIC_GAIN_SETTING 0xD2
+#define AK7755_D3_LIN_LO3_VOLUME_SETTING 0xD3
+#define AK7755_D4_LO1_LO2_VOLUME_SETTING 0xD4
+#define AK7755_D5_ADC_DVOLUME_SETTING1 0xD5
+#define AK7755_D6_ADC_DVOLUME_SETTING2 0xD6
+#define AK7755_D7_ADC2_DVOLUME_SETTING1 0xD7
+#define AK7755_D8_DAC_DVOLUME_SETTING1 0xD8
+#define AK7755_D9_DAC_DVOLUME_SETTING2 0xD9
+#define AK7755_DA_MUTE_ADRC_ZEROCROSS_SET 0xDA
+#define AK7755_DB_ADRC_MIC_GAIN_READ 0xDB
+#define AK7755_DC_TEST_SETTING 0xDC
+#define AK7755_DD_ADC2_DVOLUME_SETTING2 0xDD
+#define AK7755_DE_DMIC_IF_SETTING 0xDE
+
+#define AK7755_MAX_REGISTERS (AK7755_DE_DMIC_IF_SETTING + 1)
+#define AK7755_MAX_REGNUM (31)
+
+/* Bitfield Definitions */
+
+/* AK7755_C0_CLOCK_SETTING1 (0xC0) Fields */
+#define AK7755_FS 0x07
+#define AK7755_FS_8KHZ (0x00 << 0)
+#define AK7755_FS_12KHZ (0x01 << 0)
+#define AK7755_FS_16KHZ (0x02 << 0)
+#define AK7755_FS_24KHZ (0x03 << 0)
+#define AK7755_FS_32KHZ (0x04 << 0)
+#define AK7755_FS_48KHZ (0x05 << 0)
+#define AK7755_FS_96KHZ (0x06 << 0)
+
+#define AK7755_M_S 0x30 //CKM1-0 (CKM2 bit is not use)
+#define AK7755_M_S_0 (0 << 4) //Master, XTI=12.288MHz
+#define AK7755_M_S_1 (1 << 4) //Master, XTI=18.432MHz
+#define AK7755_M_S_2 (2 << 4) //Slave, XTI=12.288MHz
+#define AK7755_M_S_3 (3 << 4) //Slave, BICK
+
+/* AK7755_C2_SERIAL_DATA_FORMAT (0xC2) Fields */
+/* LRCK I/F Format */
+#define AK7755_LRIF 0x30
+#define AK7755_LRIF_MSB_MODE (0 << 4)
+#define AK7755_LRIF_I2S_MODE (1 << 4)
+#define AK7755_LRIF_PCM_SHORT_MODE (2 << 4)
+#define AK7755_LRIF_PCM_LONG_MODE (3 << 4)
+/* Input Format is set as "MSB(24- bit)" by following register.
+ CONT03(DIF2,DOF2), CONT06(DIFDA, DIF1), CONT07(DOF4,DOF3,DOF1) */
+
+/* AK7755_CA_CLK_SDOUT_SETTING (0xCA) Fields */
+#define AK7755_BICK_LRCK (3 << 5) //BICKOE, LRCKOE
+
+
+
+#define MAX_LOOP_TIMES 3
+
+#define CRC_COMMAND_READ_RESULT 0x72
+#define TOTAL_NUM_OF_PRAM_MAX 20483
+#define TOTAL_NUM_OF_CRAM_MAX 6147
+#define TOTAL_NUM_OF_OFREG_MAX 99
+#define TOTAL_NUM_OF_ACRAM_MAX 6147
+
+static const char *ak7755_firmware_pram[] =
+{
+ "Off",
+ "basic",
+ "data2",
+ "data3",
+ "data4",
+ "data5",
+ "data6",
+ "data7",
+ "data8",
+ "data9",
+};
+
+static const char *ak7755_firmware_cram[] =
+{
+ "Off",
+ "basic",
+ "data2",
+ "data3",
+ "data4",
+ "data5",
+ "data6",
+ "data7",
+ "data8",
+ "data9",
+};
+
+static const char *ak7755_firmware_ofreg[] =
+{
+ "Off",
+ "basic",
+ "data2",
+ "data3",
+ "data4",
+};
+
+static const char *ak7755_firmware_acram[] =
+{
+ "Off",
+ "basic",
+ "data2",
+ "data3",
+ "data4",
+};
+
+#include "ak7755ctl.h"
+
+#endif
+
diff --git a/sound/soc/codecs/ak7755_dsp_code.h b/sound/soc/codecs/ak7755_dsp_code.h
new file mode 100644
index 00000000..43a4cc5d
--- /dev/null
+++ b/sound/soc/codecs/ak7755_dsp_code.h
@@ -0,0 +1,6220 @@
+static u8 ak7755_pram_basic[]= {
+ 0xB8, 0x00, 0x00, // PRAM Write Command
+ 0x0C, 0x94, 0xED, 0x1E, 0x74,
+ 0x04, 0xA8, 0x9C, 0x6D, 0x55,
+ 0x00, 0x44, 0x02, 0x11, 0x99,
+ 0x09, 0x58, 0x6F, 0x4D, 0xD0,
+ 0x01, 0x5A, 0x7C, 0xC9, 0x27,
+ 0x09, 0x35, 0x31, 0x01, 0x86,
+ 0x03, 0x4B, 0xFA, 0x2C, 0x60,
+ 0x0E, 0xF8, 0x5B, 0xA8, 0xD6,
+ 0x04, 0x02, 0x37, 0xDD, 0x00,
+ 0x05, 0x79, 0x77, 0x03, 0x9D,
+ 0x07, 0xAE, 0xA3, 0x43, 0x38,
+ 0x0E, 0xD9, 0xA6, 0x5E, 0x1F,
+ 0x00, 0x7B, 0xE3, 0xE6, 0x41,
+ 0x09, 0x8A, 0xB8, 0x79, 0xB1,
+ 0x03, 0x68, 0x1B, 0xB8, 0x98,
+ 0x08, 0x55, 0xA7, 0x8B, 0x7A,
+ 0x01, 0x8F, 0x58, 0x91, 0x42,
+ 0x04, 0xAC, 0x14, 0xDB, 0xF2,
+ 0x0B, 0x37, 0xC2, 0x1F, 0x0C,
+ 0x06, 0xA5, 0x9C, 0xED, 0xE6,
+ 0x01, 0xA6, 0xC0, 0xAD, 0xBB,
+ 0x05, 0xFE, 0x2A, 0x81, 0x4A,
+ 0x03, 0xBF, 0xC7, 0x3A, 0x4F,
+ 0x0D, 0x44, 0x86, 0x74, 0x8C,
+ 0x03, 0x43, 0xBC, 0x3B, 0x53,
+ 0x07, 0xC5, 0xCD, 0x84, 0x59,
+ 0x04, 0x79, 0xF3, 0xE4, 0x2E,
+ 0x01, 0xB5, 0x71, 0x37, 0x20,
+ 0x08, 0x46, 0x13, 0x93, 0xD3,
+ 0x05, 0xB7, 0x82, 0x8D, 0x69,
+ 0x02, 0xA4, 0x57, 0xEC, 0x94,
+ 0x0C, 0x06, 0x32, 0x8D, 0x2F,
+ 0x08, 0xB1, 0xD7, 0x59, 0xE3,
+ 0x0E, 0x83, 0x5C, 0xF6, 0x0B,
+ 0x0F, 0x55, 0x03, 0x95, 0xE5,
+ 0x0C, 0x5E, 0xF0, 0x1E, 0xBA,
+ 0x08, 0x5C, 0x20, 0x7B, 0x66,
+ 0x07, 0x29, 0xFB, 0x43, 0x5F,
+ 0x0A, 0xC8, 0xC7, 0xA7, 0x68,
+ 0x03, 0xB7, 0x43, 0xC8, 0xE3,
+ 0x0B, 0xB3, 0xA3, 0x26, 0x5A,
+ 0x0D, 0x76, 0xEE, 0xC5, 0xB0,
+ 0x0E, 0x14, 0x8B, 0xD3, 0xF6,
+ 0x09, 0x3E, 0x49, 0xA9, 0x98,
+ 0x0D, 0x34, 0xDA, 0x5F, 0xD1,
+ 0x03, 0xAC, 0xB3, 0xC3, 0xEC,
+ 0x06, 0xB6, 0xEC, 0x12, 0x0D,
+ 0x0A, 0x05, 0x2A, 0xCD, 0xB2,
+ 0x0C, 0xE9, 0x3D, 0xF3, 0x98,
+ 0x09, 0xC2, 0xF6, 0xCB, 0x3E,
+ 0x00, 0xFF, 0x83, 0xD9, 0xA5,
+ 0x0A, 0x89, 0xEE, 0xD9, 0xE7,
+ 0x04, 0x0A, 0x71, 0xCE, 0x95,
+ 0x04, 0xC4, 0x40, 0x21, 0x18,
+ 0x0E, 0x55, 0x87, 0xF4, 0xDC,
+ 0x0A, 0x15, 0xA0, 0x6C, 0x92,
+ 0x0F, 0x93, 0x52, 0x30, 0x18,
+ 0x0A, 0x64, 0x3B, 0x22, 0xC7,
+ 0x08, 0x37, 0x4E, 0xBA, 0x0D,
+ 0x0D, 0x89, 0xA9, 0xFF, 0xE4,
+ 0x0B, 0x06, 0x54, 0x70, 0x39,
+ 0x02, 0x2B, 0x6C, 0xA4, 0x33,
+ 0x04, 0xBC, 0x5B, 0x1B, 0xAB,
+ 0x0E, 0x56, 0x7A, 0x28, 0xAE,
+ 0x02, 0xCC, 0x22, 0xCF, 0x9B,
+ 0x05, 0x72, 0x0D, 0xAB, 0x89,
+ 0x09, 0xD1, 0x82, 0x30, 0x9C,
+ 0x0B, 0x0D, 0xE9, 0xBD, 0x25,
+ 0x0B, 0x4F, 0xD9, 0x21, 0x0C,
+ 0x06, 0xA6, 0x61, 0x37, 0x9E,
+ 0x09, 0x7F, 0x45, 0x08, 0x38,
+ 0x0F, 0x1F, 0x74, 0x1C, 0xEB,
+ 0x00, 0x5A, 0xFA, 0xAE, 0xA6,
+ 0x07, 0xAE, 0x40, 0x7B, 0xA4,
+ 0x0C, 0x54, 0xA8, 0x6F, 0x4B,
+ 0x0B, 0x34, 0x3B, 0xC3, 0xFE,
+ 0x0F, 0x7C, 0x5D, 0xC8, 0x25,
+ 0x0B, 0x47, 0x98, 0xB6, 0x2A,
+ 0x07, 0x1B, 0x56, 0x13, 0x11,
+ 0x00, 0xD4, 0xE5, 0xB9, 0x56,
+ 0x0A, 0x83, 0xB3, 0x28, 0x56,
+ 0x0F, 0xE3, 0xCF, 0xFC, 0xFD,
+ 0x0D, 0x91, 0xA0, 0x28, 0xD2,
+ 0x0E, 0xDA, 0x9B, 0xE5, 0x9E,
+ 0x0F, 0xB9, 0xF4, 0xB1, 0x2A,
+ 0x04, 0xA4, 0x94, 0x2F, 0x94,
+ 0x0D, 0x91, 0x66, 0x49, 0xEB,
+ 0x08, 0xC1, 0x4E, 0x17, 0xB6,
+ 0x09, 0x26, 0x47, 0xFC, 0x1E,
+ 0x08, 0xB9, 0x90, 0x4E, 0x47,
+ 0x0F, 0x3E, 0x6C, 0x50, 0x3D,
+ 0x06, 0xAE, 0x27, 0x24, 0x0B,
+ 0x08, 0xC2, 0x72, 0x2A, 0xBD,
+ 0x06, 0xE4, 0x50, 0xAB, 0x0F,
+ 0x04, 0x96, 0xFC, 0x9C, 0x2B,
+ 0x08, 0x46, 0xF1, 0xAD, 0xFD,
+ 0x0F, 0xBA, 0x2B, 0x34, 0x3D,
+ 0x00, 0x6B, 0x6E, 0xC1, 0x6B,
+ 0x0A, 0xA0, 0x53, 0xBC, 0xBB,
+ 0x01, 0xCE, 0x94, 0x57, 0x51,
+ 0x01, 0x9C, 0x2E, 0x6C, 0xD0,
+ 0x0F, 0x5F, 0x7C, 0xBD, 0xF1,
+ 0x02, 0x70, 0x55, 0xED, 0x1E,
+ 0x0C, 0x89, 0x2D, 0x9E, 0xDD,
+ 0x0D, 0x1D, 0x87, 0x02, 0x11,
+ 0x04, 0xB4, 0xDE, 0xEF, 0x4D,
+ 0x09, 0xF0, 0x9B, 0x78, 0x83,
+ 0x0C, 0xA8, 0xF1, 0x35, 0xCB,
+ 0x0C, 0xF2, 0xCA, 0xFA, 0x2C,
+ 0x05, 0xC7, 0xF8, 0xFB, 0xA0,
+ 0x07, 0x8C, 0x42, 0xD7, 0xD5,
+ 0x00, 0xA5, 0x79, 0x73, 0x32,
+ 0x0D, 0x27, 0xAE, 0xA6, 0xF0,
+ 0x08, 0x5E, 0xD8, 0xA7, 0xD4,
+ 0x0F, 0xF0, 0x7B, 0x64, 0x6C,
+ 0x01, 0x29, 0xDA, 0x3A, 0xC9,
+ 0x01, 0x52, 0x38, 0xDC, 0x0A,
+ 0x04, 0x88, 0x04, 0x23, 0x01,
+ 0x06, 0xB0, 0xDC, 0xDB, 0x99,
+ 0x00, 0xB4, 0xF9, 0x9A, 0x1B,
+ 0x0E, 0x6A, 0x62, 0x83, 0x11,
+ 0x06, 0xC7, 0x70, 0x58, 0xEB,
+ 0x00, 0xF1, 0xF1, 0x81, 0xA5,
+ 0x0B, 0x54, 0x2B, 0xAA, 0x81,
+ 0x06, 0xF2, 0xE7, 0x07, 0x32,
+ 0x0F, 0x0C, 0xC0, 0x86, 0x70,
+ 0x01, 0xB3, 0x48, 0xFC, 0x37,
+ 0x00, 0xA6, 0x41, 0xCC, 0x82,
+ 0x03, 0xB4, 0x79, 0xF3, 0x62,
+ 0x04, 0x20, 0x31, 0x71, 0x31,
+ 0x00, 0x08, 0x46, 0x13, 0x95,
+ 0x01, 0xEC, 0xB7, 0x22, 0x85,
+ 0x05, 0xFB, 0x2F, 0x37, 0xEC,
+ 0x04, 0xCC, 0x06, 0x36, 0xBC,
+ 0x0F, 0xE8, 0xB1, 0xD0, 0x53,
+ 0x03, 0xEE, 0x83, 0xDD, 0x46,
+ 0x0B, 0x5F, 0x55, 0x06, 0xB2,
+ 0x09, 0xDC, 0x0E, 0x74, 0x96,
+ 0x06, 0x89, 0x0D, 0x21, 0x73,
+ 0x04, 0x87, 0x7C, 0x77, 0xC1,
+ 0x03, 0x8B, 0x9D, 0x04, 0xAF,
+ 0x08, 0xA3, 0x62, 0xC5, 0x48,
+ 0x0F, 0x6A, 0xE4, 0x22, 0x28,
+ 0x00, 0xDD, 0xA3, 0x2A, 0xC3,
+ 0x06, 0x6E, 0x4D, 0x8A, 0xDB,
+ 0x06, 0x18, 0xEB, 0xC9, 0xA9,
+ 0x04, 0x0C, 0x6F, 0xDA, 0x57,
+ 0x01, 0x32, 0x28, 0xB3, 0xC7,
+ 0x0D, 0x06, 0xB6, 0xEC, 0x16,
+ 0x0E, 0xFB, 0x81, 0x2B, 0xCB,
+ 0x08, 0x1C, 0xE9, 0x3D, 0x75,
+ 0x02, 0x48, 0x42, 0xF6, 0xCD,
+ 0x02, 0xF0, 0xF4, 0x43, 0xD7,
+ 0x07, 0x32, 0x09, 0x4A, 0xE0,
+ 0x07, 0xCD, 0x8A, 0x97, 0xCC,
+ 0x05, 0xC4, 0xC4, 0xC6, 0x11,
+ 0x08, 0x4E, 0x55, 0x82, 0xD2,
+ 0x04, 0x0A, 0xB5, 0xAE, 0x6C,
+ 0x0B, 0x5F, 0x73, 0x5A, 0xF0,
+ 0x08, 0xCA, 0x34, 0xBF, 0xA2,
+ 0x07, 0x59, 0x66, 0x8F, 0xBA,
+ 0x0D, 0x6D, 0xDF, 0xAD, 0x7D,
+ 0x04, 0x0A, 0x56, 0x97, 0x70,
+ 0x09, 0x82, 0xFE, 0x6A, 0x24,
+ 0x02, 0xD5, 0x2C, 0x9A, 0x1D,
+ 0x01, 0xAE, 0x83, 0x3C, 0x9E,
+ 0x05, 0x43, 0x5E, 0xA3, 0xCF,
+ 0x0B, 0x44, 0xA5, 0x0D, 0xAB,
+ 0x08, 0xD9, 0x41, 0x44, 0x7A,
+ 0x0D, 0xFA, 0xC9, 0xEF, 0x73,
+ 0x04, 0x7A, 0xCE, 0xD9, 0x25,
+ 0x0F, 0x77, 0x26, 0x60, 0x31,
+ 0x05, 0x38, 0xBF, 0x45, 0x8E,
+ 0x02, 0xCF, 0x1F, 0x70, 0x2B,
+ 0x0B, 0xB0, 0x5A, 0xFE, 0x1B,
+ 0x04, 0xAF, 0x2F, 0xE6, 0x79,
+ 0x04, 0xF5, 0xD4, 0xCE, 0xED,
+ 0x0B, 0xDB, 0x34, 0x3D, 0xF3,
+ 0x0E, 0x0F, 0x7C, 0x5A, 0x7A,
+ 0x09, 0x3B, 0x4A, 0x1F, 0x3E,
+ 0x0A, 0x47, 0x1B, 0x57, 0x13,
+ 0x01, 0x00, 0x84, 0x63, 0x89,
+ 0x0A, 0x1B, 0xDD, 0x72, 0x20,
+ 0x06, 0x9F, 0xB2, 0x4B, 0x7E,
+ 0x0D, 0x4C, 0xC0, 0x61, 0x99,
+ 0x0E, 0xFE, 0x85, 0x5D, 0x6D,
+ 0x0E, 0x3E, 0xE8, 0x35, 0xB7,
+ 0x08, 0xB6, 0x75, 0xDC, 0x23,
+ 0x06, 0xDE, 0x60, 0x6B, 0x03,
+ 0x02, 0xAA, 0xB0, 0xCA, 0x17,
+ 0x0C, 0x68, 0x17, 0x87, 0xF8,
+ 0x06, 0xF8, 0x39, 0x94, 0x0A,
+ 0x0E, 0x0F, 0x9E, 0x6E, 0xD4,
+ 0x06, 0xB4, 0x8E, 0x22, 0x22,
+ 0x0B, 0x08, 0xA0, 0x72, 0xA4,
+ 0x07, 0x25, 0xC4, 0x50, 0xAD,
+ 0x0F, 0x64, 0x92, 0xFC, 0x9A,
+ 0x0B, 0x80, 0xC2, 0x55, 0xE5,
+ 0x0F, 0x16, 0x3E, 0xCF, 0x7C,
+ 0x0D, 0xD1, 0xEF, 0x6E, 0xC1,
+ 0x0B, 0xD3, 0x24, 0x52, 0xBC,
+ 0x07, 0x9E, 0x31, 0x6F, 0xE7,
+ 0x08, 0x22, 0x58, 0x2B, 0x67,
+ 0x08, 0x6A, 0xAF, 0xF9, 0xEA,
+ 0x08, 0x5B, 0xE0, 0x90, 0x6D,
+ 0x07, 0x72, 0x18, 0xA5, 0x1C,
+ 0x05, 0xDD, 0xE8, 0x44, 0xC2,
+ 0x08, 0x9D, 0x45, 0x5C, 0xEF,
+ 0x01, 0xC8, 0xAA, 0x5A, 0x60,
+ 0x01, 0xAF, 0xBD, 0xB5, 0xF3,
+ 0x0B, 0x8C, 0xC9, 0xCB, 0xF2,
+ 0x04, 0xF5, 0x36, 0x78, 0xFB,
+ 0x0C, 0xD6, 0xD6, 0x02, 0xC9,
+ 0x04, 0xC5, 0x05, 0x7F, 0x7D,
+ 0x0B, 0x9C, 0xC7, 0xAE, 0x62,
+ 0x0B, 0x9E, 0xDA, 0xD5, 0xA1,
+ 0x06, 0x1F, 0x70, 0x7F, 0xE2,
+ 0x0E, 0x40, 0xAD, 0xDA, 0xFC,
+ 0x01, 0x37, 0x72, 0x38, 0x1A,
+ 0x08, 0x98, 0x88, 0x80, 0x34,
+ 0x01, 0x62, 0x10, 0xDA, 0xDB,
+ 0x09, 0x42, 0x3C, 0xFF, 0x12,
+ 0x03, 0xF0, 0x6A, 0x62, 0x43,
+ 0x03, 0x46, 0xE7, 0x74, 0x50,
+ 0x0B, 0x2F, 0xF1, 0xF7, 0x41,
+ 0x0D, 0xBB, 0x01, 0xAF, 0xAA,
+ 0x03, 0x4A, 0xFA, 0xEA, 0x07,
+ 0x08, 0x4F, 0x51, 0x40, 0x86,
+ 0x00, 0x3C, 0x13, 0x43, 0xBC,
+ 0x0F, 0x59, 0x57, 0xC5, 0xCC,
+ 0x02, 0x53, 0xB4, 0xF9, 0xF3,
+ 0x02, 0xA4, 0x73, 0x31, 0x3B,
+ 0x01, 0x10, 0x0B, 0x46, 0x13,
+ 0x05, 0x61, 0xBD, 0xB7, 0x22,
+ 0x01, 0x69, 0xFA, 0xA0, 0xF7,
+ 0x00, 0xD4, 0xCD, 0x02, 0x72,
+ 0x0D, 0x2F, 0x68, 0xB1, 0xD6,
+ 0x09, 0x63, 0x4E, 0x83, 0x5B,
+ 0x0A, 0x2F, 0x5F, 0x55, 0x15,
+ 0x05, 0xE5, 0xDC, 0x0A, 0x45,
+ 0x0E, 0xBA, 0x89, 0x08, 0x92,
+ 0x0B, 0x66, 0x87, 0xFE, 0x75,
+ 0x01, 0xEF, 0x8B, 0x9F, 0x4E,
+ 0x07, 0x68, 0xF3, 0x60, 0xF5,
+ 0x08, 0xE3, 0x6A, 0xE4, 0x10,
+ 0x0C, 0x10, 0x9C, 0x27, 0x22,
+ 0x0F, 0x7A, 0x60, 0x45, 0x02,
+ 0x03, 0xF6, 0x4D, 0x6F, 0xC9,
+ 0x09, 0x98, 0x0C, 0x65, 0x1A,
+ 0x0F, 0xB1, 0xE7, 0xAC, 0xB3,
+ 0x07, 0xDD, 0x06, 0xB6, 0xEC,
+ 0x06, 0xDF, 0x2A, 0x05, 0x2B,
+ 0x07, 0xB8, 0x0C, 0xA9, 0x35,
+ 0x05, 0x12, 0x19, 0xC6, 0xC7,
+ 0x0D, 0x0E, 0xF0, 0xF9, 0x89,
+ 0x0F, 0x17, 0x32, 0x8F, 0x7E,
+ 0x01, 0xE7, 0xCD, 0x8E, 0xB0,
+ 0x0E, 0x55, 0x60, 0x4D, 0x40,
+ 0x01, 0x18, 0x4A, 0xD5, 0x86,
+ 0x04, 0xDC, 0x8E, 0x95, 0xA7,
+ 0x0C, 0xC2, 0x58, 0x11, 0xE2,
+ 0x00, 0x49, 0x4E, 0x36, 0x0F,
+ 0x00, 0x96, 0xDD, 0x61, 0xC5,
+ 0x0A, 0x5C, 0xE0, 0xD8, 0x2D,
+ 0x0D, 0x05, 0x8A, 0x57, 0x97,
+ 0x00, 0x39, 0xD2, 0x7A, 0xEA,
+ 0x04, 0x33, 0x85, 0xE9, 0xAB,
+ 0x0D, 0xE1, 0xFF, 0x01, 0xB4,
+ 0x0E, 0x64, 0x12, 0x1B, 0x93,
+ 0x0F, 0x9B, 0x15, 0x27, 0xA9,
+ 0x0B, 0x89, 0x88, 0x88, 0xE0,
+ 0x00, 0x9C, 0xAB, 0x05, 0x0A,
+ 0x05, 0x14, 0x26, 0xCF, 0xD1,
+ 0x09, 0xBF, 0x29, 0x66, 0x68,
+ 0x01, 0x94, 0x6D, 0x7F, 0x45,
+ 0x0E, 0xB2, 0xCF, 0x1F, 0x74,
+ 0x0A, 0xBB, 0x34, 0x5A, 0xFA,
+ 0x08, 0x14, 0xAF, 0x2E, 0xE0,
+ 0x03, 0xC5, 0x75, 0xD4, 0x48,
+ 0x0B, 0x0B, 0xCA, 0xF4, 0x33,
+ 0x03, 0xFE, 0x0F, 0x78, 0x6D,
+ 0x08, 0x25, 0x3B, 0x41, 0x95,
+ 0x06, 0x2A, 0x47, 0x9D, 0x67,
+ 0x03, 0x11, 0x00, 0x80, 0x41,
+ 0x05, 0x56, 0x0A, 0x53, 0x7A,
+ 0x04, 0x56, 0x8D, 0xB2, 0x43,
+ 0x06, 0x4D, 0xCC, 0xC2, 0xE3,
+ 0x08, 0xD2, 0xFE, 0x8B, 0x1D,
+ 0x05, 0x9E, 0x3E, 0xEC, 0x10,
+ 0x08, 0x60, 0xB5, 0xF5, 0x50,
+};
+
+static u8 ak7755_cram_basic[]= {
+ 0xB4, 0x00, 0x00, // CRAM Write Command
+ 0x00, 0x00, 0x00, // EQ1 LPF fc = 125Hz
+ 0x00, 0x42, 0x7A,
+ 0x00, 0x00, 0x00,
+ 0x1F, 0x7B, 0x0B,
+ 0x00, 0x42, 0x7A,
+ 0xFF, 0x50, 0x67, // EQ2 BPF fo = 250Hz
+ 0x00, 0x00, 0x00,
+ 0xE2, 0x1C, 0x4C,
+ 0x3D, 0xDB, 0x38,
+ 0x00, 0xAF, 0x99,
+ 0xFD, 0x7D, 0x8E, // EQ3 BPF fo = 1000Hz
+ 0x00, 0x00, 0x00,
+ 0xE7, 0xB8, 0xC0,
+ 0x37, 0xCB, 0xFE,
+ 0x02, 0x82, 0x72,
+ 0xF8, 0x9F, 0x19, // EQ4 BPF fo = 4000Hz
+ 0x00, 0x00, 0x00,
+ 0xF6, 0xB4, 0x01,
+ 0x23, 0xC3, 0x9E,
+ 0x07, 0x60, 0xE7,
+ 0x00, 0x00, 0x00, // EQ5 HPF fc = 7500Hz
+ 0xEB, 0x25, 0x7E,
+ 0x00, 0x00, 0x00,
+ 0x09, 0xB5, 0x04,
+ 0x14, 0xDA, 0x82,
+ 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x00, // EQ1 Gain
+ 0x00, 0x00, 0x00, // EQ2 Gain
+ 0x00, 0x00, 0x00, // EQ3 Gain
+ 0x00, 0x00, 0x00, // EQ4 Gain
+ 0x00, 0x00, 0x00, // EQ5 Gain
+ 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, // HPF1
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00,
+ 0x7D, 0x63, 0x00,
+ 0x21, 0xF6, 0x00,
+ 0x7D, 0x63, 0x00,
+ 0x21, 0xF6, 0x00,
+ 0x7F, 0xFA, 0x00,
+ 0x55, 0x72, 0x00,
+ 0xF8, 0x6E, 0x00,
+ 0xE6, 0xDA, 0xB0,
+ 0x17, 0x92, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x00, // MIX_VOL_L
+ 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x00, // HPF2
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x00, // MIX_VOL_R
+};
+
+static u8 ak7755_pram_aec[]= {
+ 0xB8,0x00,0x00, // PRAM Write Command
+ 0x0C, 0xB4, 0xED, 0x1E, 0x42,
+ 0x04, 0xA9, 0x1C, 0x6D, 0x49,
+ 0x04, 0x44, 0x82, 0x1A, 0x44,
+ 0x0F, 0x58, 0x76, 0xCD, 0x88,
+ 0x0D, 0x5A, 0x7E, 0x89, 0x1D,
+ 0x03, 0x35, 0x29, 0x03, 0x8C,
+ 0x0F, 0x4A, 0x05, 0x6C, 0x68,
+ 0x0A, 0x70, 0xFE, 0x20, 0xE7,
+ 0x01, 0x86, 0xD2, 0x15, 0x72,
+ 0x09, 0x79, 0x37, 0xC3, 0xAE,
+ 0x07, 0xAE, 0xA2, 0x4F, 0x79,
+ 0x0E, 0xD9, 0xA1, 0xD2, 0xA2,
+ 0x00, 0x7B, 0xE2, 0xEA, 0xAB,
+ 0x09, 0xDA, 0x38, 0xF5, 0xEE,
+ 0x02, 0x38, 0xDE, 0xB4, 0x07,
+ 0x08, 0x04, 0x23, 0x05, 0x15,
+ 0x0C, 0xDE, 0x9B, 0xD1, 0x73,
+ 0x04, 0xFD, 0x92, 0x57, 0x99,
+ 0x06, 0x67, 0xD8, 0x99, 0x75,
+ 0x0B, 0xF4, 0x58, 0xEB, 0x2A,
+ 0x0D, 0xF6, 0xA0, 0x2D, 0x8E,
+ 0x09, 0xAF, 0xC4, 0x01, 0x43,
+ 0x0E, 0xEC, 0x54, 0x3A, 0x4B,
+ 0x06, 0xC1, 0x84, 0xF0, 0xBD,
+ 0x0F, 0x42, 0x33, 0x3F, 0xFD,
+ 0x0B, 0xC5, 0x8C, 0x02, 0x5A,
+ 0x0F, 0xFB, 0x3C, 0x62, 0xA4,
+ 0x0D, 0xB4, 0xE6, 0xF1, 0x0D,
+ 0x04, 0x46, 0x63, 0x95, 0x68,
+ 0x06, 0xB5, 0xD0, 0x85, 0x69,
+ 0x07, 0x25, 0x38, 0xE4, 0xC9,
+ 0x00, 0x06, 0x63, 0xCD, 0x26,
+ 0x03, 0x33, 0x19, 0x59, 0xE3,
+ 0x02, 0x82, 0xC8, 0xB6, 0x16,
+ 0x03, 0x55, 0x73, 0x15, 0xEC,
+ 0x07, 0x8C, 0x86, 0x9E, 0xBA,
+ 0x05, 0x1C, 0xE1, 0x7B, 0x60,
+ 0x0B, 0x68, 0x7F, 0xC1, 0xE8,
+ 0x07, 0x98, 0xB3, 0xE7, 0x75,
+ 0x0F, 0xE6, 0xA1, 0xC8, 0xEA,
+ 0x01, 0x61, 0xAF, 0x20, 0x10,
+ 0x00, 0x26, 0xEA, 0x03, 0x67,
+ 0x02, 0x45, 0x68, 0xD3, 0xFF,
+ 0x02, 0xEC, 0x04, 0xA9, 0x98,
+ 0x07, 0xE1, 0x8D, 0x5F, 0xD1,
+ 0x0F, 0xAC, 0xB3, 0xC7, 0xE3,
+ 0x0A, 0xB7, 0x76, 0xD6, 0xA3,
+ 0x06, 0x05, 0x58, 0x0B, 0xB1,
+ 0x0C, 0xE9, 0x3F, 0x75, 0x12,
+ 0x09, 0xC2, 0xF6, 0x4D, 0xC4,
+ 0x00, 0xFF, 0x81, 0xDF, 0xDD,
+ 0x0D, 0x89, 0x4E, 0xD1, 0xE7,
+ 0x01, 0x8A, 0x91, 0xC6, 0xD3,
+ 0x08, 0xC4, 0x40, 0x21, 0x1F,
+ 0x05, 0xD2, 0xD0, 0xF4, 0xDC,
+ 0x06, 0x14, 0x27, 0xAC, 0x8F,
+ 0x03, 0x93, 0x53, 0x70, 0x29,
+ 0x03, 0xB4, 0x5F, 0xAE, 0x87,
+ 0x03, 0x67, 0x91, 0xBA, 0x4D,
+ 0x0D, 0xD8, 0x2D, 0x7D, 0x4B,
+ 0x0A, 0x57, 0x97, 0x70, 0x39,
+ 0x0E, 0x7A, 0x15, 0xE4, 0x3B,
+ 0x09, 0xEF, 0x65, 0xDD, 0xE5,
+ 0x0F, 0x07, 0xBE, 0x2E, 0x6E,
+ 0x02, 0x9D, 0xA3, 0xCF, 0x99,
+ 0x09, 0x23, 0x4A, 0xAB, 0x80,
+ 0x08, 0x80, 0x40, 0x30, 0x9C,
+ 0x07, 0x0D, 0xE9, 0xB9, 0x2B,
+ 0x02, 0xCF, 0x3B, 0x27, 0x3F,
+ 0x0C, 0xA6, 0x43, 0xB1, 0xB4,
+ 0x05, 0x5F, 0x45, 0x8E, 0x8D,
+ 0x07, 0x1F, 0x74, 0x1A, 0xDB,
+ 0x0C, 0x5B, 0x66, 0xA8, 0x09,
+ 0x04, 0xA8, 0xA0, 0x7B, 0x96,
+ 0x09, 0xD4, 0x37, 0xA7, 0x02,
+ 0x07, 0x35, 0xBA, 0x03, 0xE3,
+ 0x0F, 0x7C, 0x5E, 0xC8, 0x25,
+ 0x03, 0x47, 0x1F, 0x3A, 0xA0,
+ 0x0F, 0x9B, 0xF5, 0x13, 0xD1,
+ 0x0A, 0x84, 0x4E, 0xB9, 0x76,
+ 0x07, 0xD3, 0xFE, 0x68, 0x5E,
+ 0x03, 0xB2, 0x71, 0xFE, 0x50,
+ 0x07, 0x46, 0x56, 0xA8, 0xD2,
+ 0x02, 0x8B, 0x60, 0xA5, 0x97,
+ 0x0E, 0xE8, 0x37, 0xB7, 0x60,
+ 0x0C, 0x75, 0xB0, 0x25, 0x5E,
+ 0x04, 0x41, 0x07, 0x4B, 0x6B,
+ 0x00, 0x96, 0x2E, 0x1B, 0xB6,
+ 0x08, 0x77, 0x87, 0x79, 0xD4,
+ 0x02, 0xB9, 0xBE, 0xCA, 0x36,
+ 0x07, 0x3E, 0xEC, 0x50, 0xCE,
+ 0x06, 0xAE, 0x26, 0x26, 0x8B,
+ 0x02, 0xC2, 0x5D, 0xAC, 0x36,
+ 0x0E, 0xE4, 0xD0, 0xAF, 0xBF,
+ 0x04, 0x96, 0xFE, 0x9A, 0x99,
+ 0x0C, 0xC7, 0xD3, 0xA5, 0xE0,
+ 0x0E, 0x3A, 0x4B, 0x38, 0x7D,
+ 0x08, 0xEB, 0xCE, 0xC1, 0xAB,
+ 0x00, 0xA0, 0x13, 0xBC, 0x9B,
+ 0x0D, 0xCE, 0xEF, 0xD7, 0x58,
+ 0x01, 0x9C, 0x2D, 0x60, 0xC1,
+ 0x0F, 0x0F, 0xF8, 0x3D, 0xF1,
+ 0x0B, 0xA3, 0xB4, 0xEF, 0x9E,
+ 0x05, 0xDE, 0x09, 0x10, 0x6D,
+ 0x0C, 0x4C, 0x44, 0x02, 0x11,
+ 0x04, 0xE5, 0x5A, 0x6A, 0x07,
+ 0x02, 0xA1, 0x60, 0x7E, 0xE9,
+ 0x01, 0xF8, 0x55, 0x33, 0x39,
+ 0x00, 0xA3, 0x54, 0xBA, 0x15,
+ 0x09, 0x96, 0x04, 0x7B, 0x9A,
+ 0x0A, 0xDF, 0xD1, 0x97, 0xEE,
+ 0x0B, 0x20, 0x77, 0x77, 0x03,
+ 0x01, 0x27, 0xD2, 0xE2, 0x4A,
+ 0x00, 0x5E, 0x5B, 0xA7, 0x9E,
+ 0x0F, 0xF0, 0x79, 0xE4, 0x6C,
+ 0x0B, 0x29, 0x9B, 0x3C, 0xF8,
+ 0x0D, 0x52, 0x1B, 0x9A, 0xB0,
+ 0x02, 0x48, 0x0C, 0xA3, 0x7E,
+ 0x0A, 0xB0, 0xDE, 0x1B, 0x91,
+ 0x02, 0xB4, 0xFE, 0x90, 0xD1,
+ 0x0E, 0x68, 0x33, 0x03, 0x1D,
+ 0x0C, 0x57, 0xF0, 0x58, 0x96,
+ 0x0C, 0xF1, 0xF7, 0x41, 0xAD,
+ 0x0B, 0x05, 0xAF, 0xBA, 0x81,
+ 0x0A, 0xF2, 0xEE, 0x37, 0xB8,
+ 0x0F, 0x5D, 0x44, 0xB6, 0x70,
+ 0x01, 0xB3, 0x3F, 0xFC, 0x36,
+ 0x00, 0xF7, 0xC7, 0xCC, 0x82,
+ 0x03, 0xB4, 0x79, 0xF3, 0x62,
+ 0x0C, 0x71, 0x37, 0x73, 0xB1,
+ 0x0C, 0x09, 0xC4, 0xD3, 0x88,
+ 0x09, 0xBD, 0x37, 0x22, 0x85,
+ 0x0B, 0xFB, 0x24, 0xB1, 0xE4,
+ 0x0C, 0xCC, 0x06, 0x32, 0x8D,
+ 0x0F, 0x98, 0x31, 0xD6, 0x59,
+ 0x0F, 0xEE, 0xDB, 0x5B, 0x7F,
+ 0x0B, 0x5F, 0x57, 0x02, 0x95,
+ 0x05, 0xDC, 0x0C, 0x70, 0x94,
+ 0x06, 0x88, 0x91, 0x61, 0x66,
+ 0x0D, 0x05, 0xF9, 0xFF, 0xC1,
+ 0x04, 0x09, 0x18, 0x84, 0xA7,
+ 0x04, 0xF3, 0xA6, 0x85, 0x41,
+ 0x0F, 0x6B, 0x62, 0xA2, 0x3D,
+ 0x09, 0x0C, 0xC7, 0x26, 0xC3,
+ 0x03, 0xC8, 0xA7, 0x0A, 0x13,
+ 0x0E, 0x49, 0x6D, 0xCD, 0xA3,
+ 0x04, 0x0D, 0xEA, 0x1A, 0x42,
+ 0x0A, 0xE1, 0x1D, 0xB7, 0x3C,
+ 0x0D, 0x06, 0xB4, 0xEC, 0x16,
+ 0x02, 0xAA, 0x76, 0xEB, 0xC2,
+ 0x04, 0x1D, 0x73, 0xFD, 0x68,
+ 0x02, 0x19, 0xC0, 0xF4, 0x52,
+ 0x02, 0xF1, 0x7E, 0xC3, 0xC2,
+ 0x0E, 0xB2, 0xE9, 0x42, 0xD1,
+ 0x0E, 0x6B, 0x6A, 0x91, 0x06,
+ 0x0F, 0xC4, 0x94, 0x40, 0x01,
+ 0x08, 0x4E, 0x57, 0x86, 0xF4,
+ 0x00, 0x8A, 0x61, 0xA7, 0xE5,
+ 0x0E, 0xDE, 0x09, 0x93, 0x2D,
+ 0x08, 0xCA, 0x36, 0xBD, 0x3D,
+ 0x0B, 0x59, 0x26, 0x4F, 0xB3,
+ 0x01, 0x6C, 0x4F, 0xED, 0x60,
+ 0x08, 0x0A, 0x27, 0xD7, 0x79,
+ 0x05, 0xD3, 0xAE, 0xEA, 0x20,
+ 0x08, 0x07, 0x3C, 0x1A, 0x1D,
+ 0x0D, 0xFF, 0x44, 0xFE, 0x27,
+ 0x04, 0x12, 0x9F, 0xA3, 0xCF,
+ 0x0B, 0x15, 0x23, 0x89, 0xA1,
+ 0x05, 0x88, 0xCC, 0x42, 0x39,
+ 0x00, 0xAB, 0x64, 0x29, 0xB0,
+ 0x04, 0x2B, 0x4F, 0xDB, 0x97,
+ 0x0F, 0x26, 0xA4, 0x62, 0x85,
+ 0x08, 0x69, 0x3C, 0xC5, 0x87,
+ 0x0E, 0xCE, 0x9F, 0x74, 0x07,
+ 0x07, 0xB1, 0xD4, 0xFA, 0xB5,
+ 0x0F, 0x2D, 0xDB, 0x60, 0x82,
+ 0x08, 0xF4, 0x56, 0x08, 0x7A,
+ 0x07, 0xDA, 0xD1, 0xFB, 0xC0,
+ 0x07, 0x8F, 0x9C, 0x5C, 0x08,
+ 0x0C, 0xBA, 0xA7, 0x9F, 0x76,
+ 0x06, 0x47, 0x5F, 0x57, 0x1A,
+ 0x01, 0x00, 0x8E, 0x65, 0xE7,
+ 0x06, 0x1B, 0xD1, 0x76, 0x22,
+ 0x04, 0x9F, 0xBA, 0x47, 0xBE,
+ 0x0F, 0x4C, 0xC0, 0x65, 0x1B,
+ 0x02, 0x7E, 0x2B, 0x1D, 0x65,
+ 0x0E, 0x5E, 0x6A, 0x35, 0xB7,
+ 0x00, 0xB5, 0xF5, 0x50, 0x29,
+ 0x0E, 0x5D, 0xC0, 0xE3, 0x43,
+ 0x07, 0xA8, 0xCB, 0x0E, 0x1E,
+ 0x06, 0x68, 0x77, 0x81, 0xB6,
+ 0x02, 0xF8, 0xF4, 0x90, 0x43,
+ 0x06, 0x8F, 0x3C, 0x6A, 0x1E,
+ 0x0E, 0x36, 0xAE, 0x20, 0x11,
+ 0x0D, 0x09, 0x41, 0x72, 0xB1,
+ 0x07, 0xA6, 0xE4, 0x50, 0xAD,
+ 0x0D, 0x64, 0x96, 0xFA, 0x9A,
+ 0x05, 0x81, 0x64, 0xD1, 0xB8,
+ 0x0D, 0x66, 0xB8, 0xCB, 0x3C,
+ 0x01, 0xD0, 0x2F, 0xAE, 0xC8,
+ 0x0B, 0xEA, 0xA2, 0x56, 0xB6,
+ 0x00, 0x03, 0x4F, 0x13, 0xD7,
+ 0x0A, 0xA3, 0x1D, 0xAF, 0x6C,
+ 0x0C, 0xEF, 0x9D, 0xB8, 0x20,
+ 0x0D, 0x73, 0x33, 0x54, 0xE5,
+ 0x05, 0xFE, 0xA4, 0x29, 0x1C,
+ 0x01, 0x5D, 0xC9, 0xC4, 0x1F,
+ 0x0D, 0x84, 0xA1, 0xD8, 0x66,
+ 0x0D, 0xC8, 0xA1, 0x5A, 0xB6,
+ 0x09, 0x2D, 0xFB, 0x31, 0x39,
+ 0x01, 0x8C, 0xA1, 0x4F, 0xF0,
+ 0x04, 0x75, 0x16, 0x74, 0x3B,
+ 0x0C, 0xD6, 0x9A, 0x82, 0xDE,
+ 0x09, 0x41, 0x05, 0x79, 0x6A,
+ 0x08, 0x1F, 0xA6, 0x2E, 0xA2,
+ 0x08, 0xBA, 0xDF, 0x59, 0xA1,
+ 0x02, 0x1E, 0x73, 0x3B, 0xFF,
+ 0x0E, 0x41, 0x29, 0xDA, 0x3C,
+ 0x0B, 0xB1, 0x52, 0x3E, 0xDA,
+ 0x00, 0x98, 0x88, 0x04, 0x23,
+ 0x09, 0xBA, 0x30, 0xDE, 0x9B,
+ 0x0D, 0x43, 0x28, 0xBD, 0x8F,
+ 0x00, 0x74, 0x0E, 0x66, 0x03,
+ 0x09, 0x46, 0x95, 0xF4, 0x58,
+ 0x03, 0xAC, 0x53, 0xF3, 0x4B,
+ 0x01, 0xBB, 0x6A, 0x6F, 0xA3,
+ 0x0D, 0x4B, 0x6E, 0x6E, 0x1A,
+ 0x01, 0xC9, 0x1D, 0x4D, 0x34,
+ 0x08, 0xBD, 0xB1, 0x43, 0xBC,
+ 0x07, 0xE0, 0x71, 0xC9, 0x46,
+ 0x09, 0xD5, 0xF4, 0x70, 0x01,
+ 0x0A, 0xA4, 0x73, 0xB5, 0x71,
+ 0x09, 0x90, 0xAA, 0x4A, 0x99,
+ 0x09, 0x61, 0x36, 0x37, 0x2B,
+ 0x0D, 0x69, 0xF9, 0x24, 0xB7,
+ 0x0C, 0xD4, 0xCE, 0x0F, 0x38,
+ 0x01, 0x2F, 0x71, 0x31, 0xDF,
+ 0x01, 0xE3, 0xEC, 0x83, 0x5B,
+ 0x0E, 0x0B, 0x5D, 0x5C, 0x48,
+ 0x09, 0xE4, 0x5D, 0x0E, 0x69,
+ 0x02, 0xBB, 0x52, 0x8C, 0xD2,
+ 0x07, 0x67, 0x5A, 0xF8, 0x4B,
+ 0x0D, 0xEE, 0x6A, 0x19, 0x31,
+ 0x0B, 0x68, 0x9D, 0x66, 0xCC,
+ 0x04, 0xE1, 0x39, 0xE2, 0x66,
+ 0x0C, 0x12, 0xDC, 0x27, 0x2F,
+ 0x08, 0xFE, 0xA0, 0x45, 0xFB,
+ 0x0F, 0xF7, 0xCA, 0xEF, 0xD4,
+ 0x05, 0x99, 0xA9, 0x65, 0x07,
+ 0x0D, 0xD1, 0x63, 0xAA, 0xB3,
+ 0x0B, 0xD7, 0x06, 0xB6, 0xF0,
+ 0x06, 0xCE, 0x28, 0x05, 0x2B,
+ 0x07, 0xB8, 0x55, 0xA9, 0x34,
+ 0x05, 0x12, 0x1B, 0xC6, 0xFC,
+ 0x06, 0x8C, 0x71, 0x7F, 0x83,
+ 0x04, 0x95, 0xB3, 0x89, 0x4E,
+ 0x0D, 0xE7, 0x40, 0x0A, 0x98,
+ 0x06, 0xD5, 0xC6, 0xC4, 0x40,
+ 0x01, 0x18, 0x4C, 0x51, 0x8C,
+ 0x08, 0xDC, 0xC1, 0x95, 0xAE,
+ 0x00, 0x92, 0x4D, 0xD3, 0x4E,
+ 0x0C, 0x18, 0xCA, 0x34, 0xB7,
+ 0x09, 0x45, 0x25, 0xE7, 0x8F,
+ 0x06, 0x0D, 0x41, 0x98, 0x25,
+ 0x0D, 0x54, 0x0A, 0x53, 0xAC,
+ 0x00, 0x39, 0xD0, 0x78, 0x50,
+ 0x04, 0x33, 0x85, 0x63, 0x10,
+ 0x0D, 0xE1, 0xFF, 0x89, 0x74,
+ 0x02, 0x65, 0x92, 0x9D, 0xBE,
+ 0x03, 0x9B, 0x63, 0x63, 0x84,
+ 0x0B, 0x89, 0x88, 0x80, 0xB3,
+ 0x08, 0x9C, 0x2B, 0x0F, 0x69,
+ 0x03, 0x14, 0xA2, 0x4F, 0xF9,
+ 0x05, 0xBF, 0x26, 0xA6, 0x51,
+ 0x0D, 0x94, 0x25, 0x7F, 0x4C,
+ 0x02, 0xB3, 0x49, 0x9F, 0x69,
+ 0x0A, 0xDB, 0xB0, 0xDA, 0xFA,
+ 0x08, 0x14, 0xAD, 0x2C, 0x52,
+ 0x03, 0xA4, 0xF5, 0xD6, 0xFB,
+ 0x0C, 0x88, 0xDC, 0x34, 0x3B,
+ 0x03, 0xFE, 0x0D, 0x7C, 0x5C,
+ 0x00, 0x25, 0x3B, 0xC9, 0xD5,
+ 0x0E, 0x2A, 0xC5, 0x15, 0x5D,
+ 0x03, 0x11, 0x02, 0x84, 0x61,
+ 0x05, 0x57, 0x9B, 0xD3, 0x6F,
+ 0x04, 0x56, 0xE9, 0xF2, 0x42,
+ 0x0E, 0x4D, 0x4C, 0xC0, 0x92,
+ 0x00, 0xD2, 0x7C, 0x89, 0x9D,
+ 0x0F, 0x9E, 0xAF, 0xE8, 0x15,
+ 0x07, 0x60, 0xB5, 0xF5, 0x61,
+ 0x05, 0x5E, 0x12, 0x40, 0xEE,
+ 0x05, 0xEA, 0x2F, 0x50, 0xD3,
+ 0x0C, 0x35, 0x44, 0x77, 0x87,
+ 0x0C, 0x1E, 0xFA, 0xB9, 0x90,
+ 0x06, 0x76, 0xF9, 0x7E, 0x65,
+ 0x0C, 0x8E, 0x36, 0xAE, 0x26,
+ 0x0A, 0x01, 0x88, 0xC0, 0xF2,
+ 0x06, 0x37, 0x30, 0xE4, 0x70,
+ 0x01, 0x3F, 0x0C, 0xD6, 0xF5,
+ 0x0A, 0x99, 0x80, 0xC6, 0x5B,
+ 0x09, 0xFD, 0x59, 0xFA, 0xC2,
+ 0x04, 0x85, 0x70, 0xE7, 0x6E,
+ 0x01, 0x6B, 0xEA, 0xA2, 0xE6,
+ 0x0C, 0xBB, 0x81, 0xCC, 0x26,
+ 0x0B, 0x51, 0x54, 0x5C, 0x26,
+ 0x00, 0xD1, 0x5E, 0xCF, 0xE5,
+ 0x05, 0xF1, 0xF3, 0x2D, 0xD4,
+ 0x05, 0x1C, 0x7C, 0xD5, 0xA9,
+ 0x04, 0x6F, 0x5C, 0x4C, 0x84,
+ 0x02, 0x11, 0x84, 0x61, 0x52,
+ 0x0F, 0x4D, 0xC8, 0x25, 0x50,
+ 0x0E, 0xC9, 0x2D, 0xF9, 0x3F,
+ 0x09, 0x01, 0x11, 0xA3, 0x4F,
+ 0x0A, 0x2C, 0x75, 0x9A, 0x72,
+ 0x0B, 0xA0, 0xD4, 0xDD, 0x82,
+ 0x0B, 0xD5, 0x0C, 0xA5, 0x70,
+ 0x07, 0x03, 0x9F, 0x27, 0xAE,
+ 0x02, 0x43, 0x38, 0xD2, 0x53,
+ 0x01, 0xDE, 0x1D, 0xFC, 0xB1,
+ 0x0E, 0xE6, 0x31, 0x29, 0xD3,
+ 0x00, 0xF8, 0x35, 0x12, 0x25,
+ 0x0A, 0xB8, 0x9A, 0x88, 0x04,
+ 0x0F, 0x08, 0x6D, 0x30, 0xC3,
+ 0x09, 0x91, 0x42, 0xB6, 0x7D,
+ 0x02, 0x5B, 0xF2, 0x6A, 0x66,
+ 0x03, 0x69, 0xC6, 0x97, 0xF4,
+ 0x04, 0xEB, 0x79, 0x71, 0xFE,
+ 0x01, 0xAD, 0xB9, 0x01, 0xA5,
+ 0x01, 0x03, 0xCB, 0x72, 0xEE,
+ 0x0C, 0xB8, 0xCE, 0xDD, 0x44,
+ 0x0A, 0x70, 0x30, 0x73, 0x4A,
+ 0x0C, 0x3F, 0xE2, 0xF7, 0xC5,
+ 0x0C, 0x82, 0x51, 0xB0, 0x73,
+ 0x0F, 0x62, 0xF3, 0xB1, 0xBC,
+ 0x0D, 0x31, 0x82, 0x48, 0x5B,
+ 0x0F, 0x95, 0x61, 0x3D, 0x3F,
+ 0x09, 0x07, 0x15, 0x7B, 0x24,
+ 0x07, 0xE4, 0xD6, 0xC8, 0x3D,
+ 0x02, 0x8D, 0x2F, 0x66, 0x7B,
+ 0x06, 0x59, 0xE1, 0xEE, 0x83,
+ 0x07, 0x76, 0x40, 0xDF, 0x5C,
+ 0x02, 0x95, 0xE7, 0xDC, 0x0E,
+ 0x04, 0x9E, 0xBA, 0x89, 0x0C,
+ 0x01, 0x7B, 0x64, 0x85, 0xC2,
+ 0x0F, 0xC1, 0xED, 0x8B, 0x99,
+ 0x08, 0xA7, 0x32, 0x33, 0xEF,
+ 0x09, 0x49, 0x63, 0x6A, 0xFF,
+ 0x0E, 0x21, 0x9A, 0xCC, 0x3A,
+ 0x0A, 0xC3, 0x7A, 0xEE, 0xB4,
+ 0x0A, 0xD3, 0xF4, 0x4B, 0xDD,
+ 0x02, 0x2A, 0x8D, 0x8E, 0xD6,
+ 0x0A, 0x5F, 0xD3, 0x63, 0xAC,
+ 0x03, 0xC7, 0xDD, 0x88, 0xFC,
+ 0x0C, 0x16, 0xBE, 0x24, 0x0F,
+ 0x0B, 0xCB, 0xB8, 0x1C, 0xE9,
+ 0x0D, 0x75, 0x10, 0x1B, 0x70,
+ 0x06, 0xCD, 0x0C, 0xF0, 0xFF,
+ 0x0F, 0xDE, 0x97, 0x32, 0x14,
+ 0x02, 0xD1, 0x90, 0xCD, 0x83,
+ 0x01, 0xC6, 0xD5, 0xC4, 0x35,
+ 0x08, 0x21, 0x9A, 0x4C, 0xD5,
+ 0x0C, 0xF4, 0x69, 0x0A, 0x35,
+ 0x07, 0xEC, 0x92, 0xDF, 0xA2,
+ 0x0F, 0x30, 0x46, 0x8A, 0x3D,
+ 0x03, 0xA3, 0x4C, 0xD9, 0x7A,
+ 0x04, 0x39, 0x21, 0x6D, 0xD8,
+ 0x0D, 0x7D, 0x56, 0x0A, 0x57,
+ 0x0B, 0x70, 0x4E, 0xD2, 0x73,
+ 0x02, 0x24, 0x33, 0x85, 0xED,
+ 0x02, 0x1D, 0x61, 0xFD, 0x87,
+ 0x04, 0x2E, 0xDE, 0x92, 0xBD,
+ 0x0F, 0xCF, 0xF0, 0xD5, 0x2A,
+ 0x0D, 0xAB, 0x89, 0x88, 0x8A,
+ 0x0E, 0x30, 0xC2, 0x2B, 0x04,
+ 0x01, 0x41, 0xB4, 0xA7, 0x4F,
+ 0x09, 0x25, 0xBF, 0x24, 0x12,
+ 0x00, 0x31, 0x94, 0x6B, 0xCA,
+ 0x09, 0x8E, 0xC4, 0x4F, 0x16,
+ 0x08, 0x1B, 0x69, 0xB0, 0x47,
+ 0x02, 0xA8, 0x94, 0xA2, 0x6E,
+ 0x08, 0x71, 0xA4, 0xF8, 0xD4,
+ 0x00, 0x65, 0x0B, 0xDB, 0xF4,
+ 0x0B, 0xC3, 0xFE, 0x8B, 0x76,
+ 0x0C, 0xC8, 0x25, 0xBF, 0x4D,
+ 0x0F, 0x36, 0x2A, 0x47, 0x11,
+ 0x0D, 0x13, 0xD0, 0x80, 0x80,
+ 0x01, 0x39, 0x56, 0x17, 0xD9,
+ 0x02, 0x28, 0x54, 0x9F, 0xB2,
+ 0x07, 0x7E, 0x17, 0x8C, 0xC9,
+ 0x03, 0x28, 0xD0, 0xFE, 0x8B,
+ 0x0D, 0x65, 0x9E, 0xB2, 0x62,
+ 0x05, 0xB7, 0x62, 0xB9, 0x3F,
+ 0x0C, 0x28, 0xDF, 0xDD, 0xDD,
+ 0x07, 0x49, 0xE9, 0xA8, 0x90,
+ 0x02, 0x17, 0xFA, 0xE8, 0x7E,
+ 0x0B, 0xFC, 0x45, 0xB8, 0xB0,
+ 0x08, 0x4A, 0xF6, 0x8D, 0xBE,
+ 0x04, 0xD4, 0x2C, 0x34, 0x2E,
+ 0x0A, 0x22, 0x55, 0xC8, 0xFB,
+ 0x0E, 0xAD, 0x7A, 0x26, 0xDC,
+ 0x0B, 0x28, 0x1B, 0x64, 0x6D,
+ 0x00, 0x9A, 0xE6, 0xC0, 0xCF,
+ 0x01, 0xA5, 0xFF, 0x16, 0x3A,
+ 0x0B, 0x3C, 0x7D, 0x54, 0x61,
+ 0x0E, 0xC1, 0x69, 0xEE, 0xEA,
+ 0x0E, 0xBD, 0x3D, 0x81, 0xD3,
+ 0x0F, 0xD7, 0x1D, 0xA1, 0x95,
+ 0x0F, 0x6C, 0xD2, 0xEF, 0xCB,
+ 0x08, 0x3D, 0xF1, 0xF3, 0x20,
+ 0x0C, 0x6D, 0xBE, 0xF8, 0xD8,
+ 0x01, 0x1C, 0xED, 0x5E, 0xCC,
+ 0x04, 0x02, 0x11, 0x86, 0x57,
+ 0x04, 0x6F, 0x18, 0xC8, 0xA8,
+ 0x0A, 0x7E, 0xCA, 0xA9, 0xB3,
+ 0x05, 0x33, 0x03, 0x8A, 0xE1,
+ 0x07, 0xFB, 0x0C, 0x75, 0x92,
+ 0x08, 0xFB, 0xA0, 0xD6, 0xDD,
+ 0x02, 0xD7, 0xD5, 0x40, 0xA5,
+ 0x05, 0x77, 0x3C, 0x5D, 0x23,
+ 0x0E, 0xA2, 0x43, 0x38, 0xE4,
+ 0x09, 0xA1, 0xDE, 0x11, 0x72,
+ 0x07, 0xE3, 0x79, 0x81, 0x2D,
+ 0x06, 0x3C, 0x74, 0x31, 0x5B,
+ 0x08, 0xDA, 0xBA, 0x98, 0x88,
+ 0x04, 0x23, 0x09, 0xCA, 0xB0,
+ 0x0E, 0x9B, 0x91, 0x40, 0x36,
+ 0x01, 0x90, 0x14, 0x32, 0x6E,
+ 0x0A, 0x03, 0x94, 0x86, 0x9E,
+ 0x04, 0x58, 0xEB, 0x2C, 0xF1,
+ 0x07, 0x41, 0xAD, 0xBB, 0x05,
+ 0x0F, 0xAA, 0x83, 0x48, 0x70,
+ 0x02, 0x07, 0x77, 0x0F, 0x54,
+ 0x08, 0x87, 0xDC, 0x3D, 0xAE,
+ 0x08, 0x3E, 0xBE, 0x60, 0xF7,
+ 0x0E, 0x4E, 0x03, 0xD3, 0xB4,
+ 0x05, 0xF3, 0xFD, 0x64, 0x75,
+ 0x09, 0x70, 0xB1, 0x10, 0x15,
+ 0x06, 0x13, 0x97, 0x67, 0xBF,
+ 0x07, 0x22, 0x87, 0x6D, 0xF1,
+ 0x08, 0xB7, 0x6F, 0xD4, 0xC5,
+ 0x0A, 0x33, 0x08, 0x2F, 0xF5,
+ 0x01, 0xD6, 0x5B, 0xE3, 0xEE,
+ 0x0F, 0x5A, 0xD3, 0x0B, 0x42,
+ 0x07, 0x02, 0x95, 0x67, 0x5C,
+ 0x0E, 0x74, 0x9E, 0xBA, 0x89,
+ 0x0C, 0x91, 0xFB, 0x66, 0x87,
+ 0x08, 0x7F, 0xC1, 0xEF, 0x8B,
+ 0x09, 0x04, 0xA5, 0x6C, 0xF9,
+ 0x0D, 0x47, 0xC9, 0x63, 0x6A,
+ 0x09, 0xE0, 0xA1, 0x90, 0x8C,
+ 0x0B, 0x28, 0x56, 0x7A, 0x6A,
+ 0x05, 0x0A, 0xD1, 0xF6, 0x49,
+ 0x0F, 0xC9, 0xA8, 0x98, 0x0C,
+ 0x05, 0x1A, 0x5D, 0xD5, 0x69,
+ 0x0C, 0xB3, 0xC7, 0xD9, 0x04,
+ 0x0A, 0xEC, 0x8F, 0x3E, 0xA3,
+ 0x09, 0x2A, 0x4E, 0xB8, 0x01,
+ 0x09, 0x3D, 0x77, 0x12, 0x19,
+ 0x0E, 0xF7, 0x68, 0x0E, 0xED,
+ 0x0D, 0x83, 0xDF, 0x95, 0xB2,
+ 0x09, 0x4E, 0xD1, 0xE7, 0xCD,
+ 0x0A, 0xE1, 0x46, 0xD5, 0xC4,
+ 0x04, 0x40, 0x21, 0x18, 0x4E,
+ 0x05, 0x86, 0xF6, 0xD8, 0x80,
+ 0x0E, 0x25, 0x6D, 0x12, 0xDF,
+ 0x08, 0xD1, 0xB1, 0x98, 0xCA,
+ 0x08, 0xBF, 0x2C, 0x87, 0x50,
+ 0x0B, 0x8F, 0x45, 0xCD, 0x69,
+ 0x08, 0x2D, 0x7F, 0x54, 0x0A,
+ 0x07, 0x97, 0x72, 0x3D, 0xD8,
+ 0x0A, 0xEA, 0x24, 0x37, 0x87,
+ 0x01, 0x9A, 0x5D, 0xE1, 0xFB,
+ 0x0B, 0xBE, 0x8E, 0x64, 0x16,
+ 0x01, 0xA2, 0x4B, 0x5B, 0x08,
+ 0x0F, 0x8D, 0xFA, 0x89, 0x81,
+ 0x08, 0x42, 0xB0, 0x9C, 0x2B,
+ 0x0F, 0xE9, 0xB9, 0x14, 0xAB,
+ 0x03, 0xD9, 0xB7, 0xFF, 0x3B,
+ 0x06, 0x11, 0xB1, 0x94, 0x69,
+ 0x03, 0x45, 0x9D, 0xF2, 0xC7,
+ 0x04, 0xF6, 0x64, 0x5B, 0xB0,
+ 0x06, 0xFB, 0x28, 0xD4, 0xB2,
+ 0x07, 0x60, 0x93, 0xA8, 0xF5,
+ 0x0D, 0xCE, 0x87, 0x0B, 0x1B,
+ 0x08, 0x3A, 0x43, 0xBE, 0x12,
+ 0x0C, 0x5C, 0xC8, 0x25, 0x3B,
+ 0x0E, 0x1E, 0xD4, 0x2A, 0x87,
+ 0x0B, 0x57, 0x11, 0x15, 0x0A,
+ 0x08, 0x60, 0xB6, 0x56, 0x06,
+ 0x0F, 0x72, 0x79, 0x56, 0x96,
+ 0x02, 0x4B, 0x7C, 0x4D, 0x4C,
+ 0x00, 0x63, 0x28, 0xD2, 0xFE,
+ 0x03, 0x1D, 0xE7, 0x9C, 0xBE,
+ 0x04, 0x35, 0xE4, 0xE0, 0xBC,
+ 0x0D, 0x50, 0x2B, 0x5E, 0x5D,
+ 0x0C, 0xE6, 0x89, 0xEB, 0x91,
+ 0x09, 0xCE, 0xD7, 0xB4, 0xE8,
+ 0x0F, 0x05, 0xBC, 0x10, 0xB8,
+ 0x03, 0x90, 0xB1, 0x76, 0x87,
+ 0x07, 0x6D, 0x94, 0x82, 0x36,
+ 0x07, 0xA6, 0xC2, 0x01, 0x08,
+ 0x02, 0x72, 0xAC, 0x33, 0x2C,
+ 0x0C, 0x50, 0xAF, 0x3F, 0x64,
+ 0x0A, 0xFC, 0xCB, 0xD9, 0x89,
+ 0x0D, 0xD3, 0x14, 0xF9, 0xED,
+ 0x0A, 0xCB, 0x3E, 0x7D, 0xD0,
+ 0x07, 0x6E, 0x92, 0xAB, 0xE3,
+ 0x00, 0x52, 0xBE, 0xB7, 0x0B,
+ 0x02, 0x92, 0x57, 0x91, 0x3C,
+ 0x05, 0xAF, 0x8C, 0xDC, 0xEF,
+ 0x06, 0x7E, 0xDD, 0xF1, 0xB3,
+ 0x00, 0x94, 0xED, 0x1E, 0x7C,
+ 0x08, 0xA9, 0x1C, 0x69, 0xA7,
+ 0x00, 0x45, 0x91, 0xD1, 0x99,
+ 0x09, 0x58, 0x1E, 0x8D, 0xC1,
+ 0x0D, 0x5B, 0xBE, 0xC9, 0x29,
+ 0x02, 0xB7, 0xE2, 0x81, 0x8C,
+ 0x0F, 0x4B, 0xAE, 0x2C, 0x7C,
+ 0x06, 0x78, 0xF9, 0xA0, 0xD6,
+ 0x0D, 0x82, 0xD5, 0xD1, 0x4A,
+ 0x09, 0x79, 0x28, 0xC3, 0x94,
+ 0x0B, 0xAF, 0x08, 0x43, 0x25,
+ 0x05, 0x5B, 0x20, 0x5E, 0x1F,
+ 0x0B, 0xF9, 0x63, 0x66, 0x41,
+ 0x05, 0xDB, 0xB8, 0x79, 0xAC,
+ 0x02, 0x38, 0xDA, 0xB8, 0x98,
+ 0x0A, 0x04, 0x23, 0x0F, 0xCA,
+ 0x00, 0xDE, 0x9B, 0x91, 0x42,
+ 0x04, 0x8D, 0x12, 0x5B, 0xF2,
+ 0x06, 0x67, 0x82, 0xD9, 0x5B,
+ 0x07, 0xF4, 0x58, 0xEB, 0x2C,
+ 0x09, 0x77, 0xE1, 0xAD, 0x7B,
+ 0x0F, 0xAE, 0xA1, 0x01, 0x0A,
+ 0x02, 0xEE, 0x07, 0x3E, 0x7D,
+ 0x07, 0x45, 0x95, 0xF0, 0xBC,
+ 0x0F, 0x43, 0xC2, 0x7F, 0xE9,
+ 0x07, 0xC5, 0xCE, 0x82, 0x53,
+ 0x0D, 0xF9, 0x13, 0x6E, 0xA4,
+ 0x08, 0x34, 0x91, 0x33, 0x90,
+ 0x00, 0xC0, 0xF3, 0x99, 0x61,
+ 0x0D, 0x37, 0x22, 0x00, 0xA3,
+ 0x01, 0x25, 0xA5, 0x64, 0xF4,
+ 0x04, 0x86, 0x90, 0x8F, 0xAF,
+ 0x01, 0xB1, 0x16, 0x5D, 0xE3,
+ 0x02, 0x81, 0xC7, 0x76, 0x0F,
+ 0x03, 0x55, 0x51, 0x55, 0xF8,
+ 0x07, 0x88, 0x4E, 0x1E, 0xBA,
+ 0x09, 0x0C, 0xE1, 0x7F, 0x54,
+ 0x0D, 0x79, 0x6C, 0xC1, 0xEE,
+ 0x0B, 0x99, 0x06, 0xA3, 0x62,
+ 0x03, 0xE6, 0xC5, 0x48, 0xE3,
+ 0x0A, 0xE2, 0x62, 0x20, 0x10,
+ 0x00, 0x26, 0xB7, 0xC3, 0x67,
+ 0x02, 0x45, 0x6B, 0x13, 0xFF,
+ 0x02, 0xE9, 0xB7, 0x29, 0x98,
+ 0x0C, 0x65, 0x18, 0x5F, 0xD1,
+ 0x0B, 0x2C, 0x11, 0xC3, 0xD7,
+ 0x06, 0xB6, 0xEC, 0x10, 0x84,
+ 0x06, 0x07, 0x2B, 0xCB, 0x8A,
+ 0x00, 0xE8, 0x40, 0x75, 0x0F,
+ 0x05, 0xC2, 0x82, 0x8D, 0x07,
+ 0x0B, 0x7B, 0x45, 0x5F, 0x17,
+ 0x02, 0x09, 0x4E, 0xDF, 0xE7,
+ 0x0D, 0x8A, 0x91, 0xC8, 0xD5,
+ 0x08, 0xC4, 0x40, 0x21, 0x1E,
+ 0x02, 0x45, 0x86, 0xF4, 0xDB,
+ 0x06, 0x14, 0xDB, 0xEC, 0x8F,
+ 0x03, 0x93, 0xAB, 0x30, 0x11,
+ 0x01, 0xB3, 0xF0, 0xA2, 0xC7,
+ 0x05, 0x66, 0x14, 0x7A, 0x10,
+ 0x0D, 0xD8, 0x2D, 0x7D, 0x54,
+ 0x0A, 0x57, 0x97, 0x70, 0xCE,
+ 0x0E, 0x7B, 0x03, 0xE4, 0x2E,
+ 0x0E, 0x6F, 0x15, 0x1D, 0xE1,
+ 0x03, 0x07, 0xBB, 0x2E, 0x6D,
+ 0x02, 0x9D, 0xA1, 0xC3, 0x8A,
+ 0x09, 0x23, 0xCD, 0xAB, 0xBE,
+ 0x00, 0x03, 0x62, 0x32, 0x1C,
+ 0x03, 0x07, 0xC9, 0xB4, 0xD4,
+ 0x01, 0x4E, 0xE2, 0xA5, 0x9F,
+ 0x06, 0xA6, 0x61, 0x35, 0xDE,
+ 0x01, 0x7E, 0xC5, 0x82, 0xB2,
+ 0x05, 0x1E, 0x9B, 0x9A, 0xFB,
+ 0x0C, 0x5A, 0xFA, 0xA8, 0x1D,
+ 0x0F, 0x2E, 0xE0, 0xF3, 0xA4,
+ 0x0D, 0xD4, 0xC8, 0xE5, 0x8B,
+ 0x03, 0xB4, 0x9B, 0x41, 0x7E,
+ 0x06, 0x7C, 0x9C, 0x4A, 0xA5,
+ 0x02, 0xC7, 0x7F, 0xB4, 0xAA,
+ 0x07, 0x1B, 0x57, 0x91, 0xAA,
+ 0x00, 0x84, 0x61, 0xBB, 0xEC,
+ 0x0B, 0xD3, 0x72, 0xAA, 0xEF,
+ 0x0F, 0xB2, 0x4B, 0xFC, 0xF5,
+ 0x0C, 0xC0, 0x63, 0xAA, 0x65,
+ 0x0E, 0x8B, 0x1D, 0xE7, 0x28,
+ 0x0E, 0xE8, 0x35, 0x35, 0xD5,
+ 0x05, 0xF5, 0x50, 0xAB, 0xEA,
+ 0x0D, 0xC0, 0xE7, 0xCB, 0x58,
+ 0x08, 0x90, 0xCE, 0x95, 0x04,
+ 0x08, 0x77, 0x87, 0x7E, 0xAF,
+ 0x08, 0xB9, 0x90, 0xC8, 0xC6,
+ 0x0F, 0x3E, 0x6C, 0xD6, 0x08,
+ 0x06, 0xAE, 0x26, 0xA0, 0x86,
+ 0x08, 0xC2, 0x70, 0xAE, 0xB3,
+ 0x06, 0xE4, 0x50, 0xAF, 0xBA,
+ 0x08, 0x96, 0xFC, 0x9A, 0xA7,
+ 0x0E, 0xC6, 0x51, 0xA5, 0xFD,
+ 0x09, 0xBA, 0xCB, 0x3C, 0x7D,
+ 0x0C, 0x6B, 0x6E, 0xC1, 0x62,
+ 0x0A, 0xA0, 0x50, 0xBC, 0xBB,
+ 0x01, 0xCE, 0x93, 0x51, 0x5B,
+ 0x01, 0x9C, 0x2F, 0xEA, 0x9A,
+ 0x0F, 0x0F, 0xF8, 0xBB, 0x7B,
+ 0x03, 0x20, 0x94, 0x6B, 0xD4,
+ 0x0C, 0xD8, 0xA9, 0x92, 0xA7,
+ 0x0C, 0x4C, 0x44, 0x8C, 0x9B,
+ 0x04, 0xE5, 0x58, 0xE1, 0x07,
+ 0x08, 0xA1, 0x5A, 0xF0, 0xC3,
+ 0x0D, 0xF9, 0x35, 0xBE, 0xCB,
+ 0x0C, 0xA3, 0x4B, 0x77, 0xA6,
+ 0x05, 0x96, 0x78, 0x76, 0xEA,
+ 0x06, 0xDD, 0x82, 0x5A, 0xDF,
+ 0x00, 0xA5, 0x79, 0xFB, 0xC9,
+ 0x0D, 0x27, 0xAE, 0x2E, 0xC9,
+ 0x08, 0x5E, 0xD9, 0x2D, 0x94,
+ 0x0F, 0xF0, 0x7B, 0x6E, 0xEC,
+ 0x01, 0x29, 0xDA, 0xBF, 0x73,
+ 0x01, 0x52, 0x38, 0x59, 0x72,
+ 0x08, 0x88, 0x04, 0xA0, 0x03,
+ 0x0A, 0xB0, 0xDC, 0x98, 0xDB,
+ 0x0D, 0x34, 0xFD, 0x92, 0x5B,
+ 0x02, 0x6A, 0x67, 0x03, 0x13,
+ 0x06, 0x97, 0xF6, 0x54, 0xE1,
+ 0x00, 0xF1, 0xF7, 0x41, 0xAB,
+ 0x07, 0x15, 0xAF, 0xAA, 0x86,
+ 0x06, 0xF2, 0xE6, 0x07, 0x00,
+ 0x03, 0x5D, 0x44, 0x86, 0x42,
+ 0x01, 0xB0, 0x43, 0xBC, 0x0C,
+ 0x0B, 0x76, 0x3D, 0xCC, 0x82,
+ 0x0F, 0xB5, 0x19, 0xF3, 0x50,
+ 0x08, 0x73, 0x35, 0x71, 0x02,
+ 0x0B, 0x89, 0xBE, 0x13, 0x95,
+ 0x0D, 0xBD, 0x57, 0x22, 0xB7,
+ 0x05, 0xF8, 0xE4, 0xB7, 0xD7,
+ 0x0F, 0x4D, 0xFE, 0x32, 0x8D,
+ 0x03, 0xEA, 0xA1, 0xD6, 0x6B,
+ 0x0F, 0xEC, 0x43, 0x5B, 0x45,
+ 0x00, 0xDE, 0xAD, 0x02, 0x95,
+ 0x09, 0xDE, 0x5B, 0x34, 0xAC,
+ 0x06, 0x8B, 0x4C, 0xE1, 0x48,
+ 0x0D, 0x06, 0x80, 0x7F, 0xC1,
+ 0x03, 0x8B, 0x59, 0x04, 0x95,
+ 0x04, 0xF2, 0xE6, 0xC5, 0x7B,
+ 0x08, 0xEB, 0x1A, 0x62, 0x20,
+ 0x0C, 0x8C, 0x27, 0x2A, 0xFD,
+ 0x06, 0x7E, 0x45, 0x0A, 0xD5,
+ 0x0A, 0x49, 0x2F, 0xC9, 0x9E,
+ 0x04, 0x3E, 0x65, 0x1A, 0x6D,
+ 0x0D, 0x61, 0x2C, 0xB3, 0xC3,
+ 0x01, 0x04, 0x16, 0xEC, 0x13,
+ 0x05, 0x28, 0x14, 0x2B, 0xCB,
+ 0x04, 0x1C, 0xA9, 0x3D, 0x42,
+ 0x0E, 0x2B, 0xC2, 0xF6, 0xFF,
+ 0x02, 0xF2, 0x3F, 0x83, 0xDB,
+ 0x0B, 0x30, 0xE9, 0x4E, 0xD4,
+ 0x0C, 0x4F, 0x9B, 0x91, 0xC6,
+ 0x09, 0xC4, 0x84, 0x40, 0x16,
+ 0x04, 0x7C, 0x55, 0x86, 0xC6,
+ 0x00, 0x88, 0x55, 0xA7, 0xE8,
+ 0x0E, 0xDD, 0xF3, 0x53, 0x35,
+ 0x03, 0x48, 0x25, 0xBF, 0xA2,
+ 0x0B, 0x59, 0x27, 0x8F, 0x8D,
+ 0x01, 0x5F, 0xD8, 0x2D, 0x4F,
+ 0x08, 0x0B, 0x57, 0x97, 0x74,
+ 0x05, 0xD3, 0x5A, 0xEA, 0x21,
+ 0x08, 0x07, 0xFC, 0x9A, 0x1D,
+ 0x0D, 0xFF, 0x47, 0xBE, 0x19,
+ 0x08, 0x20, 0x9D, 0xA3, 0xFD,
+ 0x07, 0x16, 0x23, 0x8D, 0xAF,
+ 0x05, 0x8B, 0xA0, 0x42, 0x35,
+ 0x07, 0x29, 0x1C, 0xE9, 0xB9,
+ 0x08, 0x2B, 0x4F, 0x99, 0x2B,
+ 0x03, 0x26, 0xA6, 0x20, 0x09,
+ 0x08, 0x6A, 0x7F, 0x45, 0xB7,
+ 0x0E, 0xCF, 0x1C, 0xF4, 0x20,
+ 0x07, 0xB0, 0x5A, 0xFA, 0x93,
+ 0x0C, 0xAF, 0xAE, 0xE0, 0x73,
+ 0x0F, 0x77, 0xCF, 0xC8, 0x67,
+ 0x0B, 0xDB, 0x34, 0x35, 0x87,
+ 0x05, 0x8D, 0x0D, 0x5F, 0xCD,
+ 0x09, 0x3B, 0x47, 0xDF, 0x38,
+ 0x06, 0x47, 0x1B, 0x17, 0x2B,
+ 0x0D, 0x02, 0x04, 0x61, 0x00,
+ 0x0A, 0x1B, 0xD0, 0xF2, 0x12,
+ 0x0A, 0x9F, 0xB2, 0x4B, 0x45,
+ 0x05, 0x4C, 0x40, 0x63, 0x28,
+ 0x09, 0x7C, 0x90, 0x9D, 0x65,
+ 0x0E, 0x3E, 0xE8, 0x3B, 0xF3,
+ 0x0B, 0x37, 0x84, 0x53, 0x2C,
+ 0x02, 0x5D, 0xC0, 0xA7, 0x47,
+ 0x07, 0xA8, 0x90, 0x8E, 0x2F,
+ 0x0A, 0x6A, 0xB7, 0x87, 0xC5,
+ 0x02, 0xF8, 0xBA, 0x10, 0x70,
+ 0x0A, 0x8F, 0x3E, 0x6C, 0x6F,
+ 0x06, 0x36, 0x2E, 0x26, 0x22,
+ 0x0A, 0x8A, 0xD9, 0xF2, 0xAC,
+ 0x07, 0xA6, 0xE4, 0x5E, 0xE9,
+ 0x04, 0xE6, 0xE7, 0xFF, 0x9F,
+ 0x05, 0x80, 0xC6, 0x11, 0xAB,
+ 0x01, 0x16, 0x3A, 0x8B, 0x04,
+ 0x01, 0xD2, 0x2B, 0x6E, 0xF8,
+ 0x07, 0xEA, 0xA3, 0xD2, 0x86,
+ 0x07, 0x81, 0xCE, 0x93, 0xEC,
+ 0x09, 0x21, 0x1C, 0x2F, 0x6C,
+ 0x0B, 0x6D, 0x14, 0x78, 0x3D,
+ 0x01, 0x73, 0x20, 0x9A, 0xA9,
+ 0x05, 0xFE, 0xA9, 0xAA, 0x19,
+ 0x01, 0x5C, 0x4C, 0x04, 0x0C,
+ 0x0D, 0x84, 0xE5, 0x18, 0x57,
+ 0x01, 0xC9, 0xA1, 0x5A, 0x47,
+ 0x05, 0x2D, 0xFA, 0xB5, 0x09,
+ 0x0D, 0x8C, 0xA3, 0x4B, 0xC1,
+ 0x04, 0x75, 0x16, 0x78, 0xFB,
+ 0x0B, 0x54, 0xC6, 0x02, 0xD7,
+ 0x05, 0x40, 0xA5, 0x77, 0x33,
+ 0x08, 0x1F, 0x56, 0xAD, 0xA7,
+ 0x0F, 0x3B, 0x5E, 0xD9, 0x95,
+ 0x02, 0x1F, 0xC7, 0xFB, 0xDA,
+ 0x0D, 0xC7, 0x2E, 0xD4, 0x21,
+ 0x05, 0xB0, 0xD2, 0x78, 0xC7,
+ 0x08, 0x98, 0x88, 0x04, 0x23,
+ 0x01, 0xCA, 0x30, 0xDE, 0x5B,
+ 0x0B, 0x43, 0x74, 0xFD, 0xB2,
+ 0x07, 0xC0, 0x6A, 0x66, 0x35,
+ 0x05, 0x46, 0xD7, 0xF4, 0x6F,
+ 0x07, 0x2E, 0x71, 0xF7, 0x79,
+ 0x01, 0xBB, 0xC5, 0xAF, 0x93,
+ 0x0A, 0xCC, 0x6B, 0xEE, 0x07,
+ 0x06, 0x4F, 0x72, 0x44, 0x9B,
+ 0x0C, 0xBC, 0x13, 0x43, 0x8A,
+ 0x03, 0xE0, 0xD7, 0x85, 0xF4,
+ 0x0E, 0x52, 0x00, 0x39, 0xC9,
+ 0x0E, 0xA4, 0xF1, 0xB5, 0x4A,
+ 0x0A, 0x96, 0x96, 0xC6, 0x13,
+ 0x09, 0x61, 0x35, 0x77, 0x14,
+ 0x0E, 0xEE, 0xB0, 0x29, 0x3E,
+ 0x08, 0xD4, 0x9F, 0xC6, 0x06,
+ 0x01, 0x2F, 0x6E, 0x31, 0xE3,
+ 0x05, 0xE3, 0x2A, 0x83, 0x63,
+ 0x0A, 0x0B, 0x70, 0x95, 0x1F,
+ 0x09, 0xE5, 0xDC, 0xCE, 0x77,
+ 0x07, 0x3A, 0x69, 0x0C, 0xA1,
+ 0x02, 0xE4, 0xE7, 0x78, 0xBF,
+ 0x0B, 0xEE, 0xF0, 0x99, 0x00,
+ 0x0B, 0x68, 0xDC, 0x66, 0xD8,
+ 0x04, 0xE3, 0xEC, 0x62, 0x6B,
+ 0x0B, 0x96, 0x25, 0xA7, 0x2A,
+ 0x09, 0x7B, 0x12, 0xC5, 0x0B,
+ 0x0F, 0xF6, 0xFD, 0x6F, 0xFF,
+ 0x05, 0x98, 0x23, 0xA5, 0x07,
+ 0x04, 0x57, 0xD5, 0xAC, 0xB3,
+ 0x0F, 0xDD, 0x06, 0xB6, 0xEC,
+ 0x0A, 0x8C, 0xAA, 0x05, 0x1D,
+ 0x07, 0xB8, 0x5C, 0xE9, 0x0A,
+ 0x09, 0x10, 0x59, 0xC2, 0xCE,
+ 0x01, 0x0E, 0x30, 0xFF, 0xBA,
+ 0x04, 0x91, 0xAB, 0x09, 0x4E,
+ 0x0D, 0xE7, 0xE2, 0x8A, 0x8C,
+ 0x0A, 0xD4, 0x04, 0xC4, 0x76,
+ 0x0D, 0x18, 0x25, 0x15, 0xBE,
+ 0x08, 0xDD, 0x5E, 0x55, 0x9D,
+ 0x00, 0x92, 0x4F, 0x93, 0x68,
+ 0x0B, 0x9E, 0x54, 0xB4, 0xBF,
+ 0x0E, 0xC7, 0xCE, 0xE7, 0xB9,
+ 0x01, 0x8A, 0x26, 0xD5, 0xA4,
+ 0x01, 0x54, 0x59, 0x97, 0xA3,
+ 0x0C, 0x39, 0x44, 0xFA, 0xDF,
+ 0x08, 0x33, 0x41, 0xAD, 0xA2,
+ 0x01, 0xE1, 0xD0, 0xC7, 0xA3,
+ 0x02, 0x64, 0x12, 0x5D, 0xA0,
+ 0x06, 0x1B, 0xF5, 0x23, 0xCD,
+ 0x02, 0x0B, 0xE8, 0x80, 0x82,
+ 0x0A, 0x9D, 0x22, 0x8D, 0xED,
+ 0x05, 0x14, 0x04, 0xCF, 0xC4,
+ 0x09, 0xBF, 0xB0, 0x26, 0x69,
+ 0x0A, 0x12, 0xC0, 0xFF, 0x45,
+ 0x04, 0xB3, 0x44, 0x1F, 0x75,
+ 0x06, 0xDB, 0x08, 0x5A, 0xCC,
+ 0x04, 0x14, 0x80, 0xEE, 0xFD,
+ 0x08, 0x22, 0x43, 0xD4, 0x48,
+ 0x0F, 0x0B, 0xDB, 0x34, 0x3B,
+ 0x0F, 0xFE, 0x07, 0x7C, 0x66,
+ 0x04, 0x27, 0xFB, 0x47, 0xAD,
+ 0x0A, 0x28, 0x47, 0x1B, 0x64,
+ 0x08, 0x90, 0xF8, 0x84, 0x61,
+ 0x05, 0x64, 0x1B, 0xD3, 0x44,
+ 0x04, 0x56, 0xDF, 0xB2, 0x7C,
+ 0x02, 0x4F, 0x4C, 0xC0, 0x5B,
+ 0x04, 0xD2, 0x3E, 0x8B, 0x24,
+ 0x0E, 0x18, 0xA7, 0xE8, 0x35,
+ 0x0B, 0x60, 0x9A, 0xF5, 0x4D,
+ 0x05, 0x5F, 0xBD, 0xC0, 0xD1,
+ 0x05, 0xEB, 0x3C, 0x90, 0xF6,
+ 0x0B, 0xB7, 0x9C, 0x37, 0xBD,
+ 0x00, 0x1E, 0x50, 0xB9, 0xAB,
+ 0x01, 0xF0, 0x11, 0xBE, 0x6C,
+ 0x08, 0x8E, 0x99, 0x2E, 0x10,
+ 0x09, 0x86, 0x43, 0xCF, 0xFB,
+ 0x00, 0x37, 0xF5, 0x24, 0x64,
+ 0x01, 0x3F, 0xCA, 0x16, 0xC9,
+ 0x06, 0x99, 0x44, 0x06, 0x69,
+ 0x09, 0xFD, 0x39, 0xFA, 0xD6,
+ 0x00, 0x7D, 0xD0, 0xAB, 0x6D,
+ 0x08, 0xEB, 0x0A, 0xA0, 0x12,
+ 0x05, 0x39, 0xE1, 0xCE, 0x53,
+ 0x0D, 0x50, 0xBB, 0x9C, 0x2B,
+ 0x00, 0xD0, 0xC0, 0x8F, 0xE5,
+ 0x01, 0xF1, 0xDD, 0xA0, 0x9D,
+ 0x06, 0x98, 0xD5, 0x58, 0xA9,
+ 0x06, 0x6C, 0xC7, 0xCC, 0x45,
+ 0x0E, 0x11, 0x44, 0xE5, 0x6E,
+ 0x03, 0x4D, 0xE7, 0x61, 0x47,
+ 0x05, 0x4F, 0x9B, 0xF9, 0x35,
+ 0x0B, 0x01, 0x8C, 0xA3, 0x4B,
+ 0x0A, 0x2C, 0x77, 0x96, 0x78,
+ 0x07, 0xA0, 0x12, 0xDD, 0x8B,
+ 0x0B, 0xD5, 0x70, 0xE5, 0x64,
+ 0x0F, 0x03, 0x1D, 0xA5, 0x2E,
+ 0x0B, 0xC3, 0xD8, 0x5E, 0x19,
+ 0x0B, 0xDF, 0xBE, 0xF0, 0x3B,
+ 0x0E, 0xE6, 0x42, 0x69, 0xD9,
+ 0x04, 0x79, 0x11, 0x52, 0x78,
+ 0x03, 0xB8, 0x58, 0x84, 0x04,
+ 0x09, 0x08, 0x68, 0x30, 0xDF,
+ 0x07, 0x91, 0x86, 0x74, 0xF4,
+ 0x0A, 0xDB, 0x52, 0x68, 0xE6,
+ 0x0A, 0x19, 0x86, 0x95, 0x74,
+ 0x01, 0x25, 0xCE, 0xFD, 0xF7,
+ 0x0B, 0xAC, 0x1F, 0x85, 0xEF,
+ 0x01, 0x07, 0xA9, 0x72, 0xEE,
+ 0x0D, 0x3B, 0xEA, 0x5D, 0x45,
+ 0x0D, 0xF7, 0xBD, 0x33, 0x43,
+ 0x0C, 0x3F, 0xE0, 0xF7, 0xC5,
+ 0x00, 0x82, 0x94, 0x74, 0x70,
+ 0x03, 0x62, 0xA6, 0x71, 0xB5,
+ 0x01, 0x31, 0x12, 0x06, 0x8C,
+ 0x03, 0x95, 0x63, 0xBD, 0x37,
+ 0x0E, 0x85, 0xAD, 0xFB, 0x2D,
+ 0x0B, 0xE4, 0x10, 0x8C, 0x0F,
+ 0x0B, 0x0D, 0xCF, 0xEA, 0x31,
+ 0x0A, 0x59, 0x27, 0x2E, 0x8A,
+ 0x02, 0x97, 0xEB, 0x5D, 0xD5,
+ 0x0B, 0x64, 0x05, 0xDE, 0x8E,
+ 0x08, 0x9E, 0x7D, 0xC9, 0x05,
+ 0x09, 0x7B, 0x66, 0x83, 0xB8,
+ 0x07, 0xC1, 0xED, 0x8F, 0x53,
+ 0x04, 0xA7, 0x6A, 0xF3, 0xE6,
+ 0x09, 0x48, 0x24, 0x6A, 0xEB,
+ 0x02, 0x20, 0x10, 0x8C, 0x2D,
+ 0x06, 0xC3, 0x29, 0xAE, 0x4C,
+ 0x0A, 0xD3, 0xF6, 0x49, 0x6F,
+ 0x00, 0x29, 0x78, 0x0E, 0xE5,
+ 0x00, 0x5E, 0x61, 0xE3, 0xEC,
+ 0x03, 0xC7, 0xDD, 0x06, 0xB7,
+ 0x06, 0x17, 0x01, 0x2A, 0x04,
+ 0x07, 0xCB, 0x97, 0xDC, 0xF4,
+ 0x01, 0x75, 0x12, 0xD9, 0xC1,
+ 0x0F, 0x4D, 0xEE, 0xF0, 0xBF,
+ 0x0A, 0x5D, 0x77, 0x32, 0xC9,
+ 0x04, 0xD0, 0x5B, 0xCD, 0x82,
+ 0x0D, 0xC6, 0xD6, 0x04, 0xFD,
+ 0x09, 0x21, 0xD8, 0x40, 0x15,
+ 0x0A, 0xF4, 0x68, 0x8A, 0x1C,
+ 0x07, 0xEC, 0x92, 0xDF, 0x93,
+ 0x0A, 0xB2, 0x58, 0xC8, 0xB4,
+ 0x05, 0xA3, 0x78, 0xD9, 0x27,
+ 0x03, 0xBA, 0xB5, 0x6D, 0xD1,
+ 0x0D, 0x7D, 0x54, 0x0A, 0x57,
+ 0x0E, 0xF2, 0x79, 0xD0, 0xFA,
+ 0x00, 0x25, 0x8C, 0x05, 0xAD,
+ 0x06, 0x1D, 0xD1, 0xBF, 0x1A,
+ 0x07, 0xAE, 0x84, 0x1E, 0x9D,
+ 0x0A, 0x41, 0x7B, 0x15, 0xE3,
+ 0x07, 0xAA, 0x35, 0x88, 0xA0,
+ 0x0E, 0x30, 0x5C, 0xAB, 0x04,
+ 0x09, 0xB9, 0x14, 0x2B, 0x4F,
+ 0x00, 0xA7, 0xFF, 0x24, 0x26,
+ 0x0A, 0x30, 0x2B, 0xE9, 0x3F,
+ 0x05, 0x8E, 0xB2, 0xC3, 0x1E,
+ 0x08, 0x1A, 0x1C, 0xB0, 0x53,
+ 0x0A, 0xA8, 0x14, 0xA3, 0x24,
+ 0x0C, 0x73, 0x63, 0xB5, 0xDD,
+ 0x04, 0x67, 0xCC, 0x1B, 0x3D,
+ 0x0B, 0xC3, 0xFE, 0x0D, 0xFC,
+ 0x0C, 0xC8, 0x25, 0x39, 0xEC,
+ 0x07, 0x36, 0x28, 0x47, 0x1B,
+ 0x0B, 0x12, 0x91, 0x80, 0x99,
+ 0x09, 0x39, 0xD6, 0x17, 0xD3,
+ 0x0A, 0x26, 0xD6, 0x9F, 0x72,
+ 0x07, 0x7D, 0x4D, 0x4C, 0xF4,
+ 0x0F, 0x28, 0xC2, 0xFE, 0xBE,
+ 0x01, 0x66, 0xFE, 0x3E, 0xDE,
+ 0x09, 0xB7, 0x20, 0xB5, 0xC2,
+ 0x0C, 0x28, 0xED, 0x9D, 0xF8,
+ 0x0B, 0x49, 0x8F, 0x28, 0xA9,
+ 0x05, 0x94, 0xFC, 0xEC, 0x4C,
+ 0x0B, 0xFD, 0x60, 0xF8, 0xA4,
+ 0x08, 0xCA, 0xD6, 0x81, 0xBE,
+ 0x07, 0xD0, 0x32, 0xB6, 0xAE,
+ 0x0A, 0x22, 0x75, 0x08, 0xCB,
+ 0x00, 0xAC, 0x31, 0xA2, 0x64,
+ 0x00, 0xAD, 0x3F, 0x64, 0x96,
+ 0x0D, 0x9A, 0x59, 0x80, 0xC6,
+ 0x01, 0xA5, 0xFD, 0x16, 0x3A,
+ 0x0A, 0x3D, 0xBD, 0xD0, 0x6B,
+ 0x0E, 0xC1, 0x6B, 0xEA, 0xA0,
+ 0x02, 0xBC, 0xB9, 0x85, 0x44,
+ 0x0F, 0xD7, 0x11, 0x21, 0xAB,
+ 0x03, 0x5E, 0xD0, 0xEF, 0x3D,
+ 0x04, 0x3E, 0x31, 0x73, 0x24,
+ 0x08, 0xEE, 0xFE, 0x7C, 0xDD,
+ 0x02, 0x9E, 0x7C, 0x5C, 0x4C,
+ 0x08, 0x02, 0x11, 0xC4, 0xEB,
+ 0x04, 0x6F, 0x4D, 0x88, 0x99,
+ 0x06, 0x7D, 0x09, 0x2D, 0xC0,
+ 0x09, 0x33, 0x02, 0x0C, 0x99,
+ 0x07, 0xFA, 0x2C, 0x75, 0xAD,
+ 0x00, 0xFB, 0x20, 0xD6, 0xDD,
+ 0x09, 0x55, 0xCE, 0xC0, 0xA5,
+ 0x05, 0x76, 0x83, 0x9D, 0x3A,
+ 0x02, 0xA1, 0x43, 0x38, 0x6A,
+ 0x05, 0xA2, 0x1E, 0x1F, 0xC5,
+ 0x07, 0xE2, 0xF6, 0x41, 0x1F,
+ 0x06, 0x3C, 0xB9, 0xB1, 0x65,
+ 0x04, 0xDB, 0xF8, 0x98, 0xB0,
+ 0x08, 0x23, 0x6E, 0xCA, 0x89,
+ 0x05, 0x18, 0x6A, 0xC2, 0x4F,
+ 0x01, 0x91, 0x5B, 0xF2, 0x6E,
+ 0x0D, 0x81, 0x68, 0x45, 0x92,
+ 0x08, 0x58, 0xEB, 0x6C, 0xFF,
+ 0x0B, 0x41, 0xED, 0xBB, 0x32,
+ 0x03, 0xAA, 0x81, 0x0A, 0xCA,
+ 0x02, 0x04, 0x3A, 0x4F, 0x64,
+ 0x08, 0x86, 0x73, 0x3D, 0x89,
+ 0x0F, 0xBC, 0x3F, 0xE0, 0xCC,
+ 0x0D, 0xCC, 0x02, 0x5F, 0xB4,
+ 0x02, 0x71, 0x79, 0x24, 0x71,
+ 0x09, 0x72, 0xF1, 0x10, 0x31,
+ 0x0E, 0x13, 0x15, 0x6D, 0xBD,
+ 0x0C, 0xA0, 0x9E, 0xE9, 0xFB,
+ 0x08, 0xB7, 0xA4, 0xD4, 0xFB,
+ 0x0A, 0x31, 0x8D, 0x2F, 0xEC,
+ 0x0D, 0xD5, 0x79, 0xE3, 0xEB,
+ 0x08, 0xD9, 0x67, 0x0B, 0x6D,
+ 0x09, 0x01, 0x55, 0xE5, 0xD8,
+ 0x02, 0x77, 0x7E, 0xBA, 0x8C,
+ 0x07, 0x63, 0x6A, 0x66, 0xB5,
+ 0x04, 0x7F, 0xC4, 0x6F, 0x82,
+ 0x09, 0x04, 0xA5, 0x68, 0xF3,
+ 0x06, 0xC5, 0x4A, 0xE3, 0x60,
+ 0x0E, 0x62, 0x5D, 0x90, 0x85,
+ 0x07, 0x2A, 0xC1, 0x7A, 0x6E,
+ 0x05, 0x0A, 0xD1, 0xFA, 0x43,
+ 0x03, 0xC9, 0xA9, 0x98, 0x11,
+ 0x09, 0x1A, 0x5F, 0xD1, 0x6B,
+ 0x06, 0x73, 0xC5, 0x5E, 0xC0,
+ 0x06, 0x6D, 0xB2, 0x3E, 0xAA,
+ 0x0B, 0xAA, 0xFB, 0xB8, 0x1C,
+ 0x05, 0x3D, 0x08, 0x92, 0x10,
+ 0x02, 0xF6, 0xCF, 0x0E, 0xF0,
+ 0x0F, 0x83, 0xDF, 0x17, 0x32,
+ 0x01, 0x4E, 0x53, 0xE5, 0x4D,
+ 0x00, 0x90, 0x27, 0x55, 0x84,
+ 0x08, 0x40, 0x5C, 0x98, 0x47,
+ 0x05, 0x86, 0xF6, 0xDC, 0x8A,
+ 0x05, 0xA7, 0xEE, 0x9E, 0xD5,
+ 0x0F, 0x53, 0x30, 0x18, 0xD7,
+ 0x08, 0xBF, 0xA2, 0xC7, 0x51,
+ 0x0D, 0x4F, 0xB8, 0x8E, 0xBE,
+ 0x08, 0xAC, 0xD9, 0xD4, 0x0A,
+ 0x09, 0x16, 0x9D, 0xB9, 0xD2,
+ 0x06, 0xEA, 0x59, 0xB3, 0x8C,
+ 0x0D, 0x9A, 0x1F, 0xE1, 0xFF,
+ 0x07, 0xBE, 0x2E, 0x64, 0x12,
+ 0x05, 0xA3, 0x4D, 0x99, 0x95,
+ 0x09, 0x8C, 0x43, 0x89, 0xC8,
+ 0x0F, 0xC2, 0x30, 0x9C, 0xAB,
+ 0x01, 0xE9, 0xC4, 0x94, 0x22,
+ 0x0F, 0xD9, 0x27, 0xBF, 0x26,
+ 0x06, 0x60, 0x33, 0x94, 0x63,
+ 0x05, 0x44, 0xAD, 0x32, 0xCE,
+ 0x03, 0x64, 0x1A, 0xDB, 0xB6,
+ 0x06, 0xFA, 0xA8, 0x14, 0xA8,
+ 0x06, 0xE0, 0xF3, 0x26, 0x75,
+ 0x0E, 0x49, 0x94, 0x8B, 0xFB,
+ 0x0C, 0x38, 0xC3, 0xFC, 0x8F,
+ 0x0C, 0x5C, 0xC8, 0x25, 0x3B,
+ 0x07, 0x9F, 0x36, 0x2E, 0x4D,
+ 0x0B, 0x57, 0x13, 0x15, 0x00,
+ 0x04, 0x61, 0x3B, 0x56, 0x1B,
+ 0x0F, 0x71, 0x68, 0x56, 0x9B,
+ 0x0E, 0x4B, 0x3E, 0x0D, 0x49,
+ 0x0B, 0xE1, 0x2B, 0x52, 0xFE,
+ 0x07, 0x19, 0x65, 0x9E, 0x3A,
+ 0x04, 0x35, 0x17, 0x20, 0xB0,
+ 0x0E, 0xD2, 0x2A, 0xDE, 0x5D,
+ 0x0C, 0xE7, 0x49, 0xEB, 0x96,
+ 0x0A, 0xCF, 0xFA, 0x36, 0x69,
+ 0x07, 0x87, 0xFC, 0x12, 0x7C,
+ 0x09, 0x90, 0x4A, 0x7A, 0x4A,
+ 0x04, 0x8C, 0x49, 0x8A, 0x32,
+ 0x0E, 0x26, 0x22, 0x11, 0x08,
+ 0x02, 0x72, 0xAC, 0x27, 0xA6,
+ 0x04, 0x50, 0xAD, 0x2F, 0xD5,
+ 0x06, 0xFC, 0x9A, 0x89, 0x32,
+ 0x06, 0x51, 0xA5, 0xED, 0xA5,
+ 0x0A, 0xCB, 0x3C, 0x6D, 0x64,
+ 0x0B, 0x6E, 0xC1, 0x7B, 0x5F,
+ 0x00, 0x52, 0xBC, 0x9B, 0x37,
+ 0x0E, 0x93, 0xD7, 0x51, 0x96,
+ 0x0C, 0x2F, 0x6C, 0xD0, 0x57,
+ 0x0F, 0xF8, 0x3D, 0xED, 0x31,
+ 0x00, 0x94, 0xED, 0x02, 0xFE,
+ 0x08, 0xA9, 0x1C, 0x71, 0x9E,
+ 0x0C, 0x44, 0x02, 0x0C, 0x86,
+ 0x05, 0x58, 0x6F, 0x50, 0x8A,
+ 0x01, 0x5A, 0x7E, 0xD4, 0xAF,
+ 0x09, 0x35, 0x33, 0x1C, 0x4E,
+ 0x03, 0x4B, 0xFA, 0x02, 0x77,
+ 0x08, 0xF9, 0xCB, 0xA0, 0xD6,
+ 0x06, 0x82, 0xD7, 0xD5, 0x40,
+ 0x09, 0x46, 0xB7, 0x03, 0x8E,
+ 0x0B, 0xAE, 0x82, 0x43, 0x2C,
+ 0x04, 0x19, 0xB1, 0xDA, 0x3F,
+ 0x00, 0x7B, 0xE2, 0xF6, 0x41,
+ 0x09, 0xDA, 0x3C, 0xE9, 0xB1,
+ 0x0A, 0x38, 0x5A, 0xA8, 0x18,
+ 0x00, 0x84, 0x83, 0x49, 0x4A,
+ 0x09, 0xDE, 0x5B, 0xA1, 0xC2,
+ 0x0D, 0x7D, 0x72, 0x6B, 0x72,
+ 0x03, 0xE7, 0xE3, 0x29, 0xC6,
+ 0x0E, 0xF5, 0x98, 0xBB, 0xAC,
+ 0x09, 0x76, 0xE1, 0xBD, 0x3B,
+ 0x0D, 0xAE, 0x2A, 0x91, 0xCA,
+ 0x02, 0xEE, 0x07, 0x2A, 0xFE,
+ 0x0D, 0x44, 0x86, 0x20, 0x0F,
+ 0x03, 0x43, 0xBC, 0x0F, 0x53,
+ 0x07, 0xC5, 0xCC, 0xB2, 0xE7,
+ 0x04, 0x79, 0xF3, 0x52, 0xA4,
+ 0x01, 0xB5, 0x71, 0x2D, 0x52,
+ 0x08, 0x46, 0x13, 0x89, 0xE3,
+ 0x0D, 0x37, 0x22, 0x99, 0xAB,
+ 0x0B, 0x24, 0xB7, 0xC9, 0xD6,
+ 0x0C, 0x06, 0x32, 0x99, 0x2D,
+ 0x08, 0xB1, 0xD6, 0x4D, 0xA1,
+ 0x0E, 0x83, 0x5B, 0x62, 0x89,
+ 0x0F, 0x55, 0x02, 0xB1, 0x27,
+ 0x07, 0x0E, 0x74, 0x9E, 0xBA,
+ 0x05, 0x0D, 0xFE, 0xBB, 0x65,
+ 0x0B, 0x79, 0x7F, 0xC1, 0xEC,
+ 0x03, 0x99, 0x84, 0xA7, 0x28,
+ 0x0B, 0x66, 0x65, 0x48, 0xA3,
+ 0x03, 0x62, 0x82, 0x20, 0x10,
+ 0x00, 0x27, 0x2A, 0x83, 0x6B,
+ 0x02, 0x7A, 0xF5, 0x13, 0xE6,
+ 0x09, 0x6F, 0xC9, 0xA5, 0x0E,
+ 0x04, 0x66, 0x1A, 0x7B, 0xCC,
+ 0x0B, 0x2E, 0x1B, 0xF3, 0x83,
+ 0x04, 0xB6, 0xE4, 0x36, 0x3E,
+ 0x08, 0x05, 0x2B, 0xFB, 0x38,
+ 0x0D, 0xA9, 0xFD, 0x75, 0x12,
+ 0x08, 0x82, 0x36, 0xCD, 0x0E,
+ 0x09, 0x7E, 0x63, 0xD3, 0x17,
+ 0x02, 0x09, 0x4E, 0xF7, 0x65,
+ 0x0D, 0x8A, 0x91, 0xE0, 0x57,
+ 0x0A, 0x45, 0x70, 0x21, 0x18,
+ 0x07, 0x5F, 0xE6, 0xF9, 0x1C,
+ 0x00, 0x17, 0xB4, 0x6C, 0x96,
+ 0x04, 0x93, 0x53, 0x30, 0x18,
+ 0x06, 0x34, 0xBF, 0x22, 0xD7,
+ 0x05, 0x77, 0x8F, 0xBA, 0x01,
+ 0x01, 0xD9, 0xD3, 0xBD, 0x49,
+ 0x02, 0x57, 0x17, 0x74, 0x26,
+ 0x08, 0x78, 0xF5, 0x24, 0x73,
+ 0x09, 0xED, 0x9A, 0x1D, 0xED,
+ 0x04, 0x85, 0x86, 0xAE, 0x64,
+ 0x02, 0x9D, 0xA3, 0xC1, 0x96,
+ 0x0C, 0xA1, 0x6D, 0xAB, 0x89,
+ 0x00, 0x8A, 0x22, 0x3D, 0x5C,
+ 0x01, 0x0F, 0xDC, 0x39, 0x1C,
+ 0x03, 0xCF, 0x79, 0x28, 0x7F,
+ 0x0E, 0x24, 0x40, 0x34, 0x66,
+ 0x00, 0xFE, 0xA5, 0x80, 0xF2,
+ 0x07, 0x9E, 0xD4, 0x14, 0x9B,
+ 0x00, 0x5A, 0xFA, 0xAD, 0xD0,
+ 0x03, 0x2F, 0x1E, 0xB3, 0xB9,
+ 0x05, 0xD4, 0x48, 0x62, 0x4E,
+ 0x0B, 0x34, 0x3B, 0xE3, 0xF7,
+ 0x07, 0x74, 0xDC, 0xC8, 0xA5,
+ 0x02, 0xCA, 0x7F, 0x16, 0xAA,
+ 0x0F, 0x12, 0xD7, 0x13, 0x91,
+ 0x09, 0x0D, 0x81, 0x19, 0xD6,
+ 0x03, 0x5B, 0xD2, 0x28, 0xD6,
+ 0x06, 0xBA, 0x8B, 0x4E, 0xCD,
+ 0x04, 0x4A, 0x43, 0x18, 0x52,
+ 0x07, 0x82, 0xDF, 0x45, 0x1E,
+ 0x0E, 0xE8, 0x35, 0x81, 0x6A,
+ 0x0D, 0xF5, 0xC0, 0x19, 0x9E,
+ 0x07, 0xC2, 0xCC, 0xC9, 0xCB,
+ 0x09, 0x95, 0x0E, 0x17, 0xB6,
+ 0x09, 0xF2, 0x67, 0xFC, 0x1E,
+ 0x00, 0xB9, 0x18, 0x48, 0xF6,
+ 0x0D, 0x3E, 0x6C, 0x52, 0x0E,
+ 0x04, 0xAE, 0x26, 0xA4, 0xC1,
+ 0x0B, 0xC3, 0xF2, 0x2A, 0xBD,
+ 0x05, 0x65, 0xF8, 0xAB, 0xF5,
+ 0x05, 0x17, 0x1F, 0x1A, 0x99,
+ 0x01, 0xC4, 0x19, 0x25, 0xFD,
+ 0x06, 0x3A, 0xCB, 0x3C, 0x7D,
+ 0x00, 0xEE, 0xC5, 0x41, 0x6B,
+ 0x0A, 0xA2, 0x50, 0xBC, 0xBB,
+ 0x01, 0x4F, 0x33, 0xD7, 0x51,
+ 0x01, 0x9D, 0xAF, 0x7A, 0x52,
+ 0x0F, 0x8E, 0x58, 0x3B, 0x33,
+ 0x0A, 0xA2, 0x60, 0xC1, 0x9E,
+ 0x0C, 0xD8, 0xB9, 0x0A, 0x6F,
+ 0x0C, 0x4C, 0x44, 0x24, 0x53,
+ 0x0A, 0x64, 0x68, 0x6F, 0x4D,
+ 0x04, 0xA1, 0x5A, 0xFE, 0xD9,
+ 0x01, 0xF9, 0x35, 0x73, 0x0F,
+ 0x06, 0xA1, 0x6B, 0xFA, 0x2D,
+ 0x09, 0x97, 0x86, 0x3B, 0xBD,
+ 0x06, 0xDD, 0x82, 0xD7, 0xD5,
+ 0x08, 0xA5, 0xF9, 0x77, 0xC3,
+ 0x07, 0x25, 0x96, 0xA2, 0x63,
+ 0x03, 0xDC, 0xE1, 0x21, 0xDE,
+ 0x04, 0xF0, 0x7B, 0xE2, 0xE6,
+ 0x0D, 0x29, 0xDA, 0xBC, 0xCC,
+ 0x08, 0x52, 0xF8, 0xDA, 0xB8,
+ 0x00, 0x08, 0xA4, 0x23, 0x09,
+ 0x00, 0xB2, 0xE5, 0x9B, 0x90,
+ 0x0A, 0x35, 0x5D, 0x9F, 0x1B,
+ 0x0A, 0x78, 0x46, 0x0E, 0xD9,
+ 0x0C, 0x95, 0xBF, 0xD8, 0xE3,
+ 0x04, 0xF3, 0xD7, 0x44, 0x2D,
+ 0x01, 0x07, 0xEC, 0xAA, 0x89,
+ 0x02, 0xF2, 0x6E, 0x09, 0x7A,
+ 0x06, 0x94, 0xC4, 0x83, 0x30,
+ 0x05, 0xFA, 0xC3, 0xB9, 0xBF,
+ 0x00, 0xF7, 0xC5, 0xC9, 0x46,
+ 0x08, 0x36, 0x12, 0x76, 0x67,
+ 0x0C, 0x79, 0x35, 0x7C, 0xF1,
+ 0x08, 0x09, 0xC6, 0x1E, 0xD5,
+ 0x09, 0xBC, 0xB7, 0x2C, 0xC5,
+ 0x00, 0x32, 0xA4, 0xB2, 0xA4,
+ 0x0C, 0x85, 0x86, 0x37, 0x0D,
+ 0x0F, 0xE8, 0xB1, 0xD3, 0x9D,
+ 0x08, 0x6C, 0xE8, 0xDE, 0x73,
+ 0x03, 0x5F, 0xD5, 0x0C, 0xD5,
+ 0x0C, 0x55, 0x8E, 0x79, 0x5E,
+ 0x02, 0x88, 0x8C, 0xEC, 0x3B,
+ 0x0F, 0x4E, 0x98, 0x7A, 0x81,
+ 0x07, 0xC2, 0x19, 0x01, 0x27,
+ 0x08, 0xF3, 0xE6, 0xC0, 0x8C,
+ 0x08, 0xE8, 0x89, 0xE7, 0x25,
+ 0x09, 0x14, 0xC7, 0x27, 0x03,
+ 0x03, 0x69, 0x25, 0x0F, 0x53,
+ 0x0E, 0x4B, 0x2F, 0xCC, 0x69,
+ 0x02, 0x0E, 0x2C, 0x9A, 0x57,
+ 0x08, 0xEB, 0x4C, 0xB6, 0x07,
+ 0x07, 0x04, 0xF1, 0xEC, 0x17,
+ 0x00, 0x2B, 0x35, 0x2B, 0xCB,
+ 0x04, 0x1C, 0xE9, 0xBD, 0x65,
+ 0x0E, 0x19, 0xC2, 0xB6, 0xC3,
+ 0x04, 0xF2, 0xC5, 0x03, 0xDE,
+ 0x07, 0x32, 0x09, 0x40, 0x95,
+ 0x0B, 0xCD, 0x8A, 0x11, 0xF3,
+ 0x0C, 0xD4, 0x04, 0x4D, 0xE1,
+ 0x00, 0xCE, 0xF5, 0x86, 0xF4,
+ 0x0C, 0x8A, 0x15, 0xA3, 0x5A,
+ 0x0A, 0xDD, 0xB3, 0x5D, 0xB0,
+ 0x02, 0xC8, 0x5F, 0xBF, 0xAA,
+ 0x0E, 0x59, 0xA7, 0x8F, 0xBA,
+ 0x05, 0x6F, 0x98, 0x20, 0x3D,
+ 0x0E, 0x08, 0x3F, 0x17, 0x78,
+ 0x05, 0xD3, 0x85, 0xEA, 0x39,
+ 0x03, 0x85, 0xED, 0x97, 0x82,
+ 0x03, 0xFF, 0x07, 0xBB, 0xAE,
+ 0x0D, 0x92, 0x7D, 0xA3, 0xCF,
+ 0x0B, 0x6D, 0xA3, 0x83, 0x7C,
+ 0x09, 0x88, 0x80, 0x42, 0x30,
+ 0x04, 0x83, 0x8D, 0xEC, 0xB9,
+ 0x04, 0x2B, 0x4F, 0xD9, 0x25,
+ 0x0F, 0x26, 0xA6, 0x65, 0x3C,
+ 0x0C, 0x23, 0x1F, 0x48, 0x0E,
+ 0x08, 0xCD, 0x78, 0xF4, 0x12,
+ 0x07, 0xB1, 0xA5, 0xFA, 0xB5,
+ 0x04, 0xAF, 0x2E, 0xE5, 0xAC,
+ 0x06, 0xF5, 0xD4, 0x45, 0x27,
+ 0x0B, 0xDB, 0x34, 0x3E, 0x70,
+ 0x0E, 0x76, 0xBC, 0x59, 0xBA,
+ 0x0D, 0xBA, 0xC7, 0x92, 0x76,
+ 0x02, 0x46, 0x9B, 0x59, 0x53,
+ 0x09, 0x81, 0x24, 0x6F, 0x79,
+ 0x06, 0x1B, 0xD3, 0x77, 0x2C,
+ 0x06, 0x9F, 0xB2, 0x4E, 0x3B,
+ 0x0D, 0x4C, 0xCC, 0x46, 0xF7,
+ 0x02, 0xFE, 0x9B, 0x0D, 0x6C,
+ 0x07, 0x3E, 0x22, 0x05, 0x37,
+ 0x02, 0xB5, 0xF5, 0xE0, 0xA3,
+ 0x0C, 0x5D, 0xC3, 0x47, 0xC3,
+ 0x09, 0xA8, 0x18, 0xCC, 0x97,
+ 0x04, 0xE8, 0xC7, 0x85, 0x7C,
+ 0x0E, 0xFA, 0xB9, 0xA0, 0x4A,
+ 0x06, 0x0E, 0x9E, 0x5C, 0x54,
+ 0x07, 0xB6, 0x4E, 0x26, 0xA2,
+ 0x09, 0x0A, 0x82, 0xF4, 0xA6,
+ 0x0F, 0x24, 0x87, 0xD6, 0xE7,
+ 0x06, 0xE5, 0x74, 0xFE, 0x1A,
+ 0x00, 0x81, 0x06, 0x73, 0x25,
+ 0x0D, 0x16, 0x3A, 0xDD, 0x3E,
+ 0x0D, 0xD0, 0x6B, 0x48, 0x83,
+ 0x0B, 0xEA, 0xA0, 0x44, 0x3E,
+ 0x0B, 0x81, 0xCE, 0x95, 0x15,
+ 0x09, 0xA1, 0x3C, 0x23, 0xEC,
+ 0x09, 0xEF, 0xCF, 0xF4, 0xFD,
+ 0x08, 0xF1, 0xC0, 0x94, 0x2D,
+ 0x00, 0xFD, 0xE8, 0xA9, 0x1C,
+ 0x01, 0x5C, 0x4C, 0xC4, 0x12,
+ 0x0D, 0x84, 0xE5, 0x18, 0x61,
+ 0x07, 0xCA, 0xF4, 0x5A, 0x7F,
+ 0x08, 0x2F, 0x39, 0x35, 0x33,
+ 0x0B, 0x8E, 0xEC, 0xCB, 0xFB,
+ 0x04, 0x3D, 0x16, 0x75, 0xBB,
+ 0x09, 0xDE, 0x1D, 0x8F, 0x57,
+ 0x05, 0x40, 0xA5, 0x7C, 0x42,
+ 0x03, 0x1F, 0x87, 0xAB, 0x14,
+ 0x09, 0x3A, 0x10, 0xD9, 0xA0,
+ 0x05, 0x1F, 0xF0, 0x7B, 0xE2,
+ 0x06, 0x41, 0x29, 0xCA, 0x3C,
+ 0x09, 0xB1, 0x52, 0x18, 0xDA,
+ 0x08, 0x98, 0x88, 0x14, 0x92,
+ 0x09, 0xCA, 0xB0, 0xDE, 0x29,
+ 0x01, 0x42, 0xB4, 0xFD, 0x21,
+ 0x0B, 0xF2, 0x6A, 0x66, 0xB7,
+ 0x09, 0x46, 0x97, 0xC1, 0x9C,
+ 0x0B, 0x2C, 0xF1, 0xEB, 0x03,
+ 0x0D, 0xBB, 0x05, 0x83, 0x28,
+ 0x01, 0x4A, 0xF2, 0xF2, 0xC5,
+ 0x01, 0x4F, 0x5D, 0x49, 0x84,
+ 0x0C, 0xBD, 0xB3, 0xC3, 0xAF,
+ 0x0F, 0xE0, 0xF7, 0xD5, 0xCC,
+ 0x08, 0x93, 0xA4, 0x7D, 0x1D,
+ 0x02, 0xA4, 0x71, 0xF5, 0x71,
+ 0x01, 0x10, 0x08, 0x06, 0x13,
+ 0x0D, 0x64, 0x3D, 0x77, 0xA2,
+ 0x0D, 0xEC, 0x5B, 0x34, 0x37,
+ 0x0D, 0xD1, 0x0C, 0x26, 0xB2,
+ 0x04, 0xAA, 0x08, 0xA1, 0x56,
+ 0x09, 0xE3, 0xEE, 0xC5, 0x59,
+ 0x06, 0x0B, 0x5F, 0x13, 0x40,
+ 0x05, 0xE5, 0xDC, 0x48, 0xF6,
+ 0x0E, 0xBA, 0x89, 0x2A, 0x23,
+ 0x00, 0x66, 0x87, 0x78, 0x7F,
+ 0x01, 0xEF, 0x8B, 0x9F, 0x07,
+ 0x0F, 0x68, 0x73, 0xE6, 0xC5,
+ 0x02, 0x23, 0x72, 0xE6, 0x91,
+ 0x00, 0x59, 0x08, 0xA7, 0x2A,
+ 0x03, 0x33, 0xEA, 0x45, 0x0A,
+ 0x01, 0xBF, 0xC9, 0xEF, 0x83,
+ 0x09, 0xD1, 0x8C, 0x65, 0x1A,
+ 0x0F, 0x98, 0xE3, 0xAC, 0xB3,
+ 0x0C, 0xDD, 0x06, 0xB6, 0xEC,
+ 0x06, 0xBE, 0xAA, 0x85, 0x2B,
+ 0x03, 0xB8, 0x9C, 0x6F, 0x37,
+ 0x05, 0x10, 0x19, 0xC2, 0xF6,
+ 0x06, 0x0E, 0xF0, 0xFF, 0x83,
+ 0x0F, 0x17, 0x32, 0x89, 0x4E,
+ 0x01, 0xE7, 0xCD, 0x8A, 0x91,
+ 0x06, 0xD4, 0x44, 0xC4, 0x40,
+ 0x01, 0x18, 0x4E, 0x55, 0x86,
+ 0x04, 0xDC, 0x8A, 0x15, 0xA7,
+ 0x07, 0x92, 0xDF, 0x95, 0x59,
+ 0x00, 0x18, 0xC8, 0x34, 0xBF,
+ 0x0B, 0xE7, 0x9D, 0xE1, 0x8F,
+ 0x0A, 0x0D, 0x69, 0x58, 0x2D,
+ 0x0D, 0x54, 0x0E, 0xD5, 0x14,
+ 0x00, 0x71, 0x56, 0x7A, 0xEA,
+ 0x04, 0x7A, 0x01, 0xEF, 0x19,
+ 0x0F, 0xA8, 0x7C, 0x81, 0x3E,
+ 0x0E, 0x2D, 0x91, 0x1D, 0xE9,
+ 0x0F, 0xD2, 0x96, 0xA5, 0x07,
+ 0x0B, 0x89, 0x89, 0x00, 0x08,
+ 0x00, 0x9C, 0xAB, 0x0D, 0xE9,
+ 0x01, 0x74, 0xA9, 0x49, 0xD3,
+ 0x0E, 0xBF, 0x26, 0xA6, 0x60,
+ 0x0D, 0x95, 0x96, 0xBF, 0x74,
+ 0x02, 0xBE, 0xCF, 0x1F, 0x46,
+ 0x06, 0xF3, 0xB0, 0x5A, 0xE6,
+ 0x04, 0x02, 0xAF, 0x2E, 0xF7,
+ 0x03, 0xA4, 0xF1, 0xD4, 0x48,
+ 0x0F, 0xA3, 0x7F, 0x34, 0xFB,
+ 0x0B, 0xFE, 0x8F, 0x7C, 0x9C,
+ 0x03, 0xA7, 0x9C, 0xC3, 0xC8,
+ 0x0A, 0x3C, 0x47, 0x1B, 0x40,
+ 0x03, 0x11, 0x04, 0x80, 0x45,
+ 0x01, 0xFE, 0xBF, 0xD3, 0xB2,
+ 0x00, 0x56, 0x1F, 0xB2, 0x8B,
+ 0x05, 0xCF, 0xEB, 0x44, 0x34,
+ 0x03, 0xD2, 0xFE, 0x8F, 0x38,
+ 0x09, 0x9F, 0xC1, 0x28, 0x04,
+ 0x0B, 0x6C, 0xB5, 0xF5, 0x62,
+ 0x05, 0x76, 0x5D, 0xC0, 0xFB,
+ 0x05, 0xFD, 0xA8, 0x90, 0xD9,
+ 0x07, 0xB6, 0x6C, 0x77, 0x87,
+ 0x04, 0xB6, 0x5C, 0xB9, 0x50,
+ 0x02, 0x76, 0x0F, 0x3E, 0xAC,
+ 0x0F, 0x0C, 0x91, 0x2A, 0x71,
+ 0x0A, 0x81, 0xA8, 0xCF, 0xB2,
+ 0x06, 0x35, 0x33, 0xE4, 0x10,
+ 0x0D, 0x3F, 0x64, 0x92, 0xD8,
+ 0x00, 0x9B, 0x1B, 0x46, 0x50,
+ 0x0D, 0x7F, 0x36, 0x36, 0xCB,
+ 0x06, 0x7F, 0x47, 0x6B, 0x2E,
+ 0x01, 0x6B, 0xEA, 0xA4, 0x72,
+ 0x06, 0xB9, 0x1A, 0x4E, 0x92,
+ 0x0F, 0xD3, 0x01, 0x90, 0x2F,
+ 0x06, 0xD2, 0x76, 0x0F, 0xB8,
+ 0x0D, 0xF1, 0x73, 0x24, 0xB6,
+ 0x07, 0x1C, 0xE7, 0x58, 0xA8,
+ 0x04, 0xEF, 0x7C, 0x40, 0x44,
+ 0x08, 0x13, 0x1F, 0xE5, 0x18,
+ 0x0F, 0x4D, 0xC8, 0xA5, 0x7E,
+ 0x04, 0xCB, 0xB6, 0x79, 0x34,
+ 0x03, 0x01, 0x8C, 0xA7, 0x6D,
+ 0x06, 0x3A, 0x75, 0x96, 0x6F,
+ 0x0B, 0xA0, 0xD2, 0xDD, 0x82,
+ 0x0F, 0x7D, 0xE4, 0xA5, 0xB9,
+ 0x0F, 0x03, 0x1D, 0x27, 0x6E,
+ 0x09, 0xC1, 0x9F, 0xDA, 0x8E,
+ 0x09, 0x5E, 0xBF, 0xFD, 0xBB,
+ 0x08, 0xE4, 0xE1, 0x29, 0x9A,
+ 0x0C, 0xF9, 0xB1, 0x56, 0x1D,
+ 0x00, 0xBA, 0x3E, 0x08, 0x05,
+ 0x0B, 0x8B, 0xEA, 0xBC, 0xDE,
+ 0x01, 0x93, 0xE0, 0xB4, 0xBD,
+ 0x02, 0x5B, 0xF2, 0x6E, 0x47,
+ 0x09, 0x1B, 0xE0, 0x17, 0xF5,
+ 0x00, 0x69, 0x0C, 0xFD, 0xF7,
+ 0x0B, 0xAF, 0x1F, 0x05, 0xEF,
+ 0x0A, 0x81, 0x4A, 0xF6, 0xCD,
+ 0x0D, 0x38, 0xE9, 0xDD, 0x45,
+ 0x0E, 0xF2, 0x9D, 0xBF, 0x43,
+ 0x06, 0x3D, 0x46, 0xF7, 0x85,
+ 0x0C, 0x82, 0x53, 0xB0, 0x5C,
+ 0x09, 0x60, 0x02, 0xF1, 0xB4,
+ 0x01, 0x31, 0x10, 0x0C, 0x61,
+ 0x03, 0x95, 0x61, 0xBD, 0x37,
+ 0x09, 0x85, 0x69, 0xFB, 0x24,
+ 0x0E, 0xE2, 0x54, 0xC0, 0x86,
+ 0x0A, 0x0B, 0xAF, 0xE4, 0xF1,
+ 0x0F, 0x19, 0x23, 0xEA, 0x03,
+ 0x01, 0x74, 0xA7, 0x5F, 0x15,
+ 0x08, 0x97, 0x4B, 0xDC, 0x4E,
+ 0x04, 0x9E, 0xB2, 0x8D, 0x52,
+ 0x01, 0x7B, 0x6E, 0x87, 0x78,
+ 0x07, 0xC1, 0x63, 0x8B, 0x59,
+ 0x0E, 0xA5, 0xD8, 0xF3, 0xE7,
+ 0x0C, 0x4A, 0xA3, 0x66, 0xE2,
+ 0x08, 0x22, 0xBE, 0x8C, 0x37,
+ 0x0A, 0xC3, 0x7A, 0x6A, 0x0D,
+ 0x00, 0xD1, 0x59, 0x49, 0x6E,
+ 0x09, 0xA9, 0x9A, 0x08, 0x2C,
+ 0x0A, 0x5F, 0xD3, 0x63, 0xAC,
+ 0x0B, 0xC7, 0x5D, 0x04, 0x36,
+ 0x0C, 0x16, 0xBE, 0xAA, 0x05,
+ 0x03, 0xE3, 0x38, 0x18, 0xE9,
+ 0x06, 0x75, 0x12, 0x19, 0xC2,
+ 0x0F, 0x4D, 0xEE, 0xFE, 0x3F,
+ 0x09, 0xDD, 0xD8, 0x32, 0x29,
+ 0x0E, 0xD1, 0xE1, 0xCD, 0x8A,
+ 0x01, 0xC6, 0xD1, 0x44, 0xC4,
+ 0x00, 0x21, 0x1C, 0xCE, 0x55,
+ 0x06, 0xF4, 0xD8, 0x08, 0x96,
+ 0x07, 0x24, 0x36, 0xDF, 0x93,
+ 0x03, 0xF9, 0xBC, 0xC8, 0xB7,
+ 0x0D, 0x6B, 0x64, 0xDF, 0x67,
+ 0x0F, 0x73, 0xAE, 0xED, 0x92,
+ 0x0D, 0xB4, 0xF7, 0x8C, 0x5D,
+ 0x07, 0x70, 0x38, 0x52, 0x30,
+ 0x06, 0x24, 0x33, 0x81, 0xFC,
+ 0x02, 0x9E, 0x41, 0x79, 0x4D,
+ 0x0E, 0x2E, 0x60, 0x12, 0x9D,
+ 0x03, 0xCF, 0x9F, 0x95, 0x23,
+ 0x0F, 0xAB, 0x8D, 0x8E, 0xC0,
+ 0x03, 0x30, 0x5B, 0x2B, 0x0D,
+ 0x0A, 0xB8, 0xD4, 0x2D, 0x0F,
+ 0x08, 0xA5, 0x5F, 0x26, 0xA6,
+ 0x01, 0xB0, 0x74, 0x69, 0x7F,
+ 0x0C, 0x8C, 0xD2, 0x49, 0x95,
+ 0x05, 0x19, 0x1B, 0xB0, 0x5A,
+ 0x03, 0xA9, 0xD4, 0x29, 0xE4,
+ 0x00, 0x73, 0xA1, 0xF5, 0xD4,
+ 0x08, 0x67, 0x0F, 0xDB, 0x34,
+ 0x09, 0xC3, 0xFA, 0x09, 0xFC,
+ 0x0D, 0xC8, 0xE1, 0x3B, 0xB4,
+ 0x0E, 0x37, 0xEA, 0x47, 0xEF,
+ 0x0E, 0x91, 0x51, 0x06, 0x71,
+ 0x09, 0xB9, 0xF5, 0x19, 0x53,
+ 0x02, 0x28, 0x56, 0x19, 0x38,
+ 0x02, 0x7C, 0x6D, 0x41, 0x80,
+ 0x01, 0x28, 0xD6, 0xF8, 0x4B,
+ 0x04, 0xE6, 0xFE, 0xBC, 0x68,
+ 0x04, 0xB5, 0x20, 0xB5, 0xC7,
+ 0x0A, 0x2B, 0x98, 0xDD, 0xC2,
+ 0x0E, 0xC9, 0x0C, 0xA8, 0x90,
+ 0x0E, 0x17, 0xB3, 0x68, 0x77,
+ 0x07, 0xFC, 0x1E, 0xF8, 0xB9,
+ 0x00, 0xCA, 0xD6, 0x8F, 0x3E,
+ 0x0C, 0xD5, 0x2E, 0x36, 0xAE,
+ 0x0C, 0x20, 0xCB, 0x08, 0xC3,
+ 0x0B, 0xAE, 0x53, 0xAA, 0x24,
+ 0x0A, 0xAF, 0xF6, 0x64, 0x92,
+ 0x08, 0x9A, 0x99, 0x8D, 0xC6,
+ 0x01, 0xA5, 0xFD, 0x16, 0x3A,
+ 0x0B, 0xF4, 0xDD, 0xD0, 0x6B,
+ 0x0E, 0xC1, 0x6F, 0xEA, 0xA0,
+ 0x02, 0xBC, 0xBB, 0x81, 0xCE,
+ 0x01, 0xD7, 0x56, 0xA7, 0xD6,
+ 0x03, 0x60, 0xD0, 0xEF, 0x16,
+ 0x08, 0x95, 0x51, 0xF7, 0xEA,
+ 0x0D, 0xEF, 0x3C, 0x7C, 0x18,
+ 0x03, 0x1E, 0xA0, 0x5C, 0x44,
+ 0x0C, 0x82, 0xB1, 0x84, 0x25,
+ 0x01, 0x6D, 0x69, 0xC5, 0xE1,
+ 0x00, 0x7C, 0x07, 0xAD, 0xF1,
+ 0x05, 0x33, 0x01, 0x80, 0x91,
+ 0x00, 0xFA, 0x2C, 0x75, 0x96,
+ 0x00, 0x7B, 0x02, 0xD6, 0xEF,
+ 0x08, 0x17, 0xD1, 0x45, 0x05,
+ 0x09, 0x77, 0x03, 0x1D, 0x2D,
+ 0x0E, 0xA2, 0x41, 0x38, 0x94,
+ 0x02, 0xA1, 0xDE, 0x1F, 0xF0,
+ 0x02, 0xE7, 0x26, 0x41, 0xFA,
+ 0x03, 0xBC, 0x19, 0xFF, 0x92,
+ 0x02, 0xD8, 0x4A, 0x98, 0xA8,
+ 0x0C, 0x20, 0x8F, 0xCC, 0xB2,
+ 0x0E, 0x9B, 0x94, 0xC6, 0x27,
+ 0x01, 0x92, 0x5B, 0x72, 0x65,
+ 0x0F, 0x01, 0x1A, 0x44, 0x17,
+ 0x0E, 0x5A, 0x3D, 0x2C, 0xF5,
+ 0x07, 0x41, 0xB5, 0xBB, 0x0A,
+ 0x05, 0x6A, 0x80, 0xCF, 0x43,
+ 0x0E, 0x07, 0x3E, 0x4F, 0x5D,
+ 0x04, 0x86, 0x7F, 0x3D, 0xB3,
+ 0x01, 0xBC, 0x3E, 0xE6, 0xFD,
+ 0x05, 0xCC, 0x02, 0x53, 0xB4,
+ 0x09, 0xF2, 0xE2, 0xA4, 0x71,
+ 0x05, 0x71, 0x29, 0x10, 0x08,
+ 0x0F, 0x93, 0x72, 0xA3, 0x3D,
+ 0x0B, 0x2A, 0x85, 0x69, 0xE2,
+ 0x04, 0xB7, 0xE0, 0x52, 0xC6,
+ 0x02, 0x32, 0x8D, 0x29, 0x28,
+ 0x09, 0x46, 0xF9, 0xE3, 0x1A,
+ 0x03, 0x73, 0xF6, 0x0B, 0x5F,
+ 0x0E, 0x81, 0x67, 0x65, 0xDC,
+ 0x06, 0xF4, 0x32, 0xBC, 0x89,
+ 0x07, 0x62, 0x89, 0xE0, 0xC4,
+ 0x00, 0xFD, 0xE5, 0xEF, 0xCB,
+ 0x01, 0x86, 0x83, 0x68, 0x33,
+ 0x06, 0xC5, 0x4C, 0xE3, 0x99,
+ 0x08, 0x60, 0xC2, 0x90, 0x9C,
+ 0x0F, 0xBA, 0x6F, 0x77, 0x6E,
+ 0x0D, 0x88, 0xF3, 0xF0, 0x49,
+ 0x0F, 0xC9, 0xAD, 0x98, 0xFF,
+ 0x0F, 0x18, 0xBD, 0x51, 0x61,
+ 0x0C, 0xB3, 0xC7, 0xDD, 0xF5,
+ 0x0F, 0xEC, 0xD6, 0xB2, 0x2A,
+ 0x0F, 0x29, 0x2F, 0xB8, 0x5C,
+ 0x05, 0x2D, 0x75, 0x12, 0x2A,
+ 0x06, 0xF6, 0xC9, 0x02, 0x30,
+ 0x0F, 0x83, 0xDF, 0x17, 0x32,
+ 0x08, 0x86, 0x31, 0xE7, 0xCD,
+ 0x03, 0x93, 0xA2, 0xD5, 0x37,
+ 0x0E, 0x42, 0xC6, 0x18, 0x46,
+ 0x0C, 0x06, 0x14, 0xD0, 0x4A,
+ 0x0C, 0xA5, 0x88, 0x92, 0x2C,
+ 0x09, 0x51, 0xD9, 0x18, 0xC8,
+ 0x0D, 0x3F, 0x42, 0xCB, 0x99,
+ 0x07, 0x8F, 0xBA, 0x0D, 0x6D,
+ 0x08, 0x2D, 0x7D, 0x54, 0x80,
+ 0x03, 0x97, 0x70, 0xBF, 0x18,
+ 0x06, 0xE6, 0x24, 0x33, 0x9C,
+ 0x0D, 0xB2, 0x9D, 0xE1, 0xFF,
+ 0x0E, 0xBE, 0xEE, 0x68, 0x92,
+ 0x07, 0xA1, 0x22, 0x9B, 0x35,
+ 0x03, 0x8D, 0xAF, 0x89, 0x88,
+ 0x00, 0x42, 0x3C, 0x9C, 0xAB,
+ 0x0D, 0xE9, 0xBD, 0x14, 0x2B,
+ 0x0F, 0xD9, 0x21, 0xBF, 0x26,
+ 0x07, 0xA8, 0xD1, 0x94, 0x69,
+ 0x06, 0x47, 0xEE, 0xB2, 0x05,
+ 0x05, 0x76, 0xEA, 0xDB, 0xB4,
+ 0x0A, 0xFA, 0xA8, 0x12, 0x65,
+ 0x0A, 0xE0, 0x73, 0xA2, 0xF5,
+ 0x04, 0x48, 0x67, 0x0B, 0xDB,
+ 0x04, 0x3B, 0x41, 0xFE, 0x0F,
+ 0x07, 0x5C, 0xC8, 0x25, 0x3B,
+ 0x0B, 0x80, 0xC9, 0xD6, 0x44,
+ 0x0B, 0x57, 0x15, 0x11, 0x00,
+ 0x0E, 0xA1, 0x3B, 0x53, 0xFC,
+ 0x03, 0x72, 0x28, 0xD6, 0x95,
+ 0x02, 0x4B, 0x7E, 0xCD, 0x86,
+ 0x00, 0x63, 0x2A, 0xD2, 0xB4,
+ 0x00, 0x1D, 0x65, 0x9E, 0x3E,
+ 0x08, 0x35, 0xB1, 0x60, 0x46,
+ 0x0C, 0xD0, 0xC9, 0x5E, 0x5D,
+ 0x08, 0x67, 0xE9, 0xE7, 0xB9,
+ 0x08, 0x48, 0xB7, 0xBA, 0x28,
+ 0x0D, 0x85, 0x02, 0x1E, 0xD8,
+ 0x01, 0x40, 0xEA, 0x7A, 0x8F,
+ 0x06, 0xEA, 0xF4, 0x82, 0x76,
+ 0x04, 0x24, 0xDC, 0x01, 0x48,
+ 0x0A, 0xF2, 0x0C, 0x3A, 0xA6,
+ 0x0E, 0x52, 0x56, 0xBF, 0x24,
+ 0x0E, 0x7C, 0x3A, 0x95, 0x00,
+ 0x0C, 0x53, 0x5B, 0xFD, 0x56,
+ 0x0A, 0xCB, 0x38, 0x7D, 0x23,
+ 0x02, 0xED, 0xAD, 0x69, 0x6A,
+ 0x09, 0x50, 0xDC, 0xBB, 0x41,
+ 0x04, 0x91, 0x29, 0x51, 0x31,
+ 0x00, 0x3F, 0x6C, 0xD0, 0xDC,
+ 0x0F, 0xF8, 0x3D, 0x75, 0xB9,
+ 0x00, 0x94, 0xED, 0x1E, 0x7C,
+ 0x0C, 0xA9, 0x18, 0x61, 0x9C,
+ 0x0C, 0x44, 0x06, 0x11, 0x84,
+ 0x05, 0x90, 0xCF, 0x4D, 0xC8,
+ 0x08, 0x58, 0x5E, 0xC9, 0xDE,
+ 0x03, 0x36, 0x31, 0x01, 0x84,
+ 0x0B, 0xCB, 0x5A, 0x20, 0xB5,
+ 0x06, 0x78, 0xFB, 0xA6, 0xDC,
+ 0x09, 0x82, 0xD7, 0xD1, 0x0A,
+ 0x05, 0x79, 0x77, 0x03, 0x9D,
+ 0x07, 0xAE, 0x20, 0x43, 0x38,
+ 0x05, 0xD9, 0xA1, 0xDA, 0x6C,
+ 0x0C, 0x7B, 0xE2, 0x26, 0x4E,
+ 0x09, 0xDA, 0x26, 0xF9, 0xB1,
+ 0x02, 0x38, 0xDA, 0x38, 0x92,
+ 0x08, 0x04, 0x21, 0x09, 0x00,
+ 0x0B, 0xDE, 0x9B, 0x91, 0xB1,
+ 0x0C, 0xFD, 0x12, 0x57, 0xF2,
+ 0x02, 0x60, 0x83, 0x15, 0x06,
+ 0x0D, 0xF7, 0x48, 0x6B, 0x0C,
+ 0x01, 0xF7, 0x45, 0xAD, 0x73,
+ 0x05, 0xAF, 0xAA, 0x8F, 0xE4,
+ 0x0A, 0xEE, 0x87, 0x34, 0xA1,
+ 0x0D, 0x44, 0x82, 0x70, 0x53,
+ 0x09, 0xC0, 0x98, 0x39, 0xAF,
+ 0x0D, 0xC6, 0xC2, 0x02, 0x13,
+ 0x04, 0x79, 0xF3, 0x68, 0x1D,
+ 0x01, 0xB5, 0x71, 0x3B, 0xA8,
+ 0x02, 0xC5, 0x3B, 0x93, 0x36,
+ 0x07, 0x34, 0x2C, 0x05, 0x29,
+ 0x03, 0x24, 0x37, 0xE8, 0x54,
+ 0x06, 0x05, 0x3D, 0x0D, 0x6F,
+ 0x01, 0x31, 0x36, 0x59, 0xE3,
+ 0x0E, 0x83, 0x5B, 0x7B, 0x01,
+ 0x0F, 0x55, 0x02, 0x91, 0x0B,
+ 0x07, 0x0E, 0x74, 0x9E, 0x94,
+ 0x09, 0x0C, 0xE5, 0x7B, 0xAE,
+ 0x07, 0x78, 0x7F, 0xC1, 0xC1,
+ 0x0B, 0x99, 0x04, 0xA7, 0x46,
+ 0x03, 0xE6, 0xC5, 0x48, 0x0D,
+ 0x02, 0x9A, 0xE2, 0x2C, 0x3E,
+ 0x06, 0xE7, 0x28, 0x45, 0x5D,
+ 0x0E, 0x45, 0x0A, 0x53, 0xFC,
+ 0x09, 0x6F, 0xC9, 0xAC, 0xB6,
+ 0x0C, 0x65, 0x1A, 0x51, 0x28,
+ 0x08, 0xAC, 0xB3, 0xC7, 0xE5,
+ 0x0E, 0xB6, 0x6C, 0x1A, 0xBE,
+ 0x02, 0x03, 0xAB, 0xC7, 0xF8,
+ 0x06, 0xEA, 0x22, 0x75, 0x32,
+ 0x09, 0xC2, 0xF2, 0xCD, 0xC6,
+ 0x00, 0xFF, 0x83, 0xD1, 0xB8,
+ 0x0A, 0x09, 0xCE, 0xDF, 0x08,
+ 0x0D, 0x8A, 0x95, 0xC6, 0x3A,
+ 0x0E, 0x47, 0x64, 0x27, 0x57,
+ 0x04, 0x56, 0x9B, 0xF4, 0x9C,
+ 0x0A, 0x15, 0xA7, 0xE6, 0x6B,
+ 0x0F, 0x93, 0x53, 0x3A, 0xE0,
+ 0x00, 0xB7, 0x97, 0xA4, 0x90,
+ 0x03, 0x64, 0x92, 0xBA, 0x4D,
+ 0x05, 0xD8, 0xAD, 0x71, 0xD4,
+ 0x00, 0x54, 0x89, 0x70, 0x79,
+ 0x0B, 0xFA, 0x0A, 0x24, 0x33,
+ 0x05, 0xED, 0x9A, 0x10, 0xEB,
+ 0x0F, 0x07, 0xBE, 0x2A, 0x8B,
+ 0x09, 0x9D, 0xA3, 0xCF, 0xB4,
+ 0x05, 0x23, 0x89, 0xAB, 0x41,
+ 0x08, 0x80, 0x42, 0x30, 0xB3,
+ 0x0B, 0x0D, 0xE9, 0xB9, 0x3B,
+ 0x0B, 0x4F, 0xD9, 0x25, 0x50,
+ 0x0E, 0xDE, 0xE0, 0x3D, 0xBB,
+ 0x03, 0xBF, 0x47, 0x08, 0xF6,
+ 0x0F, 0x1F, 0x74, 0x9A, 0xD1,
+ 0x00, 0x5A, 0xFA, 0xAD, 0x3B,
+ 0x0F, 0x2E, 0xE0, 0x7D, 0x5D,
+ 0x0E, 0xD4, 0x48, 0x67, 0x33,
+ 0x0B, 0x34, 0x3A, 0xC1, 0x47,
+ 0x0F, 0x7C, 0x58, 0x4C, 0x2F,
+ 0x02, 0xC7, 0x7F, 0x36, 0xEA,
+ 0x0F, 0x98, 0x77, 0x91, 0xA5,
+ 0x00, 0x84, 0x61, 0x39, 0x6E,
+ 0x0B, 0xD3, 0x72, 0x2C, 0x1C,
+ 0x07, 0xE2, 0xCB, 0x72, 0x4D,
+ 0x04, 0xC6, 0xE3, 0x24, 0x92,
+ 0x0E, 0x8B, 0x19, 0x65, 0x49,
+ 0x07, 0xE8, 0xF5, 0xBB, 0xA0,
+ 0x0F, 0xF6, 0x7B, 0x29, 0x1E,
+ 0x04, 0xC2, 0xC7, 0x49, 0x2B,
+ 0x02, 0x93, 0xE5, 0x17, 0xB4,
+ 0x01, 0xDF, 0x67, 0xF8, 0xDE,
+ 0x00, 0xE1, 0x10, 0x46, 0x76,
+ 0x07, 0x38, 0xEC, 0x58, 0xCE,
+ 0x0E, 0xAE, 0xA6, 0x2E, 0x01,
+ 0x00, 0xC4, 0xF2, 0xA0, 0x77,
+ 0x0C, 0xE7, 0x16, 0xAD, 0x1F,
+ 0x0C, 0x95, 0x7C, 0x94, 0x19,
+ 0x08, 0x45, 0xF3, 0xAB, 0x3D,
+ 0x0F, 0x39, 0x0F, 0x32, 0x3D,
+ 0x00, 0x6B, 0x62, 0x41, 0x58,
+ 0x08, 0xA0, 0x56, 0xBA, 0xBB,
+ 0x01, 0xCE, 0x1F, 0x57, 0x51,
+ 0x03, 0x9D, 0xAB, 0x6A, 0x90,
+ 0x0F, 0x8F, 0x5F, 0x3D, 0xF1,
+ 0x01, 0xA1, 0x38, 0xEB, 0x9E,
+ 0x0F, 0xD8, 0x69, 0x10, 0xED,
+ 0x0D, 0x4D, 0x84, 0x84, 0x1B,
+ 0x05, 0x07, 0x58, 0xE9, 0x07,
+ 0x02, 0xA2, 0x6F, 0x7E, 0xD9,
+ 0x0D, 0xF9, 0x37, 0x35, 0x8B,
+ 0x07, 0xA3, 0x4B, 0xFA, 0x1E,
+ 0x0E, 0x15, 0x8A, 0x7D, 0x2A,
+ 0x0E, 0x5D, 0x21, 0xD5, 0x55,
+ 0x0B, 0x26, 0x8B, 0xF1, 0x76,
+ 0x04, 0x25, 0x8E, 0xAF, 0x03,
+ 0x01, 0x5C, 0x99, 0xA1, 0x1E,
+ 0x05, 0xF3, 0x43, 0x62, 0xE2,
+ 0x01, 0x29, 0xDA, 0x30, 0xCA,
+ 0x09, 0xD2, 0x99, 0x58, 0x38,
+ 0x03, 0x0B, 0xF6, 0xA5, 0x7F,
+ 0x02, 0x32, 0xFE, 0x96, 0x11,
+ 0x0A, 0xB4, 0x79, 0x10, 0xDB,
+ 0x0B, 0x68, 0x66, 0x03, 0xD9,
+ 0x0F, 0x95, 0xB7, 0xDE, 0xA1,
+ 0x06, 0xF2, 0xC9, 0x41, 0xA9,
+ 0x09, 0x05, 0xAB, 0xAC, 0x01,
+ 0x0A, 0xF2, 0xEA, 0x0B, 0xC8,
+ 0x0F, 0xDF, 0x40, 0x86, 0x70,
+ 0x07, 0xB0, 0x02, 0xBC, 0x3E,
+ 0x00, 0xF7, 0xC1, 0xC0, 0xB0,
+ 0x03, 0xB4, 0x7D, 0x73, 0x62,
+ 0x04, 0x71, 0xB2, 0xF1, 0x31,
+ 0x00, 0x08, 0x46, 0x13, 0x95,
+ 0x01, 0x3D, 0x97, 0x22, 0x85,
+ 0x09, 0x7A, 0x84, 0xB7, 0xE4,
+ 0x0D, 0x4E, 0x22, 0x32, 0x79,
+ 0x05, 0xEB, 0xF3, 0x56, 0x5B,
+ 0x0B, 0x6E, 0x23, 0x56, 0x76,
+ 0x02, 0xDD, 0x71, 0x02, 0x61,
+ 0x0F, 0xDF, 0x4A, 0x74, 0x96,
+ 0x02, 0x09, 0xAC, 0xEC, 0x7B,
+ 0x06, 0x87, 0x79, 0x7F, 0xC1,
+ 0x0F, 0x8B, 0x9A, 0x00, 0x2D,
+ 0x08, 0xF3, 0xE4, 0xC3, 0x02,
+ 0x08, 0x6A, 0xE2, 0x62, 0x20,
+ 0x0C, 0x8C, 0x25, 0x6A, 0xCC,
+ 0x0A, 0x6E, 0x5F, 0x0A, 0xE1,
+ 0x06, 0x49, 0x6F, 0x49, 0xA3,
+ 0x08, 0x0C, 0x65, 0x9A, 0x55,
+ 0x01, 0x63, 0xAC, 0x33, 0xCD,
+ 0x0D, 0x06, 0xB6, 0x6C, 0xDC,
+ 0x0E, 0xAA, 0x05, 0xAB, 0xC1,
+ 0x08, 0x1C, 0xEB, 0x3D, 0x7F,
+ 0x09, 0x19, 0xC2, 0xF6, 0xFE,
+ 0x06, 0xF0, 0x7F, 0x8F, 0xDF,
+ 0x0F, 0x34, 0x89, 0x40, 0x11,
+ 0x0D, 0xCE, 0xC6, 0x11, 0x86,
+ 0x0E, 0xC4, 0xC4, 0x40, 0x1B,
+ 0x08, 0x4E, 0x55, 0x8B, 0xF0,
+ 0x05, 0x0A, 0xF5, 0xA7, 0xDE,
+ 0x0C, 0x5E, 0xA3, 0x53, 0x30,
+ 0x01, 0x4B, 0xD4, 0xA3, 0xA2,
+ 0x07, 0x59, 0x67, 0x91, 0xA7,
+ 0x0B, 0x6D, 0xD8, 0x2D, 0xFD,
+ 0x02, 0x0A, 0x57, 0x97, 0xF0,
+ 0x09, 0xD2, 0xFA, 0xEA, 0xF7,
+ 0x03, 0x84, 0x6D, 0x94, 0x54,
+ 0x09, 0x7D, 0x07, 0xB2, 0xAE,
+ 0x0E, 0x11, 0xCF, 0x23, 0xCB,
+ 0x0B, 0x15, 0x23, 0x89, 0x99,
+ 0x01, 0x02, 0xE0, 0x4F, 0xF0,
+ 0x06, 0xA8, 0x40, 0x69, 0xBD,
+ 0x04, 0x2B, 0x4D, 0xD5, 0xAE,
+ 0x06, 0x26, 0x66, 0x61, 0xF1,
+ 0x0C, 0x6B, 0x3F, 0x47, 0x0E,
+ 0x02, 0xCF, 0x1D, 0x70, 0x90,
+ 0x0B, 0xB0, 0x5A, 0xFE, 0x9A,
+ 0x04, 0xAF, 0x2E, 0xED, 0xF7,
+ 0x0C, 0xED, 0x54, 0x05, 0xA7,
+ 0x0B, 0xDB, 0x34, 0x38, 0xC6,
+ 0x05, 0x8C, 0xAE, 0xD8, 0xF9,
+ 0x0E, 0xB8, 0x95, 0x1F, 0x36,
+ 0x0A, 0x47, 0x19, 0x5A, 0x17,
+ 0x01, 0x00, 0x86, 0x6C, 0x7C,
+ 0x0D, 0x98, 0x0A, 0x70, 0x9A,
+ 0x06, 0x9F, 0xB6, 0x46, 0x3A,
+ 0x05, 0x49, 0x40, 0x6F, 0xA8,
+ 0x0B, 0x7E, 0x67, 0x1D, 0xB6,
+ 0x0E, 0x3E, 0xE8, 0x71, 0xA0,
+ 0x08, 0xB5, 0x75, 0x50, 0x29,
+ 0x07, 0xDC, 0x20, 0xEB, 0x49,
+ 0x03, 0x81, 0x10, 0xDE, 0x97,
+ 0x0F, 0x62, 0x17, 0x8A, 0x3C,
+ 0x04, 0xFB, 0xE5, 0x10, 0x4E,
+ 0x06, 0x8F, 0x3C, 0x62, 0x1D,
+ 0x0E, 0x36, 0xAE, 0xAB, 0xA6,
+ 0x08, 0x88, 0x22, 0x7E, 0xBD,
+ 0x0F, 0x25, 0xC0, 0x52, 0x3E,
+ 0x06, 0x66, 0xB2, 0xBC, 0x68,
+ 0x03, 0x83, 0xA4, 0x51, 0xA1,
+ 0x05, 0x96, 0x9A, 0xCB, 0x3C,
+ 0x0D, 0xD0, 0x6B, 0x63, 0x45,
+ 0x09, 0xEA, 0xA0, 0x54, 0xBE,
+ 0x0B, 0x81, 0xCE, 0x93, 0xD7,
+ 0x01, 0x21, 0x1E, 0x2B, 0x26,
+ 0x08, 0x6F, 0xAF, 0xE8, 0xBD,
+ 0x0F, 0xF2, 0x10, 0x94, 0xED,
+ 0x07, 0xFD, 0x38, 0xA5, 0x1C,
+ 0x04, 0x5E, 0x6C, 0x54, 0xB3,
+ 0x0B, 0x87, 0x82, 0x58, 0x6D,
+ 0x05, 0x48, 0x01, 0x56, 0x3E,
+ 0x00, 0x2F, 0x99, 0x39, 0xB3,
+ 0x0B, 0x8F, 0xC7, 0xCB, 0xFE,
+ 0x0C, 0x75, 0x96, 0x7B, 0xCD,
+ 0x00, 0xD6, 0xDD, 0x81, 0xD2,
+ 0x05, 0x40, 0xA5, 0x74, 0x33,
+ 0x0A, 0x1D, 0xC7, 0xAE, 0xA2,
+ 0x0B, 0x3A, 0x5E, 0xDF, 0xE1,
+ 0x04, 0x1C, 0x86, 0x7B, 0xE6,
+ 0x08, 0xC0, 0x19, 0xDA, 0x3C,
+ 0x09, 0xB1, 0x52, 0x26, 0xC7,
+ 0x01, 0x19, 0x6C, 0x28, 0x23,
+ 0x01, 0xCA, 0x34, 0xCE, 0x1B,
+ 0x08, 0x42, 0x70, 0xFD, 0x12,
+ 0x03, 0xF0, 0x6A, 0x66, 0x83,
+ 0x03, 0x45, 0xF8, 0xF4, 0x5C,
+ 0x03, 0x2C, 0x71, 0xF7, 0x41,
+ 0x04, 0xB9, 0x45, 0x9F, 0x2A,
+ 0x0B, 0x49, 0x82, 0x6E, 0x03,
+ 0x03, 0x4F, 0x9D, 0x44, 0x86,
+ 0x02, 0xBD, 0xB3, 0x45, 0xBC,
+ 0x07, 0xE0, 0x77, 0xD5, 0x4C,
+ 0x02, 0x52, 0x36, 0x77, 0xBA,
+ 0x00, 0xA4, 0x70, 0x33, 0xF1,
+ 0x08, 0x10, 0xC9, 0xF6, 0x93,
+ 0x04, 0x60, 0x7D, 0x37, 0x22,
+ 0x05, 0x69, 0xFB, 0x32, 0xB5,
+ 0x0C, 0xC6, 0xAC, 0x0B, 0xF2,
+ 0x0D, 0x2F, 0xEE, 0x97, 0x54,
+ 0x03, 0xE0, 0x85, 0x83, 0x5F,
+ 0x0C, 0x08, 0xDE, 0xD5, 0x03,
+ 0x0B, 0x64, 0xEC, 0x0E, 0x74,
+ 0x0E, 0xBA, 0x8B, 0x12, 0xA8,
+ 0x02, 0xE7, 0x66, 0xD4, 0x7F,
+ 0x09, 0xEF, 0x0A, 0x19, 0x84,
+ 0x0E, 0x68, 0x32, 0xE6, 0x45,
+ 0x00, 0xE1, 0x6A, 0xE2, 0xE2,
+ 0x0A, 0x13, 0xF6, 0xA7, 0x2E,
+ 0x03, 0x7A, 0x6E, 0xC5, 0x0A,
+ 0x03, 0xF6, 0x4A, 0xEF, 0xC9,
+ 0x0D, 0x98, 0x0C, 0x73, 0x1A,
+ 0x07, 0xD1, 0xE3, 0xAC, 0x33,
+ 0x07, 0xDC, 0x86, 0xB8, 0xF1,
+ 0x0F, 0xBC, 0xEA, 0x05, 0xAB,
+ 0x01, 0xBB, 0x62, 0xE9, 0x39,
+ 0x05, 0x12, 0x19, 0x42, 0xF6,
+ 0x0D, 0x0E, 0xF3, 0x7F, 0x83,
+ 0x0B, 0x17, 0x32, 0x0F, 0xCE,
+ 0x08, 0xE7, 0x0D, 0xBA, 0x11,
+ 0x07, 0xD4, 0x00, 0xC4, 0x40,
+ 0x01, 0x18, 0x4A, 0x43, 0x84,
+ 0x0C, 0xCE, 0xED, 0x18, 0x67,
+ 0x0C, 0x92, 0xD9, 0xB5, 0xD1,
+ 0x0A, 0x1B, 0xBC, 0x34, 0xBB,
+ 0x09, 0x44, 0xBB, 0xE7, 0x8F,
+ 0x0A, 0x0D, 0x6D, 0xDC, 0x97,
+ 0x04, 0xD6, 0x4E, 0x57, 0x66,
+ 0x0A, 0x3A, 0x56, 0x7A, 0xE8,
+ 0x0D, 0x33, 0x45, 0xE1, 0xDA,
+ 0x04, 0x63, 0xBB, 0x07, 0x4C,
+ 0x04, 0x67, 0x97, 0x1D, 0xAB,
+ 0x06, 0x9B, 0xD5, 0x2F, 0x0D,
+ 0x09, 0x89, 0x88, 0x8C, 0x02,
+ 0x02, 0x9C, 0xAB, 0x09, 0x69,
+ 0x08, 0x94, 0xCD, 0x4F, 0xD9,
+ 0x04, 0x3D, 0x46, 0xA6, 0x60,
+ 0x09, 0x14, 0xC9, 0x7D, 0xC5,
+ 0x0C, 0xB2, 0xCF, 0x1B, 0xB4,
+ 0x0B, 0x59, 0x90, 0x57, 0xFF,
+ 0x09, 0x95, 0x4F, 0x2E, 0xD3,
+ 0x0B, 0xA4, 0x75, 0xD4, 0x7A,
+ 0x07, 0x0B, 0xD9, 0x30, 0xF1,
+ 0x0D, 0x7F, 0x3F, 0x7C, 0x5C,
+ 0x04, 0x25, 0x39, 0x47, 0x91,
+ 0x06, 0x2A, 0x47, 0x15, 0x4A,
+ 0x0B, 0x90, 0x94, 0x89, 0x21,
+ 0x00, 0x57, 0x9B, 0xDE, 0xF2,
+ 0x01, 0xDF, 0x5F, 0xBF, 0x8B,
+ 0x0E, 0x4D, 0x4C, 0xC4, 0x27,
+ 0x08, 0xD2, 0xFE, 0x8F, 0x99,
+ 0x05, 0x9E, 0x3C, 0xE6, 0x7C,
+ 0x07, 0x60, 0xB4, 0xF1, 0x94,
+ 0x00, 0x5E, 0x9D, 0x40, 0x6D,
+ 0x0B, 0xEB, 0xA8, 0x90, 0x4E,
+ 0x05, 0xB6, 0x6C, 0x77, 0x07,
+ 0x0D, 0xFE, 0x18, 0xB5, 0x81,
+ 0x0B, 0x14, 0xCF, 0x3E, 0x6C,
+ 0x0E, 0x8D, 0xA5, 0xAE, 0x2E,
+ 0x0B, 0x01, 0xC8, 0xC2, 0x72,
+ 0x0C, 0x37, 0xA6, 0x62, 0x9A,
+ 0x01, 0x1F, 0x64, 0x96, 0xFF,
+ 0x03, 0x19, 0x60, 0xC4, 0xD1,
+ 0x0C, 0x7C, 0xF6, 0xBA, 0x8B,
+ 0x0D, 0xF8, 0x33, 0xED, 0xE4,
+ 0x09, 0xEB, 0x4A, 0x2C, 0x92,
+ 0x08, 0xBB, 0x82, 0xCE, 0x13,
+ 0x03, 0x51, 0x21, 0x9A, 0xEF,
+ 0x0D, 0xD0, 0x2B, 0x0F, 0x2F,
+ 0x0C, 0xF0, 0xB3, 0x20, 0x94,
+ 0x04, 0x9F, 0xBF, 0x5A, 0x29,
+ 0x0C, 0x6D, 0x5C, 0x4C, 0x44,
+ 0x0E, 0x11, 0x85, 0x65, 0x56,
+ 0x0F, 0x4D, 0xC8, 0xA7, 0x81,
+ 0x0E, 0xC9, 0x2D, 0xFE, 0xAF,
+ 0x09, 0xC1, 0x85, 0x24, 0x7D,
+ 0x0A, 0x2C, 0x75, 0x96, 0x78,
+ 0x03, 0x09, 0x76, 0x5C, 0x01,
+ 0x03, 0xD5, 0x44, 0xA4, 0xF9,
+ 0x07, 0x03, 0x99, 0x27, 0xAE,
+ 0x03, 0x43, 0xF8, 0x58, 0xAA,
+ 0x00, 0x5C, 0x5F, 0xF0, 0x7B,
+ 0x08, 0xE5, 0xE0, 0x29, 0xDE,
+ 0x04, 0x79, 0x16, 0xD3, 0xB8,
+ 0x0A, 0xB8, 0x99, 0x08, 0x04,
+ 0x0A, 0x89, 0x2A, 0xB2, 0x5E,
+ 0x0A, 0x91, 0x86, 0xB4, 0x24,
+ 0x08, 0x58, 0x59, 0xEA, 0x67,
+ 0x0A, 0x99, 0xA9, 0x15, 0x74,
+ 0x04, 0xEB, 0x23, 0x31, 0xC6,
+ 0x0D, 0xAC, 0x55, 0xC5, 0xAC,
+ 0x0A, 0x81, 0x4A, 0xF4, 0x35,
+ 0x07, 0x3A, 0x4F, 0x5A, 0xDE,
+ 0x0C, 0xB0, 0xB4, 0x34, 0x0B,
+ 0x0C, 0x3F, 0xE0, 0xF7, 0xC5,
+ 0x0E, 0x82, 0x57, 0xB5, 0xF9,
+ 0x0A, 0xE2, 0x44, 0xF3, 0x35,
+ 0x00, 0x31, 0xD0, 0x08, 0x46,
+ 0x0B, 0x17, 0x21, 0xB1, 0x77,
+ 0x08, 0x86, 0xCE, 0x7B, 0x26,
+ 0x0E, 0xE4, 0x14, 0xC0, 0x46,
+ 0x0B, 0x8C, 0xE7, 0xE8, 0xF1,
+ 0x06, 0x59, 0xE3, 0xEE, 0x83,
+ 0x0B, 0x76, 0x0B, 0x5B, 0xCB,
+ 0x02, 0x95, 0xE5, 0xDC, 0x0E,
+ 0x04, 0x9E, 0xB3, 0x89, 0x0C,
+ 0x01, 0x7B, 0x66, 0x87, 0x78,
+ 0x0E, 0xC1, 0x2B, 0x8B, 0x40,
+ 0x0C, 0x27, 0xC8, 0xF3, 0xE6,
+ 0x05, 0x48, 0xE3, 0x6C, 0x39,
+ 0x02, 0x20, 0x10, 0x8B, 0xBD,
+ 0x00, 0x03, 0x73, 0xE9, 0x1F,
+ 0x0A, 0xD3, 0xF6, 0x49, 0x6F,
+ 0x00, 0xA8, 0x38, 0x0D, 0xE5,
+ 0x03, 0xDD, 0x91, 0xE3, 0xEC,
+ 0x0B, 0x44, 0xE9, 0x0A, 0x39,
+ 0x08, 0x16, 0xA6, 0x2E, 0xC5,
+ 0x0B, 0xCB, 0xB8, 0x1C, 0xE9,
+ 0x0C, 0x77, 0x52, 0x19, 0xC2,
+ 0x0F, 0x4D, 0xFA, 0xF0, 0x3F,
+ 0x03, 0xDF, 0x03, 0x32, 0x09,
+ 0x0E, 0xD1, 0xE4, 0xCD, 0x8A,
+ 0x00, 0x6C, 0xB5, 0xC4, 0xC4,
+ 0x01, 0x88, 0xF8, 0x4E, 0x55,
+ 0x06, 0xF4, 0xDC, 0x8A, 0x15,
+ 0x0E, 0x6E, 0xD2, 0xDB, 0x62,
+ 0x09, 0x33, 0xAD, 0xCA, 0x3C,
+ 0x06, 0xA2, 0x07, 0x55, 0x27,
+ 0x06, 0x38, 0x09, 0x4D, 0x18,
+ 0x07, 0x7E, 0xE2, 0x8A, 0x17,
+ 0x07, 0x70, 0x39, 0xD6, 0x08,
+ 0x02, 0x25, 0xB3, 0x99, 0xED,
+ 0x0A, 0x1D, 0xE1, 0xC9, 0x8D,
+ 0x0A, 0x2E, 0x64, 0x12, 0x1D,
+ 0x07, 0xCF, 0x99, 0x15, 0xA3,
+ 0x0C, 0xAB, 0x49, 0x86, 0xC9,
+ 0x03, 0xB0, 0x7C, 0xAB, 0x0D,
+ 0x01, 0x33, 0x14, 0x26, 0x8F,
+ 0x09, 0x25, 0xBF, 0x30, 0x24,
+ 0x00, 0x31, 0x94, 0x4F, 0xBD,
+ 0x0F, 0x8D, 0x38, 0x4F, 0x1B,
+ 0x04, 0x1A, 0xD9, 0xBD, 0x5E,
+ 0x02, 0xA8, 0x94, 0xA2, 0xAE,
+ 0x08, 0x7A, 0x24, 0xF8, 0x14,
+ 0x08, 0x67, 0x09, 0xD9, 0x86,
+ 0x00, 0x40, 0x27, 0x0B, 0x79,
+ 0x00, 0xE8, 0x25, 0x3B, 0x76,
+ 0x07, 0xB6, 0x8A, 0x4B, 0xDB,
+ 0x0C, 0x90, 0xF3, 0x8D, 0x80,
+ 0x0D, 0x39, 0x55, 0x9B, 0xDC,
+ 0x0A, 0xE0, 0xEE, 0x99, 0x32,
+ 0x03, 0xFF, 0xED, 0x40, 0x80,
+ 0x03, 0xAD, 0x70, 0xF0, 0xC2,
+ 0x07, 0x66, 0x5C, 0xBE, 0xF8,
+ 0x0D, 0x37, 0xC0, 0xB5, 0xF5,
+ 0x09, 0x29, 0x9B, 0xDD, 0x00,
+ 0x0E, 0xC8, 0x2A, 0xA4, 0xD0,
+ 0x0E, 0x17, 0xB6, 0x6E, 0x3D,
+ 0x03, 0xFC, 0x1E, 0xFC, 0x79,
+ 0x00, 0x4A, 0x72, 0x8F, 0x3E,
+ 0x0D, 0x56, 0xCE, 0x26, 0xAC,
+ 0x07, 0xA2, 0xE2, 0xB8, 0xC0,
+ 0x02, 0xAC, 0x36, 0xA2, 0x6E,
+ 0x00, 0xAD, 0x38, 0xE0, 0x5C,
+ 0x04, 0x9A, 0x1D, 0x80, 0x06,
+ 0x09, 0x27, 0xF9, 0x16, 0xFA,
+ 0x02, 0x3C, 0xB9, 0xD0, 0xAB,
+ 0x07, 0xC3, 0x2B, 0xEA, 0x63,
+ 0x06, 0xBC, 0xBB, 0x85, 0x8E,
+ 0x07, 0xD7, 0x51, 0x25, 0x1C,
+ 0x0F, 0x6E, 0xD0, 0xEF, 0x0F,
+ 0x09, 0x3D, 0x31, 0x73, 0x20,
+ 0x0D, 0xEC, 0xDF, 0xFC, 0x98,
+ 0x09, 0x1C, 0x6D, 0xD8, 0x46,
+ 0x04, 0x02, 0x13, 0x80, 0x6F,
+ 0x03, 0x6F, 0x4D, 0xC8, 0xA1,
+ 0x06, 0x7E, 0xCA, 0xAD, 0xF7,
+ 0x05, 0x33, 0x17, 0x8C, 0xA3,
+ 0x01, 0x3A, 0x2E, 0x72, 0x0B,
+ 0x08, 0xFB, 0xA0, 0x56, 0xD7,
+ 0x02, 0xD7, 0xD1, 0xC0, 0x6F,
+ 0x09, 0x77, 0x07, 0x1D, 0x2D,
+ 0x0E, 0xA2, 0x47, 0xB8, 0x54,
+ 0x09, 0xA1, 0xDA, 0x9F, 0xFA,
+ 0x0B, 0xE2, 0xE6, 0xC1, 0xE3,
+ 0x0A, 0x3C, 0xFB, 0xB1, 0x98,
+ 0x03, 0xDA, 0xB8, 0x98, 0x88,
+ 0x0E, 0xC3, 0x11, 0x4D, 0x1F,
+ 0x0E, 0x9B, 0x91, 0x5E, 0x23,
+ 0x0D, 0x92, 0x5B, 0xE2, 0x6A,
+ 0x0E, 0x2B, 0x99, 0x56, 0x17,
+ 0x0C, 0xF0, 0x4B, 0x0C, 0x71,
+ 0x0E, 0x69, 0x6D, 0xBB, 0x85,
+ 0x06, 0x02, 0x61, 0x4A, 0x72,
+ 0x0E, 0x07, 0x3A, 0x59, 0x5F,
+ 0x04, 0x86, 0x70, 0xAB, 0xF1,
+ 0x03, 0xBC, 0x3F, 0xF6, 0x75,
+ 0x05, 0xCC, 0x82, 0x75, 0x76,
+ 0x07, 0x72, 0x52, 0xA4, 0x71,
+ 0x0E, 0x71, 0x31, 0x1E, 0x41,
+ 0x0F, 0x93, 0x75, 0x61, 0xBD,
+ 0x0E, 0xA3, 0x65, 0x75, 0xFB,
+ 0x04, 0xB7, 0xE4, 0xC8, 0x55,
+ 0x00, 0x32, 0x8D, 0x3F, 0x68,
+ 0x07, 0xD6, 0x59, 0xF3, 0x6E,
+ 0x05, 0x73, 0xF6, 0x1B, 0xDF,
+ 0x03, 0x2B, 0x15, 0xF5, 0x5C,
+ 0x08, 0xDC, 0x3E, 0xAA, 0x09,
+ 0x0A, 0x48, 0xDB, 0x46, 0x07,
+ 0x0F, 0x57, 0x01, 0xEF, 0x0B,
+ 0x0E, 0x2D, 0x67, 0x68, 0x73,
+ 0x06, 0xED, 0xC8, 0xF5, 0x68,
+ 0x02, 0x4B, 0xA0, 0x06, 0xCE,
+ 0x07, 0x2A, 0xC3, 0x6C, 0xEC,
+ 0x0C, 0x10, 0xB3, 0xFB, 0x89,
+ 0x0F, 0xC9, 0xA9, 0xBE, 0x0E,
+ 0x0F, 0x19, 0x86, 0x51, 0x67,
+ 0x02, 0x32, 0xF7, 0xDD, 0x06,
+ 0x0D, 0xEC, 0x16, 0xB0, 0xB7,
+ 0x09, 0x2A, 0x27, 0xB8, 0x02,
+ 0x09, 0x3D, 0x79, 0x10, 0x9A,
+ 0x0B, 0x74, 0xE5, 0x02, 0xEC,
+ 0x05, 0x80, 0x39, 0x17, 0x3A,
+ 0x05, 0x52, 0xD1, 0xE7, 0xDA,
+ 0x02, 0x39, 0x66, 0xD3, 0x84,
+ 0x08, 0x72, 0x21, 0x18, 0x52,
+ 0x0D, 0x86, 0xF0, 0xD8, 0xC1,
+ 0x0C, 0x27, 0x0C, 0x92, 0x1F,
+ 0x0A, 0xDD, 0xD0, 0x19, 0x1D,
+ 0x0C, 0x17, 0x06, 0xC1, 0x19,
+ 0x0F, 0x0D, 0x9E, 0x0D, 0xAD,
+ 0x01, 0x2D, 0xBD, 0x54, 0xCA,
+ 0x06, 0x12, 0x90, 0x3D, 0x98,
+ 0x00, 0x2A, 0x26, 0xB4, 0x52,
+ 0x09, 0x9A, 0x1D, 0xE5, 0xBF,
+ 0x05, 0xBE, 0x2A, 0x60, 0x52,
+ 0x0D, 0x23, 0x6F, 0x9B, 0x15,
+ 0x02, 0x8C, 0x6B, 0x89, 0x88,
+ 0x02, 0x42, 0x34, 0x98, 0xEB,
+ 0x0D, 0xE9, 0xB9, 0x14, 0x2B,
+ 0x0E, 0xD8, 0xE5, 0xBB, 0xF1,
+ 0x0F, 0xE0, 0xD1, 0x95, 0xA9,
+ 0x06, 0x6D, 0x4E, 0xB6, 0x4F,
+ 0x06, 0xF2, 0xFE, 0xDB, 0x70,
+ 0x00, 0xF9, 0x59, 0x14, 0x8F,
+ 0x0C, 0xE0, 0x73, 0xA0, 0x75,
+ 0x04, 0x48, 0x67, 0x0B, 0xDB,
+ 0x05, 0x3B, 0x03, 0xFE, 0x0F,
+ 0x0C, 0x5C, 0xC8, 0x25, 0x71,
+ 0x0E, 0xDF, 0xFE, 0x2E, 0xC7,
+ 0x00, 0x57, 0x13, 0x11, 0x00,
+ 0x08, 0x60, 0xD3, 0x96, 0x05,
+ 0x0B, 0x72, 0x20, 0x52, 0xD4,
+ 0x0A, 0x4B, 0x7E, 0x4C, 0x9B,
+ 0x08, 0xCB, 0x88, 0xD4, 0xBE,
+ 0x07, 0x0D, 0x65, 0x9E, 0x3D,
+ 0x0E, 0x35, 0xB3, 0x64, 0xF5,
+ 0x0D, 0x50, 0x2D, 0x5E, 0x5D,
+ 0x03, 0x67, 0xAD, 0xEF, 0xE8,
+ 0x09, 0xDE, 0xD7, 0xB6, 0xA8,
+ 0x04, 0x96, 0x3C, 0x1A, 0x38,
+ 0x01, 0x12, 0x0A, 0x77, 0x4F,
+ 0x0E, 0xFD, 0xF0, 0x8E, 0x36,
+ 0x0E, 0x26, 0x22, 0x01, 0x08,
+ 0x02, 0x72, 0xAC, 0x37, 0xA6,
+ 0x06, 0x50, 0xAD, 0x39, 0x24,
+ 0x0E, 0x34, 0x3A, 0x99, 0xC0,
+ 0x06, 0xD0, 0x0D, 0xFD, 0x16,
+ 0x01, 0xCB, 0x3C, 0x7D, 0xD0,
+ 0x03, 0x6E, 0x41, 0x65, 0x2A,
+ 0x08, 0xD4, 0x3E, 0xB7, 0x81,
+ 0x04, 0x97, 0x74, 0x51, 0x01,
+ 0x00, 0x2F, 0x6D, 0x50, 0xEC,
+ 0x07, 0x7E, 0xBD, 0xF1, 0x33,
+ 0x0A, 0x90, 0x48, 0x1E, 0x3C,
+ 0x00, 0x29, 0xBE, 0x60, 0x1C,
+ 0x04, 0xC5, 0xA2, 0x1C, 0x44,
+ 0x0D, 0xD1, 0xCF, 0x40, 0x08,
+ 0x01, 0x5A, 0x7E, 0xC4, 0x29,
+ 0x09, 0x35, 0x33, 0x05, 0xC9,
+ 0x08, 0xCF, 0x50, 0x28, 0x0E,
+ 0x0D, 0xFB, 0x19, 0x2D, 0x92,
+ 0x04, 0x30, 0x97, 0xD5, 0x80,
+ 0x0F, 0x7D, 0x73, 0x83, 0x8D,
+ 0x0E, 0x9E, 0x62, 0x43, 0xF8,
+ 0x0E, 0xD9, 0xA1, 0xDE, 0x1F,
+ 0x00, 0x7B, 0xE2, 0xE6, 0x41,
+ 0x02, 0x5E, 0x96, 0xFF, 0x32,
+ 0x09, 0xBB, 0x38, 0x38, 0x98,
+ 0x01, 0xB6, 0x63, 0x09, 0x0A,
+ 0x0A, 0xDA, 0x9C, 0x91, 0x52,
+ 0x0D, 0xCD, 0x52, 0x5B, 0x32,
+ 0x0A, 0x66, 0x05, 0x17, 0x0F,
+ 0x07, 0xF4, 0x58, 0x6B, 0x66,
+ 0x01, 0xF7, 0x41, 0x2B, 0x31,
+ 0x09, 0xAF, 0xAA, 0x01, 0x59,
+ 0x02, 0xEE, 0x07, 0x39, 0x0B,
+ 0x05, 0xC7, 0xA5, 0x32, 0x29,
+ 0x0B, 0x41, 0x9C, 0x6F, 0x34,
+ 0x0D, 0xC1, 0xC7, 0x02, 0x57,
+ 0x0C, 0xF9, 0x53, 0x62, 0xA4,
+ 0x01, 0xB5, 0x71, 0x31, 0xE2,
+ 0x08, 0x46, 0x13, 0x57, 0xE3,
+ 0x0D, 0x37, 0x22, 0xD6, 0x2D,
+ 0x0B, 0x24, 0xB7, 0x26, 0x56,
+ 0x07, 0x82, 0x81, 0x09, 0x65,
+ 0x08, 0xB1, 0xD6, 0x49, 0xE3,
+ 0x0E, 0x83, 0x5B, 0x66, 0x0B,
+ 0x04, 0xD1, 0xB1, 0x13, 0x94,
+ 0x0C, 0x0E, 0x70, 0x9E, 0xBA,
+ 0x09, 0x0C, 0xE5, 0x75, 0x2F,
+ 0x07, 0x78, 0x7A, 0x42, 0xEA,
+ 0x00, 0x1D, 0xBD, 0xA9, 0xAC,
+ 0x03, 0xE6, 0xC9, 0xCE, 0x29,
+ 0x01, 0x66, 0xDB, 0x26, 0x61,
+ 0x0C, 0x27, 0x2D, 0x45, 0xB0,
+ 0x0C, 0x45, 0x0F, 0xD5, 0x36,
+ 0x09, 0x6F, 0xC9, 0xAA, 0xE2,
+ 0x0C, 0x05, 0x9A, 0x5F, 0xD1,
+ 0x03, 0x4C, 0x13, 0xC7, 0xDD,
+ 0x0F, 0x35, 0x8C, 0x94, 0x3E,
+ 0x03, 0x07, 0x2B, 0xCD, 0x38,
+ 0x06, 0xED, 0x25, 0xF5, 0x1A,
+ 0x09, 0xC2, 0xF1, 0x4D, 0x04,
+ 0x00, 0xFF, 0x82, 0x5B, 0xDD,
+ 0x02, 0x09, 0x4E, 0xDD, 0xED,
+ 0x07, 0x8E, 0x8A, 0xC6, 0xD4,
+ 0x0D, 0x47, 0x20, 0x23, 0x98,
+ 0x07, 0x57, 0xE2, 0xF4, 0x1C,
+ 0x0A, 0x15, 0xA6, 0xE8, 0x58,
+ 0x05, 0x97, 0x48, 0x30, 0x1A,
+ 0x0A, 0x34, 0xBF, 0xA2, 0xCD,
+ 0x00, 0xE7, 0x6F, 0xBA, 0x3C,
+ 0x04, 0xD8, 0xEC, 0xFF, 0xD4,
+ 0x00, 0x53, 0x88, 0xF0, 0x79,
+ 0x0B, 0x7A, 0x2A, 0x26, 0xB3,
+ 0x05, 0xED, 0x9A, 0x13, 0xA8,
+ 0x05, 0x03, 0xA1, 0xAE, 0x24,
+ 0x0B, 0x9F, 0x83, 0xCD, 0x1B,
+ 0x0F, 0x27, 0x92, 0x2B, 0x8B,
+ 0x08, 0x80, 0x42, 0x3C, 0xAD,
+ 0x0B, 0x0D, 0xEB, 0xB9, 0x14,
+ 0x05, 0xCE, 0xE9, 0x25, 0xBF,
+ 0x06, 0xA6, 0x60, 0x1F, 0x89,
+ 0x05, 0x7F, 0x44, 0x4E, 0xBC,
+ 0x07, 0x9F, 0xC0, 0x1A, 0x5B,
+ 0x08, 0xF8, 0xDA, 0xA8, 0x94,
+ 0x05, 0x2A, 0xC5, 0xF3, 0xA0,
+ 0x0C, 0xD4, 0x88, 0x6B, 0x4B,
+ 0x01, 0x30, 0x1F, 0x43, 0xBE,
+ 0x07, 0xFC, 0xFC, 0xC8, 0x25,
+ 0x0B, 0x47, 0x9B, 0x36, 0x2A,
+ 0x07, 0x1B, 0x5B, 0x13, 0x11,
+ 0x02, 0x84, 0x65, 0x3F, 0x16,
+ 0x03, 0x53, 0xD6, 0x28, 0xD6,
+ 0x0F, 0x53, 0xE9, 0x70, 0x04,
+ 0x05, 0x41, 0x82, 0x24, 0xD2,
+ 0x07, 0x81, 0x7D, 0x68, 0x5E,
+ 0x0E, 0xE8, 0x37, 0x91, 0x22,
+ 0x0F, 0xF1, 0x70, 0x29, 0x5A,
+ 0x0D, 0xC0, 0xE5, 0x47, 0x2F,
+ 0x00, 0x90, 0x4A, 0x17, 0x76,
+ 0x00, 0xF7, 0x26, 0xFE, 0x9E,
+ 0x03, 0x3D, 0x2C, 0xCA, 0x44,
+ 0x06, 0xBC, 0x6D, 0x56, 0x0E,
+ 0x0C, 0xAA, 0x0B, 0x22, 0x05,
+ 0x01, 0xC2, 0xB2, 0xAC, 0x37,
+ 0x06, 0xE4, 0x50, 0xA1, 0x0D,
+ 0x04, 0x96, 0xFD, 0x16, 0x13,
+ 0x00, 0xC6, 0x53, 0xA3, 0x77,
+ 0x0A, 0x3A, 0xCB, 0xFC, 0x4E,
+ 0x0C, 0x6B, 0x6A, 0xC1, 0x59,
+ 0x02, 0xA0, 0xD2, 0xB2, 0xBB,
+ 0x09, 0xCF, 0x13, 0xDB, 0xD1,
+ 0x01, 0x9C, 0x2F, 0x62, 0x55,
+ 0x0F, 0x0F, 0xF8, 0x39, 0xC3,
+ 0x03, 0x20, 0x94, 0xE0, 0x9D,
+ 0x00, 0xD8, 0xA8, 0xDC, 0x6E,
+ 0x0C, 0x4C, 0x46, 0x0C, 0x58,
+ 0x0C, 0xE5, 0xD8, 0xE3, 0xD0,
+ 0x00, 0xA0, 0xDB, 0xFE, 0x89,
+ 0x05, 0x79, 0x94, 0xB1, 0x81,
+ 0x07, 0x27, 0xF7, 0x7E, 0x1E,
+ 0x0D, 0x16, 0xD8, 0xF9, 0x20,
+ 0x0C, 0xD9, 0xB4, 0xD7, 0xF5,
+ 0x09, 0xA5, 0xB9, 0x77, 0xC3,
+ 0x0D, 0x27, 0xAA, 0xA2, 0x43,
+ 0x08, 0x5E, 0xD9, 0xA1, 0xDE,
+ 0x07, 0xF0, 0xF9, 0xE2, 0x26,
+ 0x0B, 0x2D, 0x90, 0xBC, 0xFB,
+ 0x0F, 0xD3, 0x08, 0xDA, 0xB8,
+ 0x00, 0x00, 0xA4, 0x2E, 0xC9,
+ 0x0A, 0xB0, 0xDC, 0xBB, 0x98,
+ 0x02, 0xB4, 0xFD, 0xB6, 0x08,
+ 0x0A, 0xEA, 0xC6, 0x03, 0x93,
+ 0x0F, 0x37, 0x14, 0x58, 0x6B,
+ 0x0C, 0xF1, 0xF7, 0x72, 0xAE,
+ 0x0B, 0x05, 0xAF, 0xEC, 0xDA,
+ 0x0A, 0xF2, 0xEE, 0x00, 0xE0,
+ 0x03, 0x42, 0xBB, 0x7A, 0x41,
+ 0x0D, 0xB3, 0x43, 0xB2, 0x76,
+ 0x04, 0xF7, 0xC4, 0x4A, 0x01,
+ 0x0A, 0xB4, 0xB8, 0x73, 0xE2,
+ 0x05, 0x2B, 0xF4, 0x7C, 0xB5,
+ 0x0A, 0x0C, 0x01, 0x93, 0x97,
+ 0x08, 0xBD, 0xF7, 0x20, 0x05,
+ 0x03, 0xFF, 0x63, 0x37, 0xC4,
+ 0x08, 0xCC, 0x05, 0xF2, 0x83,
+ 0x0F, 0xE8, 0xB1, 0xD8, 0x44,
+ 0x0A, 0xEE, 0x43, 0x57, 0x36,
+ 0x03, 0xDD, 0x21, 0x04, 0xD5,
+ 0x0F, 0xD8, 0x4A, 0xF4, 0x96,
+ 0x00, 0x49, 0x0E, 0xE9, 0xFC,
+ 0x0E, 0x07, 0xD8, 0x7E, 0x41,
+ 0x04, 0x08, 0x7B, 0x84, 0xA7,
+ 0x0A, 0xF3, 0xE7, 0xC3, 0xC8,
+ 0x03, 0x6A, 0xE2, 0x62, 0x20,
+ 0x01, 0x8C, 0xE7, 0x2A, 0xC3,
+ 0x02, 0xEC, 0x05, 0x08, 0x62,
+ 0x0C, 0x4D, 0x28, 0x49, 0xAD,
+ 0x08, 0x0C, 0x65, 0x1C, 0xEE,
+ 0x08, 0x63, 0x6C, 0xB3, 0x87,
+ 0x05, 0x04, 0xB6, 0xE0, 0x16,
+ 0x0E, 0xAA, 0x05, 0x37, 0x89,
+ 0x08, 0x1C, 0xE9, 0x3E, 0x43,
+ 0x02, 0x19, 0xC0, 0xF6, 0x89,
+ 0x04, 0xF4, 0xC7, 0x83, 0xCF,
+ 0x0E, 0xB2, 0xE9, 0x42, 0x11,
+ 0x0E, 0x4F, 0xEA, 0x9D, 0xC6,
+ 0x05, 0xC4, 0xC4, 0x40, 0x21,
+ 0x08, 0x4E, 0x55, 0x82, 0x07,
+ 0x06, 0x8E, 0x24, 0x27, 0xFC,
+ 0x0E, 0xDF, 0x92, 0xD3, 0x01,
+ 0x00, 0xC2, 0xB4, 0xB2, 0x62,
+ 0x0F, 0x5B, 0x67, 0x83, 0xFA,
+ 0x01, 0x6D, 0xD1, 0x6D, 0x7E,
+ 0x0C, 0x8A, 0xF7, 0x99, 0x70,
+ 0x01, 0x53, 0xDA, 0xEA, 0x64,
+ 0x03, 0x85, 0xED, 0x9A, 0x59,
+ 0x01, 0xFF, 0x07, 0xBD, 0x5D,
+ 0x0F, 0x96, 0x5E, 0x2E, 0x4A,
+ 0x05, 0x94, 0x13, 0x8D, 0xAB,
+ 0x09, 0x88, 0x80, 0x76, 0x6D,
+ 0x0C, 0xAB, 0x09, 0xD5, 0xEA,
+ 0x06, 0x2B, 0x4B, 0xE9, 0xA5,
+ 0x0D, 0x26, 0xA2, 0x20, 0xB1,
+ 0x07, 0x69, 0xBF, 0x75, 0x0E,
+ 0x01, 0xCE, 0xD3, 0x44, 0x9A,
+ 0x08, 0xB1, 0x96, 0xCA, 0x28,
+ 0x07, 0xAE, 0xE2, 0xC0, 0xF3,
+ 0x07, 0xF4, 0x14, 0x48, 0xE7,
+ 0x0A, 0xDA, 0xF4, 0x3B, 0xC3,
+ 0x0F, 0x0E, 0xBC, 0x5C, 0xC8,
+ 0x0C, 0xEA, 0xE7, 0x93, 0x36,
+ 0x02, 0x45, 0x1B, 0x5B, 0x13,
+ 0x01, 0x00, 0x84, 0x47, 0xBB,
+ 0x0C, 0x1F, 0x82, 0xF2, 0x38,
+ 0x0D, 0x1B, 0x71, 0xCF, 0xBD,
+ 0x0D, 0x4C, 0xC0, 0x60, 0x1A,
+ 0x02, 0xFE, 0x8B, 0x10, 0x60,
+ 0x06, 0x3E, 0x68, 0x35, 0xB7,
+ 0x08, 0x35, 0x55, 0x50, 0x29,
+ 0x00, 0xDC, 0xF0, 0xE7, 0x49,
+ 0x0B, 0xA8, 0x92, 0xE0, 0x0A,
+ 0x0E, 0x69, 0xF7, 0x9B, 0xFC,
+ 0x08, 0xF8, 0xB9, 0xB0, 0xCA,
+ 0x00, 0x8F, 0x3E, 0x6C, 0xD4,
+ 0x09, 0x36, 0x6E, 0x26, 0xA2,
+ 0x00, 0x08, 0x02, 0x76, 0xAF,
+ 0x06, 0x26, 0x04, 0x50, 0xA4,
+ 0x0F, 0x64, 0x96, 0xFA, 0x10,
+ 0x01, 0x82, 0xC6, 0x51, 0x65,
+ 0x07, 0x12, 0x59, 0x4B, 0x3E,
+ 0x09, 0xD0, 0x6B, 0x68, 0x41,
+ 0x0F, 0xEA, 0xA0, 0x54, 0x7C,
+ 0x0B, 0x00, 0x6E, 0x9D, 0x9E,
+ 0x01, 0xA0, 0x3D, 0xAF, 0x6C,
+ 0x08, 0xEF, 0x8E, 0x78, 0x7D,
+ 0x08, 0x79, 0x22, 0x99, 0x2D,
+ 0x04, 0x78, 0x84, 0xA9, 0x18,
+ 0x06, 0xDF, 0xAE, 0xC8, 0x86,
+ 0x01, 0x84, 0xE7, 0x58, 0x32,
+ 0x05, 0xC0, 0x20, 0x57, 0xBE,
+ 0x09, 0x2D, 0xF9, 0x35, 0x33,
+ 0x08, 0x8E, 0xE3, 0x49, 0x7A,
+ 0x06, 0x71, 0xFF, 0x78, 0xEB,
+ 0x00, 0xD6, 0xD9, 0x82, 0xD7,
+ 0x05, 0x40, 0xA9, 0x79, 0x77,
+ 0x01, 0x9D, 0x21, 0x28, 0x22,
+ 0x0A, 0x38, 0x98, 0x5B, 0x21,
+ 0x0F, 0x1E, 0x35, 0xF7, 0x27,
+ 0x06, 0x41, 0x2C, 0x5A, 0x07,
+ 0x01, 0x33, 0x12, 0x38, 0x1A,
+ 0x08, 0x7A, 0xA8, 0x04, 0xD2,
+ 0x09, 0xCA, 0xB1, 0x58, 0x11,
+ 0x01, 0x42, 0xB6, 0xF9, 0xD8,
+ 0x01, 0xF6, 0x18, 0x66, 0x01,
+ 0x09, 0x46, 0x97, 0xF8, 0x63,
+ 0x05, 0xAD, 0xC1, 0xF7, 0x41,
+ 0x04, 0x3B, 0xE5, 0xAF, 0x2A,
+ 0x08, 0x48, 0x92, 0xE2, 0x47,
+ 0x00, 0x4B, 0x2D, 0xC4, 0x8E,
+ 0x00, 0xBD, 0xB3, 0x4F, 0xFE,
+ 0x07, 0xE2, 0xF7, 0xD9, 0xCC,
+ 0x08, 0x57, 0xDA, 0x79, 0xE3,
+ 0x0A, 0xAC, 0xF1, 0xB8, 0xB1,
+ 0x01, 0x10, 0x08, 0x4A, 0x97,
+ 0x09, 0x61, 0xB6, 0xB7, 0x21,
+ 0x0C, 0x69, 0x3B, 0x2A, 0xB7,
+ 0x0D, 0xD5, 0x0C, 0x06, 0x72,
+ 0x03, 0xAE, 0xD8, 0xB1, 0xD6,
+ 0x09, 0xE3, 0xEC, 0xAD, 0x12,
+ 0x06, 0x0B, 0x5E, 0xD1, 0x9F,
+ 0x0D, 0x65, 0x7D, 0x8E, 0xF4,
+ 0x06, 0x38, 0xA8, 0x0C, 0x61,
+ 0x07, 0x66, 0x87, 0xF8, 0x71,
+ 0x08, 0x6F, 0x7E, 0x9B, 0x84,
+ 0x0D, 0x6C, 0x8E, 0xE6, 0xE5,
+ 0x01, 0x63, 0x8E, 0xEC, 0xA2,
+ 0x0A, 0x14, 0xF7, 0x27, 0x6A,
+ 0x0A, 0xFA, 0x9A, 0x43, 0x4A,
+ 0x09, 0xF2, 0x34, 0x6F, 0xD9,
+ 0x09, 0x98, 0x08, 0x65, 0x1A,
+ 0x05, 0xD5, 0x1E, 0xAC, 0xB2,
+ 0x0E, 0x5D, 0xE6, 0xB0, 0xAC,
+ 0x0C, 0xBA, 0xD7, 0x05, 0x3B,
+ 0x0B, 0xB8, 0x18, 0xE9, 0x3D,
+ 0x05, 0x12, 0x15, 0xC2, 0xF6,
+ 0x0F, 0x0E, 0xF0, 0xF9, 0xC3,
+ 0x07, 0x97, 0x92, 0x09, 0xCE,
+ 0x01, 0x66, 0x6D, 0x8E, 0x0C,
+ 0x0F, 0x55, 0x24, 0xC4, 0x40,
+ 0x09, 0x1A, 0x4E, 0x59, 0x86,
+ 0x04, 0xDC, 0x88, 0x33, 0xE5,
+ 0x06, 0x96, 0xAB, 0x93, 0x43,
+ 0x00, 0x18, 0xCA, 0x38, 0x7B,
+ 0x02, 0xC7, 0x5B, 0x6A, 0x8A,
+ 0x0A, 0x0D, 0x6B, 0xD6, 0xE7,
+ 0x0D, 0x54, 0x0E, 0x57, 0x66,
+ 0x00, 0x39, 0xD2, 0x7A, 0x19,
+ 0x0C, 0x3B, 0x05, 0xE0, 0x5A,
+ 0x03, 0x60, 0xCF, 0x07, 0xBE,
+ 0x0E, 0x64, 0x10, 0xBD, 0xAA,
+ 0x0F, 0x9B, 0x15, 0x3F, 0xDA,
+ 0x02, 0x20, 0x68, 0xB0, 0xC8,
+ 0x04, 0x9C, 0xAB, 0x0D, 0x69,
+ 0x0D, 0x14, 0x2B, 0x4F, 0x59,
+ 0x05, 0x3F, 0x86, 0xA8, 0x29,
+ 0x00, 0x94, 0xA8, 0xFF, 0x45,
+ 0x06, 0xB0, 0xCE, 0x93, 0x74,
+ 0x0A, 0xDB, 0xB1, 0xCC, 0xB8,
+ 0x08, 0x14, 0xAD, 0x08, 0x62,
+ 0x09, 0xA0, 0x76, 0x54, 0x58,
+ 0x07, 0x0B, 0xD9, 0x3A, 0xBF,
+ 0x0B, 0x7C, 0x6E, 0xF0, 0x9C,
+ 0x08, 0x25, 0x39, 0x41, 0x55,
+ 0x0C, 0x2E, 0xEF, 0x1B, 0x5F,
+ 0x03, 0x11, 0x00, 0x89, 0x24,
+ 0x01, 0x46, 0x9B, 0xDE, 0xB2,
+ 0x06, 0xD7, 0xAF, 0xB2, 0x4B,
+ 0x06, 0xCD, 0xEC, 0xD0, 0xE3,
+ 0x03, 0x51, 0x1C, 0x0B, 0x11,
+ 0x0D, 0x1E, 0x9E, 0xC8, 0xB5,
+ 0x0C, 0xE3, 0x57, 0x73, 0xE1,
+ 0x09, 0x5E, 0x4D, 0xC2, 0x2A,
+ 0x05, 0xD1, 0xA8, 0x90, 0xD7,
+ 0x07, 0xB6, 0x60, 0x75, 0x4A,
+ 0x0C, 0x1E, 0xF0, 0xB9, 0x90,
+ 0x08, 0x76, 0x87, 0x32, 0x2C,
+ 0x06, 0x8E, 0x3E, 0xA2, 0x66,
+ 0x00, 0xA9, 0xB8, 0xC4, 0xF2,
+ 0x0F, 0x1F, 0x66, 0xE2, 0xD0,
+ 0x0C, 0x97, 0x84, 0x96, 0xFC,
+ 0x0A, 0x31, 0x20, 0xD0, 0x13,
+ 0x05, 0xFD, 0x16, 0x2C, 0x49,
+ 0x0C, 0x7D, 0xD0, 0x7D, 0xAC,
+ 0x01, 0x6B, 0xEA, 0x86, 0x10,
+ 0x04, 0xB9, 0x81, 0xC2, 0x93,
+ 0x0D, 0x55, 0xAD, 0x1C, 0x3F,
+ 0x07, 0xD0, 0xEF, 0x0F, 0xF8,
+ 0x01, 0xEE, 0x8C, 0xDC, 0xA5,
+ 0x01, 0x1A, 0x1C, 0xD8, 0xAD,
+ 0x06, 0xAD, 0x9C, 0x45, 0x75,
+ 0x02, 0x11, 0x84, 0xF9, 0x1A,
+ 0x03, 0x49, 0x28, 0xA1, 0x5E,
+ 0x04, 0x09, 0x6D, 0xF0, 0x01,
+ 0x03, 0x01, 0x8C, 0xBF, 0x09,
+ 0x06, 0x2C, 0x12, 0x96, 0x71,
+ 0x03, 0xED, 0x54, 0xD1, 0x82,
+ 0x07, 0xD5, 0x40, 0x29, 0x33,
+ 0x07, 0x03, 0x9D, 0xAB, 0xE4,
+ 0x02, 0x43, 0x3A, 0x5A, 0xD3,
+ 0x0D, 0xDC, 0x7F, 0xF0, 0x7F,
+ 0x08, 0x26, 0x81, 0x20, 0xE6,
+ 0x0C, 0xF9, 0xB1, 0x4E, 0x7A,
+ 0x06, 0xBA, 0x78, 0x88, 0x00,
+ 0x09, 0xC9, 0x8A, 0xB9, 0xE1,
+ 0x0B, 0x91, 0x42, 0xA8, 0xBF,
+ 0x0E, 0x5B, 0x98, 0xEA, 0x6F,
+ 0x0B, 0x54, 0xC4, 0x9B, 0xF4,
+ 0x08, 0xEB, 0x2C, 0x7D, 0xBD,
+ 0x01, 0xAD, 0xBB, 0x89, 0xE5,
+ 0x0A, 0x81, 0x48, 0xF6, 0xE4,
+ 0x0C, 0x3A, 0x4F, 0x5D, 0x44,
+ 0x06, 0x70, 0xBD, 0xBD, 0x0A,
+ 0x0C, 0x3F, 0xE1, 0x77, 0xC5,
+ 0x0C, 0x82, 0x52, 0xB4, 0x79,
+ 0x03, 0x62, 0xA4, 0x71, 0xBF,
+ 0x01, 0x31, 0x10, 0x06, 0x0F,
+ 0x03, 0x95, 0x60, 0x3D, 0x37,
+ 0x02, 0x85, 0x68, 0x7B, 0x24,
+ 0x07, 0xE4, 0xD5, 0x4C, 0x06,
+ 0x02, 0x8D, 0x2E, 0xE8, 0xB1,
+ 0x06, 0x59, 0xE1, 0xEE, 0x89,
+ 0x0B, 0x76, 0x0B, 0x52, 0x11,
+ 0x08, 0x75, 0xFE, 0x55, 0x5C,
+ 0x04, 0x9E, 0xBA, 0x99, 0x0E,
+ 0x0A, 0x7B, 0x66, 0x87, 0x78,
+ 0x07, 0x41, 0x4F, 0x8B, 0x99,
+ 0x0D, 0x27, 0x88, 0xF3, 0xE6,
+ 0x0B, 0xC9, 0xD3, 0x6A, 0xE2,
+ 0x02, 0x20, 0x10, 0x92, 0x3A,
+ 0x03, 0x42, 0x9A, 0x42, 0x54,
+ 0x0C, 0xD3, 0xF6, 0x49, 0xEF,
+ 0x0F, 0xA9, 0x98, 0x0C, 0xE5,
+ 0x0A, 0x3F, 0x51, 0x63, 0xAC,
+ 0x03, 0xA6, 0x5D, 0x06, 0xB6,
+ 0x05, 0x14, 0xDA, 0xAA, 0xC5,
+ 0x01, 0xCF, 0x08, 0x1C, 0xEB,
+ 0x05, 0xD4, 0xB2, 0x1F, 0xC2,
+ 0x0E, 0xC5, 0x8E, 0xF6, 0xFF,
+ 0x0B, 0xD6, 0x97, 0x32, 0x89,
+ 0x07, 0xDB, 0x87, 0xC0, 0x4A,
+ 0x01, 0xC6, 0xD5, 0xC4, 0xC4,
+ 0x00, 0x21, 0x18, 0x68, 0x57,
+ 0x0C, 0xF0, 0x77, 0x8A, 0x11,
+ 0x0C, 0xEC, 0x92, 0xDF, 0x93,
+ 0x0A, 0xB0, 0xFA, 0xC6, 0x34,
+ 0x07, 0x22, 0x67, 0x49, 0xE7,
+ 0x01, 0x3B, 0x3D, 0x6D, 0xD8,
+ 0x04, 0xFC, 0xB4, 0x06, 0x57,
+ 0x0F, 0x72, 0x19, 0xD2, 0xFA,
+ 0x00, 0x20, 0x84, 0x85, 0xEF,
+ 0x02, 0x9D, 0x41, 0xFF, 0x87,
+ 0x06, 0x2C, 0x04, 0x0E, 0x1D,
+ 0x09, 0xCB, 0x2F, 0x95, 0x27,
+ 0x0D, 0xAB, 0x8B, 0x88, 0x80,
+ 0x09, 0x30, 0x9C, 0xA5, 0x10,
+ 0x0B, 0xB9, 0x14, 0x27, 0x0F,
+ 0x00, 0xA5, 0x5B, 0x2A, 0xE6,
+ 0x00, 0x11, 0x14, 0x69, 0x7F,
+ 0x05, 0xAC, 0xB2, 0xCF, 0x1F,
+ 0x0E, 0x1E, 0x67, 0xB0, 0x58,
+ 0x03, 0x29, 0x94, 0xAD, 0xAE,
+ 0x0B, 0x73, 0xA4, 0xF9, 0xC5,
+ 0x01, 0x65, 0x2F, 0xDB, 0xC5,
+ 0x01, 0xC7, 0x40, 0x0F, 0x74,
+ 0x04, 0x48, 0x85, 0x37, 0x07,
+ 0x06, 0x34, 0x0E, 0x47, 0xEA,
+ 0x0D, 0x17, 0xAE, 0x80, 0x86,
+ 0x09, 0xB9, 0xF6, 0x17, 0x93,
+ 0x0A, 0xAA, 0x72, 0x93, 0xF2,
+ 0x02, 0x7E, 0x89, 0x4C, 0x31,
+ 0x01, 0x28, 0xD6, 0xFA, 0xCB,
+ 0x0D, 0x65, 0x9E, 0x3E, 0x31,
+ 0x04, 0x9E, 0xA0, 0xB5, 0xF5,
+ 0x0A, 0x2D, 0x9D, 0x5D, 0xC8,
+ 0x0E, 0x49, 0x2B, 0xA8, 0x90,
+ 0x05, 0x17, 0xB6, 0x68, 0x77,
+ 0x0D, 0x3C, 0x1F, 0x71, 0x32,
+ 0x00, 0x4A, 0x76, 0xAF, 0xBD,
+ 0x0C, 0x54, 0x8E, 0x16, 0xEC,
+ 0x06, 0x22, 0x01, 0x08, 0xC2,
+ 0x02, 0xAC, 0x37, 0xA6, 0xE4,
+ 0x0B, 0xAD, 0x3F, 0x64, 0x96,
+ 0x0C, 0x9A, 0x9B, 0x80, 0xFE,
+ 0x09, 0xA6, 0x7D, 0x18, 0xBA,
+ 0x0B, 0x3C, 0x79, 0xD0, 0x6B,
+ 0x0E, 0xC1, 0x6F, 0xEA, 0xA0,
+ 0x00, 0xBC, 0xBB, 0x87, 0xCE,
+ 0x03, 0xD7, 0xD1, 0x21, 0x9C,
+ 0x0F, 0x6D, 0x50, 0xEF, 0x0F,
+ 0x08, 0x3D, 0xF1, 0x73, 0x20,
+ 0x06, 0xED, 0x1E, 0x70, 0x58,
+ 0x09, 0x1C, 0x6D, 0x5A, 0x46,
+ 0x05, 0xE0, 0x13, 0x84, 0xE5,
+ 0x02, 0x6B, 0x80, 0xC8, 0xB1,
+ 0x01, 0x7E, 0xC9, 0x2D, 0xF9,
+ 0x09, 0x13, 0x01, 0x8C, 0x9B,
+ 0x00, 0xFA, 0x2C, 0x75, 0x96,
+ 0x01, 0x7B, 0x40, 0xDA, 0x9D,
+ 0x08, 0xD2, 0xD7, 0xC0, 0x85,
+ 0x05, 0x77, 0x03, 0x99, 0x11,
+ 0x0E, 0xA2, 0x41, 0x34, 0x83,
+ 0x00, 0x21, 0x3C, 0x15, 0xF0,
+ 0x02, 0xE0, 0x82, 0x41, 0xE9,
+ 0x03, 0x3D, 0x39, 0xBC, 0x12,
+ 0x0A, 0xDA, 0xB8, 0x9C, 0xC8,
+ 0x04, 0x23, 0x09, 0xCE, 0x2D,
+ 0x0E, 0x7B, 0x31, 0x66, 0x36,
+ 0x0D, 0x92, 0x5B, 0xF2, 0x6A,
+ 0x0E, 0x80, 0xB9, 0x42, 0xD7,
+ 0x06, 0x58, 0xEB, 0x28, 0xF1,
+ 0x07, 0x41, 0xAD, 0xB6, 0x18,
+ 0x0E, 0xAA, 0x4D, 0x4A, 0xF2,
+ 0x0E, 0x07, 0x36, 0x4F, 0x5D,
+ 0x04, 0x86, 0x70, 0xBD, 0xB3,
+ 0x01, 0xBC, 0x3F, 0xE4, 0x77,
+ 0x05, 0xCC, 0x82, 0x5F, 0x69,
+ 0x08, 0xF3, 0xA6, 0xA4, 0x71,
+ 0x05, 0x71, 0x35, 0x10, 0x08,
+ 0x0F, 0x10, 0x55, 0x65, 0x3D,
+ 0x0E, 0xA0, 0xC7, 0x6D, 0xBB,
+ 0x0E, 0xB3, 0x3E, 0x54, 0xDC,
+ 0x0F, 0x32, 0x4D, 0x2B, 0xA8,
+ 0x08, 0x54, 0x19, 0xE1, 0x6E,
+ 0x09, 0x5F, 0xAA, 0x8B, 0x4F,
+ 0x0C, 0x02, 0x55, 0xE7, 0x5C,
+ 0x0E, 0x74, 0x9E, 0xBA, 0x89,
+ 0x0E, 0xE1, 0x7F, 0x62, 0x07,
+ 0x08, 0x7F, 0xC1, 0xEF, 0x8B,
+ 0x08, 0x64, 0x67, 0x68, 0xF3,
+ 0x06, 0xC5, 0x48, 0xE3, 0x6A,
+ 0x02, 0x62, 0x22, 0x14, 0x06,
+ 0x0B, 0x2A, 0xC0, 0xBA, 0x5F,
+ 0x05, 0x0A, 0xD3, 0xF6, 0xBB,
+ 0x07, 0x49, 0x09, 0x94, 0x4C,
+ 0x0D, 0x9B, 0xFF, 0xDC, 0x63,
+ 0x0C, 0xB3, 0xC7, 0xDD, 0x06,
+ 0x06, 0xEC, 0x16, 0xBA, 0xF7,
+ 0x05, 0x2B, 0xCB, 0xB8, 0x1C,
+ 0x0B, 0x3D, 0x79, 0x16, 0x99,
+ 0x0A, 0x74, 0xED, 0x02, 0xF0,
+ 0x0E, 0x63, 0x3F, 0x17, 0x32,
+ 0x00, 0xCC, 0xB1, 0xEB, 0x4D,
+ 0x00, 0x95, 0x24, 0x55, 0xD4,
+ 0x04, 0x40, 0x21, 0x14, 0x93,
+ 0x0D, 0x07, 0x56, 0xD0, 0x8A,
+ 0x0D, 0x25, 0xCC, 0x9F, 0xDF,
+ 0x09, 0x57, 0xD7, 0x98, 0xDA,
+ 0x0C, 0x3F, 0x02, 0xC7, 0x59,
+ 0x0E, 0x0D, 0x9A, 0x07, 0x6D,
+ 0x02, 0x29, 0x8E, 0x54, 0x1A,
+ 0x0E, 0x15, 0x50, 0x39, 0x12,
+ 0x00, 0xEE, 0xCE, 0x33, 0x95,
+ 0x05, 0x1A, 0xBD, 0xE1, 0x3F,
+ 0x07, 0xBE, 0x2A, 0xE4, 0x12,
+ 0x0D, 0xA3, 0xCB, 0x9B, 0x15,
+ 0x03, 0x8D, 0xAF, 0x89, 0x88,
+ 0x00, 0x42, 0x34, 0x9C, 0xAB,
+ 0x0D, 0xE9, 0xBD, 0x14, 0x2B,
+ 0x06, 0x59, 0xC7, 0xBD, 0xA6,
+ 0x0F, 0x62, 0x51, 0x94, 0xA9,
+ 0x05, 0x41, 0x7E, 0x32, 0xDF,
+ 0x06, 0x75, 0xF8, 0xD6, 0x30,
+ 0x0A, 0xFA, 0xAB, 0x94, 0xAF,
+ 0x0E, 0xE0, 0x70, 0x20, 0x7F,
+ 0x04, 0x48, 0x65, 0x0B, 0xD1,
+ 0x0E, 0x3F, 0x3E, 0x7E, 0x0E,
+ 0x0C, 0x5C, 0xCA, 0x21, 0x53,
+ 0x07, 0x9F, 0x35, 0xAE, 0x2E,
+ 0x0B, 0x57, 0x10, 0x91, 0x0A,
+ 0x04, 0x61, 0x3B, 0x56, 0x11,
+ 0x09, 0x76, 0xD5, 0xD6, 0x9E,
+ 0x02, 0x4B, 0x7A, 0x4D, 0x4C,
+ 0x00, 0x63, 0x2C, 0xD2, 0xFE,
+ 0x02, 0x9D, 0x83, 0x9C, 0xBE,
+ 0x08, 0x35, 0xB3, 0x60, 0xB5,
+ 0x05, 0x50, 0x29, 0x5E, 0x5D,
+ 0x09, 0xE5, 0x29, 0xEB, 0x68,
+ 0x0A, 0xCA, 0xEF, 0x36, 0x78,
+ 0x0E, 0x86, 0x1E, 0x13, 0x78,
+ 0x09, 0x90, 0x49, 0xF6, 0x85,
+ 0x0E, 0x6C, 0x56, 0x8A, 0xBC,
+ 0x04, 0x22, 0xDF, 0x81, 0x09,
+ 0x0B, 0xF2, 0x4E, 0x3D, 0xA6,
+ 0x0D, 0xD1, 0x4D, 0x33, 0x64,
+ 0x06, 0xFC, 0x99, 0x19, 0x8A,
+ 0x06, 0x51, 0xA7, 0xFD, 0x1C,
+ 0x03, 0xC9, 0x5C, 0x71, 0x90,
+ 0x01, 0x6A, 0x3D, 0xEB, 0xE8,
+ 0x09, 0xD2, 0x5C, 0xB7, 0xC1,
+ 0x0E, 0x93, 0xD7, 0x51, 0x21,
+ 0x0C, 0x2F, 0x6C, 0xD4, 0x07,
+ 0x0F, 0xF8, 0x3D, 0xF5, 0x9A,
+ 0x00, 0x94, 0xEF, 0x1E, 0x7C,
+ 0x08, 0xA9, 0x1C, 0xED, 0x5C,
+ 0x05, 0xC4, 0xE2, 0x31, 0x0E,
+ 0x05, 0x58, 0x6F, 0x4D, 0xC8,
+ 0x01, 0x5A, 0x7E, 0xCD, 0xF0,
+ 0x09, 0x35, 0x33, 0x01, 0x8C,
+ 0x01, 0x4B, 0xFA, 0x2A, 0x75,
+ 0x06, 0x78, 0xF9, 0xA0, 0xD6,
+ 0x0D, 0x82, 0x57, 0xD5, 0x40,
+ 0x0E, 0x79, 0x77, 0x03, 0x9D,
+ 0x07, 0xAE, 0xA0, 0x4E, 0x65,
+ 0x0E, 0xD9, 0xA1, 0x5E, 0x15,
+ 0x00, 0x7B, 0xE2, 0x66, 0x4B,
+ 0x09, 0xDA, 0x3C, 0x79, 0xBB,
+ 0x02, 0x38, 0xDA, 0x38, 0x92,
+ 0x08, 0x04, 0x21, 0x04, 0x80,
+ 0x00, 0xDE, 0x9B, 0xAC, 0x00,
+ 0x04, 0xFD, 0x92, 0x66, 0xB0,
+ 0x0A, 0x66, 0x03, 0x24, 0x04,
+ 0x07, 0xF4, 0x58, 0xD6, 0x6E,
+ 0x01, 0xF7, 0x41, 0x90, 0xF9,
+ 0x05, 0xAF, 0xAA, 0xBC, 0x08,
+ 0x02, 0xEE, 0x07, 0x07, 0x0D,
+ 0x0D, 0x44, 0x86, 0x4D, 0xFF,
+ 0x03, 0x43, 0xBC, 0x02, 0xA2,
+ 0x07, 0xC5, 0xCC, 0xBF, 0x11,
+ 0x04, 0x79, 0xF3, 0x5F, 0xE6,
+ 0x01, 0xB5, 0x71, 0x0C, 0x52,
+ 0x08, 0x46, 0x13, 0xA8, 0x23,
+ 0x0D, 0x37, 0x22, 0x89, 0xB4,
+ 0x0B, 0x24, 0xB7, 0xE4, 0xD4,
+ 0x0C, 0x06, 0x32, 0x8D, 0xC7,
+ 0x03, 0xB1, 0xD6, 0x59, 0x0A,
+ 0x02, 0x83, 0x5F, 0x36, 0x08,
+ 0x06, 0xD5, 0xE2, 0x9B, 0xF8,
+ 0x05, 0x8F, 0x94, 0x9E, 0xFA,
+ 0x01, 0x8C, 0x41, 0x75, 0x2E,
+ 0x0F, 0xF1, 0xDF, 0xC1, 0x2F,
+ 0x02, 0x99, 0xC4, 0xA7, 0x62,
+ 0x09, 0x06, 0xC4, 0xC2, 0xC0,
+ 0x0B, 0xE3, 0xA6, 0xAE, 0xD5,
+ 0x0D, 0x26, 0xEE, 0x65, 0x70,
+ 0x0F, 0x44, 0xCA, 0xC7, 0xBE,
+ 0x08, 0x6E, 0x09, 0x3D, 0x60,
+ 0x0D, 0x64, 0xDA, 0x4F, 0xD1,
+ 0x0B, 0xAC, 0x33, 0xE5, 0x5D,
+ 0x06, 0xB6, 0xEC, 0x18, 0xA3,
+ 0x01, 0x80, 0x31, 0xC5, 0x31,
+ 0x07, 0x6C, 0x1D, 0xFB, 0xD6,
+ 0x01, 0x42, 0x56, 0xCB, 0x0E,
+ 0x00, 0xFF, 0x83, 0xF1, 0xD2,
+ 0x0A, 0x09, 0xCE, 0xF7, 0x67,
+ 0x0D, 0x8A, 0x91, 0xC8, 0xC8,
+ 0x0F, 0x41, 0x5A, 0x2F, 0x91,
+ 0x05, 0xD0, 0xA6, 0x74, 0xDC,
+ 0x03, 0x15, 0x67, 0xEA, 0x92,
+ 0x04, 0x93, 0x53, 0x30, 0x18,
+ 0x0A, 0x34, 0xBD, 0xA2, 0xC7,
+ 0x00, 0xC7, 0x6B, 0x3C, 0x0D,
+ 0x0D, 0xD8, 0x29, 0xFD, 0x54,
+ 0x0A, 0x57, 0x93, 0xF2, 0xBA,
+ 0x02, 0x32, 0x6E, 0x24, 0x33,
+ 0x05, 0xA4, 0x1E, 0x1F, 0x62,
+ 0x0D, 0x4E, 0x3D, 0xA8, 0xA4,
+ 0x02, 0xD4, 0x20, 0x4F, 0xD1,
+ 0x05, 0x6A, 0x0E, 0x2D, 0x43,
+ 0x08, 0x80, 0x43, 0xB0, 0xD6,
+ 0x0B, 0x0D, 0xE9, 0xB9, 0x14,
+ 0x03, 0x2F, 0x5B, 0x23, 0xB5,
+ 0x0D, 0xA6, 0x60, 0x31, 0x94,
+ 0x00, 0xFF, 0xA5, 0x8E, 0xB2,
+ 0x05, 0xDF, 0x70, 0x10, 0x98,
+ 0x03, 0xDB, 0x1E, 0x88, 0x94,
+ 0x0C, 0xAF, 0x00, 0x45, 0xA4,
+ 0x04, 0x55, 0xA8, 0x61, 0x09,
+ 0x0B, 0x35, 0xDB, 0xC3, 0xFE,
+ 0x04, 0x7C, 0x5C, 0xC8, 0x25,
+ 0x02, 0x47, 0x5F, 0x38, 0x62,
+ 0x0E, 0x9B, 0xB7, 0x1D, 0xD1,
+ 0x0A, 0x81, 0x05, 0x39, 0x76,
+ 0x07, 0xD3, 0x62, 0x28, 0x55,
+ 0x06, 0xB2, 0x8B, 0x70, 0x50,
+ 0x05, 0xC1, 0xA7, 0x28, 0x92,
+ 0x0C, 0x8B, 0x1D, 0x63, 0x9E,
+ 0x0C, 0xE8, 0x31, 0xB1, 0x20,
+ 0x07, 0xF5, 0xD4, 0xAF, 0x1E,
+ 0x0C, 0xC2, 0xE3, 0xCD, 0x75,
+ 0x09, 0x11, 0x4A, 0x97, 0xB6,
+ 0x08, 0x6F, 0x00, 0x7E, 0x9D,
+ 0x08, 0xA0, 0x14, 0x4A, 0x76,
+ 0x0D, 0x77, 0xE8, 0xD2, 0x04,
+ 0x04, 0xE7, 0xA2, 0xA2, 0x41,
+ 0x08, 0x5B, 0xF6, 0x2A, 0xB4,
+ 0x06, 0xFC, 0xD7, 0x2B, 0xFC,
+ 0x04, 0x8F, 0x78, 0x9A, 0x99,
+ 0x02, 0x8F, 0xD0, 0xA3, 0xB7,
+ 0x06, 0x73, 0x4F, 0xBC, 0x7D,
+ 0x01, 0x72, 0xEA, 0x41, 0x6B,
+ 0x0A, 0xA0, 0x56, 0x3C, 0xBB,
+ 0x01, 0x86, 0x14, 0x55, 0xD2,
+ 0x01, 0xD5, 0xAB, 0x6C, 0xD0,
+ 0x0D, 0x46, 0x7B, 0x3B, 0x3B,
+ 0x03, 0x69, 0x11, 0x6B, 0x94,
+ 0x0E, 0x11, 0x2D, 0x9C, 0x2D,
+ 0x0D, 0x07, 0x80, 0x82, 0x11,
+ 0x04, 0xED, 0xDF, 0xEF, 0x4D,
+ 0x08, 0xE8, 0xDE, 0x7E, 0xC9,
+ 0x0F, 0xB0, 0xB4, 0x35, 0x4B,
+ 0x0C, 0xEA, 0xCB, 0xFA, 0x2C,
+ 0x04, 0x1F, 0xF8, 0xFB, 0xA0,
+ 0x0E, 0xDF, 0xC2, 0xD5, 0x55,
+ 0x0A, 0xA0, 0x4E, 0x77, 0x07,
+ 0x05, 0x27, 0x2E, 0x20, 0xC3,
+ 0x01, 0x6F, 0x59, 0xA7, 0xDE,
+ 0x05, 0xF5, 0x43, 0x62, 0xE7,
+ 0x03, 0x29, 0xDA, 0x3A, 0xF9,
+ 0x09, 0x52, 0xB8, 0x58, 0x38,
+ 0x09, 0xB9, 0x84, 0x23, 0x09,
+ 0x0B, 0x33, 0x3E, 0x9D, 0x52,
+ 0x0A, 0xB6, 0x9D, 0x90, 0xDB,
+ 0x08, 0x6F, 0x5D, 0x83, 0x1D,
+ 0x0E, 0x97, 0x73, 0xDA, 0x6B,
+ 0x05, 0x40, 0x77, 0x47, 0xAD,
+ 0x01, 0x00, 0x92, 0xAA, 0x80,
+ 0x08, 0xF2, 0xEA, 0x01, 0x3A,
+ 0x07, 0x5D, 0xC7, 0x04, 0xF0,
+ 0x0C, 0x02, 0xC3, 0xBC, 0x3F,
+ 0x00, 0xF7, 0xC1, 0x4C, 0xC8,
+ 0x01, 0xB4, 0x7D, 0x75, 0xE8,
+ 0x06, 0x71, 0xB5, 0x77, 0xFB,
+ 0x01, 0x78, 0x86, 0x13, 0x95,
+ 0x00, 0x4D, 0xD7, 0x22, 0x85,
+ 0x0F, 0xFB, 0x24, 0xB3, 0x64,
+ 0x08, 0xDC, 0x06, 0x32, 0xBF,
+ 0x0F, 0xE8, 0x31, 0xD2, 0x86,
+ 0x0F, 0xCA, 0x83, 0x5B, 0x6F,
+ 0x09, 0x5F, 0x51, 0x06, 0x95,
+ 0x05, 0xDC, 0x0E, 0x74, 0x9E,
+ 0x0A, 0x0B, 0x08, 0x61, 0x7B,
+ 0x0E, 0x02, 0x54, 0x7F, 0x01,
+ 0x07, 0x1F, 0x3D, 0x04, 0x67,
+ 0x00, 0xF6, 0xE2, 0xC5, 0x88,
+ 0x0B, 0x4E, 0x62, 0x62, 0xE0,
+ 0x08, 0x1C, 0x87, 0x2E, 0x83,
+ 0x03, 0x6E, 0x81, 0x06, 0x53,
+ 0x0E, 0x40, 0xAB, 0x4D, 0x9A,
+ 0x01, 0x85, 0xA1, 0x1E, 0x2B,
+ 0x01, 0x63, 0x28, 0x37, 0xDC,
+ 0x0D, 0x3F, 0x3E, 0xE0, 0x8C,
+ 0x0E, 0xE3, 0x8D, 0xAB, 0xCB,
+ 0x08, 0x35, 0x6D, 0x3F, 0xC0,
+ 0x02, 0x18, 0x45, 0x76, 0xCD,
+ 0x0E, 0xF1, 0x7B, 0x83, 0xDF,
+ 0x05, 0x7B, 0x8D, 0x4E, 0x9B,
+ 0x07, 0xE4, 0x0E, 0x91, 0xC6,
+ 0x07, 0xC5, 0x40, 0xCD, 0x61,
+ 0x0A, 0x77, 0xD1, 0x8B, 0xB4,
+ 0x0C, 0x0A, 0xBD, 0x27, 0xEC,
+ 0x02, 0x66, 0x3B, 0x53, 0x30,
+ 0x0A, 0x03, 0x9C, 0xB9, 0xA2,
+ 0x07, 0xF0, 0xCF, 0x0D, 0x0F,
+ 0x0D, 0x6D, 0x5C, 0x2D, 0x7D,
+ 0x04, 0x8B, 0xF3, 0x97, 0x70,
+ 0x09, 0x53, 0xDD, 0x6A, 0x24,
+ 0x01, 0x4C, 0x48, 0x9C, 0x17,
+ 0x03, 0x56, 0xA3, 0xB8, 0x2E,
+ 0x04, 0x93, 0x39, 0x23, 0xCF,
+ 0x0B, 0xAC, 0x87, 0x8D, 0xAB,
+ 0x08, 0x88, 0x48, 0xC2, 0x30,
+ 0x0D, 0x92, 0xC5, 0xE8, 0x08,
+ 0x07, 0x62, 0x87, 0xDF, 0x65,
+ 0x0E, 0x0F, 0x6E, 0xE2, 0x84,
+ 0x04, 0xE9, 0xDB, 0x41, 0x55,
+ 0x03, 0xCE, 0xDB, 0x78, 0x80,
+ 0x0A, 0xB1, 0x9D, 0x7A, 0xA8,
+ 0x07, 0xE6, 0xE9, 0xE0, 0x39,
+ 0x05, 0xDC, 0x11, 0x4E, 0x2D,
+ 0x08, 0xDA, 0xF0, 0xB6, 0x83,
+ 0x0D, 0x36, 0xB8, 0x51, 0x88,
+ 0x04, 0xBB, 0xAF, 0x1F, 0x36,
+ 0x0B, 0xFE, 0xF3, 0x57, 0x13,
+ 0x02, 0xC9, 0x6C, 0x67, 0xB9,
+ 0x07, 0xB2, 0x3B, 0xF2, 0x28,
+ 0x07, 0x9F, 0x76, 0x4B, 0x7E,
+ 0x0C, 0xCD, 0x24, 0x63, 0x28,
+ 0x03, 0x7F, 0x6C, 0x9D, 0x65,
+ 0x0D, 0xF7, 0x01, 0x33, 0x3D,
+ 0x03, 0x1C, 0x15, 0x56, 0xA9,
+ 0x0F, 0xDC, 0x20, 0xE7, 0x49,
+ 0x0A, 0x11, 0x70, 0xCE, 0x17,
+ 0x06, 0x68, 0x77, 0x87, 0xFC,
+ 0x0E, 0xF8, 0xB9, 0x90, 0x4A,
+ 0x04, 0x8F, 0x3E, 0x6A, 0x94,
+ 0x0E, 0x36, 0xA2, 0x2A, 0x7D,
+ 0x00, 0x88, 0x22, 0x73, 0x1E,
+ 0x07, 0xA6, 0xE8, 0x5C, 0x72,
+ 0x0F, 0x64, 0x9A, 0xF0, 0xC5,
+ 0x01, 0x81, 0x66, 0xD7, 0x6F,
+ 0x05, 0x94, 0x1A, 0xCD, 0xFC,
+ 0x0D, 0xD0, 0x67, 0x62, 0x1E,
+ 0x0B, 0xEA, 0xAC, 0x5E, 0x23,
+ 0x0B, 0x81, 0xC2, 0x9E, 0xC8,
+ 0x01, 0x21, 0x90, 0x23, 0xF3,
+ 0x00, 0xEF, 0x07, 0xF5, 0x22,
+ 0x0A, 0x73, 0x20, 0x94, 0xED,
+ 0x02, 0x7C, 0xDE, 0x69, 0x1F,
+ 0x04, 0x5D, 0x8C, 0x44, 0x42,
+ 0x01, 0x84, 0xE5, 0x58, 0x6F,
+ 0x0D, 0xC8, 0xA1, 0x5E, 0xF6,
+ 0x09, 0x2D, 0xF9, 0xB5, 0x39,
+ 0x0A, 0x8C, 0xA3, 0x4B, 0xFA,
+ 0x04, 0x75, 0x1E, 0x7E, 0xFB,
+ 0x0A, 0xD3, 0xB4, 0x02, 0xC7,
+ 0x0D, 0x40, 0x2D, 0x79, 0x77,
+ 0x03, 0x9D, 0x2B, 0xAE, 0xA2,
+ 0x08, 0x38, 0x5E, 0xD9, 0xA1,
+ 0x02, 0x1F, 0x8B, 0x7B, 0xFC,
+ 0x06, 0x41, 0x29, 0xD6, 0x7F,
+ 0x09, 0xB1, 0x52, 0x3A, 0x59,
+ 0x00, 0x18, 0x2C, 0x04, 0xE3,
+ 0x00, 0xC8, 0xB0, 0xD2, 0x9B,
+ 0x0B, 0x47, 0xDA, 0xFD, 0x9A,
+ 0x07, 0xEE, 0x6A, 0x66, 0x14,
+ 0x01, 0x6E, 0x17, 0xF2, 0x58,
+ 0x03, 0xAD, 0x51, 0xF7, 0x81,
+ 0x01, 0xAD, 0x05, 0xAF, 0xBD,
+ 0x0D, 0x42, 0xF2, 0xEE, 0x36,
+ 0x03, 0x4D, 0x59, 0x48, 0xC6,
+ 0x0A, 0xB8, 0xC1, 0xC3, 0xAC,
+ 0x07, 0x4A, 0xD7, 0xC9, 0xCC,
+ 0x0A, 0x03, 0x34, 0x7F, 0xF3,
+ 0x0B, 0xA6, 0x71, 0xB9, 0x31,
+ 0x0B, 0x15, 0x78, 0x46, 0x17,
+ 0x0F, 0x64, 0xCB, 0x37, 0x23,
+ 0x09, 0x76, 0x04, 0xD8, 0x86,
+ 0x0D, 0xD6, 0xCC, 0x0A, 0x72,
+ 0x07, 0x2A, 0x9E, 0xB1, 0xD2,
+ 0x01, 0x4A, 0x4E, 0x8F, 0x5B,
+ 0x0E, 0x1B, 0xDF, 0x53, 0x02,
+ 0x0C, 0xE7, 0xDC, 0x02, 0x34,
+ 0x04, 0xBF, 0xFD, 0x0C, 0xE9,
+ 0x0B, 0x66, 0x87, 0x7E, 0x75,
+ 0x09, 0xEF, 0x0F, 0x99, 0xC4,
+ 0x0D, 0xA8, 0xF2, 0x6C, 0x37,
+ 0x0C, 0xE3, 0x6A, 0xE6, 0x62,
+ 0x08, 0x10, 0x08, 0x27, 0xEA,
+ 0x03, 0x7B, 0xEE, 0x41, 0x5D,
+ 0x03, 0xF6, 0x49, 0x6B, 0x90,
+ 0x0D, 0x98, 0x0C, 0x61, 0x1A,
+ 0x07, 0xF9, 0xEB, 0xAC, 0x73,
+ 0x07, 0xF4, 0x8A, 0xB6, 0xA6,
+ 0x0D, 0xBE, 0xAA, 0x05, 0x5A,
+ 0x0B, 0xB8, 0x1C, 0xE7, 0x39,
+ 0x05, 0x12, 0x19, 0xDC, 0xB3,
+ 0x05, 0x0E, 0x70, 0xD2, 0x43,
+ 0x07, 0x15, 0x32, 0x05, 0x4E,
+ 0x09, 0x62, 0x6D, 0x87, 0x51,
+ 0x06, 0xD5, 0xC4, 0xC0, 0x7A,
+ 0x01, 0x18, 0x4E, 0x51, 0xFD,
+ 0x04, 0xDC, 0x8A, 0x05, 0xA5,
+ 0x0C, 0x92, 0xDF, 0xB3, 0x51,
+ 0x09, 0x90, 0x2A, 0x39, 0x7F,
+ 0x0B, 0x0D, 0x39, 0x6B, 0x8F,
+ 0x06, 0x13, 0x6D, 0xD8, 0x1C,
+ 0x03, 0xD5, 0x3A, 0x57, 0x97,
+ 0x00, 0x39, 0xD2, 0x64, 0x79,
+ 0x04, 0x33, 0x85, 0xA3, 0x4E,
+ 0x0B, 0xE1, 0xFF, 0x17, 0x3E,
+ 0x08, 0x64, 0x12, 0xCD, 0x23,
+ 0x09, 0x1B, 0xB5, 0x13, 0x0D,
+ 0x0D, 0x08, 0x28, 0x80, 0xC2,
+ 0x00, 0x9C, 0x29, 0x0D, 0xE0,
+ 0x09, 0x15, 0xAB, 0x4F, 0xD9,
+ 0x0C, 0xBD, 0x26, 0xA0, 0x20,
+ 0x0B, 0x91, 0xE1, 0x7F, 0x4D,
+ 0x06, 0xB2, 0x4F, 0x19, 0x34,
+ 0x0A, 0xDB, 0xB0, 0x5A, 0xFA,
+ 0x08, 0x14, 0xAF, 0x3A, 0xEB,
+ 0x0A, 0xA4, 0x35, 0x95, 0x9E,
+ 0x01, 0x0B, 0xDB, 0xA4, 0xB1,
+ 0x05, 0xFE, 0x0F, 0xCC, 0xD6,
+ 0x0E, 0xE5, 0x9B, 0x47, 0x1F,
+ 0x00, 0xEB, 0xE7, 0x1B, 0xD7,
+ 0x03, 0x51, 0x80, 0x84, 0x61,
+ 0x09, 0x17, 0x9B, 0xD3, 0x72,
+ 0x01, 0x54, 0xDF, 0xBE, 0x0B,
+ 0x0E, 0x4D, 0x4C, 0xC6, 0x29,
+ 0x0C, 0xD2, 0xFD, 0x8D, 0x1D,
+ 0x09, 0x9E, 0x3E, 0xEC, 0x36,
+ 0x07, 0x60, 0x35, 0xF1, 0xCC,
+ 0x02, 0xDB, 0x3A, 0xC0, 0xE7,
+ 0x01, 0xAA, 0x28, 0x80, 0x8E,
+ 0x07, 0xB6, 0x68, 0xC3, 0x44,
+ 0x08, 0x1E, 0xF8, 0xA9, 0x10,
+ 0x0E, 0x76, 0x8C, 0xBE, 0xEC,
+ 0x01, 0xCE, 0xF6, 0xAE, 0xA6,
+ 0x07, 0x40, 0xCA, 0xC2, 0xF2,
+ 0x0D, 0xF7, 0x46, 0xEA, 0x84,
+ 0x0C, 0xFD, 0x04, 0xC0, 0xE7,
+ 0x0A, 0x99, 0x80, 0xE1, 0xCB,
+ 0x05, 0xFD, 0x16, 0x37, 0x57,
+ 0x06, 0xBD, 0xD9, 0xE0, 0x47,
+ 0x09, 0xAB, 0x4A, 0xA1, 0xD2,
+ 0x0C, 0xBB, 0x81, 0xC8, 0x88,
+ 0x07, 0x51, 0x21, 0x9B, 0xF5,
+ 0x0C, 0xD0, 0xEF, 0x19, 0xBA,
+ 0x07, 0x31, 0x7A, 0xAB, 0xBA,
+ 0x05, 0xDE, 0xDC, 0xD9, 0x29,
+ 0x05, 0xED, 0xBC, 0x4C, 0x04,
+ 0x0B, 0x93, 0xE4, 0xE9, 0x58,
+ 0x0F, 0x4D, 0xC8, 0x87, 0x18,
+ 0x04, 0xCC, 0xAC, 0x79, 0x25,
+ 0x03, 0x01, 0x8C, 0x83, 0x4B,
+ 0x0A, 0x2C, 0x75, 0x86, 0x7A,
+ 0x0B, 0xA0, 0xD6, 0xFD, 0x80,
+ 0x0C, 0xD5, 0x40, 0xA5, 0x79,
+ 0x0F, 0xCB, 0x3D, 0x2B, 0xAE,
+ 0x0B, 0x42, 0x98, 0x50, 0xC4,
+ 0x01, 0xDE, 0x1F, 0xFD, 0xFE,
+ 0x0A, 0x6F, 0xE1, 0x29, 0x1A,
+ 0x04, 0xF9, 0x31, 0x5F, 0xF8,
+ 0x02, 0xBA, 0x98, 0x8C, 0x44,
+ 0x0B, 0x08, 0x4A, 0xBE, 0x9E,
+ 0x0B, 0x91, 0x42, 0xB0, 0x45,
+ 0x09, 0xDE, 0x43, 0x6E, 0x62,
+ 0x08, 0x9C, 0xF7, 0x99, 0xB0,
+ 0x01, 0x3B, 0xC8, 0xF1, 0x37,
+ 0x08, 0xAD, 0x7B, 0x08, 0x2B,
+ 0x0A, 0x81, 0x4A, 0xF2, 0x1D,
+ 0x09, 0xBB, 0x7F, 0x5D, 0x44,
+ 0x0E, 0xF0, 0x1D, 0xBD, 0x5E,
+ 0x0C, 0x3F, 0xE0, 0xFB, 0x1C,
+ 0x04, 0x82, 0xD3, 0xB4, 0x79,
+ 0x09, 0xA2, 0xAD, 0x7A, 0xFC,
+ 0x03, 0x18, 0x94, 0x18, 0xC6,
+ 0x03, 0xBC, 0xE1, 0xBD, 0x37,
+ 0x02, 0xAC, 0xE9, 0xF7, 0x35,
+ 0x0E, 0xE7, 0x94, 0xC8, 0x82,
+ 0x0B, 0x0F, 0x4F, 0xE4, 0xB1,
+ 0x06, 0x59, 0xE3, 0xF8, 0x81,
+ 0x01, 0x73, 0xA9, 0x5F, 0x45,
+ 0x0E, 0x95, 0xE1, 0x5C, 0x0D,
+ 0x0C, 0x1F, 0x1A, 0x89, 0x4C,
+ 0x08, 0xF8, 0x06, 0x84, 0x7D,
+ 0x0F, 0xC1, 0xEF, 0x8F, 0xC4,
+ 0x04, 0xA7, 0x68, 0xFE, 0x62,
+ 0x05, 0x48, 0xE3, 0x6A, 0x31,
+ 0x08, 0xE0, 0x16, 0x07, 0x7A,
+ 0x0A, 0xC3, 0x7A, 0x2E, 0x45,
+ 0x02, 0xD3, 0xF2, 0x59, 0x6F,
+ 0x09, 0xA9, 0x9C, 0x21, 0xE1,
+ 0x08, 0x5F, 0xD5, 0x63, 0x2C,
+ 0x01, 0xC7, 0xDD, 0x06, 0x36,
+ 0x0C, 0x76, 0x3E, 0x8C, 0x07,
+ 0x0B, 0xAA, 0x38, 0x1C, 0x3A,
+ 0x0D, 0x75, 0x12, 0x19, 0xC2,
+ 0x06, 0xCD, 0x0E, 0xD4, 0x3B,
+ 0x03, 0xDF, 0x17, 0x14, 0x0B,
+ 0x05, 0xD1, 0xE7, 0xCD, 0x8A,
+ 0x0B, 0x26, 0xDD, 0x4F, 0xAC,
+ 0x00, 0x21, 0x18, 0x4E, 0x55,
+ 0x06, 0xF4, 0xDC, 0xAA, 0x15,
+ 0x07, 0xEC, 0x92, 0xCF, 0x11,
+ 0x03, 0x30, 0x18, 0xDA, 0x36,
+ 0x0F, 0xA2, 0xC7, 0x49, 0x65,
+ 0x0F, 0xBA, 0x0D, 0x4D, 0xDA,
+ 0x06, 0x7D, 0x54, 0x0A, 0x57,
+ 0x0E, 0x72, 0x19, 0xD0, 0xFA,
+ 0x00, 0x21, 0x84, 0x85, 0xE5,
+ 0x0A, 0x1D, 0xE5, 0xFF, 0x07,
+ 0x0E, 0x2E, 0x68, 0x12, 0x9D,
+ 0x01, 0xCF, 0x9B, 0x13, 0xA3,
+ 0x04, 0xAB, 0x49, 0x8A, 0x00,
+ 0x03, 0x31, 0x5C, 0xAB, 0x0D,
+ 0x02, 0xB9, 0x14, 0x2B, 0x4F,
+ 0x09, 0x25, 0xBF, 0x06, 0xA6,
+ 0x00, 0x31, 0x94, 0x79, 0x7F,
+ 0x05, 0x8E, 0xB0, 0xDF, 0x1F,
+ 0x04, 0x1A, 0xDA, 0xA0, 0xD0,
+ 0x0A, 0xA8, 0x15, 0xBF, 0xA4,
+ 0x00, 0x73, 0xA5, 0xE5, 0x5E,
+ 0x08, 0x67, 0x0A, 0xCB, 0xBE,
+ 0x0B, 0xC3, 0xFF, 0x1F, 0xF6,
+ 0x0C, 0xC8, 0x24, 0x2B, 0xCD,
+ 0x0F, 0x36, 0x2B, 0x57, 0x91,
+ 0x07, 0x13, 0x10, 0x10, 0x0E,
+ 0x01, 0x39, 0x57, 0x0B, 0x59,
+ 0x02, 0x28, 0x57, 0x8F, 0x38,
+ 0x0B, 0x7E, 0x4C, 0x4C, 0x4A,
+ 0x03, 0x28, 0xD3, 0xFE, 0x01,
+ 0x0D, 0x65, 0x9C, 0x1E, 0x62,
+ 0x0E, 0xB7, 0x60, 0xB5, 0xF5,
+ 0x0C, 0x09, 0x5E, 0x5D, 0xC3,
+ 0x0E, 0x49, 0x29, 0xA8, 0xD0,
+ 0x06, 0x97, 0x16, 0x68, 0x77,
+ 0x0D, 0x3C, 0x18, 0x73, 0x37,
+ 0x08, 0xCB, 0xD6, 0x83, 0x3E,
+ 0x04, 0x56, 0xCE, 0x34, 0x2E,
+ 0x0C, 0x27, 0xC4, 0x88, 0xC6,
+ 0x08, 0xA9, 0xF0, 0xA6, 0xE5,
+ 0x09, 0xAD, 0xFF, 0x66, 0x2C,
+ 0x0C, 0x9A, 0x99, 0x84, 0xBD,
+ 0x01, 0xA5, 0xFD, 0x16, 0x3A,
+ 0x0B, 0x3C, 0x7C, 0xD0, 0x6B,
+ 0x0E, 0xC1, 0x69, 0xEA, 0xA0,
+ 0x09, 0xBC, 0xBB, 0x81, 0xCE,
+ 0x0F, 0xF7, 0x51, 0x21, 0x9F,
+ 0x06, 0x6C, 0x12, 0xEF, 0x4F,
+ 0x00, 0xBD, 0x51, 0x73, 0x20,
+ 0x0E, 0x2D, 0x18, 0xF7, 0x46,
+ 0x01, 0x9D, 0xCD, 0x50, 0x4C,
+ 0x0C, 0x00, 0x51, 0x86, 0x65,
+ 0x02, 0x6A, 0x81, 0x48, 0xA5,
+ 0x00, 0x7B, 0x06, 0x2D, 0xF8,
+ 0x0C, 0x31, 0x21, 0x82, 0x63,
+ 0x01, 0xFF, 0xE3, 0x75, 0xB6,
+ 0x01, 0xFB, 0x60, 0xD4, 0x5D,
+ 0x02, 0xD7, 0xD5, 0x44, 0xDC,
+ 0x09, 0x77, 0x03, 0x9D, 0x27,
+ 0x0E, 0xA2, 0x42, 0x38, 0x5E,
+ 0x09, 0xA1, 0xDC, 0x1F, 0xF0,
+ 0x00, 0xE2, 0xE6, 0x41, 0x29,
+ 0x06, 0x1C, 0xF9, 0xB1, 0x51,
+ 0x01, 0xDA, 0x7A, 0x98, 0xC8,
+ 0x0C, 0xA3, 0xA9, 0x4A, 0xB0,
+ 0x04, 0x5B, 0x97, 0xC9, 0x18,
+ 0x05, 0x13, 0xFB, 0xFE, 0x6A,
+ 0x0E, 0x01, 0x59, 0x44, 0x17,
+ 0x0E, 0x5D, 0x3F, 0xAC, 0xF5,
+ 0x0D, 0x44, 0x7B, 0xBB, 0x04,
+ 0x06, 0xAA, 0x41, 0x48, 0x48,
+ 0x0E, 0x07, 0x3A, 0x4B, 0x26,
+ 0x04, 0x86, 0x70, 0xBD, 0xB3,
+ 0x03, 0xBC, 0x3F, 0x60, 0xF7,
+ 0x05, 0xCC, 0x80, 0x53, 0xB4,
+ 0x02, 0xF3, 0x62, 0xA4, 0x71,
+ 0x09, 0x51, 0x31, 0x10, 0x0B,
+ 0x0F, 0x13, 0x57, 0x61, 0xFD,
+ 0x0F, 0xA2, 0x25, 0x69, 0xFB,
+ 0x0E, 0x77, 0xE2, 0x5F, 0x76,
+ 0x0E, 0xB3, 0x2D, 0x23, 0xE8,
+ 0x09, 0xD4, 0x19, 0xE1, 0x6E,
+ 0x09, 0x5E, 0xAD, 0x8B, 0x5B,
+ 0x0F, 0x07, 0x48, 0xE5, 0xDD,
+ 0x07, 0x74, 0x5E, 0xB8, 0x33,
+ 0x0C, 0xE1, 0x7B, 0x62, 0xFC,
+ 0x08, 0x7F, 0xC1, 0xEF, 0x8B,
+ 0x09, 0x04, 0xA7, 0xE8, 0xF3,
+ 0x06, 0xC5, 0x4A, 0xE3, 0x6A,
+ 0x09, 0x62, 0x20, 0x10, 0x8C,
+ 0x07, 0x2A, 0xC1, 0x7A, 0x6E,
+ 0x0F, 0xCA, 0xD5, 0x7D, 0x8B,
+ 0x07, 0x49, 0x09, 0x1A, 0x8C,
+ 0x0E, 0x9F, 0xEA, 0xD1, 0x63,
+ 0x0C, 0xB3, 0xC7, 0x5B, 0x8C,
+ 0x06, 0xEC, 0x16, 0xBE, 0xAA,
+ 0x05, 0x2B, 0xC9, 0xB8, 0x1C,
+ 0x02, 0x3D, 0x75, 0x12, 0x19,
+ 0x0E, 0xD4, 0xCD, 0x0E, 0xC1,
+ 0x0F, 0x83, 0xDD, 0x17, 0x32,
+ 0x09, 0x4E, 0xD1, 0x6B, 0x87,
+ 0x0A, 0x91, 0xC6, 0x59, 0x8E,
+ 0x04, 0x40, 0x23, 0x18, 0x44,
+ 0x0F, 0x66, 0xF5, 0x57, 0x41,
+ 0x05, 0xA7, 0xEC, 0x82, 0xDD,
+ 0x09, 0xB3, 0x31, 0x93, 0x07,
+ 0x04, 0xBF, 0xA2, 0xD7, 0x5B,
+ 0x0D, 0x6F, 0xA1, 0x86, 0xA2,
+ 0x08, 0x2D, 0x7D, 0x44, 0x08,
+ 0x0D, 0x77, 0x6B, 0xB2, 0x03,
+ 0x0A, 0xEA, 0x24, 0x23, 0x87,
+ 0x06, 0x9A, 0x1D, 0xE1, 0xFF,
+ 0x0B, 0xBE, 0x2C, 0x64, 0x1C,
+ 0x0D, 0xA3, 0xD9, 0x9B, 0x15,
+ 0x09, 0x6D, 0xAA, 0x02, 0x5E,
+ 0x00, 0x42, 0x34, 0x9C, 0xB4,
+ 0x07, 0x29, 0xBA, 0x1F, 0xF3,
+ 0x0F, 0xD9, 0x25, 0x3F, 0x2C,
+ 0x06, 0x60, 0x32, 0x14, 0x69,
+ 0x0F, 0x45, 0x8C, 0xB2, 0xCF,
+ 0x05, 0x94, 0x01, 0x50, 0x6C,
+ 0x0A, 0xFA, 0xA8, 0x04, 0xAD,
+ 0x05, 0xE0, 0x73, 0xA4, 0xF5,
+ 0x08, 0x48, 0x66, 0x4B, 0xD5,
+ 0x0C, 0x3B, 0x55, 0xF2, 0x0F,
+ 0x00, 0x60, 0xC8, 0x25, 0x0A,
+ 0x0B, 0x99, 0x36, 0x2A, 0x75,
+ 0x07, 0x55, 0x13, 0x11, 0x33,
+ 0x08, 0x43, 0x39, 0x56, 0x18,
+ 0x0B, 0x73, 0xA8, 0x56, 0x5F,
+ 0x02, 0x4B, 0x7E, 0xCD, 0x06,
+ 0x00, 0x63, 0x28, 0x56, 0xF4,
+ 0x0B, 0x1D, 0x65, 0x12, 0x74,
+ 0x08, 0x35, 0xB7, 0xEC, 0xFF,
+ 0x05, 0x50, 0x29, 0xD2, 0x17,
+ 0x00, 0xE7, 0x49, 0x67, 0xE2,
+ 0x00, 0xCE, 0x17, 0x3A, 0xE2,
+ 0x07, 0x87, 0xFC, 0x92, 0x72,
+ 0x09, 0x90, 0x4A, 0xFA, 0xC5,
+ 0x0E, 0x6C, 0x54, 0x02, 0xFC,
+ 0x0E, 0x26, 0x20, 0x01, 0x02,
+ 0x08, 0x92, 0xB7, 0xBC, 0x57,
+ 0x04, 0x50, 0xAD, 0x2F, 0x66,
+ 0x0D, 0xFC, 0x9A, 0x99, 0x80,
+ 0x0A, 0x73, 0xA5, 0xFD, 0x27,
+ 0x0A, 0xCB, 0x3E, 0x7D, 0xD0,
+ 0x0B, 0x6E, 0xC1, 0xEB, 0xE0,
+ 0x00, 0x52, 0xBC, 0x37, 0xCB,
+ 0x0E, 0x93, 0xD7, 0xDD, 0x6B,
+ 0x06, 0xCF, 0x77, 0x5B, 0x16,
+ 0x0F, 0xF8, 0x3D, 0x71, 0x79,
+ 0x08, 0x94, 0x6F, 0x1E, 0xBC,
+ 0x02, 0x49, 0x07, 0xE6, 0xA0,
+ 0x0C, 0x44, 0x02, 0x01, 0x86,
+ 0x0F, 0xB8, 0x74, 0xC6, 0x36,
+ 0x01, 0x5A, 0x7E, 0xDF, 0x2F,
+ 0x03, 0xD5, 0x28, 0x8D, 0x8C,
+ 0x03, 0x4B, 0xFA, 0x3C, 0x77,
+ 0x0D, 0x78, 0xFB, 0xA0, 0xD6,
+ 0x01, 0x9D, 0x28, 0x29, 0x43,
+ 0x09, 0x5B, 0x77, 0x03, 0x9E,
+ 0x07, 0xAE, 0xA0, 0x43, 0x38,
+ 0x0E, 0xD9, 0xA1, 0x5E, 0x55,
+ 0x00, 0x7B, 0xE2, 0x66, 0x4B,
+ 0x09, 0xDA, 0x3C, 0x79, 0xBB,
+ 0x02, 0x38, 0xD8, 0xB8, 0xD2,
+ 0x02, 0xE4, 0x38, 0x85, 0xC0,
+ 0x00, 0xDE, 0x9B, 0x81, 0x40,
+ 0x0E, 0x1D, 0x89, 0xD7, 0xFE,
+ 0x0A, 0x66, 0x03, 0x09, 0x44,
+ 0x0C, 0xF4, 0x58, 0xEB, 0x2C,
+ 0x09, 0xF7, 0xC5, 0xAD, 0x7B,
+ 0x0F, 0xA9, 0x85, 0x81, 0x6A,
+ 0x02, 0xEE, 0x03, 0x17, 0x4A,
+ 0x0D, 0x44, 0x8A, 0x70, 0xBD,
+ 0x0B, 0x43, 0x38, 0x3F, 0x20,
+ 0x0F, 0xC7, 0xC8, 0x82, 0xA7,
+ 0x04, 0x79, 0xF3, 0x62, 0xA4,
+ 0x01, 0xB5, 0x7D, 0x35, 0x25,
+ 0x00, 0x46, 0x97, 0x95, 0xA1,
+ 0x05, 0x35, 0x26, 0x85, 0xA9,
+ 0x0B, 0x24, 0xB7, 0xE4, 0xD4,
+ 0x0C, 0x06, 0x3E, 0x89, 0x19,
+ 0x00, 0xB1, 0x52, 0x59, 0x23,
+ 0x06, 0x81, 0x5F, 0x76, 0xCB,
+ 0x0F, 0x55, 0x02, 0x95, 0xE5,
+ 0x0C, 0x0E, 0x78, 0x9A, 0x82,
+ 0x01, 0x0C, 0x65, 0x7B, 0xA6,
+ 0x0F, 0x7A, 0x7B, 0xC1, 0x2F,
+ 0x0B, 0x99, 0x04, 0xA7, 0x68,
+ 0x03, 0xE6, 0xC1, 0x5C, 0xDA,
+ 0x00, 0x02, 0x78, 0x2C, 0x3B,
+ 0x0E, 0x27, 0x2A, 0xC3, 0xFA,
+ 0x0C, 0x45, 0x0A, 0xE3, 0x76,
+ 0x09, 0x0F, 0x49, 0xA9, 0x98,
+ 0x0C, 0x85, 0xBA, 0x5F, 0xD1,
+ 0x03, 0xAC, 0xB3, 0xC7, 0xDD,
+ 0x06, 0xB6, 0xEC, 0x00, 0xBC,
+ 0x0A, 0x05, 0x2B, 0xDD, 0xFA,
+ 0x0C, 0xE9, 0x3D, 0x65, 0x12,
+ 0x09, 0xC2, 0xF6, 0xCD, 0x0E,
+ 0x00, 0xFF, 0x83, 0xEF, 0x17,
+ 0x02, 0x09, 0x4A, 0xC1, 0xE7,
+ 0x07, 0x6A, 0x8B, 0x4A, 0xE2,
+ 0x06, 0xC4, 0x40, 0x21, 0x98,
+ 0x0C, 0x55, 0x86, 0xC4, 0x5C,
+ 0x0A, 0x75, 0x27, 0xEC, 0x92,
+ 0x0F, 0x73, 0xF3, 0x30, 0x18,
+ 0x0A, 0x34, 0xBF, 0xA2, 0xC7,
+ 0x09, 0x67, 0x8F, 0xAC, 0x0F,
+ 0x0D, 0xD8, 0x2D, 0x6B, 0x16,
+ 0x0A, 0x57, 0x97, 0x60, 0x39,
+ 0x02, 0x7A, 0xEA, 0x24, 0x33,
+ 0x05, 0xED, 0x9A, 0x2D, 0xE1,
+ 0x0F, 0x07, 0xBA, 0x3E, 0x64,
+ 0x08, 0x7D, 0xB8, 0xC3, 0xD8,
+ 0x07, 0x23, 0x8D, 0xAB, 0x09,
+ 0x0A, 0x80, 0x42, 0x00, 0x1C,
+ 0x0B, 0x6D, 0x69, 0xB9, 0x14,
+ 0x0B, 0xAF, 0x79, 0x25, 0xBF,
+ 0x06, 0xA6, 0x60, 0x31, 0x94,
+ 0x09, 0x7F, 0x45, 0x98, 0xB0,
+ 0x0F, 0x1F, 0x74, 0x0C, 0x99,
+ 0x00, 0x5A, 0xFA, 0xB8, 0x14,
+ 0x0F, 0x2E, 0xE0, 0x73, 0xA4,
+ 0x05, 0xD4, 0x48, 0x67, 0x0B,
+ 0x0B, 0x34, 0x3B, 0xF3, 0xFE,
+ 0x0F, 0x7C, 0x58, 0xD8, 0x25,
+ 0x01, 0xA7, 0x83, 0x3A, 0x7A,
+ 0x05, 0x1B, 0x57, 0x13, 0x91,
+ 0x02, 0x84, 0x61, 0x09, 0xD6,
+ 0x0B, 0xB3, 0xF2, 0x28, 0x56,
+ 0x0F, 0x52, 0xEB, 0x7E, 0x4D,
+ 0x0C, 0xC0, 0x63, 0x28, 0xD2,
+ 0x0E, 0x8B, 0x1D, 0x73, 0x9C,
+ 0x0E, 0xE8, 0x35, 0xA1, 0x22,
+ 0x05, 0xF5, 0x50, 0x39, 0x5E,
+ 0x0D, 0xC0, 0xE7, 0x49, 0xEB,
+ 0x08, 0x90, 0xCE, 0x27, 0xB6,
+ 0x08, 0x77, 0x83, 0xEC, 0x1E,
+ 0x02, 0x59, 0x8C, 0xC6, 0x2A,
+ 0x0D, 0x3E, 0x6C, 0x54, 0x0E,
+ 0x04, 0xAE, 0x26, 0x12, 0x81,
+ 0x08, 0xA2, 0xF2, 0xAC, 0x37,
+ 0x06, 0x04, 0xF0, 0xAD, 0x3F,
+ 0x04, 0x96, 0xFC, 0x9A, 0x99,
+ 0x00, 0xC6, 0x51, 0xB3, 0xFF,
+ 0x06, 0x3A, 0xCB, 0x2A, 0x3F,
+ 0x00, 0x6B, 0x6E, 0xD1, 0x6B,
+ 0x0A, 0xA0, 0x52, 0xBC, 0xBB,
+ 0x01, 0xCE, 0x93, 0xF7, 0x51,
+ 0x0A, 0x9C, 0x2F, 0x6C, 0xD0,
+ 0x07, 0x0F, 0x7A, 0x30, 0xB1,
+ 0x09, 0x26, 0xA0, 0x6D, 0x3E,
+ 0x0C, 0xD8, 0xAD, 0x1C, 0x6D,
+ 0x0C, 0x4C, 0x44, 0x02, 0x11,
+ 0x06, 0xE5, 0x58, 0x61, 0x4D,
+ 0x08, 0xA1, 0xDA, 0x7E, 0xC9,
+ 0x0D, 0xF8, 0xB5, 0x33, 0x01,
+ 0x0C, 0xA3, 0x4B, 0xFA, 0x2C,
+ 0x05, 0x96, 0x78, 0xFF, 0xAA,
+ 0x06, 0xDD, 0x82, 0xD3, 0xE7,
+ 0x00, 0xA5, 0x7B, 0x77, 0x03,
+ 0x06, 0x27, 0xAE, 0xA2, 0x43,
+ 0x01, 0x5E, 0x19, 0xA1, 0xDE,
+ 0x07, 0x70, 0xDB, 0xE2, 0xE6,
+ 0x0B, 0xE9, 0xC3, 0x30, 0x96,
+ 0x00, 0x53, 0xFD, 0xDA, 0xB8,
+ 0x08, 0x09, 0xA0, 0x23, 0x09,
+ 0x09, 0xB1, 0x1B, 0x9D, 0x9B,
+ 0x00, 0x35, 0x5D, 0x94, 0x5B,
+ 0x03, 0x6B, 0xA6, 0x03, 0x19,
+ 0x06, 0x16, 0x54, 0x58, 0xEB,
+ 0x07, 0xF1, 0xF7, 0x41, 0xAD,
+ 0x07, 0x05, 0xA4, 0x2A, 0x92,
+ 0x06, 0xCD, 0x1A, 0xC7, 0x2E,
+ 0x07, 0x5D, 0xC4, 0x86, 0x70,
+ 0x07, 0x73, 0x54, 0xB0, 0x45,
+ 0x02, 0xFE, 0x41, 0x8C, 0x02,
+ 0x01, 0xBD, 0xFD, 0xA3, 0xE2,
+ 0x06, 0x78, 0x31, 0x47, 0x71,
+ 0x02, 0x01, 0xC6, 0x15, 0x15,
+ 0x01, 0xB4, 0xB7, 0x64, 0xC7,
+ 0x09, 0xF2, 0xA4, 0xA1, 0x66,
+ 0x0F, 0xCC, 0x06, 0x32, 0x8D,
+ 0x03, 0xE8, 0xB2, 0x16, 0x68,
+ 0x0A, 0xEE, 0x43, 0x5B, 0xB6,
+ 0x02, 0x59, 0x95, 0x0E, 0xD5,
+ 0x0F, 0xDA, 0x5C, 0xF4, 0xBE,
+ 0x03, 0x8B, 0x4C, 0xED, 0x7B,
+ 0x0C, 0x81, 0x3C, 0x7F, 0x81,
+ 0x07, 0x8B, 0x99, 0x0C, 0x95,
+ 0x02, 0xF5, 0xB4, 0x45, 0x68,
+ 0x0A, 0x68, 0xA2, 0x6E, 0x20,
+ 0x0A, 0x8A, 0x61, 0x2A, 0x83,
+ 0x02, 0x6E, 0x45, 0x02, 0xA1,
+ 0x0C, 0x4F, 0x3D, 0x49, 0x89,
+ 0x01, 0x0E, 0x25, 0x16, 0x5F,
+ 0x0B, 0x65, 0xE4, 0xB3, 0x87,
+ 0x05, 0x06, 0xB6, 0xE4, 0xA4,
+ 0x04, 0xAC, 0x57, 0xAB, 0xEB,
+ 0x01, 0x1E, 0xA9, 0x31, 0x75,
+ 0x08, 0x1F, 0x88, 0xF6, 0x8D,
+ 0x06, 0xF0, 0xFF, 0x8B, 0x2D,
+ 0x0D, 0x34, 0x5B, 0xCE, 0xF1,
+ 0x0E, 0xCF, 0xCA, 0x9D, 0xC6,
+ 0x0F, 0xC2, 0x88, 0x40, 0x61,
+ 0x00, 0x4E, 0x55, 0x8F, 0xC6,
+ 0x06, 0x8C, 0x47, 0x27, 0xCC,
+ 0x0B, 0xDD, 0xD3, 0x5F, 0x30,
+ 0x02, 0xCC, 0x7A, 0xBF, 0xE2,
+ 0x0F, 0x59, 0x67, 0x86, 0xC8,
+ 0x07, 0x6B, 0x8A, 0xAD, 0x5D,
+ 0x0D, 0x08, 0x17, 0x9B, 0x70,
+ 0x03, 0xD4, 0x2A, 0xEA, 0x64,
+ 0x0B, 0x85, 0xED, 0x93, 0xAF,
+ 0x0B, 0xF9, 0x55, 0x3E, 0x0E,
+ 0x0D, 0x10, 0xDD, 0xAF, 0xCF,
+ 0x01, 0x13, 0x71, 0x8D, 0xEB,
+ 0x01, 0x88, 0x80, 0x4B, 0xC2,
+ 0x06, 0xAD, 0x5F, 0x69, 0x99,
+ 0x0C, 0x2B, 0x4F, 0xD9, 0x17,
+ 0x0F, 0x26, 0xA6, 0x60, 0x31,
+ 0x0F, 0x69, 0x7F, 0x45, 0x8E,
+ 0x0B, 0xCD, 0x5F, 0x78, 0x1A,
+ 0x01, 0xB6, 0x0F, 0x7A, 0xE8,
+ 0x0C, 0xAF, 0x2E, 0xEC, 0xD3,
+ 0x0E, 0xF3, 0xB7, 0x48, 0x47,
+ 0x02, 0xD9, 0x74, 0x37, 0xC3,
+ 0x04, 0x09, 0x2B, 0xDC, 0x88,
+ 0x0D, 0x3B, 0x47, 0x93, 0x97,
+ 0x00, 0x41, 0x78, 0x57, 0x33,
+ 0x08, 0x02, 0xC4, 0x6D, 0x39,
+ 0x0C, 0x1D, 0x8A, 0xF2, 0x68,
+ 0x0E, 0x9F, 0xB2, 0x47, 0xDC,
+ 0x07, 0x4A, 0xA3, 0x63, 0x08,
+ 0x0B, 0xFC, 0xCB, 0x11, 0x65,
+ 0x04, 0x38, 0xB3, 0xB5, 0xF7,
+ 0x08, 0xB5, 0xF5, 0x5C, 0x8A,
+ 0x04, 0x5B, 0xA3, 0xE7, 0x69,
+ 0x02, 0xAA, 0xD0, 0xC2, 0x17,
+ 0x0C, 0x6E, 0x2A, 0x07, 0xBC,
+ 0x06, 0xF8, 0xB9, 0x9C, 0xEE,
+ 0x0C, 0x89, 0x5D, 0x6C, 0x74,
+ 0x07, 0x34, 0xEE, 0x2A, 0x22,
+ 0x0B, 0x0E, 0x9D, 0xF2, 0xEC,
+ 0x0F, 0xA6, 0xE4, 0x5C, 0x08,
+ 0x05, 0x62, 0xF5, 0xFC, 0xBA,
+ 0x00, 0x82, 0x86, 0x5D, 0xA5,
+ 0x07, 0x10, 0x5B, 0x4B, 0x7C,
+ 0x05, 0xD0, 0x6B, 0x62, 0x67,
+ 0x01, 0xEC, 0xC3, 0x52, 0x9C,
+ 0x02, 0x83, 0x8E, 0x9F, 0xD7,
+ 0x0B, 0x27, 0xFF, 0x2F, 0x2C,
+ 0x08, 0xEF, 0x0F, 0xF4, 0x9A,
+ 0x01, 0x73, 0x20, 0x94, 0xED,
+ 0x05, 0x7C, 0xD8, 0xA9, 0x1C,
+ 0x04, 0xDC, 0xAC, 0x44, 0xC2,
+ 0x0B, 0x82, 0x83, 0x58, 0x2F,
+ 0x05, 0xC8, 0xA1, 0x5E, 0x58,
+ 0x03, 0x2B, 0x84, 0xB5, 0x32,
+ 0x08, 0x0E, 0xC3, 0x47, 0xFA,
+ 0x06, 0x73, 0xFE, 0x78, 0xBB,
+ 0x08, 0xD6, 0xDD, 0x86, 0xF7,
+ 0x0F, 0x46, 0xD8, 0xF9, 0x76,
+ 0x0A, 0x1F, 0x47, 0xA2, 0xA2,
+ 0x09, 0x3E, 0x34, 0xD9, 0xE1,
+ 0x06, 0x1F, 0xF0, 0x7F, 0xC3,
+ 0x0C, 0x47, 0x54, 0x5A, 0x3D,
+ 0x00, 0x33, 0x32, 0x34, 0xDA,
+ 0x02, 0x9E, 0xE4, 0x04, 0x63,
+ 0x01, 0xCA, 0xB0, 0xDA, 0xB9,
+ 0x0B, 0x44, 0xC9, 0x7D, 0x93,
+ 0x02, 0x70, 0x0A, 0x6A, 0x03,
+ 0x03, 0x40, 0xF9, 0xF4, 0x18,
+ 0x03, 0x2C, 0xF1, 0xF3, 0x62,
+ 0x07, 0xBD, 0x78, 0x2F, 0xAB,
+ 0x08, 0xC8, 0x92, 0xE2, 0x07,
+ 0x00, 0x49, 0x2D, 0x44, 0xC6,
+ 0x08, 0xBD, 0xB3, 0x47, 0x98,
+ 0x05, 0xE6, 0x8A, 0x45, 0xCD,
+ 0x0B, 0xD1, 0xD4, 0x75, 0xF3,
+ 0x08, 0xA2, 0x03, 0xB5, 0x31,
+ 0x09, 0x10, 0x08, 0x42, 0x36,
+ 0x0F, 0x67, 0xC0, 0xB7, 0x23,
+ 0x0C, 0xEB, 0x9B, 0x28, 0xB7,
+ 0x0E, 0xD2, 0xB8, 0x06, 0x72,
+ 0x05, 0x2F, 0xE8, 0xB5, 0xF0,
+ 0x03, 0xE5, 0x93, 0x03, 0x5A,
+ 0x0F, 0x89, 0x3F, 0x59, 0x02,
+ 0x0F, 0xE3, 0xAA, 0x0E, 0x34,
+ 0x06, 0xBA, 0x89, 0x08, 0xC6,
+ 0x01, 0x60, 0xFA, 0xF8, 0x7E,
+ 0x08, 0x6D, 0xEB, 0x95, 0x04,
+ 0x0D, 0x6E, 0x8B, 0x66, 0x85,
+ 0x00, 0xE3, 0x6A, 0xE6, 0x44,
+ 0x08, 0x10, 0x8C, 0x23, 0x0D,
+ 0x09, 0x7C, 0x13, 0xC5, 0x0B,
+ 0x0A, 0x74, 0x29, 0x63, 0xC9,
+ 0x03, 0x9E, 0x77, 0x65, 0x5A,
+ 0x07, 0xD1, 0x63, 0xA8, 0x93,
+ 0x0F, 0xDD, 0x06, 0xB2, 0xCA,
+ 0x0C, 0xB8, 0xD7, 0x85, 0x2A,
+ 0x02, 0x3A, 0x7C, 0xE5, 0x3D,
+ 0x0F, 0x14, 0x64, 0x42, 0xB6,
+ 0x05, 0x0E, 0xF0, 0xFB, 0xA2,
+ 0x07, 0x17, 0x32, 0x0D, 0x69,
+ 0x0B, 0xE1, 0xB0, 0x0A, 0x90,
+ 0x06, 0xD5, 0xC4, 0xC4, 0x40,
+ 0x0A, 0x18, 0x4E, 0x55, 0x86,
+ 0x0D, 0x5C, 0x6A, 0x15, 0x67,
+ 0x06, 0x94, 0x5F, 0x13, 0x13,
+ 0x08, 0x18, 0xCA, 0x30, 0x9F,
+ 0x08, 0xC1, 0xC1, 0x67, 0x8E,
+ 0x03, 0x8F, 0x0D, 0xD4, 0x2D,
+ 0x07, 0x52, 0x88, 0xD7, 0xD7,
+ 0x08, 0x39, 0xD2, 0x7E, 0xCA,
+ 0x0E, 0x35, 0x1D, 0xED, 0x9B,
+ 0x04, 0x63, 0x9F, 0x0B, 0xBE,
+ 0x04, 0x62, 0x96, 0x1D, 0xE3,
+ 0x07, 0x9B, 0x15, 0x27, 0xAC,
+ 0x01, 0x8F, 0x10, 0x80, 0x43,
+ 0x09, 0x1E, 0xCB, 0x01, 0xE9,
+ 0x03, 0x12, 0xAD, 0xCF, 0x99,
+ 0x0D, 0xBF, 0x26, 0xA2, 0x42,
+ 0x0B, 0x92, 0xF1, 0x7F, 0x44,
+ 0x07, 0x30, 0xAF, 0x13, 0x74,
+ 0x00, 0xDD, 0x38, 0xDA, 0xBA,
+ 0x00, 0x14, 0xAF, 0x2A, 0xC3,
+ 0x09, 0xA2, 0x6D, 0xD4, 0x49,
+ 0x0E, 0x89, 0xBB, 0x38, 0x3B,
+ 0x09, 0xF8, 0x85, 0xFC, 0x1C,
+ 0x00, 0x25, 0x3B, 0x43, 0xBB,
+ 0x0C, 0x2C, 0xDF, 0x1B, 0x56,
+ 0x0A, 0x93, 0x60, 0x88, 0x61,
+ 0x03, 0x50, 0x97, 0x53, 0x32,
+ 0x00, 0x56, 0x9F, 0xB6, 0x6E,
+ 0x04, 0x4B, 0xD4, 0xC0, 0x62,
+ 0x01, 0x50, 0x9E, 0x87, 0x1D,
+ 0x0F, 0x98, 0xB0, 0x68, 0x75,
+ 0x0F, 0x60, 0xB5, 0xF1, 0x76,
+ 0x03, 0x58, 0xC5, 0xC0, 0xE6,
+ 0x00, 0x69, 0xC8, 0x9C, 0xCE,
+ 0x0D, 0xB0, 0xF8, 0xF7, 0xC7,
+ 0x04, 0x1E, 0xF8, 0xBD, 0xB7,
+ 0x00, 0x70, 0x17, 0x3E, 0x6D,
+ 0x0D, 0x0C, 0x56, 0xA2, 0x26,
+ 0x08, 0x07, 0x9B, 0xC2, 0x32,
+ 0x04, 0x37, 0xA6, 0xE0, 0x76,
+ 0x05, 0x3F, 0x64, 0x92, 0xDB,
+ 0x00, 0x9F, 0x18, 0xC6, 0x50,
+ 0x0C, 0x7F, 0x76, 0x36, 0xCB,
+ 0x06, 0x7B, 0x45, 0xEB, 0x2E,
+ 0x09, 0x6B, 0xEA, 0xA4, 0x72,
+ 0x04, 0xBB, 0x81, 0xCA, 0xB5,
+ 0x0D, 0x57, 0xB9, 0x9C, 0x2E,
+ 0x05, 0x52, 0x8F, 0x03, 0xF8,
+ 0x07, 0xF7, 0xEB, 0x20, 0xD4,
+ 0x05, 0x1E, 0x7C, 0xDC, 0x88,
+ 0x04, 0x6D, 0x5C, 0x48, 0x63,
+ 0x08, 0x17, 0x1C, 0xE5, 0x59,
+ 0x0F, 0x4D, 0xC8, 0xA1, 0x5A,
+ 0x05, 0xC9, 0x2D, 0xF9, 0x35,
+ 0x03, 0x01, 0x8C, 0xA3, 0x4B,
+ 0x01, 0xA9, 0x0E, 0x16, 0x78,
+ 0x0B, 0xA0, 0xD6, 0xD3, 0xC6,
+ 0x0C, 0x57, 0x31, 0xA6, 0x7C,
+ 0x0B, 0x03, 0x9D, 0x67, 0xA0,
+ 0x0E, 0x43, 0x38, 0x1E, 0xE1,
+ 0x0D, 0xDE, 0x1C, 0x70, 0x41,
+ 0x0E, 0xE6, 0x41, 0x29, 0xE1,
+ 0x04, 0xF9, 0x31, 0x5E, 0x38,
+ 0x01, 0x3A, 0x83, 0x08, 0x04,
+ 0x08, 0x09, 0xCA, 0xB0, 0xDE,
+ 0x0B, 0x91, 0x42, 0xB4, 0xFD,
+ 0x09, 0xDE, 0x69, 0xEA, 0x66,
+ 0x03, 0x19, 0x46, 0x99, 0x71,
+ 0x08, 0xEB, 0x2C, 0xFF, 0x3E,
+ 0x0A, 0x28, 0x02, 0x05, 0xAF,
+ 0x0A, 0x81, 0x4A, 0xFC, 0x27,
+ 0x0C, 0xBF, 0x91, 0xDD, 0x44,
+ 0x0A, 0x70, 0xBB, 0x33, 0x7A,
+ 0x05, 0xBF, 0x00, 0xF9, 0x05,
+ 0x04, 0x83, 0xB3, 0xB8, 0x79,
+ 0x0A, 0xE3, 0x44, 0x7F, 0xF5,
+ 0x01, 0x31, 0x10, 0x0C, 0x4F,
+ 0x03, 0x95, 0x61, 0xB9, 0x0E,
+ 0x09, 0x00, 0xA8, 0x7B, 0x24,
+ 0x0F, 0x2C, 0x74, 0xC2, 0xC6,
+ 0x0A, 0x0C, 0x8F, 0xE6, 0xF1,
+ 0x06, 0x59, 0xE3, 0xEE, 0x83,
+ 0x0B, 0x76, 0x09, 0x5B, 0x1C,
+ 0x02, 0x95, 0xE6, 0xDC, 0x0E,
+ 0x04, 0x9E, 0xB8, 0x89, 0x0C,
+ 0x0A, 0xFE, 0xAE, 0x09, 0x31,
+ 0x04, 0xC1, 0xEF, 0x8B, 0x99,
+ 0x04, 0xA7, 0x68, 0xF3, 0xE6,
+ 0x0D, 0x48, 0xE1, 0x6A, 0xE2,
+ 0x0A, 0x50, 0x90, 0x82, 0xE7,
+ 0x0A, 0xC3, 0x7A, 0xE0, 0xCF,
+ 0x0A, 0xD3, 0xF6, 0xCD, 0x65,
+ 0x09, 0xA9, 0x9A, 0x0C, 0x6F,
+ 0x0A, 0x5F, 0xD3, 0x6E, 0xA5,
+ 0x0F, 0xC5, 0xDD, 0x06, 0x8F,
+ 0x04, 0x16, 0x3C, 0xA8, 0x85,
+ 0x01, 0xCD, 0x0B, 0x9C, 0xC9,
+ 0x0D, 0x75, 0x10, 0x14, 0x8B,
+ 0x06, 0xCD, 0x0F, 0x70, 0xFF,
+ 0x03, 0xDF, 0x17, 0x32, 0x09,
+ 0x06, 0xD1, 0x63, 0xCF, 0x0A,
+ 0x09, 0xC7, 0x55, 0xC8, 0xC4,
+ 0x08, 0xA3, 0x16, 0x4E, 0x95,
+ 0x0C, 0xF2, 0x68, 0x8A, 0x55,
+ 0x07, 0xEC, 0x90, 0xD1, 0x9A,
+ 0x03, 0x30, 0x1A, 0xC4, 0xFE,
+ 0x05, 0xA4, 0x73, 0x59, 0x66,
+ 0x07, 0xBA, 0x8D, 0x6D, 0xD8,
+ 0x0D, 0x7D, 0x56, 0x07, 0x1E,
+ 0x07, 0x70, 0x38, 0x52, 0x7A,
+ 0x0A, 0x24, 0x31, 0x81, 0xE7,
+ 0x01, 0x1D, 0xE1, 0xFF, 0x07,
+ 0x06, 0x2E, 0x64, 0x12, 0x9D,
+ 0x03, 0xCF, 0x99, 0x18, 0x2A,
+ 0x0D, 0xAB, 0x89, 0x88, 0x80,
+ 0x0B, 0x30, 0x5E, 0xA9, 0x8D,
+ 0x03, 0xBF, 0xCB, 0x2B, 0x6F,
+ 0x05, 0x25, 0xBF, 0xA6, 0x92,
+ 0x08, 0x31, 0x14, 0x67, 0x3F,
+ 0x0D, 0x8C, 0xB2, 0xC1, 0xDF,
+ 0x0D, 0x1B, 0x5B, 0xBD, 0x5A,
+ 0x03, 0xAA, 0x14, 0xA2, 0x2E,
+ 0x00, 0x73, 0xA6, 0xF8, 0x5D,
+ 0x04, 0x67, 0x08, 0x1B, 0x00,
+ 0x02, 0x43, 0x1E, 0x02, 0x7C,
+ 0x05, 0x4A, 0x47, 0x39, 0xC7,
+ 0x05, 0x30, 0xC8, 0xC7, 0x3B,
+ 0x07, 0x13, 0x11, 0x0D, 0xCD,
+ 0x09, 0x49, 0xD4, 0x15, 0x13,
+ 0x02, 0x28, 0x56, 0x11, 0x38,
+ 0x0B, 0x7E, 0x4D, 0xC8, 0xCA,
+ 0x03, 0x28, 0xD2, 0x70, 0xC1,
+ 0x0D, 0x65, 0x9E, 0x3E, 0xE8,
+ 0x0C, 0xB7, 0xA0, 0xB7, 0x75,
+ 0x09, 0x28, 0x9E, 0x51, 0xC0,
+ 0x07, 0x49, 0xEB, 0xA8, 0x90,
+ 0x0E, 0x17, 0xB6, 0x6C, 0xFD,
+ 0x0F, 0xFC, 0x1E, 0xF8, 0xB9,
+ 0x09, 0xCA, 0x94, 0x8D, 0xBE,
+ 0x06, 0x52, 0x6C, 0xB6, 0xAC,
+ 0x0F, 0xA0, 0x61, 0x08, 0x02,
+ 0x0A, 0xAC, 0x37, 0xA6, 0xE4,
+ 0x08, 0xAD, 0x3F, 0x60, 0x62,
+ 0x06, 0x9C, 0x7B, 0x00, 0xD6,
+ 0x08, 0xA5, 0x3F, 0x1B, 0xBA,
+ 0x02, 0x3D, 0xBD, 0xDE, 0xAB,
+ 0x06, 0xC1, 0x6B, 0xEA, 0xA0,
+ 0x0A, 0xBC, 0xBB, 0x85, 0x47,
+ 0x0A, 0xD7, 0x91, 0x2D, 0x9C,
+ 0x06, 0x6D, 0x10, 0xED, 0x8F,
+ 0x00, 0x3D, 0xF1, 0x73, 0x20,
+ 0x0C, 0xED, 0x1C, 0x78, 0x52,
+ 0x02, 0x99, 0xBD, 0xD1, 0xC5,
+ 0x0D, 0x82, 0xF1, 0x89, 0xE5,
+ 0x02, 0x69, 0xAF, 0x48, 0xE1,
+ 0x0A, 0x7E, 0xCB, 0x20, 0xB0,
+ 0x05, 0x33, 0x00, 0x0C, 0xA3,
+ 0x0B, 0xFA, 0x2C, 0x75, 0x96,
+ 0x00, 0xFB, 0xA0, 0xD6, 0xD7,
+ 0x0B, 0xD7, 0x15, 0x4D, 0x2C,
+ 0x00, 0xF7, 0xE3, 0x91, 0x27,
+ 0x07, 0x23, 0xA3, 0x3A, 0xDE,
+ 0x01, 0xA1, 0xDE, 0x1F, 0xF0,
+ 0x03, 0xE2, 0xE4, 0x45, 0xE3,
+ 0x06, 0x3C, 0xFA, 0x71, 0x66,
+ 0x01, 0x58, 0xD8, 0x95, 0x88,
+ 0x0E, 0x25, 0xEB, 0x4A, 0xB8,
+ 0x02, 0x9B, 0x92, 0xC2, 0x80,
+ 0x04, 0x93, 0x9B, 0xFF, 0x6A,
+ 0x0E, 0x03, 0x19, 0x46, 0x97,
+ 0x0C, 0x58, 0xE9, 0x28, 0x78,
+ 0x0F, 0x41, 0xAD, 0x3F, 0xB1,
+ 0x07, 0xAA, 0x82, 0xC8, 0x78,
+ 0x0E, 0x07, 0x38, 0x41, 0x97,
+ 0x0C, 0x86, 0x72, 0xB0, 0xBA,
+ 0x0B, 0xBC, 0xBF, 0x60, 0xF7,
+ 0x0D, 0x4C, 0x22, 0x51, 0x34,
+ 0x03, 0xF5, 0xBC, 0xA4, 0x51,
+ 0x0C, 0x71, 0xF1, 0x12, 0x88,
+ 0x0C, 0x15, 0x4B, 0x61, 0x9D,
+ 0x0E, 0x20, 0xA5, 0x6B, 0x7B,
+ 0x0E, 0xB1, 0x3F, 0x54, 0xEC,
+ 0x0F, 0xB0, 0xCD, 0x23, 0xE8,
+ 0x0B, 0xD0, 0x82, 0x63, 0xCE,
+ 0x0A, 0xDA, 0xB6, 0x07, 0x5F,
+ 0x0F, 0x04, 0x4E, 0x65, 0xFC,
+ 0x04, 0x72, 0x40, 0xBA, 0x88,
+ 0x04, 0xE1, 0x7B, 0x68, 0x8E,
+ 0x00, 0x7F, 0xC1, 0xED, 0x01,
+ 0x01, 0x04, 0xA7, 0x65, 0x7A,
+ 0x0A, 0xC5, 0x4B, 0x23, 0x5E,
+ 0x0A, 0x62, 0x20, 0x1D, 0x86,
+ 0x0F, 0x2A, 0xC1, 0x7A, 0x6E,
+ 0x0F, 0x0C, 0x31, 0x76, 0x48,
+ 0x07, 0xC9, 0xA9, 0x95, 0x85,
+ 0x0F, 0xDA, 0x57, 0xDC, 0xA2,
+ 0x0C, 0xB3, 0xC5, 0xDD, 0x06,
+ 0x06, 0xEC, 0x14, 0xBE, 0xA0,
+ 0x05, 0x2B, 0xC9, 0xB5, 0x55,
+ 0x09, 0x3D, 0x74, 0x92, 0x19,
+ 0x02, 0xF6, 0xCF, 0x0E, 0xFA,
+ 0x07, 0x83, 0xDF, 0x17, 0x32,
+ 0x02, 0x4E, 0xD1, 0xE7, 0xCD,
+ 0x03, 0x11, 0x22, 0xD5, 0x04,
+ 0x0E, 0x46, 0xC4, 0x98, 0x0E,
+ 0x0C, 0x86, 0x34, 0xD8, 0x8A,
+ 0x0F, 0xA1, 0x16, 0x12, 0xDE,
+ 0x0F, 0x53, 0x31, 0x58, 0xF3,
+ 0x0D, 0x3D, 0x82, 0xC9, 0x19,
+ 0x0D, 0x89, 0x53, 0x0D, 0x7D,
+ 0x04, 0x2D, 0x7B, 0xD4, 0x33,
+ 0x0E, 0x97, 0xB0, 0x37, 0x92,
+ 0x03, 0xE8, 0x64, 0x37, 0x85,
+ 0x07, 0x9C, 0xE7, 0x61, 0xFE,
+ 0x0B, 0xBE, 0x2C, 0x24, 0x2B,
+ 0x04, 0x21, 0xEF, 0x95, 0x55,
+ 0x09, 0x8B, 0x40, 0x09, 0x8C,
+ 0x09, 0x42, 0xF0, 0x98, 0xAB,
+ 0x07, 0xEF, 0x43, 0x94, 0x2A,
+ 0x03, 0xD9, 0x27, 0xFF, 0x1F,
+ 0x0F, 0xE2, 0x31, 0x9A, 0x29,
+ 0x05, 0x43, 0x61, 0xB2, 0xCB,
+ 0x03, 0x74, 0x1F, 0xDB, 0x89,
+ 0x03, 0xFA, 0x68, 0x1A, 0xEF,
+ 0x07, 0xE2, 0x33, 0xA0, 0xB5,
+ 0x0E, 0x4E, 0x9D, 0x8B, 0xDA,
+ 0x08, 0x3B, 0xC2, 0xBE, 0x36,
+ 0x05, 0xDE, 0xC8, 0x2B, 0x7B,
+ 0x0D, 0x99, 0xC2, 0x2A, 0x57,
+ 0x07, 0x57, 0x12, 0xD1, 0x39,
+ 0x0D, 0xE3, 0x19, 0x58, 0x5B,
+ 0x09, 0x74, 0xDC, 0x56, 0x97,
+ 0x0E, 0x4B, 0x7A, 0xCD, 0x75,
+ 0x09, 0x63, 0xE8, 0xDC, 0xBE,
+ 0x02, 0x1C, 0xA5, 0x9A, 0x7E,
+ 0x02, 0x33, 0x4D, 0xE0, 0xB4,
+ 0x09, 0x50, 0x28, 0x1E, 0x64,
+ 0x09, 0x65, 0x49, 0xE5, 0xE8,
+ 0x0A, 0xC8, 0xEE, 0xB6, 0x78,
+ 0x0B, 0x87, 0xFD, 0xDE, 0xC1,
+ 0x00, 0x12, 0x6A, 0x78, 0xCF,
+ 0x04, 0x6A, 0xAD, 0x8E, 0x32,
+ 0x02, 0x26, 0x23, 0x81, 0x31,
+ 0x0B, 0x72, 0x6C, 0x33, 0xE6,
+ 0x0D, 0x52, 0xED, 0x31, 0x24,
+ 0x0C, 0xFA, 0x60, 0x19, 0x81,
+ 0x0A, 0x52, 0x1E, 0x7D, 0x2F,
+ 0x0A, 0xCB, 0x3C, 0x73, 0xAB,
+ 0x01, 0x68, 0x3E, 0xEB, 0xEB,
+ 0x09, 0xD3, 0x7C, 0xBB, 0x41,
+ 0x02, 0xAB, 0xD7, 0x51, 0x36,
+ 0x00, 0x10, 0x90, 0xD0, 0xD6,
+ 0x0F, 0xF8, 0x3D, 0xF5, 0xAE,
+ 0x09, 0x14, 0x0D, 0x10, 0x3C,
+ 0x01, 0x2F, 0xFC, 0x6D, 0x9C,
+ 0x0C, 0x44, 0x02, 0x11, 0x84,
+ 0x0C, 0xF0, 0x8F, 0x49, 0x08,
+ 0x01, 0x5A, 0x7E, 0xC9, 0x2D,
+ 0x09, 0x35, 0x33, 0x05, 0x77,
+ 0x03, 0x4B, 0xFA, 0x2C, 0x75,
+ 0x0D, 0x78, 0xFB, 0xA0, 0xD6,
+ 0x01, 0x82, 0xD6, 0x95, 0x79,
+ 0x0C, 0xFB, 0x77, 0x0D, 0xDD,
+ 0x0D, 0xA9, 0xAA, 0x43, 0x3C,
+ 0x02, 0xD9, 0xA3, 0x9E, 0x26,
+ 0x09, 0xF9, 0xE2, 0xE8, 0x01,
+ 0x03, 0xDD, 0x34, 0xF9, 0xA1,
+ 0x0E, 0x38, 0xD8, 0xF8, 0xA1,
+ 0x01, 0x86, 0x03, 0x07, 0x8A,
+ 0x0A, 0xD9, 0x9C, 0x91, 0x4A,
+ 0x08, 0xFD, 0x93, 0x1B, 0xCB,
+ 0x03, 0xE4, 0x43, 0x17, 0x06,
+ 0x0D, 0xF3, 0x5F, 0xEB, 0x2E,
+ 0x0B, 0xF0, 0x49, 0xAD, 0xBA,
+ 0x0C, 0xAF, 0x6A, 0x85, 0x4A,
+ 0x08, 0xE9, 0x34, 0x3A, 0x4E,
+ 0x01, 0x44, 0x87, 0x30, 0x84,
+ 0x0A, 0xC1, 0xFC, 0x31, 0xA0,
+ 0x0D, 0xC2, 0xDC, 0x82, 0x57,
+ 0x08, 0x79, 0xF1, 0x22, 0x9D,
+ 0x08, 0x37, 0x31, 0x3F, 0x50,
+ 0x02, 0x41, 0x03, 0x95, 0x71,
+ 0x01, 0x37, 0x20, 0xC5, 0x50,
+ 0x02, 0xA6, 0xB7, 0xEA, 0x94,
+ 0x06, 0x01, 0x3C, 0x0D, 0x27,
+ 0x04, 0xB1, 0xD7, 0x19, 0xDA,
+ 0x07, 0x01, 0x7B, 0x78, 0x4B,
+ 0x05, 0x52, 0x0C, 0x15, 0xE7,
+ 0x06, 0x09, 0x64, 0x9E, 0xBB,
+ 0x05, 0x0C, 0xE3, 0xFB, 0x5F,
+ 0x0E, 0x79, 0xBF, 0xCF, 0xAF,
+ 0x01, 0x9E, 0x37, 0xA7, 0x69,
+ 0x0F, 0xE6, 0xC4, 0x08, 0xDA,
+ 0x03, 0x60, 0x42, 0x2E, 0x50,
+ 0x06, 0x20, 0x32, 0xC3, 0x7E,
+ 0x02, 0x45, 0x08, 0x93, 0xCF,
+ 0x00, 0xED, 0xE9, 0xA7, 0xD8,
+ 0x06, 0x62, 0x02, 0x5F, 0xC1,
+ 0x0F, 0xAC, 0xB2, 0x87, 0xE4,
+ 0x0F, 0x34, 0xEC, 0x18, 0xFE,
+ 0x00, 0x02, 0x3D, 0x4B, 0xBA,
+ 0x00, 0xE9, 0x3F, 0x35, 0x2B,
+ 0x00, 0x40, 0xB6, 0xC3, 0x4E,
+ 0x0A, 0xF8, 0x95, 0x5F, 0x1F,
+ 0x08, 0x0E, 0x56, 0xD1, 0xE6,
+ 0x01, 0x8A, 0x95, 0x46, 0xEC,
+ 0x0D, 0xC5, 0xE0, 0x2F, 0x58,
+ 0x04, 0x52, 0xB5, 0xF4, 0xDD,
+ 0x06, 0x15, 0xA6, 0xAC, 0xAB,
+ 0x06, 0x11, 0x53, 0x3E, 0x58,
+ 0x00, 0x33, 0x9F, 0x22, 0xC3,
+ 0x05, 0x67, 0x8D, 0xFA, 0x34,
+ 0x04, 0x5A, 0x2D, 0x73, 0x14,
+ 0x00, 0x50, 0xB7, 0xF0, 0x29,
+ 0x0E, 0x7A, 0xEB, 0x64, 0x0A,
+ 0x0C, 0x6F, 0xBA, 0x13, 0xA1,
+ 0x05, 0x00, 0xA0, 0xAE, 0x66,
+ 0x0E, 0x9D, 0xA1, 0x8F, 0xA2,
+ 0x0C, 0xA1, 0xCD, 0xA5, 0xC9,
+ 0x02, 0x87, 0x5C, 0xB0, 0x94,
+ 0x01, 0x0A, 0xC9, 0x39, 0x15,
+ 0x07, 0x4F, 0xDF, 0xA5, 0x86,
+ 0x0F, 0xA6, 0xA0, 0x3F, 0xD4,
+ 0x00, 0x7D, 0x05, 0x8A, 0xB2,
+ 0x05, 0x18, 0x47, 0x1A, 0xDA,
+ 0x0C, 0x5A, 0xFB, 0xE8, 0x2D,
+ 0x06, 0xAC, 0xC0, 0x7D, 0xE4,
+ 0x0F, 0xD3, 0x61, 0x67, 0x0F,
+ 0x07, 0x34, 0x39, 0x83, 0xC7,
+ 0x06, 0xFE, 0x7C, 0xC6, 0x65,
+ 0x01, 0x40, 0xB6, 0x36, 0x3A,
+ 0x0B, 0x1B, 0x55, 0x53, 0x28,
+ 0x09, 0x06, 0x61, 0x37, 0x16,
+ 0x01, 0xD4, 0x55, 0x28, 0x5E,
+ 0x03, 0xB2, 0x4A, 0x3E, 0x74,
+ 0x05, 0x42, 0x23, 0x26, 0x92,
+ 0x04, 0x8C, 0x3A, 0x65, 0x9C,
+ 0x04, 0xEF, 0x1C, 0xB7, 0x61,
+ 0x09, 0xF5, 0x54, 0xA9, 0x67,
+ 0x04, 0xC0, 0x27, 0x47, 0xAB,
+ 0x01, 0x92, 0x8E, 0x13, 0xF6,
+ 0x02, 0x70, 0xB4, 0xFC, 0x1F,
+ 0x04, 0xB9, 0x91, 0x0A, 0x4F,
+ 0x06, 0xBC, 0x2C, 0x5A, 0xCE,
+ 0x0C, 0xA9, 0x17, 0xA2, 0x05,
+ 0x04, 0xC2, 0x70, 0xEC, 0x0E,
+ 0x0F, 0x66, 0x10, 0xA3, 0x7F,
+ 0x0E, 0x91, 0xCD, 0x1A, 0x89,
+ 0x0C, 0xC6, 0x50, 0xE5, 0xC4,
+ 0x0F, 0xB8, 0xCB, 0x32, 0x3D,
+ 0x0A, 0x6C, 0x41, 0x41, 0x69,
+ 0x06, 0xA0, 0x50, 0xFC, 0x82,
+ 0x08, 0x4C, 0xB3, 0xD9, 0x11,
+ 0x0B, 0x9B, 0x00, 0xEC, 0xD8,
+ 0x05, 0x08, 0xC9, 0xBD, 0xF0,
+ 0x0F, 0x20, 0x96, 0x6D, 0x27,
+ 0x05, 0x58, 0x49, 0x12, 0x2D,
+ 0x05, 0x4E, 0x24, 0x06, 0x91,
+ 0x0E, 0xE2, 0x6B, 0x6F, 0x4C,
+ 0x04, 0xA2, 0xE1, 0xFE, 0xF0,
+ 0x0D, 0xF9, 0x35, 0x3D, 0x7A,
+ 0x06, 0xA4, 0x70, 0xFA, 0x2D,
+ 0x09, 0x96, 0x7E, 0x3B, 0x99,
+ 0x0F, 0x5F, 0xC6, 0xD9, 0x95,
+ 0x0A, 0xA2, 0x4F, 0x77, 0x01,
+ 0x01, 0x24, 0x15, 0x22, 0x7A,
+ 0x08, 0x5E, 0xD9, 0xAF, 0xA5,
+ 0x05, 0xF7, 0x40, 0xE2, 0xE7,
+ 0x08, 0xA8, 0x1A, 0x3C, 0x39,
+ 0x0D, 0x6A, 0x38, 0xDA, 0xAF,
+ 0x04, 0xB7, 0xF8, 0x23, 0x30,
+ 0x0A, 0xB0, 0xDE, 0x9F, 0x4C,
+ 0x0B, 0x34, 0x1D, 0x9C, 0x1B,
+ 0x0B, 0xEC, 0x86, 0x03, 0xD9,
+ 0x06, 0x97, 0xF4, 0x58, 0xEB,
+ 0x05, 0x59, 0x17, 0x45, 0x6D,
+ 0x0B, 0x05, 0xAF, 0xAA, 0x81,
+ 0x0A, 0xF2, 0xEE, 0x03, 0xC1,
+ 0x0F, 0x5D, 0x44, 0x86, 0x70,
+ 0x06, 0xB3, 0x43, 0xBC, 0x3F,
+ 0x0C, 0xF7, 0xC7, 0xCC, 0xBB,
+ 0x0B, 0xB4, 0x7B, 0xF3, 0x62,
+ 0x0C, 0x71, 0xB5, 0x71, 0x31,
+ 0x09, 0x08, 0x86, 0x11, 0x15,
+ 0x08, 0x3F, 0x77, 0x2C, 0xC5,
+ 0x03, 0xFC, 0x60, 0xB7, 0xF4,
+ 0x08, 0xF4, 0x06, 0x32, 0x9A,
+ 0x06, 0xE9, 0x71, 0xD6, 0x99,
+ 0x0F, 0xD1, 0x7F, 0x5B, 0x4F,
+ 0x0B, 0x5F, 0x55, 0x06, 0x08,
+ 0x0C, 0xDC, 0xCE, 0x7A, 0xDE,
+ 0x03, 0x8F, 0xCC, 0xE1, 0xBB,
+ 0x06, 0x87, 0x78, 0x7F, 0xC1,
+ 0x06, 0xA3, 0x59, 0x00, 0x27,
+ 0x08, 0xF3, 0xE6, 0xCB, 0x41,
+ 0x03, 0x6A, 0xE2, 0x66, 0xAA,
+ 0x00, 0x8C, 0x25, 0x2A, 0xC3,
+ 0x01, 0x6E, 0x45, 0x0A, 0xD3,
+ 0x0E, 0x49, 0x6D, 0xC9, 0xA9,
+ 0x00, 0x0C, 0x64, 0x9A, 0x5F,
+ 0x09, 0x63, 0xAC, 0xB3, 0xC7,
+ 0x05, 0x86, 0x15, 0x6E, 0x96,
+ 0x0E, 0xAA, 0x05, 0xAB, 0xCB,
+ 0x08, 0x1C, 0xEA, 0x3F, 0xFF,
+ 0x02, 0x19, 0xC2, 0x76, 0xCD,
+ 0x0E, 0xF0, 0xFC, 0x81, 0x55,
+ 0x07, 0x32, 0x09, 0xCE, 0xD1,
+ 0x07, 0xCD, 0x89, 0x13, 0x4C,
+ 0x05, 0xC4, 0xC6, 0x44, 0x2B,
+ 0x03, 0x4E, 0x55, 0x86, 0xF4,
+ 0x04, 0x8A, 0x95, 0xA9, 0x2C,
+ 0x09, 0x58, 0xD6, 0x53, 0x30,
+ 0x00, 0xCA, 0x36, 0xBF, 0xA2,
+ 0x0F, 0x59, 0xE6, 0x81, 0xFA,
+ 0x05, 0x6D, 0xDA, 0x2D, 0x7D,
+ 0x0F, 0x8D, 0x12, 0x93, 0x0B,
+ 0x01, 0xD2, 0x7A, 0xEE, 0x5D,
+ 0x08, 0x85, 0xED, 0x9A, 0x1D,
+ 0x01, 0xFF, 0x01, 0xBE, 0xEA,
+ 0x04, 0x12, 0x9D, 0xA3, 0xCF,
+ 0x0B, 0x15, 0x27, 0x8D, 0x6F,
+ 0x09, 0x88, 0x80, 0x42, 0x30,
+ 0x0C, 0xAB, 0x0D, 0x69, 0x33,
+ 0x04, 0x2B, 0x4F, 0xD9, 0x25,
+ 0x0F, 0x26, 0xA2, 0xE0, 0xBB,
+ 0x04, 0x69, 0x7F, 0x65, 0x4B,
+ 0x02, 0xCF, 0x1F, 0x74, 0xDF,
+ 0x0B, 0xB0, 0x5A, 0xFA, 0xA8,
+ 0x04, 0xAF, 0x2E, 0xE0, 0x73,
+ 0x04, 0xF5, 0xD4, 0xC8, 0xED,
+ 0x0B, 0xDB, 0x36, 0x1B, 0x49,
+ 0x05, 0x0F, 0x7C, 0x5C, 0xC8,
+ 0x0D, 0x3B, 0x47, 0x9F, 0x36,
+ 0x06, 0x46, 0x5F, 0x57, 0x0E,
+ 0x0B, 0xC0, 0x96, 0xEF, 0x96,
+ 0x0E, 0x1B, 0xD7, 0x72, 0xE8,
+ 0x0A, 0x9E, 0x0A, 0x8B, 0x63,
+ 0x07, 0x8C, 0xC9, 0x6D, 0x9A,
+ 0x0A, 0xFE, 0x8F, 0x1D, 0xA5,
+ 0x02, 0x3F, 0x2A, 0x75, 0xAA,
+ 0x0A, 0x75, 0xFC, 0x5E, 0x9C,
+ 0x06, 0x5D, 0xC4, 0xE7, 0x89,
+ 0x07, 0xA8, 0xB5, 0x8E, 0x0A,
+ 0x0C, 0xA8, 0x61, 0x09, 0x44,
+ 0x06, 0xF8, 0xBD, 0x90, 0x8A,
+ 0x0A, 0x8F, 0x4E, 0x2C, 0x49,
+ 0x04, 0xF6, 0xB8, 0xA8, 0x99,
+ 0x09, 0x08, 0xC6, 0x72, 0x6C,
+ 0x0B, 0xA6, 0x66, 0x50, 0xB0,
+ 0x05, 0xA4, 0x80, 0x72, 0x24,
+ 0x01, 0x80, 0xC2, 0x51, 0x65,
+ 0x01, 0x16, 0xA3, 0xCB, 0x21,
+ 0x07, 0x10, 0x7D, 0xE0, 0x00,
+ 0x03, 0xEA, 0xA4, 0x52, 0x7C,
+ 0x00, 0x81, 0xCE, 0x93, 0xD7,
+};
+
+static u8 ak7755_cram_aec[]= {
+ 0xB4, 0x00, 0x00, // CRAM Write Command
+ 0x7F, 0xFF, 0xF0,
+ 0x7F, 0xF6, 0x20,
+ 0x7F, 0xD8, 0x80,
+ 0x7F, 0xA7, 0x30,
+ 0x7F, 0x62, 0x30,
+ 0x7F, 0x09, 0x90,
+ 0x7E, 0x9D, 0x50,
+ 0x7E, 0x1D, 0x90,
+ 0x7D, 0x8A, 0x60,
+ 0x7C, 0xE3, 0xD0,
+ 0x7C, 0x2A, 0x00,
+ 0x7B, 0x5D, 0x00,
+ 0x7A, 0x7D, 0x00,
+ 0x79, 0x8A, 0x20,
+ 0x78, 0x84, 0x80,
+ 0x77, 0x6C, 0x50,
+ 0x76, 0x41, 0xB0,
+ 0x75, 0x04, 0xD0,
+ 0x73, 0xB5, 0xF0,
+ 0x72, 0x55, 0x30,
+ 0x70, 0xE2, 0xD0,
+ 0x6F, 0x5F, 0x00,
+ 0x6D, 0xCA, 0x10,
+ 0x6C, 0x24, 0x30,
+ 0x6A, 0x6D, 0xA0,
+ 0x68, 0xA6, 0xA0,
+ 0x66, 0xCF, 0x80,
+ 0x64, 0xE8, 0x90,
+ 0x62, 0xF2, 0x00,
+ 0x60, 0xEC, 0x40,
+ 0x5E, 0xD7, 0x80,
+ 0x5C, 0xB4, 0x20,
+ 0x5A, 0x82, 0x80,
+ 0x58, 0x42, 0xE0,
+ 0x55, 0xF5, 0xA0,
+ 0x53, 0x9B, 0x30,
+ 0x51, 0x33, 0xD0,
+ 0x4E, 0xBF, 0xF0,
+ 0x4C, 0x3F, 0xE0,
+ 0x49, 0xB4, 0x10,
+ 0x47, 0x1C, 0xF0,
+ 0x44, 0x7A, 0xD0,
+ 0x41, 0xCE, 0x20,
+ 0x3F, 0x17, 0x50,
+ 0x3C, 0x56, 0xC0,
+ 0x39, 0x8C, 0xE0,
+ 0x36, 0xBA, 0x20,
+ 0x33, 0xDE, 0xF0,
+ 0x30, 0xFB, 0xC0,
+ 0x2E, 0x11, 0x10,
+ 0x2B, 0x1F, 0x30,
+ 0x28, 0x26, 0xC0,
+ 0x25, 0x28, 0x10,
+ 0x22, 0x23, 0xA0,
+ 0x1F, 0x1A, 0x00,
+ 0x1C, 0x0B, 0x80,
+ 0x18, 0xF8, 0xC0,
+ 0x15, 0xE2, 0x10,
+ 0x12, 0xC8, 0x10,
+ 0x0F, 0xAB, 0x20,
+ 0x0C, 0x8B, 0xD0,
+ 0x09, 0x6A, 0x90,
+ 0x06, 0x47, 0xE0,
+ 0x03, 0x24, 0x30,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x14, 0x00,
+ 0xF0, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0xFF, 0x87, 0x50,
+ 0xFE, 0x8C, 0x50,
+ 0xFD, 0xE9, 0x70,
+ 0x00, 0x00, 0x00,
+ 0x06, 0xD8, 0xD0,
+ 0x11, 0x8D, 0x30,
+ 0x1B, 0xAE, 0x90,
+ 0x1F, 0xDC, 0xD0,
+ 0x1B, 0xAE, 0x90,
+ 0x11, 0x8D, 0x30,
+ 0x06, 0xD8, 0xD0,
+ 0x00, 0x00, 0x00,
+ 0xFD, 0xE9, 0x70,
+ 0xFE, 0x8C, 0x50,
+ 0xFF, 0x87, 0x50,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x00,
+ 0x07, 0x87, 0x80,
+ 0x78, 0x78, 0x80,
+ 0x00, 0x19, 0x00,
+ 0x45, 0xD9, 0xB0,
+ 0x3A, 0x26, 0x50,
+ 0x00, 0x1A, 0x00,
+ 0x05, 0x4A, 0x20,
+ 0x7A, 0xB5, 0xE0,
+ 0x00, 0x1D, 0x00,
+ 0x52, 0xF8, 0x20,
+ 0x2D, 0x07, 0xE0,
+ 0x00, 0x20, 0x00,
+ 0x43, 0xC3, 0xC0,
+ 0x3C, 0x3C, 0x40,
+ 0x00, 0x24, 0x00,
+ 0x72, 0xE1, 0xA0,
+ 0x0D, 0x1E, 0x60,
+ 0x00, 0x28, 0x00,
+ 0x7F, 0xFF, 0xF0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x2B, 0x00,
+ 0x0D, 0x1E, 0x60,
+ 0x72, 0xE1, 0xA0,
+ 0x00, 0x2F, 0x00,
+ 0x3C, 0x3C, 0x40,
+ 0x43, 0xC3, 0xC0,
+ 0x00, 0x32, 0x00,
+ 0x2D, 0x07, 0xE0,
+ 0x52, 0xF8, 0x20,
+ 0x00, 0x35, 0x00,
+ 0x7A, 0xB5, 0xE0,
+ 0x05, 0x4A, 0x20,
+ 0x00, 0x36, 0x00,
+ 0x3A, 0x26, 0x50,
+ 0x45, 0xD9, 0xB0,
+ 0x00, 0x37, 0x00,
+ 0x78, 0x78, 0x80,
+ 0x07, 0x87, 0x80,
+ 0x20, 0x00, 0x00,
+ 0x06, 0x66, 0x60,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x0A, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00,
+ 0x00, 0xC2, 0x00,
+ 0x00, 0x00, 0x10,
+ 0x01, 0x50, 0x20,
+ 0x03, 0x00, 0x30,
+ 0x04, 0x50, 0x40,
+ 0x06, 0x00, 0x50,
+ 0x07, 0x50, 0x60,
+ 0x09, 0x00, 0x70,
+ 0x10, 0x50, 0x80,
+ 0x12, 0x00, 0x90,
+ 0x13, 0x50, 0xA0,
+ 0x15, 0x00, 0xB0,
+ 0x16, 0x50, 0xC0,
+ 0x18, 0x00, 0xD0,
+ 0x19, 0x50, 0xE0,
+ 0x21, 0x00, 0xF0,
+ 0x22, 0x51, 0x00,
+ 0x24, 0x01, 0x10,
+ 0x25, 0x51, 0x20,
+ 0x27, 0x01, 0x30,
+ 0x28, 0x51, 0x40,
+ 0x30, 0x01, 0x50,
+ 0x31, 0x51, 0x60,
+ 0x33, 0x01, 0x70,
+ 0x34, 0x51, 0x80,
+ 0x36, 0x01, 0x90,
+ 0x01, 0x50, 0x20,
+ 0x03, 0x00, 0x30,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x00,
+ 0x00, 0x20, 0x00,
+ 0x00, 0x40, 0x00,
+ 0x00, 0x60, 0x00,
+ 0x00, 0x7F, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x02, 0x87, 0xA0,
+ 0x00, 0xCC, 0xD0,
+ 0x00, 0x40, 0xC0,
+ 0x00, 0x14, 0x80,
+ 0x00, 0xCC, 0xD0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x07, 0x40,
+ 0x00, 0x1C, 0x20,
+ 0x00, 0x29, 0xE0,
+ 0x00, 0x06, 0x20,
+ 0xFF, 0xB7, 0x40,
+ 0xFF, 0x96, 0x70,
+ 0xFF, 0xDC, 0x30,
+ 0x00, 0x29, 0x10,
+ 0x00, 0x00, 0x80,
+ 0xFF, 0xA9, 0xB0,
+ 0xFF, 0xD3, 0x90,
+ 0x00, 0x4E, 0xA0,
+ 0x00, 0x34, 0xB0,
+ 0xFF, 0x99, 0x10,
+ 0xFF, 0xA4, 0x60,
+ 0x00, 0x6C, 0xF0,
+ 0x00, 0x7D, 0xA0,
+ 0xFF, 0x85, 0xC0,
+ 0xFF, 0x50, 0x20,
+ 0x00, 0x7E, 0x50,
+ 0x00, 0xE7, 0xD0,
+ 0xFF, 0x7F, 0xF0,
+ 0xFE, 0xD3, 0x60,
+ 0x00, 0x78, 0xE0,
+ 0x01, 0x7B, 0xF0,
+ 0xFF, 0x96, 0xC0,
+ 0xFE, 0x27, 0x10,
+ 0x00, 0x4D, 0x20,
+ 0x02, 0x44, 0x30,
+ 0xFF, 0xDD, 0xD0,
+ 0xFD, 0x3F, 0x70,
+ 0xFF, 0xE3, 0xD0,
+ 0x03, 0x51, 0x40,
+ 0x00, 0x73, 0x80,
+ 0xFC, 0x04, 0x30,
+ 0xFF, 0x13, 0xD0,
+ 0x04, 0xC9, 0x20,
+ 0x01, 0x93, 0x50,
+ 0xFA, 0x37, 0x10,
+ 0xFD, 0x80, 0x50,
+ 0x07, 0x18, 0xF0,
+ 0x03, 0xDC, 0xF0,
+ 0xF7, 0x08, 0x60,
+ 0xF9, 0xF4, 0x10,
+ 0x0C, 0x00, 0x30,
+ 0x0A, 0x1A, 0x30,
+ 0xED, 0xCD, 0x40,
+ 0xEB, 0x8C, 0x30,
+ 0x28, 0x40, 0xF0,
+ 0x70, 0x4E, 0x60,
+ 0x70, 0x4E, 0x60,
+ 0x28, 0x40, 0xF0,
+ 0xEB, 0x8C, 0x30,
+ 0xED, 0xCD, 0x40,
+ 0x0A, 0x1A, 0x30,
+ 0x0C, 0x00, 0x30,
+ 0xF9, 0xF4, 0x10,
+ 0xF7, 0x08, 0x60,
+ 0x03, 0xDC, 0xF0,
+ 0x07, 0x18, 0xF0,
+ 0xFD, 0x80, 0x50,
+ 0xFA, 0x37, 0x10,
+ 0x01, 0x93, 0x50,
+ 0x04, 0xC9, 0x20,
+ 0xFF, 0x13, 0xD0,
+ 0xFC, 0x04, 0x30,
+ 0x00, 0x73, 0x80,
+ 0x03, 0x51, 0x40,
+ 0xFF, 0xE3, 0xD0,
+ 0xFD, 0x3F, 0x70,
+ 0xFF, 0xDD, 0xD0,
+ 0x02, 0x44, 0x30,
+ 0x00, 0x4D, 0x20,
+ 0xFE, 0x27, 0x10,
+ 0xFF, 0x96, 0xC0,
+ 0x01, 0x7B, 0xF0,
+ 0x00, 0x78, 0xE0,
+ 0xFE, 0xD3, 0x60,
+ 0xFF, 0x7F, 0xF0,
+ 0x00, 0xE7, 0xD0,
+ 0x00, 0x7E, 0x50,
+ 0xFF, 0x50, 0x20,
+ 0xFF, 0x85, 0xC0,
+ 0x00, 0x7D, 0xA0,
+ 0x00, 0x6C, 0xF0,
+ 0xFF, 0xA4, 0x60,
+ 0xFF, 0x99, 0x10,
+ 0x00, 0x34, 0xB0,
+ 0x00, 0x4E, 0xA0,
+ 0xFF, 0xD3, 0x90,
+ 0xFF, 0xA9, 0xB0,
+ 0x00, 0x00, 0x80,
+ 0x00, 0x29, 0x10,
+ 0xFF, 0xDC, 0x30,
+ 0xFF, 0x96, 0x70,
+ 0xFF, 0xB7, 0x40,
+ 0x00, 0x06, 0x20,
+ 0x00, 0x29, 0xE0,
+ 0x00, 0x1C, 0x20,
+ 0x00, 0x07, 0x40,
+ 0x00, 0x00, 0x00,
+ 0xFF, 0xFD, 0x60,
+ 0xFF, 0xF9, 0x60,
+ 0xFF, 0xFD, 0x40,
+ 0x00, 0x0A, 0x90,
+ 0x00, 0x0C, 0x80,
+ 0xFF, 0xF8, 0x00,
+ 0xFF, 0xEF, 0x60,
+ 0x00, 0x0D, 0xB0,
+ 0x00, 0x1F, 0xE0,
+ 0xFF, 0xF3, 0x50,
+ 0xFF, 0xD0, 0xC0,
+ 0x00, 0x0E, 0x40,
+ 0x00, 0x48, 0x10,
+ 0xFF, 0xF5, 0x80,
+ 0xFF, 0x9A, 0x50,
+ 0x00, 0x05, 0x20,
+ 0x00, 0x8D, 0x90,
+ 0x00, 0x06, 0xB0,
+ 0xFF, 0x41, 0xD0,
+ 0xFF, 0xE7, 0xB0,
+ 0x00, 0xFB, 0x20,
+ 0x00, 0x33, 0x80,
+ 0xFE, 0xBB, 0x40,
+ 0xFF, 0xA6, 0x60,
+ 0x01, 0x9E, 0x30,
+ 0x00, 0x8E, 0xD0,
+ 0xFD, 0xF6, 0x70,
+ 0xFF, 0x29, 0x50,
+ 0x02, 0x8B, 0x40,
+ 0x01, 0x37, 0x70,
+ 0xFC, 0xD7, 0x60,
+ 0xFE, 0x46, 0xE0,
+ 0x03, 0xEB, 0x30,
+ 0x02, 0x69, 0x50,
+ 0xFB, 0x1D, 0x40,
+ 0xFC, 0xA1, 0x60,
+ 0x06, 0x2D, 0x70,
+ 0x04, 0xC5, 0x00,
+ 0xF7, 0xF6, 0x20,
+ 0xF9, 0x02, 0x40,
+ 0x0B, 0x14, 0x00,
+ 0x0B, 0x17, 0xC0,
+ 0xEE, 0xB1, 0x80,
+ 0xEA, 0x7B, 0x10,
+ 0x27, 0x7C, 0x40,
+ 0x71, 0xE1, 0xE0,
+ 0x71, 0xE1, 0xE0,
+ 0x27, 0x7C, 0x40,
+ 0xEA, 0x7B, 0x10,
+ 0xEE, 0xB1, 0x80,
+ 0x0B, 0x17, 0xC0,
+ 0x0B, 0x14, 0x00,
+ 0xF9, 0x02, 0x40,
+ 0xF7, 0xF6, 0x20,
+ 0x04, 0xC5, 0x00,
+ 0x06, 0x2D, 0x70,
+ 0xFC, 0xA1, 0x60,
+ 0xFB, 0x1D, 0x40,
+ 0x02, 0x69, 0x50,
+ 0x03, 0xEB, 0x30,
+ 0xFE, 0x46, 0xE0,
+ 0xFC, 0xD7, 0x60,
+ 0x01, 0x37, 0x70,
+ 0x02, 0x8B, 0x40,
+ 0xFF, 0x29, 0x50,
+ 0xFD, 0xF6, 0x70,
+ 0x00, 0x8E, 0xD0,
+ 0x01, 0x9E, 0x30,
+ 0xFF, 0xA6, 0x60,
+ 0xFE, 0xBB, 0x40,
+ 0x00, 0x33, 0x80,
+ 0x00, 0xFB, 0x20,
+ 0xFF, 0xE7, 0xB0,
+ 0xFF, 0x41, 0xD0,
+ 0x00, 0x06, 0xB0,
+ 0x00, 0x8D, 0x90,
+ 0x00, 0x05, 0x20,
+ 0xFF, 0x9A, 0x50,
+ 0xFF, 0xF5, 0x80,
+ 0x00, 0x48, 0x10,
+ 0x00, 0x0E, 0x40,
+ 0xFF, 0xD0, 0xC0,
+ 0xFF, 0xF3, 0x50,
+ 0x00, 0x1F, 0xE0,
+ 0x00, 0x0D, 0xB0,
+ 0xFF, 0xEF, 0x60,
+ 0xFF, 0xF8, 0x00,
+ 0x00, 0x0C, 0x80,
+ 0x00, 0x0A, 0x90,
+ 0xFF, 0xFD, 0x40,
+ 0xFF, 0xF9, 0x60,
+ 0xFF, 0xFD, 0x60,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x14, 0x00,
+ 0xF0, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0xFF, 0x87, 0x50,
+ 0xFE, 0x8C, 0x50,
+ 0xFD, 0xE9, 0x70,
+ 0x00, 0x00, 0x00,
+ 0x06, 0xD8, 0xD0,
+ 0x11, 0x8D, 0x30,
+ 0x1B, 0xAE, 0x90,
+ 0x1F, 0xDC, 0xD0,
+ 0x1B, 0xAE, 0x90,
+ 0x11, 0x8D, 0x30,
+ 0x06, 0xD8, 0xD0,
+ 0x00, 0x00, 0x00,
+ 0xFD, 0xE9, 0x70,
+ 0xFE, 0x8C, 0x50,
+ 0xFF, 0x87, 0x50,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x00,
+ 0x07, 0x87, 0x80,
+ 0x78, 0x78, 0x80,
+ 0x00, 0x19, 0x00,
+ 0x45, 0xD9, 0xB0,
+ 0x3A, 0x26, 0x50,
+ 0x00, 0x1A, 0x00,
+ 0x05, 0x4A, 0x20,
+ 0x7A, 0xB5, 0xE0,
+ 0x00, 0x1D, 0x00,
+ 0x52, 0xF8, 0x20,
+ 0x2D, 0x07, 0xE0,
+ 0x00, 0x20, 0x00,
+ 0x43, 0xC3, 0xC0,
+ 0x3C, 0x3C, 0x40,
+ 0x00, 0x24, 0x00,
+ 0x72, 0xE1, 0xA0,
+ 0x0D, 0x1E, 0x60,
+ 0x00, 0x28, 0x00,
+ 0x7F, 0xFF, 0xF0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x2B, 0x00,
+ 0x0D, 0x1E, 0x60,
+ 0x72, 0xE1, 0xA0,
+ 0x00, 0x2F, 0x00,
+ 0x3C, 0x3C, 0x40,
+ 0x43, 0xC3, 0xC0,
+ 0x00, 0x32, 0x00,
+ 0x2D, 0x07, 0xE0,
+ 0x52, 0xF8, 0x20,
+ 0x00, 0x35, 0x00,
+ 0x7A, 0xB5, 0xE0,
+ 0x05, 0x4A, 0x20,
+ 0x00, 0x36, 0x00,
+ 0x3A, 0x26, 0x50,
+ 0x45, 0xD9, 0xB0,
+ 0x00, 0x37, 0x00,
+ 0x78, 0x78, 0x80,
+ 0x07, 0x87, 0x80,
+ 0x20, 0x00, 0x00,
+ 0x06, 0x66, 0x60,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0xC8, 0x00, 0x00,
+ 0xEB, 0xD8, 0x60,
+ 0x42, 0xCD, 0xA0,
+ 0xA2, 0x68, 0x10,
+ 0x62, 0xB9, 0xF0,
+ 0x0C, 0x35, 0x90,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x14, 0x00,
+ 0xF0, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0xFF, 0x87, 0x50,
+ 0xFE, 0x8C, 0x50,
+ 0xFD, 0xE9, 0x70,
+ 0x00, 0x00, 0x00,
+ 0x06, 0xD8, 0xD0,
+ 0x11, 0x8D, 0x30,
+ 0x1B, 0xAE, 0x90,
+ 0x1F, 0xDC, 0xD0,
+ 0x1B, 0xAE, 0x90,
+ 0x11, 0x8D, 0x30,
+ 0x06, 0xD8, 0xD0,
+ 0x00, 0x00, 0x00,
+ 0xFD, 0xE9, 0x70,
+ 0xFE, 0x8C, 0x50,
+ 0xFF, 0x87, 0x50,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x00,
+ 0x07, 0x87, 0x80,
+ 0x78, 0x78, 0x80,
+ 0x00, 0x19, 0x00,
+ 0x6A, 0x3E, 0xF0,
+ 0x15, 0xC1, 0x10,
+ 0x00, 0x1F, 0x00,
+ 0x51, 0x95, 0xE0,
+ 0x2E, 0x6A, 0x20,
+ 0x00, 0x22, 0x00,
+ 0x13, 0x41, 0x00,
+ 0x6C, 0xBF, 0x00,
+ 0x00, 0x26, 0x00,
+ 0x27, 0xFE, 0xD0,
+ 0x58, 0x01, 0x30,
+ 0x00, 0x2A, 0x00,
+ 0x31, 0x49, 0xC0,
+ 0x4E, 0xB6, 0x40,
+ 0x00, 0x2E, 0x00,
+ 0x51, 0x64, 0x10,
+ 0x2E, 0x9B, 0xF0,
+ 0x00, 0x31, 0x00,
+ 0x29, 0x02, 0x10,
+ 0x56, 0xFD, 0xF0,
+ 0x00, 0x33, 0x00,
+ 0x3B, 0x6D, 0x40,
+ 0x44, 0x92, 0xC0,
+ 0x00, 0x35, 0x00,
+ 0x7A, 0xB5, 0xE0,
+ 0x05, 0x4A, 0x20,
+ 0x00, 0x36, 0x00,
+ 0x6C, 0xB7, 0x00,
+ 0x13, 0x49, 0x00,
+ 0x00, 0x36, 0x00,
+ 0x15, 0xC1, 0x10,
+ 0x6A, 0x3E, 0xF0,
+ 0x00, 0x37, 0x00,
+ 0x78, 0x78, 0x80,
+ 0x07, 0x87, 0x80,
+ 0x20, 0x00, 0x00,
+ 0x06, 0x66, 0x60,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x02, 0x33, 0x00,
+ 0x01, 0x50, 0x10,
+ 0x00, 0x00, 0x20,
+ 0x01, 0x50, 0x30,
+ 0x03, 0x00, 0x40,
+ 0x04, 0x50, 0x50,
+ 0x06, 0x00, 0x60,
+ 0x07, 0x50, 0x70,
+ 0x09, 0x00, 0x80,
+ 0x10, 0x50, 0x90,
+ 0x12, 0x00, 0xA0,
+ 0x13, 0x50, 0xB0,
+ 0x15, 0x00, 0xC0,
+ 0x16, 0x50, 0xD0,
+ 0x18, 0x00, 0xD0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x14, 0x00,
+ 0xF0, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0xFF, 0x87, 0x50,
+ 0xFE, 0x8C, 0x50,
+ 0xFD, 0xE9, 0x70,
+ 0x00, 0x00, 0x00,
+ 0x06, 0xD8, 0xD0,
+ 0x11, 0x8D, 0x30,
+ 0x1B, 0xAE, 0x90,
+ 0x1F, 0xDC, 0xD0,
+ 0x1B, 0xAE, 0x90,
+ 0x11, 0x8D, 0x30,
+ 0x06, 0xD8, 0xD0,
+ 0x00, 0x00, 0x00,
+ 0xFD, 0xE9, 0x70,
+ 0xFE, 0x8C, 0x50,
+ 0xFF, 0x87, 0x50,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x00,
+ 0x07, 0x87, 0x80,
+ 0x78, 0x78, 0x80,
+ 0x00, 0x19, 0x00,
+ 0x45, 0xD9, 0xB0,
+ 0x3A, 0x26, 0x50,
+ 0x00, 0x1A, 0x00,
+ 0x05, 0x4A, 0x20,
+ 0x7A, 0xB5, 0xE0,
+ 0x00, 0x1D, 0x00,
+ 0x52, 0xF8, 0x20,
+ 0x2D, 0x07, 0xE0,
+ 0x00, 0x20, 0x00,
+ 0x43, 0xC3, 0xC0,
+ 0x3C, 0x3C, 0x40,
+ 0x00, 0x24, 0x00,
+ 0x72, 0xE1, 0xA0,
+ 0x0D, 0x1E, 0x60,
+ 0x00, 0x28, 0x00,
+ 0x7F, 0xFF, 0xF0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x2B, 0x00,
+ 0x0D, 0x1E, 0x60,
+ 0x72, 0xE1, 0xA0,
+ 0x00, 0x2F, 0x00,
+ 0x3C, 0x3C, 0x40,
+ 0x43, 0xC3, 0xC0,
+ 0x00, 0x32, 0x00,
+ 0x2D, 0x07, 0xE0,
+ 0x52, 0xF8, 0x20,
+ 0x00, 0x35, 0x00,
+ 0x7A, 0xB5, 0xE0,
+ 0x05, 0x4A, 0x20,
+ 0x00, 0x36, 0x00,
+ 0x3A, 0x26, 0x50,
+ 0x45, 0xD9, 0xB0,
+ 0x00, 0x37, 0x00,
+ 0x78, 0x78, 0x80,
+ 0x07, 0x87, 0x80,
+ 0x20, 0x00, 0x00,
+ 0x06, 0x66, 0x60,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0xC9, 0x10,
+ 0x02, 0x5B, 0x20,
+ 0x03, 0xED, 0x20,
+ 0x05, 0x7F, 0x00,
+ 0x07, 0x10, 0xA0,
+ 0x08, 0xA2, 0x00,
+ 0x0A, 0x33, 0x10,
+ 0x0B, 0xC3, 0xB0,
+ 0x0D, 0x53, 0xE0,
+ 0x0E, 0xE3, 0x80,
+ 0x10, 0x72, 0xA0,
+ 0x12, 0x01, 0x10,
+ 0x13, 0x8E, 0xE0,
+ 0x15, 0x1B, 0xE0,
+ 0x16, 0xA8, 0x10,
+ 0x18, 0x33, 0x60,
+ 0x19, 0xBD, 0xD0,
+ 0x1B, 0x47, 0x30,
+ 0x1C, 0xCF, 0x90,
+ 0x1E, 0x56, 0xD0,
+ 0x1F, 0xDC, 0xE0,
+ 0x21, 0x61, 0xB0,
+ 0x22, 0xE5, 0x40,
+ 0x24, 0x67, 0x70,
+ 0x25, 0xE8, 0x40,
+ 0x27, 0x67, 0xA0,
+ 0x28, 0xE5, 0x70,
+ 0x2A, 0x61, 0xB0,
+ 0x2B, 0xDC, 0x50,
+ 0x2D, 0x55, 0x40,
+ 0x2E, 0xCC, 0x70,
+ 0x30, 0x41, 0xC0,
+ 0x31, 0xB5, 0x50,
+ 0x33, 0x26, 0xE0,
+ 0x34, 0x96, 0x80,
+ 0x36, 0x04, 0x20,
+ 0x37, 0x6F, 0xA0,
+ 0x38, 0xD9, 0x00,
+ 0x3A, 0x40, 0x30,
+ 0x3B, 0xA5, 0x20,
+ 0x3D, 0x07, 0xC0,
+ 0x3E, 0x68, 0x10,
+ 0x3F, 0xC5, 0xF0,
+ 0x41, 0x21, 0x60,
+ 0x42, 0x7A, 0x40,
+ 0x43, 0xD0, 0xA0,
+ 0x45, 0x24, 0x50,
+ 0x46, 0x75, 0x70,
+ 0x47, 0xC3, 0xC0,
+ 0x49, 0x0F, 0x50,
+ 0x4A, 0x58, 0x20,
+ 0x4B, 0x9E, 0x00,
+ 0x4C, 0xE1, 0x00,
+ 0x4E, 0x21, 0x00,
+ 0x4F, 0x5E, 0x10,
+ 0x50, 0x98, 0x00,
+ 0x51, 0xCE, 0xD0,
+ 0x53, 0x02, 0x80,
+ 0x54, 0x33, 0x00,
+ 0x55, 0x60, 0x40,
+ 0x56, 0x8A, 0x30,
+ 0x57, 0xB0, 0xD0,
+ 0x58, 0xD4, 0x10,
+ 0x59, 0xF3, 0xE0,
+ 0x5B, 0x10, 0x30,
+ 0x5C, 0x29, 0x10,
+ 0x5D, 0x3E, 0x50,
+ 0x5E, 0x50, 0x00,
+ 0x5F, 0x5E, 0x10,
+ 0x60, 0x68, 0x70,
+ 0x61, 0x6F, 0x10,
+ 0x62, 0x72, 0x00,
+ 0x63, 0x71, 0x10,
+ 0x64, 0x6C, 0x60,
+ 0x65, 0x63, 0xC0,
+ 0x66, 0x57, 0x40,
+ 0x67, 0x46, 0xC0,
+ 0x68, 0x32, 0x50,
+ 0x69, 0x19, 0xE0,
+ 0x69, 0xFD, 0x60,
+ 0x6A, 0xDC, 0xD0,
+ 0x6B, 0xB8, 0x10,
+ 0x6C, 0x8F, 0x30,
+ 0x6D, 0x62, 0x20,
+ 0x6E, 0x30, 0xE0,
+ 0x6E, 0xFB, 0x60,
+ 0x6F, 0xC1, 0x90,
+ 0x70, 0x83, 0x80,
+ 0x71, 0x41, 0x10,
+ 0x71, 0xFA, 0x40,
+ 0x72, 0xAF, 0x00,
+ 0x73, 0x5F, 0x60,
+ 0x74, 0x0B, 0x50,
+ 0x74, 0xB2, 0xD0,
+ 0x75, 0x55, 0xC0,
+ 0x75, 0xF4, 0x30,
+ 0x76, 0x8E, 0x10,
+ 0x77, 0x23, 0x60,
+ 0x77, 0xB4, 0x10,
+ 0x78, 0x40, 0x30,
+ 0x78, 0xC7, 0xB0,
+ 0x79, 0x4A, 0x80,
+ 0x79, 0xC8, 0xA0,
+ 0x7A, 0x42, 0x10,
+ 0x7A, 0xB6, 0xD0,
+ 0x7B, 0x26, 0xD0,
+ 0x7B, 0x92, 0x10,
+ 0x7B, 0xF8, 0x90,
+ 0x7C, 0x5A, 0x40,
+ 0x7C, 0xB7, 0x20,
+ 0x7D, 0x0F, 0x40,
+ 0x7D, 0x62, 0x90,
+ 0x7D, 0xB1, 0x00,
+ 0x7D, 0xFA, 0xA0,
+ 0x7E, 0x3F, 0x50,
+ 0x7E, 0x7F, 0x40,
+ 0x7E, 0xBA, 0x40,
+ 0x7E, 0xF0, 0x60,
+ 0x7F, 0x21, 0x90,
+ 0x7F, 0x4D, 0xE0,
+ 0x7F, 0x75, 0x50,
+ 0x7F, 0x97, 0xD0,
+ 0x7F, 0xB5, 0x60,
+ 0x7F, 0xCE, 0x10,
+ 0x7F, 0xE1, 0xC0,
+ 0x7F, 0xF0, 0x90,
+ 0x7F, 0xFA, 0x70,
+ 0x7F, 0xFF, 0x60,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00,
+ 0x03, 0x46, 0xE0,
+ 0x00, 0xBE, 0x00,
+ 0x02, 0x0C, 0x50,
+ 0x20, 0x00, 0x00,
+ 0x14, 0x00, 0x00,
+ 0x00, 0x0C, 0x00,
+ 0x0C, 0xCC, 0xD0,
+ 0x00, 0x51, 0xF0,
+ 0x04, 0x00, 0x00,
+ 0x00, 0x41, 0x90,
+ 0x01, 0x47, 0xB0,
+ 0x7E, 0xB8, 0x50,
+ 0x7B, 0xC0, 0x00,
+ 0x38, 0x00, 0x00,
+ 0x0C, 0xCC, 0xD0,
+ 0x01, 0x47, 0xB0,
+ 0x06, 0x66, 0x60,
+ 0x06, 0x66, 0x60,
+ 0xF5, 0xFF, 0xF0,
+ 0x20, 0x00, 0x00,
+ 0x00, 0x28, 0xF0,
+ 0x00, 0x28, 0x00,
+ 0x01, 0x47, 0xB0,
+ 0x0F, 0x5C, 0x30,
+ 0x00, 0x51, 0xF0,
+ 0xF7, 0x45, 0xD0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x28, 0xF0,
+ 0x00, 0x16, 0x00,
+ 0x01, 0x47, 0xB0,
+ 0x0C, 0xCC, 0xD0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x28, 0xF0,
+ 0x00, 0x42, 0x00,
+ 0x2B, 0x85, 0x20,
+ 0x14, 0x7A, 0xE0,
+ 0x0C, 0xCC, 0xD0,
+ 0x08, 0xF5, 0xC0,
+ 0x05, 0x1E, 0xC0,
+ 0x02, 0x8F, 0x60,
+ 0x08, 0x00, 0x00,
+ 0x00, 0x90, 0x00,
+ 0x00, 0x00, 0x00,
+ 0xC8, 0x00, 0x00,
+ 0x5A, 0x9D, 0xF0,
+ 0x06, 0x66, 0x00,
+ 0x13, 0x33, 0x00,
+ 0x13, 0x33, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x0D, 0x1B, 0x40,
+ 0x1A, 0x36, 0x80,
+ 0xC9, 0xD2, 0x70,
+ 0x75, 0x5B, 0xE0,
+ 0x0D, 0x1B, 0x40,
+ 0x0D, 0x1B, 0x40,
+ 0x1A, 0x36, 0x80,
+ 0xC9, 0xD2, 0x70,
+ 0x75, 0x5B, 0xE0,
+ 0x0D, 0x1B, 0x40,
+ 0x3C, 0x8A, 0xE0,
+ 0x86, 0xEA, 0x40,
+ 0xC6, 0xBA, 0x60,
+ 0x78, 0xE5, 0xF0,
+ 0x3C, 0x8A, 0xE0,
+ 0x18, 0xFE, 0x60,
+ 0x0C, 0x7F, 0x30,
+ 0xEA, 0xAA, 0xB0,
+ 0x3C, 0x57, 0x00,
+ 0x18, 0xFE, 0x60,
+ 0x00, 0x80, 0x00,
+ 0x02, 0x80, 0x00,
+ 0x01, 0x40, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x12, 0xC8, 0x10,
+ 0x11, 0x0F, 0x70,
+ 0x7F, 0xFE, 0x00,
+ 0x6E, 0x77, 0xF0,
+ 0x80, 0x01, 0x00,
+ 0x11, 0x88, 0x20,
+ 0x80, 0x00, 0x00,
+ 0x7F, 0xFD, 0x00,
+ 0x5C, 0xEF, 0xE0,
+ 0x7F, 0xFE, 0x00,
+ 0x6E, 0x77, 0xF0,
+ 0x7F, 0xFE, 0x00,
+ 0x6E, 0x77, 0xF0,
+ 0x80, 0x01, 0x00,
+ 0x11, 0x88, 0x20,
+ 0x80, 0x00, 0x00,
+ 0x7F, 0xFD, 0x00,
+ 0x5C, 0xEF, 0xE0,
+ 0x7F, 0xFE, 0x00,
+ 0x6E, 0x77, 0xF0,
+ 0x7F, 0xFE, 0x00,
+ 0x6E, 0x77, 0xF0,
+ 0x80, 0x01, 0x00,
+ 0x11, 0x88, 0x20,
+ 0x80, 0x00, 0x00,
+ 0x7F, 0xFD, 0x00,
+ 0x5C, 0xEF, 0xE0,
+ 0x7F, 0xFE, 0x00,
+ 0x6E, 0x77, 0xF0,
+ 0x7F, 0xFE, 0x00,
+ 0x6E, 0x77, 0xF0,
+ 0x80, 0x01, 0x00,
+ 0x11, 0x88, 0x20,
+ 0x80, 0x00, 0x00,
+ 0x7F, 0xFD, 0x00,
+ 0x5C, 0xEF, 0xE0,
+ 0x7F, 0xFE, 0x00,
+ 0x6E, 0x77, 0xF0,
+ 0x03, 0x04, 0x10,
+ 0x7D, 0x0D, 0xB0,
+ 0x03, 0x04, 0x10,
+ 0x7D, 0x0D, 0xB0,
+ 0x03, 0x04, 0x10,
+ 0x7D, 0x0D, 0xB0,
+ 0x03, 0x04, 0x10,
+ 0x7D, 0x0D, 0xB0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x00,
+ 0xFE, 0x80, 0x00,
+ 0x0A, 0x80, 0x00,
+ 0xDD, 0x00, 0x00,
+ 0x68, 0xFF, 0x80,
+ 0x34, 0x7F, 0x00,
+ 0xFC, 0x80, 0x80,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x3F, 0xF0,
+ 0x08, 0x5F, 0xB0,
+ 0xEA, 0x91, 0x40,
+ 0xF7, 0xA0, 0x50,
+ 0x55, 0x2E, 0xD0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x51, 0x20,
+ 0xF8, 0x3B, 0xA0,
+ 0x19, 0x90, 0xF0,
+ 0x5C, 0x00, 0x00,
+ 0x19, 0x90, 0xF0,
+ 0xF8, 0x3B, 0xA0,
+ 0x00, 0x51, 0x20,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0xFF, 0xFE, 0x40,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x0A, 0x30,
+ 0x00, 0x00, 0x00,
+ 0xFF, 0xE5, 0x50,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x34, 0x70,
+ 0x00, 0x00, 0x00,
+ 0xFF, 0xA6, 0xF0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x8A, 0x40,
+ 0x00, 0x00, 0x00,
+ 0xFF, 0x35, 0xA0,
+ 0x00, 0x00, 0x00,
+ 0x01, 0x1C, 0x90,
+ 0x00, 0x00, 0x00,
+ 0xFE, 0x7A, 0x70,
+ 0x00, 0x00, 0x00,
+ 0x02, 0x0D, 0x20,
+ 0x00, 0x00, 0x00,
+ 0xFD, 0x3F, 0x80,
+ 0x00, 0x00, 0x00,
+ 0x03, 0xB9, 0x20,
+ 0x00, 0x00, 0x00,
+ 0xFA, 0xD2, 0x20,
+ 0x00, 0x00, 0x00,
+ 0x07, 0xAE, 0xA0,
+ 0x00, 0x00, 0x00,
+ 0xF2, 0xB3, 0xD0,
+ 0x00, 0x00, 0x00,
+ 0x28, 0xA6, 0x10,
+ 0x40, 0x00, 0x00,
+ 0x28, 0xA6, 0x10,
+ 0x00, 0x00, 0x00,
+ 0xF2, 0xB3, 0xD0,
+ 0x00, 0x00, 0x00,
+ 0x07, 0xAE, 0xA0,
+ 0x00, 0x00, 0x00,
+ 0xFA, 0xD2, 0x20,
+ 0x00, 0x00, 0x00,
+ 0x03, 0xB9, 0x20,
+ 0x00, 0x00, 0x00,
+ 0xFD, 0x3F, 0x80,
+ 0x00, 0x00, 0x00,
+ 0x02, 0x0D, 0x20,
+ 0x00, 0x00, 0x00,
+ 0xFE, 0x7A, 0x70,
+ 0x00, 0x00, 0x00,
+ 0x01, 0x1C, 0x90,
+ 0x00, 0x00, 0x00,
+ 0xFF, 0x35, 0xA0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x8A, 0x40,
+ 0x00, 0x00, 0x00,
+ 0xFF, 0xA6, 0xF0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x34, 0x70,
+ 0x00, 0x00, 0x00,
+ 0xFF, 0xE5, 0x50,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x0A, 0x30,
+ 0x00, 0x00, 0x00,
+ 0xFF, 0xFE, 0x40,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00,
+ 0x00, 0x07, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00,
+ 0x04, 0xFF, 0x00,
+ 0x08, 0x40, 0x00,
+ 0x0B, 0x40, 0x00,
+ 0x7C, 0x00, 0x00,
+ 0x04, 0x00, 0x00,
+ 0x02, 0x10, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x9E, 0xDD, 0xA0,
+ 0x0C, 0x67, 0x50,
+ 0x40, 0x00, 0x00,
+ 0x00, 0x10, 0x60,
+ 0x7F, 0xEF, 0xA0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00,
+ 0x00, 0x01, 0x00,
+ 0x00, 0x12, 0x00,
+ 0x00, 0x10, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x05, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00,
+ 0x00, 0xB5, 0x00,
+ 0x00, 0xCB, 0x00,
+ 0x00, 0x40, 0x00,
+ 0x00, 0x80, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x07, 0xED, 0x00,
+ 0x00, 0x80, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0xB1, 0x00,
+ 0x01, 0x02, 0x00,
+ 0x05, 0x7F, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x51, 0x00,
+ 0x01, 0xDF, 0x00,
+ 0x7F, 0xFF, 0xF0,
+ 0xF0, 0x00, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x7E, 0x00, 0x00,
+ 0x02, 0x00, 0x00,
+ 0x01, 0x4A, 0xA0,
+ 0x06, 0x57, 0xF0,
+ 0x06, 0x57, 0xF0,
+ 0x00, 0x04, 0x00,
+ 0x7F, 0xF0, 0x00,
+ 0x00, 0x10, 0x00,
+ 0x1D, 0x9A, 0x50,
+ 0xF9, 0xA8, 0x10,
+ 0x00, 0x56, 0x00,
+ 0x01, 0xE0, 0x00,
+ 0x7F, 0xFF, 0xF0,
+ 0xF0, 0x00, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x7E, 0x00, 0x00,
+ 0x02, 0x00, 0x00,
+ 0x01, 0x4A, 0xA0,
+ 0x06, 0x57, 0xF0,
+ 0x06, 0x57, 0xF0,
+ 0x00, 0x04, 0x00,
+ 0x7F, 0xF0, 0x00,
+ 0x00, 0x10, 0x00,
+ 0x1D, 0x9A, 0x50,
+ 0xF9, 0xA8, 0x10,
+ 0x40, 0x3B, 0x00,
+ 0x3F, 0xFC, 0x30,
+ 0x10, 0x00, 0x00,
+ 0x7F, 0xFF, 0xF0,
+ 0x01, 0x00, 0x00,
+ 0x3A, 0xE2, 0x60,
+ 0x8A, 0x3B, 0x40,
+ 0xC9, 0xD2, 0x70,
+ 0x75, 0x5B, 0xE0,
+ 0x3A, 0xE2, 0x60,
+ 0x7C, 0x00, 0x00,
+ 0x04, 0x00, 0x00,
+ 0x7F, 0xC0, 0x00,
+ 0x00, 0x40, 0x00,
+ 0x7C, 0x00, 0x00,
+ 0x04, 0x00, 0x00,
+ 0x08, 0x00, 0x00,
+ 0x40, 0x00, 0x30,
+ 0x20, 0x00, 0x00,
+ 0x7F, 0xC0, 0x00,
+ 0x00, 0x40, 0x00,
+ 0x05, 0xA3, 0x00,
+ 0x00, 0x14, 0xE0,
+ 0x00, 0x50, 0x00,
+ 0x0A, 0x06, 0x10,
+ 0x7C, 0x00, 0x00,
+ 0x04, 0x00, 0x00,
+ 0x20, 0x00, 0x00,
+ 0x60, 0x00, 0x00,
+ 0x5A, 0x9D, 0xF0,
+ 0x03, 0x2B, 0xF0,
+ 0x3C, 0x6B, 0x80,
+ 0x3F, 0xA1, 0xF0,
+ 0x40, 0x01, 0xE0,
+ 0x02, 0x00, 0x00,
+ 0x0A, 0x06, 0x10,
+ 0x3F, 0xFF, 0x10,
+ 0x40, 0x5E, 0x90,
+ 0x50, 0xC3, 0x30,
+ 0x00, 0x50, 0x00,
+ 0x03, 0xFD, 0x90,
+ 0x7C, 0x00, 0x00,
+ 0x04, 0x00, 0x00,
+ 0x20, 0x00, 0x00,
+ 0x60, 0x00, 0x00,
+ 0x20, 0x26, 0xF0,
+ 0x03, 0x2B, 0xF0,
+ 0x3C, 0x6B, 0x80,
+ 0x3F, 0xA1, 0xF0,
+ 0x40, 0x01, 0xE0,
+ 0x02, 0x00, 0x00,
+ 0x03, 0xFD, 0x90,
+ 0x3F, 0xFF, 0x10,
+ 0x40, 0x5E, 0x90,
+ 0x50, 0xC3, 0x30,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00,
+ 0x00, 0x09, 0x00,
+ 0x00, 0x07, 0x00, /* 0x00, 0x08, 0x00, 0x08=Right, 0x07=Left */
+ 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x35, 0x3B, 0xA4,
+ 0x87, 0x08, 0xCA,
+ 0xDB, 0x3A, 0xA2,
+ 0x54, 0x6B, 0xA7,
+ 0x4C, 0x10, 0x6B,
+ 0x35, 0x3B, 0xA4,
+ 0x87, 0x08, 0xCA,
+ 0xDB, 0x3A, 0xA2,
+ 0x54, 0x6B, 0xA7,
+ 0x4C, 0x10, 0x6B,
+ 0x3E, 0x1D, 0xB7,
+ 0x83, 0xC4, 0x91,
+ 0xC3, 0xA8, 0xF6,
+ 0x7C, 0x1F, 0xD5,
+ 0x3E, 0x1D, 0xB7,
+ 0x25, 0xE3, 0x8C,
+ 0xA9, 0x24, 0x30,
+ 0xCF, 0x83, 0x1F,
+ 0x6E, 0x64, 0xB3,
+ 0x39, 0x0A, 0x41,
+ 0x3A, 0xD6, 0xA1,
+ 0x8A, 0x52, 0xBE,
+ 0xC9, 0xE9, 0xF9,
+ 0x75, 0x44, 0x7D,
+ 0x3A, 0xD6, 0xA1,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x0E, 0x7D, 0xA0,
+ 0x0E, 0x7D, 0xA0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00,
+ 0x00, 0x06, 0x00,
+ 0x33, 0x33, 0x30,
+ 0x01, 0x47, 0xB0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x01, 0xEB, 0x80,
+ 0x14, 0x00, 0x00,
+ 0xC0, 0x00, 0x00,
+ 0x10, 0x00, 0x00,
+ 0x02, 0x00, 0x00,
+ 0x19, 0x99, 0xA0,
+ 0x00, 0x00, 0x00,
+ 0x74, 0x7A, 0xE0,
+ 0x40, 0x00, 0x00,
+ 0x05, 0x1E, 0xC0,
+ 0x02, 0x8F, 0x60,
+ 0x05, 0x1E, 0xC0,
+ 0x02, 0x8F, 0x60,
+ 0x1C, 0xA7, 0xD0,
+ 0x1C, 0xA7, 0xD0,
+ 0x1C, 0xA7, 0xD0,
+ 0x1C, 0xA7, 0xD0,
+ 0x1C, 0xA7, 0xD0,
+ 0x1C, 0xA7, 0xD0,
+ 0x40, 0x26, 0xE0,
+ 0x40, 0x26, 0xE0,
+ 0x40, 0x26, 0xE0,
+ 0x40, 0x26, 0xE0,
+ 0x40, 0x26, 0xE0,
+ 0x40, 0x26, 0xE0,
+ 0x00, 0x08, 0x00,
+ 0x00, 0x10, 0x00,
+ 0x00, 0x28, 0x00,
+ 0x00, 0x40, 0x00,
+ 0x00, 0x58, 0x00,
+ 0x00, 0x7F, 0x00,
+ 0x00, 0x80, 0x00,
+ 0x00, 0x06, 0x00,
+ 0x33, 0x33, 0x30,
+ 0x01, 0x47, 0xB0,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x01, 0xEB, 0x80,
+ 0x14, 0x00, 0x00,
+ 0xC0, 0x00, 0x00,
+ 0x10, 0x00, 0x00,
+ 0x02, 0x00, 0x00,
+ 0x19, 0x99, 0xA0,
+ 0x00, 0x00, 0x00,
+ 0x74, 0x7A, 0xE0,
+ 0x40, 0x00, 0x00,
+ 0x05, 0x1E, 0xC0,
+ 0x02, 0x8F, 0x60,
+ 0x05, 0x1E, 0xC0,
+ 0x02, 0x8F, 0x60,
+ 0x1C, 0xA7, 0xD0,
+ 0x1C, 0xA7, 0xD0,
+ 0x1C, 0xA7, 0xD0,
+ 0x1C, 0xA7, 0xD0,
+ 0x1C, 0xA7, 0xD0,
+ 0x1C, 0xA7, 0xD0,
+ 0x40, 0x26, 0xE0,
+ 0x40, 0x26, 0xE0,
+ 0x40, 0x26, 0xE0,
+ 0x40, 0x26, 0xE0,
+ 0x40, 0x26, 0xE0,
+ 0x40, 0x26, 0xE0,
+ 0x00, 0x08, 0x00,
+ 0x00, 0x10, 0x00,
+ 0x00, 0x28, 0x00,
+ 0x00, 0x40, 0x00,
+ 0x00, 0x58, 0x00,
+ 0x00, 0x7F, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x0B, 0xFF, 0x00,
+ 0x02, 0x80, 0x00,
+ 0xB0, 0x00, 0x00,
+ 0x00, 0x84, 0x00,
+ 0x7F, 0xFF, 0x00,
+ 0xF0, 0x00, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x3C, 0x00,
+ 0x16, 0x98, 0x00,
+ 0x00, 0x46, 0x00,
+ 0x16, 0x98, 0x00,
+ 0x00, 0x46, 0x00,
+ 0x16, 0x98, 0x00,
+ 0x00, 0x0A, 0x00,
+ 0x16, 0x98, 0x00,
+ 0x50, 0xC8, 0x00,
+ 0x20, 0x0F, 0x00,
+ 0x50, 0xC8, 0x00,
+ 0x20, 0x0F, 0x00,
+ 0x30, 0x1E, 0x00,
+ 0x20, 0x00, 0x00,
+ 0x50, 0xC8, 0x00,
+ 0x20, 0x0A, 0x00,
+ 0x30, 0x3C, 0x00,
+ 0x16, 0x8C, 0x00,
+ 0x06, 0x18, 0x00,
+ 0x16, 0x98, 0x00,
+ 0x00, 0x06, 0x00,
+ 0x16, 0xC0, 0x00,
+ 0x00, 0x3C, 0x00,
+ 0x17, 0x58, 0x00,
+ 0x00, 0x64, 0x00,
+ 0x1F, 0x58, 0x00,
+ 0x00, 0x50, 0x00,
+ 0x17, 0x58, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x00,
+ 0x00, 0x02, 0x10,
+ 0x07, 0xEB, 0x80,
+ 0x04, 0x02, 0x70,
+ 0x03, 0xE8, 0x00,
+ 0x00, 0x01, 0x00,
+ 0x14, 0x49, 0x61,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00,
+ 0x00, 0xA1, 0x24,
+ 0x00, 0xCA, 0xDE,
+ 0x00, 0xFF, 0x65,
+ 0x01, 0x41, 0x85,
+ 0x01, 0x94, 0xC6,
+ 0x01, 0xFD, 0x94,
+ 0x02, 0x81, 0x85,
+ 0x03, 0x27, 0xA0,
+ 0x03, 0xF8, 0xBD,
+ 0x05, 0x9C, 0x2F,
+ 0x07, 0xEC, 0xAA,
+ 0x0B, 0x31, 0x90,
+ 0x0F, 0xCF, 0xB7,
+ 0x16, 0x55, 0x8D,
+ 0x1F, 0x8C, 0x41,
+ 0x7F, 0xFF, 0xFF,
+ 0x65, 0xAC, 0x8C,
+ 0x47, 0xFA, 0xCD,
+ 0x32, 0xF5, 0x2D,
+ 0x24, 0x13, 0x47,
+ 0x19, 0x8A, 0x13,
+ 0x12, 0x14, 0x9A,
+ 0x0C, 0xCC, 0xCD,
+ 0x7F, 0xFF, 0xFF,
+ 0x7F, 0xFF, 0xFF,
+ 0x7F, 0xFF, 0xFF,
+ 0x7F, 0xFF, 0xFF,
+ 0x7F, 0xFF, 0xFF,
+ 0x7F, 0xFF, 0xFF,
+ 0x7F, 0xFF, 0xFF,
+ 0x7F, 0xFF, 0xFF,
+ 0x03, 0xFF, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x02, 0x02, 0x70,
+ 0x02, 0xD6, 0xB0,
+ 0x04, 0x02, 0x70,
+ 0x05, 0xA9, 0xE0,
+ 0x08, 0x00, 0x00,
+ 0x0B, 0x4C, 0xE0,
+ 0x0F, 0xF6, 0x50,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x21, 0x87, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x21, 0x2F, 0x00,
+ 0x40, 0x00, 0x00,
+ 0x7F, 0x8A, 0xD0,
+ 0xAA, 0xD1, 0xB0,
+ 0xD5, 0xA3, 0x70,
+ 0x65, 0xD8, 0x00,
+ 0xF8, 0x00, 0x00,
+ 0x60, 0x00, 0x00,
+ 0x6E, 0xD9, 0xF0,
+ 0x49, 0xE6, 0xA0,
+ 0xE7, 0x5D, 0xD0,
+ 0x10, 0x6C, 0x20,
+ 0xF2, 0x50, 0x90,
+ 0x0C, 0xC5, 0xE0,
+ 0xF3, 0x3A, 0x20,
+ 0x08, 0x00, 0x00,
+ 0x5A, 0x82, 0x80,
+ 0x00, 0x00, 0x00,
+ 0x05, 0x05, 0x00,
+ 0x07, 0x1B, 0x00,
+ 0x08, 0xB5, 0x00,
+ 0x0A, 0x11, 0x00,
+ 0x0B, 0x44, 0x00,
+ 0x0C, 0x5A, 0x00,
+ 0x0D, 0x5B, 0x00,
+ 0x0E, 0x4A, 0x00,
+ 0x0F, 0x2C, 0x00,
+ 0x10, 0x02, 0x00,
+ 0x10, 0xCE, 0x00,
+ 0x11, 0x91, 0x00,
+ 0x12, 0x4E, 0x00,
+ 0x13, 0x03, 0x00,
+ 0x13, 0xB3, 0x00,
+ 0x14, 0x5D, 0x00,
+ 0x15, 0x02, 0x00,
+ 0x15, 0xA3, 0x00,
+ 0x16, 0x41, 0x00,
+ 0x16, 0xDA, 0x00,
+ 0x17, 0x70, 0x00,
+ 0x18, 0x03, 0x00,
+ 0x18, 0x93, 0x00,
+ 0x19, 0x20, 0x00,
+ 0x19, 0xAB, 0x00,
+ 0x1A, 0x33, 0x00,
+ 0x1A, 0xB9, 0x00,
+ 0x1B, 0x3D, 0x00,
+ 0x1B, 0xBF, 0x00,
+ 0x1C, 0x3F, 0x00,
+ 0x1C, 0xBD, 0x00,
+ 0x1D, 0x39, 0x00,
+ 0x1D, 0xB4, 0x00,
+ 0x1E, 0x2E, 0x00,
+ 0x1E, 0xA5, 0x00,
+ 0x1F, 0x1C, 0x00,
+ 0x1F, 0x91, 0x00,
+ 0x20, 0x05, 0x00,
+ 0x20, 0x77, 0x00,
+ 0x20, 0xE8, 0x00,
+ 0x21, 0x59, 0x00,
+ 0x21, 0xC8, 0x00,
+ 0x22, 0x36, 0x00,
+ 0x22, 0xA3, 0x00,
+ 0x23, 0x0F, 0x00,
+ 0x23, 0x7A, 0x00,
+ 0x23, 0xE4, 0x00,
+ 0x24, 0x4D, 0x00,
+ 0x24, 0xB6, 0x00,
+ 0x25, 0x1D, 0x00,
+ 0x25, 0x84, 0x00,
+ 0x25, 0xEA, 0x00,
+ 0x26, 0x50, 0x00,
+ 0x26, 0xB4, 0x00,
+ 0x27, 0x18, 0x00,
+ 0x27, 0x7B, 0x00,
+ 0x27, 0xDE, 0x00,
+ 0x28, 0x3F, 0x00,
+ 0x28, 0xA1, 0x00,
+ 0x29, 0x01, 0x00,
+ 0x29, 0x61, 0x00,
+ 0x29, 0xC1, 0x00,
+ 0x2A, 0x1F, 0x00,
+ 0x00, 0x01, 0x00,
+ 0x00, 0x0E, 0x00,
+ 0x20, 0x16, 0x00,
+ 0x10, 0x17, 0x00,
+ 0x01, 0x03, 0x00,
+};
+
+
+static u8 ak7755_ofreg_basic[]= {
+ 0xB2,0x00,0x00, // OFREG Write Command
+ 0x00, 0x00, 0x00, // 0x000
+ 0x00, 0x00, 0x00, // 0x001
+ 0x00, 0x00, 0x00, // 0x002
+ 0x00, 0x00, 0x00, // 0x003
+ 0x00, 0x00, 0x00, // 0x004
+ 0x00, 0x00, 0x00, // 0x005
+ 0x00, 0x00, 0x00, // 0x006
+ 0x00, 0x00, 0x00, // 0x007
+};
+
+static u8 ak7755_acram_basic[]= {
+ 0xBB,0x00,0x00, // ACRAM Write Command
+ 0x00, 0x00, 0x00, // 0x000
+ 0x00, 0x00, 0x00, // 0x001
+ 0x00, 0x00, 0x00, // 0x002
+ 0x00, 0x00, 0x00, // 0x003
+ 0x00, 0x00, 0x00, // 0x004
+ 0x00, 0x00, 0x00, // 0x005
+ 0x00, 0x00, 0x00, // 0x006
+ 0x00, 0x00, 0x00, // 0x007
+};
+
+
diff --git a/sound/soc/codecs/ak7755ctl.h b/sound/soc/codecs/ak7755ctl.h
new file mode 100644
index 00000000..dd5e5246
--- /dev/null
+++ b/sound/soc/codecs/ak7755ctl.h
@@ -0,0 +1,75 @@
+ /* ak7755ioctrl.h
+ *
+ * Copyright (C) 2014 Asahi Kasei Microdevices Corporation.
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * 14/04/09 1.0
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __DSP_AK7755_H__
+#define __DSP_AK7755_H__
+
+/* IO CONTROL definition of AK7755 */
+#define AK7755_IOCTL_MAGIC 's'
+
+#define AK7755_MAGIC 0xD0
+#define MAX_WREG 32
+#define MAX_WCRAM 48
+
+enum ak7755_ram_type {
+ RAMTYPE_PRAM = 0,
+ RAMTYPE_CRAM,
+ RAMTYPE_OFREG,
+ RAMTYPE_ACRAM,
+};
+
+
+enum ak7755_status {
+ POWERDOWN = 0,
+ SUSPEND,
+ STANDBY,
+ DOWNLOAD,
+ RUN,
+};
+
+typedef struct _REG_CMD {
+ unsigned char addr;
+ unsigned char data;
+} REG_CMD;
+
+struct ak7755_wreg_handle {
+ REG_CMD *regcmd;
+ int len;
+};
+
+struct ak7755_wcram_handle{
+ int addr;
+ unsigned char *cram;
+ int len;
+};
+
+struct ak7755_loadram_handle {
+ int ramtype;
+ int mode;
+};
+
+#define AK7755_IOCTL_SETSTATUS _IOW(AK7755_MAGIC, 0x10, int)
+#define AK7755_IOCTL_GETSTATUS _IOR(AK7755_MAGIC, 0x11, int)
+#define AK7755_IOCTL_SETMIR _IOW(AK7755_MAGIC, 0x12, int)
+#define AK7755_IOCTL_GETMIR _IOR(AK7755_MAGIC, 0x13, unsigned long)
+#define AK7755_IOCTL_WRITEREG _IOW(AK7755_MAGIC, 0x14, struct ak7755_wreg_handle)
+#define AK7755_IOCTL_WRITECRAM _IOW(AK7755_MAGIC, 0x15, struct ak7755_wcram_handle)
+#define AK7755_IOCTL_LOADRAM _IOW(AK7755_MAGIC, 0x16, struct ak7755_loadram_handle)
+
+#endif
+
diff --git a/sound/soc/codecs/ambarella_dummy.c b/sound/soc/codecs/ambarella_dummy.c
new file mode 100644
index 00000000..4b6e882c
--- /dev/null
+++ b/sound/soc/codecs/ambarella_dummy.c
@@ -0,0 +1,169 @@
+/*
+ * ambarella_dummy.c -- A2SAUC ALSA SoC Audio driver
+ *
+ * History:
+ * 2008/10/17 - [Andrew Lu] created file
+ * 2009/03/12 - [Cao Rongrong] Port to 2.6.27
+ * 2009/06/10 - [Cao Rongrong] Port to 2.6.29
+ * 2011/03/20 - [Cao Rongrong] Port to 2.6.38
+ *
+ * Coryright (c) 2008-2009, Ambarella, Inc.
+ * http://www.ambarella.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/initval.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <linux/of_gpio.h>
+#include "ambarella_dummy.h"
+
+static inline unsigned int ambdummy_codec_read(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ return 0;
+}
+
+static inline int ambdummy_codec_write(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int value)
+{
+ return 0;
+}
+
+static int ambdummy_mute(struct snd_soc_dai *dai, int mute)
+{
+ return 0;
+}
+
+static int ambdummy_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ codec->dapm.bias_level = level;
+ return 0;
+}
+
+#define AMBDUMMY_RATES SNDRV_PCM_RATE_8000_48000
+
+#define AMBDUMMY_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_ops ambdummy_dai_ops = {
+ .digital_mute = ambdummy_mute,
+};
+
+static struct snd_soc_dai_driver ambdummy_dai = {
+ .name = "AMBARELLA_DUMMY_CODEC",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 2,
+ .channels_max = 6,
+ .rates = AMBDUMMY_RATES,
+ .formats = AMBDUMMY_FORMATS,},
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 2,
+ .channels_max = 6,
+ .rates = AMBDUMMY_RATES,
+ .formats = AMBDUMMY_FORMATS,},
+ .ops = &ambdummy_dai_ops,
+};
+
+#if defined(CONFIG_PM)
+static int ambdummy_suspend(struct snd_soc_codec *codec)
+{
+ ambdummy_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ ambdummy_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+ return 0;
+}
+
+static int ambdummy_resume(struct snd_soc_codec *codec)
+{
+ ambdummy_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ ambdummy_set_bias_level(codec, SND_SOC_BIAS_ON);
+
+ return 0;
+}
+#else
+#define ambdummy_suspend NULL
+#define ambdummy_resume NULL
+#endif
+static int ambdummy_probe(struct snd_soc_codec *codec)
+{
+ printk(KERN_INFO "AMBARELLA SoC Audio DUMMY Codec\n");
+
+ ambdummy_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ return 0;
+}
+
+/* power down chip */
+static int ambdummy_remove(struct snd_soc_codec *codec)
+{
+ ambdummy_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+ return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_ambdummy = {
+ .probe = ambdummy_probe,
+ .remove = ambdummy_remove,
+ .suspend = ambdummy_suspend,
+ .resume = ambdummy_resume,
+ .reg_cache_size = 0,
+ .read = ambdummy_codec_read,
+ .write = ambdummy_codec_write,
+ .set_bias_level =ambdummy_set_bias_level,
+};
+
+static int ambdummy_codec_probe(struct platform_device *pdev)
+{
+ return snd_soc_register_codec(&pdev->dev,
+ &soc_codec_dev_ambdummy, &ambdummy_dai, 1);
+}
+
+static int ambdummy_codec_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_codec(&pdev->dev);
+ return 0;
+}
+
+static struct of_device_id ambdummy_of_match[] = {
+ { .compatible = "ambarella,dummycodec",},
+ {},
+};
+MODULE_DEVICE_TABLE(of, ambdummy_of_match);
+
+static struct platform_driver ambdummy_codec_driver = {
+ .probe = ambdummy_codec_probe,
+ .remove = ambdummy_codec_remove,
+ .driver = {
+ .name = "ambdummy-codec",
+ .owner = THIS_MODULE,
+ .of_match_table = ambdummy_of_match,
+ },
+};
+
+static int __init ambarella_dummy_codec_init(void)
+{
+ return platform_driver_register(&ambdummy_codec_driver);
+
+}
+module_init(ambarella_dummy_codec_init);
+
+static void __exit ambarella_dummy_codec_exit(void)
+{
+ platform_driver_unregister(&ambdummy_codec_driver);
+}
+module_exit(ambarella_dummy_codec_exit);
+
+MODULE_DESCRIPTION("Soc Ambarella Dummy Codec Driver");
+MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
+MODULE_LICENSE("GPL");
+
diff --git a/sound/soc/codecs/ambarella_dummy.h b/sound/soc/codecs/ambarella_dummy.h
new file mode 100644
index 00000000..127464d0
--- /dev/null
+++ b/sound/soc/codecs/ambarella_dummy.h
@@ -0,0 +1,9 @@
+/*
+ * ambarella_dummy.h -- Ambarella dummy codec driver
+ *
+ */
+
+#ifndef _AMBARELLA_DUMMY_H
+#define _AMBARELLA_DUMMY_H
+
+#endif /* _AMBARELLA_DUMMY_H */
diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c
new file mode 100644
index 00000000..20bdcc1f
--- /dev/null
+++ b/sound/soc/codecs/es8328.c
@@ -0,0 +1,686 @@
+/*
+ * es8328.c -- ES8328 ALSA Soc Audio driver
+ *
+ * Copyright 2011 Ambarella Ltd.
+ *
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * Based on es8328.c from Everest Semiconductor
+ *
+ * History:
+ * 2011/10/19 - [Cao Rongrong] Created file
+ * 2013/01/14 - [Ken He] Port to 3.8
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+#include <sound/es8328.h>
+
+#include "es8328.h"
+
+#define ES8328_VERSION "v1.0"
+
+/* codec private data */
+struct es8328_priv {
+ unsigned int sysclk;
+ void *control_data;
+};
+
+
+/*
+ * es8328 register cache
+ * We can't read the es8328 register space when we
+ * are using 2 wire for device control, so we cache them instead.
+ */
+static const u8 es8328_reg[] = {
+ 0x06, 0x1C, 0xC3, 0xFC, /* 0 */
+ 0xC0, 0x00, 0x00, 0x7C, /* 4 */
+ 0x80, 0x00, 0x00, 0x06, /* 8 */
+ 0x00, 0x06, 0x30, 0x30, /* 12 */
+ 0xC0, 0xC0, 0x38, 0xB0, /* 16 */
+ 0x32, 0x06, 0x00, 0x00, /* 20 */
+ 0x06, 0x32, 0xC0, 0xC0, /* 24 */
+ 0x08, 0x06, 0x1F, 0xF7, /* 28 */
+ 0xFD, 0xFF, 0x1F, 0xF7, /* 32 */
+ 0xFD, 0xFF, 0x00, 0x38, /* 36 */
+ 0x38, 0x38, 0x38, 0x38, /* 40 */
+ 0x38, 0x00, 0x00, 0x00, /* 44 */
+ 0x00, 0x00, 0x00, 0x00, /* 48 */
+ 0x00, 0x00, 0x00, 0x00, /* 52 */
+};
+
+/* DAC/ADC Volume: min -96.0dB (0xC0) ~ max 0dB (0x00) ( 0.5 dB step ) */
+static const DECLARE_TLV_DB_SCALE(digital_tlv, -9600, 50, 0);
+/* Analog Out Volume: min -30.0dB (0x00) ~ max 3dB (0x21) ( 1 dB step ) */
+static const DECLARE_TLV_DB_SCALE(out_tlv, -3000, 100, 0);
+/* Analog In Volume: min 0dB (0x00) ~ max 24dB (0x08) ( 3 dB step ) */
+static const DECLARE_TLV_DB_SCALE(in_tlv, 0, 300, 0);
+
+static const struct snd_kcontrol_new es8328_snd_controls[] = {
+ SOC_DOUBLE_R_TLV("Playback Volume",
+ ES8328_LDAC_VOL, ES8328_RDAC_VOL, 0, 0xC0, 1, digital_tlv),
+ SOC_DOUBLE_R_TLV("Analog Out Volume",
+ ES8328_LOUT1_VOL, ES8328_ROUT1_VOL, 0, 0x1D, 0, out_tlv),
+
+ SOC_DOUBLE_R_TLV("Capture Volume",
+ ES8328_LADC_VOL, ES8328_RADC_VOL, 0, 0xC0, 1, digital_tlv),
+ SOC_DOUBLE_TLV("Analog In Volume",
+ ES8328_ADCCONTROL1, 4, 0, 0x08, 0, in_tlv),
+};
+
+/*
+ * DAPM Controls
+ */
+
+/* Channel Input Mixer */
+static const char *es8328_line_texts[] = { "Line 1", "Line 2", "Differential"};
+static const unsigned int es8328_line_values[] = { 0, 1, 3};
+
+static const struct soc_enum es8328_lline_enum =
+ SOC_VALUE_ENUM_SINGLE(ES8328_ADCCONTROL2, 6, 0xC0,
+ ARRAY_SIZE(es8328_line_texts), es8328_line_texts,
+ es8328_line_values);
+static const struct snd_kcontrol_new es8328_left_line_controls =
+ SOC_DAPM_VALUE_ENUM("Route", es8328_lline_enum);
+
+static const struct soc_enum es8328_rline_enum =
+ SOC_VALUE_ENUM_SINGLE(ES8328_ADCCONTROL2, 4, 0x30,
+ ARRAY_SIZE(es8328_line_texts), es8328_line_texts,
+ es8328_line_values);
+static const struct snd_kcontrol_new es8328_right_line_controls =
+ SOC_DAPM_VALUE_ENUM("Route", es8328_lline_enum);
+
+
+/* Left Mixer */
+static const struct snd_kcontrol_new es8328_left_mixer_controls[] = {
+ SOC_DAPM_SINGLE("Left Playback Switch", ES8328_DACCONTROL17, 7, 1, 0),
+ SOC_DAPM_SINGLE("Left Bypass Switch" , ES8328_DACCONTROL17, 6, 1, 0),
+};
+
+/* Right Mixer */
+static const struct snd_kcontrol_new es8328_right_mixer_controls[] = {
+ SOC_DAPM_SINGLE("Right Playback Switch", ES8328_DACCONTROL20, 7, 1, 0),
+ SOC_DAPM_SINGLE("Right Bypass Switch" , ES8328_DACCONTROL20, 6, 1, 0),
+};
+
+/* Mono ADC Mux */
+static const char *es8328_mono_mux[] = {"Stereo", "Mono (Left)", "Mono (Right)", "NONE"};
+static const struct soc_enum monomux =
+ SOC_ENUM_SINGLE(ES8328_ADCCONTROL3, 3, 4, es8328_mono_mux);
+static const struct snd_kcontrol_new es8328_monomux_controls =
+ SOC_DAPM_ENUM("Route", monomux);
+
+static const struct snd_soc_dapm_widget es8328_dapm_widgets[] = {
+ /* DAC Part */
+ SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
+ &es8328_left_mixer_controls[0], ARRAY_SIZE(es8328_left_mixer_controls)),
+ SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
+ &es8328_right_mixer_controls[0], ARRAY_SIZE(es8328_right_mixer_controls)),
+
+ SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0, &es8328_left_line_controls),
+ SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0, &es8328_right_line_controls),
+
+ SND_SOC_DAPM_DAC("Left DAC" , "Left Playback" , ES8328_DACPOWER, 7, 1),
+ SND_SOC_DAPM_DAC("Right DAC" , "Right Playback", ES8328_DACPOWER, 6, 1),
+ SND_SOC_DAPM_PGA("Left Out 1" , ES8328_DACPOWER, 5, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Right Out 1", ES8328_DACPOWER, 4, 0, NULL, 0),
+ /* SND_SOC_DAPM_PGA("Left Out 2" , ES8328_DACPOWER, 3, 0, NULL, 0), */
+ /* SND_SOC_DAPM_PGA("Right Out 2", ES8328_DACPOWER, 2, 0, NULL, 0), */
+
+ SND_SOC_DAPM_OUTPUT("LOUT1"),
+ SND_SOC_DAPM_OUTPUT("ROUT1"),
+ SND_SOC_DAPM_OUTPUT("LOUT2"),
+ SND_SOC_DAPM_OUTPUT("ROUT2"),
+
+ /* ADC Part */
+ SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0, &es8328_monomux_controls),
+ SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0, &es8328_monomux_controls),
+
+ SND_SOC_DAPM_PGA("Left Analog Input" , ES8328_ADCPOWER, 7, 1, NULL, 0),
+ SND_SOC_DAPM_PGA("Right Analog Input", ES8328_ADCPOWER, 6, 1, NULL, 0),
+ SND_SOC_DAPM_ADC("Left ADC" , "Left Capture" , ES8328_ADCPOWER, 5, 1),
+ SND_SOC_DAPM_ADC("Right ADC", "Right Capture", ES8328_ADCPOWER, 4, 1),
+
+ SND_SOC_DAPM_MICBIAS("Mic Bias", ES8328_ADCPOWER, 3, 1),
+
+ SND_SOC_DAPM_INPUT("MICIN"),
+ SND_SOC_DAPM_INPUT("LINPUT1"),
+ SND_SOC_DAPM_INPUT("LINPUT2"),
+ SND_SOC_DAPM_INPUT("RINPUT1"),
+ SND_SOC_DAPM_INPUT("RINPUT2"),
+};
+
+static const struct snd_soc_dapm_route intercon[] = {
+ /* left mixer */
+ {"Left Mixer", "Left Playback Switch", "Left DAC"},
+
+ /* right mixer */
+ {"Right Mixer", "Right Playback Switch", "Right DAC"},
+
+ /* left out 1 */
+ {"Left Out 1", NULL, "Left Mixer"},
+ {"LOUT1", NULL, "Left Out 1"},
+
+ /* right out 1 */
+ {"Right Out 1", NULL, "Right Mixer"},
+ {"ROUT1", NULL, "Right Out 1"},
+
+ /* Left Line Mux */
+ {"Left Line Mux", "Line 1", "LINPUT1"},
+ {"Left Line Mux", "Line 2", "LINPUT2"},
+ {"Left Line Mux", "Differential", "MICIN"},
+
+ /* Right Line Mux */
+ {"Right Line Mux", "Line 1", "RINPUT1"},
+ {"Right Line Mux", "Line 2", "RINPUT2"},
+ {"Right Line Mux", "Differential", "MICIN"},
+
+ /* Left ADC Mux */
+ {"Left ADC Mux", "Stereo", "Left Line Mux"},
+// {"Left ADC Mux", "Mono (Left)" , "Left Line Mux"},
+
+ /* Right ADC Mux */
+ {"Right ADC Mux", "Stereo", "Right Line Mux"},
+// {"Right ADC Mux", "Mono (Right)", "Right Line Mux"},
+
+ /* ADC */
+ {"Left ADC" , NULL, "Left ADC Mux"},
+ {"Right ADC", NULL, "Right ADC Mux"},
+};
+
+static inline unsigned int es8328_read_reg_cache(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ u8 *cache = codec->reg_cache;
+
+ if (reg >= ES8328_CACHEREGNUM)
+ return -1;
+
+ return cache[reg];
+}
+
+static int es8328_write(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int value)
+{
+ u8 *cache = codec->reg_cache;
+ struct i2c_client *client = codec->control_data;
+
+ if (reg >= ES8328_CACHEREGNUM)
+ return -EIO;
+
+ if (i2c_smbus_write_byte_data(client, reg, value)) {
+ pr_err("ES8328: I2C write failed\n");
+ return -EIO;
+ }
+ /* We've written to the hardware, so update the cache */
+ cache[reg] = value;
+
+ return 0;
+}
+
+static int es8328_sync(struct snd_soc_codec *codec)
+{
+ u8 *cache = codec->reg_cache;
+ int i, r = 0;
+
+ for (i = 0; i < ES8328_CACHEREGNUM; i++)
+ r |= snd_soc_write(codec, i, cache[i]);
+
+ return r;
+};
+
+static int es8328_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
+
+ es8328->sysclk = freq;
+ return 0;
+}
+
+static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u8 iface = 0;
+ u8 adciface = 0;
+ u8 daciface = 0;
+
+ iface = snd_soc_read(codec, ES8328_IFACE);
+ adciface = snd_soc_read(codec, ES8328_ADC_IFACE);
+ daciface = snd_soc_read(codec, ES8328_DAC_IFACE);
+
+ /* set master/slave audio interface */
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM: // MASTER MODE
+ iface |= 0x80;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS: // SLAVE MODE
+ iface &= 0x7F;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* interface format */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ adciface &= 0xFC;
+ daciface &= 0xF9;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ case SND_SOC_DAIFMT_LEFT_J:
+ case SND_SOC_DAIFMT_DSP_A:
+ case SND_SOC_DAIFMT_DSP_B:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* clock inversion */
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ iface &= 0xDF;
+ adciface &= 0xDF;
+ daciface &= 0xBF;
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ iface |= 0x20;
+ adciface |= 0x20;
+ daciface |= 0x40;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ iface |= 0x20;
+ adciface &= 0xDF;
+ daciface &= 0xBF;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ iface &= 0xDF;
+ adciface |= 0x20;
+ daciface |= 0x40;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_write(codec, ES8328_IFACE , iface);
+ snd_soc_write(codec, ES8328_ADC_IFACE, adciface);
+ snd_soc_write(codec, ES8328_DAC_IFACE, daciface);
+
+ return 0;
+}
+
+static int es8328_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ u16 iface;
+
+ if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ iface = snd_soc_read(codec, ES8328_DAC_IFACE) & 0xC7;
+ /* bit size */
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ iface |= 0x0018;
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ iface |= 0x0008;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ iface |= 0x0020;
+ break;
+ }
+ /* set iface & srate */
+ snd_soc_write(codec, ES8328_DAC_IFACE, iface);
+ } else {
+ iface = snd_soc_read(codec, ES8328_ADC_IFACE) & 0xE3;
+ /* bit size */
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ iface |= 0x000C;
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ iface |= 0x0004;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ iface |= 0x0010;
+ break;
+ }
+ /* set iface */
+ snd_soc_write(codec, ES8328_ADC_IFACE, iface);
+ }
+
+ return 0;
+}
+
+static int es8328_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ unsigned char val = 0;
+
+ val = snd_soc_read(codec, ES8328_DAC_MUTE);
+ if (mute){
+ val |= 0x04;
+ } else {
+ val &= ~0x04;
+ }
+
+ snd_soc_write(codec, ES8328_DAC_MUTE, val);
+
+ return 0;
+}
+
+
+static int es8328_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ switch(level) {
+ case SND_SOC_BIAS_ON:
+ break;
+
+ case SND_SOC_BIAS_PREPARE:
+ if(codec->dapm.bias_level != SND_SOC_BIAS_ON) {
+ /* updated by David-everest,5-25
+ // Chip Power on
+ snd_soc_write(codec, ES8328_CHIPPOWER, 0xF3);
+ // VMID control
+ snd_soc_write(codec, ES8328_CONTROL1 , 0x06);
+ // ADC/DAC DLL power on
+ snd_soc_write(codec, ES8328_CONTROL2 , 0xF3);
+ */
+ snd_soc_write(codec, ES8328_ADCPOWER, 0x00);
+ snd_soc_write(codec, ES8328_DACPOWER , 0x30);
+ snd_soc_write(codec, ES8328_CHIPPOWER , 0x00);
+ }
+ break;
+
+ case SND_SOC_BIAS_STANDBY:
+ /*
+ // ADC/DAC DLL power on
+ snd_soc_write(codec, ES8328_CONTROL2 , 0xFF);
+ // Chip Power off
+ snd_soc_write(codec, ES8328_CHIPPOWER, 0xF3);
+ */
+ snd_soc_write(codec, ES8328_ADCPOWER, 0x00);
+ snd_soc_write(codec, ES8328_DACPOWER , 0x30);
+ snd_soc_write(codec, ES8328_CHIPPOWER , 0x00);
+ break;
+
+ case SND_SOC_BIAS_OFF:
+ /*
+ // ADC/DAC DLL power off
+ snd_soc_write(codec, ES8328_CONTROL2 , 0xFF);
+ // Chip Control
+ snd_soc_write(codec, ES8328_CONTROL1 , 0x00);
+ // Chip Power off
+ snd_soc_write(codec, ES8328_CHIPPOWER, 0xFF);
+ */
+ snd_soc_write(codec, ES8328_ADCPOWER, 0xff);
+ snd_soc_write(codec, ES8328_DACPOWER , 0xC0);
+ snd_soc_write(codec, ES8328_CHIPPOWER , 0xC3);
+ break;
+ }
+
+ codec->dapm.bias_level = level;
+
+ return 0;
+}
+
+
+#define ES8328_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
+
+#define ES8328_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
+ SNDRV_PCM_FMTBIT_S24_LE)
+
+static const struct snd_soc_dai_ops es8328_dai_ops = {
+ .hw_params = es8328_pcm_hw_params,
+ .set_fmt = es8328_set_dai_fmt,
+ .set_sysclk = es8328_set_dai_sysclk,
+ .digital_mute = es8328_mute,
+};
+
+
+struct snd_soc_dai_driver es8328_dai = {
+ .name = "ES8328",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = ES8328_RATES,
+ .formats = ES8328_FORMATS,},
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = ES8328_RATES,
+ .formats = ES8328_FORMATS,},
+ .ops = &es8328_dai_ops,
+};
+
+EXPORT_SYMBOL_GPL(es8328_dai);
+
+
+static int es8328_suspend(struct snd_soc_codec *codec, pm_message_t state)
+{
+ es8328_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static int es8328_resume(struct snd_soc_codec *codec)
+{
+ es8328_sync(codec);
+ es8328_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ return 0;
+}
+
+static int es8328_remove(struct snd_soc_codec *codec)
+{
+ struct es8328_platform_data *es8328_pdata;
+
+ es8328_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+ es8328_pdata = codec->dev->platform_data;
+ gpio_free(es8328_pdata->power_pin);
+
+ return 0;
+}
+
+static int es8328_probe(struct snd_soc_codec *codec)
+{
+ struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
+ struct es8328_platform_data *es8328_pdata;
+ int ret = 0;
+
+ dev_info(codec->dev, "ES8328 Audio Codec %s", ES8328_VERSION);
+
+ codec->control_data = es8328->control_data;
+
+ es8328_pdata = codec->dev->platform_data;
+ if (!es8328_pdata)
+ return -EINVAL;
+
+ /* Power on ES8328 codec */
+ if (gpio_is_valid(es8328_pdata->power_pin)) {
+ ret = gpio_request(es8328_pdata->power_pin, "es8328 power");
+ if (ret < 0)
+ return ret;
+ } else {
+ return -ENODEV;
+ }
+ gpio_direction_output(es8328_pdata->power_pin, GPIO_HIGH);
+ msleep(es8328_pdata->power_delay);
+
+ es8328_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ snd_soc_write(codec, ES8328_MASTERMODE , 0x00); // SLAVE MODE, MCLK not divide
+ snd_soc_write(codec, ES8328_CHIPPOWER , 0xf3); // Power down: ADC DEM, DAC DSM/DEM, ADC/DAC state machine, ADC/DAC ananlog reference
+ snd_soc_write(codec, ES8328_DACCONTROL21, 0x80); // DACLRC and ADCLRC same, ADC/DAC DLL power up, Enable MCLK input from PAD.
+
+ snd_soc_write(codec, ES8328_CONTROL1 , 0x05); // VMIDSEL (500 kohme divider enabled)
+ snd_soc_write(codec, ES8328_CONTROL2 , 0x72); //
+
+ snd_soc_write(codec, ES8328_DACPOWER , 0x30); // DAC R/L Power on, OUT1 enable, OUT2 disable
+ snd_soc_write(codec, ES8328_ADCPOWER , 0x00); //
+ snd_soc_write(codec, ES8328_ANAVOLMANAG, 0x7C); //
+
+ //-----------------------------------------------------------------------------------------------------------------
+ snd_soc_write(codec, ES8328_ADCCONTROL1, 0x66); // MIC PGA gain: +24dB
+ snd_soc_write(codec, ES8328_ADCCONTROL2, 0xf0); // LINSEL(L-R differential), RINGSEL(L-R differential)
+ snd_soc_write(codec, ES8328_ADCCONTROL3, 0x82); // Input Select: LIN2/RIN2
+ snd_soc_write(codec, ES8328_ADCCONTROL4, 0x4C); // Left data = left ADC, right data = right ADC, 24 bits I2S
+ snd_soc_write(codec, ES8328_ADCCONTROL5, 0x02); // 256fs
+ //snd_soc_write(codec, ES8328_ADCCONTROL6, 0x00); // Disable High pass filter
+
+ snd_soc_write(codec, ES8328_LADC_VOL, 0x00); // 0dB
+ snd_soc_write(codec, ES8328_RADC_VOL, 0x00); // 0dB
+
+ //snd_soc_write(codec, ES8328_ADCCONTROL10, 0x3A); // ALC stereo, Max gain(17.5dB), Min gain(0dB)
+ snd_soc_write(codec, ES8328_ADCCONTROL10, 0xe2); // ALC stereo, Max gain(17.5dB), Min gain(0dB),updated by david-everest,5-25
+ snd_soc_write(codec, ES8328_ADCCONTROL11, 0xA0); // ALCLVL(-1.5dB), ALCHLD(0ms)
+ snd_soc_write(codec, ES8328_ADCCONTROL12, 0x05); // ALCDCY(1.64ms/363us), ALCATK(1664us/363.2us)
+ snd_soc_write(codec, ES8328_ADCCONTROL13, 0x06); // ALCMODE(ALC mode), ALCZC(disable), TIME_OUT(disable), WIN_SIZE(96 samples)
+ snd_soc_write(codec, ES8328_ADCCONTROL14, 0xd3); // NGTH(XXX), NGG(mute ADC output), NGAT(enable)
+
+
+ //----------------------------------------------------------------------------------------------------------------
+ snd_soc_write(codec, ES8328_DACCONTROL1, 0x18); // I2S 16bits
+ snd_soc_write(codec, ES8328_DACCONTROL2, 0x02); // 256fs
+
+ snd_soc_write(codec, ES8328_LDAC_VOL, 0x00); // left DAC volume
+ snd_soc_write(codec, ES8328_RDAC_VOL, 0x00); // right DAC volume
+
+ snd_soc_write(codec, ES8328_DACCONTROL3, 0xE0); // DAC unmute
+
+ snd_soc_write(codec, ES8328_DACCONTROL17, 0xb8); // left DAC to left mixer enable,
+ snd_soc_write(codec, ES8328_DACCONTROL18, 0x38); // ???
+ snd_soc_write(codec, ES8328_DACCONTROL19, 0x38); // ???
+ snd_soc_write(codec, ES8328_DACCONTROL20, 0xb8); // right DAC to right mixer enable,
+
+ snd_soc_write(codec, ES8328_CHIPPOWER, 0x00); // ALL Block POWER ON
+ //snd_soc_write(codec, ES8328_CONTROL2 , 0x72); // updated by david-everest,5-25
+ //mdelay(100);
+
+ snd_soc_write(codec, ES8328_LOUT1_VOL, 0x1D); //
+ snd_soc_write(codec, ES8328_ROUT1_VOL, 0x1D); //
+ snd_soc_write(codec, ES8328_LOUT2_VOL, 0x00); // Disable LOUT2
+ snd_soc_write(codec, ES8328_ROUT2_VOL, 0x00); // Disable ROUT2
+
+ snd_soc_add_codec_controls(codec, es8328_snd_controls,
+ ARRAY_SIZE(es8328_snd_controls));
+ snd_soc_dapm_new_controls(&codec->dapm, es8328_dapm_widgets,
+ ARRAY_SIZE(es8328_dapm_widgets));
+ snd_soc_dapm_add_routes(&codec->dapm, intercon, ARRAY_SIZE(intercon));
+
+ return ret;
+}
+
+
+static struct snd_soc_codec_driver soc_codec_dev_es8328 = {
+ .probe = es8328_probe,
+ .remove = es8328_remove,
+ .suspend = es8328_suspend,
+ .resume = es8328_resume,
+ .read = es8328_read_reg_cache,
+ .write = es8328_write,
+ .set_bias_level = es8328_set_bias_level,
+ .reg_cache_size = ARRAY_SIZE(es8328_reg),
+ .reg_word_size = sizeof(u8),
+ .reg_cache_default = es8328_reg,
+ .reg_cache_step = 1,
+};
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static int es8328_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct es8328_priv *es8328;
+ int ret;
+
+ es8328 = kzalloc(sizeof(struct es8328_priv), GFP_KERNEL);
+ if (es8328 == NULL)
+ return -ENOMEM;
+
+ i2c_set_clientdata(i2c, es8328);
+ es8328->control_data = i2c;
+
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_es8328, &es8328_dai, 1);
+ if (ret < 0)
+ kfree(es8328);
+
+ return ret;
+}
+
+static int es8328_i2c_remove(struct i2c_client *i2c)
+{
+ snd_soc_unregister_codec(&i2c->dev);
+ kfree(i2c_get_clientdata(i2c));
+
+ return 0;
+}
+
+static const struct i2c_device_id es8328_i2c_id[] = {
+ { "es8328", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, es8328_i2c_id);
+
+static struct i2c_driver es8328_i2c_driver = {
+ .driver = {
+ .name = "es8328-codec",
+ .owner = THIS_MODULE,
+ },
+ .probe = es8328_i2c_probe,
+ .remove = es8328_i2c_remove,
+ .id_table = es8328_i2c_id,
+};
+#endif
+
+static int __init es8328_modinit(void)
+{
+ int ret = 0;
+
+#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
+ ret = i2c_add_driver(&es8328_i2c_driver);
+ if (ret != 0) {
+ pr_err("Failed to register ES8328 I2C driver: %d\n", ret);
+ }
+#endif
+ return ret;
+}
+module_init(es8328_modinit);
+
+static void __exit es8328_exit(void)
+{
+#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
+ i2c_del_driver(&es8328_i2c_driver);
+#endif
+}
+module_exit(es8328_exit);
+
+MODULE_DESCRIPTION("ASoC ES8328 driver");
+MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
+MODULE_LICENSE("GPL");
+
diff --git a/sound/soc/codecs/es8328.h b/sound/soc/codecs/es8328.h
new file mode 100644
index 00000000..a8c3bc06
--- /dev/null
+++ b/sound/soc/codecs/es8328.h
@@ -0,0 +1,157 @@
+/*
+ * es8328.h -- ES8328 Soc Audio driver
+ *
+ * Copyright 2011 Ambarella Ltd.
+ *
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _ES8328_H
+#define _ES8328_H
+
+#define CONFIG_HHTECH_MINIPMP 1
+
+/* ES8328 register space */
+
+#define ES8328_CONTROL1 0x00
+#define ES8328_CONTROL2 0x01
+#define ES8328_CHIPPOWER 0x02
+#define ES8328_ADCPOWER 0x03
+#define ES8328_DACPOWER 0x04
+#define ES8328_CHIPLOPOW1 0x05
+#define ES8328_CHIPLOPOW2 0x06
+#define ES8328_ANAVOLMANAG 0x07
+#define ES8328_MASTERMODE 0x08
+#define ES8328_ADCCONTROL1 0x09
+#define ES8328_ADCCONTROL2 0x0a
+#define ES8328_ADCCONTROL3 0x0b
+#define ES8328_ADCCONTROL4 0x0c
+#define ES8328_ADCCONTROL5 0x0d
+#define ES8328_ADCCONTROL6 0x0e
+#define ES8328_ADCCONTROL7 0x0f
+#define ES8328_ADCCONTROL8 0x10
+#define ES8328_ADCCONTROL9 0x11
+#define ES8328_ADCCONTROL10 0x12
+#define ES8328_ADCCONTROL11 0x13
+#define ES8328_ADCCONTROL12 0x14
+#define ES8328_ADCCONTROL13 0x15
+#define ES8328_ADCCONTROL14 0x16
+
+#define ES8328_DACCONTROL1 0x17
+#define ES8328_DACCONTROL2 0x18
+#define ES8328_DACCONTROL3 0x19
+#define ES8328_DACCONTROL4 0x1a
+#define ES8328_DACCONTROL5 0x1b
+#define ES8328_DACCONTROL6 0x1c
+#define ES8328_DACCONTROL7 0x1d
+#define ES8328_DACCONTROL8 0x1e
+#define ES8328_DACCONTROL9 0x1f
+#define ES8328_DACCONTROL10 0x20
+#define ES8328_DACCONTROL11 0x21
+#define ES8328_DACCONTROL12 0x22
+#define ES8328_DACCONTROL13 0x23
+#define ES8328_DACCONTROL14 0x24
+#define ES8328_DACCONTROL15 0x25
+#define ES8328_DACCONTROL16 0x26
+#define ES8328_DACCONTROL17 0x27
+#define ES8328_DACCONTROL18 0x28
+#define ES8328_DACCONTROL19 0x29
+#define ES8328_DACCONTROL20 0x2a
+#define ES8328_DACCONTROL21 0x2b
+#define ES8328_DACCONTROL22 0x2c
+#define ES8328_DACCONTROL23 0x2d
+#define ES8328_DACCONTROL24 0x2e
+#define ES8328_DACCONTROL25 0x2f
+#define ES8328_DACCONTROL26 0x30
+#define ES8328_DACCONTROL27 0x31
+#define ES8328_DACCONTROL28 0x32
+#define ES8328_DACCONTROL29 0x33
+#define ES8328_DACCONTROL30 0x34
+
+#define ES8328_LADC_VOL ES8328_ADCCONTROL8
+#define ES8328_RADC_VOL ES8328_ADCCONTROL9
+
+#define ES8328_LDAC_VOL ES8328_DACCONTROL4
+#define ES8328_RDAC_VOL ES8328_DACCONTROL5
+
+#define ES8328_LOUT1_VOL ES8328_DACCONTROL24
+#define ES8328_ROUT1_VOL ES8328_DACCONTROL25
+#define ES8328_LOUT2_VOL ES8328_DACCONTROL26
+#define ES8328_ROUT2_VOL ES8328_DACCONTROL27
+
+#define ES8328_ADC_MUTE ES8328_ADCCONTROL7
+#define ES8328_DAC_MUTE ES8328_DACCONTROL3
+
+
+
+#define ES8328_IFACE ES8328_MASTERMODE
+
+#define ES8328_ADC_IFACE ES8328_ADCCONTROL4
+#define ES8328_ADC_SRATE ES8328_ADCCONTROL5
+
+#define ES8328_DAC_IFACE ES8328_DACCONTROL1
+#define ES8328_DAC_SRATE ES8328_DACCONTROL2
+
+
+
+#define ES8328_CACHEREGNUM 53
+#define ES8328_SYSCLK 0
+
+struct es8328_setup_data {
+ int i2c_bus;
+ unsigned short i2c_address;
+};
+
+#if 1 //lzcx
+#define ES8328_PLL1 0
+#define ES8328_PLL2 1
+
+/* clock inputs */
+#define ES8328_MCLK 0
+#define ES8328_PCMCLK 1
+
+/* clock divider id's */
+#define ES8328_PCMDIV 0
+#define ES8328_BCLKDIV 1
+#define ES8328_VXCLKDIV 2
+
+/* PCM clock dividers */
+#define ES8328_PCM_DIV_1 (0 << 6)
+#define ES8328_PCM_DIV_3 (2 << 6)
+#define ES8328_PCM_DIV_5_5 (3 << 6)
+#define ES8328_PCM_DIV_2 (4 << 6)
+#define ES8328_PCM_DIV_4 (5 << 6)
+#define ES8328_PCM_DIV_6 (6 << 6)
+#define ES8328_PCM_DIV_8 (7 << 6)
+
+/* BCLK clock dividers */
+#define ES8328_BCLK_DIV_1 (0 << 7)
+#define ES8328_BCLK_DIV_2 (1 << 7)
+#define ES8328_BCLK_DIV_4 (2 << 7)
+#define ES8328_BCLK_DIV_8 (3 << 7)
+
+/* VXCLK clock dividers */
+#define ES8328_VXCLK_DIV_1 (0 << 6)
+#define ES8328_VXCLK_DIV_2 (1 << 6)
+#define ES8328_VXCLK_DIV_4 (2 << 6)
+#define ES8328_VXCLK_DIV_8 (3 << 6)
+#define ES8328_VXCLK_DIV_16 (4 << 6)
+
+#define ES8328_DAI_HIFI 0
+#define ES8328_DAI_VOICE 1
+
+#define ES8328_1536FS 1536
+#define ES8328_1024FS 1024
+#define ES8328_768FS 768
+#define ES8328_512FS 512
+#define ES8328_384FS 384
+#define ES8328_256FS 256
+#define ES8328_128FS 128
+#endif
+
+#endif
+
diff --git a/sound/soc/codecs/es8374.c b/sound/soc/codecs/es8374.c
new file mode 100644
index 00000000..12897c48
--- /dev/null
+++ b/sound/soc/codecs/es8374.c
@@ -0,0 +1,1564 @@
+/*
+ * es8374.c -- ES8374 ALSA SoC Audio Codec
+ *
+ * Copyright (C) 2016 Everest Semiconductor Co., Ltd
+ *
+ * Authors: XianqingZheng(xqzheng@ambarella.com)
+ *
+ * Based on es8374.c by David Yang(yangxiaohua@everest-semi.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/regmap.h>
+#include <linux/stddef.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/tlv.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+#include <linux/of_gpio.h>
+#include "es8374.h"
+
+//#define ES8374_SPI
+/*
+ * es8374 register cache
+ */
+static struct reg_default es8374_reg_defaults[] = {
+ { 0x00, 0x03 },
+ { 0x01, 0x03 },
+ { 0x02, 0x00 },
+ { 0x03, 0x20 },
+ { 0x04, 0x00 },
+ { 0x05, 0x11 },
+ { 0x06, 0x01 },
+ { 0x07, 0x00 },
+ { 0x08, 0x20 },
+ { 0x09, 0x80 },
+ { 0x0a, 0x4A },
+ { 0x0b, 0x00 },
+ { 0x0c, 0x00 },
+ { 0x0d, 0x00 },
+ { 0x0e, 0x00 },
+ { 0x0f, 0x00 },
+
+ { 0x10, 0x00 },
+ { 0x11, 0x00 },
+ { 0x12, 0x40 },
+ { 0x13, 0x40 },
+ { 0x14, 0x9C },
+ { 0x15, 0xBE },
+ { 0x16, 0x00 },
+ { 0x17, 0xA0 },
+ { 0x18, 0xFC },
+ { 0x19, 0x00 },
+ { 0x1a, 0x18 },
+ { 0x1b, 0x00 },
+ { 0x1c, 0x10 },
+ { 0x1d, 0x10 },
+ { 0x1e, 0x00 },
+ { 0x1f, 0x08 },
+
+ { 0x20, 0x08 },
+ { 0x21, 0xD4 },
+ { 0x22, 0x00 },
+ { 0x23, 0x00 },
+ { 0x24, 0x18 },
+ { 0x25, 0xC0 },
+ { 0x26, 0x1C },
+ { 0x27, 0x00 },
+ { 0x28, 0xB0 },
+ { 0x29, 0x32 },
+ { 0x2a, 0x03 },
+ { 0x2b, 0x00 },
+ { 0x2c, 0x0D },
+ { 0x2d, 0x06 },
+ { 0x2e, 0x1F },
+ { 0x2f, 0xF7 },
+
+ { 0x30, 0xFD },
+ { 0x31, 0xFF },
+ { 0x32, 0x1F },
+ { 0x33, 0xF7 },
+ { 0x34, 0xFD },
+ { 0x35, 0xFF },
+ { 0x36, 0x04 },
+ { 0x37, 0x01 },
+ { 0x38, 0xC0 },
+ { 0x39, 0x00 },
+ { 0x3a, 0x02 },
+ { 0x3b, 0x17 },
+ { 0x3c, 0xFD },
+ { 0x3d, 0xFF },
+ { 0x3e, 0x07 },
+ { 0x3f, 0xFD },
+
+ { 0x40, 0xFF },
+ { 0x41, 0x00 },
+ { 0x42, 0xFF },
+ { 0x43, 0xBB },
+ { 0x44, 0xFF },
+ { 0x45, 0x00 },
+ { 0x46, 0x00 },
+ { 0x47, 0x00 },
+ { 0x48, 0x00 },
+ { 0x49, 0x00 },
+ { 0x4a, 0x00 },
+ { 0x4b, 0x00 },
+ { 0x4c, 0x00 },
+ { 0x4d, 0x00 },
+ { 0x4e, 0x00 },
+ { 0x4f, 0x00 },
+
+ { 0x50, 0x00 },
+ { 0x51, 0x00 },
+ { 0x52, 0x00 },
+ { 0x53, 0x00 },
+ { 0x54, 0x00 },
+ { 0x55, 0x00 },
+ { 0x56, 0x00 },
+ { 0x57, 0x00 },
+ { 0x58, 0x00 },
+ { 0x59, 0x00 },
+ { 0x5a, 0x00 },
+ { 0x5b, 0x00 },
+ { 0x5c, 0x00 },
+ { 0x5d, 0x00 },
+ { 0x5e, 0x00 },
+ { 0x5f, 0x00 },
+
+ { 0x60, 0x00 },
+ { 0x61, 0x00 },
+ { 0x62, 0x00 },
+ { 0x63, 0x00 },
+ { 0x64, 0x00 },
+ { 0x65, 0x00 },
+ { 0x66, 0x00 },
+ { 0x67, 0x00 },
+ { 0x68, 0x00 },
+ { 0x69, 0x00 },
+ { 0x6a, 0x00 },
+ { 0x6b, 0x00 },
+ { 0x6c, 0x00 },
+ { 0x6d, 0x00 },
+ { 0x6e, 0x00 },
+ { 0x6f, 0x00 },
+
+};
+#if 0
+static u8 es8374_equalizer_src[] = {
+ 0x0A, 0x9B, 0x32, 0x03, 0x5C, 0x5D, 0x4B, 0x24, 0x0A, 0x9B,
+ 0x32, 0x03, 0x4C, 0x1F, 0x43, 0x05, 0x6D, 0x27, 0x54, 0x06,
+ 0x4D, 0xE1, 0x32, 0x02, 0x3E, 0x55, 0x2A, 0x20, 0x4D, 0xE1,
+ 0x32, 0x02, 0x2E, 0x17, 0x22, 0x01, 0x9F, 0xE7, 0x43, 0x25,
+ 0x4B, 0xD9, 0x21, 0x01, 0xF9, 0xD4, 0x11, 0x21, 0x4B, 0xD9,
+ 0x21, 0x01, 0xE9, 0x96, 0x19, 0x00, 0x4C, 0xE7, 0x22, 0x23,
+};
+#endif
+struct sp_config {
+ u8 spc, mmcc, spfs;
+ u32 srate;
+ u8 lrcdiv;
+ u8 sclkdiv;
+};
+
+/* codec private data */
+
+struct es8374_private {
+ enum snd_soc_control_type control_type;
+ struct spi_device *spi;
+ struct i2c_client *i2c;
+
+ struct snd_soc_codec *codec;
+ struct regmap *regmap;
+ u32 clk_id;
+ u32 mclk;
+
+ /* platform dependant DVDD voltage configuration */
+/* u8 dvdd_pwr_vol;
+ u8 pll_div;
+*/
+ int pwr_gpio;
+ unsigned int pwr_active;
+ bool dmic_enable;
+ u8 reg_cache[110];
+};
+
+struct es8374_private *es8374_data;
+
+static bool es8374_volatile_register(struct device *dev,
+ unsigned int reg)
+{
+ if ((reg < 0x80)) {
+ if((reg != 0x19) && (reg != 0x23)) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+}
+
+static bool es8374_readable_register(struct device *dev,
+ unsigned int reg)
+{
+ if ((reg < 0x80)) {
+ if((reg != 0x19) && (reg != 0x23)) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+}
+static bool es8374_writable_register(struct device *dev,
+ unsigned int reg)
+{
+ if ((reg < 0x80)) {
+ if((reg != 0x19) && (reg != 0x23)) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+}
+
+
+/*
+* Define ADC and DAC Volume
+*/
+static const DECLARE_TLV_DB_SCALE(vdac_tlv, 0, 50, 0);
+static const DECLARE_TLV_DB_SCALE(vadc_tlv, 0, 50, 0);
+/*
+* Define D2SE MIC BOOST GAIN
+*/
+static const DECLARE_TLV_DB_SCALE(mic_boost_tlv, 0, 1500, 0);
+/*
+* Define LINE PGA GAIN
+*/
+static const DECLARE_TLV_DB_SCALE(linin_pga_tlv, 0, 300, 0);
+/*
+* Define dmic boost gain
+*/
+static const DECLARE_TLV_DB_SCALE(dmic_6db_scaleup_tlv, 0, 600, 0);
+/*
+* Definitiiion ALC noise gate type
+*/
+
+static const char * const ng_type_txt[] = {"Constant PGA Gain",
+ "Mute ADC Output"};
+static const struct soc_enum ng_type =
+SOC_ENUM_SINGLE(ES8374_ALC_NGTH_REG2B, 6, 2, ng_type_txt);
+
+
+static const char * const alc_mode_txt[] = {
+ "ALC Mode",
+ "Limiter Mode"
+};
+
+static const struct soc_enum alc_mode =
+SOC_ENUM_SINGLE(ES8374_ALC_EN_MAX_GAIN_REG26, 5, 2, alc_mode_txt);
+
+/*
+* Define MONO output gain
+*/
+static const DECLARE_TLV_DB_SCALE(mono_out_gain_tlv, 0, 150, 0);
+/*
+* Definitiiion dac auto mute type
+*/
+
+static const char * const dac_auto_mute_type_txt[] = {
+ "AUTO MUTE DISABLE",
+ "MONO OUTPUT MUTE",
+ "SPEAKER MUTE",
+ "MONO OUT & SPEAKER MUTE"
+ };
+static const struct soc_enum dac_auto_mute_type =
+SOC_ENUM_SINGLE(ES8374_DAC_CONTROL_REG37, 4, 4, dac_auto_mute_type_txt);
+/*
+* Definitiiion dac dsm mute type
+*/
+
+static const char * const dac_dsm_mute_type_txt[] = {
+ "DAC DSM UNMUTE",
+ "DAC DSM MUTE",
+ };
+static const struct soc_enum dac_dsm_mute_type =
+SOC_ENUM_SINGLE(ES8374_DAC_CONTROL_REG37, 0, 2, dac_dsm_mute_type_txt);
+
+/*
+ * es8374 Controls
+ */
+static const struct snd_kcontrol_new es8374_snd_controls[] = {
+ /*
+ * controls for capture path
+ */
+ SOC_SINGLE_TLV("D2SE MIC BOOST GAIN",
+ ES8374_AIN_PWR_SRC_REG21, 2, 1, 0, mic_boost_tlv),
+ SOC_SINGLE_TLV("LIN PGA GAIN",
+ ES8374_AIN_PGA_REG22, 0, 15, 0, linin_pga_tlv),
+ SOC_SINGLE_TLV("DMIC 6DB SCALE UP GAIN",
+ ES8374_ADC_CONTROL_REG24, 7, 1, 0, dmic_6db_scaleup_tlv),
+ SOC_SINGLE("ADC Double FS Mode", ES8374_ADC_CONTROL_REG24, 6, 1, 0),
+ SOC_SINGLE("ADC Soft Ramp", ES8374_ADC_CONTROL_REG24, 4, 1, 0),
+ SOC_SINGLE("ADC MUTE", ES8374_ADC_CONTROL_REG24, 5, 1, 0),
+ SOC_SINGLE("ADC INVERTED", ES8374_ADC_CONTROL_REG24, 2, 1, 0),
+ SOC_SINGLE("ADC HPF COEFFICIENT", ES8374_ADC_HPF_REG2C, 0, 31, 0),
+// SOC_SINGLE_TLV("ADC Capture Volume",
+// ES8374_ADC_VOLUME_REG25, 0, 192, 1, adc_rec_tlv),
+ SOC_SINGLE("ALC Capture Target Volume", ES8374_ALC_LVL_HLD_REG28, 4, 15, 0),
+ SOC_SINGLE("ALC Capture Max PGA", ES8374_ALC_EN_MAX_GAIN_REG26, 0, 31, 0),
+ SOC_SINGLE("ALC Capture Min PGA", ES8374_ALC_MIN_GAIN_REG27, 0, 31, 0),
+// SOC_ENUM("ALC Capture Function", alc_func),
+ SOC_ENUM("ALC Mode", alc_mode),
+ SOC_SINGLE("ALC Capture Hold Time", ES8374_ALC_LVL_HLD_REG28, 0, 15, 0),
+ SOC_SINGLE("ALC Capture Decay Time", ES8374_ALC_DCY_ATK_REG29, 4, 15, 0),
+ SOC_SINGLE("ALC Capture Attack Time", ES8374_ALC_DCY_ATK_REG29, 0, 15, 0),
+ SOC_SINGLE("ALC Capture NG Threshold", ES8374_ALC_NGTH_REG2B, 0, 31, 0),
+ SOC_ENUM("ALC Capture NG Type", ng_type),
+ SOC_SINGLE("ALC Capture NG Switch", ES8374_ALC_NGTH_REG2B, 5, 1, 0),
+
+ /*
+ * controls for playback path
+ */
+ SOC_SINGLE("DAC Double FS Mode", ES8374_DAC_CONTROL_REG37, 7, 1, 0),
+ SOC_SINGLE("DAC Soft Ramp Rate", ES8374_DAC_CONTROL_REG36, 2, 7, 0),
+ SOC_SINGLE("DAC MUTE", ES8374_DAC_CONTROL_REG36, 5, 1, 0),
+ SOC_SINGLE("DAC OFFSET", ES8374_DAC_OFFSET_REG39, 0, 255, 0),
+ SOC_ENUM("DAC AUTO MUTE TYPE", dac_auto_mute_type),
+ SOC_ENUM("DAC DSM MUTE TYPE", dac_dsm_mute_type),
+
+ SOC_SINGLE_TLV("ADC Capture Volume",
+ ES8374_ADC_VOLUME_REG25, 0, 192, 1, vadc_tlv),
+ SOC_SINGLE_TLV("DAC Playback Volume",
+ ES8374_DAC_VOLUME_REG38, 0, 192, 1, vdac_tlv),
+ SOC_SINGLE_TLV("MONO OUT GAIN",
+ ES8374_MONO_GAIN_REG1B, 0, 15, 0, mono_out_gain_tlv),
+ SOC_SINGLE_TLV("SPEAKER MIXER GAIN",
+ ES8374_SPK_MIX_GAIN_REG1D, 0, 15, 0, mono_out_gain_tlv),
+ SOC_SINGLE_TLV("SPEAKER OUTPUT Volume",
+ ES8374_SPK_OUT_GAIN_REG1E, 0, 7, 0, mono_out_gain_tlv),
+};
+
+/*
+ * DAPM Controls
+ */
+/*
+* alc on/off
+*/
+static const char * const es8374_alc_enable_txt[] = {
+ "ALC OFF",
+ "ALC ON",
+};
+
+static const struct soc_enum es8374_alc_enable_enum =
+SOC_ENUM_SINGLE(ES8374_ALC_EN_MAX_GAIN_REG26, 6,
+ ARRAY_SIZE(es8374_alc_enable_txt), es8374_alc_enable_txt);
+
+
+static const struct snd_kcontrol_new es8374_alc_enable_controls =
+ SOC_DAPM_ENUM("Route", es8374_alc_enable_enum);
+/*
+* adc line in select
+*/
+static const char * const es8374_adc_input_src_txt[] = {
+ "LIN1-RIN1",
+ "LIN2-RIN2",
+};
+static const unsigned int es8374_adc_input_src_values[] = {
+ 0, 1};
+static const struct soc_enum es8374_adc_input_src_enum =
+SOC_VALUE_ENUM_SINGLE(ES8374_AIN_PWR_SRC_REG21, 4, 0x30,
+ ARRAY_SIZE(es8374_adc_input_src_txt),
+ es8374_adc_input_src_txt,
+ es8374_adc_input_src_values);
+static const struct snd_kcontrol_new es8374_adc_input_src_controls =
+ SOC_DAPM_ENUM("Route", es8374_adc_input_src_enum);
+
+/*
+ * ANALOG IN MUX
+ */
+static const char * const es8374_analog_input_mux_txt[] = {
+ "LIN1",
+ "LIN2",
+ "DIFF OUT1",
+ "DIFF OUT2",
+ "PGA OUT1",
+ "PGA OUT2"
+};
+static const unsigned int es8374_analog_input_mux_values[] = {
+ 0, 1, 2, 3, 4, 5};
+static const struct soc_enum es8374_analog_input_mux_enum =
+SOC_VALUE_ENUM_SINGLE(ES8374_MONO_MIX_REG1A, 0, 0x7,
+ ARRAY_SIZE(es8374_analog_input_mux_txt),
+ es8374_analog_input_mux_txt,
+ es8374_analog_input_mux_values);
+static const struct snd_kcontrol_new es8374_analog_input_mux_controls =
+SOC_DAPM_ENUM("Route", es8374_analog_input_mux_enum);
+/*
+ * MONO OUTPUT MIXER
+ */
+static const struct snd_kcontrol_new es8374_mono_out_mixer_controls[] = {
+ SOC_DAPM_SINGLE("LIN TO MONO OUT Switch", ES8374_MONO_MIX_REG1A, 6, 1, 0),
+ SOC_DAPM_SINGLE("DAC TO MONO OUT Switch", ES8374_MONO_MIX_REG1A, 7, 1, 0),
+};
+/*
+ * SPEAKER OUTPUT MIXER
+ */
+static const struct snd_kcontrol_new es8374_speaker_mixer_controls[] = {
+ SOC_DAPM_SINGLE("LIN TO SPEAKER OUT Switch", ES8374_SPK_MIX_REG1C, 6, 1, 0),
+ SOC_DAPM_SINGLE("DAC TO SPEAKER OUT Switch", ES8374_SPK_MIX_REG1C, 7, 1, 0),
+};
+/*
+ * digital microphone soure
+ */
+static const char * const es8374_dmic_mux_txt[] = {
+ "DMIC DISABLE1",
+ "DMIC DISABLE2",
+ "DMIC AT HIGH LEVEL",
+ "DMIC AT LOW LEVEL",
+};
+static const unsigned int es8374_dmic_mux_values[] = {
+ 0, 1, 2, 3};
+static const struct soc_enum es8374_dmic_mux_enum =
+ SOC_VALUE_ENUM_SINGLE(ES8374_ADC_CONTROL_REG24, 0, 0x3,
+ ARRAY_SIZE(es8374_dmic_mux_txt),
+ es8374_dmic_mux_txt,
+ es8374_dmic_mux_values);
+static const struct snd_kcontrol_new es8374_dmic_mux_controls =
+ SOC_DAPM_ENUM("Route", es8374_dmic_mux_enum);
+/*
+ * ADC sdp soure
+ */
+static const char * const es8374_adc_sdp_mux_txt[] = {
+ "FROM ADC OUT",
+ "FROM EQUALIZER",
+};
+static const unsigned int es8374_adc_sdp_mux_values[] = {
+ 0, 1};
+static const struct soc_enum es8374_adc_sdp_mux_enum =
+ SOC_VALUE_ENUM_SINGLE(ES8374_EQ_SRC_REG2D, 7, 0x80,
+ ARRAY_SIZE(es8374_adc_sdp_mux_txt),
+ es8374_adc_sdp_mux_txt,
+ es8374_adc_sdp_mux_values);
+static const struct snd_kcontrol_new es8374_adc_sdp_mux_controls =
+ SOC_DAPM_ENUM("Route", es8374_adc_sdp_mux_enum);
+
+/*
+ * DAC dsm soure
+ */
+static const char * const es8374_dac_dsm_mux_txt[] = {
+ "FROM SDP IN",
+ "FROM EQUALIZER",
+};
+static const unsigned int es8374_dac_dsm_mux_values[] = {
+ 0, 1};
+static const struct soc_enum es8374_dac_dsm_mux_enum =
+ SOC_VALUE_ENUM_SINGLE(ES8374_EQ_SRC_REG2D, 6, 0x40,
+ ARRAY_SIZE(es8374_dac_dsm_mux_txt),
+ es8374_dac_dsm_mux_txt,
+ es8374_dac_dsm_mux_values);
+static const struct snd_kcontrol_new es8374_dac_dsm_mux_controls =
+ SOC_DAPM_ENUM("Route", es8374_dac_dsm_mux_enum);
+/*
+ * equalizer data soure
+ */
+static const char * const es8374_equalizer_src_mux_txt[] = {
+ "FROM ADC OUT",
+ "FROM SDP IN",
+};
+static const unsigned int es8374_equalizer_src_mux_values[] = {
+ 0, 1};
+static const struct soc_enum es8374_equalizer_src_mux_enum =
+ SOC_VALUE_ENUM_SINGLE(ES8374_EQ_SRC_REG2D, 5, 0x20,
+ ARRAY_SIZE(es8374_equalizer_src_mux_txt),
+ es8374_equalizer_src_mux_txt,
+ es8374_equalizer_src_mux_values);
+static const struct snd_kcontrol_new es8374_equalizer_src_mux_controls =
+ SOC_DAPM_ENUM("Route", es8374_equalizer_src_mux_enum);
+/*
+ * DAC data soure
+ */
+static const char * const es8374_dac_data_mux_txt[] = {
+ "SELECT SDP LEFT DATA",
+ "SELECT SDP RIGHT DATA",
+};
+static const unsigned int es8374_dac_data_mux_values[] = {
+ 0, 1};
+static const struct soc_enum es8374_dac_data_mux_enum =
+ SOC_VALUE_ENUM_SINGLE(ES8374_DAC_CONTROL_REG36, 6, 0x40,
+ ARRAY_SIZE(es8374_dac_data_mux_txt),
+ es8374_dac_data_mux_txt,
+ es8374_dac_data_mux_values);
+static const struct snd_kcontrol_new es8374_dac_data_mux_controls =
+ SOC_DAPM_ENUM("Route", es8374_dac_data_mux_enum);
+
+static const struct snd_soc_dapm_widget es8374_dapm_widgets[] = {
+ /* Input Lines */
+ SND_SOC_DAPM_INPUT("DMIC"),
+ SND_SOC_DAPM_INPUT("MIC1"),
+ SND_SOC_DAPM_INPUT("MIC2"),
+ SND_SOC_DAPM_INPUT("LIN1"),
+ SND_SOC_DAPM_INPUT("LIN2"),
+
+ /*
+ * Capture path
+ */
+ SND_SOC_DAPM_MICBIAS("micbias", ES8374_ANA_REF_REG14,
+ 4, 1),
+
+ /* Input MUX */
+ SND_SOC_DAPM_MUX("DIFFERENTIAL MUX", SND_SOC_NOPM, 0, 0,
+ &es8374_adc_input_src_controls),
+
+ SND_SOC_DAPM_PGA("DIFFERENTIAL PGA", SND_SOC_NOPM,
+ 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_PGA("LINE PGA", SND_SOC_NOPM,
+ 0, 0, NULL, 0),
+
+ /* ADCs */
+ SND_SOC_DAPM_ADC("MONO ADC", NULL, SND_SOC_NOPM, 0, 0),
+
+ /* Dmic MUX */
+ SND_SOC_DAPM_MUX("DMIC MUX", SND_SOC_NOPM, 0, 0,
+ &es8374_dmic_mux_controls),
+
+ /* Dmic MUX */
+ SND_SOC_DAPM_MUX("ALC MUX", SND_SOC_NOPM, 0, 0,
+ &es8374_alc_enable_controls),
+
+
+ /* sdp MUX */
+ SND_SOC_DAPM_MUX("SDP OUT MUX", SND_SOC_NOPM, 0, 0,
+ &es8374_adc_sdp_mux_controls),
+
+ /* Digital Interface */
+ SND_SOC_DAPM_AIF_OUT("I2S OUT", "I2S1 Capture", 1,
+ SND_SOC_NOPM, 0, 0),
+
+ /*
+ * Render path
+ */
+ SND_SOC_DAPM_AIF_IN("I2S IN", "I2S1 Playback", 0,
+ SND_SOC_NOPM, 0, 0),
+
+ /* DACs SDP DATA SRC MUX */
+ SND_SOC_DAPM_MUX("DAC SDP SRC MUX", SND_SOC_NOPM, 0, 0,
+ &es8374_dac_data_mux_controls),
+
+ /* DACs DATA SRC MUX */
+ SND_SOC_DAPM_MUX("DAC SRC MUX", SND_SOC_NOPM, 0, 0,
+ &es8374_dac_dsm_mux_controls),
+
+ SND_SOC_DAPM_DAC("MONO DAC", NULL, SND_SOC_NOPM, 0, 0),
+
+
+ /* hpmux for hp mixer */
+ SND_SOC_DAPM_MUX("ANALOG INPUT MUX", SND_SOC_NOPM, 0, 0,
+ &es8374_analog_input_mux_controls),
+
+ /* Output mixer */
+ SND_SOC_DAPM_MIXER("MONO MIXER", SND_SOC_NOPM,
+ 0, 0, &es8374_mono_out_mixer_controls[0], ARRAY_SIZE(es8374_mono_out_mixer_controls)),
+ SND_SOC_DAPM_MIXER("SPEAKER MIXER", SND_SOC_NOPM,
+ 0, 0, &es8374_speaker_mixer_controls[0], ARRAY_SIZE(es8374_speaker_mixer_controls)),
+
+ /*
+ * Equalizer path
+ */
+ SND_SOC_DAPM_MUX("EQUALIZER MUX", SND_SOC_NOPM, 0, 0,
+ &es8374_equalizer_src_mux_controls),
+
+ /* Output Lines */
+ SND_SOC_DAPM_OUTPUT("MOUT"),
+ SND_SOC_DAPM_OUTPUT("SPKOUT"),
+
+};
+
+
+static const struct snd_soc_dapm_route es8374_dapm_routes[] = {
+ /*
+ * record route map
+ */
+ {"MIC1", NULL, "micbias"},
+ {"MIC2", NULL, "micbias"},
+ {"DMIC", NULL, "micbias"},
+
+ {"DIFFERENTIAL MUX", "LIN1-RIN1", "MIC1"},
+ {"DIFFERENTIAL MUX", "LIN2-RIN2", "MIC2"},
+
+ {"DIFFERENTIAL PGA", NULL, "DIFFERENTIAL MUX"},
+
+ {"LINE PGA", NULL, "DIFFERENTIAL PGA"},
+
+ {"MONO ADC", NULL, "LINE PGA"},
+
+ {"DMIC MUX", "DMIC DISABLE1", "MONO ADC"},
+ {"DMIC MUX", "DMIC DISABLE2", "MONO ADC"},
+ {"DMIC MUX", "DMIC AT HIGH LEVEL", "DMIC"},
+ {"DMIC MUX", "DMIC AT LOW LEVEL", "DMIC"},
+
+ {"ALC MUX", "ALC OFF", "DMIC MUX"},
+ {"ALC MUX", "ALC ON", "DMIC MUX"},
+
+ /*
+ * Equalizer path
+ */
+ {"EQUALIZER MUX", "FROM ADC OUT", "ALC MUX"},
+ {"EQUALIZER MUX", "FROM SDP IN", "I2S IN"},
+
+ {"SDP OUT MUX", "FROM ADC OUT", "ALC MUX"},
+ {"SDP OUT MUX", "FROM EQUALIZER", "EQUALIZER MUX"},
+
+ {"I2S OUT", NULL, "SDP OUT MUX"},
+ /*
+ * playback route map
+ */
+ {"DAC SDP SRC MUX", "SELECT SDP LEFT DATA", "I2S IN"},
+ {"DAC SDP SRC MUX", "SELECT SDP RIGHT DATA", "I2S IN"},
+
+
+
+ {"DAC SRC MUX", "FROM SDP IN", "DAC SDP SRC MUX"},
+ {"DAC SRC MUX", "FROM EQUALIZER", "EQUALIZER MUX"},
+
+ {"MONO DAC", NULL, "DAC SRC MUX"},
+
+ {"ANALOG INPUT MUX", "LIN1", "LIN1"},
+ {"ANALOG INPUT MUX", "LIN2", "LIN2"},
+ {"ANALOG INPUT MUX", "DIFF OUT1", "DIFFERENTIAL MUX"},
+ {"ANALOG INPUT MUX", "DIFF OUT2", "DIFFERENTIAL PGA"},
+ {"ANALOG INPUT MUX", "PGA OUT1", "LINE PGA"},
+ {"ANALOG INPUT MUX", "PGA OUT2", "LINE PGA"},
+
+
+ {"MONO MIXER", "LIN TO MONO OUT Switch", "ANALOG INPUT MUX"},
+ {"MONO MIXER", "DAC TO MONO OUT Switch", "MONO DAC"},
+
+ {"SPEAKER MIXER", "LIN TO SPEAKER OUT Switch", "ANALOG INPUT MUX"},
+ {"SPEAKER MIXER", "DAC TO SPEAKER OUT Switch", "MONO DAC"},
+
+
+ {"MOUT", NULL, "MONO MIXER"},
+ {"SPKOUT", NULL, "SPEAKER MIXER"},
+
+};
+
+#if 0
+static int es8374_set_pll(struct snd_soc_dai *dai, int pll_id,
+ int source, unsigned int freq_in, unsigned int freq_out)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct es8374_private *priv = snd_soc_codec_get_drvdata(codec);
+ u16 reg;
+ u8 N, K1, K2, K3;
+ float tmp;
+ u32 Kcoefficient;
+ switch (pll_id) {
+ case ES8374_PLL:
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ /* Disable PLL */
+ // pll hold in reset state
+ snd_soc_update_bits(codec, ES8374_PLL_CONTROL1_REG09,
+ 0x40, 0x00);
+
+ if (!freq_in || !freq_out)
+ return 0;
+
+ switch (source) {
+
+ case ES8374_PLL_SRC_FRM_MCLK:
+ // Select PLL
+ snd_soc_update_bits(codec, ES8374_CLK_MANAGEMENT_REG02,
+ 0x08, 0x08);
+ break;
+ default:
+ //Disable PLL
+ snd_soc_update_bits(codec, ES8374_CLK_MANAGEMENT_REG02,
+ 0x08, 0x00);
+ return -EINVAL;
+ }
+ /*get N & K */
+ tmp = 0;
+ if (source == ES8374_PLL_SRC_FRM_MCLK) {
+ if(freq_in >19200000)
+ {
+ freq_in /= 2;
+ snd_soc_update_bits(codec, ES8374_CLK_MANAGEMENT_REG01,
+ 0x80, 0x80); /* mclk div2 = 1 */
+ }
+ tmp = (float)freq_out * (float)priv->pll_div + 4000;
+ tmp /= (float)freq_in;
+ N = (u8)tmp;
+ tmp = tmp - (float)N;
+ tmp = tmp * 0.6573598222296 * (1<<22);
+ Kcoefficient = (u32)tmp;
+ K1 = Kcoefficient / 65536;
+ Kcoefficient = Kcoefficient - K1 * 65536;
+ K2 = Kcoefficient /256;
+ K3 = Kcoefficient - K2 * 256;
+ }
+ dev_dbg(codec->dev, "N=%x, K3=%x, K2=%x, K1=%x\n", N, K3, K2, K1);
+
+ reg = snd_soc_read(codec, ES8374_PLL_N_REG0B);
+ reg &= 0xF0;
+ reg |= (N & 0x0F);
+ snd_soc_write(codec, ES8374_PLL_N_REG0B, reg);
+
+ K1 &= 0x3F;
+ snd_soc_write(codec, ES8374_PLL_K_REG0C, K1);
+ snd_soc_write(codec, ES8374_PLL_K_REG0D, K2);
+ snd_soc_write(codec, ES8374_PLL_K_REG0E, K3);
+
+
+ /* pll div 8 */
+ reg = snd_soc_read(codec, ES8374_PLL_CONTROL1_REG09);
+ reg &= 0xfc;
+ reg |= 0x01;
+ snd_soc_write(codec, ES8374_PLL_CONTROL1_REG09, reg);
+
+ /* configure the pll power voltage */
+ switch (priv->dvdd_pwr_vol) {
+ case 0x18:
+ snd_soc_update_bits(codec, ES8374_PLL_CONTROL2_REG0A, 0x0c, 0x00); /* dvdd=1.8v */
+ break;
+ case 0x25:
+ snd_soc_update_bits(codec, ES8374_PLL_CONTROL2_REG0A, 0x0c, 0x04); /* dvdd=2.5v */
+ break;
+ case 0x33:
+ snd_soc_update_bits(codec, ES8374_PLL_CONTROL2_REG0A, 0x0c, 0x08); /* dvdd=3.3v */
+ break;
+ default:
+ snd_soc_update_bits(codec, ES8374_PLL_CONTROL2_REG0A, 0x0c, 0x00); /* dvdd=1.8v */
+ break;
+ }
+ /* enable PLL */
+ snd_soc_update_bits(codec, ES8374_PLL_CONTROL1_REG09,
+ 0x40, 0x40);
+ priv->mclk = freq_out;
+ return 0;
+}
+#endif
+
+struct _coeff_div {
+ u32 mclk; /* mclk frequency */
+ u32 rate; /* sample rate */
+ u8 div; /* adcclk and dacclk divider */
+ u8 fsmode; /* adcclk and dacclk divider */
+ u8 divdouble; /* adcclk and dacclk divider */
+ u8 lrck_h; /* adclrck divider and daclrck divider */
+ u8 lrck_l;
+ u8 sr; /* sclk divider */
+ u8 osr; /* adc osr */
+};
+
+
+/* codec hifi mclk clock divider coefficients */
+static const struct _coeff_div coeff_div[] = {
+
+// MCLK , LRCK,DIV,FSMODE,divDOUBLE,LRCK-H,LRCK-L,BCLK,OSR
+ /*
+ //12M288
+ {12288000, 96000 , 1 , 1 , 0 , 0x00 , 0x80 , 2 , 32},
+ {12288000, 64000 , 3 , 1 , 1 , 0x00 , 0xC0 , 2 , 32},
+ {12288000, 48000 , 1 , 0 , 0 , 0x01 , 0x00 , 2 , 32},
+ {12288000, 32000 , 3 , 0 , 1 , 0x01 , 0x80 , 2 , 32},
+ {12288000, 24000 , 2 , 0 , 0 , 0x02 , 0x00 , 2 , 32},
+ {12288000, 16000 , 3 , 0 , 0 , 0x03 , 0x00 , 2 , 32},
+ {12288000, 12000 , 4 , 0 , 0 , 0x04 , 0x00 , 2 , 32},
+ {12288000, 8000 , 6 , 0 , 0 , 0x06 , 0x00 , 2 , 32},
+
+ // 12M
+ {12000000, 96000 , 1 , 1 , 0 , 0x00 , 0x7D , 2 , 31},
+ {12000000, 88200 , 1 , 1 , 0 , 0x00 , 0x88 , 2 , 34},
+ {12000000, 48000 , 5 , 1 , 1 , 0x00 , 0xFA , 2 , 25},
+ {12000000, 44100 , 1 , 0 , 0 , 0x01 , 0x10 , 2 , 34},
+ {12000000, 32000 , 3 , 1 , 0 , 0x01 , 0x77 , 2 , 31},
+ {12000000, 24000 , 5 , 1 , 0 , 0x02 , 0x00 , 2 , 25},
+ {12000000, 22050 , 2 , 0 , 0 , 0x02 , 0x20 , 2 , 34},
+ {12000000, 16000 , 15, 1 , 1 , 0x02 , 0xEE , 2 , 25},
+ {12000000, 12000 , 5 , 0 , 0 , 0x03 , 0xE8 , 2 , 25},
+ {12000000, 11025 , 4 , 0 , 0 , 0x04 , 0x40 , 2 , 34},
+ {12000000, 8000 , 15, 0 , 1 , 0x05 , 0xDC , 2 , 25},
+
+ //11M2896
+ {11289600, 88200 , 1 , 1 , 0 , 0x00 , 0x80 , 2 , 32},
+ {11289600, 44100 , 1 , 0 , 0 , 0x01 , 0x00 , 2 , 32},
+ {11289600, 22050 , 2 , 0 , 0 , 0x02 , 0x00 , 2 , 32},
+ {11289600, 11025 , 4 , 0 , 0 , 0x04 , 0x00 , 2 , 32},
+
+*/
+
+ /* 8k */
+ {12288000, 8000 , 6 , 0 , 0 , 0x06 , 0x00 , 2 , 32},
+ {12000000, 8000 , 15, 0 , 1 , 0x05 , 0xDC , 2 , 25},
+ {11289600, 8000 , 6 , 0 , 0 , 0x05, 0x83, 20, 29},
+ {18432000, 8000 , 9 , 0 , 0 , 0x09, 0x00, 27, 32},
+ {16934400, 8000 , 8 , 0 , 0 , 0x08, 0x44, 25, 33},
+ {12000000, 8000 , 7 , 0 , 0 , 0x05, 0xdc, 21, 25},
+ {19200000, 8000 , 12, 0 , 0 , 0x09, 0x60, 27, 25},
+
+ /* 11.025k */
+ {11289600, 11025 , 4 , 0 , 0 , 0x04 , 0x00 , 2 , 32},
+ {12000000, 11025 , 4 , 0 , 0 , 0x04 , 0x40 , 2 , 34},
+ {16934400, 11025, 6 , 0 , 0 , 0x06, 0x00, 21, 32},
+
+
+ /* 12k */
+ {12000000, 12000 , 5 , 0 , 0 , 0x03 , 0xE8 , 2 , 25},
+ {12288000, 12000 , 4 , 0 , 0 , 0x04 , 0x00 , 2 , 32},
+
+ /* 16k */
+ {12288000, 16000 , 3 , 0 , 0 , 0x03 , 0x00 , 2 , 32},
+ {18432000, 16000, 5 , 0 , 0 , 0x04, 0x80, 18, 25},
+ {12000000, 16000 , 15, 1 , 1 , 0x02 , 0xEE , 2 , 25},
+ {19200000, 16000, 6 , 0 , 0 , 0x04, 0xb0, 18, 25},
+
+ /* 22.05k */
+ {11289600, 22050 , 2 , 0 , 0 , 0x02 , 0x00 , 2 , 32},
+ {16934400, 22050, 3 , 0 , 0 , 0x03, 0x00, 12, 32},
+ {12000000, 22050 , 2 , 0 , 0 , 0x02 , 0x20 , 2 , 34},
+
+ /* 24k */
+ {12000000, 24000 , 5 , 1 , 0 , 0x02 , 0x00 , 2 , 25},
+ {12288000, 24000 , 2 , 0 , 0 , 0x02 , 0x00 , 2 , 32},
+
+ /* 32k */
+ {12288000, 32000 , 3 , 0 , 1 , 0x01 , 0x80 , 2 , 32},
+ {18432000, 32000, 2 , 0 , 0 , 0x02, 0x40, 9 , 32},
+ {12000000, 32000 , 3 , 1 , 0 , 0x01 , 0x77 , 2 , 31},
+ {19200000, 32000, 3 , 0 , 0 , 0x02, 0x58, 10, 25},
+
+ /* 44.1k */
+ {11289600, 44100 , 1 , 0 , 0 , 0x01 , 0x00 , 2 , 32},
+ {16934400, 44100, 1 , 0 , 0 , 0x01, 0x80, 6 , 32},
+ {12000000, 44100 , 1 , 0 , 0 , 0x01 , 0x10 , 2 , 34},
+
+ /* 48k */
+ {12288000, 48000 , 1 , 0 , 0 , 0x01 , 0x00 , 2 , 32},
+ {18432000, 48000, 1 , 0 , 0 , 0x01, 0x80, 6 , 32},
+ {12000000, 48000 , 5 , 1 , 1 , 0x00 , 0xFA , 2 , 25},
+ {19200000, 48000, 2 , 0 , 0 , 0x01, 0x90, 6, 25},
+
+ /* 64k */
+ {12288000, 64000 , 3 , 1 , 1 , 0x00 , 0xC0 , 2 , 32},
+
+ /* 88.2k */
+ {11289600, 88200 , 1 , 1 , 0 , 0x00 , 0x80 , 2 , 32},
+ {16934400, 88200, 1 , 0 , 0 , 0x00, 0xc0, 3 , 48},
+ {12000000, 88200 , 1 , 1 , 0 , 0x00 , 0x88 , 2 , 34},
+
+ /* 96k */
+ {12288000, 96000 , 1 , 1 , 0 , 0x00 , 0x80 , 2 , 32},
+ {18432000, 96000, 1 , 0 , 0 , 0x00, 0xc0, 3 , 48},
+ {12000000, 96000 , 1 , 1 , 0 , 0x00 , 0x7D , 2 , 31},
+ {19200000, 96000, 1 , 0 , 0 , 0x00, 0xc8, 3 , 25},
+};
+static inline int get_coeff(int mclk, int rate)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
+ if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
+ return i;
+ }
+
+ return -EINVAL;
+}
+
+/* The set of rates we can generate from the above for each SYSCLK */
+#if 0
+static unsigned int rates_12288[] = {
+ 8000, 12000, 16000, 24000, 24000, 32000, 48000, 96000,
+};
+
+static struct snd_pcm_hw_constraint_list constraints_12288 = {
+ .count = ARRAY_SIZE(rates_12288),
+ .list = rates_12288,
+};
+
+static unsigned int rates_112896[] = {
+ 8000, 11025, 22050, 44100,
+};
+
+static struct snd_pcm_hw_constraint_list constraints_112896 = {
+ .count = ARRAY_SIZE(rates_112896),
+ .list = rates_112896,
+};
+
+static unsigned int rates_12[] = {
+ 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
+ 48000, 88235, 96000,
+};
+
+static struct snd_pcm_hw_constraint_list constraints_12 = {
+ .count = ARRAY_SIZE(rates_12),
+ .list = rates_12,
+};
+#endif
+
+/*
+ * if PLL not be used, use internal clk1 for mclk,otherwise, use internal clk2 for PLL source.
+ */
+static int es8374_set_dai_sysclk(struct snd_soc_dai *dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = dai->codec;
+
+ if (clk_id == ES8374_CLKID_MCLK) {
+ snd_soc_write(codec,0x09,0x80); //pll set:reset on ,set start
+ snd_soc_write(codec,0x0C,0x00); //pll set:k
+ snd_soc_write(codec,0x0D,0x00); //pll set:k
+ snd_soc_write(codec,0x0E,0x00); //pll set:k
+
+ }
+
+ return 0;
+}
+
+static int es8374_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u8 iface = 0;
+ u8 adciface = 0;
+ u8 daciface = 0;
+
+ iface = snd_soc_read(codec, ES8374_MS_BCKDIV_REG0F);
+ adciface = snd_soc_read(codec, ES8374_ADC_FMT_REG10);
+ daciface = snd_soc_read(codec, ES8374_DAC_FMT_REG11);
+
+ /* set master/slave audio interface */
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM: /* MASTER MODE */
+ iface |= 0x80;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS: /* SLAVE MODE */
+ iface &= 0x7F;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+
+ /* interface format */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ adciface &= 0xFC;
+ daciface &= 0xFC;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ return -EINVAL;
+ case SND_SOC_DAIFMT_LEFT_J:
+ adciface &= 0xFC;
+ daciface &= 0xFC;
+ adciface |= 0x01;
+ daciface |= 0x01;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ adciface &= 0xDC;
+ daciface &= 0xDC;
+ adciface |= 0x03;
+ daciface |= 0x03;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ adciface &= 0xDC;
+ daciface &= 0xDC;
+ adciface |= 0x23;
+ daciface |= 0x23;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+
+ /* clock inversion */
+ if(((fmt & SND_SOC_DAIFMT_FORMAT_MASK)==SND_SOC_DAIFMT_I2S) ||
+ ((fmt & SND_SOC_DAIFMT_FORMAT_MASK)==SND_SOC_DAIFMT_LEFT_J))
+ {
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+
+ iface &= 0xDF;
+ adciface &= 0xDF;
+ daciface &= 0xDF;
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ iface |= 0x20;
+ adciface |= 0x20;
+ daciface |= 0x20;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ iface |= 0x20;
+ adciface &= 0xDF;
+ daciface &= 0xDF;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ iface &= 0xDF;
+ adciface |= 0x20;
+ daciface |= 0x20;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+ snd_soc_write(codec, ES8374_MS_BCKDIV_REG0F, iface);
+ snd_soc_write(codec, ES8374_ADC_FMT_REG10, adciface);
+ snd_soc_write(codec, ES8374_DAC_FMT_REG11, daciface);
+ return 0;
+}
+static int es8374_pcm_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ return 0;
+}
+
+static int es8374_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ struct es8374_private *es8374 = snd_soc_codec_get_drvdata(codec);
+ u16 iface;
+
+ if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ iface = snd_soc_read(codec, ES8374_DAC_FMT_REG11) & 0xE3;
+ /* bit size */
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ iface |= 0x0c;
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ iface |= 0x04;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ iface |= 0x10;
+ break;
+ }
+ /* set iface & srate */
+ snd_soc_write(codec, ES8374_DAC_FMT_REG11, iface);
+ /*set speak and mono for playback*/
+ snd_soc_write(codec, ES8374_MONO_MIX_REG1A, 0xA0);
+ snd_soc_write(codec, ES8374_SPK_MIX_REG1C, 0x90);
+
+ } else {
+ iface = snd_soc_read(codec, ES8374_ADC_FMT_REG10) & 0xE3;
+ /* bit size */
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ iface |= 0x0c;
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ iface |= 0x04;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ iface |= 0x10;
+ break;
+ }
+ /* set iface */
+ snd_soc_write(codec, ES8374_ADC_FMT_REG10, iface);
+ }
+
+ if(es8374->dmic_enable){
+ snd_soc_write(codec, ES8374_ADC_CONTROL_REG24, 0x8A); //6DB & DIMC=H
+ snd_soc_write(codec,0x12,0x40);
+ snd_soc_write(codec,0x13,0x40);
+ snd_soc_write(codec,0x22,0x00);
+ snd_soc_write(codec, 0x26, 0x50);
+ snd_soc_write(codec, 0x28, 0x80);
+
+ } else {
+ snd_soc_write(codec,0x24,0x08); //adc set
+ snd_soc_write(codec, ES8374_GPIO_INSERT_REG6D, 0x1F); //set gpio1 to GM SHORT
+ }
+
+/*
+* please add the hardware clock divider setting to get the correct LRCK, SCLK frequency
+*/
+ return 0;
+}
+
+static int es8374_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ snd_soc_write(codec, ES8374_CLK_MANAGEMENT_REG01, 0x7f);
+ snd_soc_write(codec, ES8374_ANA_REF_REG14, 0x8a);
+ snd_soc_write(codec, ES8374_ANA_PWR_CTL_REG15, 0x40);
+ snd_soc_update_bits(codec, ES8374_AIN_PWR_SRC_REG21, 0xc0, 0x00);
+ snd_soc_write(codec, ES8374_MONO_MIX_REG1A, 0xa0);
+ snd_soc_write(codec, ES8374_SPK_MIX_REG1C, 0x90);
+ snd_soc_write(codec, ES8374_SPK_MIX_GAIN_REG1D, 0x02);
+ snd_soc_write(codec, ES8374_SPK_OUT_GAIN_REG1E, 0xa0);
+ snd_soc_write(codec, ES8374_DAC_CONTROL_REG36, 0x00);
+ snd_soc_write(codec, ES8374_DAC_CONTROL_REG37, 0x00);
+ snd_soc_write(codec, ES8374_DAC_VOLUME_REG38, 0x00);
+ snd_soc_write(codec, ES8374_ADC_VOLUME_REG25, 0x00);
+ snd_soc_write(codec, ES8374_AIN_PGA_REG22, 0x06);
+
+ break;
+
+ case SND_SOC_BIAS_PREPARE:
+ break;
+
+ case SND_SOC_BIAS_STANDBY:
+ snd_soc_update_bits(codec, ES8374_AIN_PWR_SRC_REG21, 0xc0, 0xc0);
+ break;
+
+ case SND_SOC_BIAS_OFF:
+ snd_soc_update_bits(codec, ES8374_AIN_PWR_SRC_REG21, 0xc0, 0xc0);
+ snd_soc_write(codec, ES8374_ALC_LVL_HLD_REG28, 0x1c);
+ snd_soc_update_bits(codec, ES8374_AIN_PWR_SRC_REG21, 0xc0, 0x00);
+ snd_soc_write(codec, ES8374_ANA_PWR_CTL_REG15, 0xbf);
+ snd_soc_write(codec, ES8374_ANA_REF_REG14, 0x14);
+ snd_soc_write(codec, ES8374_CLK_MANAGEMENT_REG01, 0x03);
+ snd_soc_write(codec, ES8374_AIN_PGA_REG22, 0x00);
+ break;
+ }
+
+ codec->dapm.bias_level = level;
+
+ return 0;
+}
+
+/*
+static int es8374_set_tristate(struct snd_soc_dai *dai, int tristate)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ dev_dbg(codec->dev, "es8374_set_tristate........\n");
+ if(tristate) {
+ snd_soc_update_bits(codec, ES8374_MS_BCKDIV_REG0F,
+ 0x40, 0x40);
+ } else {
+ snd_soc_update_bits(codec, ES8374_MS_BCKDIV_REG0F,
+ 0x40, 0x00);
+ }
+
+ return 0;
+}
+*/
+
+static int es8374_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec = dai->codec;
+
+ dev_dbg(codec->dev, "%s %d\n", __func__, mute);
+ if (mute) {
+ snd_soc_update_bits(codec, ES8374_DAC_CONTROL_REG36, 0x20, 0x20);
+ } else {
+ if (dai->playback_active)
+ snd_soc_update_bits(codec, ES8374_DAC_CONTROL_REG36, 0x20, 0x00);
+ }
+ return 0;
+}
+
+
+#define es8374_RATES SNDRV_PCM_RATE_8000_96000
+
+#define es8374_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
+ SNDRV_PCM_FMTBIT_S24_LE)
+
+static struct snd_soc_dai_ops es8374_ops = {
+ .startup = es8374_pcm_startup,
+ .hw_params = es8374_pcm_hw_params,
+ .set_fmt = es8374_set_dai_fmt,
+ .set_sysclk = es8374_set_dai_sysclk,
+ .digital_mute = es8374_mute,
+};
+
+static struct snd_soc_dai_driver es8374_dai[] = {
+ { .name = "ES8374 HiFi",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = es8374_RATES,
+ .formats = es8374_FORMATS,
+ },
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = es8374_RATES,
+ .formats = es8374_FORMATS,
+ },
+ .ops = &es8374_ops,
+ .symmetric_rates = 1,
+ },
+};
+
+static int es8374_suspend(struct snd_soc_codec *codec)
+{
+ struct es8374_private *es8374 = snd_soc_codec_get_drvdata(codec);
+ int i;
+
+ for(i = 0; i <= 110; i++) {
+ es8374->reg_cache[i] = snd_soc_read(codec, i);
+ }
+
+ snd_soc_write(codec, ES8374_DAC_VOLUME_REG38, 0xc0);
+ snd_soc_write(codec, ES8374_ADC_VOLUME_REG25, 0xc0);
+ snd_soc_write(codec, ES8374_DAC_CONTROL_REG36, 0x20);
+ snd_soc_write(codec, ES8374_DAC_CONTROL_REG37, 0x21);
+ snd_soc_write(codec, ES8374_MONO_MIX_REG1A, 0x08);
+ snd_soc_write(codec, ES8374_SPK_MIX_REG1C, 0x10);
+ snd_soc_write(codec, ES8374_SPK_MIX_GAIN_REG1D, 0x10);
+ snd_soc_write(codec, ES8374_SPK_OUT_GAIN_REG1E, 0x40);
+ snd_soc_update_bits(codec, ES8374_AIN_PWR_SRC_REG21, 0xc0, 0x00);
+ snd_soc_write(codec, ES8374_ANA_PWR_CTL_REG15, 0xbf);
+ snd_soc_write(codec, ES8374_ANA_REF_REG14, 0x14);
+ snd_soc_write(codec, ES8374_CLK_MANAGEMENT_REG01, 0x03);
+
+ return 0;
+}
+
+static int es8374_resume(struct snd_soc_codec *codec)
+{
+ struct es8374_private *es8374 = snd_soc_codec_get_drvdata(codec);
+ int i;
+#if 0
+ snd_soc_write(codec, ES8374_CLK_MANAGEMENT_REG01, 0x7f);
+ snd_soc_write(codec, ES8374_ANA_REF_REG14, 0x8a);
+ snd_soc_write(codec, ES8374_ANA_PWR_CTL_REG15, 0x40);
+ snd_soc_update_bits(codec, ES8374_AIN_PWR_SRC_REG21, 0xc0, 0x50);
+ snd_soc_write(codec, ES8374_MONO_MIX_REG1A, 0xa0);
+ snd_soc_write(codec, ES8374_SPK_MIX_REG1C, 0x90);
+ snd_soc_write(codec, ES8374_SPK_MIX_GAIN_REG1D, 0x02);
+ snd_soc_write(codec, ES8374_SPK_OUT_GAIN_REG1E, 0xa0);
+ snd_soc_write(codec, ES8374_DAC_CONTROL_REG36, 0x00);
+ snd_soc_write(codec, ES8374_DAC_CONTROL_REG37, 0x00);
+ snd_soc_write(codec, ES8374_DAC_VOLUME_REG38, 0x00);
+ snd_soc_write(codec, ES8374_ADC_VOLUME_REG25, 0x00);
+#endif
+
+ for(i = 0; i <= 110; i++) {
+ snd_soc_write(codec, i, es8374->reg_cache[i]);
+ }
+
+ return 0;
+}
+
+static int es8374_parse_dts(struct es8374_private *es8374)
+{
+#ifdef CONFIG_OF
+ struct device *dev;
+ struct device_node *np;
+ enum of_gpio_flags flags;
+ int ret, dmic;
+
+ if (es8374->control_type == SND_SOC_I2C) {
+ dev = &(es8374->i2c->dev);
+ } else {
+ dev = &(es8374->spi->dev);
+ }
+
+ np = dev->of_node;
+
+ if (!np)
+ return -1;
+
+ ret = of_property_read_u32(np, "es8374,dmic", &dmic);
+ if(ret == 0 && dmic == 1) {
+ es8374->dmic_enable = 1;
+ } else {
+ es8374->dmic_enable = 0;
+ }
+
+ es8374->pwr_gpio = of_get_named_gpio_flags(np, "es8374,pwr-gpio", 0, &flags);
+ if (es8374->pwr_gpio < 0 || !gpio_is_valid(es8374->pwr_gpio)) {
+ es8374->pwr_gpio = -1;
+ } else {
+ es8374->pwr_active = !!(flags & OF_GPIO_ACTIVE_LOW);
+ }
+
+#endif
+
+ return 0;
+}
+
+static int es8374_probe(struct snd_soc_codec *codec)
+{
+ int ret = 0;
+ struct es8374_private *es8374 = es8374_data;
+
+ codec->control_data = es8374->regmap;
+ ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
+ if (ret < 0)
+ return ret;
+
+ es8374->codec = codec;
+ snd_soc_codec_set_drvdata(codec, es8374);
+
+ es8374_parse_dts(es8374);
+ if (gpio_is_valid(es8374->pwr_gpio)) {
+ ret = devm_gpio_request(codec->dev, es8374->pwr_gpio, "es8374 power pin");
+ if(ret == 0)
+ gpio_direction_output(es8374->pwr_gpio, es8374->pwr_active);
+ }
+
+ snd_soc_write(codec,0x00,0x3F); //IC Rst start
+ msleep(1); //DELAY_MS
+ snd_soc_write(codec,0x00,0x03); //IC Rst stop
+ snd_soc_write(codec,0x01,0x7F); //IC clk on
+ snd_soc_write(codec,0x05,0x11); //clk div set
+ snd_soc_write(codec,0x36,0x00); //dac set
+ snd_soc_write(codec,0x12,0x30); //timming set
+ snd_soc_write(codec,0x13,0x20); //timming set
+ snd_soc_write(codec,0x21,0x50); //adc set: SEL LIN1 CH+PGAGAIN=0DB
+ snd_soc_write(codec,0x22,0xFF); //adc set: PGA GAIN=0DB
+ snd_soc_write(codec,0x21,0x10); //adc set: SEL LIN1 CH+PGAGAIN=0DB
+ snd_soc_write(codec,0x00,0x80); // IC START
+ msleep(50); //DELAY_MS
+ snd_soc_write(codec,0x14,0x8A); // IC START
+ snd_soc_write(codec,0x15,0x40); // IC START
+ snd_soc_write(codec,0x1A,0xA0); // monoout set
+ snd_soc_write(codec,0x1B,0x19); // monoout set
+ snd_soc_write(codec,0x1C,0x90); // spk set
+ snd_soc_write(codec,0x1D,0x02); // spk set
+ snd_soc_write(codec,0x1F,0x00); // spk set
+ snd_soc_write(codec,0x1E,0xA0); // spk on
+ snd_soc_write(codec,0x28,0x00); // alc set
+ snd_soc_write(codec,0x25,0x00); // ADCVOLUME on
+ snd_soc_write(codec,0x38,0x00); // DACVOLUMEL on
+ snd_soc_write(codec,0x37,0x00); // dac set
+ snd_soc_write(codec,0x6D,0x40); //SEL:GPIO1=DMIC CLK OUT+SEL:GPIO2=PLL CLK OUT
+
+ es8374_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ return ret;
+}
+
+static int es8374_remove(struct snd_soc_codec *codec)
+{
+ es8374_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_es8374 = {
+ .probe = es8374_probe,
+ .remove = es8374_remove,
+ .suspend = es8374_suspend,
+ .resume = es8374_resume,
+ .set_bias_level = es8374_set_bias_level,
+
+ .controls = es8374_snd_controls,
+ .num_controls = ARRAY_SIZE(es8374_snd_controls),
+ .dapm_widgets = es8374_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(es8374_dapm_widgets),
+ .dapm_routes = es8374_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(es8374_dapm_routes),
+};
+
+static struct regmap_config es8374_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .max_register = ES8374_MAX_REGISTER,
+ .reg_defaults = es8374_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(es8374_reg_defaults),
+ .volatile_reg = es8374_volatile_register,
+ .writeable_reg = es8374_writable_register,
+ .readable_reg = es8374_readable_register,
+ .cache_type = REGCACHE_RBTREE,
+};
+
+#ifdef CONFIG_OF
+static struct of_device_id es8374_if_dt_ids[] = {
+ { .compatible = "ambarella,es8374", },
+ { }
+};
+#endif
+
+#if defined(ES8374_SPI)
+static int es8374_spi_probe(struct spi_device *spi)
+{
+ struct es8374_private *es8374;
+ int ret;
+
+ es8374 = kzalloc(sizeof(struct es8374_private), GFP_KERNEL);
+ if (es8374 == NULL)
+ return -ENOMEM;
+
+ es8374->control_type = SND_SOC_SPI;
+ es8374->spi = spi;
+
+ spi_set_drvdata(spi, es8374);
+
+ es8374->regmap = devm_regmap_init_spi(spi, &es8374_regmap);
+ if (IS_ERR(es8374->regmap)) {
+ ret = PTR_ERR(es8374->regmap);
+ dev_err(&spi->dev, "regmap_init() failed: %d\n", ret);
+ return ret;
+ }
+
+ es8374_data = es8374;
+
+ ret = snd_soc_register_codec(&spi->dev,
+ &soc_codec_dev_es8374, &es8374_dai, 1);
+ if (ret < 0)
+ kfree(es8374);
+ return ret;
+}
+
+static int es8374_spi_remove(struct spi_device *spi)
+{
+ snd_soc_unregister_codec(&spi->dev);
+ kfree(spi_get_drvdata(spi));
+ return 0;
+}
+
+static struct spi_driver es8374_spi_driver = {
+ .driver = {
+ .name = "es8374",
+ .owner = THIS_MODULE,
+#ifdef CONFIG_OF
+ .of_match_table = of_match_ptr(es8374_if_dt_ids),
+#endif
+ },
+ .probe = es8374_spi_probe,
+ .remove = es8374_spi_remove,
+};
+#endif /* CONFIG_SPI_MASTER */
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static void es8374_i2c_shutdown(struct i2c_client *i2c)
+{
+ struct snd_soc_codec *codec;
+ struct es8374_private *es8374;
+
+ es8374 = i2c_get_clientdata(i2c);
+ codec = es8374->codec;
+
+ snd_soc_write(codec, ES8374_DAC_VOLUME_REG38, 0xc0);
+ snd_soc_write(codec, ES8374_ADC_VOLUME_REG25, 0xc0);
+ snd_soc_write(codec, ES8374_DAC_CONTROL_REG36, 0x20);
+ snd_soc_write(codec, ES8374_DAC_CONTROL_REG37, 0x21);
+ snd_soc_write(codec, ES8374_MONO_MIX_REG1A, 0x08);
+ snd_soc_write(codec, ES8374_SPK_MIX_REG1C, 0x10);
+ snd_soc_write(codec, ES8374_SPK_MIX_GAIN_REG1D, 0x10);
+ snd_soc_write(codec, ES8374_SPK_OUT_GAIN_REG1E, 0x40);
+ snd_soc_update_bits(codec, ES8374_AIN_PWR_SRC_REG21, 0xc0, 0xc0);
+ snd_soc_write(codec, ES8374_ANA_PWR_CTL_REG15, 0xbf);
+ snd_soc_write(codec, ES8374_ANA_REF_REG14, 0x14);
+ snd_soc_write(codec, ES8374_CLK_MANAGEMENT_REG01, 0x03);
+
+ return;
+}
+
+static int es8374_i2c_probe(struct i2c_client *i2c_client,
+ const struct i2c_device_id *id)
+{
+ struct es8374_private *es8374;
+ int ret = -1;
+
+ es8374 = kzalloc(sizeof(*es8374), GFP_KERNEL);
+ if (es8374 == NULL)
+ return -ENOMEM;
+
+ es8374->control_type = SND_SOC_I2C;
+ es8374->i2c = i2c_client;
+
+ i2c_set_clientdata(i2c_client, es8374);
+ es8374->regmap = devm_regmap_init_i2c(i2c_client, &es8374_regmap);
+ if (IS_ERR(es8374->regmap)) {
+ ret = PTR_ERR(es8374->regmap);
+ dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
+ return ret;
+ }
+
+ es8374_data = es8374;
+
+ ret = snd_soc_register_codec(&i2c_client->dev, &soc_codec_dev_es8374,
+ &es8374_dai[0], ARRAY_SIZE(es8374_dai));
+ if (ret < 0) {
+ kfree(es8374);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int es8374_i2c_remove(struct i2c_client *client)
+{
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
+ return 0;
+}
+
+static const struct i2c_device_id es8374_i2c_id[] = {
+ {"es8374", 0 },
+ {"10ES8374:00", 0},
+ {"10ES8374", 0},
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, es8374_i2c_id);
+
+static struct i2c_driver es8374_i2c_driver = {
+ .driver = {
+ .name = "es8374",
+ .owner = THIS_MODULE,
+#ifdef CONFIG_OF
+ .of_match_table = of_match_ptr(es8374_if_dt_ids),
+#endif
+ },
+ .shutdown = es8374_i2c_shutdown,
+ .probe = es8374_i2c_probe,
+ .remove = es8374_i2c_remove,
+ .id_table = es8374_i2c_id,
+};
+#endif
+
+static int __init es8374_init(void)
+{
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ return i2c_add_driver(&es8374_i2c_driver);
+#endif
+#ifdef ES8374_SPI
+ return spi_register_driver(&es8374_spi_driver);
+#endif
+}
+
+static void __exit es8374_exit(void)
+{
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ return i2c_del_driver(&es8374_i2c_driver);
+#endif
+#ifdef ES8374_SPI
+ return spi_unregister_driver(&es8374_spi_driver);
+#endif
+}
+
+module_init(es8374_init);
+module_exit(es8374_exit);
+
+MODULE_DESCRIPTION("ASoC es8374 driver");
+MODULE_AUTHOR("XianqingZheng <xqzheng@ambarella.com>");
+MODULE_LICENSE("GPL");
+
diff --git a/sound/soc/codecs/es8374.h b/sound/soc/codecs/es8374.h
new file mode 100644
index 00000000..0d427004
--- /dev/null
+++ b/sound/soc/codecs/es8374.h
@@ -0,0 +1,151 @@
+/*
+* ES8374.h -- ES8374 ALSA SoC Audio Codec
+*
+*
+*
+* Authors:
+*
+* Based on ES8374.h by David Yang
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*/
+
+#ifndef _ES8374_H
+#define _ES8374_H
+
+/* THE REGISTER DEFINITION FORMAT */
+/*
+* ES8374_REGISTER NAME_REG_REGISTER ADDRESS
+*/
+#define ES8374_RESET_REG00 0x00 /* this register is used to reset digital,csm,clock manager etc.*/
+
+/*
+* Clock Scheme Register definition
+*/
+#define ES8374_CLK_MANAGEMENT_REG01 0x01 /* The register is used to turn on/off the clock for ADC, DAC, MCLK, BCLK and CLASS D */
+#define ES8374_CLK_MANAGEMENT_REG02 0x02 /* ADC, PLL clock */
+
+
+#define ES8374_ADC_OSR_REG03 0x03 /* The ADC OSR setting */
+#define ES8374_DAC_FLT_CNT_REG04 0x04 /* The DAC filter counter waiting cycles control */
+#define ES8374_CLK_DIV_REG05 0x05 /* ADC&DAC internal mclk Divider */
+#define ES8374_LRCK_DIV_REG06 0x06 /* The LRCK divider */
+#define ES8374_LRCK_DIV_REG07 0x07
+#define ES8374_CLASS_D_DIV_REG08 0x08 /* Class D clock divider */
+/*
+* PLL control register definition
+*/
+#define ES8374_PLL_CONTROL1_REG09 0x09 /* Register 0x09 for PLL reset, power up/down, dither and divider settting */
+#define ES8374_PLL_CONTROL2_REG0A 0x0A /* Register 0x0A for PLL low power, gain, supply voltage and vco setting */
+#define ES8374_PLL_N_REG0B 0x0B /* Register 0x0B for N and pll calibrate */
+#define ES8374_PLL_K_REG0C 0x0C /* Register 0x0C - 0x0E for PLLK */
+#define ES8374_PLL_K_REG0D 0x0D
+#define ES8374_PLL_K_REG0E 0x0E
+/*
+* The serial digital audio port
+*/
+#define ES8374_MS_BCKDIV_REG0F 0x0F /* The setting for Master/Slave mode and BCLK divider */
+#define ES8374_ADC_FMT_REG10 0x10 /* ADC Format */
+#define ES8374_DAC_FMT_REG11 0x11 /* DAC Format */
+
+/*
+* The system Control
+*/
+#define ES8374_CHP_INI_REG12 0x12 /* The time control for chip initialization */
+#define ES8374_POWERUP_REG13 0x13 /* The time control for power up */
+/*
+* The analog control
+*/
+#define ES8374_ANA_REF_REG14 0x14 /* The analog reference */
+#define ES8374_ANA_PWR_CTL_REG15 0x15 /* The analog power up/down */
+#define ES8374_ANA_LOW_PWR_REG16 0x16 /* Low power setting*/
+#define ES8374_ANA_REF_LP_REG17 0x17 /* Reference and low power setting */
+#define ES8374_ANA_BIAS_REG18 0x18 /* Bias selecting */
+/*
+* MONO OUT
+*/
+#define ES8374_MONO_MIX_REG1A 0x1A /* MonoMixer */
+#define ES8374_MONO_GAIN_REG1B 0x1B /* Mono Out Gain */
+/*
+* SPEAKER OUT
+*/
+#define ES8374_SPK_MIX_REG1C 0x1C /* Speaker Mixer */
+#define ES8374_SPK_MIX_GAIN_REG1D 0x1D /* Speaker Mixer Gain */
+#define ES8374_SPK_OUT_GAIN_REG1E 0x1E /* Speaker Output Gain */
+#define ES8374_SPK_CTL_REG1F 0x1F /* Speaker control */
+#define ES8374_SPK_CTL_REG20 0x20 /* Speaker control */
+/*
+* Analog In
+*/
+#define ES8374_AIN_PWR_SRC_REG21 0x21 /* Power control and source selecting for AIN*/
+#define ES8374_AIN_PGA_REG22 0x22 /* AIN PGA Gain Control */
+/*
+* ADC Control
+*/
+#define ES8374_ADC_CONTROL_REG24 0x24 /* adc and DMIC Setting */
+#define ES8374_ADC_VOLUME_REG25 0x25 /* adc volume */
+/*
+* ADC ALC
+*/
+#define ES8374_ALC_EN_MAX_GAIN_REG26 0x26 /* adc alc enable and max gain setting */
+#define ES8374_ALC_MIN_GAIN_REG27 0x27 /* ADC Alc min gain */
+#define ES8374_ALC_LVL_HLD_REG28 0x28 /* alc level and hold time control */
+#define ES8374_ALC_DCY_ATK_REG29 0x29 /* ALC DCY and ATK time control */
+#define ES8374_ALC_WIN_SIZE_REG2A 0x2A /* ALC WIN Size */
+#define ES8374_ALC_NGTH_REG2B 0x2B /* alc noise gate setting */
+/*
+* ADC HPF setting
+*/
+#define ES8374_ADC_HPF_REG2C 0x2C /* The high pass filter coefficient*/
+/*
+* Equalizer SRC setting
+*/
+#define ES8374_EQ_SRC_REG2D 0x2D /* adc src, dac src and EQ SRC setting */
+
+/*
+* ADC 1st shelving filter
+*/
+#define ES8374_ADC_SHV_A_REG2E 0x2E /* adc shelving A*/
+#define ES8374_ADC_SHV_A_REG2F 0x2F
+#define ES8374_ADC_SHV_A_REG30 0x30
+#define ES8374_ADC_SHV_A_REG31 0x31
+
+#define ES8374_ADC_SHV_B_REG32 0x32 /* ADC Shelving B*/
+#define ES8374_ADC_SHV_B_REG33 0x33
+#define ES8374_ADC_SHV_B_REG34 0x34
+#define ES8374_ADC_SHV_B_REG35 0x35
+
+/*
+* DAC control
+*/
+#define ES8374_DAC_CONTROL_REG36 0x36 /* dac control1 */
+#define ES8374_DAC_CONTROL_REG37 0x37 /* dac control2 */
+
+#define ES8374_DAC_VOLUME_REG38 0x38 /* dac volume */
+#define ES8374_DAC_OFFSET_REG39 0x39 /* DAC offset */
+
+/*
+* DAC 2nd shleving filter
+*/
+/* register 0x3A to 0x44 is for dac shelving filter */
+/*
+* Equalizer coeffient
+*/
+/* register 0x45 to 0x6c is for 2nd equalizer filter, this filter can be shared by DAC and ADC */
+
+#define ES8374_GPIO_INSERT_REG6D 0x6D /* GPIO & HP INSERT CONTROL */
+#define ES8374_FLAG_REG6E 0x6E /* Flag register */
+
+/* The End Of Register definition */
+
+#define ES8374_PLL 1
+#define ES8374_PLL_SRC_FRM_MCLK 1
+
+#define ES8374_CLKID_MCLK 0
+#define ES8374_CLKID_PLLO 1
+
+#define ES8374_MAX_REGISTER 128
+
+#endif
diff --git a/sound/soc/codecs/es8388.c b/sound/soc/codecs/es8388.c
new file mode 100644
index 00000000..164141cd
--- /dev/null
+++ b/sound/soc/codecs/es8388.c
@@ -0,0 +1,971 @@
+/*
+ * es8388.c -- ES8388 ALSA Soc Audio driver
+ *
+ * Copyright 2014 Ambarella Ltd.
+ *
+ * Author: Ken He <jianhe@ambarella.com>
+ *
+ * Based on es8328.c from Everest Semiconductor
+ *
+ * History:
+ * 2014/07/01 - [Ken He] Created file
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/of_device.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+#include <linux/regmap.h>
+
+#include "es8388.h"
+
+#define ES8388_VERSION "v1.0"
+
+/* codec private data */
+struct es8388_priv {
+ unsigned int aud_rst_pin;
+ unsigned int aud_rst_active;
+ struct regmap *regmap;
+ unsigned int sysclk;
+};
+
+/*
+ * es8388 register
+ */
+static struct reg_default es8388_reg_defaults[] = {
+ { 0, 0x06 },
+ { 1, 0x1c },
+ { 2, 0xC3 },
+ { 3, 0xFC },
+ { 4, 0xC0 },
+ { 5, 0x00 },
+ { 6, 0x00 },
+ { 7, 0x7C },
+ { 8, 0x80 },
+ { 9, 0x00 },
+ { 10, 0x00 },
+ { 11, 0x06 },
+ { 12, 0x00 },
+ { 13, 0x06 },
+ { 14, 0x30 },
+ { 15, 0x30 },
+ { 16, 0xC0 },
+ { 17, 0xC0 },
+ { 18, 0x38 },
+ { 19, 0xB0 },
+ { 20, 0x32 },
+ { 21, 0x06 },
+ { 22, 0x00 },
+ { 23, 0x00 },
+ { 24, 0x06 },
+ { 25, 0x32 },
+ { 26, 0xC0 },
+ { 27, 0xC0 },
+ { 28, 0x08 },
+ { 29, 0x06 },
+ { 30, 0x1F },
+ { 31, 0xF7 },
+ { 32, 0xFD },
+ { 33, 0xFF },
+ { 34, 0x1F },
+ { 35, 0xF7 },
+ { 36, 0xFD },
+ { 37, 0xFF },
+ { 38, 0x00 },
+ { 39, 0x38 },
+ { 40, 0x38 },
+ { 41, 0x38 },
+ { 42, 0x38 },
+ { 43, 0x38 },
+ { 44, 0x38 },
+ { 45, 0x00 },
+ { 46, 0x00 },
+ { 47, 0x00 },
+ { 48, 0x00 },
+ { 49, 0x00 },
+ { 50, 0x00 },
+ { 51, 0x00 },
+ { 52, 0x00 },
+};
+
+static int spk_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ int i;
+ struct snd_soc_codec *codec = w->codec;
+ struct es8388_priv *es8388 = snd_soc_codec_get_drvdata(codec);
+ //printk("%s %d *****\n", __FUNCTION__, __LINE__);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ gpio_direction_output(es8388->aud_rst_pin, 0);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ //Add speaker amplifier mute control
+ mdelay(100);
+ for( i = 0; i < 0x1d; i++)
+ {
+ snd_soc_write(codec, ES8388_DACCONTROL24, i); //LOUT1/ROUT1 VOLUME
+ snd_soc_write(codec, ES8388_DACCONTROL25, i);
+ snd_soc_write(codec, ES8388_DACCONTROL26, i); //LOUT2/ROUT2 VOLUME
+ snd_soc_write(codec, ES8388_DACCONTROL27, i);
+ mdelay(5);
+ }
+ gpio_direction_output(es8388->aud_rst_pin, 1);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ gpio_direction_output(es8388->aud_rst_pin, 0);
+ snd_soc_write(codec, ES8388_DACPOWER, 0x00);
+ mdelay(100);
+ for( i = 0; i < 0x1d; i++)
+ {
+ snd_soc_write(codec, ES8388_DACCONTROL24, 0x1d-i); //LOUT1/ROUT1 VOLUME
+ snd_soc_write(codec, ES8388_DACCONTROL25, 0x1d-i);
+ snd_soc_write(codec, ES8388_DACCONTROL26, 0x1d-i); //LOUT2/ROUT2 VOLUME
+ snd_soc_write(codec, ES8388_DACCONTROL27, 0x1d-i);
+ mdelay(5);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int adc_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ unsigned int regv;
+ struct snd_soc_codec *codec = w->codec;
+ //printk("%s %d**************** *****\n", __FUNCTION__, __LINE__);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ snd_soc_write(codec, ES8388_ADCPOWER, 0x00);
+ snd_soc_write(codec, ES8388_CHIPPOWER, 0x00);
+ mdelay(100);
+ regv = snd_soc_read(codec, ES8388_ADCCONTROL3);
+ regv &= 0xFB;
+ snd_soc_write(codec, ES8388_ADCCONTROL3, regv);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ regv = snd_soc_read(codec, ES8388_ADCCONTROL3);
+ regv |= 0x4;
+ snd_soc_write(codec, ES8388_ADCCONTROL3, regv);
+ snd_soc_write(codec, ES8388_ADCPOWER, 0xF9);
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+
+/* DAC/ADC Volume: min -96.0dB (0xC0) ~ max 0dB (0x00) ( 0.5 dB step ) */
+static const DECLARE_TLV_DB_SCALE(digital_tlv, -9600, 50, 0);
+/* Analog Out Volume: min -30.0dB (0x00) ~ max 3dB (0x21) ( 1 dB step ) */
+static const DECLARE_TLV_DB_SCALE(out_tlv, -3000, 100, 0);
+/* Analog In Volume: min 0dB (0x00) ~ max 24dB (0x08) ( 3 dB step ) */
+static const DECLARE_TLV_DB_SCALE(in_tlv, 0, 300, 0);
+
+static const struct snd_kcontrol_new es8388_snd_controls[] = {
+ SOC_DOUBLE_R_TLV("Playback Volume",
+ ES8388_LDAC_VOL, ES8388_RDAC_VOL, 0, 0xC0, 1, digital_tlv),
+ SOC_DOUBLE_R_TLV("Analog Out Volume",
+ ES8388_LOUT1_VOL, ES8388_ROUT1_VOL, 0, 0x1D, 0, out_tlv),
+
+ SOC_DOUBLE_R_TLV("Capture Volume",
+ ES8388_LADC_VOL, ES8388_RADC_VOL, 0, 0xC0, 1, digital_tlv),
+ SOC_DOUBLE_TLV("Analog In Volume",
+ ES8388_ADCCONTROL1, 4, 0, 0x08, 0, in_tlv),
+};
+
+/*
+ * DAPM Controls
+ */
+
+/* Channel Input Mixer */
+static const char *es8388_line_texts[] = { "Line 1", "Line 2", "Differential"};
+static const unsigned int es8388_line_values[] = { 0, 1, 3};
+
+static const struct soc_enum es8388_lline_enum =
+ SOC_VALUE_ENUM_SINGLE(ES8388_ADCCONTROL2, 6, 4,
+ ARRAY_SIZE(es8388_line_texts), es8388_line_texts,
+ es8388_line_values);
+static const struct snd_kcontrol_new es8388_left_line_controls =
+ SOC_DAPM_VALUE_ENUM("Route", es8388_lline_enum);
+
+static const struct soc_enum es8388_rline_enum =
+ SOC_VALUE_ENUM_SINGLE(ES8388_ADCCONTROL2, 4, 4,
+ ARRAY_SIZE(es8388_line_texts), es8388_line_texts,
+ es8388_line_values);
+static const struct snd_kcontrol_new es8388_right_line_controls =
+ SOC_DAPM_VALUE_ENUM("Route", es8388_rline_enum);
+
+
+/* Left Mixer */
+static const struct snd_kcontrol_new es8388_left_mixer_controls[] = {
+ SOC_DAPM_SINGLE("Left Playback Switch", ES8388_DACCONTROL17, 7, 1, 0),
+ SOC_DAPM_SINGLE("Left Bypass Switch" , ES8388_DACCONTROL17, 6, 1, 0),
+};
+
+/* Right Mixer */
+static const struct snd_kcontrol_new es8388_right_mixer_controls[] = {
+ SOC_DAPM_SINGLE("Right Playback Switch", ES8388_DACCONTROL20, 7, 1, 0),
+ SOC_DAPM_SINGLE("Right Bypass Switch" , ES8388_DACCONTROL20, 6, 1, 0),
+};
+#if 0
+/* Differential Mux */
+static const char *es8388_diff_sel[] = {"Line 1", "Line 2"};
+static const struct soc_enum diffmux =
+ SOC_ENUM_SINGLE(ES8388_ADCCONTROL3, 7, 2, es8388_diff_sel);
+static const struct snd_kcontrol_new es8388_diffmux_controls =
+ SOC_DAPM_ENUM("Route", diffmux);
+#endif
+/* Mono ADC Mux */
+static const char *es8388_mono_mux[] = {"Stereo", "Mono (Left)", "Mono (Right)", "NONE"};
+static const unsigned int es8388_monomux_values[] = { 0, 1, 2, 3};
+/*static const struct soc_enum monomux =
+ SOC_ENUM_SINGLE(ES8388_ADCCONTROL3, 3, 4, es8388_mono_mux);
+static const struct snd_kcontrol_new es8388_monomux_controls =
+ SOC_DAPM_ENUM("Route", monomux);
+*/
+static const struct soc_enum monomux =
+ SOC_VALUE_ENUM_SINGLE(ES8388_ADCCONTROL3, 3, 4,
+ ARRAY_SIZE(es8388_mono_mux), es8388_mono_mux,
+ es8388_monomux_values);
+static const struct snd_kcontrol_new es8388_monomux_controls =
+ SOC_DAPM_VALUE_ENUM("Route", monomux);
+
+#if 0
+static const struct snd_kcontrol_new adc_switch_ctl =
+SOC_DAPM_SINGLE("Switch",ES8388_ADCCONTROL7, 2, 1, 1);
+#endif
+
+static const struct snd_soc_dapm_widget es8388_dapm_widgets[] = {
+ /* DAC Part */
+ SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
+ &es8388_left_mixer_controls[0], ARRAY_SIZE(es8388_left_mixer_controls)),
+ SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
+ &es8388_right_mixer_controls[0], ARRAY_SIZE(es8388_right_mixer_controls)),
+
+ SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0, &es8388_left_line_controls),
+ SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0, &es8388_right_line_controls),
+
+ SND_SOC_DAPM_DAC("Left DAC" , "Left Playback" , ES8388_DACPOWER, 7, 1),
+ SND_SOC_DAPM_DAC("Right DAC" , "Right Playback", ES8388_DACPOWER, 6, 1),
+ SND_SOC_DAPM_PGA_E("Left Out 1", ES8388_DACPOWER, 5, 0, NULL,
+ 0, spk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_PGA_E("Right Out 1", ES8388_DACPOWER, 4, 0, NULL,
+ 0, spk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
+
+ /* SND_SOC_DAPM_PGA("Left Out 2" , ES8388_DACPOWER, 3, 0, NULL, 0), */
+ /* SND_SOC_DAPM_PGA("Right Out 2", ES8388_DACPOWER, 2, 0, NULL, 0), */
+
+ SND_SOC_DAPM_OUTPUT("LOUT1"),
+ SND_SOC_DAPM_OUTPUT("ROUT1"),
+ SND_SOC_DAPM_OUTPUT("LOUT2"),
+ SND_SOC_DAPM_OUTPUT("ROUT2"),
+
+ /* ADC Part */
+// SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0,
+// &es8388_diffmux_controls),
+
+// SND_SOC_DAPM_MUX("Left Line Mux", ES8388_ADCPOWER, 7, 1, &es8388_left_line_controls),
+// SND_SOC_DAPM_MUX("Right Line Mux", ES8388_ADCPOWER, 6, 1, &es8388_right_line_controls),
+
+ SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0, &es8388_monomux_controls),
+ SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0, &es8388_monomux_controls),
+//SND_SOC_DAPM_MUX("Left ADC Mux", ES8388_ADCPOWER, 7, 1, &es8388_monomux_controls),
+//SND_SOC_DAPM_MUX("Right ADC Mux", ES8388_ADCPOWER, 6, 1, &es8388_monomux_controls),
+ SND_SOC_DAPM_PGA("Left Analog Input" , ES8388_ADCPOWER, 7, 1, NULL, 0),
+ SND_SOC_DAPM_PGA("Right Analog Input", ES8388_ADCPOWER, 6, 1, NULL, 0),
+ SND_SOC_DAPM_ADC_E("Left ADC" , "Left Capture" , ES8388_ADCPOWER, 5, 1,
+ adc_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_ADC_E("Right ADC", "Right Capture", ES8388_ADCPOWER, 4, 1,
+ adc_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MICBIAS("Mic Bias", ES8388_ADCPOWER, 3, 1),
+
+ SND_SOC_DAPM_INPUT("MICIN"),
+ SND_SOC_DAPM_INPUT("LINPUT1"),
+ SND_SOC_DAPM_INPUT("LINPUT2"),
+ SND_SOC_DAPM_INPUT("RINPUT1"),
+ SND_SOC_DAPM_INPUT("RINPUT2"),
+};
+
+static const struct snd_soc_dapm_route audio_map[] = {
+ /* left mixer */
+ {"Left Mixer", "Left Playback Switch", "Left DAC"},
+
+ /* right mixer */
+ {"Right Mixer", "Right Playback Switch", "Right DAC"},
+
+ /* left out 1 */
+ {"Left Out 1", NULL, "Left Mixer"},
+ {"LOUT1", NULL, "Left Out 1"},
+
+ /* right out 1 */
+ {"Right Out 1", NULL, "Right Mixer"},
+ {"ROUT1", NULL, "Right Out 1"},
+
+ /* Left Line Mux */
+ {"Left Line Mux", "Line 1", "LINPUT1"},
+ {"Left Line Mux", "Line 2", "LINPUT2"},
+ {"Left Line Mux", NULL, "MICIN"},
+
+ /* Right Line Mux */
+ {"Right Line Mux", "Line 1", "RINPUT1"},
+ {"Right Line Mux", "Line 2", "RINPUT2"},
+ {"Right Line Mux", NULL, "MICIN"},
+
+ /* Left ADC Mux */
+ {"Left ADC Mux", "Stereo", "Left Line Mux"},
+// {"Left ADC Mux", "Mono (Left)" , "Left Line Mux"},
+
+ /* Right ADC Mux */
+ {"Right ADC Mux", "Stereo", "Right Line Mux"},
+// {"Right ADC Mux", "Mono (Right)", "Right Line Mux"},
+
+ /* ADC */
+ {"Left ADC" , NULL, "Left ADC Mux"},
+ {"Right ADC", NULL, "Right ADC Mux"},
+};
+
+static int es8388_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct es8388_priv *es8388 = snd_soc_codec_get_drvdata(codec);
+
+ es8388->sysclk = freq;
+ return 0;
+}
+
+static int es8388_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u8 iface = 0;
+ u8 adciface = 0;
+ u8 daciface = 0;
+
+ iface = snd_soc_read(codec, ES8388_IFACE);
+ adciface = snd_soc_read(codec, ES8388_ADC_IFACE);
+ daciface = snd_soc_read(codec, ES8388_DAC_IFACE);
+
+ /* set master/slave audio interface */
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM: // MASTER MODE
+ iface |= 0x80;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS: // SLAVE MODE
+ iface &= 0x7F;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* interface format */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ adciface &= 0xFC;
+ daciface &= 0xF9;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ case SND_SOC_DAIFMT_LEFT_J:
+ case SND_SOC_DAIFMT_DSP_A:
+ case SND_SOC_DAIFMT_DSP_B:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* clock inversion */
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ iface &= 0xDF;
+ adciface &= 0xDF;
+ daciface &= 0xBF;
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ iface |= 0x20;
+ adciface |= 0x20;
+ daciface |= 0x40;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ iface |= 0x20;
+ adciface &= 0xDF;
+ daciface &= 0xBF;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ iface &= 0xDF;
+ adciface |= 0x20;
+ daciface |= 0x40;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_write(codec, ES8388_IFACE, iface);
+ snd_soc_write(codec, ES8388_ADC_IFACE, adciface);
+ snd_soc_write(codec, ES8388_DAC_IFACE, daciface);
+
+ return 0;
+}
+
+static int es8388_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ u16 iface;
+
+ if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ iface = snd_soc_read(codec, ES8388_DAC_IFACE) & 0xC7;
+ /* bit size */
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ iface |= 0x0018;
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ iface |= 0x0008;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ iface |= 0x0020;
+ break;
+ }
+ /* set iface & srate */
+ snd_soc_write(codec, ES8388_DAC_IFACE, iface);
+ } else {
+ iface = snd_soc_read(codec, ES8388_ADC_IFACE) & 0xE3;
+ /* bit size */
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ iface |= 0x000C;
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ iface |= 0x0004;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ iface |= 0x0010;
+ break;
+ }
+ /* set iface */
+ snd_soc_write(codec, ES8388_ADC_IFACE, iface);
+ }
+
+ return 0;
+}
+
+static int es8388_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ unsigned char val = 0;
+
+ val = snd_soc_read(codec, ES8388_DAC_MUTE);
+ if (mute){
+ val |= 0x04;
+ } else {
+ val &= ~0x04;
+ }
+
+ snd_soc_write(codec, ES8388_DAC_MUTE, val);
+
+ return 0;
+}
+
+
+static int es8388_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ switch(level) {
+ case SND_SOC_BIAS_ON:
+ break;
+
+ case SND_SOC_BIAS_PREPARE:
+ if(codec->dapm.bias_level != SND_SOC_BIAS_ON) {
+ /* updated by David-everest,5-25
+ // Chip Power on
+ snd_soc_write(codec, ES8388_CHIPPOWER, 0xF3);
+ // VMID control
+ snd_soc_write(codec, ES8388_CONTROL1 , 0x06);
+ // ADC/DAC DLL power on
+ snd_soc_write(codec, ES8388_CONTROL2 , 0xF3);
+ */
+ snd_soc_write(codec, ES8388_ADCPOWER, 0x00);
+ snd_soc_write(codec, ES8388_DACPOWER , 0x30);
+ snd_soc_write(codec, ES8388_CHIPPOWER , 0x00);
+ }
+ break;
+
+ case SND_SOC_BIAS_STANDBY:
+ /*
+ // ADC/DAC DLL power on
+ snd_soc_write(codec, ES8388_CONTROL2 , 0xFF);
+ // Chip Power off
+ snd_soc_write(codec, ES8388_CHIPPOWER, 0xF3);
+ */
+ snd_soc_write(codec, ES8388_ADCPOWER, 0x00);
+ snd_soc_write(codec, ES8388_DACPOWER , 0x30);
+ snd_soc_write(codec, ES8388_CHIPPOWER , 0x00);
+ break;
+
+ case SND_SOC_BIAS_OFF:
+ /*
+ // ADC/DAC DLL power off
+ snd_soc_write(codec, ES8388_CONTROL2 , 0xFF);
+ // Chip Control
+ snd_soc_write(codec, ES8388_CONTROL1 , 0x00);
+ // Chip Power off
+ snd_soc_write(codec, ES8388_CHIPPOWER, 0xFF);
+ */
+ snd_soc_write(codec, ES8388_ADCPOWER, 0xFF);
+ snd_soc_write(codec, ES8388_DACPOWER , 0xC0);
+ snd_soc_write(codec, ES8388_CHIPPOWER , 0xC3);
+ break;
+ }
+
+ codec->dapm.bias_level = level;
+
+ return 0;
+}
+
+
+#define ES8388_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
+
+#define ES8388_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
+ SNDRV_PCM_FMTBIT_S24_LE)
+
+static const struct snd_soc_dai_ops es8388_dai_ops = {
+ .hw_params = es8388_pcm_hw_params,
+ .set_fmt = es8388_set_dai_fmt,
+ .set_sysclk = es8388_set_dai_sysclk,
+ .digital_mute = es8388_mute,
+};
+
+
+struct snd_soc_dai_driver es8388_dai = {
+ .name = "es8388-hifi",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = ES8388_RATES,
+ .formats = ES8388_FORMATS,},
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = ES8388_RATES,
+ .formats = ES8388_FORMATS,},
+ .ops = &es8388_dai_ops,
+ .symmetric_rates = 1,
+};
+
+static int es8388_suspend(struct snd_soc_codec *codec)
+{
+ es8388_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static int es8388_resume(struct snd_soc_codec *codec)
+{
+ es8388_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ return 0;
+}
+
+static int es8388_remove(struct snd_soc_codec *codec)
+{
+ es8388_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static inline int es8388_reset(struct regmap *map)
+{
+ int ret = 0;
+ regmap_write(map, 0x00, 0x80);
+ ret = regmap_write(map, 0x00, 0x00);
+ return ret;
+}
+
+static int es8388_probe(struct snd_soc_codec *codec)
+{
+ struct es8388_priv *es8388 = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
+ //int i = 0;
+
+ dev_info(codec->dev, "ES8388 Audio Codec %s", ES8388_VERSION);
+ codec->control_data = es8388->regmap;
+
+ ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
+ }
+
+ ret = devm_gpio_request(codec->dev, es8388->aud_rst_pin, "es8388 aud reset");
+ if (ret < 0){
+ dev_err(codec->dev, "Failed to request rst_pin: %d\n", ret);
+ return ret;
+ }
+
+ /* Reset NS4890 aud */
+ gpio_direction_output(es8388->aud_rst_pin, es8388->aud_rst_active);
+ msleep(1);
+
+ es8388_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ snd_soc_write(codec, ES8388_MASTERMODE,0x00);
+ snd_soc_write(codec, ES8388_CHIPPOWER, 0xF3);
+ snd_soc_write(codec, ES8388_DACCONTROL23, 0x00);
+// snd_soc_write(codec, ES8388_ANAVOLMANAG, 0x74);
+ snd_soc_write(codec, ES8388_DACCONTROL21, 0x80);
+ snd_soc_write(codec, ES8388_CONTROL1, 0x30);
+ snd_soc_write(codec, ES8388_CHIPLOPOW2, 0xFF);
+ snd_soc_write(codec, ES8388_CHIPLOPOW1, 0x00);
+ //-------------ADC---------------------------//
+ snd_soc_write(codec, ES8388_ADCCONTROL1, 0x88);
+ snd_soc_write(codec, ES8388_ADCCONTROL2, 0xF0);
+ snd_soc_write(codec, ES8388_ADCCONTROL3, 0x06); //adc output in tri-state
+ snd_soc_write(codec, ES8388_ADCCONTROL4, 0x0C);
+ snd_soc_write(codec, ES8388_ADCCONTROL5, 0x66); //compitable with ES8388S
+ snd_soc_write(codec, ES8388_ADCCONTROL7, 0x30);
+ snd_soc_write(codec, ES8388_ADCCONTROL8, 0x00);
+ snd_soc_write(codec, ES8388_ADCCONTROL9, 0x00);
+ snd_soc_write(codec, ES8388_ADCCONTROL10, 0xD2);
+ snd_soc_write(codec, ES8388_ADCCONTROL11, 0xB0);
+ snd_soc_write(codec, ES8388_ADCCONTROL12, 0x12);
+ snd_soc_write(codec, ES8388_ADCCONTROL13, 0x06);
+ snd_soc_write(codec, ES8388_ADCCONTROL14, 0x11);
+ //-------------DAC-----------------------------//
+ snd_soc_write(codec, ES8388_DACCONTROL1, 0x18);
+ snd_soc_write(codec, ES8388_DACCONTROL2, 0x82); //compitable with ES8388S
+ snd_soc_write(codec, ES8388_DACCONTROL3, 0x76);
+ snd_soc_write(codec, ES8388_DACCONTROL4, 0x00);
+ snd_soc_write(codec, ES8388_DACCONTROL5, 0x00);
+ snd_soc_write(codec, ES8388_DACCONTROL17, 0xB8);
+ snd_soc_write(codec, ES8388_DACCONTROL20, 0xB8);
+
+ snd_soc_write(codec, ES8388_CHIPPOWER, 0x00);
+ snd_soc_write(codec, ES8388_CONTROL1, 0x36);
+ snd_soc_write(codec, ES8388_CONTROL2, 0x72);
+ snd_soc_write(codec, ES8388_DACPOWER, 0x00); //only start up DAC, disable LOUT/ROUT
+ snd_soc_write(codec, ES8388_ADCPOWER, 0x09);
+ snd_soc_write(codec, ES8388_CONTROL1, 0x32);
+ snd_soc_write(codec, ES8388_DACCONTROL3, 0x72);
+/*
+ for( i = 0; i < 0x1d; i++)
+ {
+ snd_soc_write(codec, ES8388_DACCONTROL24, i); //LOUT1/ROUT1 VOLUME
+ snd_soc_write(codec, ES8388_DACCONTROL25, i);
+ snd_soc_write(codec, ES8388_DACCONTROL26, i); //LOUT2/ROUT2 VOLUME
+ snd_soc_write(codec, ES8388_DACCONTROL27, i);
+ msleep(5);
+ }
+*/
+ return ret;
+}
+
+static int es8388s_probe(struct snd_soc_codec *codec)
+{
+ struct es8388_priv *es8388 = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
+
+ dev_info(codec->dev, "ES8388s Audio Codec %s", ES8388_VERSION);
+ codec->control_data = es8388->regmap;
+
+ ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
+ }
+
+ es8388_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ /* Enable Diff PGA for ES8388S */
+ snd_soc_write(codec, 0x35,0xA0);
+ snd_soc_write(codec, 0x38,0x02);
+
+ snd_soc_write(codec, ES8388_MASTERMODE,0x00);
+ snd_soc_write(codec, ES8388_CHIPPOWER, 0xF3);
+ snd_soc_write(codec, ES8388_DACCONTROL23, 0x00);
+// snd_soc_write(codec, ES8388_ANAVOLMANAG, 0x74);
+ snd_soc_write(codec, ES8388_DACCONTROL21, 0x80);
+ snd_soc_write(codec, ES8388_CONTROL1, 0x30);
+ snd_soc_write(codec, ES8388_CHIPLOPOW2, 0xFF);
+ snd_soc_write(codec, ES8388_CHIPLOPOW1, 0x00);
+ //-------------ADC---------------------------//
+ snd_soc_write(codec, ES8388_ADCCONTROL1, 0x40);
+ snd_soc_write(codec, ES8388_ADCCONTROL2, 0xF0);
+ snd_soc_write(codec, ES8388_ADCCONTROL3, 0x82); /* adc output in tri-state */
+ snd_soc_write(codec, ES8388_ADCCONTROL4, 0x4C);
+ snd_soc_write(codec, ES8388_ADCCONTROL5, 0x02); /* compitable with ES8388S */
+ snd_soc_write(codec, ES8388_ADCCONTROL6, 0x2c);
+ snd_soc_write(codec, ES8388_ADCCONTROL8, 0x00);
+ snd_soc_write(codec, ES8388_ADCCONTROL9, 0x00);
+ snd_soc_write(codec, ES8388_ADCCONTROL10, 0xDa);
+ snd_soc_write(codec, ES8388_ADCCONTROL11, 0xB0);
+ snd_soc_write(codec, ES8388_ADCCONTROL12, 0x12);
+ snd_soc_write(codec, ES8388_ADCCONTROL13, 0x06);
+ snd_soc_write(codec, ES8388_ADCCONTROL14, 0x11);
+ //-------------DAC-----------------------------//
+ snd_soc_write(codec, ES8388_DACCONTROL1, 0x18);
+ snd_soc_write(codec, ES8388_DACCONTROL2, 0x02); /* compitable with ES8388S */
+ snd_soc_write(codec, ES8388_DACCONTROL3, 0x76);
+ snd_soc_write(codec, ES8388_DACCONTROL4, 0x00);
+ snd_soc_write(codec, ES8388_DACCONTROL5, 0x00);
+ snd_soc_write(codec, ES8388_DACCONTROL17, 0xB8);
+ snd_soc_write(codec, ES8388_DACCONTROL20, 0xB8);
+
+ snd_soc_write(codec, ES8388_CHIPPOWER, 0x00);
+ snd_soc_write(codec, ES8388_CONTROL1, 0x36);
+ snd_soc_write(codec, ES8388_CONTROL2, 0x72);
+ snd_soc_write(codec, ES8388_DACPOWER, 0x00); //only start up DAC, disable LOUT/ROUT
+ snd_soc_write(codec, ES8388_ADCPOWER, 0x09);
+ snd_soc_write(codec, ES8388_CONTROL1, 0x32);
+ snd_soc_write(codec, ES8388_DACCONTROL3, 0x72);
+
+ return ret;
+}
+
+static bool es8388_volatile_register(struct device *dev,
+ unsigned int reg)
+{
+ switch (reg) {
+ case ES8388_CONTROL1:
+ case ES8388_CONTROL2:
+ case ES8388_CHIPPOWER:
+ case ES8388_ADCPOWER:
+ case ES8388_DACPOWER:
+ case ES8388_CHIPLOPOW1:
+ case ES8388_CHIPLOPOW2:
+ case ES8388_ANAVOLMANAG:
+ case ES8388_MASTERMODE:
+ case ES8388_ADCCONTROL1:
+ case ES8388_ADCCONTROL2:
+ case ES8388_ADCCONTROL3:
+ case ES8388_ADCCONTROL4:
+ case ES8388_ADCCONTROL5:
+ case ES8388_ADCCONTROL6:
+ case ES8388_ADCCONTROL7:
+ case ES8388_ADCCONTROL8:
+ case ES8388_ADCCONTROL9:
+ case ES8388_ADCCONTROL10:
+ case ES8388_ADCCONTROL11:
+ case ES8388_ADCCONTROL12:
+ case ES8388_ADCCONTROL13:
+ case ES8388_ADCCONTROL14:
+ case ES8388_DACCONTROL1:
+ case ES8388_DACCONTROL2:
+ case ES8388_DACCONTROL3:
+ case ES8388_DACCONTROL4:
+ case ES8388_DACCONTROL5:
+ case ES8388_DACCONTROL6:
+ case ES8388_DACCONTROL7:
+ case ES8388_DACCONTROL8:
+ case ES8388_DACCONTROL9:
+ case ES8388_DACCONTROL10:
+ case ES8388_DACCONTROL11:
+ case ES8388_DACCONTROL12:
+ case ES8388_DACCONTROL13:
+ case ES8388_DACCONTROL14:
+ case ES8388_DACCONTROL15:
+ case ES8388_DACCONTROL16:
+ case ES8388_DACCONTROL17:
+ case ES8388_DACCONTROL18:
+ case ES8388_DACCONTROL19:
+ case ES8388_DACCONTROL20:
+ case ES8388_DACCONTROL21:
+ case ES8388_DACCONTROL22:
+ case ES8388_DACCONTROL23:
+ case ES8388_DACCONTROL24:
+ case ES8388_DACCONTROL25:
+ case ES8388_DACCONTROL26:
+ case ES8388_DACCONTROL27:
+ case ES8388_DACCONTROL28:
+ case ES8388_DACCONTROL29:
+ case ES8388_DACCONTROL30:
+ return true;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+
+static struct snd_soc_codec_driver soc_codec_dev_es8388 = {
+ .probe = es8388_probe,
+ .remove = es8388_remove,
+ .suspend = es8388_suspend,
+ .resume = es8388_resume,
+ .set_bias_level = es8388_set_bias_level,
+
+ .dapm_widgets = es8388_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(es8388_dapm_widgets),
+ .dapm_routes = audio_map,
+ .num_dapm_routes = ARRAY_SIZE(audio_map),
+
+ .controls = es8388_snd_controls,
+ .num_controls = ARRAY_SIZE(es8388_snd_controls),
+};
+
+static struct snd_soc_codec_driver soc_codec_dev_es8388s = {
+ .probe = es8388s_probe,
+ .remove = es8388_remove,
+ .suspend = es8388_suspend,
+ .resume = es8388_resume,
+ .set_bias_level = es8388_set_bias_level,
+
+ .dapm_widgets = es8388_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(es8388_dapm_widgets),
+ .dapm_routes = audio_map,
+ .num_dapm_routes = ARRAY_SIZE(audio_map),
+
+ .controls = es8388_snd_controls,
+ .num_controls = ARRAY_SIZE(es8388_snd_controls),
+};
+
+static struct regmap_config es8388_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .max_register = ES8388_MAX_REGISTER,
+ .reg_defaults = es8388_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(es8388_reg_defaults),
+ .volatile_reg = es8388_volatile_register,
+ .cache_type = REGCACHE_RBTREE,
+};
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static struct of_device_id es8388_of_match[];
+static int es8388_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct device_node *np = i2c->dev.of_node;
+ struct es8388_priv *es8388;
+ int ret = 0;
+ enum of_gpio_flags flags;
+ int rst_pin;
+ const struct snd_soc_codec_driver *driver;
+
+ es8388 = devm_kzalloc(&i2c->dev, sizeof(struct es8388_priv), GFP_KERNEL);
+ if (es8388 == NULL)
+ return -ENOMEM;
+
+ rst_pin = of_get_gpio_flags(np, 0, &flags);
+ if (rst_pin < 0 || !gpio_is_valid(rst_pin))
+ return -ENXIO;
+
+ es8388->aud_rst_pin = rst_pin;
+ es8388->aud_rst_active = !!(flags & OF_GPIO_ACTIVE_LOW);
+
+ i2c_set_clientdata(i2c, es8388);
+ es8388->regmap = devm_regmap_init_i2c(i2c, &es8388_regmap);
+ if (IS_ERR(es8388->regmap)) {
+ ret = PTR_ERR(es8388->regmap);
+ dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
+ return ret;
+ }
+
+ driver = NULL;
+ if (np) {
+ const struct of_device_id *of_id;
+
+ of_id = of_match_device(es8388_of_match, &i2c->dev);
+ if (of_id)
+ driver = of_id->data;
+ } else {
+ driver = (struct snd_soc_codec_driver *)id->driver_data;
+ }
+
+ if (!driver) {
+ dev_err(&i2c->dev, "no driver\n");
+ return -EINVAL;
+ }
+
+ ret = snd_soc_register_codec(&i2c->dev,
+ driver, &es8388_dai, 1);
+
+ return ret;
+}
+
+static int es8388_i2c_remove(struct i2c_client *i2c)
+{
+ snd_soc_unregister_codec(&i2c->dev);
+ return 0;
+}
+
+static struct of_device_id es8388_of_match[] = {
+ { .compatible = "ambarella,es8388", .data = &soc_codec_dev_es8388},
+ { .compatible = "ambarella,es8388s",.data = &soc_codec_dev_es8388s},
+ {},
+};
+MODULE_DEVICE_TABLE(of, es8388_of_match);
+static const struct i2c_device_id es8388_i2c_id[] = {
+ { "es8388", (kernel_ulong_t)&soc_codec_dev_es8388},
+ { "es8388s",(kernel_ulong_t)&soc_codec_dev_es8388s},
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, es8388_i2c_id);
+
+static struct i2c_driver es8388_i2c_driver = {
+ .driver = {
+ .name = "es8388-codec",
+ .owner = THIS_MODULE,
+ .of_match_table = es8388_of_match,
+ },
+ .probe = es8388_i2c_probe,
+ .remove = es8388_i2c_remove,
+ .id_table = es8388_i2c_id,
+};
+#endif
+
+static int __init es8388_modinit(void)
+{
+ int ret = 0;
+
+#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
+ ret = i2c_add_driver(&es8388_i2c_driver);
+ if (ret != 0) {
+ pr_err("Failed to register ES8388 I2C driver: %d\n", ret);
+ }
+#endif
+ return ret;
+}
+module_init(es8388_modinit);
+
+static void __exit es8388_exit(void)
+{
+#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
+ i2c_del_driver(&es8388_i2c_driver);
+#endif
+}
+module_exit(es8388_exit);
+
+MODULE_DESCRIPTION("ASoC ES8388 driver");
+MODULE_AUTHOR("Ken He <jianhe@ambarella.com>");
+MODULE_LICENSE("GPL");
+
diff --git a/sound/soc/codecs/es8388.h b/sound/soc/codecs/es8388.h
new file mode 100644
index 00000000..cbb144ba
--- /dev/null
+++ b/sound/soc/codecs/es8388.h
@@ -0,0 +1,159 @@
+/*
+ * es8388.h -- ES8388 Soc Audio driver
+ *
+ * Copyright 2011 Ambarella Ltd.
+ *
+ * Author: Cao Rongrong <rrcao@ambarella.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _ES8388_H
+#define _ES8388_H
+
+#define CONFIG_HHTECH_MINIPMP 1
+
+/* ES8388 register space */
+
+#define ES8388_CONTROL1 0x00
+#define ES8388_CONTROL2 0x01
+#define ES8388_CHIPPOWER 0x02
+#define ES8388_ADCPOWER 0x03
+#define ES8388_DACPOWER 0x04
+#define ES8388_CHIPLOPOW1 0x05
+#define ES8388_CHIPLOPOW2 0x06
+#define ES8388_ANAVOLMANAG 0x07
+#define ES8388_MASTERMODE 0x08
+#define ES8388_ADCCONTROL1 0x09
+#define ES8388_ADCCONTROL2 0x0a
+#define ES8388_ADCCONTROL3 0x0b
+#define ES8388_ADCCONTROL4 0x0c
+#define ES8388_ADCCONTROL5 0x0d
+#define ES8388_ADCCONTROL6 0x0e
+#define ES8388_ADCCONTROL7 0x0f
+#define ES8388_ADCCONTROL8 0x10
+#define ES8388_ADCCONTROL9 0x11
+#define ES8388_ADCCONTROL10 0x12
+#define ES8388_ADCCONTROL11 0x13
+#define ES8388_ADCCONTROL12 0x14
+#define ES8388_ADCCONTROL13 0x15
+#define ES8388_ADCCONTROL14 0x16
+
+#define ES8388_DACCONTROL1 0x17
+#define ES8388_DACCONTROL2 0x18
+#define ES8388_DACCONTROL3 0x19
+#define ES8388_DACCONTROL4 0x1a
+#define ES8388_DACCONTROL5 0x1b
+#define ES8388_DACCONTROL6 0x1c
+#define ES8388_DACCONTROL7 0x1d
+#define ES8388_DACCONTROL8 0x1e
+#define ES8388_DACCONTROL9 0x1f
+#define ES8388_DACCONTROL10 0x20
+#define ES8388_DACCONTROL11 0x21
+#define ES8388_DACCONTROL12 0x22
+#define ES8388_DACCONTROL13 0x23
+#define ES8388_DACCONTROL14 0x24
+#define ES8388_DACCONTROL15 0x25
+#define ES8388_DACCONTROL16 0x26
+#define ES8388_DACCONTROL17 0x27
+#define ES8388_DACCONTROL18 0x28
+#define ES8388_DACCONTROL19 0x29
+#define ES8388_DACCONTROL20 0x2a
+#define ES8388_DACCONTROL21 0x2b
+#define ES8388_DACCONTROL22 0x2c
+#define ES8388_DACCONTROL23 0x2d
+#define ES8388_DACCONTROL24 0x2e
+#define ES8388_DACCONTROL25 0x2f
+#define ES8388_DACCONTROL26 0x30
+#define ES8388_DACCONTROL27 0x31
+#define ES8388_DACCONTROL28 0x32
+#define ES8388_DACCONTROL29 0x33
+#define ES8388_DACCONTROL30 0x34
+
+#define ES8388_LADC_VOL ES8388_ADCCONTROL8
+#define ES8388_RADC_VOL ES8388_ADCCONTROL9
+
+#define ES8388_LDAC_VOL ES8388_DACCONTROL4
+#define ES8388_RDAC_VOL ES8388_DACCONTROL5
+
+#define ES8388_LOUT1_VOL ES8388_DACCONTROL24
+#define ES8388_ROUT1_VOL ES8388_DACCONTROL25
+#define ES8388_LOUT2_VOL ES8388_DACCONTROL26
+#define ES8388_ROUT2_VOL ES8388_DACCONTROL27
+
+#define ES8388_ADC_MUTE ES8388_ADCCONTROL7
+#define ES8388_DAC_MUTE ES8388_DACCONTROL3
+
+
+
+#define ES8388_IFACE ES8388_MASTERMODE
+
+#define ES8388_ADC_IFACE ES8388_ADCCONTROL4
+#define ES8388_ADC_SRATE ES8388_ADCCONTROL5
+
+#define ES8388_DAC_IFACE ES8388_DACCONTROL1
+#define ES8388_DAC_SRATE ES8388_DACCONTROL2
+
+
+#define ES8388_MAX_REGISTER 53
+#define ES8388_CACHEREGNUM 53
+#define ES8388_SYSCLK 0
+
+struct es8388_setup_data {
+ int i2c_bus;
+ unsigned short i2c_address;
+};
+
+#if 1 //lzcx
+#define ES8388_PLL1 0
+#define ES8388_PLL2 1
+
+/* clock inputs */
+#define ES8388_MCLK 0
+#define ES8388_PCMCLK 1
+#define ES8388_BCLK_IN 1
+#define ES8388_MCLK_IN_BCLK_OUT 2
+
+/* clock divider id's */
+#define ES8388_PCMDIV 0
+#define ES8388_BCLKDIV 1
+#define ES8388_VXCLKDIV 2
+
+/* PCM clock dividers */
+#define ES8388_PCM_DIV_1 (0 << 6)
+#define ES8388_PCM_DIV_3 (2 << 6)
+#define ES8388_PCM_DIV_5_5 (3 << 6)
+#define ES8388_PCM_DIV_2 (4 << 6)
+#define ES8388_PCM_DIV_4 (5 << 6)
+#define ES8388_PCM_DIV_6 (6 << 6)
+#define ES8388_PCM_DIV_8 (7 << 6)
+
+/* BCLK clock dividers */
+#define ES8388_BCLK_DIV_1 (0 << 7)
+#define ES8388_BCLK_DIV_2 (1 << 7)
+#define ES8388_BCLK_DIV_4 (2 << 7)
+#define ES8388_BCLK_DIV_8 (3 << 7)
+
+/* VXCLK clock dividers */
+#define ES8388_VXCLK_DIV_1 (0 << 6)
+#define ES8388_VXCLK_DIV_2 (1 << 6)
+#define ES8388_VXCLK_DIV_4 (2 << 6)
+#define ES8388_VXCLK_DIV_8 (3 << 6)
+#define ES8388_VXCLK_DIV_16 (4 << 6)
+
+#define ES8388_DAI_HIFI 0
+#define ES8388_DAI_VOICE 1
+
+#define ES8388_1536FS 1536
+#define ES8388_1024FS 1024
+#define ES8388_768FS 768
+#define ES8388_512FS 512
+#define ES8388_384FS 384
+#define ES8388_256FS 256
+#define ES8388_128FS 128
+#endif
+
+#endif
+
diff --git a/sound/soc/codecs/rt5670-dsp.c b/sound/soc/codecs/rt5670-dsp.c
new file mode 100644
index 00000000..86bdc1f4
--- /dev/null
+++ b/sound/soc/codecs/rt5670-dsp.c
@@ -0,0 +1,1429 @@
+/*
+ * rt5670.c -- RT5670 ALSA SoC DSP driver
+ *
+ * Copyright 2011 Realtek Semiconductor Corp.
+ * Author: Johnny Hsu <johnnyhsu@realtek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+#define RTK_IOCTL
+#ifdef RTK_IOCTL
+#include <linux/spi/spi.h>
+#include "rt_codec_ioctl.h"
+#endif
+
+#include "rt5670.h"
+#include "rt5670-dsp.h"
+
+#define DSP_CLK_RATE RT5670_DSP_CLK_96K
+
+static unsigned short rt5670_dsp_patch[][2] = {
+ {0xe1, 0x0010}, {0xe2, 0x0000}, {0xe0, 0x6ac9},
+ {0xe1, 0x0064}, {0xe2, 0x0000}, {0xe0, 0x68c5},
+ {0xe1, 0x3f00}, {0xe2, 0x8301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f01}, {0xe2, 0x9212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f02}, {0xe2, 0x830f}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f03}, {0xe2, 0x9301}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f04}, {0xe2, 0x81cc}, {0xe3, 0x008c}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f05}, {0xe2, 0x4009}, {0xe3, 0x000a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f06}, {0xe2, 0x267c}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f07}, {0xe2, 0x23a2}, {0xe3, 0x00d0}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f08}, {0xe2, 0x9212}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f09}, {0xe2, 0x93ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f0a}, {0xe2, 0x83ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f0b}, {0xe2, 0x278a}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f0c}, {0xe2, 0x1bf0}, {0xe3, 0x00a1}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f0d}, {0xe2, 0x8212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f0e}, {0xe2, 0x9301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f0f}, {0xe2, 0x81cc}, {0xe3, 0x008c}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f10}, {0xe2, 0x1918}, {0xe3, 0x004f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f11}, {0xe2, 0x8301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f12}, {0xe2, 0x9212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f13}, {0xe2, 0x830f}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f14}, {0xe2, 0x9301}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f15}, {0xe2, 0x8212}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f16}, {0xe2, 0x93ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f17}, {0xe2, 0x83ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f18}, {0xe2, 0x278a}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f19}, {0xe2, 0x1bf1}, {0xe3, 0x0071}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f1a}, {0xe2, 0x8212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f1b}, {0xe2, 0x9301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f1c}, {0xe2, 0x8117}, {0xe3, 0x00e5}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f1d}, {0xe2, 0x191b}, {0xe3, 0x004f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f1e}, {0xe2, 0x8301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f1f}, {0xe2, 0x9212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f20}, {0xe2, 0x830f}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f21}, {0xe2, 0x9301}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f22}, {0xe2, 0x8212}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f23}, {0xe2, 0x93ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f24}, {0xe2, 0x83ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f25}, {0xe2, 0x278a}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f26}, {0xe2, 0x1bf2}, {0xe3, 0x0041}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f27}, {0xe2, 0x8212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f28}, {0xe2, 0x9301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f29}, {0xe2, 0x8117}, {0xe3, 0x00e5}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f2a}, {0xe2, 0x1921}, {0xe3, 0x007f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f2b}, {0xe2, 0x8301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f2c}, {0xe2, 0x9212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f2d}, {0xe2, 0x8307}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f2e}, {0xe2, 0x9301}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f2f}, {0xe2, 0x81cc}, {0xe3, 0x008c}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f30}, {0xe2, 0x4009}, {0xe3, 0x000a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f31}, {0xe2, 0x267c}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f32}, {0xe2, 0x23a2}, {0xe3, 0x00d0}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f33}, {0xe2, 0x9212}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f34}, {0xe2, 0x93ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f35}, {0xe2, 0x83ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f36}, {0xe2, 0x278a}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f37}, {0xe2, 0x1bf3}, {0xe3, 0x0051}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f38}, {0xe2, 0x8212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f39}, {0xe2, 0x9301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f3a}, {0xe2, 0x81cc}, {0xe3, 0x008c}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f3b}, {0xe2, 0x3400}, {0xe3, 0x004e}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f3c}, {0xe2, 0x1a09}, {0xe3, 0x00ef}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f3d}, {0xe2, 0x8301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f3e}, {0xe2, 0x9212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f3f}, {0xe2, 0x8307}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f40}, {0xe2, 0x9301}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f41}, {0xe2, 0x8212}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f42}, {0xe2, 0x93ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f43}, {0xe2, 0x83ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f44}, {0xe2, 0x278a}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f45}, {0xe2, 0x1bf4}, {0xe3, 0x0031}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f46}, {0xe2, 0x8212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f47}, {0xe2, 0x9301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f48}, {0xe2, 0x8117}, {0xe3, 0x00e5}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f49}, {0xe2, 0x3400}, {0xe3, 0x004e}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f4a}, {0xe2, 0x1a0c}, {0xe3, 0x00ef}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f4b}, {0xe2, 0x8301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f4c}, {0xe2, 0x9212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f4d}, {0xe2, 0x8307}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f4e}, {0xe2, 0x9301}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f4f}, {0xe2, 0x8212}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f50}, {0xe2, 0x93ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f51}, {0xe2, 0x83ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f52}, {0xe2, 0x278a}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f53}, {0xe2, 0x1bf5}, {0xe3, 0x0011}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f54}, {0xe2, 0x8212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f55}, {0xe2, 0x9301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f56}, {0xe2, 0x8117}, {0xe3, 0x00e5}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f57}, {0xe2, 0x3400}, {0xe3, 0x004e}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f58}, {0xe2, 0x1a13}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f59}, {0xe2, 0x8e77}, {0xe3, 0x00c5}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f5a}, {0xe2, 0x34b8}, {0xe3, 0x0001}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f5b}, {0xe2, 0x3960}, {0xe3, 0x0002}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f5c}, {0xe2, 0x17f6}, {0xe3, 0x000e}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f5d}, {0xe2, 0x6000}, {0xe3, 0x0016}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f5e}, {0xe2, 0x7000}, {0xe3, 0x005a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f5f}, {0xe2, 0x6800}, {0xe3, 0x0055}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f60}, {0xe2, 0x7800}, {0xe3, 0x0019}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f61}, {0xe2, 0x1859}, {0xe3, 0x00bf}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f62}, {0xe2, 0x8230}, {0xe3, 0x0010}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f63}, {0xe2, 0x26e0}, {0xe3, 0x00df}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f64}, {0xe2, 0x1bf6}, {0xe3, 0x0072}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f65}, {0xe2, 0x3c00}, {0xe3, 0x0015}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f66}, {0xe2, 0x194f}, {0xe3, 0x00df}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f67}, {0xe2, 0x0c20}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f68}, {0xe2, 0x8240}, {0xe3, 0x0003}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f69}, {0xe2, 0x8324}, {0xe3, 0x0007}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f6a}, {0xe2, 0x2029}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f6b}, {0xe2, 0x9240}, {0xe3, 0x000c}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f6c}, {0xe2, 0x824c}, {0xe3, 0x0003}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f6d}, {0xe2, 0x2029}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f6e}, {0xe2, 0x924c}, {0xe3, 0x000c}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f6f}, {0xe2, 0x0c30}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f70}, {0xe2, 0x1950}, {0xe3, 0x002f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f71}, {0xe2, 0x962c}, {0xe3, 0x0076}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f72}, {0xe2, 0x962c}, {0xe3, 0x0086}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f73}, {0xe2, 0x4001}, {0xe3, 0x009a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f74}, {0xe2, 0x922c}, {0xe3, 0x009a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f75}, {0xe2, 0x3521}, {0xe3, 0x0091}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f76}, {0xe2, 0x3521}, {0xe3, 0x0062}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f77}, {0xe2, 0x3521}, {0xe3, 0x00c0}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f78}, {0xe2, 0x3c00}, {0xe3, 0x00c5}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f79}, {0xe2, 0x0c0c}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f7a}, {0xe2, 0x17f8}, {0xe3, 0x00ee}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f7b}, {0xe2, 0x6000}, {0xe3, 0x00a5}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f7c}, {0xe2, 0x22fa}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f7d}, {0xe2, 0x6000}, {0xe3, 0x0049}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f7e}, {0xe2, 0x66e2}, {0xe3, 0x0051}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f7f}, {0xe2, 0x1bf8}, {0xe3, 0x00c3}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f80}, {0xe2, 0x26ea}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f81}, {0xe2, 0x1bf8}, {0xe3, 0x00c3}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f82}, {0xe2, 0x822c}, {0xe3, 0x008a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f83}, {0xe2, 0x2262}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f84}, {0xe2, 0x822c}, {0xe3, 0x0094}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f85}, {0xe2, 0x26e2}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f86}, {0xe2, 0x1bf8}, {0xe3, 0x00a0}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f83}, {0xe2, 0x2262}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f84}, {0xe2, 0x822c}, {0xe3, 0x0094}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f85}, {0xe2, 0x26e2}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f86}, {0xe2, 0x1bf8}, {0xe3, 0x00a0}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f87}, {0xe2, 0x822c}, {0xe3, 0x007a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f88}, {0xe2, 0x2262}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f89}, {0xe2, 0x922c}, {0xe3, 0x007a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f8a}, {0xe2, 0x822c}, {0xe3, 0x009a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f8b}, {0xe2, 0x922c}, {0xe3, 0x008a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f8c}, {0xe2, 0x822c}, {0xe3, 0x009a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f8d}, {0xe2, 0x2262}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f8e}, {0xe2, 0x922c}, {0xe3, 0x009a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f8f}, {0xe2, 0x0c08}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f90}, {0xe2, 0x8230}, {0xe3, 0x0030}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f91}, {0xe2, 0x2398}, {0xe3, 0x005f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f92}, {0xe2, 0x1bfa}, {0xe3, 0x0020}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f93}, {0xe2, 0x822c}, {0xe3, 0x007a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f94}, {0xe2, 0x822c}, {0xe3, 0x00c4}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f95}, {0xe2, 0x26e2}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f96}, {0xe2, 0x1bf9}, {0xe3, 0x00e5}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f97}, {0xe2, 0x822c}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f98}, {0xe2, 0x22e2}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f99}, {0xe2, 0x922c}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f9a}, {0xe2, 0x1bfa}, {0xe3, 0x0022}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f9b}, {0xe2, 0x962c}, {0xe3, 0x00a6}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f9c}, {0xe2, 0x962c}, {0xe3, 0x00b6}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f9d}, {0xe2, 0x1bfa}, {0xe3, 0x002f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f9e}, {0xe2, 0x4100}, {0xe3, 0x0014}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f9f}, {0xe2, 0x922c}, {0xe3, 0x00b4}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fa0}, {0xe2, 0x4001}, {0xe3, 0x0044}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fa1}, {0xe2, 0x922c}, {0xe3, 0x00a4}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fa2}, {0xe2, 0x3c00}, {0xe3, 0x0075}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fa3}, {0xe2, 0x193c}, {0xe3, 0x00af}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fa4}, {0xe2, 0x8230}, {0xe3, 0x0030}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fa5}, {0xe2, 0x2398}, {0xe3, 0x005f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fa6}, {0xe2, 0x1bfb}, {0xe3, 0x0050}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fa7}, {0xe2, 0x822c}, {0xe3, 0x00ba}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fa8}, {0xe2, 0x267a}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fa9}, {0xe2, 0x1bfb}, {0xe3, 0x0050}, {0xe0, 0x0dcf},
+ {0xe1, 0x3faa}, {0xe2, 0x8230}, {0xe3, 0x001a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fab}, {0xe2, 0x267a}, {0xe3, 0x007f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fac}, {0xe2, 0x4001}, {0xe3, 0x006a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fad}, {0xe2, 0x4001}, {0xe3, 0x00f1}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fae}, {0xe2, 0x2279}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3faf}, {0xe2, 0x0d04}, {0xe3, 0x007a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fb0}, {0xe2, 0x3724}, {0xe3, 0x0001}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fb1}, {0xe2, 0x0900}, {0xe3, 0x0007}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fb2}, {0xe2, 0xa7ff}, {0xe3, 0x00f5}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fb3}, {0xe2, 0xa7ff}, {0xe3, 0x00f5}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fb4}, {0xe2, 0xa7ff}, {0xe3, 0x00f5}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fb5}, {0xe2, 0x3b24}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fb6}, {0xe2, 0x194f}, {0xe3, 0x003f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fb7}, {0xe2, 0x822e}, {0xe3, 0x00a0}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fb8}, {0xe2, 0x2780}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fb9}, {0xe2, 0x1bfb}, {0xe3, 0x00e0}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fba}, {0xe2, 0x3c00}, {0xe3, 0x0025}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fbb}, {0xe2, 0x3916}, {0xe3, 0x0012}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fbc}, {0xe2, 0x3501}, {0xe3, 0x00a1}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fbd}, {0xe2, 0x1dbe}, {0xe3, 0x008f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fbe}, {0xe2, 0x810b}, {0xe3, 0x00f1}, {0xe0, 0x0dcf},
+ {0xe1, 0x3fbf}, {0xe2, 0x1831}, {0xe3, 0x00df}, {0xe0, 0x0dcf},
+ {0xe1, 0x0064}, {0xe2, 0x0000}, {0xe0, 0x68c5},
+ {0xe1, 0x3fa0}, {0xe2, 0x9183}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fb0}, {0xe2, 0x3f00}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fa1}, {0xe2, 0x91b3}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fb1}, {0xe2, 0x3f11}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fa2}, {0xe2, 0x9216}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fb2}, {0xe2, 0x3f1e}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fa3}, {0xe2, 0xe09d}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fb3}, {0xe2, 0x3f2b}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fa4}, {0xe2, 0xe0cd}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fb4}, {0xe2, 0x3f3d}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fa5}, {0xe2, 0xe130}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fb5}, {0xe2, 0x3f4b}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fa6}, {0xe2, 0x859a}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fb6}, {0xe2, 0x3f59}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fa7}, {0xe2, 0x94fc}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fb7}, {0xe2, 0x3f62}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fa8}, {0xe2, 0x93c9}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fb8}, {0xe2, 0x3f71}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fa9}, {0xe2, 0x94f2}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fb9}, {0xe2, 0x3fa4}, {0xe0, 0x3bcb},
+ {0xe1, 0x22cc}, {0xe2, 0x0001}, {0xe0, 0x3bcb},
+ {0xe1, 0x3faa}, {0xe2, 0x823a}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fba}, {0xe2, 0x023e}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fab}, {0xe2, 0x831c}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fbb}, {0xe2, 0x3fb7}, {0xe0, 0x3bcb},
+ {0xe1, 0x0010}, {0xe2, 0x0001}, {0xe0, 0x6ac9},
+ {0xe1, 0x0064}, {0xe2, 0x0000}, {0xe0, 0x68c5},
+ {0xe1, 0x3f00}, {0xe2, 0x26e1}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f01}, {0xe2, 0x1924}, {0xe3, 0x009f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f02}, {0xe2, 0x82f5}, {0xe3, 0x0050}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f03}, {0xe2, 0x26e0}, {0xe3, 0x00df}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f04}, {0xe2, 0x1bf0}, {0xe3, 0x0072}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f05}, {0xe2, 0x3400}, {0xe3, 0x0008}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f06}, {0xe2, 0x198e}, {0xe3, 0x003f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f07}, {0xe2, 0x0c20}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f08}, {0xe2, 0x80f5}, {0xe3, 0x00b3}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f09}, {0xe2, 0x8149}, {0xe3, 0x00b7}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f0a}, {0xe2, 0x2029}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f0b}, {0xe2, 0x90f5}, {0xe3, 0x00bc}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f0c}, {0xe2, 0x8101}, {0xe3, 0x00b3}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f0d}, {0xe2, 0x2029}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f0e}, {0xe2, 0x9101}, {0xe3, 0x00bc}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f0f}, {0xe2, 0x0c30}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f10}, {0xe2, 0x198e}, {0xe3, 0x009f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f11}, {0xe2, 0x9433}, {0xe3, 0x0006}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f12}, {0xe2, 0x9433}, {0xe3, 0x0016}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f13}, {0xe2, 0x4001}, {0xe3, 0x009a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f14}, {0xe2, 0x9033}, {0xe3, 0x002a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f15}, {0xe2, 0x3527}, {0xe3, 0x0041}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f16}, {0xe2, 0x3527}, {0xe3, 0x0012}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f17}, {0xe2, 0x3527}, {0xe3, 0x0070}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f18}, {0xe2, 0x3c00}, {0xe3, 0x00c5}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f19}, {0xe2, 0x0c0c}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f1a}, {0xe2, 0x17f2}, {0xe3, 0x00ee}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f1b}, {0xe2, 0x6000}, {0xe3, 0x00a5}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f1c}, {0xe2, 0x22fa}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f1d}, {0xe2, 0x6000}, {0xe3, 0x0049}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f1e}, {0xe2, 0x66e2}, {0xe3, 0x0051}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f1f}, {0xe2, 0x1bf2}, {0xe3, 0x00c3}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f20}, {0xe2, 0x26ea}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f21}, {0xe2, 0x1bf2}, {0xe3, 0x00c3}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f22}, {0xe2, 0x8033}, {0xe3, 0x001a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f23}, {0xe2, 0x2262}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f24}, {0xe2, 0x8033}, {0xe3, 0x0024}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f25}, {0xe2, 0x26e2}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f26}, {0xe2, 0x1bf2}, {0xe3, 0x00a0}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f27}, {0xe2, 0x8033}, {0xe3, 0x000a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f28}, {0xe2, 0x2262}, {0xe3, 0x621f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f29}, {0xe2, 0x9033}, {0xe3, 0x000a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f2a}, {0xe2, 0x8033}, {0xe3, 0x002a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f2b}, {0xe2, 0x9033}, {0xe3, 0x001a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f2c}, {0xe2, 0x8033}, {0xe3, 0x002a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f2d}, {0xe2, 0x2262}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f2e}, {0xe2, 0x9033}, {0xe3, 0x002a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f2f}, {0xe2, 0x0c08}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f30}, {0xe2, 0x82f5}, {0xe3, 0x0060}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f31}, {0xe2, 0x2398}, {0xe3, 0x005f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f32}, {0xe2, 0x1bf4}, {0xe3, 0x0020}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f33}, {0xe2, 0x8033}, {0xe3, 0x000a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f34}, {0xe2, 0x8033}, {0xe3, 0x0054}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f35}, {0xe2, 0x26e2}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f36}, {0xe2, 0x1bf3}, {0xe3, 0x00e5}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f37}, {0xe2, 0x8033}, {0xe3, 0x003a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f38}, {0xe2, 0x22e2}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f39}, {0xe2, 0x9033}, {0xe3, 0x003a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f3a}, {0xe2, 0x1bf4}, {0xe3, 0x0022}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f3b}, {0xe2, 0x9433}, {0xe3, 0x0036}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f3c}, {0xe2, 0x9433}, {0xe3, 0x0046}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f3d}, {0xe2, 0x1bf4}, {0xe3, 0x002f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f3e}, {0xe2, 0x4100}, {0xe3, 0x0014}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f3f}, {0xe2, 0x9033}, {0xe3, 0x0044}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f40}, {0xe2, 0x4001}, {0xe3, 0x0044}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f41}, {0xe2, 0x9033}, {0xe3, 0x0034}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f42}, {0xe2, 0x3c00}, {0xe3, 0x0075}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f43}, {0xe2, 0x192f}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f44}, {0xe2, 0x82f5}, {0xe3, 0x0060}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f45}, {0xe2, 0x2398}, {0xe3, 0x005f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f46}, {0xe2, 0x1bf5}, {0xe3, 0x0050}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f47}, {0xe2, 0x8033}, {0xe3, 0x004a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f48}, {0xe2, 0x267a}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f49}, {0xe2, 0x1bf5}, {0xe3, 0x0050}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f4a}, {0xe2, 0x82f5}, {0xe3, 0x005a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f4b}, {0xe2, 0x267a}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f4c}, {0xe2, 0x4001}, {0xe3, 0x006a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f4d}, {0xe2, 0x4001}, {0xe3, 0x00f1}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f4e}, {0xe2, 0x2279}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f4f}, {0xe2, 0x0d04}, {0xe3, 0x007a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f50}, {0xe2, 0x3549}, {0xe3, 0x00b1}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f51}, {0xe2, 0x0900}, {0xe3, 0x0007}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f52}, {0xe2, 0xa7ff}, {0xe3, 0x00f5}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f53}, {0xe2, 0xa7ff}, {0xe3, 0x00f5}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f54}, {0xe2, 0xa7ff}, {0xe3, 0x00f5}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f55}, {0xe2, 0x3949}, {0xe3, 0x00b0}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f56}, {0xe2, 0x1984}, {0xe3, 0x003f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f57}, {0xe2, 0x82b6}, {0xe3, 0x0061}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f58}, {0xe2, 0x17f8}, {0xe3, 0x006e}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f59}, {0xe2, 0x8291}, {0xe3, 0x006a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f5a}, {0xe2, 0x602a}, {0xe3, 0x0065}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f5b}, {0xe2, 0x2084}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f5c}, {0xe2, 0x0d00}, {0xe3, 0x00fc}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f5d}, {0xe2, 0x0d00}, {0xe3, 0x00eb}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f5e}, {0xe2, 0x2058}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f5f}, {0xe2, 0x1067}, {0xe3, 0x00be}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f60}, {0xe2, 0x1073}, {0xe3, 0x0087}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f61}, {0xe2, 0x1047}, {0xe3, 0x00a9}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f62}, {0xe2, 0x0e5b}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f63}, {0xe2, 0x2262}, {0xe3, 0x009f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f64}, {0xe2, 0x902f}, {0xe3, 0x009f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f65}, {0xe2, 0x902f}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f66}, {0xe2, 0x1c95}, {0xe3, 0x00cf}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f67}, {0xe2, 0x1c50}, {0xe3, 0x00cf}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f68}, {0xe2, 0x0f22}, {0xe3, 0x00ff}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f69}, {0xe2, 0x802f}, {0xe3, 0x009a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f6a}, {0xe2, 0x0d00}, {0xe3, 0x005f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f6b}, {0xe2, 0x4000}, {0xe3, 0x0004}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f6c}, {0xe2, 0x060a}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f6d}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f6e}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f6f}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f70}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f71}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f72}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f73}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f74}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f75}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f76}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f77}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f78}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f79}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f7a}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f7b}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f7c}, {0xe2, 0x802f}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f7d}, {0xe2, 0x2b3a}, {0xe3, 0x00b4}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f7e}, {0xe2, 0x2262}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f7f}, {0xe2, 0x0d00}, {0xe3, 0x009a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f80}, {0xe2, 0x1023}, {0xe3, 0x0061}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f81}, {0xe2, 0x2027}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f82}, {0xe2, 0x428b}, {0xe3, 0x00e6}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f83}, {0xe2, 0x2024}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f84}, {0xe2, 0x82b7}, {0xe3, 0x0084}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f85}, {0xe2, 0x2b24}, {0xe3, 0x0078}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f86}, {0xe2, 0x92b7}, {0xe3, 0x008a}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f87}, {0xe2, 0x1a20}, {0xe3, 0x007f}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f88}, {0xe2, 0x47ff}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f89}, {0xe2, 0x92b5}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f8a}, {0xe2, 0x356d}, {0xe3, 0x00b1}, {0xe0, 0x0dcf},
+ {0xe1, 0x3f8b}, {0xe2, 0x19e4}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
+ {0xe1, 0x0064}, {0xe2, 0x0000}, {0xe0, 0x68c5},
+ {0xe1, 0x3fa0}, {0xe2, 0x9248}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fb0}, {0xe2, 0x3f00}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fa1}, {0xe2, 0x98e2}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fb1}, {0xe2, 0x3f02}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fa2}, {0xe2, 0x92f0}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fb2}, {0xe2, 0x3f11}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fa3}, {0xe2, 0x9842}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fb3}, {0xe2, 0x3f44}, {0xe0, 0x3bcb},
+ {0xe1, 0x0335}, {0xe2, 0x0001}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fa4}, {0xe2, 0xa1d6}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fb4}, {0xe2, 0x3f57}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fa5}, {0xe2, 0x9e3f}, {0xe0, 0x3bcb},
+ {0xe1, 0x3fb5}, {0xe2, 0x3f88}, {0xe0, 0x3bcb},
+ {0xe1, 0x0010}, {0xe2, 0x0000}, {0xe0, 0x6ac9}
+};
+#define RT5670_DSP_PATCH_NUM \
+ (sizeof(rt5670_dsp_patch) / sizeof(rt5670_dsp_patch[0]))
+
+/* DSP init */
+static unsigned short rt5670_dsp_init[][2] = {
+ {0x2260, 0x30d9}, {0x2261, 0x30d9}, {0x2289, 0x7fff}, {0x2290, 0x7fff},
+ {0x2288, 0x0002}, {0x22b2, 0x0002}, {0x2295, 0x0001}, {0x22b3, 0x0001},
+ {0x22d7, 0x0008}, {0x22d8, 0x0009}, {0x22d9, 0x0000}, {0x22da, 0x0001},
+ {0x22fd, 0x009e}, {0x22c1, 0x1006}, {0x22c2, 0x1006}, {0x22c3, 0x1007},
+ {0x22c4, 0x1007}
+};
+#define RT5670_DSP_INIT_NUM \
+ (sizeof(rt5670_dsp_init) / sizeof(rt5670_dsp_init[0]))
+
+/* MCLK rate */
+static unsigned short rt5670_dsp_4096000[][2] = {
+ {0x226c, 0x000c}, {0x226d, 0x000c}, {0x226e, 0x0022},
+};
+#define RT5670_DSP_4096000_NUM \
+ (sizeof(rt5670_dsp_4096000) / sizeof(rt5670_dsp_4096000[0]))
+
+static unsigned short rt5670_dsp_12288000[][2] = {
+ {0x226c, 0x000c}, {0x226d, 0x000c}, {0x226e, 0x0026},
+};
+#define RT5670_DSP_12288000_NUM \
+ (sizeof(rt5670_dsp_12288000) / sizeof(rt5670_dsp_12288000[0]))
+
+static unsigned short rt5670_dsp_11289600[][2] = {
+ {0x226c, 0x0031}, {0x226d, 0x0050}, {0x226e, 0x0009},
+};
+#define RT5670_DSP_11289600_NUM \
+ (sizeof(rt5670_dsp_11289600) / sizeof(rt5670_dsp_11289600[0]))
+
+static unsigned short rt5670_dsp_24576000[][2] = {
+ {0x226c, 0x000c}, {0x226d, 0x000c}, {0x226e, 0x002c},
+};
+#define RT5670_DSP_24576000_NUM \
+ (sizeof(rt5670_dsp_24576000) / sizeof(rt5670_dsp_24576000[0]))
+
+/* sample rate */
+static unsigned short rt5670_dsp_48_441[][2] = {
+ {0x22f2, 0x0058}, {0x2301, 0x0016}
+};
+#define RT5670_DSP_48_441_NUM \
+ (sizeof(rt5670_dsp_48_441) / sizeof(rt5670_dsp_48_441[0]))
+
+static unsigned short rt5670_dsp_24[][2] = {
+ {0x22f2, 0x0058}, {0x2301, 0x0004}
+};
+#define RT5670_DSP_24_NUM (sizeof(rt5670_dsp_24) / sizeof(rt5670_dsp_24[0]))
+
+static unsigned short rt5670_dsp_16[][2] = {
+ {0x22f2, 0x004c}, {0x2301, 0x0002}
+};
+#define RT5670_DSP_16_NUM (sizeof(rt5670_dsp_16) / sizeof(rt5670_dsp_16[0]))
+
+static unsigned short rt5670_dsp_8[][2] = {
+ {0x22f2, 0x004c}, {0x2301, 0x0000}
+};
+#define RT5670_DSP_8_NUM (sizeof(rt5670_dsp_8) / sizeof(rt5670_dsp_8[0]))
+
+/* DSP mode */
+static unsigned short rt5670_dsp_ns[][2] = {
+ {0x22f8, 0x8005}, {0x2375, 0x7ff0}, {0x2376, 0x7990}, {0x2377, 0x7332},
+ {0x2388, 0x7fff}, {0x2389, 0x6000}, {0x238a, 0x0000}, {0x238b, 0x1000},
+ {0x238c, 0x1000}, {0x23a1, 0x2000}, {0x2303, 0x0200}, {0x2304, 0x0032},
+ {0x2305, 0x0000}, {0x230c, 0x0200}, {0x22fb, 0x0000}
+};
+#define RT5670_DSP_NS_NUM \
+ (sizeof(rt5670_dsp_ns) / sizeof(rt5670_dsp_ns[0]))
+
+static unsigned short rt5670_dsp_aec[][2] = {
+ {0x22f8, 0x8003}, {0x232f, 0x00d0}, {0x2355, 0x2666}, {0x2356, 0x2666},
+ {0x2357, 0x2666}, {0x2358, 0x6666}, {0x2359, 0x6666}, {0x235a, 0x6666},
+ {0x235b, 0x7fff}, {0x235c, 0x7fff}, {0x235d, 0x7fff}, {0x235e, 0x7fff},
+ {0x235f, 0x7fff}, {0x2360, 0x7fff}, {0x2361, 0x7fff}, {0x2362, 0x1000},
+ {0x2367, 0x0007}, {0x2368, 0x4000}, {0x2369, 0x0008}, {0x236a, 0x2000},
+ {0x236b, 0x0009}, {0x236c, 0x003c}, {0x236d, 0x0000}, {0x236f, 0x2000},
+ {0x2370, 0x0008}, {0x2371, 0x000a}, {0x2373, 0x0000}, {0x2374, 0x7fff},
+ {0x2375, 0x7ff0}, {0x2376, 0x7990}, {0x2377, 0x7332}, {0x2379, 0x1000},
+ {0x237a, 0x1000}, {0x2388, 0x7fff}, {0x2389, 0x6000}, {0x238a, 0x4000},
+ {0x238b, 0x1000}, {0x238c, 0x1000}, {0x2398, 0x4668}, {0x23a1, 0x2000},
+ {0x23a3, 0x4000}, {0x23ad, 0x2000}, {0x23ae, 0x2000}, {0x23af, 0x2000},
+ {0x23b4, 0x2000}, {0x23b5, 0x2000}, {0x23b6, 0x2000}, {0x23bb, 0x6000},
+ {0x2303, 0x0710}, {0x2304, 0x0332}, {0x230c, 0x0200}, {0x230d, 0x0080},
+ {0x2310, 0x0010}, {0x22fb, 0x0000}
+};
+#define RT5670_DSP_AEC_NUM \
+ (sizeof(rt5670_dsp_aec) / sizeof(rt5670_dsp_aec[0]))
+
+static unsigned short rt5670_dsp_vt[][2] = {
+ {0x22f8, 0x8003}, {0x2371, 0x000a}, {0x2373, 0x0000}, {0x2374, 0x7fff},
+ {0x2375, 0x7ff0}, {0x2376, 0x7990}, {0x2377, 0x7332}, {0x2379, 0x1000},
+ {0x237a, 0x1000}, {0x2388, 0x7fff}, {0x2389, 0x6000}, {0x238b, 0x1000},
+ {0x238c, 0x1000}, {0x23a1, 0x2000}, {0x2304, 0x0332}, {0x230c, 0x0200},
+ {0x22fb, 0x0000}
+};
+#define RT5670_DSP_VT_NUM (sizeof(rt5670_dsp_vt) / sizeof(rt5670_dsp_vt[0]))
+
+static unsigned short rt5670_dsp_vr[][2] = {
+ {0x22f8, 0x8003}, {0x2304, 0x0332}, {0x2305, 0x0000}, {0x2309, 0x0400},
+ {0x230c, 0x0200}, {0x230d, 0x0080}, {0x2310, 0x0004}, {0x232f, 0x0100},
+ {0x2371, 0x000a}, {0x2373, 0x3000}, {0x2374, 0x5000}, {0x2375, 0x7ff0},
+ {0x2376, 0x7990}, {0x2377, 0x7332}, {0x2379, 0x1000}, {0x237a, 0x1000},
+ {0x2386, 0x0200}, {0x2388, 0x4000}, {0x2389, 0x4000}, {0x238a, 0x0000},
+ {0x238b, 0x2000}, {0x238c, 0x1800}, {0x239b, 0x0000}, {0x239c, 0x0a00},
+ {0x239d, 0x0000}, {0x239e, 0x7fff}, {0x239f, 0x0001}, {0x23a1, 0x3000},
+ {0x23a2, 0x1000}, {0x23ad, 0x0000}, {0x23ae, 0x0000}, {0x23af, 0x0000},
+ {0x23c4, 0x2000}, {0x23b0, 0x0000}, {0x23b1, 0x0000}, {0x23b2, 0x0000},
+ {0x23b3, 0x0000}, {0x23b4, 0x0000}, {0x23b5, 0x0000}, {0x23b6, 0x0000},
+ {0x23b7, 0x0000}, {0x23b8, 0x0000}, {0x23b9, 0x0000}, {0x23ba, 0x0000},
+ {0x23bb, 0x0000}, {0x22fb, 0x0000}
+};
+#define RT5670_DSP_VR_NUM (sizeof(rt5670_dsp_vr) / sizeof(rt5670_dsp_vr[0]))
+
+static unsigned short rt5670_dsp_ffp_ns[][2] = {
+ {0x22f8, 0x8003}, {0x2304, 0x8332}, {0x2371, 0x000a}, {0x2373, 0x0000},
+ {0x2374, 0x7fff}, {0x2379, 0x1800}, {0x237a, 0x1800}, {0x230c, 0x0200},
+ {0x23a2, 0x1000}, {0x2388, 0x7000}, {0x238b, 0x2000}, {0x238c, 0x2000},
+ {0x23a8, 0x2000}, {0x23a9, 0x4000}, {0x23aa, 0x0100}, {0x23ab, 0x7800},
+ {0x22fb, 0x0000}
+};
+#define RT5670_DSP_FFP_NS_NUM \
+ (sizeof(rt5670_dsp_ffp_ns) / sizeof(rt5670_dsp_ffp_ns[0]))
+
+static unsigned short rt5670_dsp_48k_sto_ffp[][2] = {
+ {0x22c1, 0x1025}, {0x22c2, 0x1026}, {0x22f8, 0x8004}, {0x22ea, 0x0001},
+ {0x230c, 0x0100}, {0x230d, 0x0100}, {0x2301, 0x0010}, {0x2303, 0x0200},
+ {0x2304, 0x8000}, {0x2305, 0x0000}, {0x2388, 0x6500}, {0x238b, 0x4000},
+ {0x238c, 0x4000}, {0x23a9, 0x2000}, {0x23aa, 0x0200}, {0x23ab, 0x7c00},
+ {0x22fb, 0x0000}
+};
+#define RT5670_DSP_48K_STO_FFP_NUM \
+ (sizeof(rt5670_dsp_48k_sto_ffp) / sizeof(rt5670_dsp_48k_sto_ffp[0]))
+
+static unsigned short rt5670_dsp_2mic_handset[][2] = {
+ {0x22f8, 0x8002}, {0x2301, 0x0002}, {0x2302, 0x0002}, {0x2303, 0x0710},
+ {0x2304, 0x4332}, {0x2305, 0x206c}, {0x236e, 0x0000}, {0x236f, 0x0001},
+ {0x237e, 0x0001}, {0x237f, 0x3800}, {0x2380, 0x3000}, {0x2381, 0x0005},
+ {0x2382, 0x0040}, {0x2383, 0x7fff}, {0x2388, 0x2c00}, {0x2389, 0x2800},
+ {0x238b, 0x1800}, {0x238c, 0x1800}, {0x238f, 0x2000}, {0x239b, 0x0002},
+ {0x239c, 0x0a00}, {0x239f, 0x0001}, {0x230c, 0x0200}, {0x22fb, 0x0000}
+};
+#define RT5670_DSP_2MIC_HANDSET_NUM \
+ (sizeof(rt5670_dsp_2mic_handset) / sizeof(rt5670_dsp_2mic_handset[0]))
+
+static unsigned short rt5670_dsp_2mic_handsfree[][2] = {
+ {0x22f8, 0x8003}, {0x2371, 0x000a}, {0x2373, 0x0000}, {0x2374, 0x7fff},
+ {0x2375, 0x7ff0}, {0x2376, 0x7990}, {0x2377, 0x7332}, {0x2379, 0x1000},
+ {0x237a, 0x1000}, {0x2388, 0x7fff}, {0x2389, 0x6000}, {0x238b, 0x1000},
+ {0x238c, 0x1000}, {0x23a1, 0x2000}, {0x2304, 0x0332}, {0x230c, 0x0200},
+ {0x22fb, 0x0000}
+};
+#define RT5670_DSP_2MIC_HANDSFREE_NUM \
+ (sizeof(rt5670_dsp_2mic_handsfree) / \
+ sizeof(rt5670_dsp_2mic_handsfree[0]))
+
+static unsigned short rt5670_dsp_aec_handsfree[][2] = {
+ {0x22f8, 0x8003}, {0x232f, 0x00d0}, {0x2355, 0x2666}, {0x2356, 0x2666},
+ {0x2357, 0x2666}, {0x2358, 0x6666}, {0x2359, 0x6666}, {0x235a, 0x6666},
+ {0x235b, 0x7fff}, {0x235c, 0x7fff}, {0x235d, 0x7fff}, {0x235e, 0x7fff},
+ {0x235f, 0x7fff}, {0x2360, 0x7fff}, {0x2361, 0x7fff}, {0x2362, 0x1000},
+ {0x2367, 0x0007}, {0x2368, 0x4000}, {0x2369, 0x0008}, {0x236a, 0x2000},
+ {0x236b, 0x0009}, {0x236c, 0x003c}, {0x236d, 0x0000}, {0x236f, 0x2000},
+ {0x2370, 0x0008}, {0x2371, 0x000a}, {0x2373, 0x0000}, {0x2374, 0x7fff},
+ {0x2375, 0x7ff0}, {0x2376, 0x7990}, {0x2377, 0x7332}, {0x2379, 0x1000},
+ {0x237a, 0x1000}, {0x2388, 0x7fff}, {0x2389, 0x6000}, {0x238a, 0x4000},
+ {0x238b, 0x1000}, {0x238c, 0x1000}, {0x2398, 0x4668}, {0x23a1, 0x2000},
+ {0x23a3, 0x4000}, {0x23ad, 0x2000}, {0x23ae, 0x2000}, {0x23af, 0x2000},
+ {0x23b4, 0x2000}, {0x23b5, 0x2000}, {0x23b6, 0x2000}, {0x23bb, 0x6000},
+ {0x2303, 0x0710}, {0x2304, 0x0332}, {0x230c, 0x0200}, {0x230d, 0x0080},
+ {0x2310, 0x0010}, {0x22fb, 0x0000}
+};
+#define RT5670_DSP_AEC_HANDSFREE_NUM \
+ (sizeof(rt5670_dsp_aec_handsfree) / sizeof(rt5670_dsp_aec_handsfree[0]))
+
+/**
+ * rt5670_dsp_done - Wait until DSP is ready.
+ * @codec: SoC Audio Codec device.
+ *
+ * To check voice DSP status and confirm it's ready for next work.
+ *
+ * Returns 0 for success or negative error code.
+ */
+static int rt5670_dsp_done(struct snd_soc_codec *codec)
+{
+ unsigned int count = 0, dsp_val;
+
+ dsp_val = snd_soc_read(codec, RT5670_DSP_CTRL1);
+ while (dsp_val & RT5670_DSP_BUSY_MASK) {
+ if (count > 10)
+ return -EBUSY;
+ dsp_val = snd_soc_read(codec, RT5670_DSP_CTRL1);
+ count++;
+ }
+
+ return 0;
+}
+
+/**
+ * rt5670_dsp_write - Write DSP register.
+ * @codec: SoC audio codec device.
+ * @param: DSP parameters.
+ *
+ * Modify voice DSP register for sound effect. The DSP can be controlled
+ * through DSP command format (0xfc), addr (0xc4), data (0xc5) and cmd (0xc6)
+ * register. It has to wait until the DSP is ready.
+ *
+ * Returns 0 for success or negative error code.
+ */
+static int rt5670_dsp_write(struct snd_soc_codec *codec,
+ unsigned int addr, unsigned int data)
+{
+ unsigned int dsp_val;
+ int ret;
+
+ ret = snd_soc_write(codec, RT5670_DSP_CTRL2, addr);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret);
+ goto err;
+ }
+ ret = snd_soc_write(codec, RT5670_DSP_CTRL3, data);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to write DSP data reg: %d\n", ret);
+ goto err;
+ }
+ dsp_val = RT5670_DSP_I2C_AL_16 | RT5670_DSP_DL_2 |
+ RT5670_DSP_CMD_MW | DSP_CLK_RATE | RT5670_DSP_CMD_EN;
+
+ ret = snd_soc_write(codec, RT5670_DSP_CTRL1, dsp_val);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret);
+ goto err;
+ }
+ ret = rt5670_dsp_done(codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "DSP is busy: %d\n", ret);
+ goto err;
+ }
+
+ return 0;
+
+err:
+ return ret;
+}
+
+/**
+ * rt5670_dsp_read - Read DSP register.
+ * @codec: SoC audio codec device.
+ * @reg: DSP register index.
+ *
+ * Read DSP setting value from voice DSP. The DSP can be controlled
+ * through DSP addr (0xc4), data (0xc5) and cmd (0xc6) register. Each
+ * command has to wait until the DSP is ready.
+ *
+ * Returns DSP register value or negative error code.
+ */
+static unsigned int rt5670_dsp_read(
+ struct snd_soc_codec *codec, unsigned int reg)
+{
+ unsigned int value;
+ unsigned int dsp_val;
+ int ret = 0;
+
+ ret = rt5670_dsp_done(codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "DSP is busy: %d\n", ret);
+ goto err;
+ }
+
+ ret = snd_soc_write(codec, RT5670_DSP_CTRL2, reg);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret);
+ goto err;
+ }
+ dsp_val = RT5670_DSP_I2C_AL_16 | RT5670_DSP_DL_0 | RT5670_DSP_RW_MASK |
+ RT5670_DSP_CMD_MR | DSP_CLK_RATE | RT5670_DSP_CMD_EN;
+
+ ret = snd_soc_write(codec, RT5670_DSP_CTRL1, dsp_val);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret);
+ goto err;
+ }
+
+ ret = rt5670_dsp_done(codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "DSP is busy: %d\n", ret);
+ goto err;
+ }
+
+ ret = snd_soc_write(codec, RT5670_DSP_CTRL2, 0x26);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret);
+ goto err;
+ }
+ dsp_val = RT5670_DSP_DL_1 | RT5670_DSP_CMD_RR | RT5670_DSP_RW_MASK |
+ DSP_CLK_RATE | RT5670_DSP_CMD_EN;
+
+ ret = snd_soc_write(codec, RT5670_DSP_CTRL1, dsp_val);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret);
+ goto err;
+ }
+
+ ret = rt5670_dsp_done(codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "DSP is busy: %d\n", ret);
+ goto err;
+ }
+
+ ret = snd_soc_write(codec, RT5670_DSP_CTRL2, 0x25);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret);
+ goto err;
+ }
+
+ dsp_val = RT5670_DSP_DL_1 | RT5670_DSP_CMD_RR | RT5670_DSP_RW_MASK |
+ DSP_CLK_RATE | RT5670_DSP_CMD_EN;
+
+ ret = snd_soc_write(codec, RT5670_DSP_CTRL1, dsp_val);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret);
+ goto err;
+ }
+
+ ret = rt5670_dsp_done(codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "DSP is busy: %d\n", ret);
+ goto err;
+ }
+
+ ret = snd_soc_read(codec, RT5670_DSP_CTRL5);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to read DSP data reg: %d\n", ret);
+ goto err;
+ }
+
+ value = ret;
+ return value;
+
+err:
+ return ret;
+}
+
+static int rt5670_dsp_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = rt5670->dsp_sw;
+
+ return 0;
+}
+
+static int rt5670_dsp_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+
+ if (rt5670->dsp_sw != ucontrol->value.integer.value[0])
+ rt5670->dsp_sw = ucontrol->value.integer.value[0];
+
+ return 0;
+}
+
+/* DSP Path Control 1 */
+static const char * const rt5670_src_rxdp_mode[] = {
+ "Normal", "Divided by 3"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_src_rxdp_enum, RT5670_DSP_PATH1,
+ RT5670_RXDP_SRC_SFT, rt5670_src_rxdp_mode);
+
+static const char * const rt5670_src_txdp_mode[] = {
+ "Normal", "Multiplied by 3"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_src_txdp_enum, RT5670_DSP_PATH1,
+ RT5670_TXDP_SRC_SFT, rt5670_src_txdp_mode);
+
+/* Sound Effect */
+static const char *rt5670_dsp_mode[] = {
+ "Disable", "NS", "AEC", "VT", "VR", "FFP+NS", "48K-stereo+FFP",
+ "2MIC Handset", "2MIC Handsfree", "AEC Handsfree"
+};
+
+static const SOC_ENUM_SINGLE_DECL(rt5670_dsp_enum, 0, 0,
+ rt5670_dsp_mode);
+
+static const struct snd_kcontrol_new rt5670_dsp_snd_controls[] = {
+ /* AEC */
+ SOC_ENUM_EXT("DSP Function Switch", rt5670_dsp_enum,
+ rt5670_dsp_get, rt5670_dsp_put),
+};
+
+/**
+ * rt5670_dsp_conf - Set DSP basic setting.
+ *
+ * @codec: SoC audio codec device.
+ *
+ * Set parameters of basic setting to DSP.
+ *
+ * Returns 0 for success or negative error code.
+ */
+static int rt5670_dsp_conf(struct snd_soc_codec *codec)
+{
+ int ret, i;
+
+ for (i = 0; i < RT5670_DSP_INIT_NUM; i++) {
+ ret = rt5670_dsp_write(codec, rt5670_dsp_init[i][0],
+ rt5670_dsp_init[i][1]);
+ if (ret < 0) {
+ dev_err(codec->dev, "Fail to config Dsp: %d\n", ret);
+ goto conf_err;
+ }
+ }
+
+ return 0;
+
+conf_err:
+
+ return ret;
+}
+
+/**
+ * rt5670_dsp_rate - Set DSP rate setting.
+ *
+ * @codec: SoC audio codec device.
+ * @sys_clk: System clock.
+ * @srate: Sampling rate.
+ *
+ * Set parameters of system clock and sampling rate to DSP.
+ *
+ * Returns 0 for success or negative error code.
+ */
+static int rt5670_dsp_rate(struct snd_soc_codec *codec, int sys_clk,
+ int srate)
+{
+ int ret, i, tab_num;
+ unsigned short (*rate_tab)[2];
+
+ dev_dbg(codec->dev,"rt5670_dsp_rate sys:%d srate:%d\n", sys_clk, srate);
+
+ switch(sys_clk) {
+ case 4096000:
+ rate_tab = rt5670_dsp_4096000;
+ tab_num = RT5670_DSP_4096000_NUM;
+ break;
+ case 11289600:
+ rate_tab = rt5670_dsp_11289600;
+ tab_num = RT5670_DSP_11289600_NUM;
+ break;
+ case 12288000:
+ rate_tab = rt5670_dsp_12288000;
+ tab_num = RT5670_DSP_12288000_NUM;
+ break;
+ case 24576000:
+ rate_tab = rt5670_dsp_24576000;
+ tab_num = RT5670_DSP_24576000_NUM;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ for (i = 0; i < tab_num; i++) {
+ ret = rt5670_dsp_write(codec, rate_tab[i][0], rate_tab[i][1]);
+ if (ret < 0)
+ goto rate_err;
+ }
+
+ switch(srate) {
+ case 8000:
+ rate_tab = rt5670_dsp_8;
+ tab_num = RT5670_DSP_8_NUM;
+ break;
+ case 16000:
+ rate_tab = rt5670_dsp_16;
+ tab_num = RT5670_DSP_16_NUM;
+ break;
+ case 24000:
+ rate_tab = rt5670_dsp_24;
+ tab_num = RT5670_DSP_24_NUM;
+ break;
+ case 44100:
+ case 48000:
+ rate_tab = rt5670_dsp_48_441;
+ tab_num = RT5670_DSP_48_441_NUM;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ for (i = 0; i < tab_num; i++) {
+ ret = rt5670_dsp_write(codec, rate_tab[i][0], rate_tab[i][1]);
+ if (ret < 0)
+ goto rate_err;
+ }
+
+ return 0;
+
+rate_err:
+
+ dev_err(codec->dev, "Fail to set rate parameters: %d\n", ret);
+ return ret;
+}
+
+/**
+ * rt5670_dsp_do_patch - Write DSP patch code.
+ *
+ * @codec: SoC audio codec device.
+ *
+ * Write patch codes to DSP.
+ *
+ * Returns 0 for success or negative error code.
+ */
+static int rt5670_dsp_do_patch(struct snd_soc_codec *codec)
+{
+ int ret, i;
+
+ for (i = 0; i < RT5670_DSP_PATCH_NUM; i++) {
+ ret = snd_soc_write(codec, rt5670_dsp_patch[i][0],
+ rt5670_dsp_patch[i][1]);
+ if (ret < 0)
+ goto patch_err;
+
+
+ if (rt5670_dsp_patch[i][0] == 0xe0) {
+ ret = rt5670_dsp_done(codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "DSP is busy: %d\n", ret);
+ goto patch_err;
+ }
+ }
+ }
+
+ return 0;
+
+patch_err:
+
+ return ret;
+}
+
+/**
+ * rt5670_dsp_set_mode - Set DSP mode parameters.
+ *
+ * @codec: SoC audio codec device.
+ * @mode: DSP mode.
+ *
+ * Set parameters of mode to DSP.
+ * There are three modes which includes " mic AEC + NS + FENS",
+ * "HFBF" and "Far-field pickup".
+ *
+ * Returns 0 for success or negative error code.
+ */
+static int rt5670_dsp_set_mode(struct snd_soc_codec *codec, int mode)
+{
+ int ret, i, tab_num;
+ unsigned short (*mode_tab)[2];
+
+ switch (mode) {
+ case RT5670_DSP_NS:
+ dev_info(codec->dev, "NS\n");
+ mode_tab = rt5670_dsp_ns;
+ tab_num = RT5670_DSP_NS_NUM;
+ break;
+
+ case RT5670_DSP_AEC:
+ dev_info(codec->dev, "AEC\n");
+ mode_tab = rt5670_dsp_aec;
+ tab_num = RT5670_DSP_AEC_NUM;
+ break;
+
+ case RT5670_DSP_VT:
+ dev_info(codec->dev, "VT\n");
+ mode_tab = rt5670_dsp_vt;
+ tab_num = RT5670_DSP_VT_NUM;
+ break;
+
+ case RT5670_DSP_VR:
+ dev_info(codec->dev, "VR\n");
+ mode_tab = rt5670_dsp_vr;
+ tab_num = RT5670_DSP_VR_NUM;
+ break;
+
+ case RT5670_DSP_FFP_NS:
+ dev_info(codec->dev, "FFP_NS\n");
+ mode_tab = rt5670_dsp_ffp_ns;
+ tab_num = RT5670_DSP_FFP_NS_NUM;
+ break;
+
+ case RT5670_DSP_48K_STO_FFP:
+ dev_info(codec->dev, "48K_STO_FFP\n");
+ mode_tab = rt5670_dsp_48k_sto_ffp;
+ tab_num = RT5670_DSP_48K_STO_FFP_NUM;
+ break;
+
+ case RT5670_DSP_2MIC_HANDSET:
+ dev_info(codec->dev, "2MIC_HANDSET\n");
+ mode_tab = rt5670_dsp_2mic_handset;
+ tab_num = RT5670_DSP_2MIC_HANDSET_NUM;
+ break;
+
+ case RT5670_DSP_2MIC_HANDSFREE:
+ dev_info(codec->dev, "2MIC_HANDSFREE\n");
+ mode_tab = rt5670_dsp_2mic_handsfree;
+ tab_num = RT5670_DSP_2MIC_HANDSFREE_NUM;
+ break;
+
+ case RT5670_DSP_AEC_HANDSFREE:
+ dev_info(codec->dev, "AEC_HANDSFREE\n");
+ mode_tab = rt5670_dsp_aec_handsfree;
+ tab_num = RT5670_DSP_AEC_HANDSFREE_NUM;
+ break;
+
+ case RT5670_DSP_DIS:
+ default:
+ dev_info(codec->dev, "Disable\n");
+ return 0;
+ }
+
+ for (i = 0; i < tab_num; i++) {
+ ret = rt5670_dsp_write(codec, mode_tab[i][0], mode_tab[i][1]);
+ if (ret < 0)
+ goto mode_err;
+ }
+
+ return 0;
+
+mode_err:
+
+ dev_err(codec->dev, "Fail to set mode %d parameters: %d\n", mode, ret);
+ return ret;
+}
+
+/**
+ * rt5670_dsp_snd_effect - Set DSP sound effect.
+ *
+ * Set parameters of sound effect to DSP.
+ *
+ * Returns 0 for success or negative error code.
+ */
+static int rt5670_dsp_snd_effect(struct snd_soc_codec *codec)
+{
+ struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+ int ret;
+
+ snd_soc_update_bits(codec, RT5670_DIG_MISC, RT5670_RST_DSP,
+ RT5670_RST_DSP);
+ snd_soc_update_bits(codec, RT5670_DIG_MISC, RT5670_RST_DSP, 0);
+
+ mdelay(10);
+/* Expend 1.6 seconds
+ ret = rt5670_dsp_do_patch(codec);
+ if (ret < 0)
+ goto effect_err;
+*/
+ ret = rt5670_dsp_rate(codec,
+ rt5670->sysclk ?
+ rt5670->sysclk : 11289600,
+ rt5670->lrck[rt5670->aif_pu] ?
+ rt5670->lrck[rt5670->aif_pu] : 44100);
+ if (ret < 0)
+ goto effect_err;
+
+ ret = rt5670_dsp_conf(codec);
+ if (ret < 0)
+ goto effect_err;
+
+ ret = rt5670_dsp_set_mode(codec, rt5670->dsp_sw);
+ if (ret < 0)
+ goto effect_err;
+
+ return 0;
+
+effect_err:
+
+ return ret;
+}
+
+static int rt5670_dsp_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMD:
+ dev_dbg(codec->dev, "%s(): PMD\n", __func__);
+ rt5670_dsp_write(codec, 0x22f9, 1);
+ break;
+
+ case SND_SOC_DAPM_POST_PMU:
+ dev_dbg(codec->dev, "%s(): PMU\n", __func__);
+ rt5670_dsp_snd_effect(codec);
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+static const struct snd_soc_dapm_widget rt5670_dsp_dapm_widgets[] = {
+ SND_SOC_DAPM_SUPPLY_S("Voice DSP", 1, SND_SOC_NOPM,
+ 0, 0, rt5670_dsp_event,
+ SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
+ SND_SOC_DAPM_PGA("DSP Downstream", SND_SOC_NOPM,
+ 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("DSP Upstream", SND_SOC_NOPM,
+ 0, 0, NULL, 0),
+};
+
+static const struct snd_soc_dapm_route rt5670_dsp_dapm_routes[] = {
+ {"DSP Downstream", NULL, "Voice DSP"},
+ {"DSP Downstream", NULL, "RxDP Mux"},
+ {"DSP Upstream", NULL, "Voice DSP"},
+ {"DSP Upstream", NULL, "8CH TDM Data"},
+ {"DSP DL Mux", "DSP", "DSP Downstream"},
+ {"DSP UL Mux", "DSP", "DSP Upstream"},
+};
+
+/**
+ * rt5670_dsp_show - Dump DSP registers.
+ * @dev: codec device.
+ * @attr: device attribute.
+ * @buf: buffer for display.
+ *
+ * To show non-zero values of all DSP registers.
+ *
+ * Returns buffer length.
+ */
+static ssize_t rt5670_dsp_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct rt5670_priv *rt5670 = i2c_get_clientdata(client);
+ struct snd_soc_codec *codec = rt5670->codec;
+ unsigned short (*rt5670_dsp_tab)[2];
+ unsigned int val;
+ int cnt = 0, i, tab_num;
+
+ switch (rt5670->dsp_sw) {
+ case RT5670_DSP_NS:
+ cnt += sprintf(buf, "[ RT5642 DSP 'NS' ]\n");
+ rt5670_dsp_tab = rt5670_dsp_ns;
+ tab_num = RT5670_DSP_NS_NUM;
+ break;
+
+ case RT5670_DSP_AEC:
+ cnt += sprintf(buf, "[ RT5642 DSP 'AEC' ]\n");
+ rt5670_dsp_tab = rt5670_dsp_aec;
+ tab_num = RT5670_DSP_AEC_NUM;
+ break;
+
+ case RT5670_DSP_VT:
+ cnt += sprintf(buf, "[ RT5642 DSP 'VT' ]\n");
+ rt5670_dsp_tab = rt5670_dsp_vt;
+ tab_num = RT5670_DSP_VT_NUM;
+ break;
+
+ case RT5670_DSP_VR:
+ cnt += sprintf(buf, "[ RT5642 DSP 'VR' ]\n");
+ rt5670_dsp_tab = rt5670_dsp_vr;
+ tab_num = RT5670_DSP_VR_NUM;
+ break;
+
+ case RT5670_DSP_FFP_NS:
+ cnt += sprintf(buf, "[ RT5642 DSP 'FFP_NS' ]\n");
+ rt5670_dsp_tab = rt5670_dsp_ffp_ns;
+ tab_num = RT5670_DSP_FFP_NS_NUM;
+ break;
+
+ case RT5670_DSP_48K_STO_FFP:
+ cnt += sprintf(buf, "[ RT5642 DSP '48K_STO_FFP' ]\n");
+ rt5670_dsp_tab = rt5670_dsp_48k_sto_ffp;
+ tab_num = RT5670_DSP_48K_STO_FFP_NUM;
+ break;
+
+ case RT5670_DSP_2MIC_HANDSET:
+ cnt += sprintf(buf, "[ RT5642 DSP '2MIC_HANDSET' ]\n");
+ rt5670_dsp_tab = rt5670_dsp_2mic_handset;
+ tab_num = RT5670_DSP_2MIC_HANDSET_NUM;
+ break;
+
+ case RT5670_DSP_2MIC_HANDSFREE:
+ cnt += sprintf(buf, "[ RT5642 DSP '2MIC_HANDSFREE' ]\n");
+ rt5670_dsp_tab = rt5670_dsp_2mic_handsfree;
+ tab_num = RT5670_DSP_2MIC_HANDSFREE_NUM;
+ break;
+
+ case RT5670_DSP_AEC_HANDSFREE:
+ cnt += sprintf(buf, "[ RT5642 DSP 'AEC_HANDSFREE' ]\n");
+ rt5670_dsp_tab = rt5670_dsp_aec_handsfree;
+ tab_num = RT5670_DSP_AEC_HANDSFREE_NUM;
+ break;
+
+ case RT5670_DSP_DIS:
+ default:
+ cnt += sprintf(buf, "RT5642 DSP Disabled\n");
+ goto dsp_done;
+ }
+
+ for (i = 0; i < tab_num; i++) {
+ if (cnt + RT5670_DSP_REG_DISP_LEN >= PAGE_SIZE)
+ break;
+ val = rt5670_dsp_read(codec, rt5670_dsp_tab[i][0]);
+ if (!val)
+ continue;
+ cnt += snprintf(buf + cnt, RT5670_DSP_REG_DISP_LEN,
+ "%04x: %04x\n", rt5670_dsp_tab[i][0], val);
+ }
+
+ rt5670_dsp_tab = rt5670_dsp_init;
+ tab_num = RT5670_DSP_INIT_NUM;
+ for (i = 0; i < tab_num; i++) {
+ if (cnt + RT5670_DSP_REG_DISP_LEN >= PAGE_SIZE)
+ break;
+ val = rt5670_dsp_read(codec, rt5670_dsp_tab[i][0]);
+ if (!val)
+ continue;
+ cnt += snprintf(buf + cnt, RT5670_DSP_REG_DISP_LEN,
+ "%04x: %04x\n",
+ rt5670_dsp_tab[i][0], val);
+ }
+
+dsp_done:
+
+ if (cnt >= PAGE_SIZE)
+ cnt = PAGE_SIZE - 1;
+
+ return cnt;
+}
+
+static ssize_t dsp_reg_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct rt5670_priv *rt5670 = i2c_get_clientdata(client);
+ struct snd_soc_codec *codec = rt5670->codec;
+ unsigned int val = 0, addr = 0;
+ int i;
+
+ pr_debug("register \"%s\" count = %d\n", buf, count);
+
+ /* address */
+ for (i = 0; i < count; i++)
+ if (*(buf + i) <= '9' && *(buf + i) >= '0')
+ addr = (addr << 4) | (*(buf + i) - '0');
+ else if (*(buf + i) <= 'f' && *(buf + i) >= 'a')
+ addr = (addr << 4) | ((*(buf + i) - 'a') + 0xa);
+ else if (*(buf + i) <= 'A' && *(buf + i) >= 'A')
+ addr = (addr << 4) | ((*(buf + i) - 'A') + 0xa);
+ else
+ break;
+
+ /* Value*/
+ for (i = i + 1; i < count; i++)
+ if (*(buf + i) <= '9' && *(buf + i) >= '0')
+ val = (val << 4) | (*(buf + i) - '0');
+ else if (*(buf + i) <= 'f' && *(buf + i) >= 'a')
+ val = (val << 4) | ((*(buf + i) - 'a') + 0xa);
+ else if (*(buf + i) <= 'F' && *(buf + i) >= 'A')
+ val = (val << 4) | ((*(buf + i) - 'A') + 0xa);
+ else
+ break;
+
+ pr_debug("addr=0x%x val=0x%x\n", addr, val);
+ if (i == count)
+ pr_debug("0x%04x = 0x%04x\n",
+ addr, rt5670_dsp_read(codec, addr));
+ else
+ rt5670_dsp_write(codec, addr, val);
+
+ return count;
+}
+static DEVICE_ATTR(dsp_reg, 0666, rt5670_dsp_show, dsp_reg_store);
+
+/**
+ * rt5670_dsp_probe - register DSP for rt5670
+ * @codec: audio codec
+ *
+ * To register DSP function for rt5670.
+ *
+ * Returns 0 for success or negative error code.
+ */
+int rt5670_dsp_probe(struct snd_soc_codec *codec)
+{
+ int ret;
+
+ if (codec == NULL)
+ return -EINVAL;
+
+ snd_soc_update_bits(codec, RT5670_PWR_DIG2,
+ RT5670_PWR_I2S_DSP, RT5670_PWR_I2S_DSP);
+
+ snd_soc_update_bits(codec, RT5670_DIG_MISC, RT5670_RST_DSP,
+ RT5670_RST_DSP);
+ snd_soc_update_bits(codec, RT5670_DIG_MISC, RT5670_RST_DSP, 0);
+
+ mdelay(10);
+
+ rt5670_dsp_write(codec, 0x22fb, 0);
+ /* power down DSP*/
+ rt5670_dsp_write(codec, 0x22f9, 1);
+
+ snd_soc_update_bits(codec, RT5670_PWR_DIG2,
+ RT5670_PWR_I2S_DSP, 0);
+
+ snd_soc_add_codec_controls(codec, rt5670_dsp_snd_controls,
+ ARRAY_SIZE(rt5670_dsp_snd_controls));
+ snd_soc_dapm_new_controls(&codec->dapm, rt5670_dsp_dapm_widgets,
+ ARRAY_SIZE(rt5670_dsp_dapm_widgets));
+ snd_soc_dapm_add_routes(&codec->dapm, rt5670_dsp_dapm_routes,
+ ARRAY_SIZE(rt5670_dsp_dapm_routes));
+
+ ret = device_create_file(codec->dev, &dev_attr_dsp_reg);
+ if (ret != 0) {
+ dev_err(codec->dev,
+ "Failed to create index_reg sysfs files: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rt5670_dsp_probe);
+
+#ifdef RTK_IOCTL
+int rt5670_dsp_ioctl_common(struct snd_hwdep *hw,
+ struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct rt_codec_cmd rt_codec;
+ int *buf;
+ int *p;
+ int ret;
+
+ struct rt_codec_cmd __user *_rt_codec = (struct rt_codec_cmd *)arg;
+ struct snd_soc_codec *codec = hw->private_data;
+ struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+
+ if (copy_from_user(&rt_codec, _rt_codec, sizeof(rt_codec))) {
+ dev_err(codec->dev, "copy_from_user faild\n");
+ return -EFAULT;
+ }
+ dev_dbg(codec->dev, "rt_codec.number=%d\n", rt_codec.number);
+ buf = kmalloc(sizeof(*buf) * rt_codec.number, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+ if (copy_from_user(buf, rt_codec.buf, sizeof(*buf) * rt_codec.number))
+ goto err;
+
+ ret = snd_soc_update_bits(codec, RT5670_PWR_DIG2,
+ RT5670_PWR_I2S_DSP, RT5670_PWR_I2S_DSP);
+ if (ret < 0) {
+ dev_err(codec->dev,
+ "Failed to power up DSP IIS interface: %d\n", ret);
+ goto err;
+ }
+
+ switch (cmd) {
+ case RT_READ_CODEC_DSP_IOCTL:
+ for (p = buf; p < buf + rt_codec.number / 2; p++)
+ *(p + rt_codec.number / 2) = rt5670_dsp_read(codec, *p);
+ if (copy_to_user(rt_codec.buf, buf,
+ sizeof(*buf) * rt_codec.number))
+ goto err;
+ break;
+
+ case RT_WRITE_CODEC_DSP_IOCTL:
+ if (codec == NULL) {
+ dev_dbg(codec->dev, "codec is null\n");
+ break;
+ }
+ for (p = buf; p < buf + rt_codec.number / 2; p++)
+ rt5670_dsp_write(codec, *p, *(p + rt_codec.number / 2));
+ break;
+
+ case RT_GET_CODEC_DSP_MODE_IOCTL:
+ *buf = rt5670->dsp_sw;
+ if (copy_to_user(rt_codec.buf, buf,
+ sizeof(*buf) * rt_codec.number))
+ goto err;
+ break;
+
+ default:
+ dev_info(codec->dev, "unsported dsp command\n");
+ break;
+ }
+
+ kfree(buf);
+ return 0;
+
+err:
+ kfree(buf);
+ return -EFAULT;
+}
+EXPORT_SYMBOL_GPL(rt5670_dsp_ioctl_common);
+#endif
+
+#ifdef CONFIG_PM
+int rt5670_dsp_suspend(struct snd_soc_codec *codec)
+{
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rt5670_dsp_suspend);
+
+int rt5670_dsp_resume(struct snd_soc_codec *codec)
+{
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rt5670_dsp_resume);
+#endif
+
diff --git a/sound/soc/codecs/rt5670-dsp.h b/sound/soc/codecs/rt5670-dsp.h
new file mode 100644
index 00000000..18c545a1
--- /dev/null
+++ b/sound/soc/codecs/rt5670-dsp.h
@@ -0,0 +1,79 @@
+/*
+ * rt5670-dsp.h -- RT5670 ALSA SoC DSP driver
+ *
+ * Copyright 2011 Realtek Microelectronics
+ * Author: Johnny Hsu <johnnyhsu@realtek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __RT5670_DSP_H__
+#define __RT5670_DSP_H__
+
+#define RT5670_DSP_CTRL1 0xe0
+#define RT5670_DSP_CTRL2 0xe1
+#define RT5670_DSP_CTRL3 0xe2
+#define RT5670_DSP_CTRL4 0xe3
+#define RT5670_DSP_CTRL5 0xe4
+
+/* DSP Control 1 (0xe0) */
+#define RT5670_DSP_CMD_MASK (0xff << 8)
+#define RT5670_DSP_CMD_PE (0x0d << 8) /* Patch Entry */
+#define RT5670_DSP_CMD_MW (0x3b << 8) /* Memory Write */
+#define RT5670_DSP_CMD_MR (0x37 << 8) /* Memory Read */
+#define RT5670_DSP_CMD_RR (0x60 << 8) /* Register Read */
+#define RT5670_DSP_CMD_RW (0x68 << 8) /* Register Write */
+#define RT5670_DSP_REG_DATHI (0x26 << 8) /* High Data Addr */
+#define RT5670_DSP_REG_DATLO (0x25 << 8) /* Low Data Addr */
+#define RT5670_DSP_CLK_MASK (0x3 << 6)
+#define RT5670_DSP_CLK_SFT 6
+#define RT5670_DSP_CLK_768K (0x0 << 6)
+#define RT5670_DSP_CLK_384K (0x1 << 6)
+#define RT5670_DSP_CLK_192K (0x2 << 6)
+#define RT5670_DSP_CLK_96K (0x3 << 6)
+#define RT5670_DSP_BUSY_MASK (0x1 << 5)
+#define RT5670_DSP_RW_MASK (0x1 << 4)
+#define RT5670_DSP_DL_MASK (0x3 << 2)
+#define RT5670_DSP_DL_0 (0x0 << 2)
+#define RT5670_DSP_DL_1 (0x1 << 2)
+#define RT5670_DSP_DL_2 (0x2 << 2)
+#define RT5670_DSP_DL_3 (0x3 << 2)
+#define RT5670_DSP_I2C_AL_16 (0x1 << 1)
+#define RT5670_DSP_CMD_EN (0x1)
+
+/* Debug String Length */
+#define RT5670_DSP_REG_DISP_LEN 25
+
+
+enum {
+ RT5670_DSP_DIS,
+ RT5670_DSP_NS,
+ RT5670_DSP_AEC,
+ RT5670_DSP_VT,
+ RT5670_DSP_VR,
+ RT5670_DSP_FFP_NS,
+ RT5670_DSP_48K_STO_FFP,
+ RT5670_DSP_2MIC_HANDSET,
+ RT5670_DSP_2MIC_HANDSFREE,
+ RT5670_DSP_AEC_HANDSFREE,
+};
+
+struct rt5670_dsp_param {
+ u16 cmd_fmt;
+ u16 addr;
+ u16 data;
+ u8 cmd;
+};
+
+int rt5670_dsp_probe(struct snd_soc_codec *codec);
+int rt5670_dsp_ioctl_common(struct snd_hwdep *hw,
+ struct file *file, unsigned int cmd, unsigned long arg);
+#ifdef CONFIG_PM
+int rt5670_dsp_suspend(struct snd_soc_codec *codec);
+int rt5670_dsp_resume(struct snd_soc_codec *codec);
+#endif
+
+#endif /* __RT5670_DSP_H__ */
+
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c
new file mode 100644
index 00000000..81d7e11f
--- /dev/null
+++ b/sound/soc/codecs/rt5670.c
@@ -0,0 +1,3826 @@
+/*
+ * rt5670.c -- RT5670 ALSA SoC audio codec driver
+ *
+ * Copyright 2012 Realtek Semiconductor Corp.
+ * Author: Bard Liao <bardliao@realtek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/jack.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+
+#define RTK_IOCTL
+#ifdef RTK_IOCTL
+#if defined(CONFIG_SND_HWDEP) || defined(CONFIG_SND_HWDEP_MODULE)
+#include "rt_codec_ioctl.h"
+#include "rt5670_ioctl.h"
+#endif
+#endif
+
+#include "rt5670.h"
+#include "rt5670-dsp.h"
+
+static int pmu_depop_time = 80;
+module_param(pmu_depop_time, int, 0644);
+
+static int hp_amp_time = 20;
+module_param(hp_amp_time, int, 0644);
+
+#define RT5672
+#define RT5670_DET_EXT_MIC 0
+//#define USE_INT_CLK
+#define JD1_FUNC
+//#define ALC_DRC_FUNC
+//#define USE_ASRC
+//#define USE_TDM
+//#define NVIDIA_DALMORE
+
+#define VERSION "0.0.7 alsa 1.0.25"
+
+struct snd_soc_codec *rt5670_codec;
+
+struct rt5670_init_reg {
+ u8 reg;
+ u16 val;
+};
+
+static struct rt5670_init_reg init_list[] = {
+ { RT5670_DIG_MISC , 0xc019 }, /* fa[0]=1, fa[3]=1'b MCLK det, fa[15:14]=11'b for pdm */
+ { RT5670_ADDA_CLK1 , 0x0000 },
+ { RT5670_IL_CMD2 , 0x0010 }, /* set Inline Command Window */
+// { RT5670_A_JD_CTRL1 , 0x0001 }, /* set JD1 mode 1 (1 port) */
+ { RT5670_PRIV_INDEX , 0x0014 },
+ { RT5670_PRIV_DATA , 0x9a8a },
+ { RT5670_PRIV_INDEX , 0x003d },
+ { RT5670_PRIV_DATA , 0x3640 },
+ { RT5670_GEN_CTRL2 , 0x0030 }, //by walk
+ { RT5670_CJ_CTRL1 , 0x4021 }, //by walk
+ { RT5670_CJ_CTRL2 , 0x28a7 }, //by walk
+ /* playback */
+ { RT5670_STO_DAC_MIXER , 0x1616 }, /* Dig inf 1 -> Sto DAC mixer -> DACL */
+ { RT5670_OUT_L1_MIXER , 0x0072 }, /* DACL1 -> OUTMIXL */
+ { RT5670_OUT_R1_MIXER , 0x00d2 }, /* DACR1 -> OUTMIXR */
+ { RT5670_LOUT_MIXER , 0xc000 },
+ { RT5670_HP_VOL , 0x8888 }, /* OUTMIX -> HPVOL */
+ { RT5670_HPO_MIXER , 0xc00a },
+// { RT5670_HPO_MIXER , 0xa000 }, /* DAC1 -> HPOLMIX */
+ { RT5670_CHARGE_PUMP , 0x0c00 },
+ { RT5670_GPIO_CTRL3 , 0x0d00 }, /* for stereo SPK */
+ /* record */
+ { RT5670_GEN_CTRL3 , 0x0084},
+ { RT5670_REC_L2_MIXER , 0x007d }, /* Mic1 -> RECMIXL */
+ { RT5670_REC_R2_MIXER , 0x0077 }, /* Mic1 -> RECMIXR */
+#if 0 /* DMIC2 */
+ { RT5670_STO1_ADC_MIXER , 0x5940 },
+#else /* AMIC */
+ { RT5670_STO1_ADC_MIXER , 0x3820 }, /* ADC -> Sto ADC mixer */
+#endif
+ { RT5670_STO1_ADC_DIG_VOL, 0xafaf }, /* Mute STO1 ADC for depop */
+ { RT5670_PDM_OUT_CTRL , 0xff01 },
+#ifdef JD1_FUNC
+ { RT5670_GPIO_CTRL2 , 0x0004 },
+ { RT5670_GPIO_CTRL1 , 0x8000 },
+ { RT5670_IRQ_CTRL2 , 0x0200 },
+ { RT5670_JD_CTRL3 , 0x0088 },
+#endif
+#if 0 //DSP
+ { RT5670_STO_DAC_MIXER , 0x4646 },
+ { RT5670_DSP_PATH1 , 0xc000 },
+ //{ RT5670_DSP_PATH1 , 0xc003 }, /* bypass dsp */
+ { RT5670_DAC_CTRL , 0x0033 },
+#endif
+
+};
+#define RT5670_INIT_REG_LEN ARRAY_SIZE(init_list)
+
+#ifdef ALC_DRC_FUNC
+static struct rt5670_init_reg alc_drc_list[] = {
+ { RT5670_ALC_DRC_CTRL1 , 0x0000 },
+ { RT5670_ALC_DRC_CTRL2 , 0x0000 },
+ { RT5670_ALC_CTRL_2 , 0x0000 },
+ { RT5670_ALC_CTRL_3 , 0x0000 },
+ { RT5670_ALC_CTRL_4 , 0x0000 },
+ { RT5670_ALC_CTRL_1 , 0x0000 },
+};
+#define RT5670_ALC_DRC_REG_LEN ARRAY_SIZE(alc_drc_list)
+#endif
+
+static int rt5670_reg_init(struct snd_soc_codec *codec)
+{
+ int i;
+
+ for (i = 0; i < RT5670_INIT_REG_LEN; i++)
+ snd_soc_write(codec, init_list[i].reg, init_list[i].val);
+#ifdef ALC_DRC_FUNC
+ for (i = 0; i < RT5670_ALC_DRC_REG_LEN; i++)
+ snd_soc_write(codec, alc_drc_list[i].reg, alc_drc_list[i].val);
+#endif
+
+ return 0;
+}
+
+static int rt5670_index_sync(struct snd_soc_codec *codec)
+{
+ int i;
+
+ for (i = 0; i < RT5670_INIT_REG_LEN; i++)
+ if (RT5670_PRIV_INDEX == init_list[i].reg ||
+ RT5670_PRIV_DATA == init_list[i].reg)
+ snd_soc_write(codec, init_list[i].reg,
+ init_list[i].val);
+ return 0;
+}
+
+static const u16 rt5670_reg[RT5670_VENDOR_ID2 + 1] = {
+ [RT5670_HP_VOL] = 0x8888,
+ [RT5670_LOUT1] = 0x8888,
+ [RT5670_CJ_CTRL1] = 0x0001,
+ [RT5670_CJ_CTRL2] = 0x0827,
+ [RT5670_IN1_IN2] = 0x0008,
+ [RT5670_INL1_INR1_VOL] = 0x0808,
+ [RT5670_DAC1_DIG_VOL] = 0xafaf,
+ [RT5670_DAC2_DIG_VOL] = 0xafaf,
+ [RT5670_DAC_CTRL] = 0x0011,
+ [RT5670_STO1_ADC_DIG_VOL] = 0x2f2f,
+ [RT5670_MONO_ADC_DIG_VOL] = 0x2f2f,
+ [RT5670_STO2_ADC_DIG_VOL] = 0x2f2f,
+ [RT5670_STO2_ADC_MIXER] = 0x7860,
+ [RT5670_STO1_ADC_MIXER] = 0x7860,
+ [RT5670_MONO_ADC_MIXER] = 0x7871,
+ [RT5670_AD_DA_MIXER] = 0x8080,
+ [RT5670_STO_DAC_MIXER] = 0x5656,
+ [RT5670_DD_MIXER] = 0x5454,
+ [RT5670_DIG_MIXER] = 0xaaa0,
+ [RT5670_DSP_PATH2] = 0x2f2f,
+ [RT5670_DIG_INF1_DATA] = 0x1002,
+ [RT5670_PDM_OUT_CTRL] = 0x5f00,
+ [RT5670_REC_L2_MIXER] = 0x007f,
+ [RT5670_REC_R2_MIXER] = 0x007f,
+ [RT5670_HPO_MIXER] = 0xe00f,
+ [RT5670_MONO_MIXER] = 0x5380,
+ [RT5670_OUT_L1_MIXER] = 0x0073,
+ [RT5670_OUT_R1_MIXER] = 0x00d3,
+ [RT5670_LOUT_MIXER] = 0xf0f0,
+ [RT5670_PWR_DIG2] = 0x0001,
+ [RT5670_PWR_ANLG1] = 0x00c3,
+ [RT5670_I2S4_SDP] = 0x8000,
+ [RT5670_I2S1_SDP] = 0x8000,
+ [RT5670_I2S2_SDP] = 0x8000,
+ [RT5670_I2S3_SDP] = 0x8000,
+ [RT5670_ADDA_CLK1] = 0x1110,
+ [RT5670_ADDA_CLK2] = 0x0e00,
+ [RT5670_DMIC_CTRL1] = 0x1505,
+ [RT5670_DMIC_CTRL2] = 0x0015,
+ [RT5670_TDM_CTRL_1] = 0x0c00,
+ [RT5670_TDM_CTRL_2] = 0x4000,
+ [RT5670_TDM_CTRL_3] = 0x0123,
+ [RT5670_DSP_CLK] = 0x1100,
+ [RT5670_ASRC_4] = 0x0008,
+ [RT5670_ASRC_10] = 0x0007,
+ [RT5670_DEPOP_M1] = 0x0004,
+ [RT5670_DEPOP_M2] = 0x1100,
+ [RT5670_DEPOP_M3] = 0x0646,
+ [RT5670_CHARGE_PUMP] = 0x0c06,
+ [RT5670_VAD_CTRL1] = 0x2184,
+ [RT5670_VAD_CTRL2] = 0x010a,
+ [RT5670_VAD_CTRL3] = 0x0aea,
+ [RT5670_VAD_CTRL4] = 0x000c,
+ [RT5670_VAD_CTRL5] = 0x0400,
+ [RT5670_ADC_EQ_CTRL1] = 0x7000,
+ [RT5670_EQ_CTRL1] = 0x6000,
+ [RT5670_ALC_DRC_CTRL2] = 0x001f,
+ [RT5670_ALC_CTRL_1] = 0x2206,
+ [RT5670_ALC_CTRL_2] = 0x1f00,
+ [RT5670_BASE_BACK] = 0x1813,
+ [RT5670_MP3_PLUS1] = 0x0690,
+ [RT5670_MP3_PLUS2] = 0x1c17,
+ [RT5670_ADJ_HPF1] = 0xb320,
+ [RT5670_HP_CALIB_AMP_DET] = 0x0400,
+ [RT5670_SV_ZCD1] = 0x0809,
+ [RT5670_IL_CMD] = 0x0001,
+ [RT5670_IL_CMD2] = 0x0049,
+ [RT5670_IL_CMD3] = 0x0009,
+ [RT5670_DRC_HL_CTRL1] = 0x8000,
+ [RT5670_ADC_MONO_HP_CTRL1] = 0xb300,
+ [RT5670_ADC_STO2_HP_CTRL1] = 0xb300,
+ [RT5670_DIG_MISC] = 0x8010,
+ [RT5670_GEN_CTRL2] = 0x0033,
+ [RT5670_GEN_CTRL3] = 0x0080,
+};
+
+static int rt5670_reset(struct snd_soc_codec *codec)
+{
+ return snd_soc_write(codec, RT5670_RESET, 0);
+}
+
+/**
+ * rt5670_index_write - Write private register.
+ * @codec: SoC audio codec device.
+ * @reg: Private register index.
+ * @value: Private register Data.
+ *
+ * Modify private register for advanced setting. It can be written through
+ * private index (0x6a) and data (0x6c) register.
+ *
+ * Returns 0 for success or negative error code.
+ */
+static int rt5670_index_write(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value)
+{
+ int ret;
+
+ ret = snd_soc_write(codec, RT5670_PRIV_INDEX, reg);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set private addr: %d\n", ret);
+ goto err;
+ }
+ ret = snd_soc_write(codec, RT5670_PRIV_DATA, value);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set private value: %d\n", ret);
+ goto err;
+ }
+ return 0;
+
+err:
+ return ret;
+}
+
+/**
+ * rt5670_index_read - Read private register.
+ * @codec: SoC audio codec device.
+ * @reg: Private register index.
+ *
+ * Read advanced setting from private register. It can be read through
+ * private index (0x6a) and data (0x6c) register.
+ *
+ * Returns private register value or negative error code.
+ */
+static unsigned int rt5670_index_read(
+ struct snd_soc_codec *codec, unsigned int reg)
+{
+ int ret;
+
+ ret = snd_soc_write(codec, RT5670_PRIV_INDEX, reg);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set private addr: %d\n", ret);
+ return ret;
+ }
+ return snd_soc_read(codec, RT5670_PRIV_DATA);
+}
+
+/**
+ * rt5670_index_update_bits - update private register bits
+ * @codec: audio codec
+ * @reg: Private register index.
+ * @mask: register mask
+ * @value: new value
+ *
+ * Writes new register value.
+ *
+ * Returns 1 for change, 0 for no change, or negative error code.
+ */
+static int rt5670_index_update_bits(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int mask, unsigned int value)
+{
+ unsigned int old, new;
+ int change, ret;
+
+ ret = rt5670_index_read(codec, reg);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to read private reg: %d\n", ret);
+ goto err;
+ }
+
+ old = ret;
+ new = (old & ~mask) | (value & mask);
+ change = old != new;
+ if (change) {
+ ret = rt5670_index_write(codec, reg, new);
+ if (ret < 0) {
+ dev_err(codec->dev,
+ "Failed to write private reg: %d\n", ret);
+ goto err;
+ }
+ }
+ return change;
+
+err:
+ return ret;
+}
+
+static unsigned rt5670_pdm1_read(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ int ret;
+
+ ret = snd_soc_write(codec, RT5670_PDM1_DATA_CTRL2, reg<<8);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set private value: %d\n", ret);
+ goto err;
+ }
+ ret = snd_soc_write(codec, RT5670_PDM_DATA_CTRL1, 0x0200);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set private value: %d\n", ret);
+ goto err;
+ }
+ do{
+ ret = snd_soc_read(codec, RT5670_PDM_DATA_CTRL1);
+ }
+ while(ret & 0x0100);
+ return snd_soc_read(codec, RT5670_PDM1_DATA_CTRL4);
+err:
+ return ret;
+}
+
+static int rt5670_pdm1_write(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value)
+{
+ int ret;
+
+ ret = snd_soc_write(codec, RT5670_PDM1_DATA_CTRL3, value);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set private addr: %d\n", ret);
+ goto err;
+ }
+ ret = snd_soc_write(codec, RT5670_PDM1_DATA_CTRL2, reg<<8);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set private value: %d\n", ret);
+ goto err;
+ }
+ ret = snd_soc_write(codec, RT5670_PDM_DATA_CTRL1, 0x0600);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set private value: %d\n", ret);
+ goto err;
+ }
+ ret = snd_soc_write(codec, RT5670_PDM_DATA_CTRL1, 0x3600);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set private value: %d\n", ret);
+ goto err;
+ }
+ do{
+ ret = snd_soc_read(codec, RT5670_PDM_DATA_CTRL1);
+ }
+ while(ret & 0x0100);
+ return 0;
+
+err:
+ return ret;
+}
+
+static unsigned rt5670_pdm2_read(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ int ret;
+
+ ret = snd_soc_write(codec, RT5670_PDM2_DATA_CTRL2, reg<<8);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set private value: %d\n", ret);
+ goto err;
+ }
+ ret = snd_soc_write(codec, RT5670_PDM_DATA_CTRL1, 0x0002);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set private value: %d\n", ret);
+ goto err;
+ }
+ do{
+ ret = snd_soc_read(codec, RT5670_PDM_DATA_CTRL1);
+ }
+ while(ret & 0x0001);
+ return snd_soc_read(codec, RT5670_PDM2_DATA_CTRL4);
+err:
+ return ret;
+}
+
+static int rt5670_pdm2_write(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value)
+{
+ int ret;
+
+ ret = snd_soc_write(codec, RT5670_PDM2_DATA_CTRL3, value);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set private addr: %d\n", ret);
+ goto err;
+ }
+ ret = snd_soc_write(codec, RT5670_PDM2_DATA_CTRL2, reg<<8);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set private value: %d\n", ret);
+ goto err;
+ }
+ ret = snd_soc_write(codec, RT5670_PDM_DATA_CTRL1, 0x0006);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set private value: %d\n", ret);
+ goto err;
+ }
+ ret = snd_soc_write(codec, RT5670_PDM_DATA_CTRL1, 0x0036);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set private value: %d\n", ret);
+ goto err;
+ }
+ do{
+ ret = snd_soc_read(codec, RT5670_PDM_DATA_CTRL1);
+ }
+ while(ret & 0x0001);
+
+ return 0;
+
+err:
+ return ret;
+}
+
+
+static int rt5670_volatile_register(
+ struct snd_soc_codec *codec, unsigned int reg)
+{
+ switch (reg) {
+ case RT5670_RESET:
+ case RT5670_PDM_DATA_CTRL1:
+ case RT5670_PDM1_DATA_CTRL4:
+ case RT5670_PDM2_DATA_CTRL4:
+ case RT5670_PRIV_DATA:
+ case RT5670_ASRC_5:
+ case RT5670_CJ_CTRL1:
+ case RT5670_CJ_CTRL2:
+ case RT5670_CJ_CTRL3:
+ case RT5670_A_JD_CTRL1:
+ case RT5670_A_JD_CTRL2:
+ case RT5670_VAD_CTRL5:
+ case RT5670_ADC_EQ_CTRL1:
+ case RT5670_EQ_CTRL1:
+ case RT5670_ALC_CTRL_1:
+ case RT5670_IRQ_CTRL2:
+ case RT5670_IRQ_CTRL3:
+ case RT5670_INT_IRQ_ST:
+ case RT5670_IL_CMD:
+ case RT5670_DSP_CTRL1:
+ case RT5670_DSP_CTRL2:
+ case RT5670_DSP_CTRL3:
+ case RT5670_DSP_CTRL4:
+ case RT5670_DSP_CTRL5:
+ case RT5670_VENDOR_ID:
+ case RT5670_VENDOR_ID1:
+ case RT5670_VENDOR_ID2:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int rt5670_readable_register(
+ struct snd_soc_codec *codec, unsigned int reg)
+{
+ switch (reg) {
+ case RT5670_RESET:
+ case RT5670_HP_VOL:
+ case RT5670_LOUT1:
+ case RT5670_CJ_CTRL1:
+ case RT5670_CJ_CTRL2:
+ case RT5670_CJ_CTRL3:
+ case RT5670_IN1_IN2:
+ case RT5670_IN3:
+ case RT5670_INL1_INR1_VOL:
+ case RT5670_DAC1_DIG_VOL:
+ case RT5670_DAC2_DIG_VOL:
+ case RT5670_DAC_CTRL:
+ case RT5670_STO1_ADC_DIG_VOL:
+ case RT5670_MONO_ADC_DIG_VOL:
+ case RT5670_STO2_ADC_DIG_VOL:
+ case RT5670_ADC_BST_VOL1:
+ case RT5670_ADC_BST_VOL2:
+ case RT5670_STO2_ADC_MIXER:
+ case RT5670_STO1_ADC_MIXER:
+ case RT5670_MONO_ADC_MIXER:
+ case RT5670_AD_DA_MIXER:
+ case RT5670_STO_DAC_MIXER:
+ case RT5670_DD_MIXER:
+ case RT5670_DIG_MIXER:
+ case RT5670_DSP_PATH1:
+ case RT5670_DSP_PATH2:
+ case RT5670_DIG_INF1_DATA:
+ case RT5670_DIG_INF2_DATA:
+ case RT5670_PDM_OUT_CTRL:
+ case RT5670_PDM_DATA_CTRL1:
+ case RT5670_PDM1_DATA_CTRL2:
+ case RT5670_PDM1_DATA_CTRL3:
+ case RT5670_PDM1_DATA_CTRL4:
+ case RT5670_PDM2_DATA_CTRL2:
+ case RT5670_PDM2_DATA_CTRL3:
+ case RT5670_PDM2_DATA_CTRL4:
+ case RT5670_REC_L1_MIXER:
+ case RT5670_REC_L2_MIXER:
+ case RT5670_REC_R1_MIXER:
+ case RT5670_REC_R2_MIXER:
+ case RT5670_HPO_MIXER:
+ case RT5670_MONO_MIXER:
+ case RT5670_OUT_L1_MIXER:
+ case RT5670_OUT_R1_MIXER:
+ case RT5670_LOUT_MIXER:
+ case RT5670_PWR_DIG1:
+ case RT5670_PWR_DIG2:
+ case RT5670_PWR_ANLG1:
+ case RT5670_PWR_ANLG2:
+ case RT5670_PWR_MIXER:
+ case RT5670_PWR_VOL:
+ case RT5670_PRIV_INDEX:
+ case RT5670_PRIV_DATA:
+ case RT5670_I2S4_SDP:
+ case RT5670_I2S1_SDP:
+ case RT5670_I2S2_SDP:
+ case RT5670_I2S3_SDP:
+ case RT5670_ADDA_CLK1:
+ case RT5670_ADDA_CLK2:
+ case RT5670_DMIC_CTRL1:
+ case RT5670_DMIC_CTRL2:
+ case RT5670_TDM_CTRL_1:
+ case RT5670_TDM_CTRL_2:
+ case RT5670_TDM_CTRL_3:
+ case RT5670_DSP_CLK:
+ case RT5670_GLB_CLK:
+ case RT5670_PLL_CTRL1:
+ case RT5670_PLL_CTRL2:
+ case RT5670_ASRC_1:
+ case RT5670_ASRC_2:
+ case RT5670_ASRC_3:
+ case RT5670_ASRC_4:
+ case RT5670_ASRC_5:
+ case RT5670_ASRC_7:
+ case RT5670_ASRC_8:
+ case RT5670_ASRC_9:
+ case RT5670_ASRC_10:
+ case RT5670_ASRC_11:
+ case RT5670_ASRC_12:
+ case RT5670_ASRC_13:
+ case RT5670_ASRC_14:
+ case RT5670_DEPOP_M1:
+ case RT5670_DEPOP_M2:
+ case RT5670_DEPOP_M3:
+ case RT5670_CHARGE_PUMP:
+ case RT5670_MICBIAS:
+ case RT5670_A_JD_CTRL1:
+ case RT5670_A_JD_CTRL2:
+ case RT5670_VAD_CTRL1:
+ case RT5670_VAD_CTRL2:
+ case RT5670_VAD_CTRL3:
+ case RT5670_VAD_CTRL4:
+ case RT5670_VAD_CTRL5:
+ case RT5670_ADC_EQ_CTRL1:
+ case RT5670_ADC_EQ_CTRL2:
+ case RT5670_EQ_CTRL1:
+ case RT5670_EQ_CTRL2:
+ case RT5670_ALC_DRC_CTRL1:
+ case RT5670_ALC_DRC_CTRL2:
+ case RT5670_ALC_CTRL_1:
+ case RT5670_ALC_CTRL_2:
+ case RT5670_ALC_CTRL_3:
+ case RT5670_JD_CTRL:
+ case RT5670_IRQ_CTRL1:
+ case RT5670_IRQ_CTRL2:
+ case RT5670_IRQ_CTRL3:
+ case RT5670_INT_IRQ_ST:
+ case RT5670_GPIO_CTRL1:
+ case RT5670_GPIO_CTRL2:
+ case RT5670_GPIO_CTRL3:
+ case RT5670_SCRABBLE_FUN:
+ case RT5670_SCRABBLE_CTRL:
+ case RT5670_BASE_BACK:
+ case RT5670_MP3_PLUS1:
+ case RT5670_MP3_PLUS2:
+ case RT5670_ADJ_HPF1:
+ case RT5670_ADJ_HPF2:
+ case RT5670_HP_CALIB_AMP_DET:
+ case RT5670_SV_ZCD1:
+ case RT5670_SV_ZCD2:
+ case RT5670_IL_CMD:
+ case RT5670_IL_CMD2:
+ case RT5670_IL_CMD3:
+ case RT5670_DRC_HL_CTRL1:
+ case RT5670_DRC_HL_CTRL2:
+ case RT5670_ADC_MONO_HP_CTRL1:
+ case RT5670_ADC_MONO_HP_CTRL2:
+ case RT5670_ADC_STO2_HP_CTRL1:
+ case RT5670_ADC_STO2_HP_CTRL2:
+ case RT5670_JD_CTRL3:
+ case RT5670_JD_CTRL4:
+ case RT5670_DIG_MISC:
+ case RT5670_DSP_CTRL1:
+ case RT5670_DSP_CTRL2:
+ case RT5670_DSP_CTRL3:
+ case RT5670_DSP_CTRL4:
+ case RT5670_DSP_CTRL5:
+ case RT5670_GEN_CTRL2:
+ case RT5670_GEN_CTRL3:
+ case RT5670_VENDOR_ID:
+ case RT5670_VENDOR_ID1:
+ case RT5670_VENDOR_ID2:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/**
+ * rt5670_headset_detect - Detect headset.
+ * @codec: SoC audio codec device.
+ * @jack_insert: Jack insert or not.
+ *
+ * Detect whether is headset or not when jack inserted.
+ *
+ * Returns detect status.
+ */
+
+int rt5670_headset_detect(struct snd_soc_codec *codec, int jack_insert)
+{
+ int jack_type, val;
+
+ if(jack_insert) {
+ snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x0);
+ snd_soc_update_bits(codec, RT5670_CJ_CTRL2,
+ RT5670_CBJ_DET_MODE | RT5670_CBJ_MN_JD,
+ RT5670_CBJ_MN_JD);
+ snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
+ RT5670_PWR_JD1, RT5670_PWR_JD1);
+ snd_soc_update_bits(codec, RT5670_DIG_MISC, 0x1, 0x1);
+ snd_soc_write(codec, RT5670_GPIO_CTRL2, 0x0004);
+ snd_soc_update_bits(codec, RT5670_GPIO_CTRL1,
+ RT5670_GP1_PIN_MASK, RT5670_GP1_PIN_IRQ);
+
+ snd_soc_update_bits(codec, RT5670_CJ_CTRL1,
+ RT5670_CBJ_BST1_EN, RT5670_CBJ_BST1_EN);
+ snd_soc_write(codec, RT5670_JD_CTRL3, 0x00f0);
+ snd_soc_update_bits(codec, RT5670_CJ_CTRL2,
+ RT5670_CBJ_MN_JD, RT5670_CBJ_MN_JD);
+ snd_soc_update_bits(codec, RT5670_CJ_CTRL2,
+ RT5670_CBJ_MN_JD, 0);
+ msleep(500);
+ val = snd_soc_read(codec, RT5670_CJ_CTRL3) & 0x7;
+ pr_debug("val=%d\n",val);
+ if (val == 0x1 || val == 0x2) {
+ jack_type = SND_JACK_HEADSET;
+ /* for push button */
+ snd_soc_update_bits(codec, RT5670_INT_IRQ_ST, 0x8, 0x8);
+ snd_soc_update_bits(codec, RT5670_IL_CMD, 0x40, 0x40);
+ snd_soc_read(codec, RT5670_IL_CMD);
+ } else {
+ snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4);
+ jack_type = SND_JACK_HEADPHONE;
+ }
+ } else {
+ snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4);
+ snd_soc_update_bits(codec, RT5670_INT_IRQ_ST, 0x8, 0x0);
+ jack_type = 0;
+ }
+
+ pr_debug("jack_type=%d\n",jack_type);
+ return jack_type;
+}
+EXPORT_SYMBOL(rt5670_headset_detect);
+
+int rt5670_button_detect(struct snd_soc_codec *codec)
+{
+ int btn_type, val;
+
+ snd_soc_update_bits(codec, RT5670_IL_CMD, 0x40, 0x40);
+
+ val = snd_soc_read(codec, RT5670_IL_CMD);
+ btn_type = val & 0xff80;
+ pr_debug("btn_type=0x%x\n",btn_type);
+ snd_soc_write(codec, RT5670_IL_CMD, val);
+ return btn_type;
+}
+EXPORT_SYMBOL(rt5670_button_detect);
+
+int rt5670_check_interrupt_event(struct snd_soc_codec *codec, int *data)
+{
+ struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+ int val, event_type;
+
+ val = snd_soc_read(codec, RT5670_A_JD_CTRL1) & 0x0020;
+ *data = 0;
+ switch (val) {
+ case 0x0:
+ /* jack insert */
+ if (rt5670->jack_type == 0) {
+ snd_soc_dapm_force_enable_pin(&codec->dapm, "Mic Det Power");
+ snd_soc_dapm_sync(&codec->dapm);
+ rt5670->jack_type = rt5670_headset_detect(codec, 1);
+ *data = rt5670->jack_type;
+ return RT5670_J_IN_EVENT;
+ }
+ event_type = 0;
+ if (snd_soc_read(codec, RT5670_INT_IRQ_ST) & 0x4) {
+ /* button event */
+ event_type |= RT5670_BTN_EVENT;
+ *data = rt5670_button_detect(codec);
+ }
+ msleep(20);
+ if (*data == 0 ||
+ ((snd_soc_read(codec, RT5670_IL_CMD) & 0xff80) == 0)) {
+ pr_debug("button release\n");
+ event_type = RT5670_BR_EVENT;
+ *data = 0;
+ }
+ return (event_type == 0 ? RT5670_UN_EVENT : event_type);
+ case 0x20:
+ default:
+ rt5670->jack_type = rt5670_headset_detect(codec, 0);
+ snd_soc_dapm_disable_pin(&codec->dapm, "Mic Det Power");
+ snd_soc_dapm_sync(&codec->dapm);
+ return RT5670_J_OUT_EVENT;
+ }
+
+ return RT5670_UN_EVENT;
+}
+EXPORT_SYMBOL(rt5670_check_interrupt_event);
+
+static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
+static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0);
+static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
+static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0);
+static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0);
+
+/* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */
+static unsigned int bst_tlv[] = {
+ TLV_DB_RANGE_HEAD(7),
+ 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
+ 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
+ 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0),
+ 3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0),
+ 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0),
+ 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0),
+ 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0),
+};
+
+/* IN1/IN2 Input Type */
+static const char *rt5670_input_mode[] = {
+ "Single ended", "Differential"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_in1_mode_enum, RT5670_IN1_IN2,
+ RT5670_IN_SFT1, rt5670_input_mode);
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_in2_mode_enum, RT5670_IN3,
+ RT5670_IN_SFT2, rt5670_input_mode);
+
+/* Interface data select */
+static const char *rt5670_data_select[] = {
+ "Normal", "Swap", "left copy to right", "right copy to left"
+};
+
+static const SOC_ENUM_SINGLE_DECL(rt5670_if2_dac_enum, RT5670_DIG_INF1_DATA,
+ RT5670_IF2_DAC_SEL_SFT, rt5670_data_select);
+
+static const SOC_ENUM_SINGLE_DECL(rt5670_if2_adc_enum, RT5670_DIG_INF1_DATA,
+ RT5670_IF2_ADC_SEL_SFT, rt5670_data_select);
+
+static const char *rt5670_tdm_adc_location_select[] = {
+ "1L/1R/2L/2R/3L/3R/4L/4R", "2L/2R/1L/1R/4L/4R/3L/3R"
+};
+
+static const SOC_ENUM_SINGLE_DECL(rt5670_tdm_adc_location_enum,
+ RT5670_TDM_CTRL_1, 9,
+ rt5670_tdm_adc_location_select);
+
+static const char *rt5670_tdm_data_swap_select[] = {
+ "L/R", "R/L", "L/L", "R/R"
+};
+
+static const SOC_ENUM_SINGLE_DECL(rt5670_tdm_adc_slot0_1_enum,
+ RT5670_TDM_CTRL_1, 6,
+ rt5670_tdm_data_swap_select);
+
+static const SOC_ENUM_SINGLE_DECL(rt5670_tdm_adc_slot2_3_enum,
+ RT5670_TDM_CTRL_1, 4,
+ rt5670_tdm_data_swap_select);
+
+static const SOC_ENUM_SINGLE_DECL(rt5670_tdm_adc_slot4_5_enum,
+ RT5670_TDM_CTRL_1, 2,
+ rt5670_tdm_data_swap_select);
+
+static const SOC_ENUM_SINGLE_DECL(rt5670_tdm_adc_slot6_7_enum,
+ RT5670_TDM_CTRL_1, 0,
+ rt5670_tdm_data_swap_select);
+
+static int rt5670_vol_rescale_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct soc_mixer_control *mc =
+ (struct soc_mixer_control *)kcontrol->private_value;
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ unsigned int val = snd_soc_read(codec, mc->reg);
+
+ ucontrol->value.integer.value[0] = RT5670_VOL_RSCL_MAX -
+ ((val & RT5670_L_VOL_MASK) >> mc->shift);
+ ucontrol->value.integer.value[1] = RT5670_VOL_RSCL_MAX -
+ (val & RT5670_R_VOL_MASK);
+
+ return 0;
+}
+
+static int rt5670_vol_rescale_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct soc_mixer_control *mc =
+ (struct soc_mixer_control *)kcontrol->private_value;
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ unsigned int val, val2;
+
+ val = RT5670_VOL_RSCL_MAX - ucontrol->value.integer.value[0];
+ val2 = RT5670_VOL_RSCL_MAX - ucontrol->value.integer.value[1];
+ return snd_soc_update_bits_locked(codec, mc->reg, RT5670_L_VOL_MASK |
+ RT5670_R_VOL_MASK, val << mc->shift | val2);
+}
+
+
+static const struct snd_kcontrol_new rt5670_snd_controls[] = {
+ /* Headphone Output Volume */
+ SOC_DOUBLE("HP Playback Switch", RT5670_HP_VOL,
+ RT5670_L_MUTE_SFT, RT5670_R_MUTE_SFT, 1, 1),
+ SOC_DOUBLE_EXT_TLV("HP Playback Volume", RT5670_HP_VOL,
+ RT5670_L_VOL_SFT, RT5670_R_VOL_SFT, RT5670_VOL_RSCL_RANGE, 0,
+ rt5670_vol_rescale_get, rt5670_vol_rescale_put, out_vol_tlv),
+ /* OUTPUT Control */
+ SOC_DOUBLE("OUT Playback Switch", RT5670_LOUT1,
+ RT5670_L_MUTE_SFT, RT5670_R_MUTE_SFT, 1, 1),
+ SOC_DOUBLE("OUT Channel Switch", RT5670_LOUT1,
+ RT5670_VOL_L_SFT, RT5670_VOL_R_SFT, 1, 1),
+ SOC_DOUBLE_TLV("OUT Playback Volume", RT5670_LOUT1,
+ RT5670_L_VOL_SFT, RT5670_R_VOL_SFT, 39, 1, out_vol_tlv),
+ /* DAC Digital Volume */
+ SOC_DOUBLE("DAC2 Playback Switch", RT5670_DAC_CTRL,
+ RT5670_M_DAC_L2_VOL_SFT, RT5670_M_DAC_R2_VOL_SFT, 1, 1),
+ SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5670_DAC1_DIG_VOL,
+ RT5670_L_VOL_SFT, RT5670_R_VOL_SFT,
+ 175, 0, dac_vol_tlv),
+ SOC_DOUBLE_TLV("Mono DAC Playback Volume", RT5670_DAC2_DIG_VOL,
+ RT5670_L_VOL_SFT, RT5670_R_VOL_SFT,
+ 175, 0, dac_vol_tlv),
+ /* IN1/IN2 Control */
+ SOC_ENUM("IN1 Mode Control", rt5670_in1_mode_enum),
+ SOC_SINGLE_TLV("IN1 Boost", RT5670_IN1_IN2,
+ RT5670_BST_SFT1, 8, 0, bst_tlv),
+ SOC_ENUM("IN2 Mode Control", rt5670_in2_mode_enum),
+ SOC_SINGLE_TLV("IN2 Boost", RT5670_IN3,
+ RT5670_BST_SFT2, 8, 0, bst_tlv),
+ /* INL/INR Volume Control */
+ SOC_DOUBLE_TLV("IN Capture Volume", RT5670_INL1_INR1_VOL,
+ RT5670_INL_VOL_SFT, RT5670_INR_VOL_SFT,
+ 31, 1, in_vol_tlv),
+ /* ADC Digital Volume Control */
+ SOC_DOUBLE("ADC Capture Switch", RT5670_STO1_ADC_DIG_VOL,
+ RT5670_L_MUTE_SFT, RT5670_R_MUTE_SFT, 1, 1),
+ SOC_DOUBLE_TLV("ADC Capture Volume", RT5670_STO1_ADC_DIG_VOL,
+ RT5670_L_VOL_SFT, RT5670_R_VOL_SFT,
+ 127, 0, adc_vol_tlv),
+
+ SOC_DOUBLE_TLV("Mono ADC Capture Volume", RT5670_MONO_ADC_DIG_VOL,
+ RT5670_L_VOL_SFT, RT5670_R_VOL_SFT,
+ 127, 0, adc_vol_tlv),
+
+ /* ADC Boost Volume Control */
+ SOC_DOUBLE_TLV("STO1 ADC Boost Gain", RT5670_ADC_BST_VOL1,
+ RT5670_STO1_ADC_L_BST_SFT, RT5670_STO1_ADC_R_BST_SFT,
+ 3, 0, adc_bst_tlv),
+
+ SOC_DOUBLE_TLV("STO2 ADC Boost Gain", RT5670_ADC_BST_VOL1,
+ RT5670_STO2_ADC_L_BST_SFT, RT5670_STO2_ADC_R_BST_SFT,
+ 3, 0, adc_bst_tlv),
+
+ /* TDM */
+ SOC_ENUM("TDM Adc Location", rt5670_tdm_adc_location_enum),
+ SOC_ENUM("TDM Adc Slot0 1 Data", rt5670_tdm_adc_slot0_1_enum),
+ SOC_ENUM("TDM Adc Slot2 3 Data", rt5670_tdm_adc_slot2_3_enum),
+ SOC_ENUM("TDM Adc Slot4 5 Data", rt5670_tdm_adc_slot4_5_enum),
+ SOC_ENUM("TDM Adc Slot6 7 Data", rt5670_tdm_adc_slot6_7_enum),
+ SOC_SINGLE("TDM IF1_DAC1_L Sel", RT5670_TDM_CTRL_3, 12, 7, 0),
+ SOC_SINGLE("TDM IF1_DAC1_R Sel", RT5670_TDM_CTRL_3, 8, 7, 0),
+ SOC_SINGLE("TDM IF1_DAC2_L Sel", RT5670_TDM_CTRL_3, 4, 7, 0),
+ SOC_SINGLE("TDM IF1_DAC2_R Sel", RT5670_TDM_CTRL_3, 0, 7, 0),
+};
+
+/**
+ * set_dmic_clk - Set parameter of dmic.
+ *
+ * @w: DAPM widget.
+ * @kcontrol: The kcontrol of this widget.
+ * @event: Event id.
+ *
+ * Choose dmic clock between 1MHz and 3MHz.
+ * It is better for clock to approximate 3MHz.
+ */
+static int set_dmic_clk(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+ int div[] = {2, 3, 4, 6, 8, 12}, idx = -EINVAL, i;
+ int rate, red, bound, temp;
+
+ rate = rt5670->lrck[rt5670->aif_pu] << 8;
+ red = 2000000 * 12;
+ for (i = 0; i < ARRAY_SIZE(div); i++) {
+ bound = div[i] * 2000000;
+ if (rate > bound)
+ continue;
+ temp = bound - rate;
+ if (temp < red) {
+ red = temp;
+ idx = i;
+ }
+ }
+#ifdef USE_ASRC
+ idx = 5;
+#endif
+ if (idx < 0)
+ dev_err(codec->dev, "Failed to set DMIC clock\n");
+ else
+ snd_soc_update_bits(codec, RT5670_DMIC_CTRL1,
+ RT5670_DMIC_CLK_MASK, idx << RT5670_DMIC_CLK_SFT);
+ return idx;
+}
+
+static int check_sysclk1_source(struct snd_soc_dapm_widget *source,
+ struct snd_soc_dapm_widget *sink)
+{
+ unsigned int val;
+
+ val = snd_soc_read(source->codec, RT5670_GLB_CLK);
+ val &= RT5670_SCLK_SRC_MASK;
+ if (val == RT5670_SCLK_SRC_PLL1)
+ return 1;
+ else
+ return 0;
+}
+
+/* Digital Mixer */
+static const struct snd_kcontrol_new rt5670_sto1_adc_l_mix[] = {
+ SOC_DAPM_SINGLE("ADC1 Switch", RT5670_STO1_ADC_MIXER,
+ RT5670_M_ADC_L1_SFT, 1, 1),
+ SOC_DAPM_SINGLE("ADC2 Switch", RT5670_STO1_ADC_MIXER,
+ RT5670_M_ADC_L2_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5670_sto1_adc_r_mix[] = {
+ SOC_DAPM_SINGLE("ADC1 Switch", RT5670_STO1_ADC_MIXER,
+ RT5670_M_ADC_R1_SFT, 1, 1),
+ SOC_DAPM_SINGLE("ADC2 Switch", RT5670_STO1_ADC_MIXER,
+ RT5670_M_ADC_R2_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5670_sto2_adc_l_mix[] = {
+ SOC_DAPM_SINGLE("ADC1 Switch", RT5670_STO2_ADC_MIXER,
+ RT5670_M_ADC_L1_SFT, 1, 1),
+ SOC_DAPM_SINGLE("ADC2 Switch", RT5670_STO2_ADC_MIXER,
+ RT5670_M_ADC_L2_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5670_sto2_adc_r_mix[] = {
+ SOC_DAPM_SINGLE("ADC1 Switch", RT5670_STO2_ADC_MIXER,
+ RT5670_M_ADC_R1_SFT, 1, 1),
+ SOC_DAPM_SINGLE("ADC2 Switch", RT5670_STO2_ADC_MIXER,
+ RT5670_M_ADC_R2_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5670_mono_adc_l_mix[] = {
+ SOC_DAPM_SINGLE("ADC1 Switch", RT5670_MONO_ADC_MIXER,
+ RT5670_M_MONO_ADC_L1_SFT, 1, 1),
+ SOC_DAPM_SINGLE("ADC2 Switch", RT5670_MONO_ADC_MIXER,
+ RT5670_M_MONO_ADC_L2_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5670_mono_adc_r_mix[] = {
+ SOC_DAPM_SINGLE("ADC1 Switch", RT5670_MONO_ADC_MIXER,
+ RT5670_M_MONO_ADC_R1_SFT, 1, 1),
+ SOC_DAPM_SINGLE("ADC2 Switch", RT5670_MONO_ADC_MIXER,
+ RT5670_M_MONO_ADC_R2_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5670_dac_l_mix[] = {
+ SOC_DAPM_SINGLE("Stereo ADC Switch", RT5670_AD_DA_MIXER,
+ RT5670_M_ADCMIX_L_SFT, 1, 1),
+ SOC_DAPM_SINGLE("DAC1 Switch", RT5670_AD_DA_MIXER,
+ RT5670_M_DAC1_L_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5670_dac_r_mix[] = {
+ SOC_DAPM_SINGLE("Stereo ADC Switch", RT5670_AD_DA_MIXER,
+ RT5670_M_ADCMIX_R_SFT, 1, 1),
+ SOC_DAPM_SINGLE("DAC1 Switch", RT5670_AD_DA_MIXER,
+ RT5670_M_DAC1_R_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5670_sto_dac_l_mix[] = {
+ SOC_DAPM_SINGLE("DAC L1 Switch", RT5670_STO_DAC_MIXER,
+ RT5670_M_DAC_L1_SFT, 1, 1),
+ SOC_DAPM_SINGLE("DAC L2 Switch", RT5670_STO_DAC_MIXER,
+ RT5670_M_DAC_L2_SFT, 1, 1),
+ SOC_DAPM_SINGLE("DAC R1 Switch", RT5670_STO_DAC_MIXER,
+ RT5670_M_DAC_R1_STO_L_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5670_sto_dac_r_mix[] = {
+ SOC_DAPM_SINGLE("DAC R1 Switch", RT5670_STO_DAC_MIXER,
+ RT5670_M_DAC_R1_SFT, 1, 1),
+ SOC_DAPM_SINGLE("DAC R2 Switch", RT5670_STO_DAC_MIXER,
+ RT5670_M_DAC_R2_SFT, 1, 1),
+ SOC_DAPM_SINGLE("DAC L1 Switch", RT5670_STO_DAC_MIXER,
+ RT5670_M_DAC_L1_STO_R_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5670_mono_dac_l_mix[] = {
+ SOC_DAPM_SINGLE("DAC L1 Switch", RT5670_DD_MIXER,
+ RT5670_M_DAC_L1_MONO_L_SFT, 1, 1),
+ SOC_DAPM_SINGLE("DAC L2 Switch", RT5670_DD_MIXER,
+ RT5670_M_DAC_L2_MONO_L_SFT, 1, 1),
+ SOC_DAPM_SINGLE("DAC R2 Switch", RT5670_DD_MIXER,
+ RT5670_M_DAC_R2_MONO_L_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5670_mono_dac_r_mix[] = {
+ SOC_DAPM_SINGLE("DAC R1 Switch", RT5670_DD_MIXER,
+ RT5670_M_DAC_R1_MONO_R_SFT, 1, 1),
+ SOC_DAPM_SINGLE("DAC R2 Switch", RT5670_DD_MIXER,
+ RT5670_M_DAC_R2_MONO_R_SFT, 1, 1),
+ SOC_DAPM_SINGLE("DAC L2 Switch", RT5670_DD_MIXER,
+ RT5670_M_DAC_L2_MONO_R_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5670_dig_l_mix[] = {
+ SOC_DAPM_SINGLE("Sto DAC Mix L Switch", RT5670_DIG_MIXER,
+ RT5670_M_STO_L_DAC_L_SFT, 1, 1),
+ SOC_DAPM_SINGLE("DAC L2 Switch", RT5670_DIG_MIXER,
+ RT5670_M_DAC_L2_DAC_L_SFT, 1, 1),
+ SOC_DAPM_SINGLE("DAC R2 Switch", RT5670_DIG_MIXER,
+ RT5670_M_DAC_R2_DAC_L_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5670_dig_r_mix[] = {
+ SOC_DAPM_SINGLE("Sto DAC Mix R Switch", RT5670_DIG_MIXER,
+ RT5670_M_STO_R_DAC_R_SFT, 1, 1),
+ SOC_DAPM_SINGLE("DAC R2 Switch", RT5670_DIG_MIXER,
+ RT5670_M_DAC_R2_DAC_R_SFT, 1, 1),
+ SOC_DAPM_SINGLE("DAC L2 Switch", RT5670_DIG_MIXER,
+ RT5670_M_DAC_L2_DAC_R_SFT, 1, 1),
+};
+
+/* Analog Input Mixer */
+static const struct snd_kcontrol_new rt5670_rec_l_mix[] = {
+ SOC_DAPM_SINGLE("INL Switch", RT5670_REC_L2_MIXER,
+ RT5670_M_IN_L_RM_L_SFT, 1, 1),
+ SOC_DAPM_SINGLE("BST2 Switch", RT5670_REC_L2_MIXER,
+ RT5670_M_BST2_RM_L_SFT, 1, 1),
+ SOC_DAPM_SINGLE("BST1 Switch", RT5670_REC_L2_MIXER,
+ RT5670_M_BST1_RM_L_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5670_rec_r_mix[] = {
+ SOC_DAPM_SINGLE("INR Switch", RT5670_REC_R2_MIXER,
+ RT5670_M_IN_R_RM_R_SFT, 1, 1),
+ SOC_DAPM_SINGLE("BST2 Switch", RT5670_REC_R2_MIXER,
+ RT5670_M_BST2_RM_R_SFT, 1, 1),
+ SOC_DAPM_SINGLE("BST1 Switch", RT5670_REC_R2_MIXER,
+ RT5670_M_BST1_RM_R_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5670_out_l_mix[] = {
+ SOC_DAPM_SINGLE("BST1 Switch", RT5670_OUT_L1_MIXER,
+ RT5670_M_BST1_OM_L_SFT, 1, 1),
+ SOC_DAPM_SINGLE("INL Switch", RT5670_OUT_L1_MIXER,
+ RT5670_M_IN_L_OM_L_SFT, 1, 1),
+ SOC_DAPM_SINGLE("DAC L2 Switch", RT5670_OUT_L1_MIXER,
+ RT5670_M_DAC_L2_OM_L_SFT, 1, 1),
+ SOC_DAPM_SINGLE("DAC L1 Switch", RT5670_OUT_L1_MIXER,
+ RT5670_M_DAC_L1_OM_L_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5670_out_r_mix[] = {
+ SOC_DAPM_SINGLE("BST2 Switch", RT5670_OUT_R1_MIXER,
+ RT5670_M_BST2_OM_R_SFT, 1, 1),
+ SOC_DAPM_SINGLE("INR Switch", RT5670_OUT_R1_MIXER,
+ RT5670_M_IN_R_OM_R_SFT, 1, 1),
+ SOC_DAPM_SINGLE("DAC R2 Switch", RT5670_OUT_R1_MIXER,
+ RT5670_M_DAC_R2_OM_R_SFT, 1, 1),
+ SOC_DAPM_SINGLE("DAC R1 Switch", RT5670_OUT_R1_MIXER,
+ RT5670_M_DAC_R1_OM_R_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5670_hpo_mix[] = {
+ SOC_DAPM_SINGLE("DAC1 Switch", RT5670_HPO_MIXER,
+ RT5670_M_DAC1_HM_SFT, 1, 1),
+ SOC_DAPM_SINGLE("HPVOL Switch", RT5670_HPO_MIXER,
+ RT5670_M_HPVOL_HM_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5670_hpvoll_mix[] = {
+ SOC_DAPM_SINGLE("DAC1 Switch", RT5670_HPO_MIXER,
+ RT5670_M_DACL1_HML_SFT, 1, 1),
+ SOC_DAPM_SINGLE("INL Switch", RT5670_HPO_MIXER,
+ RT5670_M_INL1_HML_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5670_hpvolr_mix[] = {
+ SOC_DAPM_SINGLE("DAC1 Switch", RT5670_HPO_MIXER,
+ RT5670_M_DACR1_HMR_SFT, 1, 1),
+ SOC_DAPM_SINGLE("INR Switch", RT5670_HPO_MIXER,
+ RT5670_M_INR1_HMR_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5670_lout_mix[] = {
+ SOC_DAPM_SINGLE("DAC L1 Switch", RT5670_LOUT_MIXER,
+ RT5670_M_DAC_L1_LM_SFT, 1, 1),
+ SOC_DAPM_SINGLE("DAC R1 Switch", RT5670_LOUT_MIXER,
+ RT5670_M_DAC_R1_LM_SFT, 1, 1),
+ SOC_DAPM_SINGLE("OUTMIX L Switch", RT5670_LOUT_MIXER,
+ RT5670_M_OV_L_LM_SFT, 1, 1),
+ SOC_DAPM_SINGLE("OUTMIX R Switch", RT5670_LOUT_MIXER,
+ RT5670_M_OV_R_LM_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5670_monoamp_mix[] = {
+ SOC_DAPM_SINGLE("DAC L2 Switch", RT5670_MONO_MIXER,
+ RT5670_M_DAC_L2_MA_SFT, 1, 1),
+ SOC_DAPM_SINGLE("MONOVOL Switch", RT5670_MONO_MIXER,
+ RT5670_M_OV_L_MM_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5670_hpl_mix[] = {
+ SOC_DAPM_SINGLE("DAC L1 Switch", RT5670_HPO_MIXER,
+ RT5670_M_DACL1_HML_SFT, 1, 1),
+ SOC_DAPM_SINGLE("INL1 Switch", RT5670_HPO_MIXER,
+ RT5670_M_INL1_HML_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5670_hpr_mix[] = {
+ SOC_DAPM_SINGLE("DAC R1 Switch", RT5670_HPO_MIXER,
+ RT5670_M_DACR1_HMR_SFT, 1, 1),
+ SOC_DAPM_SINGLE("INR1 Switch", RT5670_HPO_MIXER,
+ RT5670_M_INR1_HMR_SFT, 1, 1),
+};
+
+/* DAC1 L/R source */ /* MX-29 [9:8] [11:10] */
+static const char *rt5670_dac1_src[] = {
+ "IF1 DAC", "IF2 DAC"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_dac1l_enum, RT5670_AD_DA_MIXER,
+ RT5670_DAC1_L_SEL_SFT, rt5670_dac1_src);
+
+static const struct snd_kcontrol_new rt5670_dac1l_mux =
+ SOC_DAPM_ENUM("DAC1 L source", rt5670_dac1l_enum);
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_dac1r_enum, RT5670_AD_DA_MIXER,
+ RT5670_DAC1_R_SEL_SFT, rt5670_dac1_src);
+
+static const struct snd_kcontrol_new rt5670_dac1r_mux =
+ SOC_DAPM_ENUM("DAC1 R source", rt5670_dac1r_enum);
+
+/*DAC2 L/R source*/ /* MX-1B [6:4] [2:0] */\
+/* TODO Use SOC_VALUE_ENUM_SINGLE_DECL */
+static const char *rt5670_dac12_src[] = {
+ "IF1 DAC", "IF2 DAC", "IF3 DAC", "TxDC DAC", "Bass", "VAD_ADC", "IF4 DAC"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_dac2l_enum, RT5670_DAC_CTRL,
+ RT5670_DAC2_L_SEL_SFT, rt5670_dac12_src);
+
+static const struct snd_kcontrol_new rt5670_dac_l2_mux =
+ SOC_DAPM_ENUM("DAC2 L source", rt5670_dac2l_enum);
+
+static const char *rt5670_dacr2_src[] = {
+ "IF1 DAC", "IF2 DAC", "IF3 DAC", "TxDC DAC", "TxDP ADC", "IF4 DAC"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_dac2r_enum, RT5670_DAC_CTRL,
+ RT5670_DAC2_R_SEL_SFT, rt5670_dacr2_src);
+
+static const struct snd_kcontrol_new rt5670_dac_r2_mux =
+ SOC_DAPM_ENUM("DAC2 R source", rt5670_dac2r_enum);
+
+/*RxDP source*/ /* MX-2D [15:13] */
+static const char *rt5670_rxdp_src[] = {
+ "IF2 DAC", "IF1 DAC", "STO1 ADC Mixer", "STO2 ADC Mixer",
+ "Mono ADC Mixer L", "Mono ADC Mixer R", "DAC1"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_rxdp_enum, RT5670_DSP_PATH1,
+ RT5670_RXDP_SEL_SFT, rt5670_rxdp_src);
+
+static const struct snd_kcontrol_new rt5670_rxdp_mux =
+ SOC_DAPM_ENUM("DAC2 L source", rt5670_rxdp_enum);
+
+/* MX-2D [1] [0] */
+static const char *rt5670_dsp_bypass_src[] = {
+ "DSP", "Bypass"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_dsp_ul_enum, RT5670_DSP_PATH1,
+ RT5670_DSP_UL_SFT, rt5670_dsp_bypass_src);
+
+static const struct snd_kcontrol_new rt5670_dsp_ul_mux =
+ SOC_DAPM_ENUM("DSP UL source", rt5670_dsp_ul_enum);
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_dsp_dl_enum, RT5670_DSP_PATH1,
+ RT5670_DSP_DL_SFT, rt5670_dsp_bypass_src);
+
+static const struct snd_kcontrol_new rt5670_dsp_dl_mux =
+ SOC_DAPM_ENUM("DSP DL source", rt5670_dsp_dl_enum);
+
+
+/* INL/R source */
+static const char *rt5670_inl_src[] = {
+ "IN2P", "MonoP"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_inl_enum, RT5670_INL1_INR1_VOL,
+ RT5670_INL_SEL_SFT, rt5670_inl_src);
+
+static const struct snd_kcontrol_new rt5670_inl_mux =
+ SOC_DAPM_ENUM("INL source", rt5670_inl_enum);
+
+static const char *rt5670_inr_src[] = {
+ "IN2N", "MonoN"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_inr_enum, RT5670_INL1_INR1_VOL,
+ RT5670_INR_SEL_SFT, rt5670_inr_src);
+
+static const struct snd_kcontrol_new rt5670_inr_mux =
+ SOC_DAPM_ENUM("INR source", rt5670_inr_enum);
+
+/* Stereo2 ADC source */
+/* MX-26 [15] */
+static const char *rt5670_stereo2_adc_lr_src[] = {
+ "L", "LR"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_stereo2_adc_lr_enum, RT5670_STO2_ADC_MIXER,
+ RT5670_STO2_ADC_SRC_SFT, rt5670_stereo2_adc_lr_src);
+
+static const struct snd_kcontrol_new rt5670_sto2_adc_lr_mux =
+ SOC_DAPM_ENUM("Stereo2 ADC LR source", rt5670_stereo2_adc_lr_enum);
+
+/* Stereo1 ADC source */
+/* MX-27 MX-26 [12] */
+static const char *rt5670_stereo_adc1_src[] = {
+ "DAC MIX", "ADC"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_stereo1_adc1_enum, RT5670_STO1_ADC_MIXER,
+ RT5670_ADC_1_SRC_SFT, rt5670_stereo_adc1_src);
+
+static const struct snd_kcontrol_new rt5670_sto_adc_l1_mux =
+ SOC_DAPM_ENUM("Stereo1 ADC L1 source", rt5670_stereo1_adc1_enum);
+
+static const struct snd_kcontrol_new rt5670_sto_adc_r1_mux =
+ SOC_DAPM_ENUM("Stereo1 ADC R1 source", rt5670_stereo1_adc1_enum);
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_stereo2_adc1_enum, RT5670_STO2_ADC_MIXER,
+ RT5670_ADC_1_SRC_SFT, rt5670_stereo_adc1_src);
+
+static const struct snd_kcontrol_new rt5670_sto2_adc_l1_mux =
+ SOC_DAPM_ENUM("Stereo2 ADC L1 source", rt5670_stereo2_adc1_enum);
+
+static const struct snd_kcontrol_new rt5670_sto2_adc_r1_mux =
+ SOC_DAPM_ENUM("Stereo2 ADC R1 source", rt5670_stereo2_adc1_enum);
+
+/* MX-27 MX-26 [11] */
+static const char *rt5670_stereo_adc2_src[] = {
+ "DAC MIX", "DMIC"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_stereo1_adc2_enum, RT5670_STO1_ADC_MIXER,
+ RT5670_ADC_2_SRC_SFT, rt5670_stereo_adc2_src);
+
+static const struct snd_kcontrol_new rt5670_sto_adc_l2_mux =
+ SOC_DAPM_ENUM("Stereo1 ADC L2 source", rt5670_stereo1_adc2_enum);
+
+static const struct snd_kcontrol_new rt5670_sto_adc_r2_mux =
+ SOC_DAPM_ENUM("Stereo1 ADC R2 source", rt5670_stereo1_adc2_enum);
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_stereo2_adc2_enum, RT5670_STO2_ADC_MIXER,
+ RT5670_ADC_2_SRC_SFT, rt5670_stereo_adc2_src);
+
+static const struct snd_kcontrol_new rt5670_sto2_adc_l2_mux =
+ SOC_DAPM_ENUM("Stereo2 ADC L2 source", rt5670_stereo2_adc2_enum);
+
+static const struct snd_kcontrol_new rt5670_sto2_adc_r2_mux =
+ SOC_DAPM_ENUM("Stereo2 ADC R2 source", rt5670_stereo2_adc2_enum);
+
+/* MX-27 MX26 [10] */
+static const char *rt5670_stereo_adc_src[] = {
+ "ADC1L ADC2R", "ADC3"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_stereo1_adc_enum, RT5670_STO1_ADC_MIXER,
+ RT5670_ADC_SRC_SFT, rt5670_stereo_adc_src);
+
+static const struct snd_kcontrol_new rt5670_sto_adc_mux =
+ SOC_DAPM_ENUM("Stereo1 ADC source", rt5670_stereo1_adc_enum);
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_stereo2_adc_enum, RT5670_STO2_ADC_MIXER,
+ RT5670_ADC_SRC_SFT, rt5670_stereo_adc_src);
+
+static const struct snd_kcontrol_new rt5670_sto2_adc_mux =
+ SOC_DAPM_ENUM("Stereo2 ADC source", rt5670_stereo2_adc_enum);
+
+/* MX-27 MX-26 [9:8] */
+static const char *rt5670_stereo_dmic_src[] = {
+ "DMIC1", "DMIC2", "DMIC3"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_stereo1_dmic_enum, RT5670_STO1_ADC_MIXER,
+ RT5670_DMIC_SRC_SFT, rt5670_stereo_dmic_src);
+
+static const struct snd_kcontrol_new rt5670_sto1_dmic_mux =
+ SOC_DAPM_ENUM("Stereo1 DMIC source", rt5670_stereo1_dmic_enum);
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_stereo2_dmic_enum, RT5670_STO2_ADC_MIXER,
+ RT5670_DMIC_SRC_SFT, rt5670_stereo_dmic_src);
+
+static const struct snd_kcontrol_new rt5670_sto2_dmic_mux =
+ SOC_DAPM_ENUM("Stereo2 DMIC source", rt5670_stereo2_dmic_enum);
+
+/* MX-27 [0] */
+static const char *rt5670_stereo_dmic3_src[] = {
+ "DMIC3", "PDM ADC"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_stereo_dmic3_enum, RT5670_STO1_ADC_MIXER,
+ RT5670_DMIC3_SRC_SFT, rt5670_stereo_dmic3_src);
+
+static const struct snd_kcontrol_new rt5670_sto_dmic3_mux =
+ SOC_DAPM_ENUM("Stereo DMIC3 source", rt5670_stereo_dmic3_enum);
+
+/* Mono ADC source */
+/* MX-28 [12] */
+static const char *rt5670_mono_adc_l1_src[] = {
+ "Mono DAC MIXL", "ADC1"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_mono_adc_l1_enum, RT5670_MONO_ADC_MIXER,
+ RT5670_MONO_ADC_L1_SRC_SFT, rt5670_mono_adc_l1_src);
+
+static const struct snd_kcontrol_new rt5670_mono_adc_l1_mux =
+ SOC_DAPM_ENUM("Mono ADC1 left source", rt5670_mono_adc_l1_enum);
+/* MX-28 [11] */
+static const char *rt5670_mono_adc_l2_src[] = {
+ "Mono DAC MIXL", "DMIC"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_mono_adc_l2_enum, RT5670_MONO_ADC_MIXER,
+ RT5670_MONO_ADC_L2_SRC_SFT, rt5670_mono_adc_l2_src);
+
+static const struct snd_kcontrol_new rt5670_mono_adc_l2_mux =
+ SOC_DAPM_ENUM("Mono ADC2 left source", rt5670_mono_adc_l2_enum);
+
+/* MX-28 [10] */
+static const char *rt5670_mono_adc_l_src[] = {
+ "ADC1", "ADC3"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_mono_adc_l_enum, RT5670_MONO_ADC_MIXER,
+ RT5670_MONO_ADC_L_SRC_SFT, rt5670_mono_adc_l_src);
+
+static const struct snd_kcontrol_new rt5670_mono_adc_l_mux =
+ SOC_DAPM_ENUM("Mono ADC left source", rt5670_mono_adc_l_enum);
+
+/* MX-28 [9:8] */
+static const char *rt5670_mono_dmic_src[] = {
+ "DMIC1", "DMIC2", "DMIC3"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_mono_dmic_l_enum, RT5670_MONO_ADC_MIXER,
+ RT5670_MONO_DMIC_L_SRC_SFT, rt5670_mono_dmic_src);
+
+static const struct snd_kcontrol_new rt5670_mono_dmic_l_mux =
+ SOC_DAPM_ENUM("Mono DMIC left source", rt5670_mono_dmic_l_enum);
+/* MX-28 [1:0] */
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_mono_dmic_r_enum, RT5670_MONO_ADC_MIXER,
+ RT5670_MONO_DMIC_R_SRC_SFT, rt5670_mono_dmic_src);
+
+static const struct snd_kcontrol_new rt5670_mono_dmic_r_mux =
+ SOC_DAPM_ENUM("Mono DMIC Right source", rt5670_mono_dmic_r_enum);
+/* MX-28 [4] */
+static const char *rt5670_mono_adc_r1_src[] = {
+ "Mono DAC MIXR", "ADC2"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_mono_adc_r1_enum, RT5670_MONO_ADC_MIXER,
+ RT5670_MONO_ADC_R1_SRC_SFT, rt5670_mono_adc_r1_src);
+
+static const struct snd_kcontrol_new rt5670_mono_adc_r1_mux =
+ SOC_DAPM_ENUM("Mono ADC1 right source", rt5670_mono_adc_r1_enum);
+/* MX-28 [3] */
+static const char *rt5670_mono_adc_r2_src[] = {
+ "Mono DAC MIXR", "DMIC"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_mono_adc_r2_enum, RT5670_MONO_ADC_MIXER,
+ RT5670_MONO_ADC_R2_SRC_SFT, rt5670_mono_adc_r2_src);
+
+static const struct snd_kcontrol_new rt5670_mono_adc_r2_mux =
+ SOC_DAPM_ENUM("Mono ADC2 right source", rt5670_mono_adc_r2_enum);
+
+/* MX-28 [2] */
+static const char *rt5670_mono_adc_r_src[] = {
+ "ADC2", "ADC3"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_mono_adc_r_enum, RT5670_MONO_ADC_MIXER,
+ RT5670_MONO_ADC_R_SRC_SFT, rt5670_mono_adc_r_src);
+
+static const struct snd_kcontrol_new rt5670_mono_adc_r_mux =
+ SOC_DAPM_ENUM("Mono ADC Right source", rt5670_mono_adc_r_enum);
+
+/* MX-2F [15] */
+static const char *rt5670_if1_adc2_in_src[] = {
+ "IF_ADC2", "VAD_ADC"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_if1_adc2_in_enum, RT5670_DIG_INF1_DATA,
+ RT5670_IF1_ADC2_IN_SFT, rt5670_if1_adc2_in_src);
+
+static const struct snd_kcontrol_new rt5670_if1_adc2_in_mux =
+ SOC_DAPM_ENUM("IF1 ADC2 IN source", rt5670_if1_adc2_in_enum);
+
+/* MX-2F [14:12] */
+static const char *rt5670_if2_adc_in_src[] = {
+ "IF_ADC1", "IF_ADC2", "IF_ADC3", "TxDC_DAC", "TxDP_ADC", "VAD_ADC"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_if2_adc_in_enum, RT5670_DIG_INF1_DATA,
+ RT5670_IF2_ADC_IN_SFT, rt5670_if2_adc_in_src);
+
+static const struct snd_kcontrol_new rt5670_if2_adc_in_mux =
+ SOC_DAPM_ENUM("IF2 ADC IN source", rt5670_if2_adc_in_enum);
+
+/* MX-30 [5:4] */
+static const char *rt5670_if4_adc_in_src[] = {
+ "IF_ADC1", "IF_ADC2", "IF_ADC3"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_if4_adc_in_enum, RT5670_DIG_INF2_DATA,
+ RT5670_IF4_ADC_IN_SFT, rt5670_if4_adc_in_src);
+
+static const struct snd_kcontrol_new rt5670_if4_adc_in_mux =
+ SOC_DAPM_ENUM("IF4 ADC IN source", rt5670_if4_adc_in_enum);
+
+/* MX-31 [15] [13] [11] [9] */
+static const char *rt5670_pdm_src[] = {
+ "Mono DAC", "Stereo DAC"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_pdm1_l_enum, RT5670_PDM_OUT_CTRL,
+ RT5670_PDM1_L_SFT, rt5670_pdm_src);
+
+static const struct snd_kcontrol_new rt5670_pdm1_l_mux =
+ SOC_DAPM_ENUM("PDM1 L source", rt5670_pdm1_l_enum);
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_pdm1_r_enum, RT5670_PDM_OUT_CTRL,
+ RT5670_PDM1_R_SFT, rt5670_pdm_src);
+
+static const struct snd_kcontrol_new rt5670_pdm1_r_mux =
+ SOC_DAPM_ENUM("PDM1 R source", rt5670_pdm1_r_enum);
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_pdm2_l_enum, RT5670_PDM_OUT_CTRL,
+ RT5670_PDM2_L_SFT, rt5670_pdm_src);
+
+static const struct snd_kcontrol_new rt5670_pdm2_l_mux =
+ SOC_DAPM_ENUM("PDM2 L source", rt5670_pdm2_l_enum);
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_pdm2_r_enum, RT5670_PDM_OUT_CTRL,
+ RT5670_PDM2_R_SFT, rt5670_pdm_src);
+
+static const struct snd_kcontrol_new rt5670_pdm2_r_mux =
+ SOC_DAPM_ENUM("PDM2 R source", rt5670_pdm2_r_enum);
+
+/* MX-FA [12] */
+static const char *rt5670_if1_adc1_in1_src[] = {
+ "IF_ADC1", "IF1_ADC3"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_if1_adc1_in1_enum, RT5670_DIG_MISC,
+ RT5670_IF1_ADC1_IN1_SFT, rt5670_if1_adc1_in1_src);
+
+static const struct snd_kcontrol_new rt5670_if1_adc1_in1_mux =
+ SOC_DAPM_ENUM("IF1 ADC1 IN1 source", rt5670_if1_adc1_in1_enum);
+
+/* MX-FA [11] */
+static const char *rt5670_if1_adc1_in2_src[] = {
+ "IF1_ADC1_IN1", "IF1_ADC4"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_if1_adc1_in2_enum, RT5670_DIG_MISC,
+ RT5670_IF1_ADC1_IN2_SFT, rt5670_if1_adc1_in2_src);
+
+static const struct snd_kcontrol_new rt5670_if1_adc1_in2_mux =
+ SOC_DAPM_ENUM("IF1 ADC1 IN2 source", rt5670_if1_adc1_in2_enum);
+
+/* MX-FA [10] */
+static const char *rt5670_if1_adc2_in1_src[] = {
+ "IF1_ADC2_IN", "IF1_ADC4"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_if1_adc2_in1_enum, RT5670_DIG_MISC,
+ RT5670_IF1_ADC2_IN1_SFT, rt5670_if1_adc2_in1_src);
+
+static const struct snd_kcontrol_new rt5670_if1_adc2_in1_mux =
+ SOC_DAPM_ENUM("IF1 ADC2 IN1 source", rt5670_if1_adc2_in1_enum);
+
+/* MX-9D [9:8] */
+static const char *rt5670_vad_adc_src[] = {
+ "Sto1 ADC L", "Mono ADC L", "Mono ADC R", "Sto2 ADC L"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5670_vad_adc_enum, RT5670_VAD_CTRL4,
+ RT5670_VAD_SEL_SFT, rt5670_vad_adc_src);
+
+static const struct snd_kcontrol_new rt5670_vad_adc_mux =
+ SOC_DAPM_ENUM("VAD ADC source", rt5670_vad_adc_enum);
+
+static int rt5670_adc_clk_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ rt5670_index_update_bits(codec,
+ RT5670_CHOP_DAC_ADC, 0x1000, 0x1000);
+ break;
+
+ case SND_SOC_DAPM_POST_PMD:
+ rt5670_index_update_bits(codec,
+ RT5670_CHOP_DAC_ADC, 0x1000, 0x0000);
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+static int rt5670_sto1_adcl_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ snd_soc_update_bits(codec, RT5670_STO1_ADC_DIG_VOL,
+ RT5670_L_MUTE, 0);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ snd_soc_update_bits(codec, RT5670_STO1_ADC_DIG_VOL,
+ RT5670_L_MUTE,
+ RT5670_L_MUTE);
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+static int rt5670_sto1_adcr_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ snd_soc_update_bits(codec, RT5670_STO1_ADC_DIG_VOL,
+ RT5670_R_MUTE, 0);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ snd_soc_update_bits(codec, RT5670_STO1_ADC_DIG_VOL,
+ RT5670_R_MUTE,
+ RT5670_R_MUTE);
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+static int rt5670_mono_adcl_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ snd_soc_update_bits(codec, RT5670_MONO_ADC_DIG_VOL,
+ RT5670_L_MUTE, 0);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ snd_soc_update_bits(codec, RT5670_MONO_ADC_DIG_VOL,
+ RT5670_L_MUTE,
+ RT5670_L_MUTE);
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+static int rt5670_mono_adcr_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ snd_soc_update_bits(codec, RT5670_MONO_ADC_DIG_VOL,
+ RT5670_R_MUTE, 0);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ snd_soc_update_bits(codec, RT5670_MONO_ADC_DIG_VOL,
+ RT5670_R_MUTE,
+ RT5670_R_MUTE);
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+void hp_amp_power(struct snd_soc_codec *codec, int on)
+{
+ if(on) {
+ snd_soc_update_bits(codec, RT5670_CHARGE_PUMP,
+ RT5670_PM_HP_MASK, RT5670_PM_HP_HV);
+ snd_soc_update_bits(codec, RT5670_GEN_CTRL2,
+ 0x0400, 0x0400);
+ /* headphone amp power on */
+ snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
+ RT5670_PWR_HA | RT5670_PWR_FV1 |
+ RT5670_PWR_FV2, RT5670_PWR_HA |
+ RT5670_PWR_FV1 | RT5670_PWR_FV2);
+ /* depop parameters */
+ snd_soc_write(codec, RT5670_DEPOP_M2, 0x3100);
+ snd_soc_write(codec, RT5670_DEPOP_M1, 0x8009);
+ rt5670_index_write(codec, RT5670_HP_DCC_INT1, 0x9f00);
+ pr_debug("hp_amp_time=%d\n",hp_amp_time);
+ mdelay(hp_amp_time);
+ snd_soc_write(codec, RT5670_DEPOP_M1, 0x8019);
+ }
+}
+
+static void rt5670_pmu_depop(struct snd_soc_codec *codec)
+{
+ /* headphone unmute sequence */
+ rt5670_index_write(codec, RT5670_MAMP_INT_REG2, 0xb400);
+ snd_soc_write(codec, RT5670_DEPOP_M3, 0x0772);
+ snd_soc_write(codec, RT5670_DEPOP_M1, 0x805d);
+ snd_soc_write(codec, RT5670_DEPOP_M1, 0x831d);
+ snd_soc_update_bits(codec, RT5670_GEN_CTRL2,
+ 0x0300, 0x0300);
+ snd_soc_update_bits(codec, RT5670_HP_VOL,
+ RT5670_L_MUTE | RT5670_R_MUTE, 0);
+ pr_debug("pmu_depop_time=%d\n",pmu_depop_time);
+ msleep(pmu_depop_time);
+ snd_soc_write(codec, RT5670_DEPOP_M1, 0x8019);
+}
+
+static void rt5670_pmd_depop(struct snd_soc_codec *codec)
+{
+ /* headphone mute sequence */
+ rt5670_index_write(codec, RT5670_MAMP_INT_REG2, 0xb400);
+ snd_soc_write(codec, RT5670_DEPOP_M3, 0x0772);
+ snd_soc_write(codec, RT5670_DEPOP_M1, 0x803d);
+ mdelay(10);
+ snd_soc_write(codec, RT5670_DEPOP_M1, 0x831d);
+ mdelay(10);
+ snd_soc_update_bits(codec, RT5670_HP_VOL,
+ RT5670_L_MUTE | RT5670_R_MUTE, RT5670_L_MUTE | RT5670_R_MUTE);
+ msleep(20);
+ snd_soc_update_bits(codec, RT5670_GEN_CTRL2, 0x0300, 0x0);
+ snd_soc_write(codec, RT5670_DEPOP_M1, 0x8019);
+ snd_soc_write(codec, RT5670_DEPOP_M3, 0x0707);
+ rt5670_index_write(codec, RT5670_MAMP_INT_REG2, 0xfc00);
+ snd_soc_write(codec, RT5670_DEPOP_M1, 0x0004);
+ msleep(30);
+}
+
+static int rt5670_hp_power_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ printk("%s SND_SOC_DAPM_POST_PMU\n",__func__);
+ hp_amp_power(codec, 1);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ printk("%s SND_SOC_DAPM_PRE_PMD\n",__func__);
+ hp_amp_power(codec, 0);
+ break;
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+static int rt5670_hp_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ rt5670_pmu_depop(codec);
+ break;
+
+ case SND_SOC_DAPM_PRE_PMD:
+ rt5670_pmd_depop(codec);
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+static int rt5670_lout_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ snd_soc_update_bits(codec, RT5670_CHARGE_PUMP,
+ RT5670_PM_HP_MASK, RT5670_PM_HP_HV);
+ snd_soc_update_bits(codec, RT5670_LOUT1,
+ RT5670_L_MUTE | RT5670_R_MUTE, 0);
+ break;
+
+ case SND_SOC_DAPM_PRE_PMD:
+ snd_soc_update_bits(codec, RT5670_LOUT1,
+ RT5670_L_MUTE | RT5670_R_MUTE,
+ RT5670_L_MUTE | RT5670_R_MUTE);
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+static int rt5670_set_dmic1_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+#ifdef NVIDIA_DALMORE
+ snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
+ RT5670_PWR_BST1 | RT5670_PWR_BST1_P,
+ RT5670_PWR_BST1 | RT5670_PWR_BST1_P);
+ snd_soc_update_bits(codec, RT5670_CJ_CTRL2, RT5670_CBJ_DET_MODE,
+ RT5670_CBJ_DET_MODE);
+#endif
+ snd_soc_update_bits(codec, RT5670_GPIO_CTRL1,
+ RT5670_GP2_PIN_MASK | RT5670_GP6_PIN_MASK |
+ RT5670_I2S2_PIN_MASK,
+ RT5670_GP2_PIN_DMIC1_SCL | RT5670_GP6_PIN_DMIC1_SDA |
+ RT5670_I2S2_PIN_GPIO);
+ snd_soc_update_bits(codec, RT5670_DMIC_CTRL1,
+ RT5670_DMIC_1L_LH_MASK | RT5670_DMIC_1R_LH_MASK |
+ RT5670_DMIC_1_DP_MASK,
+ RT5670_DMIC_1L_LH_FALLING | RT5670_DMIC_1R_LH_RISING |
+ RT5670_DMIC_1_DP_IN2P);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+#ifdef NVIDIA_DALMORE
+ snd_soc_update_bits(codec, RT5670_CJ_CTRL2, RT5670_CBJ_DET_MODE,
+ 0);
+ snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
+ RT5670_PWR_BST1 | RT5670_PWR_BST1_P, 0);
+#endif
+ break;
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+static int rt5670_set_dmic2_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_update_bits(codec, RT5670_GPIO_CTRL1,
+ RT5670_GP2_PIN_MASK | RT5670_GP4_PIN_MASK,
+ RT5670_GP2_PIN_DMIC1_SCL | RT5670_GP4_PIN_DMIC2_SDA);
+ snd_soc_update_bits(codec, RT5670_DMIC_CTRL1,
+ RT5670_DMIC_2L_LH_MASK | RT5670_DMIC_2R_LH_MASK |
+ RT5670_DMIC_2_DP_MASK,
+ RT5670_DMIC_2L_LH_FALLING | RT5670_DMIC_2R_LH_RISING |
+ RT5670_DMIC_2_DP_IN1N);
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+static int rt5670_set_dmic3_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_update_bits(codec, RT5670_GPIO_CTRL1,
+ RT5670_GP2_PIN_MASK | RT5670_GP4_PIN_MASK,
+ RT5670_GP2_PIN_DMIC1_SCL | RT5670_GP4_PIN_DMIC2_SDA);
+ snd_soc_update_bits(codec, RT5670_DMIC_CTRL1,
+ RT5670_DMIC_2L_LH_MASK | RT5670_DMIC_2R_LH_MASK |
+ RT5670_DMIC_2_DP_MASK,
+ RT5670_DMIC_2L_LH_FALLING | RT5670_DMIC_2R_LH_RISING |
+ RT5670_DMIC_2_DP_IN1N);
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+static int rt5670_bst1_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ printk("%s SND_SOC_DAPM_POST_PMU\n",__func__);
+ snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x0);
+ snd_soc_update_bits(codec,RT5670_CHARGE_PUMP,
+ RT5670_OSW_L_MASK | RT5670_OSW_R_MASK,
+ RT5670_OSW_L_DIS | RT5670_OSW_R_DIS);
+
+ snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
+ RT5670_PWR_BST1_P, RT5670_PWR_BST1_P);
+ if(rt5670->combo_jack_en) {
+ snd_soc_update_bits(codec, RT5670_PWR_VOL,
+ RT5670_PWR_MIC_DET, RT5670_PWR_MIC_DET);
+ }
+ break;
+
+ case SND_SOC_DAPM_PRE_PMD:
+ printk("%s SND_SOC_DAPM_POST_PMD\n",__func__);
+ snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4);
+ snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
+ RT5670_PWR_BST1_P, 0);
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+static int rt5670_bst2_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ printk("%s SND_SOC_DAPM_POST_PMU\n",__func__);
+ snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
+ RT5670_PWR_BST2_P, RT5670_PWR_BST2_P);
+ break;
+
+ case SND_SOC_DAPM_PRE_PMD:
+ printk("%s SND_SOC_DAPM_POST_PMD\n",__func__);
+ snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
+ RT5670_PWR_BST2_P, 0);
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+static int rt5670_pdm1_l_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ snd_soc_update_bits(codec, RT5670_PDM_OUT_CTRL,
+ RT5670_M_PDM1_L, 0);
+ break;
+
+ case SND_SOC_DAPM_PRE_PMD:
+ snd_soc_update_bits(codec, RT5670_PDM_OUT_CTRL,
+ RT5670_M_PDM1_L, RT5670_M_PDM1_L);
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+static int rt5670_pdm1_r_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ snd_soc_update_bits(codec, RT5670_PDM_OUT_CTRL,
+ RT5670_M_PDM1_R, 0);
+ break;
+
+ case SND_SOC_DAPM_PRE_PMD:
+ snd_soc_update_bits(codec, RT5670_PDM_OUT_CTRL,
+ RT5670_M_PDM1_R, RT5670_M_PDM1_R);
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+static int rt5670_pdm2_l_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ snd_soc_update_bits(codec, RT5670_PDM_OUT_CTRL,
+ RT5670_M_PDM2_L, 0);
+ break;
+
+ case SND_SOC_DAPM_PRE_PMD:
+ snd_soc_update_bits(codec, RT5670_PDM_OUT_CTRL,
+ RT5670_M_PDM2_L, RT5670_M_PDM2_L);
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+static int rt5670_pdm2_r_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ snd_soc_update_bits(codec, RT5670_PDM_OUT_CTRL,
+ RT5670_M_PDM2_R, 0);
+ break;
+
+ case SND_SOC_DAPM_PRE_PMD:
+ snd_soc_update_bits(codec, RT5670_PDM_OUT_CTRL,
+ RT5670_M_PDM2_R, RT5670_M_PDM2_R);
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+static int rt5670_asrc_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+
+ pr_debug("%s\n",__func__);
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ snd_soc_write(w->codec, RT5670_ASRC_1, 0xffff);
+ snd_soc_write(w->codec, RT5670_ASRC_2, 0x1221);
+ snd_soc_write(w->codec, RT5670_ASRC_3, 0x0022);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ snd_soc_write(w->codec, RT5670_ASRC_1, 0);
+ snd_soc_write(w->codec, RT5670_ASRC_2, 0);
+ snd_soc_write(w->codec, RT5670_ASRC_3, 0);
+ default:
+ return 0;
+ }
+ return 0;
+}
+
+static const struct snd_soc_dapm_widget rt5670_dapm_widgets[] = {
+ SND_SOC_DAPM_SUPPLY("ASRC enable", SND_SOC_NOPM, 0, 0,
+ rt5670_asrc_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_SUPPLY("PLL1", RT5670_PWR_ANLG2,
+ RT5670_PWR_PLL_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("I2S DSP", RT5670_PWR_DIG2,
+ RT5670_PWR_I2S_DSP_BIT, 0, NULL, 0),
+#ifdef JD1_FUNC
+ SND_SOC_DAPM_SUPPLY("JD Power", SND_SOC_NOPM,
+ 0, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("Mic Det Power", RT5670_PWR_VOL,
+ RT5670_PWR_MIC_DET_BIT, 0, NULL, 0),
+#else
+ SND_SOC_DAPM_SUPPLY("JD Power", RT5670_PWR_ANLG2,
+ RT5670_PWR_JD1_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("Mic Det Power", SND_SOC_NOPM,
+ 0, 0, NULL, 0),
+#endif
+
+ /* Input Side */
+ /* micbias */
+ SND_SOC_DAPM_MICBIAS("micbias1", RT5670_PWR_ANLG2,
+ RT5670_PWR_MB1_BIT, 0),
+ SND_SOC_DAPM_MICBIAS("micbias2", RT5670_PWR_ANLG2,
+ RT5670_PWR_MB2_BIT, 0),
+
+ /* Input Lines */
+ SND_SOC_DAPM_INPUT("DMIC L1"),
+ SND_SOC_DAPM_INPUT("DMIC R1"),
+ SND_SOC_DAPM_INPUT("DMIC L2"),
+ SND_SOC_DAPM_INPUT("DMIC R2"),
+ SND_SOC_DAPM_INPUT("DMIC L3"),
+ SND_SOC_DAPM_INPUT("DMIC R3"),
+
+ SND_SOC_DAPM_INPUT("IN1P"),
+ SND_SOC_DAPM_INPUT("IN1N"),
+ SND_SOC_DAPM_INPUT("IN2P"),
+ SND_SOC_DAPM_INPUT("IN2N"),
+
+ SND_SOC_DAPM_PGA("DMIC1", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("DMIC2", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("DMIC3", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0,
+ set_dmic_clk, SND_SOC_DAPM_PRE_PMU),
+ SND_SOC_DAPM_SUPPLY("DMIC1 Power", RT5670_DMIC_CTRL1,
+ RT5670_DMIC_1_EN_SFT, 0, rt5670_set_dmic1_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_SUPPLY("DMIC2 Power", RT5670_DMIC_CTRL1,
+ RT5670_DMIC_2_EN_SFT, 0, rt5670_set_dmic2_event,
+ SND_SOC_DAPM_PRE_PMU),
+ SND_SOC_DAPM_SUPPLY("DMIC3 Power", RT5670_DMIC_CTRL1,
+ RT5670_DMIC_3_EN_SFT, 0, rt5670_set_dmic3_event,
+ SND_SOC_DAPM_PRE_PMU),
+ /* Boost */
+ SND_SOC_DAPM_PGA_E("BST1", RT5670_PWR_ANLG2,
+ RT5670_PWR_BST1_BIT, 0, NULL, 0, rt5670_bst1_event,
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+ SND_SOC_DAPM_PGA_E("BST2", RT5670_PWR_ANLG2,
+ RT5670_PWR_BST2_BIT, 0, NULL, 0, rt5670_bst2_event,
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+ /* Input Volume */
+ SND_SOC_DAPM_PGA("INL VOL", RT5670_PWR_VOL,
+ RT5670_PWR_IN_L_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("INR VOL", RT5670_PWR_VOL,
+ RT5670_PWR_IN_R_BIT, 0, NULL, 0),
+ /* IN Mux */
+ SND_SOC_DAPM_MUX("INL Mux", SND_SOC_NOPM, 0, 0, &rt5670_inl_mux),
+ SND_SOC_DAPM_MUX("INR Mux", SND_SOC_NOPM, 0, 0, &rt5670_inr_mux),
+ /* REC Mixer */
+ SND_SOC_DAPM_MIXER("RECMIXL", RT5670_PWR_MIXER, RT5670_PWR_RM_L_BIT, 0,
+ rt5670_rec_l_mix, ARRAY_SIZE(rt5670_rec_l_mix)),
+ SND_SOC_DAPM_MIXER("RECMIXR", RT5670_PWR_MIXER, RT5670_PWR_RM_R_BIT, 0,
+ rt5670_rec_r_mix, ARRAY_SIZE(rt5670_rec_r_mix)),
+ /* ADCs */
+ SND_SOC_DAPM_ADC("ADC 1", NULL, SND_SOC_NOPM,
+ 0, 0),
+ SND_SOC_DAPM_ADC("ADC 2", NULL, SND_SOC_NOPM,
+ 0, 0),
+
+ SND_SOC_DAPM_PGA("ADC 1_2", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_SUPPLY("ADC 1 power",RT5670_PWR_DIG1,
+ RT5670_PWR_ADC_L_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("ADC 2 power",RT5670_PWR_DIG1,
+ RT5670_PWR_ADC_R_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("ADC clock",SND_SOC_NOPM, 0, 0,
+ rt5670_adc_clk_event, SND_SOC_DAPM_POST_PMD |
+ SND_SOC_DAPM_POST_PMU),
+ /* ADC Mux */
+ SND_SOC_DAPM_MUX("Stereo1 DMIC Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_sto1_dmic_mux),
+ SND_SOC_DAPM_MUX("Stereo1 ADC L2 Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_sto_adc_l2_mux),
+ SND_SOC_DAPM_MUX("Stereo1 ADC R2 Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_sto_adc_r2_mux),
+ SND_SOC_DAPM_MUX("Stereo1 ADC L1 Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_sto_adc_l1_mux),
+ SND_SOC_DAPM_MUX("Stereo1 ADC R1 Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_sto_adc_r1_mux),
+ SND_SOC_DAPM_MUX("Stereo2 DMIC Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_sto2_dmic_mux),
+ SND_SOC_DAPM_MUX("Stereo2 ADC L2 Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_sto2_adc_l2_mux),
+ SND_SOC_DAPM_MUX("Stereo2 ADC R2 Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_sto2_adc_r2_mux),
+ SND_SOC_DAPM_MUX("Stereo2 ADC L1 Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_sto2_adc_l1_mux),
+ SND_SOC_DAPM_MUX("Stereo2 ADC R1 Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_sto2_adc_r1_mux),
+ SND_SOC_DAPM_MUX("Stereo2 ADC LR Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_sto2_adc_lr_mux),
+ SND_SOC_DAPM_MUX("Mono ADC L Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_mono_adc_l_mux),
+ SND_SOC_DAPM_MUX("Mono ADC R Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_mono_adc_r_mux),
+ SND_SOC_DAPM_MUX("Mono DMIC L Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_mono_dmic_l_mux),
+ SND_SOC_DAPM_MUX("Mono DMIC R Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_mono_dmic_r_mux),
+ SND_SOC_DAPM_MUX("Mono ADC L2 Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_mono_adc_l2_mux),
+ SND_SOC_DAPM_MUX("Mono ADC L1 Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_mono_adc_l1_mux),
+ SND_SOC_DAPM_MUX("Mono ADC R1 Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_mono_adc_r1_mux),
+ SND_SOC_DAPM_MUX("Mono ADC R2 Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_mono_adc_r2_mux),
+ /* ADC Mixer */
+ SND_SOC_DAPM_SUPPLY_S("adc stereo1 filter", 1, RT5670_PWR_DIG2,
+ RT5670_PWR_ADC_S1F_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY_S("adc stereo2 filter", 1, RT5670_PWR_DIG2,
+ RT5670_PWR_ADC_S2F_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER_E("Sto1 ADC MIXL", SND_SOC_NOPM, 0, 0,
+ rt5670_sto1_adc_l_mix, ARRAY_SIZE(rt5670_sto1_adc_l_mix),
+ rt5670_sto1_adcl_event, SND_SOC_DAPM_PRE_PMD |
+ SND_SOC_DAPM_POST_PMU),
+ SND_SOC_DAPM_MIXER_E("Sto1 ADC MIXR", SND_SOC_NOPM, 0, 0,
+ rt5670_sto1_adc_r_mix, ARRAY_SIZE(rt5670_sto1_adc_r_mix),
+ rt5670_sto1_adcr_event, SND_SOC_DAPM_PRE_PMD |
+ SND_SOC_DAPM_POST_PMU),
+ SND_SOC_DAPM_MIXER("Sto2 ADC MIXL", SND_SOC_NOPM, 0, 0,
+ rt5670_sto2_adc_l_mix, ARRAY_SIZE(rt5670_sto2_adc_l_mix)),
+ SND_SOC_DAPM_MIXER("Sto2 ADC MIXR", SND_SOC_NOPM, 0, 0,
+ rt5670_sto2_adc_r_mix, ARRAY_SIZE(rt5670_sto2_adc_r_mix)),
+ SND_SOC_DAPM_SUPPLY_S("adc mono left filter", 1, RT5670_PWR_DIG2,
+ RT5670_PWR_ADC_MF_L_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER_E("Mono ADC MIXL", SND_SOC_NOPM, 0, 0,
+ rt5670_mono_adc_l_mix, ARRAY_SIZE(rt5670_mono_adc_l_mix),
+ rt5670_mono_adcl_event, SND_SOC_DAPM_PRE_PMD |
+ SND_SOC_DAPM_POST_PMU),
+ SND_SOC_DAPM_SUPPLY_S("adc mono right filter", 1, RT5670_PWR_DIG2,
+ RT5670_PWR_ADC_MF_R_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER_E("Mono ADC MIXR", SND_SOC_NOPM, 0, 0,
+ rt5670_mono_adc_r_mix, ARRAY_SIZE(rt5670_mono_adc_r_mix),
+ rt5670_mono_adcr_event, SND_SOC_DAPM_PRE_PMD |
+ SND_SOC_DAPM_POST_PMU),
+
+ /* ADC PGA */
+ SND_SOC_DAPM_PGA("Stereo1 ADC MIXL", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Stereo1 ADC MIXR", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Stereo2 ADC MIXL", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Stereo2 ADC MIXR", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Sto2 ADC LR MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Stereo1 ADC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Stereo2 ADC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("VAD_ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("IF_ADC1", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("IF_ADC2", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("IF_ADC3", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("IF1_ADC1", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("IF1_ADC2", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("IF1_ADC3", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("IF1_ADC4", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ /* DSP */
+ SND_SOC_DAPM_PGA("TxDP_ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("TxDP_ADC_L", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("TxDP_ADC_R", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("TxDC_DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_PGA("8CH TDM Data", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_MUX("DSP UL Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_dsp_ul_mux),
+ SND_SOC_DAPM_MUX("DSP DL Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_dsp_dl_mux),
+
+ SND_SOC_DAPM_MUX("RxDP Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_rxdp_mux),
+
+ /* IF2 Mux */
+ SND_SOC_DAPM_MUX("IF2 ADC Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_if2_adc_in_mux),
+
+ /* Digital Interface */
+ SND_SOC_DAPM_SUPPLY("I2S1", RT5670_PWR_DIG1,
+ RT5670_PWR_I2S1_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("IF1 DAC1", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("IF1 DAC2", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("IF1 DAC1 L", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("IF1 DAC1 R", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("IF1 DAC2 L", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("IF1 DAC2 R", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("IF1 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("IF1 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("IF1 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("I2S2", RT5670_PWR_DIG1,
+ RT5670_PWR_I2S2_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("IF2 DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("IF2 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("IF2 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("IF2 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("IF2 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("IF2 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ /* Digital Interface Select */
+ SND_SOC_DAPM_MUX("IF1 ADC1 IN1 Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_if1_adc1_in1_mux),
+ SND_SOC_DAPM_MUX("IF1 ADC1 IN2 Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_if1_adc1_in2_mux),
+ SND_SOC_DAPM_MUX("IF1 ADC2 IN Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_if1_adc2_in_mux),
+ SND_SOC_DAPM_MUX("IF1 ADC2 IN1 Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_if1_adc2_in1_mux),
+ SND_SOC_DAPM_MUX("VAD ADC Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_vad_adc_mux),
+
+ /* Audio Interface */
+ SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("AIF2RX", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
+
+ /* Audio DSP */
+ SND_SOC_DAPM_PGA("Audio DSP", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ /* Output Side */
+ /* DAC mixer before sound effect */
+ SND_SOC_DAPM_MIXER("DAC1 MIXL", SND_SOC_NOPM, 0, 0,
+ rt5670_dac_l_mix, ARRAY_SIZE(rt5670_dac_l_mix)),
+ SND_SOC_DAPM_MIXER("DAC1 MIXR", SND_SOC_NOPM, 0, 0,
+ rt5670_dac_r_mix, ARRAY_SIZE(rt5670_dac_r_mix)),
+ SND_SOC_DAPM_PGA("DAC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ /* DAC2 channel Mux */
+ SND_SOC_DAPM_MUX("DAC L2 Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_dac_l2_mux),
+ SND_SOC_DAPM_MUX("DAC R2 Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_dac_r2_mux),
+ SND_SOC_DAPM_PGA("DAC L2 Volume", RT5670_PWR_DIG1,
+ RT5670_PWR_DAC_L2_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("DAC R2 Volume", RT5670_PWR_DIG1,
+ RT5670_PWR_DAC_R2_BIT, 0, NULL, 0),
+
+ SND_SOC_DAPM_MUX("DAC1 L Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_dac1l_mux),
+ SND_SOC_DAPM_MUX("DAC1 R Mux", SND_SOC_NOPM, 0, 0,
+ &rt5670_dac1r_mux),
+
+ /* DAC Mixer */
+ SND_SOC_DAPM_SUPPLY_S("dac stereo1 filter", 1, RT5670_PWR_DIG2,
+ RT5670_PWR_DAC_S1F_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY_S("dac mono left filter", 1, RT5670_PWR_DIG2,
+ RT5670_PWR_DAC_MF_L_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY_S("dac mono right filter", 1, RT5670_PWR_DIG2,
+ RT5670_PWR_DAC_MF_R_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0,
+ rt5670_sto_dac_l_mix, ARRAY_SIZE(rt5670_sto_dac_l_mix)),
+ SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0,
+ rt5670_sto_dac_r_mix, ARRAY_SIZE(rt5670_sto_dac_r_mix)),
+ SND_SOC_DAPM_MIXER("Mono DAC MIXL", SND_SOC_NOPM, 0, 0,
+ rt5670_mono_dac_l_mix, ARRAY_SIZE(rt5670_mono_dac_l_mix)),
+ SND_SOC_DAPM_MIXER("Mono DAC MIXR", SND_SOC_NOPM, 0, 0,
+ rt5670_mono_dac_r_mix, ARRAY_SIZE(rt5670_mono_dac_r_mix)),
+ SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0,
+ rt5670_dig_l_mix, ARRAY_SIZE(rt5670_dig_l_mix)),
+ SND_SOC_DAPM_MIXER("DAC MIXR", SND_SOC_NOPM, 0, 0,
+ rt5670_dig_r_mix, ARRAY_SIZE(rt5670_dig_r_mix)),
+
+ /* DACs */
+ SND_SOC_DAPM_SUPPLY("DAC L1 Power", RT5670_PWR_DIG1,
+ RT5670_PWR_DAC_L1_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("DAC R1 Power", RT5670_PWR_DIG1,
+ RT5670_PWR_DAC_R1_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_DAC("DAC L1", NULL, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_DAC("DAC R1", NULL, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_DAC("DAC L2", NULL, RT5670_PWR_DIG1,
+ RT5670_PWR_DAC_L2_BIT, 0),
+
+ SND_SOC_DAPM_DAC("DAC R2", NULL, RT5670_PWR_DIG1,
+ RT5670_PWR_DAC_R2_BIT, 0),
+ /* OUT Mixer */
+
+ SND_SOC_DAPM_MIXER("OUT MIXL", RT5670_PWR_MIXER, RT5670_PWR_OM_L_BIT,
+ 0, rt5670_out_l_mix, ARRAY_SIZE(rt5670_out_l_mix)),
+ SND_SOC_DAPM_MIXER("OUT MIXR", RT5670_PWR_MIXER, RT5670_PWR_OM_R_BIT,
+ 0, rt5670_out_r_mix, ARRAY_SIZE(rt5670_out_r_mix)),
+ /* Ouput Volume */
+ SND_SOC_DAPM_MIXER("HPOVOL MIXL", RT5670_PWR_VOL, RT5670_PWR_HV_L_BIT,
+ 0, rt5670_hpvoll_mix, ARRAY_SIZE(rt5670_hpvoll_mix)),
+ SND_SOC_DAPM_MIXER("HPOVOL MIXR", RT5670_PWR_VOL, RT5670_PWR_HV_R_BIT,
+ 0, rt5670_hpvolr_mix, ARRAY_SIZE(rt5670_hpvolr_mix)),
+ SND_SOC_DAPM_PGA("DAC 1", SND_SOC_NOPM,
+ 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("DAC 2", SND_SOC_NOPM,
+ 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("HPOVOL", SND_SOC_NOPM,
+ 0, 0, NULL, 0),
+
+ /* HPO/LOUT/Mono Mixer */
+ SND_SOC_DAPM_MIXER("HPO MIX", SND_SOC_NOPM, 0, 0,
+ rt5670_hpo_mix, ARRAY_SIZE(rt5670_hpo_mix)),
+ SND_SOC_DAPM_MIXER("LOUT MIX", RT5670_PWR_ANLG1, RT5670_PWR_LM_BIT,
+ 0, rt5670_lout_mix, ARRAY_SIZE(rt5670_lout_mix)),
+ SND_SOC_DAPM_SUPPLY_S("Improve HP Amp Drv", 1, SND_SOC_NOPM,
+ 0, 0, rt5670_hp_power_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_SUPPLY("HP L Amp", RT5670_PWR_ANLG1,
+ RT5670_PWR_HP_L_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("HP R Amp", RT5670_PWR_ANLG1,
+ RT5670_PWR_HP_R_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0,
+ rt5670_hp_event, SND_SOC_DAPM_PRE_PMD |
+ SND_SOC_DAPM_POST_PMU),
+ SND_SOC_DAPM_PGA_S("LOUT Amp", 1, SND_SOC_NOPM, 0, 0,
+ rt5670_lout_event, SND_SOC_DAPM_PRE_PMD |
+ SND_SOC_DAPM_POST_PMU),
+#ifdef RT5672
+ SND_SOC_DAPM_PGA("SPO Amp", SND_SOC_NOPM, 0, 0, NULL, 0),
+#endif
+
+ /* PDM */
+ SND_SOC_DAPM_SUPPLY("PDM1 Power", RT5670_PWR_DIG2,
+ RT5670_PWR_PDM1_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("PDM2 Power", RT5670_PWR_DIG2,
+ RT5670_PWR_PDM2_BIT, 0, NULL, 0),
+
+ SND_SOC_DAPM_MUX_E("PDM1 L Mux", SND_SOC_NOPM, 0, 0, &rt5670_pdm1_l_mux,
+ rt5670_pdm1_l_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+ SND_SOC_DAPM_MUX_E("PDM1 R Mux", SND_SOC_NOPM, 0, 0, &rt5670_pdm1_r_mux,
+ rt5670_pdm1_r_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+ SND_SOC_DAPM_MUX_E("PDM2 L Mux", SND_SOC_NOPM, 0, 0, &rt5670_pdm2_l_mux,
+ rt5670_pdm2_l_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+ SND_SOC_DAPM_MUX_E("PDM2 R Mux", SND_SOC_NOPM, 0, 0, &rt5670_pdm2_r_mux,
+ rt5670_pdm2_r_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+
+ /* Output Lines */
+ SND_SOC_DAPM_OUTPUT("HPOL"),
+ SND_SOC_DAPM_OUTPUT("HPOR"),
+ SND_SOC_DAPM_OUTPUT("LOUTL"),
+ SND_SOC_DAPM_OUTPUT("LOUTR"),
+ SND_SOC_DAPM_OUTPUT("PDM2L"),
+ SND_SOC_DAPM_OUTPUT("PDM2R"),
+#ifdef RT5672
+ SND_SOC_DAPM_OUTPUT("SPOL"),
+ SND_SOC_DAPM_OUTPUT("SPOR"),
+#else
+ SND_SOC_DAPM_OUTPUT("PDM1L"),
+ SND_SOC_DAPM_OUTPUT("PDM1R"),
+#endif
+};
+
+static const struct snd_soc_dapm_route rt5670_dapm_routes[] = {
+#ifdef USE_ASRC
+ {"I2S1", NULL, "ASRC enable"},
+ {"I2S2", NULL, "ASRC enable"},
+#endif
+// { "micbias1", NULL, "DAC L1 Power" },
+// { "micbias1", NULL, "DAC R1 Power" },
+
+ { "DMIC1", NULL, "DMIC L1" },
+ { "DMIC1", NULL, "DMIC R1" },
+ { "DMIC2", NULL, "DMIC L2" },
+ { "DMIC2", NULL, "DMIC R2" },
+ { "DMIC3", NULL, "DMIC L3" },
+ { "DMIC3", NULL, "DMIC R3" },
+
+ { "BST1", NULL, "IN1P" },
+ { "BST1", NULL, "IN1N" },
+// { "BST1", NULL, "JD Power" },
+// { "BST1", NULL, "Mic Det Power" },
+ { "BST2", NULL, "IN2P" },
+ { "BST2", NULL, "IN2N" },
+
+ { "INL VOL", NULL, "IN2P" },
+ { "INR VOL", NULL, "IN2N" },
+
+ { "RECMIXL", "INL Switch", "INL VOL" },
+ { "RECMIXL", "BST2 Switch", "BST2" },
+ { "RECMIXL", "BST1 Switch", "BST1" },
+
+ { "RECMIXR", "INR Switch", "INR VOL" },
+ { "RECMIXR", "BST2 Switch", "BST2" },
+ { "RECMIXR", "BST1 Switch", "BST1" },
+
+ { "ADC 1", NULL, "RECMIXL" },
+ { "ADC 1", NULL, "ADC 1 power" },
+ { "ADC 1", NULL, "ADC clock" },
+ { "ADC 2", NULL, "RECMIXR" },
+ { "ADC 2", NULL, "ADC 2 power" },
+ { "ADC 2", NULL, "ADC clock" },
+
+ { "DMIC L1", NULL, "DMIC CLK" },
+ { "DMIC L1", NULL, "DMIC1 Power" },
+ { "DMIC R1", NULL, "DMIC CLK" },
+ { "DMIC R1", NULL, "DMIC1 Power" },
+ { "DMIC L2", NULL, "DMIC CLK" },
+ { "DMIC L2", NULL, "DMIC2 Power" },
+ { "DMIC R2", NULL, "DMIC CLK" },
+ { "DMIC R2", NULL, "DMIC2 Power" },
+ { "DMIC L3", NULL, "DMIC CLK" },
+ { "DMIC L3", NULL, "DMIC3 Power" },
+ { "DMIC R3", NULL, "DMIC CLK" },
+ { "DMIC R3", NULL, "DMIC3 Power" },
+
+ { "Stereo1 DMIC Mux", "DMIC1", "DMIC1" },
+ { "Stereo1 DMIC Mux", "DMIC2", "DMIC2" },
+ { "Stereo1 DMIC Mux", "DMIC3", "DMIC3" },
+
+ { "Stereo2 DMIC Mux", "DMIC1", "DMIC1" },
+ { "Stereo2 DMIC Mux", "DMIC2", "DMIC2" },
+ { "Stereo2 DMIC Mux", "DMIC3", "DMIC3" },
+
+ { "Mono DMIC L Mux", "DMIC1", "DMIC L1" },
+ { "Mono DMIC L Mux", "DMIC2", "DMIC L2" },
+ { "Mono DMIC L Mux", "DMIC3", "DMIC L3" },
+
+ { "Mono DMIC R Mux", "DMIC1", "DMIC R1" },
+ { "Mono DMIC R Mux", "DMIC2", "DMIC R2" },
+ { "Mono DMIC R Mux", "DMIC3", "DMIC R3" },
+
+ { "ADC 1_2", NULL, "ADC 1" },
+ { "ADC 1_2", NULL, "ADC 2" },
+
+ { "Stereo1 ADC L2 Mux", "DMIC", "Stereo1 DMIC Mux" },
+ { "Stereo1 ADC L2 Mux", "DAC MIX", "DAC MIXL" },
+ { "Stereo1 ADC L1 Mux", "ADC", "ADC 1_2" },
+ { "Stereo1 ADC L1 Mux", "DAC MIX", "DAC MIXL" },
+
+ { "Stereo1 ADC R1 Mux", "ADC", "ADC 1_2" },
+ { "Stereo1 ADC R1 Mux", "DAC MIX", "DAC MIXR" },
+ { "Stereo1 ADC R2 Mux", "DMIC", "Stereo1 DMIC Mux" },
+ { "Stereo1 ADC R2 Mux", "DAC MIX", "DAC MIXR" },
+
+ { "Mono ADC L2 Mux", "DMIC", "Mono DMIC L Mux" },
+ { "Mono ADC L2 Mux", "Mono DAC MIXL", "Mono DAC MIXL" },
+ { "Mono ADC L1 Mux", "Mono DAC MIXL", "Mono DAC MIXL" },
+ { "Mono ADC L1 Mux", "ADC1", "ADC 1" },
+
+ { "Mono ADC R1 Mux", "Mono DAC MIXR", "Mono DAC MIXR" },
+ { "Mono ADC R1 Mux", "ADC2", "ADC 2" },
+ { "Mono ADC R2 Mux", "DMIC", "Mono DMIC R Mux" },
+ { "Mono ADC R2 Mux", "Mono DAC MIXR", "Mono DAC MIXR" },
+
+ { "Sto1 ADC MIXL", "ADC1 Switch", "Stereo1 ADC L1 Mux" },
+ { "Sto1 ADC MIXL", "ADC2 Switch", "Stereo1 ADC L2 Mux" },
+ { "Sto1 ADC MIXR", "ADC1 Switch", "Stereo1 ADC R1 Mux" },
+ { "Sto1 ADC MIXR", "ADC2 Switch", "Stereo1 ADC R2 Mux" },
+
+ { "Stereo1 ADC MIXL", NULL, "Sto1 ADC MIXL" },
+ { "Stereo1 ADC MIXL", NULL, "adc stereo1 filter" },
+ { "adc stereo1 filter", NULL, "PLL1", check_sysclk1_source },
+
+ { "Stereo1 ADC MIXR", NULL, "Sto1 ADC MIXR" },
+ { "Stereo1 ADC MIXR", NULL, "adc stereo1 filter" },
+ { "adc stereo1 filter", NULL, "PLL1", check_sysclk1_source },
+
+ { "Mono ADC MIXL", "ADC1 Switch", "Mono ADC L1 Mux" },
+ { "Mono ADC MIXL", "ADC2 Switch", "Mono ADC L2 Mux" },
+ { "Mono ADC MIXL", NULL, "adc mono left filter" },
+ { "adc mono left filter", NULL, "PLL1", check_sysclk1_source },
+
+ { "Mono ADC MIXR", "ADC1 Switch", "Mono ADC R1 Mux" },
+ { "Mono ADC MIXR", "ADC2 Switch", "Mono ADC R2 Mux" },
+ { "Mono ADC MIXR", NULL, "adc mono right filter" },
+ { "adc mono right filter", NULL, "PLL1", check_sysclk1_source },
+
+ { "Stereo2 ADC L2 Mux", "DMIC", "Stereo2 DMIC Mux" },
+ { "Stereo2 ADC L2 Mux", "DAC MIX", "DAC MIXL" },
+ { "Stereo2 ADC L1 Mux", "ADC", "ADC 1_2" },
+ { "Stereo2 ADC L1 Mux", "DAC MIX", "DAC MIXL" },
+
+ { "Stereo2 ADC R1 Mux", "ADC", "ADC 1_2" },
+ { "Stereo2 ADC R1 Mux", "DAC MIX", "DAC MIXR" },
+ { "Stereo2 ADC R2 Mux", "DMIC", "Stereo2 DMIC Mux" },
+ { "Stereo2 ADC R2 Mux", "DAC MIX", "DAC MIXR" },
+
+ { "Sto2 ADC MIXL", "ADC1 Switch", "Stereo2 ADC L1 Mux" },
+ { "Sto2 ADC MIXL", "ADC2 Switch", "Stereo2 ADC L2 Mux" },
+ { "Sto2 ADC MIXR", "ADC1 Switch", "Stereo2 ADC R1 Mux" },
+ { "Sto2 ADC MIXR", "ADC2 Switch", "Stereo2 ADC R2 Mux" },
+
+ { "Sto2 ADC LR MIX", NULL, "Sto2 ADC MIXL" },
+ { "Sto2 ADC LR MIX", NULL, "Sto2 ADC MIXR" },
+
+ { "Stereo2 ADC LR Mux", "L", "Sto2 ADC MIXL" },
+ { "Stereo2 ADC LR Mux", "LR", "Sto2 ADC LR MIX" },
+
+ { "Stereo2 ADC MIXL", NULL, "Stereo2 ADC LR Mux" },
+ { "Stereo2 ADC MIXL", NULL, "adc stereo2 filter" },
+ { "adc stereo2 filter", NULL, "PLL1", check_sysclk1_source },
+
+ { "Stereo2 ADC MIXR", NULL, "Sto2 ADC MIXR" },
+ { "Stereo2 ADC MIXR", NULL, "adc stereo2 filter" },
+ { "adc stereo2 filter", NULL, "PLL1", check_sysclk1_source },
+
+ { "VAD ADC Mux", "Sto1 ADC L", "Stereo1 ADC MIXL" },
+ { "VAD ADC Mux", "Mono ADC L", "Mono ADC MIXL" },
+ { "VAD ADC Mux", "Mono ADC R", "Mono ADC MIXR" },
+ { "VAD ADC Mux", "Sto2 ADC L", "Sto2 ADC MIXL" },
+
+ { "VAD_ADC", NULL, "VAD ADC Mux" },
+
+ { "IF_ADC1", NULL, "Stereo1 ADC MIXL" },
+ { "IF_ADC1", NULL, "Stereo1 ADC MIXR" },
+ { "IF_ADC2", NULL, "Mono ADC MIXL" },
+ { "IF_ADC2", NULL, "Mono ADC MIXR" },
+ { "IF_ADC3", NULL, "Stereo2 ADC MIXL" },
+ { "IF_ADC3", NULL, "Stereo2 ADC MIXR" },
+
+ { "IF1 ADC1 IN1 Mux", "IF_ADC1", "IF_ADC1" },
+ { "IF1 ADC1 IN1 Mux", "IF1_ADC3", "IF1_ADC3" },
+
+ { "IF1 ADC1 IN2 Mux", "IF1_ADC1_IN1", "IF1 ADC1 IN1 Mux" },
+ { "IF1 ADC1 IN2 Mux", "IF1_ADC4", "IF1_ADC4" },
+
+ { "IF1 ADC2 IN Mux", "IF_ADC2", "IF_ADC2" },
+ { "IF1 ADC2 IN Mux", "VAD_ADC", "VAD_ADC" },
+
+ { "IF1 ADC2 IN1 Mux", "IF1_ADC2_IN", "IF1 ADC2 IN Mux" },
+ { "IF1 ADC2 IN1 Mux", "IF1_ADC4", "IF1_ADC4" },
+
+ { "IF1_ADC1" , NULL, "IF1 ADC1 IN2 Mux" },
+ { "IF1_ADC2" , NULL, "IF1 ADC2 IN1 Mux" },
+
+ { "Stereo1 ADC MIX", NULL, "Stereo1 ADC MIXL" },
+ { "Stereo1 ADC MIX", NULL, "Stereo1 ADC MIXR" },
+ { "Stereo2 ADC MIX", NULL, "Sto2 ADC MIXL" },
+ { "Stereo2 ADC MIX", NULL, "Sto2 ADC MIXR" },
+
+ { "RxDP Mux", "IF2 DAC", "IF2 DAC" },
+ { "RxDP Mux", "IF1 DAC", "IF1 DAC2" },
+ { "RxDP Mux", "STO1 ADC Mixer", "Stereo1 ADC MIX" },
+ { "RxDP Mux", "STO2 ADC Mixer", "Stereo2 ADC MIX" },
+ { "RxDP Mux", "Mono ADC Mixer L", "Mono ADC MIXL" },
+ { "RxDP Mux", "Mono ADC Mixer R", "Mono ADC MIXR" },
+ { "RxDP Mux", "DAC1", "DAC MIX" },
+
+ { "8CH TDM Data", NULL, "Stereo1 ADC MIXL" },
+ { "8CH TDM Data", NULL, "Stereo1 ADC MIXR" },
+ { "8CH TDM Data", NULL, "Mono ADC MIXL" },
+ { "8CH TDM Data", NULL, "Mono ADC MIXR" },
+ { "8CH TDM Data", NULL, "Sto2 ADC MIXL" },
+ { "8CH TDM Data", NULL, "Sto2 ADC MIXR" },
+ { "8CH TDM Data", NULL, "IF2 DAC L" },
+ { "8CH TDM Data", NULL, "IF2 DAC R" },
+
+ { "DSP UL Mux", "Bypass", "8CH TDM Data" },
+ { "DSP UL Mux", NULL, "I2S DSP" },
+ { "DSP DL Mux", "Bypass", "RxDP Mux" },
+ { "DSP DL Mux", NULL, "I2S DSP" },
+
+ { "TxDP_ADC_L", NULL, "DSP UL Mux" },
+ { "TxDP_ADC_R", NULL, "DSP UL Mux" },
+ { "TxDC_DAC", NULL, "DSP DL Mux" },
+
+ { "TxDP_ADC", NULL, "TxDP_ADC_L" },
+ { "TxDP_ADC", NULL, "TxDP_ADC_R" },
+
+ { "IF1 ADC", NULL, "I2S1" },
+ { "IF1 ADC", NULL, "IF1_ADC1" },
+#ifdef USE_TDM
+ { "IF1 ADC", NULL, "IF1_ADC2" },
+ { "IF1 ADC", NULL, "IF_ADC3" },
+ { "IF1 ADC", NULL, "TxDP_ADC" },
+#endif
+
+ { "IF2 ADC Mux", "IF_ADC1", "IF_ADC1" },
+ { "IF2 ADC Mux", "IF_ADC2", "IF_ADC2" },
+ { "IF2 ADC Mux", "IF_ADC3", "IF_ADC3" },
+ { "IF2 ADC Mux", "TxDC_DAC", "TxDC_DAC" },
+ { "IF2 ADC Mux", "TxDP_ADC", "TxDP_ADC" },
+ { "IF2 ADC Mux", "VAD_ADC", "VAD_ADC" },
+
+ { "IF2 ADC L", NULL, "IF2 ADC Mux" },
+ { "IF2 ADC R", NULL, "IF2 ADC Mux" },
+
+ { "IF2 ADC", NULL, "I2S2" },
+ { "IF2 ADC", NULL, "IF2 ADC L" },
+ { "IF2 ADC", NULL, "IF2 ADC R" },
+
+ { "AIF1TX", NULL, "IF1 ADC" },
+ { "AIF2TX", NULL, "IF2 ADC" },
+
+ { "IF1 DAC1", NULL, "AIF1RX" },
+#ifdef USE_TDM
+ { "IF1 DAC2", NULL, "AIF1RX" },
+#endif
+ { "IF2 DAC", NULL, "AIF2RX" },
+
+ { "IF1 DAC1", NULL, "I2S1" },
+ { "IF1 DAC2", NULL, "I2S1" },
+ { "IF2 DAC", NULL, "I2S2" },
+
+ { "IF1 DAC2 L", NULL, "IF1 DAC2" },
+ { "IF1 DAC2 R", NULL, "IF1 DAC2" },
+ { "IF1 DAC1 L", NULL, "IF1 DAC1" },
+ { "IF1 DAC1 R", NULL, "IF1 DAC1" },
+ { "IF2 DAC L", NULL, "IF2 DAC" },
+ { "IF2 DAC R", NULL, "IF2 DAC" },
+
+ { "DAC1 L Mux", "IF1 DAC", "IF1 DAC1 L" },
+ { "DAC1 L Mux", "IF2 DAC", "IF2 DAC L" },
+
+ { "DAC1 R Mux", "IF1 DAC", "IF1 DAC1 R" },
+ { "DAC1 R Mux", "IF2 DAC", "IF2 DAC R" },
+
+ { "DAC1 MIXL", "Stereo ADC Switch", "Stereo1 ADC MIXL" },
+ { "DAC1 MIXL", "DAC1 Switch", "DAC1 L Mux" },
+ { "DAC1 MIXL", NULL, "dac stereo1 filter" },
+ { "DAC1 MIXR", "Stereo ADC Switch", "Stereo1 ADC MIXR" },
+ { "DAC1 MIXR", "DAC1 Switch", "DAC1 R Mux" },
+ { "DAC1 MIXR", NULL, "dac stereo1 filter" },
+
+ { "DAC MIX", NULL, "DAC1 MIXL" },
+ { "DAC MIX", NULL, "DAC1 MIXR" },
+
+ { "Audio DSP", NULL, "DAC1 MIXL" },
+ { "Audio DSP", NULL, "DAC1 MIXR" },
+
+ { "DAC L2 Mux", "IF1 DAC", "IF1 DAC1 L" },
+ { "DAC L2 Mux", "IF2 DAC", "IF2 DAC L" },
+ { "DAC L2 Mux", "TxDC DAC", "TxDC_DAC" },
+ { "DAC L2 Mux", "VAD_ADC", "VAD_ADC" },
+ { "DAC L2 Volume", NULL, "DAC L2 Mux" },
+ { "DAC L2 Volume", NULL, "dac mono left filter" },
+
+ { "DAC R2 Mux", "IF1 DAC", "IF1 DAC1 R" },
+ { "DAC R2 Mux", "IF2 DAC", "IF2 DAC R" },
+ { "DAC R2 Mux", "TxDC DAC", "TxDC_DAC" },
+ { "DAC R2 Mux", "TxDP ADC", "TxDP_ADC" },
+ { "DAC R2 Volume", NULL, "DAC R2 Mux" },
+ { "DAC R2 Volume", NULL, "dac mono right filter" },
+
+ { "Stereo DAC MIXL", "DAC L1 Switch", "DAC1 MIXL" },
+ { "Stereo DAC MIXL", "DAC R1 Switch", "DAC1 MIXR" },
+ { "Stereo DAC MIXL", "DAC L2 Switch", "DAC L2 Volume" },
+ { "Stereo DAC MIXL", NULL, "dac stereo1 filter" },
+ { "Stereo DAC MIXR", "DAC R1 Switch", "DAC1 MIXR" },
+ { "Stereo DAC MIXR", "DAC L1 Switch", "DAC1 MIXL" },
+ { "Stereo DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" },
+ { "Stereo DAC MIXR", NULL, "dac stereo1 filter" },
+
+ { "Mono DAC MIXL", "DAC L1 Switch", "DAC1 MIXL" },
+ { "Mono DAC MIXL", "DAC L2 Switch", "DAC L2 Volume" },
+ { "Mono DAC MIXL", "DAC R2 Switch", "DAC R2 Volume" },
+ { "Mono DAC MIXL", NULL, "dac mono left filter" },
+ { "Mono DAC MIXR", "DAC R1 Switch", "DAC1 MIXR" },
+ { "Mono DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" },
+ { "Mono DAC MIXR", "DAC L2 Switch", "DAC L2 Volume" },
+ { "Mono DAC MIXR", NULL, "dac mono right filter" },
+
+ { "DAC MIXL", "Sto DAC Mix L Switch", "Stereo DAC MIXL" },
+ { "DAC MIXL", "DAC L2 Switch", "DAC L2 Volume" },
+ { "DAC MIXL", "DAC R2 Switch", "DAC R2 Volume" },
+ { "DAC MIXR", "Sto DAC Mix R Switch", "Stereo DAC MIXR" },
+ { "DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" },
+ { "DAC MIXR", "DAC L2 Switch", "DAC L2 Volume" },
+
+ { "DAC L1", NULL, "DAC L1 Power" },
+ { "DAC L1", NULL, "Stereo DAC MIXL" },
+ { "DAC L1", NULL, "PLL1", check_sysclk1_source },
+ { "DAC R1", NULL, "DAC R1 Power" },
+ { "DAC R1", NULL, "Stereo DAC MIXR" },
+ { "DAC R1", NULL, "PLL1", check_sysclk1_source },
+ { "DAC L2", NULL, "Mono DAC MIXL" },
+ { "DAC L2", NULL, "PLL1", check_sysclk1_source },
+ { "DAC R2", NULL, "Mono DAC MIXR" },
+ { "DAC R2", NULL, "PLL1", check_sysclk1_source },
+
+ { "OUT MIXL", "BST1 Switch", "BST1" },
+ { "OUT MIXL", "INL Switch", "INL VOL" },
+ { "OUT MIXL", "DAC L2 Switch", "DAC L2" },
+ { "OUT MIXL", "DAC L1 Switch", "DAC L1" },
+
+ { "OUT MIXR", "BST2 Switch", "BST2" },
+ { "OUT MIXR", "INR Switch", "INR VOL" },
+ { "OUT MIXR", "DAC R2 Switch", "DAC R2" },
+ { "OUT MIXR", "DAC R1 Switch", "DAC R1" },
+
+ { "HPOVOL MIXL", "DAC1 Switch", "DAC L1" },
+ { "HPOVOL MIXL", "INL Switch", "INL VOL" },
+ { "HPOVOL MIXR", "DAC1 Switch", "DAC R1" },
+ { "HPOVOL MIXR", "INR Switch", "INR VOL" },
+
+ { "DAC 2", NULL, "DAC L2" },
+ { "DAC 2", NULL, "DAC R2" },
+ { "DAC 1", NULL, "DAC L1" },
+ { "DAC 1", NULL, "DAC R1" },
+ { "HPOVOL", NULL, "HPOVOL MIXL" },
+ { "HPOVOL", NULL, "HPOVOL MIXR" },
+ { "HPO MIX", "DAC1 Switch", "DAC 1" },
+ { "HPO MIX", "HPVOL Switch", "HPOVOL" },
+
+ { "LOUT MIX", "DAC L1 Switch", "DAC L1" },
+ { "LOUT MIX", "DAC R1 Switch", "DAC R1" },
+ { "LOUT MIX", "OUTMIX L Switch", "OUT MIXL" },
+ { "LOUT MIX", "OUTMIX R Switch", "OUT MIXR" },
+
+ { "PDM1 L Mux", "Stereo DAC", "Stereo DAC MIXL" },
+ { "PDM1 L Mux", "Mono DAC", "Mono DAC MIXL" },
+ { "PDM1 L Mux", NULL, "PDM1 Power" },
+ { "PDM1 R Mux", "Stereo DAC", "Stereo DAC MIXR" },
+ { "PDM1 R Mux", "Mono DAC", "Mono DAC MIXR" },
+ { "PDM1 R Mux", NULL, "PDM1 Power" },
+ { "PDM2 L Mux", "Stereo DAC", "Stereo DAC MIXL" },
+ { "PDM2 L Mux", "Mono DAC", "Mono DAC MIXL" },
+ { "PDM2 L Mux", NULL, "PDM2 Power" },
+ { "PDM2 R Mux", "Stereo DAC", "Stereo DAC MIXR" },
+ { "PDM2 R Mux", "Mono DAC", "Mono DAC MIXR" },
+ { "PDM2 R Mux", NULL, "PDM2 Power" },
+
+ { "HP Amp", NULL, "HPO MIX" },
+ { "HP Amp", NULL, "JD Power" },
+ { "HP Amp", NULL, "Mic Det Power" },
+ { "HPOL", NULL, "HP Amp" },
+ { "HPOL", NULL, "HP L Amp" },
+ { "HPOL", NULL, "Improve HP Amp Drv" },
+ { "HPOR", NULL, "HP Amp" },
+ { "HPOR", NULL, "HP R Amp" },
+ { "HPOR", NULL, "Improve HP Amp Drv" },
+
+ { "LOUT Amp", NULL, "LOUT MIX" },
+ { "LOUTL", NULL, "LOUT Amp" },
+ { "LOUTR", NULL, "LOUT Amp" },
+#ifndef RT5672
+ { "PDM1L", NULL, "PDM1 L Mux" },
+ { "PDM1R", NULL, "PDM1 R Mux" },
+ { "PDM2L", NULL, "PDM2 L Mux" },
+ { "PDM2R", NULL, "PDM2 R Mux" },
+#else
+ { "SPO Amp", NULL, "PDM1 L Mux" },
+ { "SPO Amp", NULL, "PDM1 R Mux" },
+ { "SPOL", NULL, "SPO Amp" },
+ { "SPOR", NULL, "SPO Amp" },
+#endif
+};
+
+static int get_sdp_info(struct snd_soc_codec *codec, int dai_id)
+{
+ int ret = 0, val;
+
+ if(codec == NULL)
+ return -EINVAL;
+
+ val = snd_soc_read(codec, RT5670_I2S1_SDP);
+ val = (val & RT5670_I2S_IF_MASK) >> RT5670_I2S_IF_SFT;
+ switch (dai_id) {
+ case RT5670_AIF1:
+ ret |= RT5670_U_IF1;
+ break;
+
+ case RT5670_AIF2:
+ ret |= RT5670_U_IF2;
+ break;
+
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int get_clk_info(int sclk, int rate)
+{
+ int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16};
+
+#ifdef USE_ASRC
+ return 0;
+#endif
+ if (sclk <= 0 || rate <= 0)
+ return -EINVAL;
+
+ rate = rate << 8;
+ for (i = 0; i < ARRAY_SIZE(pd); i++)
+ if (sclk == rate * pd[i])
+ return i;
+
+ return -EINVAL;
+}
+
+static int rt5670_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+ unsigned int val_len = 0, val_clk, mask_clk, dai_sel;
+ int pre_div, bclk_ms, frame_size;
+
+ if (RT5670_AIF2 == dai->id) {
+ snd_soc_update_bits(codec, RT5670_GPIO_CTRL1,
+ RT5670_I2S2_PIN_MASK, RT5670_I2S2_PIN_I2S);
+ }
+ rt5670->lrck[dai->id] = params_rate(params);
+ pre_div = get_clk_info(rt5670->sysclk, rt5670->lrck[dai->id]);
+ if (pre_div < 0) {
+ dev_err(codec->dev, "Unsupported clock setting\n");
+ return -EINVAL;
+ }
+ frame_size = snd_soc_params_to_frame_size(params);
+ if (frame_size < 0) {
+ dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
+ return -EINVAL;
+ }
+ bclk_ms = frame_size > 32 ? 1 : 0;
+ rt5670->bclk[dai->id] = rt5670->lrck[dai->id] * (32 << bclk_ms);
+
+ dev_dbg(dai->dev, "bclk is %dHz and lrck is %dHz\n",
+ rt5670->bclk[dai->id], rt5670->lrck[dai->id]);
+ dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n",
+ bclk_ms, pre_div, dai->id);
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ val_len |= RT5670_I2S_DL_20;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ val_len |= RT5670_I2S_DL_24;
+ break;
+ case SNDRV_PCM_FORMAT_S8:
+ val_len |= RT5670_I2S_DL_8;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ dai_sel = get_sdp_info(codec, dai->id);
+ if (dai_sel < 0) {
+ dev_err(codec->dev, "Failed to get sdp info: %d\n", dai_sel);
+ return -EINVAL;
+ }
+ if (dai_sel & RT5670_U_IF1) {
+ mask_clk = RT5670_I2S_BCLK_MS1_MASK | RT5670_I2S_PD1_MASK;
+ val_clk = bclk_ms << RT5670_I2S_BCLK_MS1_SFT |
+ pre_div << RT5670_I2S_PD1_SFT;
+ snd_soc_update_bits(codec, RT5670_I2S1_SDP,
+ RT5670_I2S_DL_MASK, val_len);
+ snd_soc_update_bits(codec, RT5670_ADDA_CLK1, mask_clk, val_clk);
+ }
+ if (dai_sel & RT5670_U_IF2) {
+ mask_clk = RT5670_I2S_BCLK_MS2_MASK | RT5670_I2S_PD2_MASK;
+ val_clk = bclk_ms << RT5670_I2S_BCLK_MS2_SFT |
+ pre_div << RT5670_I2S_PD2_SFT;
+ snd_soc_update_bits(codec, RT5670_I2S2_SDP,
+ RT5670_I2S_DL_MASK, val_len);
+ snd_soc_update_bits(codec, RT5670_ADDA_CLK1, mask_clk, val_clk);
+ }
+
+
+ return 0;
+}
+
+static int rt5670_hw_free(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+
+ if (RT5670_AIF2 == dai->id) {
+ snd_soc_update_bits(codec, RT5670_GPIO_CTRL1,
+ RT5670_I2S2_PIN_MASK, RT5670_I2S2_PIN_GPIO);
+ }
+
+ return 0;
+}
+
+
+static int rt5670_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+
+ rt5670->aif_pu = dai->id;
+ return 0;
+}
+
+static int rt5670_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+ unsigned int reg_val = 0, dai_sel;
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ rt5670->master[dai->id] = 1;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ reg_val |= RT5670_I2S_MS_S;
+ rt5670->master[dai->id] = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ reg_val |= RT5670_I2S_BP_INV;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ reg_val |= RT5670_I2S_DF_LEFT;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ reg_val |= RT5670_I2S_DF_PCM_A;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ reg_val |= RT5670_I2S_DF_PCM_B;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ dai_sel = get_sdp_info(codec, dai->id);
+ if (dai_sel < 0) {
+ dev_err(codec->dev, "Failed to get sdp info: %d\n", dai_sel);
+ return -EINVAL;
+ }
+ if (dai_sel & RT5670_U_IF1) {
+ snd_soc_update_bits(codec, RT5670_I2S1_SDP,
+ RT5670_I2S_MS_MASK | RT5670_I2S_BP_MASK |
+ RT5670_I2S_DF_MASK, reg_val);
+ }
+ if (dai_sel & RT5670_U_IF2) {
+ snd_soc_update_bits(codec, RT5670_I2S2_SDP,
+ RT5670_I2S_MS_MASK | RT5670_I2S_BP_MASK |
+ RT5670_I2S_DF_MASK, reg_val);
+ }
+
+
+ return 0;
+}
+
+static int rt5670_set_dai_sysclk(struct snd_soc_dai *dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+ unsigned int reg_val = 0;
+
+ printk("\n=========[rt5670] %s(%d),CLK id is %d freq = %d \n",__FUNCTION__,__LINE__, clk_id, freq);
+
+ if (freq == rt5670->sysclk && clk_id == rt5670->sysclk_src)
+ return 0;
+
+ switch (clk_id) {
+ case RT5670_SCLK_S_MCLK:
+ reg_val |= RT5670_SCLK_SRC_MCLK;
+ break;
+ case RT5670_SCLK_S_PLL1:
+ reg_val |= RT5670_SCLK_SRC_PLL1;
+ break;
+ case RT5670_SCLK_S_RCCLK:
+ reg_val |= RT5670_SCLK_SRC_RCCLK;
+ break;
+ default:
+ dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+ return -EINVAL;
+ }
+ snd_soc_update_bits(codec, RT5670_GLB_CLK,
+ RT5670_SCLK_SRC_MASK, reg_val);
+ rt5670->sysclk = freq;
+ rt5670->sysclk_src = clk_id;
+
+ dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
+
+ return 0;
+}
+
+/**
+ * rt5670_pll_calc - Calcualte PLL M/N/K code.
+ * @freq_in: external clock provided to codec.
+ * @freq_out: target clock which codec works on.
+ * @pll_code: Pointer to structure with M, N, K and bypass flag.
+ *
+ * Calcualte M/N/K code to configure PLL for codec. And K is assigned to 2
+ * which make calculation more efficiently.
+ *
+ * Returns 0 for success or negative error code.
+ */
+static int rt5670_pll_calc(const unsigned int freq_in,
+ const unsigned int freq_out, struct rt5670_pll_code *pll_code)
+{
+ int max_n = RT5670_PLL_N_MAX, max_m = RT5670_PLL_M_MAX;
+ int k, n = 0, m = 0, red, n_t, m_t, pll_out, in_t;
+ int out_t, red_t = abs(freq_out - freq_in);
+ bool bypass = false;
+
+ if (RT5670_PLL_INP_MAX < freq_in || RT5670_PLL_INP_MIN > freq_in)
+ return -EINVAL;
+
+ k = 100000000 / freq_out - 2;
+ if (k > RT5670_PLL_K_MAX)
+ k = RT5670_PLL_K_MAX;
+ for (n_t = 0; n_t <= max_n; n_t++) {
+ in_t = freq_in / (k + 2);
+ pll_out = freq_out / (n_t + 2);
+ if (in_t < 0)
+ continue;
+ if (in_t == pll_out) {
+ bypass = true;
+ n = n_t;
+ goto code_find;
+ }
+ red = abs(in_t - pll_out);
+ if (red < red_t) {
+ bypass = true;
+ n = n_t;
+ m = m_t;
+ if (red == 0)
+ goto code_find;
+ red_t = red;
+ }
+ for (m_t = 0; m_t <= max_m; m_t++) {
+ out_t = in_t / (m_t + 2);
+ red = abs(out_t - pll_out);
+ if (red < red_t) {
+ bypass = false;
+ n = n_t;
+ m = m_t;
+ if (red == 0)
+ goto code_find;
+ red_t = red;
+ }
+ }
+ }
+ pr_debug("Only get approximation about PLL\n");
+
+code_find:
+
+ pll_code->m_bp = bypass;
+ pll_code->m_code = m;
+ pll_code->n_code = n;
+ pll_code->k_code = k;
+ return 0;
+}
+
+static int rt5670_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
+ unsigned int freq_in, unsigned int freq_out)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+ struct rt5670_pll_code pll_code;
+ int ret, dai_sel;
+
+ if (source == rt5670->pll_src && freq_in == rt5670->pll_in &&
+ freq_out == rt5670->pll_out)
+ return 0;
+
+ if (!freq_in || !freq_out) {
+ dev_dbg(codec->dev, "PLL disabled\n");
+
+ rt5670->pll_in = 0;
+ rt5670->pll_out = 0;
+ snd_soc_update_bits(codec, RT5670_GLB_CLK,
+ RT5670_SCLK_SRC_MASK, RT5670_SCLK_SRC_MCLK);
+ return 0;
+ }
+
+ switch (source) {
+ case RT5670_PLL1_S_MCLK:
+ snd_soc_update_bits(codec, RT5670_GLB_CLK,
+ RT5670_PLL1_SRC_MASK, RT5670_PLL1_SRC_MCLK);
+ break;
+ case RT5670_PLL1_S_BCLK1:
+ case RT5670_PLL1_S_BCLK2:
+ case RT5670_PLL1_S_BCLK3:
+ case RT5670_PLL1_S_BCLK4:
+ dai_sel = get_sdp_info(codec, dai->id);
+ if (dai_sel < 0) {
+ dev_err(codec->dev,
+ "Failed to get sdp info: %d\n", dai_sel);
+ return -EINVAL;
+ }
+ if (dai_sel & RT5670_U_IF1) {
+ snd_soc_update_bits(codec, RT5670_GLB_CLK,
+ RT5670_PLL1_SRC_MASK, RT5670_PLL1_SRC_BCLK1);
+ }
+ if (dai_sel & RT5670_U_IF2) {
+ snd_soc_update_bits(codec, RT5670_GLB_CLK,
+ RT5670_PLL1_SRC_MASK, RT5670_PLL1_SRC_BCLK2);
+ }
+ break;
+ default:
+ dev_err(codec->dev, "Unknown PLL source %d\n", source);
+ return -EINVAL;
+ }
+
+ ret = rt5670_pll_calc(freq_in, freq_out, &pll_code);
+ if (ret < 0) {
+ dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
+ return ret;
+ }
+
+ dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n", pll_code.m_bp,
+ (pll_code.m_bp ? 0 : pll_code.m_code), pll_code.n_code, pll_code.k_code);
+
+ snd_soc_write(codec, RT5670_PLL_CTRL1,
+ pll_code.n_code << RT5670_PLL_N_SFT | pll_code.k_code);
+ snd_soc_write(codec, RT5670_PLL_CTRL2,
+ (pll_code.m_bp ? 0 : pll_code.m_code) << RT5670_PLL_M_SFT |
+ pll_code.m_bp << RT5670_PLL_M_BP_SFT);
+
+ rt5670->pll_in = freq_in;
+ rt5670->pll_out = freq_out;
+ rt5670->pll_src = source;
+
+ return 0;
+}
+
+static int rt5670_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+ unsigned int rx_mask, int slots, int slot_width)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ unsigned int val = 0;
+
+ if (rx_mask || tx_mask)
+ val |= (1 << 14);
+
+ switch (slots) {
+ case 4:
+ val |= (1 << 12);
+ break;
+ case 6:
+ val |= (2 << 12);
+ break;
+ case 8:
+ val |= (3 << 12);
+ break;
+ case 2:
+ default:
+ break;
+ }
+
+ switch (slot_width) {
+ case 20:
+ val |= (1 << 10);
+ break;
+ case 24:
+ val |= (2 << 10);
+ break;
+ case 32:
+ val |= (3 << 10);
+ break;
+ case 16:
+ default:
+ break;
+ }
+
+ snd_soc_update_bits(codec, RT5670_TDM_CTRL_1, 0x7c00, val);
+
+ return 0;
+}
+
+
+/**
+ * rt5670_index_show - Dump private registers.
+ * @dev: codec device.
+ * @attr: device attribute.
+ * @buf: buffer for display.
+ *
+ * To show non-zero values of all private registers.
+ *
+ * Returns buffer length.
+ */
+static ssize_t rt5670_index_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct rt5670_priv *rt5670 = i2c_get_clientdata(client);
+ struct snd_soc_codec *codec = rt5670->codec;
+ unsigned int val;
+ int cnt = 0, i;
+
+ codec->cache_bypass = 1;
+ cnt += sprintf(buf, "RT5670 index register\n");
+ for (i = 0; i < 0xff; i++) {
+ if (cnt + RT5670_REG_DISP_LEN >= PAGE_SIZE)
+ break;
+ val = rt5670_index_read(codec, i);
+ if (!val)
+ continue;
+ cnt += snprintf(buf + cnt, RT5670_REG_DISP_LEN,
+ "%02x: %04x\n", i, val);
+ }
+ codec->cache_bypass = 0;
+
+ if (cnt >= PAGE_SIZE)
+ cnt = PAGE_SIZE - 1;
+
+ return cnt;
+}
+
+static ssize_t rt5670_index_store(struct device *dev,struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct rt5670_priv *rt5670 = i2c_get_clientdata(client);
+ struct snd_soc_codec *codec = rt5670->codec;
+ unsigned int val=0,addr=0;
+ int i;
+
+ for(i=0;i<count;i++)
+ {
+ if(*(buf+i) <= '9' && *(buf+i)>='0')
+ {
+ addr = (addr << 4) | (*(buf+i)-'0');
+ }
+ else if(*(buf+i) <= 'f' && *(buf+i)>='a')
+ {
+ addr = (addr << 4) | ((*(buf+i)-'a')+0xa);
+ }
+ else if(*(buf+i) <= 'F' && *(buf+i)>='A')
+ {
+ addr = (addr << 4) | ((*(buf+i)-'A')+0xa);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ for(i=i+1 ;i<count;i++)
+ {
+ if(*(buf+i) <= '9' && *(buf+i)>='0')
+ {
+ val = (val << 4) | (*(buf+i)-'0');
+ }
+ else if(*(buf+i) <= 'f' && *(buf+i)>='a')
+ {
+ val = (val << 4) | ((*(buf+i)-'a')+0xa);
+ }
+ else if(*(buf+i) <= 'F' && *(buf+i)>='A')
+ {
+ val = (val << 4) | ((*(buf+i)-'A')+0xa);
+
+ }
+ else
+ {
+ break;
+ }
+ }
+ printk("addr=0x%x val=0x%x\n",addr,val);
+ if(addr > RT5670_VENDOR_ID2 || val > 0xffff || val < 0)
+ return count;
+
+ if(i==count)
+ {
+ printk("0x%02x = 0x%04x\n",addr,rt5670_index_read(codec, addr));
+ }
+ else
+ {
+ rt5670_index_write(codec, addr, val);
+ }
+
+
+ return count;
+}
+static DEVICE_ATTR(index_reg, 0666, rt5670_index_show, rt5670_index_store);
+
+static ssize_t rt5670_codec_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct rt5670_priv *rt5670 = i2c_get_clientdata(client);
+ struct snd_soc_codec *codec = rt5670->codec;
+ unsigned int val;
+ int cnt = 0, i;
+
+ for (i = 0; i <= RT5670_VENDOR_ID2; i++) {
+ if (cnt + RT5670_REG_DISP_LEN >= PAGE_SIZE)
+ break;
+ val = snd_soc_read(codec, i);
+ if (!val)
+ continue;
+ cnt += snprintf(buf + cnt, RT5670_REG_DISP_LEN,
+ "#rng%02x #rv%04x #rd0\n", i, val);
+ }
+
+ if (cnt >= PAGE_SIZE)
+ cnt = PAGE_SIZE - 1;
+
+ return cnt;
+}
+
+static ssize_t rt5670_codec_store(struct device *dev,struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct rt5670_priv *rt5670 = i2c_get_clientdata(client);
+ struct snd_soc_codec *codec = rt5670->codec;
+ unsigned int val=0,addr=0;
+ int i;
+
+ printk("register \"%s\" count=%d\n",buf,count);
+ for(i=0;i<count;i++)
+ {
+ if(*(buf+i) <= '9' && *(buf+i)>='0')
+ {
+ addr = (addr << 4) | (*(buf+i)-'0');
+ }
+ else if(*(buf+i) <= 'f' && *(buf+i)>='a')
+ {
+ addr = (addr << 4) | ((*(buf+i)-'a')+0xa);
+ }
+ else if(*(buf+i) <= 'F' && *(buf+i)>='A')
+ {
+ addr = (addr << 4) | ((*(buf+i)-'A')+0xa);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ for(i=i+1 ;i<count;i++)
+ {
+ if(*(buf+i) <= '9' && *(buf+i)>='0')
+ {
+ val = (val << 4) | (*(buf+i)-'0');
+ }
+ else if(*(buf+i) <= 'f' && *(buf+i)>='a')
+ {
+ val = (val << 4) | ((*(buf+i)-'a')+0xa);
+ }
+ else if(*(buf+i) <= 'F' && *(buf+i)>='A')
+ {
+ val = (val << 4) | ((*(buf+i)-'A')+0xa);
+
+ }
+ else
+ {
+ break;
+ }
+ }
+ printk("addr=0x%x val=0x%x\n",addr,val);
+ if(addr > RT5670_VENDOR_ID2 || val > 0xffff || val < 0)
+ return count;
+
+ if(i==count)
+ {
+ printk("0x%02x = 0x%04x\n",addr,codec->hw_read(codec, addr));
+ }
+ else
+ {
+ snd_soc_write(codec, addr, val);
+ }
+
+
+ return count;
+}
+
+static DEVICE_ATTR(codec_reg, 0666, rt5670_codec_show, rt5670_codec_store);
+
+static int rt5670_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ break;
+
+ case SND_SOC_BIAS_PREPARE:
+ if (SND_SOC_BIAS_STANDBY == codec->dapm.bias_level) {
+ snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
+ RT5670_PWR_VREF1 | RT5670_PWR_MB |
+ RT5670_PWR_BG | RT5670_PWR_VREF2,
+ RT5670_PWR_VREF1 | RT5670_PWR_MB |
+ RT5670_PWR_BG | RT5670_PWR_VREF2);
+ mdelay(10);
+ snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
+ RT5670_PWR_FV1 | RT5670_PWR_FV2,
+ RT5670_PWR_FV1 | RT5670_PWR_FV2);
+ snd_soc_update_bits(codec, RT5670_CHARGE_PUMP,
+ RT5670_OSW_L_MASK | RT5670_OSW_R_MASK,
+ RT5670_OSW_L_DIS | RT5670_OSW_R_DIS);
+ snd_soc_update_bits(codec, RT5670_DIG_MISC, 0x1, 0x1);
+ snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
+ RT5670_LDO_SEL_MASK, 0x3);
+ }
+ break;
+
+ case SND_SOC_BIAS_STANDBY:
+ break;
+
+ case SND_SOC_BIAS_OFF:
+ snd_soc_write(codec, RT5670_PWR_DIG1, 0x0000);
+ snd_soc_write(codec, RT5670_PWR_DIG2, 0x0001);
+ snd_soc_write(codec, RT5670_PWR_VOL, 0x0000);
+ snd_soc_write(codec, RT5670_PWR_MIXER, 0x0001);
+#ifdef JD1_FUNC
+ snd_soc_write(codec, RT5670_PWR_ANLG1, 0x2800);
+ snd_soc_write(codec, RT5670_PWR_ANLG2, 0x0004);
+#else
+ snd_soc_write(codec, RT5670_PWR_ANLG1, 0x0000);
+ snd_soc_write(codec, RT5670_PWR_ANLG2, 0x0000);
+#endif
+ if (rt5670->jack_type == SND_JACK_HEADSET) {
+ snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
+ 0x0003, 0x0003);
+ snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
+ 0x0c00, 0x0c00);
+ snd_soc_update_bits(codec, RT5670_PWR_DIG1,
+ 0x1800, 0x1800);
+ snd_soc_update_bits(codec, RT5670_PWR_VOL,
+ 0x0020, 0x0020);
+ }
+ break;
+
+ default:
+ break;
+ }
+ codec->dapm.bias_level = level;
+
+ return 0;
+}
+
+static int rt5670_probe(struct snd_soc_codec *codec)
+{
+ struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+#ifdef RTK_IOCTL
+#if defined(CONFIG_SND_HWDEP) || defined(CONFIG_SND_HWDEP_MODULE)
+ struct rt_codec_ops *ioctl_ops = rt_codec_get_ioctl_ops();
+#endif
+#endif
+ int ret;
+
+ printk("dbg: %s line %d\n",__func__,__LINE__);
+ pr_info("Codec driver version %s\n", VERSION);
+
+ codec->dapm.idle_bias_off = 1;
+
+ ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
+ }
+ rt5670_reset(codec);
+ snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
+ RT5670_PWR_HP_L | RT5670_PWR_HP_R |
+ RT5670_PWR_VREF2, RT5670_PWR_VREF2);
+ msleep(1000);
+
+ rt5670_reset(codec);
+ snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
+ RT5670_PWR_VREF1 | RT5670_PWR_MB |
+ RT5670_PWR_BG | RT5670_PWR_VREF2,
+ RT5670_PWR_VREF1 | RT5670_PWR_MB |
+ RT5670_PWR_BG | RT5670_PWR_VREF2);
+ msleep(10);
+ snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
+ RT5670_PWR_FV1 | RT5670_PWR_FV2,
+ RT5670_PWR_FV1 | RT5670_PWR_FV2);
+ /* DMIC */
+ if (rt5670->dmic_en == RT5670_DMIC1) {
+ snd_soc_update_bits(codec, RT5670_GPIO_CTRL1,
+ RT5670_GP2_PIN_MASK, RT5670_GP2_PIN_DMIC1_SCL);
+ snd_soc_update_bits(codec, RT5670_DMIC_CTRL1,
+ RT5670_DMIC_1L_LH_MASK | RT5670_DMIC_1R_LH_MASK,
+ RT5670_DMIC_1L_LH_FALLING | RT5670_DMIC_1R_LH_RISING);
+ } else if (rt5670->dmic_en == RT5670_DMIC2) {
+ snd_soc_update_bits(codec, RT5670_GPIO_CTRL1,
+ RT5670_GP2_PIN_MASK, RT5670_GP2_PIN_DMIC1_SCL);
+ snd_soc_update_bits(codec, RT5670_DMIC_CTRL1,
+ RT5670_DMIC_2L_LH_MASK | RT5670_DMIC_2R_LH_MASK,
+ RT5670_DMIC_2L_LH_FALLING | RT5670_DMIC_2R_LH_RISING);
+ }
+
+ rt5670_reg_init(codec);
+#ifdef JD1_FUNC
+ snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
+ RT5670_PWR_MB | RT5670_PWR_BG,
+ RT5670_PWR_MB | RT5670_PWR_BG);
+ snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
+ RT5670_PWR_JD1,
+ RT5670_PWR_JD1);
+#endif
+
+ snd_soc_update_bits(codec, RT5670_PWR_ANLG1, RT5670_LDO_SEL_MASK, 0x0);
+ snd_soc_update_bits(codec, RT5670_GPIO_CTRL1,
+ RT5670_I2S2_PIN_MASK, RT5670_I2S2_PIN_GPIO);
+
+ rt5670->codec = codec;
+ rt5670->combo_jack_en = true; /* enable combo jack */
+
+ snd_soc_add_codec_controls(codec, rt5670_snd_controls,
+ ARRAY_SIZE(rt5670_snd_controls));
+ snd_soc_dapm_new_controls(&codec->dapm, rt5670_dapm_widgets,
+ ARRAY_SIZE(rt5670_dapm_widgets));
+ snd_soc_dapm_add_routes(&codec->dapm, rt5670_dapm_routes,
+ ARRAY_SIZE(rt5670_dapm_routes));
+
+ rt5670->dsp_sw = RT5670_DSP_NS;
+ rt5670_dsp_probe(codec);
+
+#ifdef RTK_IOCTL
+#if defined(CONFIG_SND_HWDEP) || defined(CONFIG_SND_HWDEP_MODULE)
+ ioctl_ops->index_write = rt5670_index_write;
+ ioctl_ops->index_read = rt5670_index_read;
+ ioctl_ops->index_update_bits = rt5670_index_update_bits;
+ ioctl_ops->ioctl_common = rt5670_ioctl_common;
+ realtek_ce_init_hwdep(codec);
+#endif
+#endif
+
+ ret = device_create_file(codec->dev, &dev_attr_index_reg);
+ if (ret != 0) {
+ dev_err(codec->dev,
+ "Failed to create index_reg sysfs files: %d\n", ret);
+ return ret;
+ }
+
+ ret = device_create_file(codec->dev, &dev_attr_codec_reg);
+ if (ret != 0) {
+ dev_err(codec->dev,
+ "Failed to create codex_reg sysfs files: %d\n", ret);
+ return ret;
+ }
+
+ rt5670_codec = codec;
+ rt5670->jack_type = 0;
+
+ return 0;
+}
+
+static int rt5670_remove(struct snd_soc_codec *codec)
+{
+ rt5670_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int rt5670_suspend(struct snd_soc_codec *codec)
+{
+ struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+
+ rt5670_dsp_suspend(codec);
+ rt5670->jack_type = 0;
+ return 0;
+}
+
+static int rt5670_resume(struct snd_soc_codec *codec)
+{
+ codec->cache_only = false;
+ codec->cache_sync = 1;
+ snd_soc_cache_sync(codec);
+ rt5670_index_sync(codec);
+ rt5670_dsp_resume(codec);
+ return 0;
+}
+#else
+#define rt5670_suspend NULL
+#define rt5670_resume NULL
+#endif
+
+static void rt5670_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+{
+ printk("enter %s\n",__func__);
+}
+
+#define RT5670_STEREO_RATES SNDRV_PCM_RATE_8000_96000
+#define RT5670_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
+
+struct snd_soc_dai_ops rt5670_aif_dai_ops = {
+ .hw_params = rt5670_hw_params,
+ .hw_free = rt5670_hw_free,
+ .prepare = rt5670_prepare,
+ .set_fmt = rt5670_set_dai_fmt,
+ .set_sysclk = rt5670_set_dai_sysclk,
+ .set_tdm_slot = rt5670_set_tdm_slot,
+ .set_pll = rt5670_set_dai_pll,
+ .shutdown = rt5670_shutdown,
+};
+
+struct snd_soc_dai_driver rt5670_dai[] = {
+ {
+ .name = "rt5670-aif1",
+ .id = RT5670_AIF1,
+ .playback = {
+ .stream_name = "AIF1 Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = RT5670_STEREO_RATES,
+ .formats = RT5670_FORMATS,
+ },
+ .capture = {
+ .stream_name = "AIF1 Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = RT5670_STEREO_RATES,
+ .formats = RT5670_FORMATS,
+ },
+ .ops = &rt5670_aif_dai_ops,
+ },
+ {
+ .name = "rt5670-aif2",
+ .id = RT5670_AIF2,
+ .playback = {
+ .stream_name = "AIF2 Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = RT5670_STEREO_RATES,
+ .formats = RT5670_FORMATS,
+ },
+ .capture = {
+ .stream_name = "AIF2 Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = RT5670_STEREO_RATES,
+ .formats = RT5670_FORMATS,
+ },
+ .ops = &rt5670_aif_dai_ops,
+ },
+};
+
+static struct snd_soc_codec_driver soc_codec_dev_rt5670 = {
+ .probe = rt5670_probe,
+ .remove = rt5670_remove,
+ .suspend = rt5670_suspend,
+ .resume = rt5670_resume,
+ .set_bias_level = rt5670_set_bias_level,
+ .reg_cache_size = RT5670_VENDOR_ID2 + 1,
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = rt5670_reg,
+ .volatile_register = rt5670_volatile_register,
+ .readable_register = rt5670_readable_register,
+ .reg_cache_step = 1,
+};
+
+static const struct i2c_device_id rt5670_i2c_id[] = {
+ { "rt5670", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, rt5670_i2c_id);
+
+static int rt5670_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct rt5670_priv *rt5670;
+ int ret;
+
+ printk("dbg: %s line %d\n",__func__,__LINE__);
+ rt5670 = kzalloc(sizeof(struct rt5670_priv), GFP_KERNEL);
+ if (NULL == rt5670)
+ return -ENOMEM;
+
+ i2c_set_clientdata(i2c, rt5670);
+
+ ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5670,
+ rt5670_dai, ARRAY_SIZE(rt5670_dai));
+ if (ret < 0)
+ kfree(rt5670);
+
+ return ret;
+}
+
+static int rt5670_i2c_remove(struct i2c_client *i2c)
+{
+ snd_soc_unregister_codec(&i2c->dev);
+ kfree(i2c_get_clientdata(i2c));
+ return 0;
+}
+
+void rt5670_i2c_shutdown(struct i2c_client *client)
+{
+ struct rt5670_priv *rt5670 = i2c_get_clientdata(client);
+ struct snd_soc_codec *codec = rt5670->codec;
+
+ printk("enter %s\n",__func__);
+ if (codec != NULL)
+ rt5670_set_bias_level(codec, SND_SOC_BIAS_OFF);
+}
+
+static struct of_device_id rt5670_of_match[] = {
+ { .compatible = "ambarella,rt5670",},
+ {},
+};
+MODULE_DEVICE_TABLE(of, rt5670_of_match);
+
+struct i2c_driver rt5670_i2c_driver = {
+ .driver = {
+ .name = "rt5670",
+ .owner = THIS_MODULE,
+ .of_match_table = rt5670_of_match,
+ },
+ .probe = rt5670_i2c_probe,
+ .remove = rt5670_i2c_remove,
+ .shutdown = rt5670_i2c_shutdown,
+ .id_table = rt5670_i2c_id,
+};
+
+static int __init rt5670_modinit(void)
+{
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ return i2c_add_driver(&rt5670_i2c_driver);
+#endif
+}
+module_init(rt5670_modinit);
+
+static void __exit rt5670_modexit(void)
+{
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ i2c_del_driver(&rt5670_i2c_driver);
+#endif
+}
+module_exit(rt5670_modexit);
+
+MODULE_DESCRIPTION("ASoC RT5670 driver");
+MODULE_AUTHOR("Bard Liao <bardliao@realtek.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/rt5670.h b/sound/soc/codecs/rt5670.h
new file mode 100644
index 00000000..4bfb55ca
--- /dev/null
+++ b/sound/soc/codecs/rt5670.h
@@ -0,0 +1,2001 @@
+/*
+ * rt5670.h -- RT5670 ALSA SoC audio driver
+ *
+ * Copyright 2011 Realtek Microelectronics
+ * Author: Johnny Hsu <johnnyhsu@realtek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __RT5670_H__
+#define __RT5670_H__
+
+/* Info */
+#define RT5670_RESET 0x00
+#define RT5670_VENDOR_ID 0xfd
+#define RT5670_VENDOR_ID1 0xfe
+#define RT5670_VENDOR_ID2 0xff
+/* I/O - Output */
+#define RT5670_HP_VOL 0x02
+#define RT5670_LOUT1 0x03
+/* I/O - Input */
+#define RT5670_CJ_CTRL1 0x0a
+#define RT5670_CJ_CTRL2 0x0b
+#define RT5670_CJ_CTRL3 0x0c
+#define RT5670_IN1_IN2 0x0d
+#define RT5670_IN3 0x0e
+#define RT5670_INL1_INR1_VOL 0x0f
+/* I/O - ADC/DAC/DMIC */
+#define RT5670_DAC1_DIG_VOL 0x19
+#define RT5670_DAC2_DIG_VOL 0x1a
+#define RT5670_DAC_CTRL 0x1b
+#define RT5670_STO1_ADC_DIG_VOL 0x1c
+#define RT5670_MONO_ADC_DIG_VOL 0x1d
+#define RT5670_ADC_BST_VOL1 0x1e
+#define RT5670_STO2_ADC_DIG_VOL 0x1f
+/* Mixer - D-D */
+#define RT5670_ADC_BST_VOL2 0x20
+#define RT5670_STO2_ADC_MIXER 0x26
+#define RT5670_STO1_ADC_MIXER 0x27
+#define RT5670_MONO_ADC_MIXER 0x28
+#define RT5670_AD_DA_MIXER 0x29
+#define RT5670_STO_DAC_MIXER 0x2a
+#define RT5670_DD_MIXER 0x2b
+#define RT5670_DIG_MIXER 0x2c
+#define RT5670_DSP_PATH1 0x2d
+#define RT5670_DSP_PATH2 0x2e
+#define RT5670_DIG_INF1_DATA 0x2f
+#define RT5670_DIG_INF2_DATA 0x30
+/* Mixer - PDM */
+#define RT5670_PDM_OUT_CTRL 0x31
+#define RT5670_PDM_DATA_CTRL1 0x32
+#define RT5670_PDM1_DATA_CTRL2 0x33
+#define RT5670_PDM1_DATA_CTRL3 0x34
+#define RT5670_PDM1_DATA_CTRL4 0x35
+#define RT5670_PDM2_DATA_CTRL2 0x36
+#define RT5670_PDM2_DATA_CTRL3 0x37
+#define RT5670_PDM2_DATA_CTRL4 0x38
+/* Mixer - ADC */
+#define RT5670_REC_L1_MIXER 0x3b
+#define RT5670_REC_L2_MIXER 0x3c
+#define RT5670_REC_R1_MIXER 0x3d
+#define RT5670_REC_R2_MIXER 0x3e
+/* Mixer - DAC */
+#define RT5670_HPO_MIXER 0x45
+#define RT5670_MONO_MIXER 0x4c
+#define RT5670_OUT_L1_MIXER 0x4f
+#define RT5670_OUT_R1_MIXER 0x52
+#define RT5670_LOUT_MIXER 0x53
+/* Power */
+#define RT5670_PWR_DIG1 0x61
+#define RT5670_PWR_DIG2 0x62
+#define RT5670_PWR_ANLG1 0x63
+#define RT5670_PWR_ANLG2 0x64
+#define RT5670_PWR_MIXER 0x65
+#define RT5670_PWR_VOL 0x66
+/* Private Register Control */
+#define RT5670_PRIV_INDEX 0x6a
+#define RT5670_PRIV_DATA 0x6c
+/* Format - ADC/DAC */
+#define RT5670_I2S4_SDP 0x6f
+#define RT5670_I2S1_SDP 0x70
+#define RT5670_I2S2_SDP 0x71
+#define RT5670_I2S3_SDP 0x72
+#define RT5670_ADDA_CLK1 0x73
+#define RT5670_ADDA_CLK2 0x74
+#define RT5670_DMIC_CTRL1 0x75
+#define RT5670_DMIC_CTRL2 0x76
+/* Format - TDM Control */
+#define RT5670_TDM_CTRL_1 0x77
+#define RT5670_TDM_CTRL_2 0x78
+#define RT5670_TDM_CTRL_3 0x79
+
+/* Function - Analog */
+#define RT5670_DSP_CLK 0x7f
+#define RT5670_GLB_CLK 0x80
+#define RT5670_PLL_CTRL1 0x81
+#define RT5670_PLL_CTRL2 0x82
+#define RT5670_ASRC_1 0x83
+#define RT5670_ASRC_2 0x84
+#define RT5670_ASRC_3 0x85
+#define RT5670_ASRC_4 0x86
+#define RT5670_ASRC_5 0x87
+#define RT5670_ASRC_7 0x89
+#define RT5670_ASRC_8 0x8a
+#define RT5670_ASRC_9 0x8b
+#define RT5670_ASRC_10 0x8c
+#define RT5670_ASRC_11 0x8d
+#define RT5670_DEPOP_M1 0x8e
+#define RT5670_DEPOP_M2 0x8f
+#define RT5670_DEPOP_M3 0x90
+#define RT5670_CHARGE_PUMP 0x91
+#define RT5670_MICBIAS 0x93
+#define RT5670_A_JD_CTRL1 0x94
+#define RT5670_A_JD_CTRL2 0x95
+#define RT5670_ASRC_12 0x97
+#define RT5670_ASRC_13 0x98
+#define RT5670_ASRC_14 0x99
+#define RT5670_VAD_CTRL1 0x9a
+#define RT5670_VAD_CTRL2 0x9b
+#define RT5670_VAD_CTRL3 0x9c
+#define RT5670_VAD_CTRL4 0x9d
+#define RT5670_VAD_CTRL5 0x9e
+/* Function - Digital */
+#define RT5670_ADC_EQ_CTRL1 0xae
+#define RT5670_ADC_EQ_CTRL2 0xaf
+#define RT5670_EQ_CTRL1 0xb0
+#define RT5670_EQ_CTRL2 0xb1
+#define RT5670_ALC_DRC_CTRL1 0xb2
+#define RT5670_ALC_DRC_CTRL2 0xb3
+#define RT5670_ALC_CTRL_1 0xb4
+#define RT5670_ALC_CTRL_2 0xb5
+#define RT5670_ALC_CTRL_3 0xb6
+#define RT5670_ALC_CTRL_4 0xb7
+#define RT5670_JD_CTRL 0xbb
+#define RT5670_IRQ_CTRL1 0xbc
+#define RT5670_IRQ_CTRL2 0xbd
+#define RT5670_IRQ_CTRL3 0xbe
+#define RT5670_INT_IRQ_ST 0xbf
+#define RT5670_GPIO_CTRL1 0xc0
+#define RT5670_GPIO_CTRL2 0xc1
+#define RT5670_GPIO_CTRL3 0xc2
+#define RT5670_SCRABBLE_FUN 0xcd
+#define RT5670_SCRABBLE_CTRL 0xce
+#define RT5670_BASE_BACK 0xcf
+#define RT5670_MP3_PLUS1 0xd0
+#define RT5670_MP3_PLUS2 0xd1
+#define RT5670_ADJ_HPF1 0xd3
+#define RT5670_ADJ_HPF2 0xd4
+#define RT5670_HP_CALIB_AMP_DET 0xd6
+#define RT5670_SV_ZCD1 0xd9
+#define RT5670_SV_ZCD2 0xda
+#define RT5670_IL_CMD 0xdb
+#define RT5670_IL_CMD2 0xdc
+#define RT5670_IL_CMD3 0xdd
+#define RT5670_DRC_HL_CTRL1 0xe6
+#define RT5670_DRC_HL_CTRL2 0xe7
+#define RT5670_ADC_MONO_HP_CTRL1 0xec
+#define RT5670_ADC_MONO_HP_CTRL2 0xed
+#define RT5670_ADC_STO2_HP_CTRL1 0xee
+#define RT5670_ADC_STO2_HP_CTRL2 0xef
+#define RT5670_JD_CTRL3 0xf8
+#define RT5670_JD_CTRL4 0xf9
+/* General Control */
+#define RT5670_DIG_MISC 0xfa
+#define RT5670_GEN_CTRL2 0xfb
+#define RT5670_GEN_CTRL3 0xfc
+
+
+/* Index of Codec Private Register definition */
+#define RT5670_DIG_VOL 0x00
+#define RT5670_PR_ALC_CTRL_1 0x01
+#define RT5670_PR_ALC_CTRL_2 0x02
+#define RT5670_PR_ALC_CTRL_3 0x03
+#define RT5670_PR_ALC_CTRL_4 0x04
+#define RT5670_PR_ALC_CTRL_5 0x05
+#define RT5670_PR_ALC_CTRL_6 0x06
+#define RT5670_BIAS_CUR1 0x12
+#define RT5670_BIAS_CUR3 0x14
+#define RT5670_CLSD_INT_REG1 0x1c
+#define RT5670_MAMP_INT_REG2 0x37
+#define RT5670_CHOP_DAC_ADC 0x3d
+#define RT5670_MIXER_INT_REG 0x3f
+#define RT5670_3D_SPK 0x63
+#define RT5670_WND_1 0x6c
+#define RT5670_WND_2 0x6d
+#define RT5670_WND_3 0x6e
+#define RT5670_WND_4 0x6f
+#define RT5670_WND_5 0x70
+#define RT5670_WND_8 0x73
+#define RT5670_DIP_SPK_INF 0x75
+#define RT5670_HP_DCC_INT1 0x77
+#define RT5670_EQ_BW_LOP 0xa0
+#define RT5670_EQ_GN_LOP 0xa1
+#define RT5670_EQ_FC_BP1 0xa2
+#define RT5670_EQ_BW_BP1 0xa3
+#define RT5670_EQ_GN_BP1 0xa4
+#define RT5670_EQ_FC_BP2 0xa5
+#define RT5670_EQ_BW_BP2 0xa6
+#define RT5670_EQ_GN_BP2 0xa7
+#define RT5670_EQ_FC_BP3 0xa8
+#define RT5670_EQ_BW_BP3 0xa9
+#define RT5670_EQ_GN_BP3 0xaa
+#define RT5670_EQ_FC_BP4 0xab
+#define RT5670_EQ_BW_BP4 0xac
+#define RT5670_EQ_GN_BP4 0xad
+#define RT5670_EQ_FC_HIP1 0xae
+#define RT5670_EQ_GN_HIP1 0xaf
+#define RT5670_EQ_FC_HIP2 0xb0
+#define RT5670_EQ_BW_HIP2 0xb1
+#define RT5670_EQ_GN_HIP2 0xb2
+#define RT5670_EQ_PRE_VOL 0xb3
+#define RT5670_EQ_PST_VOL 0xb4
+
+
+/* global definition */
+#define RT5670_L_MUTE (0x1 << 15)
+#define RT5670_L_MUTE_SFT 15
+#define RT5670_VOL_L_MUTE (0x1 << 14)
+#define RT5670_VOL_L_SFT 14
+#define RT5670_R_MUTE (0x1 << 7)
+#define RT5670_R_MUTE_SFT 7
+#define RT5670_VOL_R_MUTE (0x1 << 6)
+#define RT5670_VOL_R_SFT 6
+#define RT5670_L_VOL_MASK (0x3f << 8)
+#define RT5670_L_VOL_SFT 8
+#define RT5670_R_VOL_MASK (0x3f)
+#define RT5670_R_VOL_SFT 0
+
+/* Combo Jack Control 1 (0x0a) */
+#define RT5670_CBJ_BST1_MASK (0xf << 12)
+#define RT5670_CBJ_BST1_SFT (12)
+#define RT5670_CBJ_JD_HP_EN (0x1 << 9)
+#define RT5670_CBJ_JD_MIC_EN (0x1 << 8)
+#define RT5670_CBJ_BST1_EN (0x1 << 2)
+
+/* Combo Jack Control 1 (0x0b) */
+#define RT5670_CBJ_MN_JD (0x1 << 12)
+#define RT5670_CAPLESS_EN (0x1 << 11)
+#define RT5670_CBJ_DET_MODE (0x1 << 7)
+
+/* IN1 and IN2 Control (0x0d) */
+/* IN3 and IN4 Control (0x0e) */
+#define RT5670_BST_MASK1 (0xf<<12)
+#define RT5670_BST_SFT1 12
+#define RT5670_BST_MASK2 (0xf<<8)
+#define RT5670_BST_SFT2 8
+#define RT5670_IN_DF1 (0x1 << 7)
+#define RT5670_IN_SFT1 7
+#define RT5670_IN_DF2 (0x1 << 6)
+#define RT5670_IN_SFT2 6
+
+/* INL and INR Volume Control (0x0f) */
+#define RT5670_INL_SEL_MASK (0x1 << 15)
+#define RT5670_INL_SEL_SFT 15
+#define RT5670_INL_SEL_IN4P (0x0 << 15)
+#define RT5670_INL_SEL_MONOP (0x1 << 15)
+#define RT5670_INL_VOL_MASK (0x1f << 8)
+#define RT5670_INL_VOL_SFT 8
+#define RT5670_INR_SEL_MASK (0x1 << 7)
+#define RT5670_INR_SEL_SFT 7
+#define RT5670_INR_SEL_IN4N (0x0 << 7)
+#define RT5670_INR_SEL_MONON (0x1 << 7)
+#define RT5670_INR_VOL_MASK (0x1f)
+#define RT5670_INR_VOL_SFT 0
+
+/* Sidetone Control (0x18) */
+#define RT5670_ST_SEL_MASK (0x7 << 9)
+#define RT5670_ST_SEL_SFT 9
+#define RT5670_M_ST_DACR2 (0x1 << 8)
+#define RT5670_M_ST_DACR2_SFT 8
+#define RT5670_M_ST_DACL2 (0x1 << 7)
+#define RT5670_M_ST_DACL2_SFT 7
+#define RT5670_ST_EN (0x1 << 6)
+#define RT5670_ST_EN_SFT 6
+
+/* DAC1 Digital Volume (0x19) */
+#define RT5670_DAC_L1_VOL_MASK (0xff << 8)
+#define RT5670_DAC_L1_VOL_SFT 8
+#define RT5670_DAC_R1_VOL_MASK (0xff)
+#define RT5670_DAC_R1_VOL_SFT 0
+
+/* DAC2 Digital Volume (0x1a) */
+#define RT5670_DAC_L2_VOL_MASK (0xff << 8)
+#define RT5670_DAC_L2_VOL_SFT 8
+#define RT5670_DAC_R2_VOL_MASK (0xff)
+#define RT5670_DAC_R2_VOL_SFT 0
+
+/* DAC2 Control (0x1b) */
+#define RT5670_M_DAC_L2_VOL (0x1 << 13)
+#define RT5670_M_DAC_L2_VOL_SFT 13
+#define RT5670_M_DAC_R2_VOL (0x1 << 12)
+#define RT5670_M_DAC_R2_VOL_SFT 12
+#define RT5670_DAC2_L_SEL_MASK (0x7 << 4)
+#define RT5670_DAC2_L_SEL_SFT 4
+#define RT5670_DAC2_R_SEL_MASK (0x7 << 0)
+#define RT5670_DAC2_R_SEL_SFT 0
+
+/* ADC Digital Volume Control (0x1c) */
+#define RT5670_ADC_L_VOL_MASK (0x7f << 8)
+#define RT5670_ADC_L_VOL_SFT 8
+#define RT5670_ADC_R_VOL_MASK (0x7f)
+#define RT5670_ADC_R_VOL_SFT 0
+
+/* Mono ADC Digital Volume Control (0x1d) */
+#define RT5670_MONO_ADC_L_VOL_MASK (0x7f << 8)
+#define RT5670_MONO_ADC_L_VOL_SFT 8
+#define RT5670_MONO_ADC_R_VOL_MASK (0x7f)
+#define RT5670_MONO_ADC_R_VOL_SFT 0
+
+/* ADC Boost Volume Control (0x1e) */
+#define RT5670_STO1_ADC_L_BST_MASK (0x3 << 14)
+#define RT5670_STO1_ADC_L_BST_SFT 14
+#define RT5670_STO1_ADC_R_BST_MASK (0x3 << 12)
+#define RT5670_STO1_ADC_R_BST_SFT 12
+#define RT5670_STO1_ADC_COMP_MASK (0x3 << 10)
+#define RT5670_STO1_ADC_COMP_SFT 10
+#define RT5670_STO2_ADC_L_BST_MASK (0x3 << 8)
+#define RT5670_STO2_ADC_L_BST_SFT 8
+#define RT5670_STO2_ADC_R_BST_MASK (0x3 << 6)
+#define RT5670_STO2_ADC_R_BST_SFT 6
+#define RT5670_STO2_ADC_COMP_MASK (0x3 << 4)
+#define RT5670_STO2_ADC_COMP_SFT 4
+
+/* Stereo2 ADC Mixer Control (0x26) */
+#define RT5670_STO2_ADC_SRC_MASK (0x1 << 15)
+#define RT5670_STO2_ADC_SRC_SFT 15
+
+/* Stereo ADC Mixer Control (0x26 0x27) */
+#define RT5670_M_ADC_L1 (0x1 << 14)
+#define RT5670_M_ADC_L1_SFT 14
+#define RT5670_M_ADC_L2 (0x1 << 13)
+#define RT5670_M_ADC_L2_SFT 13
+#define RT5670_ADC_1_SRC_MASK (0x1 << 12)
+#define RT5670_ADC_1_SRC_SFT 12
+#define RT5670_ADC_1_SRC_ADC (0x1 << 12)
+#define RT5670_ADC_1_SRC_DACMIX (0x0 << 12)
+#define RT5670_ADC_2_SRC_MASK (0x1 << 11)
+#define RT5670_ADC_2_SRC_SFT 11
+#define RT5670_ADC_SRC_MASK (0x1 << 10)
+#define RT5670_ADC_SRC_SFT 10
+#define RT5670_DMIC_SRC_MASK (0x3 << 8)
+#define RT5670_DMIC_SRC_SFT 8
+#define RT5670_M_ADC_R1 (0x1 << 6)
+#define RT5670_M_ADC_R1_SFT 6
+#define RT5670_M_ADC_R2 (0x1 << 5)
+#define RT5670_M_ADC_R2_SFT 5
+#define RT5670_DMIC3_SRC_MASK (0x1 << 1)
+#define RT5670_DMIC3_SRC_SFT 0
+
+/* Mono ADC Mixer Control (0x28) */
+#define RT5670_M_MONO_ADC_L1 (0x1 << 14)
+#define RT5670_M_MONO_ADC_L1_SFT 14
+#define RT5670_M_MONO_ADC_L2 (0x1 << 13)
+#define RT5670_M_MONO_ADC_L2_SFT 13
+#define RT5670_MONO_ADC_L1_SRC_MASK (0x1 << 12)
+#define RT5670_MONO_ADC_L1_SRC_SFT 12
+#define RT5670_MONO_ADC_L1_SRC_DACMIXL (0x0 << 12)
+#define RT5670_MONO_ADC_L1_SRC_ADCL (0x1 << 12)
+#define RT5670_MONO_ADC_L2_SRC_MASK (0x1 << 11)
+#define RT5670_MONO_ADC_L2_SRC_SFT 11
+#define RT5670_MONO_ADC_L_SRC_MASK (0x1 << 10)
+#define RT5670_MONO_ADC_L_SRC_SFT 10
+#define RT5670_MONO_DMIC_L_SRC_MASK (0x3 << 8)
+#define RT5670_MONO_DMIC_L_SRC_SFT 8
+#define RT5670_M_MONO_ADC_R1 (0x1 << 6)
+#define RT5670_M_MONO_ADC_R1_SFT 6
+#define RT5670_M_MONO_ADC_R2 (0x1 << 5)
+#define RT5670_M_MONO_ADC_R2_SFT 5
+#define RT5670_MONO_ADC_R1_SRC_MASK (0x1 << 4)
+#define RT5670_MONO_ADC_R1_SRC_SFT 4
+#define RT5670_MONO_ADC_R1_SRC_ADCR (0x1 << 4)
+#define RT5670_MONO_ADC_R1_SRC_DACMIXR (0x0 << 4)
+#define RT5670_MONO_ADC_R2_SRC_MASK (0x1 << 3)
+#define RT5670_MONO_ADC_R2_SRC_SFT 3
+#define RT5670_MONO_ADC_R_SRC_MASK (0x1 << 2)
+#define RT5670_MONO_ADC_R_SRC_SFT 2
+#define RT5670_MONO_DMIC_R_SRC_MASK (0x3)
+#define RT5670_MONO_DMIC_R_SRC_SFT 0
+
+/* ADC Mixer to DAC Mixer Control (0x29) */
+#define RT5670_M_ADCMIX_L (0x1 << 15)
+#define RT5670_M_ADCMIX_L_SFT 15
+#define RT5670_M_DAC1_L (0x1 << 14)
+#define RT5670_M_DAC1_L_SFT 14
+#define RT5670_DAC1_R_SEL_MASK (0x3 << 10)
+#define RT5670_DAC1_R_SEL_SFT 10
+#define RT5670_DAC1_R_SEL_IF1 (0x0 << 10)
+#define RT5670_DAC1_R_SEL_IF2 (0x1 << 10)
+#define RT5670_DAC1_R_SEL_IF3 (0x2 << 10)
+#define RT5670_DAC1_R_SEL_IF4 (0x3 << 10)
+#define RT5670_DAC1_L_SEL_MASK (0x3 << 8)
+#define RT5670_DAC1_L_SEL_SFT 8
+#define RT5670_DAC1_L_SEL_IF1 (0x0 << 8)
+#define RT5670_DAC1_L_SEL_IF2 (0x1 << 8)
+#define RT5670_DAC1_L_SEL_IF3 (0x2 << 8)
+#define RT5670_DAC1_L_SEL_IF4 (0x3 << 8)
+#define RT5670_M_ADCMIX_R (0x1 << 7)
+#define RT5670_M_ADCMIX_R_SFT 7
+#define RT5670_M_DAC1_R (0x1 << 6)
+#define RT5670_M_DAC1_R_SFT 6
+
+/* Stereo DAC Mixer Control (0x2a) */
+#define RT5670_M_DAC_L1 (0x1 << 14)
+#define RT5670_M_DAC_L1_SFT 14
+#define RT5670_DAC_L1_STO_L_VOL_MASK (0x1 << 13)
+#define RT5670_DAC_L1_STO_L_VOL_SFT 13
+#define RT5670_M_DAC_L2 (0x1 << 12)
+#define RT5670_M_DAC_L2_SFT 12
+#define RT5670_DAC_L2_STO_L_VOL_MASK (0x1 << 11)
+#define RT5670_DAC_L2_STO_L_VOL_SFT 11
+#define RT5670_M_DAC_R1_STO_L (0x1 << 9)
+#define RT5670_M_DAC_R1_STO_L_SFT 9
+#define RT5670_DAC_R1_STO_L_VOL_MASK (0x1 << 8)
+#define RT5670_DAC_R1_STO_L_VOL_SFT 8
+#define RT5670_M_DAC_R1 (0x1 << 6)
+#define RT5670_M_DAC_R1_SFT 6
+#define RT5670_DAC_R1_STO_R_VOL_MASK (0x1 << 5)
+#define RT5670_DAC_R1_STO_R_VOL_SFT 5
+#define RT5670_M_DAC_R2 (0x1 << 4)
+#define RT5670_M_DAC_R2_SFT 4
+#define RT5670_DAC_R2_STO_R_VOL_MASK (0x1 << 3)
+#define RT5670_DAC_R2_STO_R_VOL_SFT 3
+#define RT5670_M_DAC_L1_STO_R (0x1 << 1)
+#define RT5670_M_DAC_L1_STO_R_SFT 1
+#define RT5670_DAC_L1_STO_R_VOL_MASK (0x1)
+#define RT5670_DAC_L1_STO_R_VOL_SFT 0
+
+/* Mono DAC Mixer Control (0x2b) */
+#define RT5670_M_DAC_L1_MONO_L (0x1 << 14)
+#define RT5670_M_DAC_L1_MONO_L_SFT 14
+#define RT5670_DAC_L1_MONO_L_VOL_MASK (0x1 << 13)
+#define RT5670_DAC_L1_MONO_L_VOL_SFT 13
+#define RT5670_M_DAC_L2_MONO_L (0x1 << 12)
+#define RT5670_M_DAC_L2_MONO_L_SFT 12
+#define RT5670_DAC_L2_MONO_L_VOL_MASK (0x1 << 11)
+#define RT5670_DAC_L2_MONO_L_VOL_SFT 11
+#define RT5670_M_DAC_R2_MONO_L (0x1 << 10)
+#define RT5670_M_DAC_R2_MONO_L_SFT 10
+#define RT5670_DAC_R2_MONO_L_VOL_MASK (0x1 << 9)
+#define RT5670_DAC_R2_MONO_L_VOL_SFT 9
+#define RT5670_M_DAC_R1_MONO_R (0x1 << 6)
+#define RT5670_M_DAC_R1_MONO_R_SFT 6
+#define RT5670_DAC_R1_MONO_R_VOL_MASK (0x1 << 5)
+#define RT5670_DAC_R1_MONO_R_VOL_SFT 5
+#define RT5670_M_DAC_R2_MONO_R (0x1 << 4)
+#define RT5670_M_DAC_R2_MONO_R_SFT 4
+#define RT5670_DAC_R2_MONO_R_VOL_MASK (0x1 << 3)
+#define RT5670_DAC_R2_MONO_R_VOL_SFT 3
+#define RT5670_M_DAC_L2_MONO_R (0x1 << 2)
+#define RT5670_M_DAC_L2_MONO_R_SFT 2
+#define RT5670_DAC_L2_MONO_R_VOL_MASK (0x1 << 1)
+#define RT5670_DAC_L2_MONO_R_VOL_SFT 1
+
+/* Digital Mixer Control (0x2c) */
+#define RT5670_M_STO_L_DAC_L (0x1 << 15)
+#define RT5670_M_STO_L_DAC_L_SFT 15
+#define RT5670_STO_L_DAC_L_VOL_MASK (0x1 << 14)
+#define RT5670_STO_L_DAC_L_VOL_SFT 14
+#define RT5670_M_DAC_L2_DAC_L (0x1 << 13)
+#define RT5670_M_DAC_L2_DAC_L_SFT 13
+#define RT5670_DAC_L2_DAC_L_VOL_MASK (0x1 << 12)
+#define RT5670_DAC_L2_DAC_L_VOL_SFT 12
+#define RT5670_M_STO_R_DAC_R (0x1 << 11)
+#define RT5670_M_STO_R_DAC_R_SFT 11
+#define RT5670_STO_R_DAC_R_VOL_MASK (0x1 << 10)
+#define RT5670_STO_R_DAC_R_VOL_SFT 10
+#define RT5670_M_DAC_R2_DAC_R (0x1 << 9)
+#define RT5670_M_DAC_R2_DAC_R_SFT 9
+#define RT5670_DAC_R2_DAC_R_VOL_MASK (0x1 << 8)
+#define RT5670_DAC_R2_DAC_R_VOL_SFT 8
+#define RT5670_M_DAC_R2_DAC_L (0x1 << 7)
+#define RT5670_M_DAC_R2_DAC_L_SFT 7
+#define RT5670_DAC_R2_DAC_L_VOL_MASK (0x1 << 6)
+#define RT5670_DAC_R2_DAC_L_VOL_SFT 6
+#define RT5670_M_DAC_L2_DAC_R (0x1 << 5)
+#define RT5670_M_DAC_L2_DAC_R_SFT 5
+#define RT5670_DAC_L2_DAC_R_VOL_MASK (0x1 << 4)
+#define RT5670_DAC_L2_DAC_R_VOL_SFT 4
+
+/* DSP Path Control 1 (0x2d) */
+#define RT5670_RXDP_SEL_MASK (0x7 << 13)
+#define RT5670_RXDP_SEL_SFT 13
+#define RT5670_RXDP_SRC_MASK (0x1 << 15)
+#define RT5670_RXDP_SRC_SFT 15
+#define RT5670_RXDP_SRC_NOR (0x0 << 15)
+#define RT5670_RXDP_SRC_DIV3 (0x1 << 15)
+#define RT5670_TXDP_SRC_MASK (0x1 << 14)
+#define RT5670_TXDP_SRC_SFT 14
+#define RT5670_TXDP_SRC_NOR (0x0 << 14)
+#define RT5670_TXDP_SRC_DIV3 (0x1 << 14)
+#define RT5670_DSP_UL_SEL (0x1 << 1)
+#define RT5670_DSP_UL_SFT 1
+#define RT5670_DSP_DL_SEL 0x1
+#define RT5670_DSP_DL_SFT 0
+
+/* DSP Path Control 2 (0x2e) */
+#define RT5670_TXDP_L_VOL_MASK (0x7f << 8)
+#define RT5670_TXDP_L_VOL_SFT 8
+#define RT5670_TXDP_R_VOL_MASK (0x7f)
+#define RT5670_TXDP_R_VOL_SFT 0
+
+/* Digital Interface Data Control (0x2f) */
+#define RT5670_IF1_ADC2_IN_SEL (0x1 << 15)
+#define RT5670_IF1_ADC2_IN_SFT 15
+#define RT5670_IF2_ADC_IN_MASK (0x7 << 12)
+#define RT5670_IF2_ADC_IN_SFT 12
+#define RT5670_IF2_DAC_SEL_MASK (0x3 << 10)
+#define RT5670_IF2_DAC_SEL_SFT 10
+#define RT5670_IF2_ADC_SEL_MASK (0x3 << 8)
+#define RT5670_IF2_ADC_SEL_SFT 8
+
+/* Digital Interface Data Control (0x30) */
+#define RT5670_IF4_ADC_IN_MASK (0x3 << 4)
+#define RT5670_IF4_ADC_IN_SFT 4
+
+/* PDM Output Control (0x31) */
+#define RT5670_PDM1_L_MASK (0x1 << 15)
+#define RT5670_PDM1_L_SFT 15
+#define RT5670_M_PDM1_L (0x1 << 14)
+#define RT5670_M_PDM1_L_SFT 14
+#define RT5670_PDM1_R_MASK (0x1 << 13)
+#define RT5670_PDM1_R_SFT 13
+#define RT5670_M_PDM1_R (0x1 << 12)
+#define RT5670_M_PDM1_R_SFT 12
+#define RT5670_PDM2_L_MASK (0x1 << 11)
+#define RT5670_PDM2_L_SFT 11
+#define RT5670_M_PDM2_L (0x1 << 10)
+#define RT5670_M_PDM2_L_SFT 10
+#define RT5670_PDM2_R_MASK (0x1 << 9)
+#define RT5670_PDM2_R_SFT 9
+#define RT5670_M_PDM2_R (0x1 << 8)
+#define RT5670_M_PDM2_R_SFT 8
+#define RT5670_PDM2_BUSY (0x1 << 7)
+#define RT5670_PDM1_BUSY (0x1 << 6)
+#define RT5670_PDM_PATTERN (0x1 << 5)
+#define RT5670_PDM_GAIN (0x1 << 4)
+#define RT5670_PDM_DIV_MASK (0x3)
+
+/* REC Left Mixer Control 1 (0x3b) */
+#define RT5670_G_HP_L_RM_L_MASK (0x7 << 13)
+#define RT5670_G_HP_L_RM_L_SFT 13
+#define RT5670_G_IN_L_RM_L_MASK (0x7 << 10)
+#define RT5670_G_IN_L_RM_L_SFT 10
+#define RT5670_G_BST4_RM_L_MASK (0x7 << 7)
+#define RT5670_G_BST4_RM_L_SFT 7
+#define RT5670_G_BST3_RM_L_MASK (0x7 << 4)
+#define RT5670_G_BST3_RM_L_SFT 4
+#define RT5670_G_BST2_RM_L_MASK (0x7 << 1)
+#define RT5670_G_BST2_RM_L_SFT 1
+
+/* REC Left Mixer Control 2 (0x3c) */
+#define RT5670_G_BST1_RM_L_MASK (0x7 << 13)
+#define RT5670_G_BST1_RM_L_SFT 13
+#define RT5670_M_IN_L_RM_L (0x1 << 5)
+#define RT5670_M_IN_L_RM_L_SFT 5
+#define RT5670_M_BST2_RM_L (0x1 << 3)
+#define RT5670_M_BST2_RM_L_SFT 3
+#define RT5670_M_BST1_RM_L (0x1 << 1)
+#define RT5670_M_BST1_RM_L_SFT 1
+
+/* REC Right Mixer Control 1 (0x3d) */
+#define RT5670_G_HP_R_RM_R_MASK (0x7 << 13)
+#define RT5670_G_HP_R_RM_R_SFT 13
+#define RT5670_G_IN_R_RM_R_MASK (0x7 << 10)
+#define RT5670_G_IN_R_RM_R_SFT 10
+#define RT5670_G_BST4_RM_R_MASK (0x7 << 7)
+#define RT5670_G_BST4_RM_R_SFT 7
+#define RT5670_G_BST3_RM_R_MASK (0x7 << 4)
+#define RT5670_G_BST3_RM_R_SFT 4
+#define RT5670_G_BST2_RM_R_MASK (0x7 << 1)
+#define RT5670_G_BST2_RM_R_SFT 1
+
+/* REC Right Mixer Control 2 (0x3e) */
+#define RT5670_G_BST1_RM_R_MASK (0x7 << 13)
+#define RT5670_G_BST1_RM_R_SFT 13
+#define RT5670_M_IN_R_RM_R (0x1 << 5)
+#define RT5670_M_IN_R_RM_R_SFT 5
+#define RT5670_M_BST2_RM_R (0x1 << 3)
+#define RT5670_M_BST2_RM_R_SFT 3
+#define RT5670_M_BST1_RM_R (0x1 << 1)
+#define RT5670_M_BST1_RM_R_SFT 1
+
+/* HPMIX Control (0x45) */
+#define RT5670_M_DAC2_HM (0x1 << 15)
+#define RT5670_M_DAC2_HM_SFT 15
+#define RT5670_M_HPVOL_HM (0x1 << 14)
+#define RT5670_M_HPVOL_HM_SFT 14
+#define RT5670_M_DAC1_HM (0x1 << 13)
+#define RT5670_M_DAC1_HM_SFT 13
+#define RT5670_G_HPOMIX_MASK (0x1 << 12)
+#define RT5670_G_HPOMIX_SFT 12
+#define RT5670_M_INR1_HMR (0x1 << 3)
+#define RT5670_M_INR1_HMR_SFT 3
+#define RT5670_M_DACR1_HMR (0x1 << 2)
+#define RT5670_M_DACR1_HMR_SFT 2
+#define RT5670_M_INL1_HML (0x1 << 1)
+#define RT5670_M_INL1_HML_SFT 1
+#define RT5670_M_DACL1_HML (0x1)
+#define RT5670_M_DACL1_HML_SFT 0
+
+/* Mono Output Mixer Control (0x4c) */
+#define RT5670_M_DAC_R2_MA (0x1 << 15)
+#define RT5670_M_DAC_R2_MA_SFT 15
+#define RT5670_M_DAC_L2_MA (0x1 << 14)
+#define RT5670_M_DAC_L2_MA_SFT 14
+#define RT5670_M_OV_R_MM (0x1 << 13)
+#define RT5670_M_OV_R_MM_SFT 13
+#define RT5670_M_OV_L_MM (0x1 << 12)
+#define RT5670_M_OV_L_MM_SFT 12
+#define RT5670_G_MONOMIX_MASK (0x1 << 10)
+#define RT5670_G_MONOMIX_SFT 10
+#define RT5670_M_DAC_R2_MM (0x1 << 9)
+#define RT5670_M_DAC_R2_MM_SFT 9
+#define RT5670_M_DAC_L2_MM (0x1 << 8)
+#define RT5670_M_DAC_L2_MM_SFT 8
+#define RT5670_M_BST4_MM (0x1 << 7)
+#define RT5670_M_BST4_MM_SFT 7
+
+/* Output Left Mixer Control 1 (0x4d) */
+#define RT5670_G_BST3_OM_L_MASK (0x7 << 13)
+#define RT5670_G_BST3_OM_L_SFT 13
+#define RT5670_G_BST2_OM_L_MASK (0x7 << 10)
+#define RT5670_G_BST2_OM_L_SFT 10
+#define RT5670_G_BST1_OM_L_MASK (0x7 << 7)
+#define RT5670_G_BST1_OM_L_SFT 7
+#define RT5670_G_IN_L_OM_L_MASK (0x7 << 4)
+#define RT5670_G_IN_L_OM_L_SFT 4
+#define RT5670_G_RM_L_OM_L_MASK (0x7 << 1)
+#define RT5670_G_RM_L_OM_L_SFT 1
+
+/* Output Left Mixer Control 2 (0x4e) */
+#define RT5670_G_DAC_R2_OM_L_MASK (0x7 << 13)
+#define RT5670_G_DAC_R2_OM_L_SFT 13
+#define RT5670_G_DAC_L2_OM_L_MASK (0x7 << 10)
+#define RT5670_G_DAC_L2_OM_L_SFT 10
+#define RT5670_G_DAC_L1_OM_L_MASK (0x7 << 7)
+#define RT5670_G_DAC_L1_OM_L_SFT 7
+
+/* Output Left Mixer Control 3 (0x4f) */
+#define RT5670_M_BST1_OM_L (0x1 << 5)
+#define RT5670_M_BST1_OM_L_SFT 5
+#define RT5670_M_IN_L_OM_L (0x1 << 4)
+#define RT5670_M_IN_L_OM_L_SFT 4
+#define RT5670_M_DAC_L2_OM_L (0x1 << 1)
+#define RT5670_M_DAC_L2_OM_L_SFT 1
+#define RT5670_M_DAC_L1_OM_L (0x1)
+#define RT5670_M_DAC_L1_OM_L_SFT 0
+
+/* Output Right Mixer Control 1 (0x50) */
+#define RT5670_G_BST4_OM_R_MASK (0x7 << 13)
+#define RT5670_G_BST4_OM_R_SFT 13
+#define RT5670_G_BST2_OM_R_MASK (0x7 << 10)
+#define RT5670_G_BST2_OM_R_SFT 10
+#define RT5670_G_BST1_OM_R_MASK (0x7 << 7)
+#define RT5670_G_BST1_OM_R_SFT 7
+#define RT5670_G_IN_R_OM_R_MASK (0x7 << 4)
+#define RT5670_G_IN_R_OM_R_SFT 4
+#define RT5670_G_RM_R_OM_R_MASK (0x7 << 1)
+#define RT5670_G_RM_R_OM_R_SFT 1
+
+/* Output Right Mixer Control 2 (0x51) */
+#define RT5670_G_DAC_L2_OM_R_MASK (0x7 << 13)
+#define RT5670_G_DAC_L2_OM_R_SFT 13
+#define RT5670_G_DAC_R2_OM_R_MASK (0x7 << 10)
+#define RT5670_G_DAC_R2_OM_R_SFT 10
+#define RT5670_G_DAC_R1_OM_R_MASK (0x7 << 7)
+#define RT5670_G_DAC_R1_OM_R_SFT 7
+
+/* Output Right Mixer Control 3 (0x52) */
+#define RT5670_M_BST2_OM_R (0x1 << 6)
+#define RT5670_M_BST2_OM_R_SFT 6
+#define RT5670_M_IN_R_OM_R (0x1 << 4)
+#define RT5670_M_IN_R_OM_R_SFT 4
+#define RT5670_M_DAC_R2_OM_R (0x1 << 1)
+#define RT5670_M_DAC_R2_OM_R_SFT 1
+#define RT5670_M_DAC_R1_OM_R (0x1)
+#define RT5670_M_DAC_R1_OM_R_SFT 0
+
+/* LOUT Mixer Control (0x53) */
+#define RT5670_M_DAC_L1_LM (0x1 << 15)
+#define RT5670_M_DAC_L1_LM_SFT 15
+#define RT5670_M_DAC_R1_LM (0x1 << 14)
+#define RT5670_M_DAC_R1_LM_SFT 14
+#define RT5670_M_OV_L_LM (0x1 << 13)
+#define RT5670_M_OV_L_LM_SFT 13
+#define RT5670_M_OV_R_LM (0x1 << 12)
+#define RT5670_M_OV_R_LM_SFT 12
+#define RT5670_G_LOUTMIX_MASK (0x1 << 11)
+#define RT5670_G_LOUTMIX_SFT 11
+
+/* Power Management for Digital 1 (0x61) */
+#define RT5670_PWR_I2S1 (0x1 << 15)
+#define RT5670_PWR_I2S1_BIT 15
+#define RT5670_PWR_I2S2 (0x1 << 14)
+#define RT5670_PWR_I2S2_BIT 14
+#define RT5670_PWR_DAC_L1 (0x1 << 12)
+#define RT5670_PWR_DAC_L1_BIT 12
+#define RT5670_PWR_DAC_R1 (0x1 << 11)
+#define RT5670_PWR_DAC_R1_BIT 11
+#define RT5670_PWR_DAC_L2 (0x1 << 7)
+#define RT5670_PWR_DAC_L2_BIT 7
+#define RT5670_PWR_DAC_R2 (0x1 << 6)
+#define RT5670_PWR_DAC_R2_BIT 6
+#define RT5670_PWR_ADC_L (0x1 << 2)
+#define RT5670_PWR_ADC_L_BIT 2
+#define RT5670_PWR_ADC_R (0x1 << 1)
+#define RT5670_PWR_ADC_R_BIT 1
+#define RT5670_PWR_CLS_D (0x1)
+#define RT5670_PWR_CLS_D_BIT 0
+
+/* Power Management for Digital 2 (0x62) */
+#define RT5670_PWR_ADC_S1F (0x1 << 15)
+#define RT5670_PWR_ADC_S1F_BIT 15
+#define RT5670_PWR_ADC_MF_L (0x1 << 14)
+#define RT5670_PWR_ADC_MF_L_BIT 14
+#define RT5670_PWR_ADC_MF_R (0x1 << 13)
+#define RT5670_PWR_ADC_MF_R_BIT 13
+#define RT5670_PWR_I2S_DSP (0x1 << 12)
+#define RT5670_PWR_I2S_DSP_BIT 12
+#define RT5670_PWR_DAC_S1F (0x1 << 11)
+#define RT5670_PWR_DAC_S1F_BIT 11
+#define RT5670_PWR_DAC_MF_L (0x1 << 10)
+#define RT5670_PWR_DAC_MF_L_BIT 10
+#define RT5670_PWR_DAC_MF_R (0x1 << 9)
+#define RT5670_PWR_DAC_MF_R_BIT 9
+#define RT5670_PWR_ADC_S2F (0x1 << 8)
+#define RT5670_PWR_ADC_S2F_BIT 8
+#define RT5670_PWR_PDM1 (0x1 << 7)
+#define RT5670_PWR_PDM1_BIT 7
+#define RT5670_PWR_PDM2 (0x1 << 6)
+#define RT5670_PWR_PDM2_BIT 6
+
+/* Power Management for Analog 1 (0x63) */
+#define RT5670_PWR_VREF1 (0x1 << 15)
+#define RT5670_PWR_VREF1_BIT 15
+#define RT5670_PWR_FV1 (0x1 << 14)
+#define RT5670_PWR_FV1_BIT 14
+#define RT5670_PWR_MB (0x1 << 13)
+#define RT5670_PWR_MB_BIT 13
+#define RT5670_PWR_LM (0x1 << 12)
+#define RT5670_PWR_LM_BIT 12
+#define RT5670_PWR_BG (0x1 << 11)
+#define RT5670_PWR_BG_BIT 11
+#define RT5670_PWR_HP_L (0x1 << 7)
+#define RT5670_PWR_HP_L_BIT 7
+#define RT5670_PWR_HP_R (0x1 << 6)
+#define RT5670_PWR_HP_R_BIT 6
+#define RT5670_PWR_HA (0x1 << 5)
+#define RT5670_PWR_HA_BIT 5
+#define RT5670_PWR_VREF2 (0x1 << 4)
+#define RT5670_PWR_VREF2_BIT 4
+#define RT5670_PWR_FV2 (0x1 << 3)
+#define RT5670_PWR_FV2_BIT 3
+#define RT5670_LDO_SEL_MASK (0x3)
+#define RT5670_LDO_SEL_SFT 0
+
+/* Power Management for Analog 2 (0x64) */
+#define RT5670_PWR_BST1 (0x1 << 15)
+#define RT5670_PWR_BST1_BIT 15
+#define RT5670_PWR_BST2 (0x1 << 13)
+#define RT5670_PWR_BST2_BIT 13
+#define RT5670_PWR_MB1 (0x1 << 11)
+#define RT5670_PWR_MB1_BIT 11
+#define RT5670_PWR_MB2 (0x1 << 10)
+#define RT5670_PWR_MB2_BIT 10
+#define RT5670_PWR_PLL (0x1 << 9)
+#define RT5670_PWR_PLL_BIT 9
+#define RT5670_PWR_BST1_P (0x1 << 6)
+#define RT5670_PWR_BST1_P_BIT 6
+#define RT5670_PWR_BST2_P (0x1 << 4)
+#define RT5670_PWR_BST2_P_BIT 4
+#define RT5670_PWR_JD1 (0x1 << 2)
+#define RT5670_PWR_JD1_BIT 2
+#define RT5670_PWR_JD (0x1 << 1)
+#define RT5670_PWR_JD_BIT 1
+
+/* Power Management for Mixer (0x65) */
+#define RT5670_PWR_OM_L (0x1 << 15)
+#define RT5670_PWR_OM_L_BIT 15
+#define RT5670_PWR_OM_R (0x1 << 14)
+#define RT5670_PWR_OM_R_BIT 14
+#define RT5670_PWR_RM_L (0x1 << 11)
+#define RT5670_PWR_RM_L_BIT 11
+#define RT5670_PWR_RM_R (0x1 << 10)
+#define RT5670_PWR_RM_R_BIT 10
+
+/* Power Management for Volume (0x66) */
+#define RT5670_PWR_HV_L (0x1 << 11)
+#define RT5670_PWR_HV_L_BIT 11
+#define RT5670_PWR_HV_R (0x1 << 10)
+#define RT5670_PWR_HV_R_BIT 10
+#define RT5670_PWR_IN_L (0x1 << 9)
+#define RT5670_PWR_IN_L_BIT 9
+#define RT5670_PWR_IN_R (0x1 << 8)
+#define RT5670_PWR_IN_R_BIT 8
+#define RT5670_PWR_MIC_DET (0x1 << 5)
+#define RT5670_PWR_MIC_DET_BIT 5
+
+/* I2S1/2/3 Audio Serial Data Port Control (0x70 0x71 0x72) */
+#define RT5670_I2S_MS_MASK (0x1 << 15)
+#define RT5670_I2S_MS_SFT 15
+#define RT5670_I2S_MS_M (0x0 << 15)
+#define RT5670_I2S_MS_S (0x1 << 15)
+#define RT5670_I2S_IF_MASK (0x7 << 12)
+#define RT5670_I2S_IF_SFT 12
+#define RT5670_I2S_O_CP_MASK (0x3 << 10)
+#define RT5670_I2S_O_CP_SFT 10
+#define RT5670_I2S_O_CP_OFF (0x0 << 10)
+#define RT5670_I2S_O_CP_U_LAW (0x1 << 10)
+#define RT5670_I2S_O_CP_A_LAW (0x2 << 10)
+#define RT5670_I2S_I_CP_MASK (0x3 << 8)
+#define RT5670_I2S_I_CP_SFT 8
+#define RT5670_I2S_I_CP_OFF (0x0 << 8)
+#define RT5670_I2S_I_CP_U_LAW (0x1 << 8)
+#define RT5670_I2S_I_CP_A_LAW (0x2 << 8)
+#define RT5670_I2S_BP_MASK (0x1 << 7)
+#define RT5670_I2S_BP_SFT 7
+#define RT5670_I2S_BP_NOR (0x0 << 7)
+#define RT5670_I2S_BP_INV (0x1 << 7)
+#define RT5670_I2S_DL_MASK (0x3 << 2)
+#define RT5670_I2S_DL_SFT 2
+#define RT5670_I2S_DL_16 (0x0 << 2)
+#define RT5670_I2S_DL_20 (0x1 << 2)
+#define RT5670_I2S_DL_24 (0x2 << 2)
+#define RT5670_I2S_DL_8 (0x3 << 2)
+#define RT5670_I2S_DF_MASK (0x3)
+#define RT5670_I2S_DF_SFT 0
+#define RT5670_I2S_DF_I2S (0x0)
+#define RT5670_I2S_DF_LEFT (0x1)
+#define RT5670_I2S_DF_PCM_A (0x2)
+#define RT5670_I2S_DF_PCM_B (0x3)
+
+/* I2S2 Audio Serial Data Port Control (0x71) */
+#define RT5670_I2S2_SDI_MASK (0x1 << 6)
+#define RT5670_I2S2_SDI_SFT 6
+#define RT5670_I2S2_SDI_I2S1 (0x0 << 6)
+#define RT5670_I2S2_SDI_I2S2 (0x1 << 6)
+
+/* ADC/DAC Clock Control 1 (0x73) */
+#define RT5670_I2S_BCLK_MS1_MASK (0x1 << 15)
+#define RT5670_I2S_BCLK_MS1_SFT 15
+#define RT5670_I2S_BCLK_MS1_32 (0x0 << 15)
+#define RT5670_I2S_BCLK_MS1_64 (0x1 << 15)
+#define RT5670_I2S_PD1_MASK (0x7 << 12)
+#define RT5670_I2S_PD1_SFT 12
+#define RT5670_I2S_PD1_1 (0x0 << 12)
+#define RT5670_I2S_PD1_2 (0x1 << 12)
+#define RT5670_I2S_PD1_3 (0x2 << 12)
+#define RT5670_I2S_PD1_4 (0x3 << 12)
+#define RT5670_I2S_PD1_6 (0x4 << 12)
+#define RT5670_I2S_PD1_8 (0x5 << 12)
+#define RT5670_I2S_PD1_12 (0x6 << 12)
+#define RT5670_I2S_PD1_16 (0x7 << 12)
+#define RT5670_I2S_BCLK_MS2_MASK (0x1 << 11)
+#define RT5670_I2S_BCLK_MS2_SFT 11
+#define RT5670_I2S_BCLK_MS2_32 (0x0 << 11)
+#define RT5670_I2S_BCLK_MS2_64 (0x1 << 11)
+#define RT5670_I2S_PD2_MASK (0x7 << 8)
+#define RT5670_I2S_PD2_SFT 8
+#define RT5670_I2S_PD2_1 (0x0 << 8)
+#define RT5670_I2S_PD2_2 (0x1 << 8)
+#define RT5670_I2S_PD2_3 (0x2 << 8)
+#define RT5670_I2S_PD2_4 (0x3 << 8)
+#define RT5670_I2S_PD2_6 (0x4 << 8)
+#define RT5670_I2S_PD2_8 (0x5 << 8)
+#define RT5670_I2S_PD2_12 (0x6 << 8)
+#define RT5670_I2S_PD2_16 (0x7 << 8)
+#define RT5670_I2S_BCLK_MS3_MASK (0x1 << 7)
+#define RT5670_I2S_BCLK_MS3_SFT 7
+#define RT5670_I2S_BCLK_MS3_32 (0x0 << 7)
+#define RT5670_I2S_BCLK_MS3_64 (0x1 << 7)
+#define RT5670_I2S_PD3_MASK (0x7 << 4)
+#define RT5670_I2S_PD3_SFT 4
+#define RT5670_I2S_PD3_1 (0x0 << 4)
+#define RT5670_I2S_PD3_2 (0x1 << 4)
+#define RT5670_I2S_PD3_3 (0x2 << 4)
+#define RT5670_I2S_PD3_4 (0x3 << 4)
+#define RT5670_I2S_PD3_6 (0x4 << 4)
+#define RT5670_I2S_PD3_8 (0x5 << 4)
+#define RT5670_I2S_PD3_12 (0x6 << 4)
+#define RT5670_I2S_PD3_16 (0x7 << 4)
+#define RT5670_DAC_OSR_MASK (0x3 << 2)
+#define RT5670_DAC_OSR_SFT 2
+#define RT5670_DAC_OSR_128 (0x0 << 2)
+#define RT5670_DAC_OSR_64 (0x1 << 2)
+#define RT5670_DAC_OSR_32 (0x2 << 2)
+#define RT5670_DAC_OSR_16 (0x3 << 2)
+#define RT5670_ADC_OSR_MASK (0x3)
+#define RT5670_ADC_OSR_SFT 0
+#define RT5670_ADC_OSR_128 (0x0)
+#define RT5670_ADC_OSR_64 (0x1)
+#define RT5670_ADC_OSR_32 (0x2)
+#define RT5670_ADC_OSR_16 (0x3)
+
+/* ADC/DAC Clock Control 2 (0x74) */
+#define RT5670_DAC_L_OSR_MASK (0x3 << 14)
+#define RT5670_DAC_L_OSR_SFT 14
+#define RT5670_DAC_L_OSR_128 (0x0 << 14)
+#define RT5670_DAC_L_OSR_64 (0x1 << 14)
+#define RT5670_DAC_L_OSR_32 (0x2 << 14)
+#define RT5670_DAC_L_OSR_16 (0x3 << 14)
+#define RT5670_ADC_R_OSR_MASK (0x3 << 12)
+#define RT5670_ADC_R_OSR_SFT 12
+#define RT5670_ADC_R_OSR_128 (0x0 << 12)
+#define RT5670_ADC_R_OSR_64 (0x1 << 12)
+#define RT5670_ADC_R_OSR_32 (0x2 << 12)
+#define RT5670_ADC_R_OSR_16 (0x3 << 12)
+#define RT5670_DAHPF_EN (0x1 << 11)
+#define RT5670_DAHPF_EN_SFT 11
+#define RT5670_ADHPF_EN (0x1 << 10)
+#define RT5670_ADHPF_EN_SFT 10
+
+/* Digital Microphone Control (0x75) */
+#define RT5670_DMIC_1_EN_MASK (0x1 << 15)
+#define RT5670_DMIC_1_EN_SFT 15
+#define RT5670_DMIC_1_DIS (0x0 << 15)
+#define RT5670_DMIC_1_EN (0x1 << 15)
+#define RT5670_DMIC_2_EN_MASK (0x1 << 14)
+#define RT5670_DMIC_2_EN_SFT 14
+#define RT5670_DMIC_2_DIS (0x0 << 14)
+#define RT5670_DMIC_2_EN (0x1 << 14)
+#define RT5670_DMIC_1L_LH_MASK (0x1 << 13)
+#define RT5670_DMIC_1L_LH_SFT 13
+#define RT5670_DMIC_1L_LH_FALLING (0x0 << 13)
+#define RT5670_DMIC_1L_LH_RISING (0x1 << 13)
+#define RT5670_DMIC_1R_LH_MASK (0x1 << 12)
+#define RT5670_DMIC_1R_LH_SFT 12
+#define RT5670_DMIC_1R_LH_FALLING (0x0 << 12)
+#define RT5670_DMIC_1R_LH_RISING (0x1 << 12)
+#define RT5670_DMIC_2_DP_MASK (0x1 << 10)
+#define RT5670_DMIC_2_DP_SFT 10
+#define RT5670_DMIC_2_DP_GPIO4 (0x0 << 10)
+#define RT5670_DMIC_2_DP_IN1N (0x1 << 10)
+#define RT5670_DMIC_2L_LH_MASK (0x1 << 9)
+#define RT5670_DMIC_2L_LH_SFT 9
+#define RT5670_DMIC_2L_LH_FALLING (0x0 << 9)
+#define RT5670_DMIC_2L_LH_RISING (0x1 << 9)
+#define RT5670_DMIC_2R_LH_MASK (0x1 << 8)
+#define RT5670_DMIC_2R_LH_SFT 8
+#define RT5670_DMIC_2R_LH_FALLING (0x0 << 8)
+#define RT5670_DMIC_2R_LH_RISING (0x1 << 8)
+#define RT5670_DMIC_CLK_MASK (0x7 << 5)
+#define RT5670_DMIC_CLK_SFT 5
+#define RT5670_DMIC_3_EN_MASK (0x1 << 4)
+#define RT5670_DMIC_3_EN_SFT 4
+#define RT5670_DMIC_3_DIS (0x0 << 4)
+#define RT5670_DMIC_3_EN (0x1 << 4)
+#define RT5670_DMIC_1_DP_MASK (0x3 << 0)
+#define RT5670_DMIC_1_DP_SFT 0
+#define RT5670_DMIC_1_DP_GPIO6 (0x0 << 0)
+#define RT5670_DMIC_1_DP_IN2P (0x1 << 0)
+#define RT5670_DMIC_1_DP_GPIO7 (0x2 << 0)
+
+/* Global Clock Control (0x80) */
+#define RT5670_SCLK_SRC_MASK (0x3 << 14)
+#define RT5670_SCLK_SRC_SFT 14
+#define RT5670_SCLK_SRC_MCLK (0x0 << 14)
+#define RT5670_SCLK_SRC_PLL1 (0x1 << 14)
+#define RT5670_SCLK_SRC_RCCLK (0x2 << 14) /* 15MHz */
+#define RT5670_PLL1_SRC_MASK (0x3 << 12)
+#define RT5670_PLL1_SRC_SFT 12
+#define RT5670_PLL1_SRC_MCLK (0x0 << 12)
+#define RT5670_PLL1_SRC_BCLK1 (0x1 << 12)
+#define RT5670_PLL1_SRC_BCLK2 (0x2 << 12)
+#define RT5670_PLL1_SRC_BCLK3 (0x3 << 12)
+#define RT5670_PLL1_PD_MASK (0x1 << 3)
+#define RT5670_PLL1_PD_SFT 3
+#define RT5670_PLL1_PD_1 (0x0 << 3)
+#define RT5670_PLL1_PD_2 (0x1 << 3)
+
+#define RT5670_PLL_INP_MAX 40000000
+#define RT5670_PLL_INP_MIN 256000
+/* PLL M/N/K Code Control 1 (0x81) */
+#define RT5670_PLL_N_MAX 0x1ff
+#define RT5670_PLL_N_MASK (RT5670_PLL_N_MAX << 7)
+#define RT5670_PLL_N_SFT 7
+#define RT5670_PLL_K_MAX 0x1f
+#define RT5670_PLL_K_MASK (RT5670_PLL_K_MAX)
+#define RT5670_PLL_K_SFT 0
+
+/* PLL M/N/K Code Control 2 (0x82) */
+#define RT5670_PLL_M_MAX 0xf
+#define RT5670_PLL_M_MASK (RT5670_PLL_M_MAX << 12)
+#define RT5670_PLL_M_SFT 12
+#define RT5670_PLL_M_BP (0x1 << 11)
+#define RT5670_PLL_M_BP_SFT 11
+
+/* ASRC Control 1 (0x83) */
+#define RT5670_STO_T_MASK (0x1 << 15)
+#define RT5670_STO_T_SFT 15
+#define RT5670_STO_T_SCLK (0x0 << 15)
+#define RT5670_STO_T_LRCK1 (0x1 << 15)
+#define RT5670_M1_T_MASK (0x1 << 14)
+#define RT5670_M1_T_SFT 14
+#define RT5670_M1_T_I2S2 (0x0 << 14)
+#define RT5670_M1_T_I2S2_D3 (0x1 << 14)
+#define RT5670_I2S2_F_MASK (0x1 << 12)
+#define RT5670_I2S2_F_SFT 12
+#define RT5670_I2S2_F_I2S2_D2 (0x0 << 12)
+#define RT5670_I2S2_F_I2S1_TCLK (0x1 << 12)
+#define RT5670_DMIC_1_M_MASK (0x1 << 9)
+#define RT5670_DMIC_1_M_SFT 9
+#define RT5670_DMIC_1_M_NOR (0x0 << 9)
+#define RT5670_DMIC_1_M_ASYN (0x1 << 9)
+#define RT5670_DMIC_2_M_MASK (0x1 << 8)
+#define RT5670_DMIC_2_M_SFT 8
+#define RT5670_DMIC_2_M_NOR (0x0 << 8)
+#define RT5670_DMIC_2_M_ASYN (0x1 << 8)
+
+/* ASRC Control 2 (0x84) */
+#define RT5670_MDA_L_M_MASK (0x1 << 15)
+#define RT5670_MDA_L_M_SFT 15
+#define RT5670_MDA_L_M_NOR (0x0 << 15)
+#define RT5670_MDA_L_M_ASYN (0x1 << 15)
+#define RT5670_MDA_R_M_MASK (0x1 << 14)
+#define RT5670_MDA_R_M_SFT 14
+#define RT5670_MDA_R_M_NOR (0x0 << 14)
+#define RT5670_MDA_R_M_ASYN (0x1 << 14)
+#define RT5670_MAD_L_M_MASK (0x1 << 13)
+#define RT5670_MAD_L_M_SFT 13
+#define RT5670_MAD_L_M_NOR (0x0 << 13)
+#define RT5670_MAD_L_M_ASYN (0x1 << 13)
+#define RT5670_MAD_R_M_MASK (0x1 << 12)
+#define RT5670_MAD_R_M_SFT 12
+#define RT5670_MAD_R_M_NOR (0x0 << 12)
+#define RT5670_MAD_R_M_ASYN (0x1 << 12)
+#define RT5670_ADC_M_MASK (0x1 << 11)
+#define RT5670_ADC_M_SFT 11
+#define RT5670_ADC_M_NOR (0x0 << 11)
+#define RT5670_ADC_M_ASYN (0x1 << 11)
+#define RT5670_STO_DAC_M_MASK (0x1 << 5)
+#define RT5670_STO_DAC_M_SFT 5
+#define RT5670_STO_DAC_M_NOR (0x0 << 5)
+#define RT5670_STO_DAC_M_ASYN (0x1 << 5)
+#define RT5670_I2S1_R_D_MASK (0x1 << 4)
+#define RT5670_I2S1_R_D_SFT 4
+#define RT5670_I2S1_R_D_DIS (0x0 << 4)
+#define RT5670_I2S1_R_D_EN (0x1 << 4)
+#define RT5670_I2S2_R_D_MASK (0x1 << 3)
+#define RT5670_I2S2_R_D_SFT 3
+#define RT5670_I2S2_R_D_DIS (0x0 << 3)
+#define RT5670_I2S2_R_D_EN (0x1 << 3)
+#define RT5670_PRE_SCLK_MASK (0x3)
+#define RT5670_PRE_SCLK_SFT 0
+#define RT5670_PRE_SCLK_512 (0x0)
+#define RT5670_PRE_SCLK_1024 (0x1)
+#define RT5670_PRE_SCLK_2048 (0x2)
+
+/* ASRC Control 3 (0x85) */
+#define RT5670_I2S1_RATE_MASK (0xf << 12)
+#define RT5670_I2S1_RATE_SFT 12
+#define RT5670_I2S2_RATE_MASK (0xf << 8)
+#define RT5670_I2S2_RATE_SFT 8
+
+/* ASRC Control 4 (0x89) */
+#define RT5670_I2S1_PD_MASK (0x7 << 12)
+#define RT5670_I2S1_PD_SFT 12
+#define RT5670_I2S2_PD_MASK (0x7 << 8)
+#define RT5670_I2S2_PD_SFT 8
+
+/* HPOUT Over Current Detection (0x8b) */
+#define RT5670_HP_OVCD_MASK (0x1 << 10)
+#define RT5670_HP_OVCD_SFT 10
+#define RT5670_HP_OVCD_DIS (0x0 << 10)
+#define RT5670_HP_OVCD_EN (0x1 << 10)
+#define RT5670_HP_OC_TH_MASK (0x3 << 8)
+#define RT5670_HP_OC_TH_SFT 8
+#define RT5670_HP_OC_TH_90 (0x0 << 8)
+#define RT5670_HP_OC_TH_105 (0x1 << 8)
+#define RT5670_HP_OC_TH_120 (0x2 << 8)
+#define RT5670_HP_OC_TH_135 (0x3 << 8)
+
+/* Class D Over Current Control (0x8c) */
+#define RT5670_CLSD_OC_MASK (0x1 << 9)
+#define RT5670_CLSD_OC_SFT 9
+#define RT5670_CLSD_OC_PU (0x0 << 9)
+#define RT5670_CLSD_OC_PD (0x1 << 9)
+#define RT5670_AUTO_PD_MASK (0x1 << 8)
+#define RT5670_AUTO_PD_SFT 8
+#define RT5670_AUTO_PD_DIS (0x0 << 8)
+#define RT5670_AUTO_PD_EN (0x1 << 8)
+#define RT5670_CLSD_OC_TH_MASK (0x3f)
+#define RT5670_CLSD_OC_TH_SFT 0
+
+/* Class D Output Control (0x8d) */
+#define RT5670_CLSD_RATIO_MASK (0xf << 12)
+#define RT5670_CLSD_RATIO_SFT 12
+#define RT5670_CLSD_OM_MASK (0x1 << 11)
+#define RT5670_CLSD_OM_SFT 11
+#define RT5670_CLSD_OM_MONO (0x0 << 11)
+#define RT5670_CLSD_OM_STO (0x1 << 11)
+#define RT5670_CLSD_SCH_MASK (0x1 << 10)
+#define RT5670_CLSD_SCH_SFT 10
+#define RT5670_CLSD_SCH_L (0x0 << 10)
+#define RT5670_CLSD_SCH_S (0x1 << 10)
+
+/* Depop Mode Control 1 (0x8e) */
+#define RT5670_SMT_TRIG_MASK (0x1 << 15)
+#define RT5670_SMT_TRIG_SFT 15
+#define RT5670_SMT_TRIG_DIS (0x0 << 15)
+#define RT5670_SMT_TRIG_EN (0x1 << 15)
+#define RT5670_HP_L_SMT_MASK (0x1 << 9)
+#define RT5670_HP_L_SMT_SFT 9
+#define RT5670_HP_L_SMT_DIS (0x0 << 9)
+#define RT5670_HP_L_SMT_EN (0x1 << 9)
+#define RT5670_HP_R_SMT_MASK (0x1 << 8)
+#define RT5670_HP_R_SMT_SFT 8
+#define RT5670_HP_R_SMT_DIS (0x0 << 8)
+#define RT5670_HP_R_SMT_EN (0x1 << 8)
+#define RT5670_HP_CD_PD_MASK (0x1 << 7)
+#define RT5670_HP_CD_PD_SFT 7
+#define RT5670_HP_CD_PD_DIS (0x0 << 7)
+#define RT5670_HP_CD_PD_EN (0x1 << 7)
+#define RT5670_RSTN_MASK (0x1 << 6)
+#define RT5670_RSTN_SFT 6
+#define RT5670_RSTN_DIS (0x0 << 6)
+#define RT5670_RSTN_EN (0x1 << 6)
+#define RT5670_RSTP_MASK (0x1 << 5)
+#define RT5670_RSTP_SFT 5
+#define RT5670_RSTP_DIS (0x0 << 5)
+#define RT5670_RSTP_EN (0x1 << 5)
+#define RT5670_HP_CO_MASK (0x1 << 4)
+#define RT5670_HP_CO_SFT 4
+#define RT5670_HP_CO_DIS (0x0 << 4)
+#define RT5670_HP_CO_EN (0x1 << 4)
+#define RT5670_HP_CP_MASK (0x1 << 3)
+#define RT5670_HP_CP_SFT 3
+#define RT5670_HP_CP_PD (0x0 << 3)
+#define RT5670_HP_CP_PU (0x1 << 3)
+#define RT5670_HP_SG_MASK (0x1 << 2)
+#define RT5670_HP_SG_SFT 2
+#define RT5670_HP_SG_DIS (0x0 << 2)
+#define RT5670_HP_SG_EN (0x1 << 2)
+#define RT5670_HP_DP_MASK (0x1 << 1)
+#define RT5670_HP_DP_SFT 1
+#define RT5670_HP_DP_PD (0x0 << 1)
+#define RT5670_HP_DP_PU (0x1 << 1)
+#define RT5670_HP_CB_MASK (0x1)
+#define RT5670_HP_CB_SFT 0
+#define RT5670_HP_CB_PD (0x0)
+#define RT5670_HP_CB_PU (0x1)
+
+/* Depop Mode Control 2 (0x8f) */
+#define RT5670_DEPOP_MASK (0x1 << 13)
+#define RT5670_DEPOP_SFT 13
+#define RT5670_DEPOP_AUTO (0x0 << 13)
+#define RT5670_DEPOP_MAN (0x1 << 13)
+#define RT5670_RAMP_MASK (0x1 << 12)
+#define RT5670_RAMP_SFT 12
+#define RT5670_RAMP_DIS (0x0 << 12)
+#define RT5670_RAMP_EN (0x1 << 12)
+#define RT5670_BPS_MASK (0x1 << 11)
+#define RT5670_BPS_SFT 11
+#define RT5670_BPS_DIS (0x0 << 11)
+#define RT5670_BPS_EN (0x1 << 11)
+#define RT5670_FAST_UPDN_MASK (0x1 << 10)
+#define RT5670_FAST_UPDN_SFT 10
+#define RT5670_FAST_UPDN_DIS (0x0 << 10)
+#define RT5670_FAST_UPDN_EN (0x1 << 10)
+#define RT5670_MRES_MASK (0x3 << 8)
+#define RT5670_MRES_SFT 8
+#define RT5670_MRES_15MO (0x0 << 8)
+#define RT5670_MRES_25MO (0x1 << 8)
+#define RT5670_MRES_35MO (0x2 << 8)
+#define RT5670_MRES_45MO (0x3 << 8)
+#define RT5670_VLO_MASK (0x1 << 7)
+#define RT5670_VLO_SFT 7
+#define RT5670_VLO_3V (0x0 << 7)
+#define RT5670_VLO_32V (0x1 << 7)
+#define RT5670_DIG_DP_MASK (0x1 << 6)
+#define RT5670_DIG_DP_SFT 6
+#define RT5670_DIG_DP_DIS (0x0 << 6)
+#define RT5670_DIG_DP_EN (0x1 << 6)
+#define RT5670_DP_TH_MASK (0x3 << 4)
+#define RT5670_DP_TH_SFT 4
+
+/* Depop Mode Control 3 (0x90) */
+#define RT5670_CP_SYS_MASK (0x7 << 12)
+#define RT5670_CP_SYS_SFT 12
+#define RT5670_CP_FQ1_MASK (0x7 << 8)
+#define RT5670_CP_FQ1_SFT 8
+#define RT5670_CP_FQ2_MASK (0x7 << 4)
+#define RT5670_CP_FQ2_SFT 4
+#define RT5670_CP_FQ3_MASK (0x7)
+#define RT5670_CP_FQ3_SFT 0
+#define RT5670_CP_FQ_1_5_KHZ 0
+#define RT5670_CP_FQ_3_KHZ 1
+#define RT5670_CP_FQ_6_KHZ 2
+#define RT5670_CP_FQ_12_KHZ 3
+#define RT5670_CP_FQ_24_KHZ 4
+#define RT5670_CP_FQ_48_KHZ 5
+#define RT5670_CP_FQ_96_KHZ 6
+#define RT5670_CP_FQ_192_KHZ 7
+
+/* HPOUT charge pump (0x91) */
+#define RT5670_OSW_L_MASK (0x1 << 11)
+#define RT5670_OSW_L_SFT 11
+#define RT5670_OSW_L_DIS (0x0 << 11)
+#define RT5670_OSW_L_EN (0x1 << 11)
+#define RT5670_OSW_R_MASK (0x1 << 10)
+#define RT5670_OSW_R_SFT 10
+#define RT5670_OSW_R_DIS (0x0 << 10)
+#define RT5670_OSW_R_EN (0x1 << 10)
+#define RT5670_PM_HP_MASK (0x3 << 8)
+#define RT5670_PM_HP_SFT 8
+#define RT5670_PM_HP_LV (0x0 << 8)
+#define RT5670_PM_HP_MV (0x1 << 8)
+#define RT5670_PM_HP_HV (0x2 << 8)
+#define RT5670_IB_HP_MASK (0x3 << 6)
+#define RT5670_IB_HP_SFT 6
+#define RT5670_IB_HP_125IL (0x0 << 6)
+#define RT5670_IB_HP_25IL (0x1 << 6)
+#define RT5670_IB_HP_5IL (0x2 << 6)
+#define RT5670_IB_HP_1IL (0x3 << 6)
+
+/* PV detection and SPK gain control (0x92) */
+#define RT5670_PVDD_DET_MASK (0x1 << 15)
+#define RT5670_PVDD_DET_SFT 15
+#define RT5670_PVDD_DET_DIS (0x0 << 15)
+#define RT5670_PVDD_DET_EN (0x1 << 15)
+#define RT5670_SPK_AG_MASK (0x1 << 14)
+#define RT5670_SPK_AG_SFT 14
+#define RT5670_SPK_AG_DIS (0x0 << 14)
+#define RT5670_SPK_AG_EN (0x1 << 14)
+
+/* Micbias Control (0x93) */
+#define RT5670_MIC1_BS_MASK (0x1 << 15)
+#define RT5670_MIC1_BS_SFT 15
+#define RT5670_MIC1_BS_9AV (0x0 << 15)
+#define RT5670_MIC1_BS_75AV (0x1 << 15)
+#define RT5670_MIC2_BS_MASK (0x1 << 14)
+#define RT5670_MIC2_BS_SFT 14
+#define RT5670_MIC2_BS_9AV (0x0 << 14)
+#define RT5670_MIC2_BS_75AV (0x1 << 14)
+#define RT5670_MIC1_CLK_MASK (0x1 << 13)
+#define RT5670_MIC1_CLK_SFT 13
+#define RT5670_MIC1_CLK_DIS (0x0 << 13)
+#define RT5670_MIC1_CLK_EN (0x1 << 13)
+#define RT5670_MIC2_CLK_MASK (0x1 << 12)
+#define RT5670_MIC2_CLK_SFT 12
+#define RT5670_MIC2_CLK_DIS (0x0 << 12)
+#define RT5670_MIC2_CLK_EN (0x1 << 12)
+#define RT5670_MIC1_OVCD_MASK (0x1 << 11)
+#define RT5670_MIC1_OVCD_SFT 11
+#define RT5670_MIC1_OVCD_DIS (0x0 << 11)
+#define RT5670_MIC1_OVCD_EN (0x1 << 11)
+#define RT5670_MIC1_OVTH_MASK (0x3 << 9)
+#define RT5670_MIC1_OVTH_SFT 9
+#define RT5670_MIC1_OVTH_600UA (0x0 << 9)
+#define RT5670_MIC1_OVTH_1500UA (0x1 << 9)
+#define RT5670_MIC1_OVTH_2000UA (0x2 << 9)
+#define RT5670_MIC2_OVCD_MASK (0x1 << 8)
+#define RT5670_MIC2_OVCD_SFT 8
+#define RT5670_MIC2_OVCD_DIS (0x0 << 8)
+#define RT5670_MIC2_OVCD_EN (0x1 << 8)
+#define RT5670_MIC2_OVTH_MASK (0x3 << 6)
+#define RT5670_MIC2_OVTH_SFT 6
+#define RT5670_MIC2_OVTH_600UA (0x0 << 6)
+#define RT5670_MIC2_OVTH_1500UA (0x1 << 6)
+#define RT5670_MIC2_OVTH_2000UA (0x2 << 6)
+#define RT5670_PWR_MB_MASK (0x1 << 5)
+#define RT5670_PWR_MB_SFT 5
+#define RT5670_PWR_MB_PD (0x0 << 5)
+#define RT5670_PWR_MB_PU (0x1 << 5)
+#define RT5670_PWR_CLK25M_MASK (0x1 << 4)
+#define RT5670_PWR_CLK25M_SFT 4
+#define RT5670_PWR_CLK25M_PD (0x0 << 4)
+#define RT5670_PWR_CLK25M_PU (0x1 << 4)
+
+/* VAD Control 4 (0x9d) */
+#define RT5670_VAD_SEL_MASK (0x3 << 8)
+#define RT5670_VAD_SEL_SFT 8
+
+/* EQ Control 1 (0xb0) */
+#define RT5670_EQ_SRC_MASK (0x1 << 15)
+#define RT5670_EQ_SRC_SFT 15
+#define RT5670_EQ_SRC_DAC (0x0 << 15)
+#define RT5670_EQ_SRC_ADC (0x1 << 15)
+#define RT5670_EQ_UPD (0x1 << 14)
+#define RT5670_EQ_UPD_BIT 14
+#define RT5670_EQ_CD_MASK (0x1 << 13)
+#define RT5670_EQ_CD_SFT 13
+#define RT5670_EQ_CD_DIS (0x0 << 13)
+#define RT5670_EQ_CD_EN (0x1 << 13)
+#define RT5670_EQ_DITH_MASK (0x3 << 8)
+#define RT5670_EQ_DITH_SFT 8
+#define RT5670_EQ_DITH_NOR (0x0 << 8)
+#define RT5670_EQ_DITH_LSB (0x1 << 8)
+#define RT5670_EQ_DITH_LSB_1 (0x2 << 8)
+#define RT5670_EQ_DITH_LSB_2 (0x3 << 8)
+
+/* EQ Control 2 (0xb1) */
+#define RT5670_EQ_HPF1_M_MASK (0x1 << 8)
+#define RT5670_EQ_HPF1_M_SFT 8
+#define RT5670_EQ_HPF1_M_HI (0x0 << 8)
+#define RT5670_EQ_HPF1_M_1ST (0x1 << 8)
+#define RT5670_EQ_LPF1_M_MASK (0x1 << 7)
+#define RT5670_EQ_LPF1_M_SFT 7
+#define RT5670_EQ_LPF1_M_LO (0x0 << 7)
+#define RT5670_EQ_LPF1_M_1ST (0x1 << 7)
+#define RT5670_EQ_HPF2_MASK (0x1 << 6)
+#define RT5670_EQ_HPF2_SFT 6
+#define RT5670_EQ_HPF2_DIS (0x0 << 6)
+#define RT5670_EQ_HPF2_EN (0x1 << 6)
+#define RT5670_EQ_HPF1_MASK (0x1 << 5)
+#define RT5670_EQ_HPF1_SFT 5
+#define RT5670_EQ_HPF1_DIS (0x0 << 5)
+#define RT5670_EQ_HPF1_EN (0x1 << 5)
+#define RT5670_EQ_BPF4_MASK (0x1 << 4)
+#define RT5670_EQ_BPF4_SFT 4
+#define RT5670_EQ_BPF4_DIS (0x0 << 4)
+#define RT5670_EQ_BPF4_EN (0x1 << 4)
+#define RT5670_EQ_BPF3_MASK (0x1 << 3)
+#define RT5670_EQ_BPF3_SFT 3
+#define RT5670_EQ_BPF3_DIS (0x0 << 3)
+#define RT5670_EQ_BPF3_EN (0x1 << 3)
+#define RT5670_EQ_BPF2_MASK (0x1 << 2)
+#define RT5670_EQ_BPF2_SFT 2
+#define RT5670_EQ_BPF2_DIS (0x0 << 2)
+#define RT5670_EQ_BPF2_EN (0x1 << 2)
+#define RT5670_EQ_BPF1_MASK (0x1 << 1)
+#define RT5670_EQ_BPF1_SFT 1
+#define RT5670_EQ_BPF1_DIS (0x0 << 1)
+#define RT5670_EQ_BPF1_EN (0x1 << 1)
+#define RT5670_EQ_LPF_MASK (0x1)
+#define RT5670_EQ_LPF_SFT 0
+#define RT5670_EQ_LPF_DIS (0x0)
+#define RT5670_EQ_LPF_EN (0x1)
+#define RT5670_EQ_CTRL_MASK (0x7f)
+
+/* Memory Test (0xb2) */
+#define RT5670_MT_MASK (0x1 << 15)
+#define RT5670_MT_SFT 15
+#define RT5670_MT_DIS (0x0 << 15)
+#define RT5670_MT_EN (0x1 << 15)
+
+/* DRC/AGC Control 1 (0xb4) */
+#define RT5670_DRC_AGC_P_MASK (0x1 << 15)
+#define RT5670_DRC_AGC_P_SFT 15
+#define RT5670_DRC_AGC_P_DAC (0x0 << 15)
+#define RT5670_DRC_AGC_P_ADC (0x1 << 15)
+#define RT5670_DRC_AGC_MASK (0x1 << 14)
+#define RT5670_DRC_AGC_SFT 14
+#define RT5670_DRC_AGC_DIS (0x0 << 14)
+#define RT5670_DRC_AGC_EN (0x1 << 14)
+#define RT5670_DRC_AGC_UPD (0x1 << 13)
+#define RT5670_DRC_AGC_UPD_BIT 13
+#define RT5670_DRC_AGC_AR_MASK (0x1f << 8)
+#define RT5670_DRC_AGC_AR_SFT 8
+#define RT5670_DRC_AGC_R_MASK (0x7 << 5)
+#define RT5670_DRC_AGC_R_SFT 5
+#define RT5670_DRC_AGC_R_48K (0x1 << 5)
+#define RT5670_DRC_AGC_R_96K (0x2 << 5)
+#define RT5670_DRC_AGC_R_192K (0x3 << 5)
+#define RT5670_DRC_AGC_R_441K (0x5 << 5)
+#define RT5670_DRC_AGC_R_882K (0x6 << 5)
+#define RT5670_DRC_AGC_R_1764K (0x7 << 5)
+#define RT5670_DRC_AGC_RC_MASK (0x1f)
+#define RT5670_DRC_AGC_RC_SFT 0
+
+/* DRC/AGC Control 2 (0xb5) */
+#define RT5670_DRC_AGC_POB_MASK (0x3f << 8)
+#define RT5670_DRC_AGC_POB_SFT 8
+#define RT5670_DRC_AGC_CP_MASK (0x1 << 7)
+#define RT5670_DRC_AGC_CP_SFT 7
+#define RT5670_DRC_AGC_CP_DIS (0x0 << 7)
+#define RT5670_DRC_AGC_CP_EN (0x1 << 7)
+#define RT5670_DRC_AGC_CPR_MASK (0x3 << 5)
+#define RT5670_DRC_AGC_CPR_SFT 5
+#define RT5670_DRC_AGC_CPR_1_1 (0x0 << 5)
+#define RT5670_DRC_AGC_CPR_1_2 (0x1 << 5)
+#define RT5670_DRC_AGC_CPR_1_3 (0x2 << 5)
+#define RT5670_DRC_AGC_CPR_1_4 (0x3 << 5)
+#define RT5670_DRC_AGC_PRB_MASK (0x1f)
+#define RT5670_DRC_AGC_PRB_SFT 0
+
+/* DRC/AGC Control 3 (0xb6) */
+#define RT5670_DRC_AGC_NGB_MASK (0xf << 12)
+#define RT5670_DRC_AGC_NGB_SFT 12
+#define RT5670_DRC_AGC_TAR_MASK (0x1f << 7)
+#define RT5670_DRC_AGC_TAR_SFT 7
+#define RT5670_DRC_AGC_NG_MASK (0x1 << 6)
+#define RT5670_DRC_AGC_NG_SFT 6
+#define RT5670_DRC_AGC_NG_DIS (0x0 << 6)
+#define RT5670_DRC_AGC_NG_EN (0x1 << 6)
+#define RT5670_DRC_AGC_NGH_MASK (0x1 << 5)
+#define RT5670_DRC_AGC_NGH_SFT 5
+#define RT5670_DRC_AGC_NGH_DIS (0x0 << 5)
+#define RT5670_DRC_AGC_NGH_EN (0x1 << 5)
+#define RT5670_DRC_AGC_NGT_MASK (0x1f)
+#define RT5670_DRC_AGC_NGT_SFT 0
+
+/* Jack Detect Control (0xbb) */
+#define RT5670_JD_MASK (0x7 << 13)
+#define RT5670_JD_SFT 13
+#define RT5670_JD_DIS (0x0 << 13)
+#define RT5670_JD_GPIO1 (0x1 << 13)
+#define RT5670_JD_JD1_IN4P (0x2 << 13)
+#define RT5670_JD_JD2_IN4N (0x3 << 13)
+#define RT5670_JD_GPIO2 (0x4 << 13)
+#define RT5670_JD_GPIO3 (0x5 << 13)
+#define RT5670_JD_GPIO4 (0x6 << 13)
+#define RT5670_JD_HP_MASK (0x1 << 11)
+#define RT5670_JD_HP_SFT 11
+#define RT5670_JD_HP_DIS (0x0 << 11)
+#define RT5670_JD_HP_EN (0x1 << 11)
+#define RT5670_JD_HP_TRG_MASK (0x1 << 10)
+#define RT5670_JD_HP_TRG_SFT 10
+#define RT5670_JD_HP_TRG_LO (0x0 << 10)
+#define RT5670_JD_HP_TRG_HI (0x1 << 10)
+#define RT5670_JD_SPL_MASK (0x1 << 9)
+#define RT5670_JD_SPL_SFT 9
+#define RT5670_JD_SPL_DIS (0x0 << 9)
+#define RT5670_JD_SPL_EN (0x1 << 9)
+#define RT5670_JD_SPL_TRG_MASK (0x1 << 8)
+#define RT5670_JD_SPL_TRG_SFT 8
+#define RT5670_JD_SPL_TRG_LO (0x0 << 8)
+#define RT5670_JD_SPL_TRG_HI (0x1 << 8)
+#define RT5670_JD_SPR_MASK (0x1 << 7)
+#define RT5670_JD_SPR_SFT 7
+#define RT5670_JD_SPR_DIS (0x0 << 7)
+#define RT5670_JD_SPR_EN (0x1 << 7)
+#define RT5670_JD_SPR_TRG_MASK (0x1 << 6)
+#define RT5670_JD_SPR_TRG_SFT 6
+#define RT5670_JD_SPR_TRG_LO (0x0 << 6)
+#define RT5670_JD_SPR_TRG_HI (0x1 << 6)
+#define RT5670_JD_MO_MASK (0x1 << 5)
+#define RT5670_JD_MO_SFT 5
+#define RT5670_JD_MO_DIS (0x0 << 5)
+#define RT5670_JD_MO_EN (0x1 << 5)
+#define RT5670_JD_MO_TRG_MASK (0x1 << 4)
+#define RT5670_JD_MO_TRG_SFT 4
+#define RT5670_JD_MO_TRG_LO (0x0 << 4)
+#define RT5670_JD_MO_TRG_HI (0x1 << 4)
+#define RT5670_JD_LO_MASK (0x1 << 3)
+#define RT5670_JD_LO_SFT 3
+#define RT5670_JD_LO_DIS (0x0 << 3)
+#define RT5670_JD_LO_EN (0x1 << 3)
+#define RT5670_JD_LO_TRG_MASK (0x1 << 2)
+#define RT5670_JD_LO_TRG_SFT 2
+#define RT5670_JD_LO_TRG_LO (0x0 << 2)
+#define RT5670_JD_LO_TRG_HI (0x1 << 2)
+#define RT5670_JD1_IN4P_MASK (0x1 << 1)
+#define RT5670_JD1_IN4P_SFT 1
+#define RT5670_JD1_IN4P_DIS (0x0 << 1)
+#define RT5670_JD1_IN4P_EN (0x1 << 1)
+#define RT5670_JD2_IN4N_MASK (0x1)
+#define RT5670_JD2_IN4N_SFT 0
+#define RT5670_JD2_IN4N_DIS (0x0)
+#define RT5670_JD2_IN4N_EN (0x1)
+
+/* IRQ Control 1 (0xbd) */
+#define RT5670_IRQ_JD_MASK (0x1 << 15)
+#define RT5670_IRQ_JD_SFT 15
+#define RT5670_IRQ_JD_BP (0x0 << 15)
+#define RT5670_IRQ_JD_NOR (0x1 << 15)
+#define RT5670_IRQ_OT_MASK (0x1 << 14)
+#define RT5670_IRQ_OT_SFT 14
+#define RT5670_IRQ_OT_BP (0x0 << 14)
+#define RT5670_IRQ_OT_NOR (0x1 << 14)
+#define RT5670_JD_STKY_MASK (0x1 << 13)
+#define RT5670_JD_STKY_SFT 13
+#define RT5670_JD_STKY_DIS (0x0 << 13)
+#define RT5670_JD_STKY_EN (0x1 << 13)
+#define RT5670_OT_STKY_MASK (0x1 << 12)
+#define RT5670_OT_STKY_SFT 12
+#define RT5670_OT_STKY_DIS (0x0 << 12)
+#define RT5670_OT_STKY_EN (0x1 << 12)
+#define RT5670_JD_P_MASK (0x1 << 11)
+#define RT5670_JD_P_SFT 11
+#define RT5670_JD_P_NOR (0x0 << 11)
+#define RT5670_JD_P_INV (0x1 << 11)
+#define RT5670_OT_P_MASK (0x1 << 10)
+#define RT5670_OT_P_SFT 10
+#define RT5670_OT_P_NOR (0x0 << 10)
+#define RT5670_OT_P_INV (0x1 << 10)
+
+/* IRQ Control 2 (0xbe) */
+#define RT5670_IRQ_MB1_OC_MASK (0x1 << 15)
+#define RT5670_IRQ_MB1_OC_SFT 15
+#define RT5670_IRQ_MB1_OC_BP (0x0 << 15)
+#define RT5670_IRQ_MB1_OC_NOR (0x1 << 15)
+#define RT5670_IRQ_MB2_OC_MASK (0x1 << 14)
+#define RT5670_IRQ_MB2_OC_SFT 14
+#define RT5670_IRQ_MB2_OC_BP (0x0 << 14)
+#define RT5670_IRQ_MB2_OC_NOR (0x1 << 14)
+#define RT5670_MB1_OC_STKY_MASK (0x1 << 11)
+#define RT5670_MB1_OC_STKY_SFT 11
+#define RT5670_MB1_OC_STKY_DIS (0x0 << 11)
+#define RT5670_MB1_OC_STKY_EN (0x1 << 11)
+#define RT5670_MB2_OC_STKY_MASK (0x1 << 10)
+#define RT5670_MB2_OC_STKY_SFT 10
+#define RT5670_MB2_OC_STKY_DIS (0x0 << 10)
+#define RT5670_MB2_OC_STKY_EN (0x1 << 10)
+#define RT5670_MB1_OC_P_MASK (0x1 << 7)
+#define RT5670_MB1_OC_P_SFT 7
+#define RT5670_MB1_OC_P_NOR (0x0 << 7)
+#define RT5670_MB1_OC_P_INV (0x1 << 7)
+#define RT5670_MB2_OC_P_MASK (0x1 << 6)
+#define RT5670_MB2_OC_P_SFT 6
+#define RT5670_MB2_OC_P_NOR (0x0 << 6)
+#define RT5670_MB2_OC_P_INV (0x1 << 6)
+#define RT5670_MB1_OC_CLR (0x1 << 3)
+#define RT5670_MB1_OC_CLR_SFT 3
+#define RT5670_MB2_OC_CLR (0x1 << 2)
+#define RT5670_MB2_OC_CLR_SFT 2
+
+/* GPIO Control 1 (0xc0) */
+#define RT5670_GP1_PIN_MASK (0x1 << 15)
+#define RT5670_GP1_PIN_SFT 15
+#define RT5670_GP1_PIN_GPIO1 (0x0 << 15)
+#define RT5670_GP1_PIN_IRQ (0x1 << 15)
+#define RT5670_GP2_PIN_MASK (0x1 << 14)
+#define RT5670_GP2_PIN_SFT 14
+#define RT5670_GP2_PIN_GPIO2 (0x0 << 14)
+#define RT5670_GP2_PIN_DMIC1_SCL (0x1 << 14)
+#define RT5670_GP3_PIN_MASK (0x3 << 12)
+#define RT5670_GP3_PIN_SFT 12
+#define RT5670_GP3_PIN_GPIO3 (0x0 << 12)
+#define RT5670_GP3_PIN_DMIC1_SDA (0x1 << 12)
+#define RT5670_GP3_PIN_IRQ (0x2 << 12)
+#define RT5670_GP4_PIN_MASK (0x1 << 11)
+#define RT5670_GP4_PIN_SFT 11
+#define RT5670_GP4_PIN_GPIO4 (0x0 << 11)
+#define RT5670_GP4_PIN_DMIC2_SDA (0x1 << 11)
+#define RT5670_DP_SIG_MASK (0x1 << 10)
+#define RT5670_DP_SIG_SFT 10
+#define RT5670_DP_SIG_TEST (0x0 << 10)
+#define RT5670_DP_SIG_AP (0x1 << 10)
+#define RT5670_GPIO_M_MASK (0x1 << 9)
+#define RT5670_GPIO_M_SFT 9
+#define RT5670_GPIO_M_FLT (0x0 << 9)
+#define RT5670_GPIO_M_PH (0x1 << 9)
+#define RT5670_I2S2_PIN_MASK (0x1 << 8)
+#define RT5670_I2S2_PIN_SFT 8
+#define RT5670_I2S2_PIN_I2S (0x0 << 8)
+#define RT5670_I2S2_PIN_GPIO (0x1 << 8)
+#define RT5670_GP5_PIN_MASK (0x1 << 7)
+#define RT5670_GP5_PIN_SFT 7
+#define RT5670_GP5_PIN_GPIO5 (0x0 << 7)
+#define RT5670_GP5_PIN_DMIC3_SCL (0x1 << 7)
+#define RT5670_GP6_PIN_MASK (0x1 << 6)
+#define RT5670_GP6_PIN_SFT 6
+#define RT5670_GP6_PIN_GPIO6 (0x0 << 6)
+#define RT5670_GP6_PIN_DMIC1_SDA (0x1 << 6)
+#define RT5670_GP7_PIN_MASK (0x3 << 4)
+#define RT5670_GP7_PIN_SFT 4
+#define RT5670_GP7_PIN_GPIO7 (0x0 << 4)
+#define RT5670_GP7_PIN_DMIC1_SDA (0x1 << 4)
+#define RT5670_GP7_PIN_PDM_SCL2 (0x2 << 4)
+#define RT5670_GP8_PIN_MASK (0x1 << 3)
+#define RT5670_GP8_PIN_SFT 3
+#define RT5670_GP8_PIN_GPIO8 (0x0 << 3)
+#define RT5670_GP8_PIN_DMIC2_SDA (0x1 << 3)
+#define RT5670_GP9_PIN_MASK (0x1 << 2)
+#define RT5670_GP9_PIN_SFT 2
+#define RT5670_GP9_PIN_GPIO9 (0x0 << 2)
+#define RT5670_GP9_PIN_DMIC3_SDA (0x1 << 2)
+#define RT5670_GP10_PIN_MASK (0x3)
+#define RT5670_GP10_PIN_SFT 0
+#define RT5670_GP10_PIN_GPIO9 (0x0)
+#define RT5670_GP10_PIN_DMIC3_SDA (0x1)
+#define RT5670_GP10_PIN_PDM_ADT2 (0x2)
+
+/* GPIO Control 2 (0xc1) */
+#define RT5670_GP4_PF_MASK (0x1 << 11)
+#define RT5670_GP4_PF_SFT 11
+#define RT5670_GP4_PF_IN (0x0 << 11)
+#define RT5670_GP4_PF_OUT (0x1 << 11)
+#define RT5670_GP4_OUT_MASK (0x1 << 10)
+#define RT5670_GP4_OUT_SFT 10
+#define RT5670_GP4_OUT_LO (0x0 << 10)
+#define RT5670_GP4_OUT_HI (0x1 << 10)
+#define RT5670_GP4_P_MASK (0x1 << 9)
+#define RT5670_GP4_P_SFT 9
+#define RT5670_GP4_P_NOR (0x0 << 9)
+#define RT5670_GP4_P_INV (0x1 << 9)
+#define RT5670_GP3_PF_MASK (0x1 << 8)
+#define RT5670_GP3_PF_SFT 8
+#define RT5670_GP3_PF_IN (0x0 << 8)
+#define RT5670_GP3_PF_OUT (0x1 << 8)
+#define RT5670_GP3_OUT_MASK (0x1 << 7)
+#define RT5670_GP3_OUT_SFT 7
+#define RT5670_GP3_OUT_LO (0x0 << 7)
+#define RT5670_GP3_OUT_HI (0x1 << 7)
+#define RT5670_GP3_P_MASK (0x1 << 6)
+#define RT5670_GP3_P_SFT 6
+#define RT5670_GP3_P_NOR (0x0 << 6)
+#define RT5670_GP3_P_INV (0x1 << 6)
+#define RT5670_GP2_PF_MASK (0x1 << 5)
+#define RT5670_GP2_PF_SFT 5
+#define RT5670_GP2_PF_IN (0x0 << 5)
+#define RT5670_GP2_PF_OUT (0x1 << 5)
+#define RT5670_GP2_OUT_MASK (0x1 << 4)
+#define RT5670_GP2_OUT_SFT 4
+#define RT5670_GP2_OUT_LO (0x0 << 4)
+#define RT5670_GP2_OUT_HI (0x1 << 4)
+#define RT5670_GP2_P_MASK (0x1 << 3)
+#define RT5670_GP2_P_SFT 3
+#define RT5670_GP2_P_NOR (0x0 << 3)
+#define RT5670_GP2_P_INV (0x1 << 3)
+#define RT5670_GP1_PF_MASK (0x1 << 2)
+#define RT5670_GP1_PF_SFT 2
+#define RT5670_GP1_PF_IN (0x0 << 2)
+#define RT5670_GP1_PF_OUT (0x1 << 2)
+#define RT5670_GP1_OUT_MASK (0x1 << 1)
+#define RT5670_GP1_OUT_SFT 1
+#define RT5670_GP1_OUT_LO (0x0 << 1)
+#define RT5670_GP1_OUT_HI (0x1 << 1)
+#define RT5670_GP1_P_MASK (0x1)
+#define RT5670_GP1_P_SFT 0
+#define RT5670_GP1_P_NOR (0x0)
+#define RT5670_GP1_P_INV (0x1)
+
+/* Scramble Function (0xcd) */
+#define RT5670_SCB_KEY_MASK (0xff)
+#define RT5670_SCB_KEY_SFT 0
+
+/* Scramble Control (0xce) */
+#define RT5670_SCB_SWAP_MASK (0x1 << 15)
+#define RT5670_SCB_SWAP_SFT 15
+#define RT5670_SCB_SWAP_DIS (0x0 << 15)
+#define RT5670_SCB_SWAP_EN (0x1 << 15)
+#define RT5670_SCB_MASK (0x1 << 14)
+#define RT5670_SCB_SFT 14
+#define RT5670_SCB_DIS (0x0 << 14)
+#define RT5670_SCB_EN (0x1 << 14)
+
+/* Baseback Control (0xcf) */
+#define RT5670_BB_MASK (0x1 << 15)
+#define RT5670_BB_SFT 15
+#define RT5670_BB_DIS (0x0 << 15)
+#define RT5670_BB_EN (0x1 << 15)
+#define RT5670_BB_CT_MASK (0x7 << 12)
+#define RT5670_BB_CT_SFT 12
+#define RT5670_BB_CT_A (0x0 << 12)
+#define RT5670_BB_CT_B (0x1 << 12)
+#define RT5670_BB_CT_C (0x2 << 12)
+#define RT5670_BB_CT_D (0x3 << 12)
+#define RT5670_M_BB_L_MASK (0x1 << 9)
+#define RT5670_M_BB_L_SFT 9
+#define RT5670_M_BB_R_MASK (0x1 << 8)
+#define RT5670_M_BB_R_SFT 8
+#define RT5670_M_BB_HPF_L_MASK (0x1 << 7)
+#define RT5670_M_BB_HPF_L_SFT 7
+#define RT5670_M_BB_HPF_R_MASK (0x1 << 6)
+#define RT5670_M_BB_HPF_R_SFT 6
+#define RT5670_G_BB_BST_MASK (0x3f)
+#define RT5670_G_BB_BST_SFT 0
+
+/* MP3 Plus Control 1 (0xd0) */
+#define RT5670_M_MP3_L_MASK (0x1 << 15)
+#define RT5670_M_MP3_L_SFT 15
+#define RT5670_M_MP3_R_MASK (0x1 << 14)
+#define RT5670_M_MP3_R_SFT 14
+#define RT5670_M_MP3_MASK (0x1 << 13)
+#define RT5670_M_MP3_SFT 13
+#define RT5670_M_MP3_DIS (0x0 << 13)
+#define RT5670_M_MP3_EN (0x1 << 13)
+#define RT5670_EG_MP3_MASK (0x1f << 8)
+#define RT5670_EG_MP3_SFT 8
+#define RT5670_MP3_HLP_MASK (0x1 << 7)
+#define RT5670_MP3_HLP_SFT 7
+#define RT5670_MP3_HLP_DIS (0x0 << 7)
+#define RT5670_MP3_HLP_EN (0x1 << 7)
+#define RT5670_M_MP3_ORG_L_MASK (0x1 << 6)
+#define RT5670_M_MP3_ORG_L_SFT 6
+#define RT5670_M_MP3_ORG_R_MASK (0x1 << 5)
+#define RT5670_M_MP3_ORG_R_SFT 5
+
+/* MP3 Plus Control 2 (0xd1) */
+#define RT5670_MP3_WT_MASK (0x1 << 13)
+#define RT5670_MP3_WT_SFT 13
+#define RT5670_MP3_WT_1_4 (0x0 << 13)
+#define RT5670_MP3_WT_1_2 (0x1 << 13)
+#define RT5670_OG_MP3_MASK (0x1f << 8)
+#define RT5670_OG_MP3_SFT 8
+#define RT5670_HG_MP3_MASK (0x3f)
+#define RT5670_HG_MP3_SFT 0
+
+/* 3D HP Control 1 (0xd2) */
+#define RT5670_3D_CF_MASK (0x1 << 15)
+#define RT5670_3D_CF_SFT 15
+#define RT5670_3D_CF_DIS (0x0 << 15)
+#define RT5670_3D_CF_EN (0x1 << 15)
+#define RT5670_3D_HP_MASK (0x1 << 14)
+#define RT5670_3D_HP_SFT 14
+#define RT5670_3D_HP_DIS (0x0 << 14)
+#define RT5670_3D_HP_EN (0x1 << 14)
+#define RT5670_3D_BT_MASK (0x1 << 13)
+#define RT5670_3D_BT_SFT 13
+#define RT5670_3D_BT_DIS (0x0 << 13)
+#define RT5670_3D_BT_EN (0x1 << 13)
+#define RT5670_3D_1F_MIX_MASK (0x3 << 11)
+#define RT5670_3D_1F_MIX_SFT 11
+#define RT5670_3D_HP_M_MASK (0x1 << 10)
+#define RT5670_3D_HP_M_SFT 10
+#define RT5670_3D_HP_M_SUR (0x0 << 10)
+#define RT5670_3D_HP_M_FRO (0x1 << 10)
+#define RT5670_M_3D_HRTF_MASK (0x1 << 9)
+#define RT5670_M_3D_HRTF_SFT 9
+#define RT5670_M_3D_D2H_MASK (0x1 << 8)
+#define RT5670_M_3D_D2H_SFT 8
+#define RT5670_M_3D_D2R_MASK (0x1 << 7)
+#define RT5670_M_3D_D2R_SFT 7
+#define RT5670_M_3D_REVB_MASK (0x1 << 6)
+#define RT5670_M_3D_REVB_SFT 6
+
+/* Adjustable high pass filter control 1 (0xd3) */
+#define RT5670_2ND_HPF_MASK (0x1 << 15)
+#define RT5670_2ND_HPF_SFT 15
+#define RT5670_2ND_HPF_DIS (0x0 << 15)
+#define RT5670_2ND_HPF_EN (0x1 << 15)
+#define RT5670_HPF_CF_L_MASK (0x7 << 12)
+#define RT5670_HPF_CF_L_SFT 12
+#define RT5670_1ST_HPF_MASK (0x1 << 11)
+#define RT5670_1ST_HPF_SFT 11
+#define RT5670_1ST_HPF_DIS (0x0 << 11)
+#define RT5670_1ST_HPF_EN (0x1 << 11)
+#define RT5670_HPF_CF_R_MASK (0x7 << 8)
+#define RT5670_HPF_CF_R_SFT 8
+#define RT5670_ZD_T_MASK (0x3 << 6)
+#define RT5670_ZD_T_SFT 6
+#define RT5670_ZD_F_MASK (0x3 << 4)
+#define RT5670_ZD_F_SFT 4
+#define RT5670_ZD_F_IM (0x0 << 4)
+#define RT5670_ZD_F_ZC_IM (0x1 << 4)
+#define RT5670_ZD_F_ZC_IOD (0x2 << 4)
+#define RT5670_ZD_F_UN (0x3 << 4)
+
+/* HP calibration control and Amp detection (0xd6) */
+#define RT5670_SI_DAC_MASK (0x1 << 11)
+#define RT5670_SI_DAC_SFT 11
+#define RT5670_SI_DAC_AUTO (0x0 << 11)
+#define RT5670_SI_DAC_TEST (0x1 << 11)
+#define RT5670_DC_CAL_M_MASK (0x1 << 10)
+#define RT5670_DC_CAL_M_SFT 10
+#define RT5670_DC_CAL_M_CAL (0x0 << 10)
+#define RT5670_DC_CAL_M_NOR (0x1 << 10)
+#define RT5670_DC_CAL_MASK (0x1 << 9)
+#define RT5670_DC_CAL_SFT 9
+#define RT5670_DC_CAL_DIS (0x0 << 9)
+#define RT5670_DC_CAL_EN (0x1 << 9)
+#define RT5670_HPD_RCV_MASK (0x7 << 6)
+#define RT5670_HPD_RCV_SFT 6
+#define RT5670_HPD_PS_MASK (0x1 << 5)
+#define RT5670_HPD_PS_SFT 5
+#define RT5670_HPD_PS_DIS (0x0 << 5)
+#define RT5670_HPD_PS_EN (0x1 << 5)
+#define RT5670_CAL_M_MASK (0x1 << 4)
+#define RT5670_CAL_M_SFT 4
+#define RT5670_CAL_M_DEP (0x0 << 4)
+#define RT5670_CAL_M_CAL (0x1 << 4)
+#define RT5670_CAL_MASK (0x1 << 3)
+#define RT5670_CAL_SFT 3
+#define RT5670_CAL_DIS (0x0 << 3)
+#define RT5670_CAL_EN (0x1 << 3)
+#define RT5670_CAL_TEST_MASK (0x1 << 2)
+#define RT5670_CAL_TEST_SFT 2
+#define RT5670_CAL_TEST_DIS (0x0 << 2)
+#define RT5670_CAL_TEST_EN (0x1 << 2)
+#define RT5670_CAL_P_MASK (0x3)
+#define RT5670_CAL_P_SFT 0
+#define RT5670_CAL_P_NONE (0x0)
+#define RT5670_CAL_P_CAL (0x1)
+#define RT5670_CAL_P_DAC_CAL (0x2)
+
+/* Soft volume and zero cross control 1 (0xd9) */
+#define RT5670_SV_MASK (0x1 << 15)
+#define RT5670_SV_SFT 15
+#define RT5670_SV_DIS (0x0 << 15)
+#define RT5670_SV_EN (0x1 << 15)
+#define RT5670_SPO_SV_MASK (0x1 << 14)
+#define RT5670_SPO_SV_SFT 14
+#define RT5670_SPO_SV_DIS (0x0 << 14)
+#define RT5670_SPO_SV_EN (0x1 << 14)
+#define RT5670_OUT_SV_MASK (0x1 << 13)
+#define RT5670_OUT_SV_SFT 13
+#define RT5670_OUT_SV_DIS (0x0 << 13)
+#define RT5670_OUT_SV_EN (0x1 << 13)
+#define RT5670_HP_SV_MASK (0x1 << 12)
+#define RT5670_HP_SV_SFT 12
+#define RT5670_HP_SV_DIS (0x0 << 12)
+#define RT5670_HP_SV_EN (0x1 << 12)
+#define RT5670_ZCD_DIG_MASK (0x1 << 11)
+#define RT5670_ZCD_DIG_SFT 11
+#define RT5670_ZCD_DIG_DIS (0x0 << 11)
+#define RT5670_ZCD_DIG_EN (0x1 << 11)
+#define RT5670_ZCD_MASK (0x1 << 10)
+#define RT5670_ZCD_SFT 10
+#define RT5670_ZCD_PD (0x0 << 10)
+#define RT5670_ZCD_PU (0x1 << 10)
+#define RT5670_M_ZCD_MASK (0x3f << 4)
+#define RT5670_M_ZCD_SFT 4
+#define RT5670_M_ZCD_RM_L (0x1 << 9)
+#define RT5670_M_ZCD_RM_R (0x1 << 8)
+#define RT5670_M_ZCD_SM_L (0x1 << 7)
+#define RT5670_M_ZCD_SM_R (0x1 << 6)
+#define RT5670_M_ZCD_OM_L (0x1 << 5)
+#define RT5670_M_ZCD_OM_R (0x1 << 4)
+#define RT5670_SV_DLY_MASK (0xf)
+#define RT5670_SV_DLY_SFT 0
+
+/* Soft volume and zero cross control 2 (0xda) */
+#define RT5670_ZCD_HP_MASK (0x1 << 15)
+#define RT5670_ZCD_HP_SFT 15
+#define RT5670_ZCD_HP_DIS (0x0 << 15)
+#define RT5670_ZCD_HP_EN (0x1 << 15)
+
+
+/* Codec Private Register definition */
+/* 3D Speaker Control (0x63) */
+#define RT5670_3D_SPK_MASK (0x1 << 15)
+#define RT5670_3D_SPK_SFT 15
+#define RT5670_3D_SPK_DIS (0x0 << 15)
+#define RT5670_3D_SPK_EN (0x1 << 15)
+#define RT5670_3D_SPK_M_MASK (0x3 << 13)
+#define RT5670_3D_SPK_M_SFT 13
+#define RT5670_3D_SPK_CG_MASK (0x1f << 8)
+#define RT5670_3D_SPK_CG_SFT 8
+#define RT5670_3D_SPK_SG_MASK (0x1f)
+#define RT5670_3D_SPK_SG_SFT 0
+
+/* Wind Noise Detection Control 1 (0x6c) */
+#define RT5670_WND_MASK (0x1 << 15)
+#define RT5670_WND_SFT 15
+#define RT5670_WND_DIS (0x0 << 15)
+#define RT5670_WND_EN (0x1 << 15)
+
+/* Wind Noise Detection Control 2 (0x6d) */
+#define RT5670_WND_FC_NW_MASK (0x3f << 10)
+#define RT5670_WND_FC_NW_SFT 10
+#define RT5670_WND_FC_WK_MASK (0x3f << 4)
+#define RT5670_WND_FC_WK_SFT 4
+
+/* Wind Noise Detection Control 3 (0x6e) */
+#define RT5670_HPF_FC_MASK (0x3f << 6)
+#define RT5670_HPF_FC_SFT 6
+#define RT5670_WND_FC_ST_MASK (0x3f)
+#define RT5670_WND_FC_ST_SFT 0
+
+/* Wind Noise Detection Control 4 (0x6f) */
+#define RT5670_WND_TH_LO_MASK (0x3ff)
+#define RT5670_WND_TH_LO_SFT 0
+
+/* Wind Noise Detection Control 5 (0x70) */
+#define RT5670_WND_TH_HI_MASK (0x3ff)
+#define RT5670_WND_TH_HI_SFT 0
+
+/* Wind Noise Detection Control 8 (0x73) */
+#define RT5670_WND_WIND_MASK (0x1 << 13) /* Read-Only */
+#define RT5670_WND_WIND_SFT 13
+#define RT5670_WND_STRONG_MASK (0x1 << 12) /* Read-Only */
+#define RT5670_WND_STRONG_SFT 12
+enum {
+ RT5670_NO_WIND,
+ RT5670_BREEZE,
+ RT5670_STORM,
+};
+
+/* Dipole Speaker Interface (0x75) */
+#define RT5670_DP_ATT_MASK (0x3 << 14)
+#define RT5670_DP_ATT_SFT 14
+#define RT5670_DP_SPK_MASK (0x1 << 10)
+#define RT5670_DP_SPK_SFT 10
+#define RT5670_DP_SPK_DIS (0x0 << 10)
+#define RT5670_DP_SPK_EN (0x1 << 10)
+
+/* EQ Pre Volume Control (0xb3) */
+#define RT5670_EQ_PRE_VOL_MASK (0xffff)
+#define RT5670_EQ_PRE_VOL_SFT 0
+
+/* EQ Post Volume Control (0xb4) */
+#define RT5670_EQ_PST_VOL_MASK (0xffff)
+#define RT5670_EQ_PST_VOL_SFT 0
+
+/* Jack Detect Control 3 (0xf8) */
+#define RT5670_CMP_MIC_IN_DET_MASK (0x7 << 12)
+#define RT5670_JD_CBJ_EN (0x1 << 7)
+#define RT5670_JD_CBJ_POL (0x1 << 6)
+#define RT5670_JD_TRI_CBJ_SEL_MASK (0x7 << 3)
+#define RT5670_JD_TRI_CBJ_SEL_SFT (3)
+#define RT5670_JD_TRI_HPO_SEL_MASK (0x7)
+#define RT5670_JD_TRI_HPO_SEL_SFT (0)
+#define RT5670_JD_F_GPIO_JD1 (0x0)
+#define RT5670_JD_F_JD1_1 (0x1)
+#define RT5670_JD_F_JD1_2 (0x2)
+#define RT5670_JD_F_JD2 (0x3)
+#define RT5670_JD_F_JD3 (0x4)
+#define RT5670_JD_F_GPIO_JD2 (0x5)
+#define RT5670_JD_F_MX0B_12 (0x6)
+
+/* Digital Misc Control (0xfa) */
+#define RT5670_RST_DSP (0x1 << 13)
+#define RT5670_IF1_ADC1_IN1_SEL (0x1 << 12)
+#define RT5670_IF1_ADC1_IN1_SFT 12
+#define RT5670_IF1_ADC1_IN2_SEL (0x1 << 11)
+#define RT5670_IF1_ADC1_IN2_SFT 11
+#define RT5670_IF1_ADC2_IN1_SEL (0x1 << 10)
+#define RT5670_IF1_ADC2_IN1_SFT 10
+
+/* General Control2 (0xfb) */
+#define RT5670_RXDC_SRC_MASK (0x1 << 7)
+#define RT5670_RXDC_SRC_STO (0x0 << 7)
+#define RT5670_RXDC_SRC_MONO (0x1 << 7)
+#define RT5670_RXDC_SRC_SFT (7)
+#define RT5670_RXDP2_SEL_MASK (0x1 << 3)
+#define RT5670_RXDP2_SEL_IF2 (0x0 << 3)
+#define RT5670_RXDP2_SEL_ADC (0x1 << 3)
+#define RT5670_RXDP2_SEL_SFT (3)
+
+
+/* Vendor ID (0xfd) */
+#define RT5670_VER_C 0x2
+#define RT5670_VER_D 0x3
+
+
+/* Volume Rescale */
+#define RT5670_VOL_RSCL_MAX 0x27
+#define RT5670_VOL_RSCL_RANGE 0x1F
+/* Debug String Length */
+#define RT5670_REG_DISP_LEN 23
+
+int rt5670_headset_detect(struct snd_soc_codec *codec, int jack_insert);
+int rt5670_check_interrupt_event(struct snd_soc_codec *codec, int *data);
+
+/* System Clock Source */
+enum {
+ RT5670_SCLK_S_MCLK,
+ RT5670_SCLK_S_PLL1,
+ RT5670_SCLK_S_RCCLK,
+};
+
+/* PLL1 Source */
+enum {
+ RT5670_PLL1_S_MCLK,
+ RT5670_PLL1_S_BCLK1,
+ RT5670_PLL1_S_BCLK2,
+ RT5670_PLL1_S_BCLK3,
+ RT5670_PLL1_S_BCLK4,
+};
+
+enum {
+ RT5670_AIF1,
+ RT5670_AIF2,
+ RT5670_AIF3,
+ RT5670_AIF4,
+ RT5670_AIFS,
+};
+
+#define RT5670_U_IF1 (0x1)
+#define RT5670_U_IF2 (0x1 << 1)
+#define RT5670_U_IF3 (0x1 << 2)
+#define RT5670_U_IF4 (0x1 << 3)
+
+enum {
+ RT5670_DMIC_DIS,
+ RT5670_DMIC1,
+ RT5670_DMIC2,
+ RT5670_DMIC3,
+};
+
+enum {
+ RT5670_BTN_EVENT = BIT(0), /* Jack evulse */
+ RT5670_BR_EVENT = BIT(1), /* Button Release */
+ RT5670_J_IN_EVENT = BIT(2), /* Jack insert */
+ RT5670_J_OUT_EVENT = BIT(3), /* Jack evulse */
+ RT5670_UN_EVENT = BIT(4), /* Unknown */
+};
+
+struct rt5670_pll_code {
+ bool m_bp; /* Indicates bypass m code or not. */
+ int m_code;
+ int n_code;
+ int k_code;
+};
+
+struct rt5670_priv {
+ struct snd_soc_codec *codec;
+ struct delayed_work patch_work;
+
+ int aif_pu;
+ int sysclk;
+ int sysclk_src;
+ int lrck[RT5670_AIFS];
+ int bclk[RT5670_AIFS];
+ int master[RT5670_AIFS];
+
+ int pll_src;
+ int pll_in;
+ int pll_out;
+
+ int dmic_en;
+ bool combo_jack_en;
+ int dsp_sw; /* expected parameter setting */
+ int jack_type;
+};
+
+#endif /* __RT5670_H__ */
diff --git a/sound/soc/codecs/rt5670_ioctl.c b/sound/soc/codecs/rt5670_ioctl.c
new file mode 100644
index 00000000..df293cdc
--- /dev/null
+++ b/sound/soc/codecs/rt5670_ioctl.c
@@ -0,0 +1,132 @@
+/*
+ * rt5670_ioctl.h -- RT5670 ALSA SoC audio driver IO control
+ *
+ * Copyright 2012 Realtek Microelectronics
+ * Author: Bard <bardliao@realtek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/spi/spi.h>
+#include <sound/soc.h>
+#include "rt_codec_ioctl.h"
+#include "rt5670_ioctl.h"
+#include "rt5670.h"
+#include "rt5670-dsp.h"
+
+hweq_t hweq_param[] = {
+ {/* NORMAL */
+ {0},
+ {0},
+ 0x0000,
+ },
+ {/* SPK */
+ {0},
+ {0x1c10,0x01f4, 0xc5e9, 0x1a98, 0x1d2c, 0xc882, 0x1c10, 0x01f4, 0xe904, 0x1c10, 0x01f4, 0xe904, 0x1c10, 0x01f4, 0x1c10, 0x01f4, 0x2000, 0x0000, 0x2000},
+ 0x0000,
+ },
+ {/* HP */
+ {0},
+ {0x1c10,0x01f4, 0xc5e9, 0x1a98, 0x1d2c, 0xc882, 0x1c10, 0x01f4, 0xe904, 0x1c10, 0x01f4, 0xe904, 0x1c10, 0x01f4, 0x1c10, 0x01f4, 0x2000, 0x0000, 0x2000},
+ 0x0000,
+ },
+};
+#define RT5670_HWEQ_LEN ARRAY_SIZE(hweq_param)
+
+int eqreg[EQ_CH_NUM][EQ_REG_NUM] = {
+ {0xa4, 0xa5, 0xeb, 0xec, 0xed, 0xee, 0xe7, 0xe8, 0xe9, 0xea, 0xe5,
+ 0xe6, 0xae, 0xaf, 0xb0, 0xb4, 0xb5, 0xb6, 0xba, 0xbb, 0xbc, 0xc0,
+ 0xc1, 0xc4, 0xc5, 0xc6, 0xca, 0xcc},
+ {0xa6, 0xa7, 0xf5, 0xf6, 0xf7, 0xf8, 0xf1, 0xf2, 0xf3, 0xf4, 0xef,
+ 0xf0, 0xb1, 0xb2, 0xb3, 0xb7, 0xb8, 0xb9, 0xbd, 0xbe, 0xbf, 0xc2,
+ 0xc3, 0xc7, 0xc8, 0xc9, 0xcb, 0xcd},
+ {0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
+ 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xe1, 0xe2},
+};
+
+int rt5670_update_eqmode(
+ struct snd_soc_codec *codec, int channel, int mode)
+{
+ struct rt_codec_ops *ioctl_ops = rt_codec_get_ioctl_ops();
+ int i;
+
+ if(codec == NULL || mode >= RT5670_HWEQ_LEN)
+ return -EINVAL;
+
+ dev_dbg(codec->dev, "%s(): mode=%d\n", __func__, mode);
+
+ for(i = 0; i <= EQ_REG_NUM; i++) {
+ hweq_param[mode].reg[i] = eqreg[channel][i];
+ }
+
+ for(i = 0; i <= EQ_REG_NUM; i++) {
+ if(hweq_param[mode].reg[i])
+ ioctl_ops->index_write(codec, hweq_param[mode].reg[i],
+ hweq_param[mode].value[i]);
+ else
+ break;
+ }
+ snd_soc_update_bits(codec, RT5670_EQ_CTRL2, RT5670_EQ_CTRL_MASK,
+ hweq_param[mode].ctrl);
+ snd_soc_update_bits(codec, RT5670_EQ_CTRL1,
+ RT5670_EQ_UPD, RT5670_EQ_UPD);
+ snd_soc_update_bits(codec, RT5670_EQ_CTRL1, RT5670_EQ_UPD, 0);
+
+ return 0;
+}
+
+int rt5670_ioctl_common(struct snd_hwdep *hw, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct snd_soc_codec *codec = hw->private_data;
+ struct rt_codec_cmd __user *_rt_codec = (struct rt_codec_cmd *)arg;
+ struct rt_codec_cmd rt_codec;
+ //struct rt_codec_ops *ioctl_ops = rt_codec_get_ioctl_ops();
+ int *buf;
+ static int eq_mode[EQ_CH_NUM];
+
+ if (copy_from_user(&rt_codec, _rt_codec, sizeof(rt_codec))) {
+ dev_err(codec->dev,"copy_from_user faild\n");
+ return -EFAULT;
+ }
+ dev_dbg(codec->dev, "%s(): rt_codec.number=%d, cmd=%d\n",
+ __func__, rt_codec.number, cmd);
+ buf = kmalloc(sizeof(*buf) * rt_codec.number, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+ if (copy_from_user(buf, rt_codec.buf, sizeof(*buf) * rt_codec.number)) {
+ goto err;
+ }
+
+ switch (cmd) {
+ case RT_SET_CODEC_HWEQ_IOCTL:
+ if (eq_mode == *buf)
+ break;
+ eq_mode[*buf] = *(buf + 1);
+ rt5670_update_eqmode(codec, eq_mode[*buf], *buf);
+ break;
+
+ case RT_GET_CODEC_ID:
+ *buf = snd_soc_read(codec, RT5670_VENDOR_ID2);
+ if (copy_to_user(rt_codec.buf, buf, sizeof(*buf) * rt_codec.number))
+ goto err;
+ break;
+ case RT_READ_CODEC_DSP_IOCTL:
+ case RT_WRITE_CODEC_DSP_IOCTL:
+ case RT_GET_CODEC_DSP_MODE_IOCTL:
+ return rt5670_dsp_ioctl_common(hw, file, cmd, arg);
+ break;
+ default:
+ break;
+ }
+
+ kfree(buf);
+ return 0;
+
+err:
+ kfree(buf);
+ return -EFAULT;
+}
+EXPORT_SYMBOL_GPL(rt5670_ioctl_common);
diff --git a/sound/soc/codecs/rt5670_ioctl.h b/sound/soc/codecs/rt5670_ioctl.h
new file mode 100644
index 00000000..dda20b19
--- /dev/null
+++ b/sound/soc/codecs/rt5670_ioctl.h
@@ -0,0 +1,46 @@
+/*
+ * rt5670_ioctl.h -- RT5670 ALSA SoC audio driver IO control
+ *
+ * Copyright 2012 Realtek Microelectronics
+ * Author: Bard <bardliao@realtek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __RT5670_IOCTL_H__
+#define __RT5670_IOCTL_H__
+
+#include <sound/hwdep.h>
+#include <linux/ioctl.h>
+
+enum {
+ NORMAL=0,
+ SPK,
+ HP,
+ MODE_NUM,
+};
+
+enum {
+ EQ_CH_DACL=0,
+ EQ_CH_DACR,
+ EQ_CH_ADC,
+ EQ_CH_NUM,
+};
+
+
+
+#define EQ_REG_NUM 28
+typedef struct hweq_s {
+ unsigned int reg[EQ_REG_NUM];
+ unsigned int value[EQ_REG_NUM];
+ unsigned int ctrl;
+} hweq_t;
+
+int rt5670_ioctl_common(struct snd_hwdep *hw, struct file *file,
+ unsigned int cmd, unsigned long arg);
+int rt5670_update_eqmode(
+ struct snd_soc_codec *codec, int channel, int mode);
+
+#endif /* __RT5670_IOCTL_H__ */
diff --git a/sound/soc/codecs/rt_codec_ioctl.c b/sound/soc/codecs/rt_codec_ioctl.c
new file mode 100644
index 00000000..f51bb0f2
--- /dev/null
+++ b/sound/soc/codecs/rt_codec_ioctl.c
@@ -0,0 +1,183 @@
+/*
+ * rt_codec_ioctl.h -- RT56XX ALSA SoC audio driver IO control
+ *
+ * Copyright 2012 Realtek Microelectronics
+ * Author: Bard <bardliao@realtek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#define DEBUG 1
+#include <linux/spi/spi.h>
+#include <sound/soc.h>
+#include "rt_codec_ioctl.h"
+
+static struct rt_codec_ops rt_codec_ioctl_ops;
+
+#if defined(CONFIG_SND_HWDEP) || defined(CONFIG_SND_HWDEP_MODULE)
+#define RT_CE_CODEC_HWDEP_NAME "rt_codec hwdep "
+static int rt_codec_hwdep_open(struct snd_hwdep *hw, struct file *file)
+{
+ struct snd_soc_codec *codec = hw->private_data;
+ dev_dbg(codec->dev, "%s()\n", __func__);
+ return 0;
+}
+
+static int rt_codec_hwdep_release(struct snd_hwdep *hw, struct file *file)
+{
+ struct snd_soc_codec *codec = hw->private_data;
+ dev_dbg(codec->dev, "%s()\n", __func__);
+ return 0;
+}
+
+static int rt_codec_hwdep_ioctl_common(struct snd_hwdep *hw,
+ struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct snd_soc_codec *codec = hw->private_data;
+ struct rt_codec_cmd __user *_rt_codec = (struct rt_codec_cmd *)arg;
+ struct rt_codec_cmd rt_codec;
+ int *buf, *p;
+
+ if (copy_from_user(&rt_codec, _rt_codec, sizeof(rt_codec))) {
+ dev_err(codec->dev,"copy_from_user faild\n");
+ return -EFAULT;
+ }
+ dev_dbg(codec->dev, "%s(): rt_codec.number=%d, cmd=%d\n",
+ __func__, rt_codec.number, cmd);
+ buf = kmalloc(sizeof(*buf) * rt_codec.number, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+ if (copy_from_user(buf, rt_codec.buf, sizeof(*buf) * rt_codec.number)) {
+ goto err;
+ }
+
+ switch (cmd) {
+ case RT_READ_CODEC_REG_IOCTL:
+ for (p = buf; p < buf + rt_codec.number / 2; p++) {
+ *(p + rt_codec.number / 2) = snd_soc_read(codec, *p);
+ }
+ if (copy_to_user(rt_codec.buf, buf, sizeof(*buf) * rt_codec.number))
+ goto err;
+ break;
+
+ case RT_WRITE_CODEC_REG_IOCTL:
+ for (p = buf; p < buf + rt_codec.number / 2; p++)
+ snd_soc_write(codec, *p, *(p + rt_codec.number / 2));
+ break;
+
+ case RT_READ_CODEC_INDEX_IOCTL:
+ if (NULL == rt_codec_ioctl_ops.index_read)
+ goto err;
+
+ for (p = buf; p < buf + rt_codec.number / 2; p++)
+ *(p+rt_codec.number/2) = rt_codec_ioctl_ops.index_read(
+ codec, *p);
+ if (copy_to_user(rt_codec.buf, buf,
+ sizeof(*buf) * rt_codec.number))
+ goto err;
+ break;
+
+ case RT_WRITE_CODEC_INDEX_IOCTL:
+ if (NULL == rt_codec_ioctl_ops.index_write)
+ goto err;
+
+ for (p = buf; p < buf + rt_codec.number / 2; p++)
+ {
+ dev_dbg(codec->dev, "%x , %x\n",
+ *p,*(p+rt_codec.number/2));
+ rt_codec_ioctl_ops.index_write(codec, *p,
+ *(p+rt_codec.number/2));
+ }
+ break;
+
+ default:
+ if (NULL == rt_codec_ioctl_ops.ioctl_common)
+ goto err;
+
+ rt_codec_ioctl_ops.ioctl_common(hw, file, cmd, arg);
+ break;
+ }
+
+ kfree(buf);
+ return 0;
+
+err:
+ kfree(buf);
+ return -EFAULT;
+}
+
+static int rt_codec_codec_dump_reg(struct snd_hwdep *hw,
+ struct file *file, unsigned long arg)
+{
+ struct snd_soc_codec *codec = hw->private_data;
+ struct rt_codec_cmd __user *_rt_codec =(struct rt_codec_cmd *)arg;
+ struct rt_codec_cmd rt_codec;
+ int i, *buf, number = codec->driver->reg_cache_size;
+
+ dev_dbg(codec->dev, "enter %s, number = %d\n", __func__, number);
+ if (copy_from_user(&rt_codec, _rt_codec, sizeof(rt_codec)))
+ return -EFAULT;
+
+ buf = kmalloc(sizeof(*buf) * number, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+
+ for (i = 0; i < number/2; i++) {
+ buf[i] = i << 1;
+ buf[i + number / 2] = codec->read(codec, buf[i]);
+ }
+ if (copy_to_user(rt_codec.buf, buf, sizeof(*buf) * i))
+ goto err;
+ rt_codec.number = number;
+ if (copy_to_user(_rt_codec, &rt_codec, sizeof(rt_codec)))
+ goto err;
+ kfree(buf);
+ return 0;
+
+err:
+ kfree(buf);
+ return -EFAULT;
+}
+
+static int rt_codec_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ switch (cmd) {
+ case RT_READ_ALL_CODEC_REG_IOCTL:
+ return rt_codec_codec_dump_reg(hw, file, arg);
+
+ default:
+ return rt_codec_hwdep_ioctl_common(hw, file, cmd, arg);
+ }
+
+ return 0;
+}
+
+int realtek_ce_init_hwdep(struct snd_soc_codec *codec)
+{
+ struct snd_hwdep *hw;
+ struct snd_card *card = codec->card->snd_card;
+ int err;
+
+ dev_dbg(codec->dev, "enter %s\n", __func__);
+
+ if ((err = snd_hwdep_new(card, RT_CE_CODEC_HWDEP_NAME, 0, &hw)) < 0)
+ return err;
+
+ strcpy(hw->name, RT_CE_CODEC_HWDEP_NAME);
+ hw->private_data = codec;
+ hw->ops.open = rt_codec_hwdep_open;
+ hw->ops.release = rt_codec_hwdep_release;
+ hw->ops.ioctl = rt_codec_hwdep_ioctl;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(realtek_ce_init_hwdep);
+#endif
+
+struct rt_codec_ops *rt_codec_get_ioctl_ops(void)
+{
+ return &rt_codec_ioctl_ops;
+}
+EXPORT_SYMBOL_GPL(rt_codec_get_ioctl_ops);
diff --git a/sound/soc/codecs/rt_codec_ioctl.h b/sound/soc/codecs/rt_codec_ioctl.h
new file mode 100644
index 00000000..56daa371
--- /dev/null
+++ b/sound/soc/codecs/rt_codec_ioctl.h
@@ -0,0 +1,78 @@
+/*
+ * rt_codec_ioctl.h -- RT56XX ALSA SoC audio driver IO control
+ *
+ * Copyright 2012 Realtek Microelectronics
+ * Author: Bard <bardliao@realtek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __RT56XX_IOCTL_H__
+#define __RT56XX_IOCTL_H__
+
+#include <sound/hwdep.h>
+#include <linux/ioctl.h>
+
+struct rt_codec_cmd {
+ size_t number;
+ int __user *buf;
+};
+
+struct rt_codec_ops {
+ int (*index_write)(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value);
+ unsigned int (*index_read)(struct snd_soc_codec *codec,
+ unsigned int reg);
+ int (*index_update_bits)(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int mask, unsigned int value);
+ int (*ioctl_common)(struct snd_hwdep *hw, struct file *file,
+ unsigned int cmd, unsigned long arg);
+};
+
+enum {
+ RT_READ_CODEC_REG_IOCTL = _IOR('R', 0x01, struct rt_codec_cmd),
+ RT_WRITE_CODEC_REG_IOCTL = _IOW('R', 0x01, struct rt_codec_cmd),
+ RT_READ_ALL_CODEC_REG_IOCTL = _IOR('R', 0x02, struct rt_codec_cmd),
+ RT_READ_CODEC_INDEX_IOCTL = _IOR('R', 0x03, struct rt_codec_cmd),
+ RT_WRITE_CODEC_INDEX_IOCTL = _IOW('R', 0x03, struct rt_codec_cmd),
+ RT_READ_CODEC_DSP_IOCTL = _IOR('R', 0x04, struct rt_codec_cmd),
+ RT_WRITE_CODEC_DSP_IOCTL = _IOW('R', 0x04, struct rt_codec_cmd),
+ RT_SET_CODEC_HWEQ_IOCTL = _IOW('R', 0x05, struct rt_codec_cmd),
+ RT_GET_CODEC_HWEQ_IOCTL = _IOR('R', 0x05, struct rt_codec_cmd),
+ RT_SET_CODEC_SPK_VOL_IOCTL = _IOW('R', 0x06, struct rt_codec_cmd),
+ RT_GET_CODEC_SPK_VOL_IOCTL = _IOR('R', 0x06, struct rt_codec_cmd),
+ RT_SET_CODEC_MIC_GAIN_IOCTL = _IOW('R', 0x07, struct rt_codec_cmd),
+ RT_GET_CODEC_MIC_GAIN_IOCTL = _IOR('R', 0x07, struct rt_codec_cmd),
+ RT_SET_CODEC_3D_SPK_IOCTL = _IOW('R', 0x08, struct rt_codec_cmd),
+ RT_GET_CODEC_3D_SPK_IOCTL = _IOR('R', 0x08, struct rt_codec_cmd),
+ RT_SET_CODEC_MP3PLUS_IOCTL = _IOW('R', 0x09, struct rt_codec_cmd),
+ RT_GET_CODEC_MP3PLUS_IOCTL = _IOR('R', 0x09, struct rt_codec_cmd),
+ RT_SET_CODEC_3D_HEADPHONE_IOCTL = _IOW('R', 0x0a, struct rt_codec_cmd),
+ RT_GET_CODEC_3D_HEADPHONE_IOCTL = _IOR('R', 0x0a, struct rt_codec_cmd),
+ RT_SET_CODEC_BASS_BACK_IOCTL = _IOW('R', 0x0b, struct rt_codec_cmd),
+ RT_GET_CODEC_BASS_BACK_IOCTL = _IOR('R', 0x0b, struct rt_codec_cmd),
+ RT_SET_CODEC_DIPOLE_SPK_IOCTL = _IOW('R', 0x0c, struct rt_codec_cmd),
+ RT_GET_CODEC_DIPOLE_SPK_IOCTL = _IOR('R', 0x0c, struct rt_codec_cmd),
+ RT_SET_CODEC_DRC_AGC_ENABLE_IOCTL = _IOW('R', 0x0d, struct rt_codec_cmd),
+ RT_GET_CODEC_DRC_AGC_ENABLE_IOCTL = _IOR('R', 0x0d, struct rt_codec_cmd),
+ RT_SET_CODEC_DSP_MODE_IOCTL = _IOW('R', 0x0e, struct rt_codec_cmd),
+ RT_GET_CODEC_DSP_MODE_IOCTL = _IOR('R', 0x0e, struct rt_codec_cmd),
+ RT_SET_CODEC_WNR_ENABLE_IOCTL = _IOW('R', 0x0f, struct rt_codec_cmd),
+ RT_GET_CODEC_WNR_ENABLE_IOCTL = _IOR('R', 0x0f, struct rt_codec_cmd),
+ RT_SET_CODEC_DRC_AGC_PAR_IOCTL = _IOW('R', 0x10, struct rt_codec_cmd),
+ RT_GET_CODEC_DRC_AGC_PAR_IOCTL = _IOR('R', 0x10, struct rt_codec_cmd),
+ RT_SET_CODEC_DIGI_BOOST_GAIN_IOCTL = _IOW('R', 0x11, struct rt_codec_cmd),
+ RT_GET_CODEC_DIGI_BOOST_GAIN_IOCTL = _IOR('R', 0x11, struct rt_codec_cmd),
+ RT_SET_CODEC_NOISE_GATE_IOCTL = _IOW('R', 0x12, struct rt_codec_cmd),
+ RT_GET_CODEC_NOISE_GATE_IOCTL = _IOR('R', 0x12, struct rt_codec_cmd),
+ RT_SET_CODEC_DRC_AGC_COMP_IOCTL = _IOW('R', 0x13, struct rt_codec_cmd),
+ RT_GET_CODEC_DRC_AGC_COMP_IOCTL = _IOR('R', 0x13, struct rt_codec_cmd),
+ RT_GET_CODEC_ID = _IOR('R', 0x30, struct rt_codec_cmd),
+};
+
+int realtek_ce_init_hwdep(struct snd_soc_codec *codec);
+struct rt_codec_ops *rt_codec_get_ioctl_ops(void);
+
+#endif /* __RT56XX_IOCTL_H__ */
diff --git a/sound/soc/codecs/tlv320adc3xxx_amb.c b/sound/soc/codecs/tlv320adc3xxx_amb.c
new file mode 100644
index 00000000..a914fdd4
--- /dev/null
+++ b/sound/soc/codecs/tlv320adc3xxx_amb.c
@@ -0,0 +1,1215 @@
+/*
+ * sound/soc/codecs/tlv320adc3xxx_amb.c
+ *
+ * Author: Dongge wu <dgwu@ambarella.com>
+ *
+ * History:
+ * 2015/10/28 - [Dongge wu] Created file
+ *
+ * Copyright (C) 2014-2018, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+
+/***************************** INCLUDES ************************************/
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/cdev.h>
+#include <linux/of_gpio.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+
+#include "tlv320adc3xxx_amb.h"
+
+/*
+ * ****************************************************************************
+ * Macros
+ * ****************************************************************************
+ *
+ */
+
+
+/* codec private data */
+struct adc3xxx_priv {
+ void *control_data;
+ unsigned int rst_pin;
+ unsigned int rst_active;
+ unsigned int sysclk;
+ int master;
+ u8 page_no;
+};
+
+static int adc3xxx_set_bias_level(struct snd_soc_codec *,
+ enum snd_soc_bias_level);
+/*
+ * ADC3xxx register cache
+ * We can't read the ADC3xxx register space when we are
+ * using 2 wire for device control, so we cache them instead.
+ * There is no point in caching the reset register
+ */
+static const u8 adc3xxx_reg[ADC3xxx_CACHEREGNUM] = {
+ 0x00, 0x00, 0x00, 0x00, /* 0 */
+ 0x00, 0x11, 0x04, 0x00, /* 4 */
+ 0x00, 0x00, 0x00, 0x00, /* 8 */
+ 0x00, 0x00, 0x00, 0x00, /* 12 */
+ 0x00, 0x00, 0x01, 0x01, /* 16 */
+ 0x80, 0x80, 0x04, 0x00, /* 20 */
+ 0x00, 0x00, 0x01, 0x00, /* 24 */
+ 0x00, 0x02, 0x01, 0x00, /* 28 */
+ 0x00, 0x10, 0x00, 0x00, /* 32 */
+ 0x00, 0x00, 0x02, 0x00, /* 36 */
+ 0x00, 0x00, 0x00, 0x00, /* 40 */
+ 0x00, 0x00, 0x00, 0x00, /* 44 */
+ 0x00, 0x00, 0x00, 0x00, /* 48 */
+ 0x00, 0x12, 0x00, 0x00, /* 52 */
+ 0x00, 0x00, 0x00, 0x44, /* 56 */
+ 0x00, 0x01, 0x00, 0x00, /* 60 */
+ 0x00, 0x00, 0x00, 0x00, /* 64 */
+ 0x00, 0x00, 0x00, 0x00, /* 68 */
+ 0x00, 0x00, 0x00, 0x00, /* 72 */
+ 0x00, 0x00, 0x00, 0x00, /* 76 */
+ 0x00, 0x00, 0x88, 0x00, /* 80 */
+ 0x00, 0x00, 0x00, 0x00, /* 84 */
+ 0x7F, 0x00, 0x00, 0x00, /* 88 */
+ 0x00, 0x00, 0x00, 0x00, /* 92 */
+ 0x7F, 0x00, 0x00, 0x00, /* 96 */
+ 0x00, 0x00, 0x00, 0x00, /* 100 */
+ 0x00, 0x00, 0x00, 0x00, /* 104 */
+ 0x00, 0x00, 0x00, 0x00, /* 108 */
+ 0x00, 0x00, 0x00, 0x00, /* 112 */
+ 0x00, 0x00, 0x00, 0x00, /* 116 */
+ 0x00, 0x00, 0x00, 0x00, /* 120 */
+ 0x00, 0x00, 0x00, 0x00, /* 124 - PAGE0 Registers(127) ends here */
+ 0x00, 0x00, 0x00, 0x00, /* 128, PAGE1-0 */
+ 0x00, 0x00, 0x00, 0x00, /* 132, PAGE1-4 */
+ 0x00, 0x00, 0x00, 0x00, /* 136, PAGE1-8 */
+ 0x00, 0x00, 0x00, 0x00, /* 140, PAGE1-12 */
+ 0x00, 0x00, 0x00, 0x00, /* 144, PAGE1-16 */
+ 0x00, 0x00, 0x00, 0x00, /* 148, PAGE1-20 */
+ 0x00, 0x00, 0x00, 0x00, /* 152, PAGE1-24 */
+ 0x00, 0x00, 0x00, 0x00, /* 156, PAGE1-28 */
+ 0x00, 0x00, 0x00, 0x00, /* 160, PAGE1-32 */
+ 0x00, 0x00, 0x00, 0x00, /* 164, PAGE1-36 */
+ 0x00, 0x00, 0x00, 0x00, /* 168, PAGE1-40 */
+ 0x00, 0x00, 0x00, 0x00, /* 172, PAGE1-44 */
+ 0x00, 0x00, 0x00, 0x00, /* 176, PAGE1-48 */
+ 0xFF, 0x00, 0x3F, 0xFF, /* 180, PAGE1-52 */
+ 0x00, 0x3F, 0x00, 0x80, /* 184, PAGE1-56 */
+ 0x80, 0x00, 0x00, 0x00, /* 188, PAGE1-60 */
+};
+
+/*
+ * adc3xxx initialization data
+ * This structure initialization contains the initialization required for
+ * ADC3xxx.
+ * These registers values (reg_val) are written into the respective ADC3xxx
+ * register offset (reg_offset) to initialize ADC3xxx.
+ * These values are used in adc3xxx_init() function only.
+ */
+struct adc3xxx_configs {
+ u8 reg_offset;
+ u8 reg_val;
+};
+
+/* The global Register Initialization sequence Array. During the Audio Driver
+ * Initialization, this array will be utilized to perform the default
+ * initialization of the audio Driver.
+ */
+static const struct adc3xxx_configs adc3xxx_reg_init[] = {
+ /* Select IN1L/IN1R Single Ended (0dB) inputs
+ * use value 10 for no connection, this enables dapm
+ * to switch ON/OFF inputs using MS Bit only.
+ * with this setup, -6dB input option is not used.
+ */
+ {LEFT_PGA_SEL_1, 0xA8},
+ {LEFT_PGA_SEL_2, 0x37},
+ {RIGHT_PGA_SEL_1, 0x28},
+ /* mute Left PGA + default gain */
+ {LEFT_APGA_CTRL, 0xc6},
+ /* mute Right PGA + default gain */
+ {RIGHT_APGA_CTRL, 0xc6},
+ {LEFT_CHN_AGC_1, 0x80},
+ {RIGHT_CHN_AGC_1, 0x80},
+ /* MICBIAS1=2.5V, MICBIAS2=2.5V */
+ {MICBIAS_CTRL, 0x50},
+ /* Use PLL for generating clocks from MCLK */
+ {CLKGEN_MUX, USE_PLL},
+ /* I2S, 16LE, codec as Master */
+ {INTERFACE_CTRL_1, 0x0C},
+ /*BDIV_CLKIN = ADC_CLK, BCLK & WCLK active when power-down */
+ {INTERFACE_CTRL_2, 0x02},
+
+ #ifdef ADC3101_CODEC_SUPPORT
+ /* Use Primary BCLK and WCLK */
+ {INTERFACE_CTRL_4, 0x0},
+ #endif
+
+ /* Left AGC Maximum Gain to 40db */
+ {LEFT_CHN_AGC_3, 0x50},
+ /* Right AGC Maximum Gain to 40db */
+ {RIGHT_CHN_AGC_3, 0X50},
+ /* ADC control, Gain soft-stepping disabled */
+ {ADC_DIGITAL, 0x02},
+ /* Fine Gain 0dB, Left/Right ADC Unmute */
+ {ADC_FGA, 0x00},
+
+ #ifdef ADC3101_CODEC_SUPPORT
+ /* DMCLK output = ADC_MOD_CLK */
+ {GPIO2_CTRL, 0x28},
+ /* DMDIN is in Dig_Mic_In mode */
+ {GPIO1_CTRL, 0x04},
+ #endif
+};
+
+/*
+ * PLL and Clock settings
+ */
+static const struct adc3xxx_rate_divs adc3xxx_divs[] = {
+ /* mclk, rate, p, r, j, d, nadc, madc, aosr, bdiv */
+ /* 8k rate */
+ {12288000, 8000, 1, 1, 7, 0000, 42, 2, 128, 8, 188},
+ /* 11.025k rate */
+ //{12000000, 11025, 1, 1, 6, 8208, 29, 2, 128, 8, 188},
+ /* 16k rate */
+ {12288000, 16000, 1, 1, 7, 0000, 21, 2, 128, 8, 188},
+ /* 22.05k rate */
+ //{12000000, 22050, 1, 1, 7, 560, 15, 2, 128, 8, 188},
+ /* 32k rate */
+ {12288000, 32000, 1, 1, 8, 0000, 12, 2, 128, 8, 188},
+ /* 44.1k rate */
+ //{12000000, 44100, 1, 1, 7, 5264, 8, 2, 128, 8, 188},
+ /* 48k rate */
+ {12288000, 48000, 1, 1, 7, 0000, 7, 2, 128, 8, 188},
+ /* 88.2k rate */
+ //{12000000, 88200, 1, 1, 7, 5264, 4, 4, 64, 8, 188},
+ /* 96k rate */
+ //{12000000, 96000, 1, 1, 8, 1920, 4, 4, 64, 8, 188},
+};
+
+/*
+ *----------------------------------------------------------------------------
+ * Function : adc3xxx_get_divs
+ * Purpose : This function is to get required divisor from the "adc3xxx_divs"
+ * table.
+ *
+ *----------------------------------------------------------------------------
+ */
+static inline int adc3xxx_get_divs(int mclk, int rate)
+{
+ int i;
+
+ printk(KERN_INFO "adc3xxx_get_divs mclk = %d, rate = %d\n", mclk, rate);
+ for (i = 0; i < ARRAY_SIZE(adc3xxx_divs); i++) {
+ if ((adc3xxx_divs[i].rate == rate)
+ && (adc3xxx_divs[i].mclk == mclk)) {
+ return i;
+ }
+ }
+
+ printk("Master clock and sample rate is not supported\n");
+ return -EINVAL;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * Function : adc3xxx_change_page
+ * Purpose : This function is to switch between page 0 and page 1.
+ *
+ *----------------------------------------------------------------------------
+ */
+int adc3xxx_change_page(struct snd_soc_codec *codec, u8 new_page)
+{
+ struct adc3xxx_priv *adc3xxx = snd_soc_codec_get_drvdata(codec);
+
+ if (i2c_smbus_write_byte_data(codec->control_data, 0x0, new_page) < 0) {
+ printk("adc3xxx_change_page: I2C Wrte Error\n");
+ return -1;
+ }
+ adc3xxx->page_no = new_page;
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * Function : adc3xxx_write_reg_cache
+ * Purpose : This function is to write adc3xxx register cache
+ *
+ *----------------------------------------------------------------------------
+ */
+static inline void adc3xxx_write_reg_cache(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value)
+{
+ u8 *cache = codec->reg_cache;
+ if (reg >= ADC3xxx_CACHEREGNUM)
+ return;
+ cache[reg] = value & 0xFF;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * Function : adc3xxx_read_reg_cache
+ * Purpose : This function is to read adc3xxx register cache
+ *
+ *----------------------------------------------------------------------------
+ */
+static inline unsigned int adc3xxx_read_reg_cache(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ u8 *cache = codec->reg_cache;
+ if (reg >= ADC3xxx_CACHEREGNUM)
+ return -1;
+ return cache[reg];
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * Function : adc3xxx_write
+ * Purpose : This function is to write to the adc3xxx register space.
+ *
+ *----------------------------------------------------------------------------
+ */
+int adc3xxx_write(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int value)
+{
+ struct adc3xxx_priv *adc3xxx = snd_soc_codec_get_drvdata(codec);
+ u8 data[2];
+ u8 page;
+
+ page = reg / ADC3xxx_PAGE_SIZE;
+
+ if (adc3xxx->page_no != page) {
+ adc3xxx_change_page(codec, page);
+ }
+
+ /* data is
+ * D15..D8 adc3xxx register offset
+ * D7...D0 register data
+ */
+ data[0] = reg % ADC3xxx_PAGE_SIZE;
+ data[1] = value & 0xFF;
+
+ if (i2c_smbus_write_byte_data(codec->control_data, data[0], data[1]) < 0) {
+ printk("adc3xxx_write: I2C write Error\n");
+ return -EIO;
+ }
+
+ /* Update register cache */
+ if ((page == 0) || (page == 1)) {
+ adc3xxx_write_reg_cache(codec, reg, data[1]);
+ }
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * Function : adc3xxx_read
+ * Purpose : This function is to read the adc3xxx register space.
+ *
+ *----------------------------------------------------------------------------
+ */
+static int adc3xxx_read(struct snd_soc_codec *codec, unsigned int reg)
+{
+ struct adc3xxx_priv *adc3xxx = snd_soc_codec_get_drvdata(codec);
+ u8 value, page;
+
+ page = reg / ADC3xxx_PAGE_SIZE;
+ if (adc3xxx->page_no != page) {
+ adc3xxx_change_page(codec, page);
+ }
+
+ /* write register address */
+ reg = reg % ADC3xxx_PAGE_SIZE;
+
+ /* read register value */
+ value = i2c_smbus_read_word_data(codec->control_data, reg);
+ if (value < 0) {
+ printk("adc3xxx_read: I2C read Error\n");
+ return -EIO;
+ }
+
+ /* Update register cache */
+ if ((page == 0) || (page == 1)) {
+ adc3xxx_write_reg_cache(codec, reg, value);
+ }
+ return value;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * Function : snd_soc_adc3xxx_put_volsw
+ * Purpose : Callback to set the value of a mixer control.
+ *
+ *----------------------------------------------------------------------------
+ */
+static int snd_soc_adc3xxx_put_volsw(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ s8 val1, val2;
+ u8 reg;
+
+ val1 = ucontrol->value.integer.value[0];
+ val2 = ucontrol->value.integer.value[1];
+
+ if ((val1 >= ADC_POS_VOL)) {
+ if (val1 > ADC_MAX_VOLUME)
+ val1 = ADC_MAX_VOLUME;
+ val1 = val1 - ADC_POS_VOL;
+ } else if ((val1 >= 0) && (val1 <= 23)) {
+ val1 = ADC_POS_VOL - val1;
+ val1 = 128 - val1;
+ } else
+ return -EINVAL;
+
+ if (val2 >= ADC_POS_VOL) {
+ if (val2 > ADC_MAX_VOLUME)
+ val2 = ADC_MAX_VOLUME;
+ val2 = val2 - ADC_POS_VOL;
+ } else if ((val2 >= 0) && (val2 <= 23)) {
+ val2 = ADC_POS_VOL - val2;
+ val2 = 128 - val2;
+ } else
+ return -EINVAL;
+
+ reg = adc3xxx_read_reg_cache(codec, LADC_VOL) & (~0x7F);
+ adc3xxx_write(codec, LADC_VOL, reg | (val1 << 0));
+ reg = adc3xxx_read_reg_cache(codec, RADC_VOL) & (~0x7F);
+ adc3xxx_write(codec, RADC_VOL, reg | (val2 << 0));
+
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * Function : snd_soc_adc3xxx_get_volsw
+ * Purpose : Callback to get the value of a mixer control.
+ *
+ *----------------------------------------------------------------------------
+ */
+static int snd_soc_adc3xxx_get_volsw(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ u8 val1;
+ u8 val2;
+
+ val1 = adc3xxx_read_reg_cache(codec, LADC_VOL) & (0x7F);
+ if ((val1 >= 0) && (val1 <= 40)) {
+ val1 = val1 + ADC_POS_VOL;
+ } else if ((val1 >= 104) && (val1 <= 127)) {
+ val1 = val1 - 104;
+ } else
+ return -EINVAL;
+
+ val2 = adc3xxx_read_reg_cache(codec, RADC_VOL) & (0x7F);
+ if ((val2 >= 0) && (val2 <= 40)) {
+ val2 = val2 + ADC_POS_VOL;
+ } else if ((val2 >= 104) && (val2 <= 127)) {
+ val2 = val2 - 104;
+ } else
+ return -EINVAL;
+
+ ucontrol->value.integer.value[0] = val1;
+ ucontrol->value.integer.value[1] = val2;
+ return 0;
+
+}
+
+#define SOC_ADC3xxx_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
+ .get = snd_soc_adc3xxx_get_volsw, .put = snd_soc_adc3xxx_put_volsw, \
+ .private_value = (unsigned long)&(struct soc_mixer_control) \
+ {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
+ .max = xmax, .invert = xinvert} }
+
+static const char *micbias_voltage[] = { "off", "2V", "2.5V", "AVDD" };
+static const char *linein_attenuation[] = { "0db", "-6db" };
+static const char *adc_softstepping[] = { "1 step", "2 step", "off" };
+
+#define MICBIAS1_ENUM 0
+#define MICBIAS2_ENUM 1
+#define ATTLINEL1_ENUM 2
+#define ATTLINEL2_ENUM 3
+#define ATTLINEL3_ENUM 4
+#define ATTLINER1_ENUM 5
+#define ATTLINER2_ENUM 6
+#define ATTLINER3_ENUM 7
+#define ADCSOFTSTEP_ENUM 8
+
+/* Creates an array of the Single Ended Widgets*/
+static const struct soc_enum adc3xxx_enum[] = {
+ SOC_ENUM_SINGLE(MICBIAS_CTRL, 5, 4, micbias_voltage),
+ SOC_ENUM_SINGLE(MICBIAS_CTRL, 3, 4, micbias_voltage),
+ SOC_ENUM_SINGLE(LEFT_PGA_SEL_1, 0, 2, linein_attenuation),
+ SOC_ENUM_SINGLE(LEFT_PGA_SEL_1, 2, 2, linein_attenuation),
+ SOC_ENUM_SINGLE(LEFT_PGA_SEL_1, 4, 2, linein_attenuation),
+ SOC_ENUM_SINGLE(RIGHT_PGA_SEL_1, 0, 2, linein_attenuation),
+ SOC_ENUM_SINGLE(RIGHT_PGA_SEL_1, 2, 2, linein_attenuation),
+ SOC_ENUM_SINGLE(RIGHT_PGA_SEL_1, 4, 2, linein_attenuation),
+ SOC_ENUM_SINGLE(ADC_DIGITAL, 0, 3, adc_softstepping),
+};
+
+/* Various Controls For adc3xxx */
+static const struct snd_kcontrol_new adc3xxx_snd_controls[] = {
+ /* PGA Gain Volume Control */
+ SOC_DOUBLE_R("PGA Gain Volume Control (0=0dB, 80=40dB)",
+ LEFT_APGA_CTRL, RIGHT_APGA_CTRL, 0, 0x50, 0),
+ /* Audio gain control (AGC) */
+ SOC_DOUBLE_R("Audio Gain Control (AGC)", LEFT_CHN_AGC_1,
+ RIGHT_CHN_AGC_1, 7, 0x01, 0),
+ /* AGC Target level control */
+ SOC_DOUBLE_R("AGC Target Level Control", LEFT_CHN_AGC_1,
+ RIGHT_CHN_AGC_1, 4, 0x07, 1),
+ /* AGC Maximum PGA applicable */
+ SOC_DOUBLE_R("AGC Maximum PGA Control", LEFT_CHN_AGC_3,
+ RIGHT_CHN_AGC_3, 0, 0x50, 0),
+ /* AGC Attack Time control */
+ SOC_DOUBLE_R("AGC Attack Time control", LEFT_CHN_AGC_4,
+ RIGHT_CHN_AGC_4, 3, 0x1F, 0),
+ /* AGC Decay Time control */
+ SOC_DOUBLE_R("AGC Decay Time control", LEFT_CHN_AGC_5,
+ RIGHT_CHN_AGC_5, 3, 0x1F, 0),
+ /* AGC Noise Bounce control */
+ SOC_DOUBLE_R("AGC Noise bounce control", LEFT_CHN_AGC_6,
+ RIGHT_CHN_AGC_6, 0, 0x1F, 0),
+ /* AGC Signal Bounce control */
+ SOC_DOUBLE_R("AGC Signal bounce control", LEFT_CHN_AGC_7,
+ RIGHT_CHN_AGC_7, 0, 0x0F, 0),
+ /* Mic Bias voltage */
+ SOC_ENUM("Mic Bias 1 Voltage", adc3xxx_enum[MICBIAS1_ENUM]),
+ SOC_ENUM("Mic Bias 2 Voltage", adc3xxx_enum[MICBIAS2_ENUM]),
+ /* ADC soft stepping */
+ SOC_ENUM("ADC soft stepping", adc3xxx_enum[ADCSOFTSTEP_ENUM]),
+ /* Left/Right Input attenuation */
+ SOC_ENUM("Left Linein1 input attenuation",
+ adc3xxx_enum[ATTLINEL1_ENUM]),
+ SOC_ENUM("Left Linein2 input attenuation",
+ adc3xxx_enum[ATTLINEL2_ENUM]),
+ SOC_ENUM("Left Linein3 input attenuation",
+ adc3xxx_enum[ATTLINEL3_ENUM]),
+ SOC_ENUM("Right Linein1 input attenuation",
+ adc3xxx_enum[ATTLINER1_ENUM]),
+ SOC_ENUM("Right Linein2 input attenuation",
+ adc3xxx_enum[ATTLINER2_ENUM]),
+ SOC_ENUM("Right Linein3 input attenuation",
+ adc3xxx_enum[ATTLINER3_ENUM]),
+ /* ADC Volume */
+ SOC_ADC3xxx_DOUBLE_R("ADC Volume Control (0=-12dB, 64=+20dB)", LADC_VOL,
+ RADC_VOL, 0, 64,0),
+ /* ADC Fine Volume */
+ SOC_SINGLE("Left ADC Fine Volume (0=-0.4dB, 4=0dB)", ADC_FGA, 4, 4, 1),
+ SOC_SINGLE("Right ADC Fine Volume (0=-0.4dB, 4=0dB)", ADC_FGA, 0, 4, 1),
+};
+
+/* Left input selection, Single Ended inputs and Differential inputs */
+static const struct snd_kcontrol_new left_input_mixer_controls[] = {
+ SOC_DAPM_SINGLE("IN1_L switch", LEFT_PGA_SEL_1, 1, 0x1, 1),
+ SOC_DAPM_SINGLE("IN2_L switch", LEFT_PGA_SEL_1, 3, 0x1, 1),
+ SOC_DAPM_SINGLE("IN3_L switch", LEFT_PGA_SEL_1, 5, 0x1, 1),
+ SOC_DAPM_SINGLE("DIF1_L switch", LEFT_PGA_SEL_1, 7, 0x1, 1),
+ SOC_DAPM_SINGLE("DIF2_L switch", LEFT_PGA_SEL_2, 5, 0x1, 1),
+ SOC_DAPM_SINGLE("DIF3_L switch", LEFT_PGA_SEL_2, 3, 0x1, 1), //DIF3_L
+ SOC_DAPM_SINGLE("IN1_R switch", LEFT_PGA_SEL_2, 1, 0x1, 1),
+};
+
+/* Right input selection, Single Ended inputs and Differential inputs */
+static const struct snd_kcontrol_new right_input_mixer_controls[] = {
+ SOC_DAPM_SINGLE("IN1_R switch", RIGHT_PGA_SEL_1, 1, 0x1, 1),
+ SOC_DAPM_SINGLE("IN2_R switch", RIGHT_PGA_SEL_1, 3, 0x1, 1),
+ SOC_DAPM_SINGLE("IN3_R switch", RIGHT_PGA_SEL_1, 5, 0x1, 1),
+ SOC_DAPM_SINGLE("DIF1_R switch", RIGHT_PGA_SEL_1, 7, 0x1, 1), // DIF1_R
+ SOC_DAPM_SINGLE("DIF2_R switch", RIGHT_PGA_SEL_2, 5, 0x1, 1),
+ SOC_DAPM_SINGLE("DIF3_R switch", RIGHT_PGA_SEL_2, 3, 0x1, 1),
+ SOC_DAPM_SINGLE("IN1_L switch", RIGHT_PGA_SEL_2, 1, 0x1, 1),
+};
+
+/* Left Digital Mic input for left ADC */
+static const struct snd_kcontrol_new left_input_dmic_controls[] = {
+ SOC_DAPM_SINGLE("Left ADC switch", ADC_DIGITAL, 3, 0x1, 0),
+};
+
+/* Right Digital Mic input for Right ADC */
+static const struct snd_kcontrol_new right_input_dmic_controls[] = {
+ SOC_DAPM_SINGLE("Right ADC switch", ADC_DIGITAL, 2, 0x1, 0),
+};
+
+/* adc3xxx Widget structure */
+static const struct snd_soc_dapm_widget adc3xxx_dapm_widgets[] = {
+
+ /* Left Input Selection */
+ SND_SOC_DAPM_MIXER("Left Input Selection", SND_SOC_NOPM, 0, 0,
+ &left_input_mixer_controls[0],
+ ARRAY_SIZE(left_input_mixer_controls)),
+ /* Right Input Selection */
+ SND_SOC_DAPM_MIXER("Right Input Selection", SND_SOC_NOPM, 0, 0,
+ &right_input_mixer_controls[0],
+ ARRAY_SIZE(right_input_mixer_controls)),
+ /*PGA selection */
+ SND_SOC_DAPM_PGA("Left PGA", LEFT_APGA_CTRL, 7, 1, NULL, 0),
+ SND_SOC_DAPM_PGA("Right PGA", RIGHT_APGA_CTRL, 7, 1, NULL, 0),
+
+ /*Digital Microphone Input Control for Left/Right ADC */
+ SND_SOC_DAPM_MIXER("Left DMic Input", SND_SOC_NOPM, 0, 0,
+ &left_input_dmic_controls[0],
+ ARRAY_SIZE(left_input_dmic_controls)),
+ SND_SOC_DAPM_MIXER("Right DMic Input", SND_SOC_NOPM , 0, 0,
+ &right_input_dmic_controls[0],
+ ARRAY_SIZE(right_input_dmic_controls)),
+
+ /* Left/Right ADC */
+ SND_SOC_DAPM_ADC("Left ADC", "Left Capture", ADC_DIGITAL, 7, 0),
+ SND_SOC_DAPM_ADC("Right ADC", "Right Capture", ADC_DIGITAL, 6, 0),
+
+ /* Inputs */
+ SND_SOC_DAPM_INPUT("IN1_L"),
+ SND_SOC_DAPM_INPUT("IN1_R"),
+ SND_SOC_DAPM_INPUT("IN2_L"),
+ SND_SOC_DAPM_INPUT("IN2_R"),
+ SND_SOC_DAPM_INPUT("IN3_L"),
+ SND_SOC_DAPM_INPUT("IN3_R"),
+ SND_SOC_DAPM_INPUT("DIF1_L"),
+ SND_SOC_DAPM_INPUT("DIF2_L"),
+ SND_SOC_DAPM_INPUT("DIF3_L"),
+ SND_SOC_DAPM_INPUT("DIF1_R"),
+ SND_SOC_DAPM_INPUT("DIF2_R"),
+ SND_SOC_DAPM_INPUT("DIF3_R"),
+ SND_SOC_DAPM_INPUT("DMic_L"),
+ SND_SOC_DAPM_INPUT("DMic_R"),
+
+};
+
+/* DAPM Routing related array declaratiom */
+static const struct snd_soc_dapm_route intercon[] = {
+/* Left input selection from switchs */
+ {"Left Input Selection", "IN1_L switch", "IN1_L"},
+ {"Left Input Selection", "IN2_L switch", "IN2_L"},
+ {"Left Input Selection", "IN3_L switch", "IN3_L"},
+ {"Left Input Selection", "DIF1_L switch", "DIF1_L"},
+ {"Left Input Selection", "DIF2_L switch", "DIF2_L"},
+ {"Left Input Selection", "DIF3_L switch", "DIF3_L"},
+ {"Left Input Selection", "IN1_R switch", "IN1_R"},
+
+/* Left input selection to left PGA */
+ {"Left PGA", NULL, "Left Input Selection"},
+
+/* Left PGA to left ADC */
+ {"Left ADC", NULL, "Left PGA"},
+
+/* Right input selection from switchs */
+ {"Right Input Selection", "IN1_R switch", "IN1_R"},
+ {"Right Input Selection", "IN2_R switch", "IN2_R"},
+ {"Right Input Selection", "IN3_R switch", "IN3_R"},
+ {"Right Input Selection", "DIF1_R switch", "DIF1_R"},
+ {"Right Input Selection", "DIF2_R switch", "DIF2_R"},
+ {"Right Input Selection", "DIF3_R switch", "DIF3_R"},
+ {"Right Input Selection", "IN1_L switch", "IN1_L"},
+
+/* Right input selection to right PGA */
+ {"Right PGA", NULL, "Right Input Selection"},
+
+/* Right PGA to right ADC */
+ {"Right ADC", NULL, "Right PGA"},
+
+/* Left DMic Input selection from switch */
+ {"Left DMic Input", "Left ADC switch", "DMic_L"},
+
+/* Left DMic to left ADC */
+ {"Left ADC", NULL, "Left DMic Input"},
+
+/* Right DMic Input selection from switch */
+ {"Right DMic Input", "Right ADC switch", "DMic_R"},
+
+/* Right DMic to right ADC */
+ {"Right ADC", NULL, "Right DMic Input"},
+};
+
+/*
+ *----------------------------------------------------------------------------
+ * Function : adc3xxx_hw_params
+ * Purpose : This function is to set the hardware parameters for adc3xxx.
+ * The functions set the sample rate and audio serial data word
+ * length.
+ *
+ *----------------------------------------------------------------------------
+ */
+static int adc3xxx_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct adc3xxx_priv *adc3xxx = snd_soc_codec_get_drvdata(codec);
+ int i, width = 16;
+ u8 data, bdiv;
+
+ i = adc3xxx_get_divs(adc3xxx->sysclk, params_rate(params));
+
+ if (i < 0) {
+ printk("Clock configuration is not supported\n");
+ return i;
+ }
+
+ /* select data word length */
+ data =
+ adc3xxx_read_reg_cache(codec, INTERFACE_CTRL_1) & (~WLENGTH_MASK);
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ width = 16;
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ data |= (0x01 << 4);
+ width = 20;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ data |= (0x02 << 4);
+ width = 24;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ data |= (0x03 << 4);
+ width = 32;
+ break;
+ }
+ adc3xxx_write(codec, INTERFACE_CTRL_1, data);
+
+ /* BCLK is derived from ADC_CLK */
+ if (width == 16) {
+ bdiv = adc3xxx_divs[i].bdiv_n;
+ } else {
+ bdiv =
+ (adc3xxx_divs[i].aosr * adc3xxx_divs[i].madc) / (2 * width);
+ }
+
+ /* P & R values */
+ adc3xxx_write(codec, PLL_PROG_PR,
+ (adc3xxx_divs[i].pll_p << PLLP_SHIFT) | (adc3xxx_divs[i].
+ pll_r <<
+ PLLR_SHIFT));
+ /* J value */
+ adc3xxx_write(codec, PLL_PROG_J, adc3xxx_divs[i].pll_j & PLLJ_MASK);
+ /* D value */
+ adc3xxx_write(codec, PLL_PROG_D_LSB,
+ adc3xxx_divs[i].pll_d & PLLD_LSB_MASK);
+ adc3xxx_write(codec, PLL_PROG_D_MSB,
+ (adc3xxx_divs[i].pll_d >> 8) & PLLD_MSB_MASK);
+ /* NADC */
+ adc3xxx_write(codec, ADC_NADC, adc3xxx_divs[i].nadc & NADC_MASK);
+ /* MADC */
+ adc3xxx_write(codec, ADC_MADC, adc3xxx_divs[i].madc & MADC_MASK);
+ /* AOSR */
+ adc3xxx_write(codec, ADC_AOSR, adc3xxx_divs[i].aosr & AOSR_MASK);
+ /* BDIV N Value */
+ adc3xxx_write(codec, BCLK_N_DIV, bdiv & BDIV_MASK);
+ msleep(10);
+
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * Function : adc3xxx_set_dai_sysclk
+ * Purpose : This function is to set the DAI system clock
+ *
+ *----------------------------------------------------------------------------
+ */
+static int adc3xxx_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct adc3xxx_priv *adc3xxx = snd_soc_codec_get_drvdata(codec);
+
+ adc3xxx->sysclk = freq;
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * Function : adc3xxx_set_dai_fmt
+ * Purpose : This function is to set the DAI format
+ *
+ *----------------------------------------------------------------------------
+ */
+static int adc3xxx_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct adc3xxx_priv *adc3xxx = snd_soc_codec_get_drvdata(codec);
+ u8 iface_reg;
+
+ iface_reg =
+ adc3xxx_read_reg_cache(codec, INTERFACE_CTRL_1) & (~FMT_MASK);
+
+ /* set master/slave audio interface */
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ adc3xxx->master = 1;
+ iface_reg |= BCLK_MASTER | WCLK_MASTER;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ adc3xxx->master = 0;
+ iface_reg &= ~ (BCLK_MASTER | WCLK_MASTER ); //new repladec | with &
+ break;
+ case SND_SOC_DAIFMT_CBS_CFM: //new case..just for debugging
+ printk("%s: SND_SOC_DAIFMT_CBS_CFM\n", __FUNCTION__);
+ adc3xxx->master = 0;
+ /* BCLK by codec ie BCLK output */
+ iface_reg |= (BCLK_MASTER);
+ iface_reg &= ~(WCLK_MASTER);
+
+ break;
+ default:
+ printk("Invalid DAI master/slave interface\n");
+ return -EINVAL;
+ }
+
+ /*
+ * match both interface format and signal polarities since they
+ * are fixed
+ */
+ switch (fmt & (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK)) {
+ case (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF):
+ break;
+ case (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF):
+ iface_reg |= (0x01 << 6);
+ break;
+ case (SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF):
+ iface_reg |= (0x01 << 6);
+ break;
+ case (SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_NB_NF):
+ iface_reg |= (0x02 << 6);
+ break;
+ case (SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF):
+ iface_reg |= (0x03 << 6);
+ break;
+ default:
+ printk("Invalid DAI format\n");
+ return -EINVAL;
+ }
+
+ /* set iface */
+ adc3xxx_write(codec, INTERFACE_CTRL_1, iface_reg);
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * Function : adc3xxx_set_bias_level
+ * Purpose : This function is to get triggered when dapm events occurs.
+ *
+ *----------------------------------------------------------------------------
+ */
+static int adc3xxx_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ struct adc3xxx_priv *adc3xxx = snd_soc_codec_get_drvdata(codec);
+ u8 reg;
+
+ /* Check if the New Bias level is equal to the existing one, if so return */
+ if (codec->dapm.bias_level == level)
+ return 0;
+
+ /* all power is driven by DAPM system */
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ if (adc3xxx->master) {
+ /* Enable pll */
+ reg = adc3xxx_read_reg_cache(codec, PLL_PROG_PR);
+ adc3xxx_write(codec, PLL_PROG_PR, reg | ENABLE_PLL);
+
+ /* 10msec delay needed after PLL power-up */
+ mdelay(10);
+
+ /* Switch on NADC Divider */
+ reg = adc3xxx_read_reg_cache(codec, ADC_NADC);
+ adc3xxx_write(codec, ADC_NADC, reg | ENABLE_NADC);
+
+ /* Switch on MADC Divider */
+ reg = adc3xxx_read_reg_cache(codec, ADC_MADC);
+ adc3xxx_write(codec, ADC_MADC, reg | ENABLE_MADC);
+
+ /* Switch on BCLK_N Divider */
+ reg = adc3xxx_read_reg_cache(codec, BCLK_N_DIV);
+ adc3xxx_write(codec, BCLK_N_DIV, reg | ENABLE_BCLK);
+ }
+ else{ //new
+ /* Enable pll */
+ reg = adc3xxx_read_reg_cache(codec, PLL_PROG_PR);
+ adc3xxx_write(codec, PLL_PROG_PR, reg | ENABLE_PLL);
+
+ /* 10msec delay needed after PLL power-up */
+ mdelay(10);
+
+ /*Switch on NADC Divider */
+ reg = adc3xxx_read_reg_cache(codec, ADC_NADC);
+ adc3xxx_write(codec, ADC_NADC, reg | ENABLE_NADC);
+
+ /* Switch on MADC Divider */
+ reg = adc3xxx_read_reg_cache(codec, ADC_MADC);
+ adc3xxx_write(codec, ADC_MADC, reg | ENABLE_MADC);
+
+ /* Switch on BCLK_N Divider */
+ reg = adc3xxx_read_reg_cache(codec, BCLK_N_DIV);
+ adc3xxx_write(codec, BCLK_N_DIV, reg | ~ENABLE_BCLK);
+
+ }
+ msleep(350);
+ break;
+
+ /* partial On */
+ case SND_SOC_BIAS_PREPARE:
+ break;
+
+ /* Off, with power */
+ case SND_SOC_BIAS_STANDBY:
+ if (adc3xxx->master) {
+ /* switch off pll */
+ reg = adc3xxx_read_reg_cache(codec, PLL_PROG_PR);
+ adc3xxx_write(codec, PLL_PROG_PR, reg & (~ENABLE_PLL));
+ msleep(10);
+
+ /* Switch off NADC Divider */
+ reg = adc3xxx_read_reg_cache(codec, ADC_NADC);
+ adc3xxx_write(codec, ADC_NADC, reg & (~ENABLE_NADC));
+
+ /* Switch off MADC Divider */
+ reg = adc3xxx_read_reg_cache(codec, ADC_MADC);
+ adc3xxx_write(codec, ADC_MADC, reg & (~ENABLE_MADC));
+
+ /* Switch off BCLK_N Divider */
+ reg = adc3xxx_read_reg_cache(codec, BCLK_N_DIV);
+ adc3xxx_write(codec, BCLK_N_DIV, reg & (~ENABLE_BCLK));
+ msleep(100);
+ }
+ break;
+
+ /* Off without power */
+ case SND_SOC_BIAS_OFF:
+
+ /* power off Left/Right ADC channels */
+ reg = adc3xxx_read_reg_cache(codec, ADC_DIGITAL);
+ adc3xxx_write(codec, ADC_DIGITAL,
+ reg & ~(LADC_PWR_ON | RADC_PWR_ON));
+
+ /* Turn off PLLs */
+ if (adc3xxx->master) {
+ /* switch off pll */
+ reg = adc3xxx_read_reg_cache(codec, PLL_PROG_PR);
+ adc3xxx_write(codec, PLL_PROG_PR, reg & (~ENABLE_PLL));
+
+ /* Switch off NADC Divider */
+ reg = adc3xxx_read_reg_cache(codec, ADC_NADC);
+ adc3xxx_write(codec, ADC_NADC, reg & (~ENABLE_NADC));
+
+ /* Switch off MADC Divider */
+ reg = adc3xxx_read_reg_cache(codec, ADC_MADC);
+ adc3xxx_write(codec, ADC_MADC, reg & (~ENABLE_MADC));
+
+ /* Switch off BCLK_N Divider */
+ reg = adc3xxx_read_reg_cache(codec, BCLK_N_DIV);
+ adc3xxx_write(codec, BCLK_N_DIV, reg & (~ENABLE_BCLK));
+ }
+ break;
+ }
+ codec->dapm.bias_level = level;
+
+ return 0;
+}
+
+static struct snd_soc_dai_ops adc3xxx_dai_ops = {
+ .hw_params = adc3xxx_hw_params,
+ .set_sysclk = adc3xxx_set_dai_sysclk,
+ .set_fmt = adc3xxx_set_dai_fmt,
+};
+
+struct snd_soc_dai_driver adc3xxx_dai = {
+ .name = "tlv320adc3xxx-hifi",
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = ADC3xxx_RATES,
+ .formats = ADC3xxx_FORMATS,
+ },
+ .ops = &adc3xxx_dai_ops,
+};
+
+EXPORT_SYMBOL_GPL(adc3xxx_dai);
+
+/*
+ *----------------------------------------------------------------------------
+ * Function : tlv320adc3xxx_init
+ * Purpose : This function is to initialise the adc3xxx driver
+ * register the mixer and dsp interfaces with the kernel.
+ *
+ *----------------------------------------------------------------------------
+ */
+static int adc3xxx_init(struct snd_soc_codec *codec)
+{
+ int i, ret = 0;
+
+ codec->name = "tlv320adc3xxx";
+ codec->num_dai = 1;
+ codec->reg_cache =
+ kmemdup(adc3xxx_reg, sizeof(adc3xxx_reg), GFP_KERNEL);
+ if (codec->reg_cache == NULL)
+ return -ENOMEM;
+
+ /* Select Page 0 */
+ adc3xxx_write(codec, PAGE_SELECT, 0);
+ /* Issue software reset to adc3xxx */
+ adc3xxx_write(codec, RESET, SOFT_RESET);
+
+ adc3xxx_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ for (i = 0;
+ i < sizeof(adc3xxx_reg_init) / sizeof(struct adc3xxx_configs);
+ i++) {
+ adc3xxx_write(codec, adc3xxx_reg_init[i].reg_offset,
+ adc3xxx_reg_init[i].reg_val);
+ }
+
+ //adc3xxx_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ return ret;
+
+ kfree(codec->reg_cache);
+ return ret;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * Function : adc3xxx_probe
+ * Purpose : This is first driver function called by the SoC core driver.
+ *
+ *----------------------------------------------------------------------------
+ */
+static int adc3xxx_probe(struct snd_soc_codec *codec)
+{
+ struct adc3xxx_priv *adc3xxx = NULL;
+ int ret = 0;
+
+ printk(KERN_INFO "ADC3xxx Audio Codec %s provided by Amba Dongge\n", ADC3xxx_VERSION);
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ codec->write = adc3xxx_write;
+ codec->read = adc3xxx_read;
+#endif
+
+ adc3xxx = (struct adc3xxx_priv *)snd_soc_codec_get_drvdata(codec);
+ codec->control_data = adc3xxx->control_data;
+ mutex_init(&codec->mutex);
+
+ ret = devm_gpio_request(codec->dev, adc3xxx->rst_pin, "adc3xxx reset");
+ if (ret < 0){
+ dev_err(codec->dev, "Failed to request rst_pin: %d\n", ret);
+ return ret;
+ }
+
+ /* Reset adc3xxx codec */
+ gpio_direction_output(adc3xxx->rst_pin, adc3xxx->rst_active);
+ msleep(2);
+ gpio_direction_output(adc3xxx->rst_pin, !adc3xxx->rst_active);
+
+ ret = adc3xxx_init(codec);
+
+ if (ret < 0) {
+ printk(KERN_ERR "adc3xxx: failed to initialise ADC3xxx\n");
+ devm_gpio_free(codec->dev, adc3xxx->rst_pin);
+ }
+
+ return ret;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * Function : adc3xxx_remove
+ * Purpose : to remove adc3xxx soc device
+ *
+ *----------------------------------------------------------------------------
+ */
+static int adc3xxx_remove(struct snd_soc_codec *codec)
+{
+ adc3xxx_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * Function : adc3xxx_suspend
+ * Purpose : This function is to suspend the adc3xxx driver.
+ *
+ *----------------------------------------------------------------------------
+ */
+static int adc3xxx_suspend(struct snd_soc_codec *codec)
+{
+ adc3xxx_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * Function : adc3xxx_resume
+ * Purpose : This function is to resume the ADC3xxx driver
+ *
+ *----------------------------------------------------------------------------
+ */
+static int adc3xxx_resume(struct snd_soc_codec *codec)
+{
+ snd_soc_cache_sync(codec);
+ adc3xxx_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ return 0;
+}
+
+struct snd_soc_codec_driver soc_codec_dev_adc3xxx = {
+ .probe = adc3xxx_probe,
+ .remove = adc3xxx_remove,
+ .suspend = adc3xxx_suspend,
+ .resume = adc3xxx_resume,
+ .set_bias_level = adc3xxx_set_bias_level,
+ .reg_cache_default = adc3xxx_reg,
+ .reg_cache_size = ARRAY_SIZE(adc3xxx_reg),
+ .reg_word_size = sizeof(u8),
+ .reg_cache_step = 1,
+
+ .controls = adc3xxx_snd_controls,
+ .num_controls = ARRAY_SIZE(adc3xxx_snd_controls),
+ .dapm_widgets = adc3xxx_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(adc3xxx_dapm_widgets),
+ .dapm_routes = intercon,
+ .num_dapm_routes = ARRAY_SIZE(intercon),
+};
+EXPORT_SYMBOL_GPL(soc_codec_dev_adc3xxx);
+
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+/*
+ *----------------------------------------------------------------------------
+ * Function : adc3xxx_i2c_probe
+ * Purpose : This function attaches the i2c client and initializes
+ * adc3xxx CODEC.
+ * NOTE:
+ * This function is called from i2c core when the I2C address is
+ * valid.
+ * If the i2c layer weren't so broken, we could pass this kind of
+ * data around
+ *
+ *----------------------------------------------------------------------------
+ */
+static int adc3xxx_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct device_node *np = i2c->dev.of_node;
+ struct adc3xxx_priv *adc3xxx = NULL;
+ enum of_gpio_flags flags;
+ int rst_pin;
+ int ret;
+
+ adc3xxx = kzalloc(sizeof(struct adc3xxx_priv), GFP_KERNEL);
+ if (adc3xxx == NULL) {
+ return -ENOMEM;
+ }
+
+ rst_pin = of_get_gpio_flags(np, 0, &flags);
+ if (rst_pin < 0 || !gpio_is_valid(rst_pin))
+ return -ENXIO;
+
+ adc3xxx->rst_pin = rst_pin;
+ adc3xxx->rst_active = !!(flags & OF_GPIO_ACTIVE_LOW);
+ adc3xxx->control_data = i2c;
+
+ i2c_set_clientdata(i2c, adc3xxx);
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_adc3xxx, &adc3xxx_dai, 1);
+ if (ret < 0){
+ kfree(adc3xxx);
+ printk("\t[adc3xxx Error!] %s(%d)\n",__FUNCTION__,__LINE__);
+ }
+
+ return ret;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * Function : adc3xxx_i2c_remove
+ * Purpose : This function removes the i2c client and uninitializes
+ * adc3xxx CODEC.
+ * NOTE:
+ * This function is called from i2c core
+ * If the i2c layer weren't so broken, we could pass this kind of
+ * data around
+ *
+ *----------------------------------------------------------------------------
+ */
+static int __exit adc3xxx_i2c_remove(struct i2c_client *client)
+{
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
+ return 0;
+}
+
+static struct of_device_id tlv320adc3xxx_of_match[] = {
+ { .compatible = "ambarella,tlv320adc3xxx",},
+ {},
+};
+MODULE_DEVICE_TABLE(of, tlv320adc3xxx_of_match);
+
+
+static const struct i2c_device_id adc3xxx_i2c_id[] = {
+ {"tlv320adc3xxx", 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, adc3xxx_i2c_id);
+
+/* machine i2c codec control layer */
+static struct i2c_driver adc3xxx_i2c_driver = {
+ .driver = {
+ .name = "tlv320adc3xxx-codec",
+ .owner = THIS_MODULE,
+ .of_match_table = tlv320adc3xxx_of_match,
+ },
+ .probe = adc3xxx_i2c_probe,
+ .remove = adc3xxx_i2c_remove,
+ .id_table = adc3xxx_i2c_id,
+};
+#endif
+
+static int __init tlv320adc3xxx_init(void)
+{
+ return i2c_add_driver(&adc3xxx_i2c_driver);
+}
+
+static void __exit tlv320adc3xxx_exit(void)
+{
+ i2c_del_driver(&adc3xxx_i2c_driver);
+}
+
+module_init(tlv320adc3xxx_init);
+module_exit(tlv320adc3xxx_exit);
+
+MODULE_DESCRIPTION("ASoC TLV320ADC3xxx codec driver");
+MODULE_AUTHOR("dgwu@ambarella.com ");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320adc3xxx_amb.h b/sound/soc/codecs/tlv320adc3xxx_amb.h
new file mode 100644
index 00000000..e18f48e3
--- /dev/null
+++ b/sound/soc/codecs/tlv320adc3xxx_amb.h
@@ -0,0 +1,378 @@
+/*
+ * sound/soc/codecs/tlv320adc3xxx_amb.H
+ *
+ * Author: Dongge wu <dgwu@ambarella.com>
+ *
+ * History:
+ * 2015/10/28 - [Dongge wu] Created file
+ *
+ * Copyright (C) 2014-2018, Ambarella, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+
+#ifndef _ADC3xxx_AMB_H
+#define _ADC3xxx_AMB_H
+
+#define AUDIO_NAME "tlv320adc3xxx"
+#define ADC3xxx_VERSION "Rev A"
+
+#define ADC3101_CODEC_SUPPORT
+//#define ADC3001_CODEC_SUPPORT
+
+/* Macro enables or disables support for TiLoad in the driver */
+#define ADC3xxx_TiLoad
+//#undef ADC3xxx_TiLoad
+
+/* 8 bit mask value */
+#define ADC3xxx_8BITS_MASK 0xFF
+
+/* Enable slave / master mode for codec */
+#define ADC3xxx_MCBSP_SLAVE //codec master
+//#undef ADC3xxx_MCBSP_SLAVE
+
+
+/****************************************************************************/
+/* Page 0 Registers */
+/****************************************************************************/
+
+/* Page select register */
+#define PAGE_SELECT 0
+/* Software reset register */
+#define RESET 1
+
+/* 2-3 Reserved */
+
+/* PLL programming register B */
+#define CLKGEN_MUX 4
+/* PLL P and R-Val */
+#define PLL_PROG_PR 5
+/* PLL J-Val */
+#define PLL_PROG_J 6
+/* PLL D-Val MSB */
+#define PLL_PROG_D_MSB 7
+/* PLL D-Val LSB */
+#define PLL_PROG_D_LSB 8
+
+/* 9-17 Reserved */
+
+/* ADC NADC */
+#define ADC_NADC 18
+/* ADC MADC */
+#define ADC_MADC 19
+/* ADC AOSR */
+#define ADC_AOSR 20
+/* ADC IADC */
+#define ADC_IADC 21
+
+/* 23-24 Reserved */
+
+/* CLKOUT MUX */
+#define CLKOUT_MUX 25
+/* CLOCKOUT M divider value */
+#define CLKOUT_M_DIV 26
+/*Audio Interface Setting Register 1*/
+#define INTERFACE_CTRL_1 27
+/* Data Slot Offset (Ch_Offset_1) */
+#define CH_OFFSET_1 28
+/* ADC interface control 2 */
+#define INTERFACE_CTRL_2 29
+/* BCLK N Divider */
+#define BCLK_N_DIV 30
+/* Secondary audio interface control 1 */
+#define INTERFACE_CTRL_3 31
+/* Secondary audio interface control 2 */
+#define INTERFACE_CTRL_4 32
+/* Secondary audio interface control 3 */
+#define INTERFACE_CTRL_5 33
+/* I2S sync */
+#define I2S_SYNC 34
+
+/* 35 Reserved */
+
+/* ADC flag register */
+#define ADC_FLAG 36
+/* Data slot offset 2 (Ch_Offset_2) */
+#define CH_OFFSET_2 37
+/* I2S TDM control register */
+#define I2S_TDM_CTRL 38
+
+/* 39-41 Reserved */
+
+/* Interrupt flags (overflow) */
+#define INTR_FLAG_1 42
+/* Interrupt flags (overflow) */
+#define INTR_FLAG_2 43
+
+/* 44 Reserved */
+
+/* Interrupt flags ADC */
+#define INTR_FLAG_ADC1 45
+
+/* 46 Reserved */
+
+/* Interrupt flags ADC */
+#define INTR_FLAG_ADC2 47
+/* INT1 interrupt control */
+#define INT1_CTRL 48
+/* INT2 interrupt control */
+#define INT2_CTRL 49
+
+/* 50 Reserved */
+
+/* DMCLK/GPIO2 control */
+#define GPIO2_CTRL 51
+/* DMDIN/GPIO1 control */
+#define GPIO1_CTRL 52
+/* DOUT Control */
+#define DOUT_CTRL 53
+
+/* 54-56 Reserved */
+
+/* ADC sync control 1 */
+#define SYNC_CTRL_1 57
+/* ADC sync control 2 */
+#define SYNC_CTRL_2 58
+/* ADC CIC filter gain control */
+#define CIC_GAIN_CTRL 59
+
+/* 60 Reserved */
+
+/* ADC processing block selection */
+#define PRB_SELECT 61
+/* Programmable instruction mode control bits */
+#define INST_MODE_CTRL 62
+
+/* 63-79 Reserved */
+
+/* Digital microphone polarity control */
+#define MIC_POLARITY_CTRL 80
+/* ADC Digital */
+#define ADC_DIGITAL 81
+/* ADC Fine Gain Adjust */
+#define ADC_FGA 82
+/* Left ADC Channel Volume Control */
+#define LADC_VOL 83
+/* Right ADC Channel Volume Control */
+#define RADC_VOL 84
+/* ADC phase compensation */
+#define ADC_PHASE_COMP 85
+/* Left Channel AGC Control Register 1 */
+#define LEFT_CHN_AGC_1 86
+/* Left Channel AGC Control Register 2 */
+#define LEFT_CHN_AGC_2 87
+/* Left Channel AGC Control Register 3 */
+#define LEFT_CHN_AGC_3 88
+/* Left Channel AGC Control Register 4 */
+#define LEFT_CHN_AGC_4 89
+/* Left Channel AGC Control Register 5 */
+#define LEFT_CHN_AGC_5 90
+/* Left Channel AGC Control Register 6 */
+#define LEFT_CHN_AGC_6 91
+/* Left Channel AGC Control Register 7 */
+#define LEFT_CHN_AGC_7 92
+/* Left AGC gain */
+#define LEFT_AGC_GAIN 93
+/* Right Channel AGC Control Register 1 */
+#define RIGHT_CHN_AGC_1 94
+/* Right Channel AGC Control Register 2 */
+#define RIGHT_CHN_AGC_2 95
+/* Right Channel AGC Control Register 3 */
+#define RIGHT_CHN_AGC_3 96
+/* Right Channel AGC Control Register 4 */
+#define RIGHT_CHN_AGC_4 97
+/* Right Channel AGC Control Register 5 */
+#define RIGHT_CHN_AGC_5 98
+/* Right Channel AGC Control Register 6 */
+#define RIGHT_CHN_AGC_6 99
+/* Right Channel AGC Control Register 7 */
+#define RIGHT_CHN_AGC_7 100
+/* Right AGC gain */
+#define RIGHT_AGC_GAIN 101
+
+/* 102-127 Reserved */
+
+/****************************************************************************/
+/* Page 1 Registers */
+/****************************************************************************/
+#define PAGE_1 128
+
+/* 1-25 Reserved */
+
+/* Dither control */
+#define DITHER_CTRL (PAGE_1 + 26)
+
+/* 27-50 Reserved */
+
+/* MICBIAS Configuration Register */
+#define MICBIAS_CTRL (PAGE_1 + 51)
+/* Left ADC input selection for Left PGA */
+#define LEFT_PGA_SEL_1 (PAGE_1 + 52)
+
+/* 53 Reserved */
+
+/* Right ADC input selection for Left PGA */
+#define LEFT_PGA_SEL_2 (PAGE_1 + 54)
+/* Right ADC input selection for right PGA */
+#define RIGHT_PGA_SEL_1 (PAGE_1 + 55)
+
+/* 56 Reserved */
+
+/* Right ADC input selection for right PGA */
+#define RIGHT_PGA_SEL_2 (PAGE_1 + 57)
+
+/* 58 Reserved */
+
+/* Left analog PGA settings */
+#define LEFT_APGA_CTRL (PAGE_1 + 59)
+/* Right analog PGA settings */
+#define RIGHT_APGA_CTRL (PAGE_1 + 60)
+/* ADC Low current Modes */
+#define LOW_CURRENT_MODES (PAGE_1 + 61)
+/* ADC analog PGA flags */
+#define ANALOG_PGA_FLAGS (PAGE_1 + 62)
+
+/* 63-127 Reserved */
+
+/****************************************************************************/
+/* Macros and definitions */
+/****************************************************************************/
+
+/* ADC3xxx register space */
+#define ADC3xxx_CACHEREGNUM 192
+#define ADC3xxx_PAGE_SIZE 128
+
+#define ADC3xxx_RATES SNDRV_PCM_RATE_8000_96000
+#define ADC3xxx_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
+ SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+/* bits defined for easy usage */
+#define D7 (0x01 << 7)
+#define D6 (0x01 << 6)
+#define D5 (0x01 << 5)
+#define D4 (0x01 << 4)
+#define D3 (0x01 << 3)
+#define D2 (0x01 << 2)
+#define D1 (0x01 << 1)
+#define D0 (0x01 << 0)
+
+/****************************************************************************/
+/* ADC3xxx Register bits */
+/****************************************************************************/
+/* PLL Enable bits */
+#define ENABLE_PLL D7
+#define ENABLE_NADC D7
+#define ENABLE_MADC D7
+#define ENABLE_BCLK D7
+
+/* Power bits */
+#define LADC_PWR_ON D7
+#define RADC_PWR_ON D6
+
+#define SOFT_RESET D0
+#define BCLK_MASTER D3
+#define WCLK_MASTER D2
+
+/* Interface register masks */
+#define FMT_MASK (D7|D6|D3|D2)
+#define WLENGTH_MASK (D5|D4)
+
+/* PLL P/R bit offsets */
+#define PLLP_SHIFT 4
+#define PLLR_SHIFT 0
+#define PLL_PR_MASK 0x7F
+#define PLLJ_MASK 0x3F
+#define PLLD_MSB_MASK 0x3F
+#define PLLD_LSB_MASK 0xFF
+#define NADC_MASK 0x7F
+#define MADC_MASK 0x7F
+#define AOSR_MASK 0xFF
+#define IADC_MASK 0xFF
+#define BDIV_MASK 0x7F
+
+/* PLL_CLKIN bits */
+#define PLL_CLKIN_SHIFT 2
+#define PLL_CLKIN_MCLK 0x0
+#define PLL_CLKIN_BCLK 0x1
+#define PLL_CLKIN_ZERO 0x3
+
+/* CODEC_CLKIN bits */
+#define CODEC_CLKIN_SHIFT 0
+#define CODEC_CLKIN_MCLK 0x0
+#define CODEC_CLKIN_BCLK 0x1
+#define CODEC_CLKIN_PLL_CLK 0x3
+
+#define USE_PLL (PLL_CLKIN_MCLK << PLL_CLKIN_SHIFT) | \
+ (CODEC_CLKIN_PLL_CLK << CODEC_CLKIN_SHIFT)
+
+/* Analog PGA control bits */
+#define LPGA_MUTE D7
+#define RPGA_MUTE D7
+
+#define LPGA_GAIN_MASK 0x7F
+#define RPGA_GAIN_MASK 0x7F
+
+/* ADC current modes */
+#define ADC_LOW_CURR_MODE D0
+
+/* Left ADC Input selection bits */
+#define LCH_SEL1_SHIFT 0
+#define LCH_SEL2_SHIFT 2
+#define LCH_SEL3_SHIFT 4
+#define LCH_SEL4_SHIFT 6
+
+#define LCH_SEL1X_SHIFT 0
+#define LCH_SEL2X_SHIFT 2
+#define LCH_SEL3X_SHIFT 4
+#define LCH_COMMON_MODE D6
+#define BYPASS_LPGA D7
+
+/* Right ADC Input selection bits */
+#define RCH_SEL1_SHIFT 0
+#define RCH_SEL2_SHIFT 2
+#define RCH_SEL3_SHIFT 4
+#define RCH_SEL4_SHIFT 6
+
+#define RCH_SEL1X_SHIFT 0
+#define RCH_SEL2X_SHIFT 2
+#define RCH_SEL3X_SHIFT 4
+#define RCH_COMMON_MODE D6
+#define BYPASS_RPGA D7
+
+/* MICBIAS control bits */
+#define MICBIAS1_SHIFT 5
+#define MICBIAS2_SHIFT 3
+
+#define ADC_MAX_VOLUME 64
+#define ADC_POS_VOL 24
+
+/****************** RATES TABLE FOR ADC3xxx ************************/
+struct adc3xxx_rate_divs {
+ u32 mclk;
+ u32 rate;
+ u8 pll_p;
+ u8 pll_r;
+ u8 pll_j;
+ u16 pll_d;
+ u8 nadc;
+ u8 madc;
+ u8 aosr;
+ u8 bdiv_n;
+ u8 iadc;
+};
+
+#endif /* _ADC3xxx_AMB_H */
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c
index 62bacb85..1d37160d 100644
--- a/sound/soc/codecs/wm8737.c
+++ b/sound/soc/codecs/wm8737.c
@@ -47,13 +47,13 @@ struct wm8737_priv {
};
static const struct reg_default wm8737_reg_defaults[] = {
- { 0, 0x00C3 }, /* R0 - Left PGA volume */
- { 1, 0x00C3 }, /* R1 - Right PGA volume */
- { 2, 0x0007 }, /* R2 - AUDIO path L */
- { 3, 0x0007 }, /* R3 - AUDIO path R */
+ { 0, 0x01C3 }, /* R0 - Left PGA volume, 0db default */
+ { 1, 0x01C3 }, /* R1 - Right PGA volume, 0db default */
+ { 2, 0x0010 }, /* R2 - AUDIO path L, apply gain immediately. */
+ { 3, 0x0010 }, /* R3 - AUDIO path R, apply gain immediately. */
{ 4, 0x0000 }, /* R4 - 3D Enhance */
{ 5, 0x0000 }, /* R5 - ADC Control */
- { 6, 0x0000 }, /* R6 - Power Management */
+ { 6, 0x01FF }, /* R6 - Power Management, turn on all modules */
{ 7, 0x000A }, /* R7 - Audio Format */
{ 8, 0x0000 }, /* R8 - Clocking */
{ 9, 0x000F }, /* R9 - MIC Preamp Control */
diff --git a/sound/soc/codecs/wm8940_amb.c b/sound/soc/codecs/wm8940_amb.c
new file mode 100644
index 00000000..5ad809d6
--- /dev/null
+++ b/sound/soc/codecs/wm8940_amb.c
@@ -0,0 +1,824 @@
+/*
+ * wm8940_amb.c -- WM8940 ALSA Soc Audio driver
+ *
+ * Copyright 2011 Ambarella Ltd.
+ *
+ * Author: Wu Dongge <dgwu@ambarella.com>
+ *
+ * Based on wm8940.c
+ * Copyright 2006 Wolfson Microelectronics PLC.
+ * Author: Jonathan Cameron <jic23@cam.ac.uk>
+ *
+ * History:
+ * 2012/10/19 - [Wu Dongge] Created file
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+
+#include "wm8940_amb.h"
+
+struct wm8940_priv {
+ unsigned int sysclk;
+ enum snd_soc_control_type control_type;
+ void *control_data;
+};
+
+static u16 wm8940_reg_defaults[] = {
+ 0x8940, /* Soft Reset */
+ 0x0000, /* Power 1 */
+ 0x0000, /* Power 2 */
+ 0x0000, /* Power 3 */
+ 0x0010, /* Interface Control */
+ 0x0000, /* Companding Control */
+ 0x0140, /* Clock Control */
+ 0x0000, /* Additional Controls */
+ 0x0000, /* GPIO Control */
+ 0x0002, /* Auto Increment Control */
+ 0x0000, /* DAC Control */
+ 0x00FF, /* DAC Volume */
+ 0,
+ 0,
+ 0x0100, /* ADC Control */
+ 0x00FF, /* ADC Volume */
+ 0x0000, /* Notch Filter 1 Control 1 */
+ 0x0000, /* Notch Filter 1 Control 2 */
+ 0x0000, /* Notch Filter 2 Control 1 */
+ 0x0000, /* Notch Filter 2 Control 2 */
+ 0x0000, /* Notch Filter 3 Control 1 */
+ 0x0000, /* Notch Filter 3 Control 2 */
+ 0x0000, /* Notch Filter 4 Control 1 */
+ 0x0000, /* Notch Filter 4 Control 2 */
+ 0x0032, /* DAC Limit Control 1 */
+ 0x0000, /* DAC Limit Control 2 */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0x0038, /* ALC Control 1 */
+ 0x000B, /* ALC Control 2 */
+ 0x0032, /* ALC Control 3 */
+ 0x0000, /* Noise Gate */
+ 0x0041, /* PLLN */
+ 0x000C, /* PLLK1 */
+ 0x0093, /* PLLK2 */
+ 0x00E9, /* PLLK3 */
+ 0,
+ 0,
+ 0x0030, /* ALC Control 4 */
+ 0,
+ 0x0002, /* Input Control */
+ 0x0050, /* PGA Gain */
+ 0,
+ 0x0002, /* ADC Boost Control */
+ 0,
+ 0x0002, /* Output Control */
+ 0x0000, /* Speaker Mixer Control */
+ 0,
+ 0,
+ 0,
+ 0x0079, /* Speaker Volume */
+ 0,
+ 0x0000, /* Mono Mixer Control */
+};
+
+static const char *wm8940_companding[] = { "Off", "NC", "u-law", "A-law" };
+static const struct soc_enum wm8940_adc_companding_enum
+= SOC_ENUM_SINGLE(WM8940_COMPANDINGCTL, 1, 4, wm8940_companding);
+static const struct soc_enum wm8940_dac_companding_enum
+= SOC_ENUM_SINGLE(WM8940_COMPANDINGCTL, 3, 4, wm8940_companding);
+
+static const char *wm8940_alc_mode_text[] = {"ALC", "Limiter"};
+static const struct soc_enum wm8940_alc_mode_enum
+= SOC_ENUM_SINGLE(WM8940_ALC3, 8, 2, wm8940_alc_mode_text);
+
+static const char *wm8940_mic_bias_level_text[] = {"0.9", "0.65"};
+static const struct soc_enum wm8940_mic_bias_level_enum
+= SOC_ENUM_SINGLE(WM8940_INPUTCTL, 8, 2, wm8940_mic_bias_level_text);
+
+static const char *wm8940_filter_mode_text[] = {"Audio", "Application"};
+static const struct soc_enum wm8940_filter_mode_enum
+= SOC_ENUM_SINGLE(WM8940_ADC, 7, 2, wm8940_filter_mode_text);
+
+static DECLARE_TLV_DB_SCALE(wm8940_spk_vol_tlv, -5700, 100, 1);
+static DECLARE_TLV_DB_SCALE(wm8940_att_tlv, -1000, 1000, 0);
+static DECLARE_TLV_DB_SCALE(wm8940_pga_vol_tlv, -1200, 75, 0);
+static DECLARE_TLV_DB_SCALE(wm8940_alc_min_tlv, -1200, 600, 0);
+static DECLARE_TLV_DB_SCALE(wm8940_alc_max_tlv, 675, 600, 0);
+static DECLARE_TLV_DB_SCALE(wm8940_alc_tar_tlv, -2250, 50, 0);
+static DECLARE_TLV_DB_SCALE(wm8940_lim_boost_tlv, 0, 100, 0);
+static DECLARE_TLV_DB_SCALE(wm8940_lim_thresh_tlv, -600, 100, 0);
+static DECLARE_TLV_DB_SCALE(wm8940_adc_tlv, -12750, 50, 1);
+static DECLARE_TLV_DB_SCALE(wm8940_capture_boost_vol_tlv, 0, 2000, 0);
+
+static const struct snd_kcontrol_new wm8940_snd_controls[] = {
+ SOC_SINGLE("Digital Loopback Switch", WM8940_COMPANDINGCTL,
+ 6, 1, 0),
+ SOC_ENUM("DAC Companding", wm8940_dac_companding_enum),
+ SOC_ENUM("ADC Companding", wm8940_adc_companding_enum),
+
+ SOC_ENUM("ALC Mode", wm8940_alc_mode_enum),
+ SOC_SINGLE("ALC Switch", WM8940_ALC1, 8, 1, 0),
+ SOC_SINGLE_TLV("ALC Capture Max Gain", WM8940_ALC1,
+ 3, 7, 0, wm8940_alc_max_tlv),
+ SOC_SINGLE_TLV("ALC Capture Min Gain", WM8940_ALC1,
+ 0, 7, 0, wm8940_alc_min_tlv),
+ SOC_SINGLE_TLV("ALC Capture Target", WM8940_ALC2,
+ 0, 14, 0, wm8940_alc_tar_tlv),
+ SOC_SINGLE("ALC Capture Hold", WM8940_ALC2, 4, 10, 0),
+ SOC_SINGLE("ALC Capture Decay", WM8940_ALC3, 4, 10, 0),
+ SOC_SINGLE("ALC Capture Attach", WM8940_ALC3, 0, 10, 0),
+ SOC_SINGLE("ALC ZC Switch", WM8940_ALC4, 1, 1, 0),
+ SOC_SINGLE("ALC Capture Noise Gate Switch", WM8940_NOISEGATE,
+ 3, 1, 0),
+ SOC_SINGLE("ALC Capture Noise Gate Threshold", WM8940_NOISEGATE,
+ 0, 7, 0),
+
+ SOC_SINGLE("DAC Playback Limiter Switch", WM8940_DACLIM1, 8, 1, 0),
+ SOC_SINGLE("DAC Playback Limiter Attack", WM8940_DACLIM1, 0, 9, 0),
+ SOC_SINGLE("DAC Playback Limiter Decay", WM8940_DACLIM1, 4, 11, 0),
+ SOC_SINGLE_TLV("DAC Playback Limiter Threshold", WM8940_DACLIM2,
+ 4, 9, 1, wm8940_lim_thresh_tlv),
+ SOC_SINGLE_TLV("DAC Playback Limiter Boost", WM8940_DACLIM2,
+ 0, 12, 0, wm8940_lim_boost_tlv),
+
+ SOC_SINGLE("Capture PGA ZC Switch", WM8940_PGAGAIN, 7, 1, 0),
+ SOC_SINGLE_TLV("Capture PGA Volume", WM8940_PGAGAIN,
+ 0, 63, 0, wm8940_pga_vol_tlv),
+ SOC_SINGLE_TLV("Digital Playback Volume", WM8940_DACVOL,
+ 0, 255, 0, wm8940_adc_tlv),
+ SOC_SINGLE_TLV("Digital Capture Volume", WM8940_ADCVOL,
+ 0, 255, 0, wm8940_adc_tlv),
+ SOC_ENUM("Mic Bias Level", wm8940_mic_bias_level_enum),
+ SOC_SINGLE_TLV("Capture Boost Volue", WM8940_ADCBOOST,
+ 8, 1, 0, wm8940_capture_boost_vol_tlv),
+ SOC_SINGLE_TLV("Speaker Playback Volume", WM8940_SPKVOL,
+ 0, 63, 0, wm8940_spk_vol_tlv),
+ SOC_SINGLE("Speaker Playback Switch", WM8940_SPKVOL, 6, 1, 1),
+
+ SOC_SINGLE_TLV("Speaker Mixer Line Bypass Volume", WM8940_SPKVOL,
+ 8, 1, 1, wm8940_att_tlv),
+ SOC_SINGLE("Speaker Playback ZC Switch", WM8940_SPKVOL, 7, 1, 0),
+
+ SOC_SINGLE("Mono Out Switch", WM8940_MONOMIX, 6, 1, 1),
+ SOC_SINGLE_TLV("Mono Mixer Line Bypass Volume", WM8940_MONOMIX,
+ 7, 1, 1, wm8940_att_tlv),
+
+ SOC_SINGLE("High Pass Filter Switch", WM8940_ADC, 8, 1, 0),
+ SOC_ENUM("High Pass Filter Mode", wm8940_filter_mode_enum),
+ SOC_SINGLE("High Pass Filter Cut Off", WM8940_ADC, 4, 7, 0),
+ SOC_SINGLE("ADC Inversion Switch", WM8940_ADC, 0, 1, 0),
+ SOC_SINGLE("DAC Inversion Switch", WM8940_DAC, 0, 1, 0),
+ SOC_SINGLE("DAC Auto Mute Switch", WM8940_DAC, 2, 1, 0),
+ SOC_SINGLE("ZC Timeout Clock Switch", WM8940_ADDCNTRL, 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new wm8940_speaker_mixer_controls[] = {
+ SOC_DAPM_SINGLE("Line Bypass Switch", WM8940_SPKMIX, 1, 1, 0),
+ SOC_DAPM_SINGLE("Aux Playback Switch", WM8940_SPKMIX, 5, 1, 0),
+ SOC_DAPM_SINGLE("PCM Playback Switch", WM8940_SPKMIX, 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new wm8940_mono_mixer_controls[] = {
+ SOC_DAPM_SINGLE("Line Bypass Switch", WM8940_MONOMIX, 1, 1, 0),
+ SOC_DAPM_SINGLE("Aux Playback Switch", WM8940_MONOMIX, 2, 1, 0),
+ SOC_DAPM_SINGLE("PCM Playback Switch", WM8940_MONOMIX, 0, 1, 0),
+};
+
+static DECLARE_TLV_DB_SCALE(wm8940_boost_vol_tlv, -1500, 300, 1);
+static const struct snd_kcontrol_new wm8940_input_boost_controls[] = {
+ SOC_DAPM_SINGLE("Mic PGA Switch", WM8940_PGAGAIN, 6, 1, 1),
+ SOC_DAPM_SINGLE_TLV("Aux Volume", WM8940_ADCBOOST,
+ 0, 7, 0, wm8940_boost_vol_tlv),
+ SOC_DAPM_SINGLE_TLV("Mic Volume", WM8940_ADCBOOST,
+ 4, 7, 0, wm8940_boost_vol_tlv),
+};
+
+static const struct snd_kcontrol_new wm8940_micpga_controls[] = {
+ SOC_DAPM_SINGLE("AUX Switch", WM8940_INPUTCTL, 2, 1, 0),
+ SOC_DAPM_SINGLE("MICP Switch", WM8940_INPUTCTL, 0, 1, 0),
+ SOC_DAPM_SINGLE("MICN Switch", WM8940_INPUTCTL, 1, 1, 0),
+};
+
+static const struct snd_soc_dapm_widget wm8940_dapm_widgets[] = {
+ SND_SOC_DAPM_MIXER("Speaker Mixer", WM8940_POWER3, 2, 0,
+ &wm8940_speaker_mixer_controls[0],
+ ARRAY_SIZE(wm8940_speaker_mixer_controls)),
+ SND_SOC_DAPM_MIXER("Mono Mixer", WM8940_POWER3, 3, 0,
+ &wm8940_mono_mixer_controls[0],
+ ARRAY_SIZE(wm8940_mono_mixer_controls)),
+ SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8940_POWER3, 0, 0),
+
+ SND_SOC_DAPM_PGA("SpkN Out", WM8940_POWER3, 5, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("SpkP Out", WM8940_POWER3, 6, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Mono Out", WM8940_POWER3, 7, 0, NULL, 0),
+ SND_SOC_DAPM_OUTPUT("MONOOUT"),
+ SND_SOC_DAPM_OUTPUT("SPKOUTP"),
+ SND_SOC_DAPM_OUTPUT("SPKOUTN"),
+
+ SND_SOC_DAPM_PGA("Aux Input", WM8940_POWER1, 6, 0, NULL, 0),
+ SND_SOC_DAPM_ADC("ADC", "HiFi Capture", WM8940_POWER2, 0, 0),
+ SND_SOC_DAPM_MIXER("Mic PGA", WM8940_POWER2, 2, 0,
+ &wm8940_micpga_controls[0],
+ ARRAY_SIZE(wm8940_micpga_controls)),
+ SND_SOC_DAPM_MIXER("Boost Mixer", WM8940_POWER2, 4, 0,
+ &wm8940_input_boost_controls[0],
+ ARRAY_SIZE(wm8940_input_boost_controls)),
+ SND_SOC_DAPM_MICBIAS("Mic Bias", WM8940_POWER1, 4, 0),
+
+ SND_SOC_DAPM_INPUT("MICN"),
+ SND_SOC_DAPM_INPUT("MICP"),
+ SND_SOC_DAPM_INPUT("AUX"),
+};
+
+static const struct snd_soc_dapm_route audio_map[] = {
+ /* Mono output mixer */
+ {"Mono Mixer", "PCM Playback Switch", "DAC"},
+ {"Mono Mixer", "Aux Playback Switch", "Aux Input"},
+ {"Mono Mixer", "Line Bypass Switch", "Boost Mixer"},
+
+ /* Speaker output mixer */
+ {"Speaker Mixer", "PCM Playback Switch", "DAC"},
+ {"Speaker Mixer", "Aux Playback Switch", "Aux Input"},
+ {"Speaker Mixer", "Line Bypass Switch", "Boost Mixer"},
+
+ /* Outputs */
+ {"Mono Out", NULL, "Mono Mixer"},
+ {"MONOOUT", NULL, "Mono Out"},
+ {"SpkN Out", NULL, "Speaker Mixer"},
+ {"SpkP Out", NULL, "Speaker Mixer"},
+ {"SPKOUTN", NULL, "SpkN Out"},
+ {"SPKOUTP", NULL, "SpkP Out"},
+
+ /* Microphone PGA */
+ {"Mic PGA", "MICN Switch", "MICN"},
+ {"Mic PGA", "MICP Switch", "MICP"},
+ {"Mic PGA", "AUX Switch", "AUX"},
+
+ /* Boost Mixer */
+ {"Boost Mixer", "Mic PGA Switch", "Mic PGA"},
+ {"Boost Mixer", "Mic Volume", "MICP"},
+ {"Boost Mixer", "Aux Volume", "Aux Input"},
+
+ {"ADC", NULL, "Boost Mixer"},
+};
+
+#define wm8940_reset(c) snd_soc_write(c, WM8940_SOFTRESET, 0);
+
+static int wm8940_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 iface = snd_soc_read(codec, WM8940_IFACE) & 0xFE67;
+ u16 clk = snd_soc_read(codec, WM8940_CLOCK) & 0x1fe;
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ clk |= 1;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ break;
+ default:
+ return -EINVAL;
+ }
+ snd_soc_write(codec, WM8940_CLOCK, clk);
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ iface |= (2 << 3);
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ iface |= (1 << 3);
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ iface |= (3 << 3);
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ iface |= (3 << 3) | (1 << 7);
+ break;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ iface |= (1 << 7);
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ iface |= (1 << 8);
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ iface |= (1 << 8) | (1 << 7);
+ break;
+ }
+
+ snd_soc_write(codec, WM8940_IFACE, iface);
+
+ return 0;
+}
+
+static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ u16 iface = snd_soc_read(codec, WM8940_IFACE) & 0xFD9F;
+ u16 addcntrl = snd_soc_read(codec, WM8940_ADDCNTRL) & 0xFFF1;
+ u16 companding = snd_soc_read(codec, WM8940_COMPANDINGCTL) & 0xFFDF;
+ int ret;
+
+ /* LoutR control */
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE
+ && params_channels(params) == 2)
+ iface |= (1 << 9);
+
+ switch (params_rate(params)) {
+ case 8000:
+ addcntrl |= (0x5 << 1);
+ break;
+ case 11025:
+ case 12000:
+ addcntrl |= (0x4 << 1);
+ break;
+ case 16000:
+ addcntrl |= (0x3 << 1);
+ break;
+ case 24000:
+ case 22050:
+ addcntrl |= (0x2 << 1);
+ break;
+ case 32000:
+ addcntrl |= (0x1 << 1);
+ break;
+ case 44100:
+ case 48000:
+ break;
+ }
+ ret = snd_soc_write(codec, WM8940_ADDCNTRL, addcntrl);
+ if (ret)
+ goto error_ret;
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S8:
+ companding = companding | (1 << 5);
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ iface |= (1 << 5);
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ iface |= (2 << 5);
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ iface |= (3 << 5);
+ break;
+ }
+ ret = snd_soc_write(codec, WM8940_COMPANDINGCTL, companding);
+ if (ret)
+ goto error_ret;
+ ret = snd_soc_write(codec, WM8940_IFACE, iface);
+
+error_ret:
+ return ret;
+}
+
+static int wm8940_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ u16 mute_reg = snd_soc_read(codec, WM8940_DAC) & 0xffbf;
+
+ if (mute)
+ mute_reg |= 0x40;
+
+ return snd_soc_write(codec, WM8940_DAC, mute_reg);
+}
+
+static int wm8940_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ u16 val = 0;
+ u16 pwr_reg = snd_soc_read(codec, WM8940_POWER1) & 0x1F0;
+ int ret = 0;
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ /* ensure bufioen and biasen and micben */
+ pwr_reg |= (1 << 2) | (1 << 3) | (1 << 4);
+ /* Enable thermal shutdown */
+ val = snd_soc_read(codec, WM8940_OUTPUTCTL);
+ ret = snd_soc_write(codec, WM8940_OUTPUTCTL, val | 0x2);
+ if (ret)
+ break;
+ /* set vmid to 50k */
+ ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x1);
+ break;
+ case SND_SOC_BIAS_PREPARE:
+ /* ensure bufioen and biasen */
+ pwr_reg |= (1 << 2) | (1 << 3);
+ ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x1);
+ break;
+ case SND_SOC_BIAS_STANDBY:
+ /* ensure bufioen and biasen */
+ pwr_reg |= (1 << 2) | (1 << 3);
+ /* set vmid to 300k for standby */
+ ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x2);
+ break;
+ case SND_SOC_BIAS_OFF:
+ ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg);
+ break;
+ }
+
+ codec->dapm.bias_level = level;
+
+ return ret;
+}
+
+struct pll_ {
+ unsigned int pre_scale:2;
+ unsigned int n:4;
+ unsigned int k;
+};
+
+static struct pll_ pll_div;
+
+/* The size in bits of the pll divide multiplied by 10
+ * to allow rounding later */
+#define FIXED_PLL_SIZE ((1 << 24) * 10)
+static void pll_factors(unsigned int target, unsigned int source)
+{
+ unsigned long long Kpart;
+ unsigned int K, Ndiv, Nmod;
+ /* The left shift ist to avoid accuracy loss when right shifting */
+ Ndiv = target / source;
+
+ if (Ndiv > 12) {
+ source <<= 1;
+ /* Multiply by 2 */
+ pll_div.pre_scale = 0;
+ Ndiv = target / source;
+ } else if (Ndiv < 3) {
+ source >>= 2;
+ /* Divide by 4 */
+ pll_div.pre_scale = 3;
+ Ndiv = target / source;
+ } else if (Ndiv < 6) {
+ source >>= 1;
+ /* divide by 2 */
+ pll_div.pre_scale = 2;
+ Ndiv = target / source;
+ } else {
+ pll_div.pre_scale = 1;
+ }
+
+ if ((Ndiv < 6) || (Ndiv > 12))
+ printk(KERN_WARNING "WM8940 N value %d outwith recommended range!\n", Ndiv);
+
+ pll_div.n = Ndiv;
+ Nmod = target % source;
+ Kpart = FIXED_PLL_SIZE * (long long)Nmod;
+
+ do_div(Kpart, source);
+ K = Kpart & 0xFFFFFFFF;
+
+ /* Check if we need to round */
+ if ((K % 10) >= 5)
+ K += 5;
+
+ /* Move down to proper range now rounding is done */
+ K /= 10;
+ pll_div.k = K;
+}
+
+/* Untested at the moment */
+static int wm8940_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
+ int source, unsigned int freq_in, unsigned int freq_out)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 reg;
+
+ /* Turn off PLL */
+ reg = snd_soc_read(codec, WM8940_POWER1);
+ snd_soc_write(codec, WM8940_POWER1, reg & 0x1df);
+
+ if (freq_in == 0 || freq_out == 0) {
+ /* Clock CODEC directly from MCLK */
+ reg = snd_soc_read(codec, WM8940_CLOCK);
+ snd_soc_write(codec, WM8940_CLOCK, reg & 0x0ff);
+ /* Pll power down */
+ snd_soc_write(codec, WM8940_PLLN, (1 << 7));
+ return 0;
+ }
+
+ /* Pll is followed by a frequency divide by 4 */
+ pll_factors(freq_out*4, freq_in);
+
+ if (pll_div.k)
+ snd_soc_write(codec, WM8940_PLLN,
+ (pll_div.pre_scale << 4) | pll_div.n | (1 << 6));
+ else /* No factional component */
+ snd_soc_write(codec, WM8940_PLLN,
+ (pll_div.pre_scale << 4) | pll_div.n);
+
+ snd_soc_write(codec, WM8940_PLLK1, (pll_div.k >> 18) & 0x3f);
+ snd_soc_write(codec, WM8940_PLLK2, (pll_div.k >> 9) & 0x1ff);
+ snd_soc_write(codec, WM8940_PLLK3, pll_div.k & 0x1ff);
+ /* Enable the PLL */
+ reg = snd_soc_read(codec, WM8940_POWER1);
+ snd_soc_write(codec, WM8940_POWER1, reg | 0x020);
+
+ /* Run CODEC from PLL instead of MCLK */
+ reg = snd_soc_read(codec, WM8940_CLOCK);
+ snd_soc_write(codec, WM8940_CLOCK, reg | 0x100);
+
+ return 0;
+}
+
+static int wm8940_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct wm8940_priv *wm8940 = snd_soc_codec_get_drvdata(codec);
+ u16 reg;
+
+ switch(clk_id) {
+ case WM8940_MCLKIN:
+ /* Clock CODEC directly from MCLK */
+ reg = snd_soc_read(codec, WM8940_CLOCK) & 0x0fe;
+ snd_soc_write(codec, WM8940_CLOCK, reg);
+
+ /* Turn off PLL */
+ reg = snd_soc_read(codec, WM8940_POWER1);
+ snd_soc_write(codec, WM8940_POWER1, reg & 0x1df);
+ break;
+ case WM8940_PLLOUT:
+ /* Clock CODEC is generated by PLL */
+ reg = snd_soc_read(codec, WM8940_CLOCK) & 0x0fe;
+ reg |= 0x100;
+ snd_soc_write(codec, WM8940_CLOCK, reg);
+
+ /* Turn on PLL */
+ reg = snd_soc_read(codec, WM8940_POWER1);
+ snd_soc_write(codec, WM8940_POWER1, reg | 0x020);
+
+// wm8940_set_dai_pll(codec_dai, clk_id, 0, freq, request_out);
+ break;
+ case WM8940_MCLKIN_BCLKOUT:
+ reg = snd_soc_read(codec, WM8940_CLOCK) & 0x0fe;
+ reg |= 0x001;
+ snd_soc_write(codec, WM8940_CLOCK, reg);
+
+ /* Turn on PLL */
+ reg = snd_soc_read(codec, WM8940_POWER1);
+ snd_soc_write(codec, WM8940_POWER1, reg | 0x020);
+
+// wm8940_set_dai_pll(codec_dai, clk_id, 0, freq, request_out);
+ break;
+
+ }
+
+ wm8940->sysclk = freq;
+}
+
+static int wm8940_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
+ int div_id, int div)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 reg;
+ int ret = 0;
+
+ switch (div_id) {
+ case WM8940_BCLKDIV:
+ reg = snd_soc_read(codec, WM8940_CLOCK) & 0xFFE3;
+ ret = snd_soc_write(codec, WM8940_CLOCK, reg | (div << 2));
+ break;
+ case WM8940_MCLKDIV:
+ reg = snd_soc_read(codec, WM8940_CLOCK) & 0xFF1F;
+ ret = snd_soc_write(codec, WM8940_CLOCK, reg | (div << 5));
+ break;
+ case WM8940_OPCLKDIV:
+ reg = snd_soc_read(codec, WM8940_GPIO) & 0xFFCF;
+ ret = snd_soc_write(codec, WM8940_GPIO, reg | (div << 4));
+ break;
+ }
+ return ret;
+}
+
+#define WM8940_RATES SNDRV_PCM_RATE_8000_48000
+
+#define WM8940_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
+ SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S20_3LE | \
+ SNDRV_PCM_FMTBIT_S24_LE | \
+ SNDRV_PCM_FMTBIT_S32_LE)
+
+static const struct snd_soc_dai_ops wm8940_dai_ops = {
+ .hw_params = wm8940_i2s_hw_params,
+ .set_sysclk = wm8940_set_dai_sysclk,
+ .digital_mute = wm8940_mute,
+ .set_fmt = wm8940_set_dai_fmt,
+ .set_clkdiv = wm8940_set_dai_clkdiv,
+ .set_pll = wm8940_set_dai_pll,
+};
+
+static struct snd_soc_dai_driver wm8940_dai = {
+ .name = "wm8940-hifi",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = WM8940_RATES,
+ .formats = WM8940_FORMATS,
+ },
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = WM8940_RATES,
+ .formats = WM8940_FORMATS,
+ },
+ .ops = &wm8940_dai_ops,
+ .symmetric_rates = 1,
+};
+
+static int wm8940_suspend(struct snd_soc_codec *codec)
+{
+ return wm8940_set_bias_level(codec, SND_SOC_BIAS_OFF);
+}
+
+static int wm8940_resume(struct snd_soc_codec *codec)
+{
+ snd_soc_cache_sync(codec);
+ wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ return 0;
+}
+
+static int wm8940_probe(struct snd_soc_codec *codec)
+{
+ int ret = 0;
+ printk(KERN_NOTICE "wm8940_probe amba.....\n");
+
+ ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
+ }
+
+ ret = wm8940_reset(codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to issue reset\n");
+ return ret;
+ }
+
+ wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ snd_soc_write(codec, WM8940_POWER1, 0x180);
+
+ /************************ RECORD PATH SETTINGS *******************************/
+ snd_soc_write(codec, WM8940_CLOCK, 0x0100); /*set MCLK, MCLKDIV 1, BCLKDIV 1, BCLK and frame clock are inputs*/
+ snd_soc_write(codec, WM8940_GPIO, 0x0000);
+ snd_soc_write(codec, WM8940_ADDCNTRL, 0x0000);
+ snd_soc_write(codec, WM8940_INPUTCTL, 0x0107);
+ snd_soc_write(codec, WM8940_PGAGAIN, 0x003d); /*set PGA gain 30db*/
+ snd_soc_write(codec, WM8940_ADCBOOST, 0x0155); /*set PGB2BOOST, MICP2BOOSTVOL gain*/
+ snd_soc_write(codec, WM8940_ADC, 0x01c0); /*Enable high pass filter 396HZ under 48k, select audio mode*/
+ snd_soc_write(codec, WM8940_ADCVOL, 0x00ff); /*Set ADC vol, 0db*/
+ snd_soc_write(codec, WM8940_ALC1, 0x0138); /*Enable ALC, set max gain +35.25db and min gain -12db*/
+ snd_soc_write(codec, WM8940_ALC2, 0x0007); /*set min alc target gain -12db and hold time 0ms*/
+ snd_soc_write(codec, WM8940_ALC3, 0x0042); /*ALC mode, DCY 384ms, ATK 24ms*/
+ snd_soc_write(codec, WM8940_ALC4, 0x0000); /*ZC OFF*/
+ snd_soc_write(codec, WM8940_NOISEGATE, 0x000f); /*Enable nosie gate and set threshold -81db*/
+ snd_soc_write(codec, WM8940_NOTCH8, 0x00c1); /*Set low pass filter from 15khz*/
+
+ /************************ PLAYBACK PATH SETTINGS *******************************/
+ snd_soc_write(codec, WM8940_DAC, 0x0000); /*Disable soft mute, Disable DAC auto mute, no inversion*/
+ snd_soc_write(codec, WM8940_DACVOL, 0x00ff); /*Set DACVOL 0dB*/
+ snd_soc_write(codec, WM8940_DACLIM1, 0x0000); /*Disable DAC Limiter*/
+ snd_soc_write(codec, WM8940_DACLIM2, 0x000c); /*Set DAC boost 12dB*/
+ snd_soc_write(codec, WM8940_SPKMIX, 0x0001); /*select output DAC to speaker mixer*/
+ snd_soc_write(codec, WM8940_SPKVOL, 0x003f); /*Eable speaker out and set speaker volume +6dB*/
+ snd_soc_write(codec, WM8940_MONOMIX, 0x0000); /*Not select DAC to mono*/
+
+ ret = snd_soc_add_codec_controls(codec, wm8940_snd_controls,
+ ARRAY_SIZE(wm8940_snd_controls));
+
+ return ret;
+}
+
+static int wm8940_remove(struct snd_soc_codec *codec)
+{
+ wm8940_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_wm8940 = {
+ .probe = wm8940_probe,
+ .remove = wm8940_remove,
+ .suspend = wm8940_suspend,
+ .resume = wm8940_resume,
+ .set_bias_level = wm8940_set_bias_level,
+ .reg_cache_size = ARRAY_SIZE(wm8940_reg_defaults),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8940_reg_defaults,
+ .reg_cache_step = 1,
+ .dapm_widgets = wm8940_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(wm8940_dapm_widgets),
+ .dapm_routes = audio_map,
+ .num_dapm_routes = ARRAY_SIZE(audio_map),
+};
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static int wm8940_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct wm8940_priv *wm8940;
+
+ wm8940 = devm_kzalloc(&i2c->dev, sizeof(struct wm8940_priv), GFP_KERNEL);
+ if (wm8940 == NULL)
+ return -ENOMEM;
+
+ i2c_set_clientdata(i2c, wm8940);
+
+ return snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8940, &wm8940_dai, 1);
+}
+
+static int wm8940_i2c_remove(struct i2c_client *client)
+{
+ snd_soc_unregister_codec(&client->dev);
+ return 0;
+}
+
+static struct of_device_id wm8940_of_match[] = {
+ { .compatible = "ambarella,wm8940",},
+ {},
+};
+MODULE_DEVICE_TABLE(of, wm8940_of_match);
+
+
+static const struct i2c_device_id wm8940_i2c_id[] = {
+ { "wm8940", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, wm8940_i2c_id);
+
+static struct i2c_driver wm8940_i2c_driver = {
+ .driver = {
+ .name = "wm8940-codec",
+ .owner = THIS_MODULE,
+ .of_match_table = wm8940_of_match,
+ },
+ .probe = wm8940_i2c_probe,
+ .remove = wm8940_i2c_remove,
+ .id_table = wm8940_i2c_id,
+};
+#endif
+
+static int __init wm8940_modinit(void)
+{
+ int ret = 0;
+
+ printk(KERN_INFO "wm8940_amb.c:: __init wm8940_modinit(void)\n");
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ ret = i2c_add_driver(&wm8940_i2c_driver);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register wm8940 I2C driver: %d\n",
+ ret);
+ }
+#endif
+ return ret;
+}
+module_init(wm8940_modinit);
+
+static void __exit wm8940_exit(void)
+{
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ i2c_del_driver(&wm8940_i2c_driver);
+#endif
+}
+module_exit(wm8940_exit);
+
+MODULE_DESCRIPTION("ASoC WM8940 driver");
+MODULE_AUTHOR("Wu Dongge <dgwu@ambarella.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8940_amb.h b/sound/soc/codecs/wm8940_amb.h
new file mode 100644
index 00000000..d60a97a2
--- /dev/null
+++ b/sound/soc/codecs/wm8940_amb.h
@@ -0,0 +1,110 @@
+/*
+ * wm8940_amb.h -- WM8940 Soc Audio driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _WM8940_AMB_H
+#define _WM8940_AMB_H
+
+struct wm8940_setup_data {
+ /* Vref to analogue output resistance */
+#define WM8940_VROI_1K 0
+#define WM8940_VROI_30K 1
+ unsigned int vroi:1;
+};
+
+/* WM8940 register space */
+#define WM8940_SOFTRESET 0x00
+#define WM8940_POWER1 0x01
+#define WM8940_POWER2 0x02
+#define WM8940_POWER3 0x03
+#define WM8940_IFACE 0x04
+#define WM8940_COMPANDINGCTL 0x05
+#define WM8940_CLOCK 0x06
+#define WM8940_ADDCNTRL 0x07
+#define WM8940_GPIO 0x08
+#define WM8940_CTLINT 0x09
+#define WM8940_DAC 0x0A
+#define WM8940_DACVOL 0x0B
+
+#define WM8940_ADC 0x0E
+#define WM8940_ADCVOL 0x0F
+#define WM8940_NOTCH1 0x10
+#define WM8940_NOTCH2 0x11
+#define WM8940_NOTCH3 0x12
+#define WM8940_NOTCH4 0x13
+#define WM8940_NOTCH5 0x14
+#define WM8940_NOTCH6 0x15
+#define WM8940_NOTCH7 0x16
+#define WM8940_NOTCH8 0x17
+#define WM8940_DACLIM1 0x18
+#define WM8940_DACLIM2 0x19
+
+#define WM8940_ALC1 0x20
+#define WM8940_ALC2 0x21
+#define WM8940_ALC3 0x22
+#define WM8940_NOISEGATE 0x23
+#define WM8940_PLLN 0x24
+#define WM8940_PLLK1 0x25
+#define WM8940_PLLK2 0x26
+#define WM8940_PLLK3 0x27
+
+#define WM8940_ALC4 0x2A
+
+#define WM8940_INPUTCTL 0x2C
+#define WM8940_PGAGAIN 0x2D
+
+#define WM8940_ADCBOOST 0x2F
+
+#define WM8940_OUTPUTCTL 0x31
+#define WM8940_SPKMIX 0x32
+
+#define WM8940_SPKVOL 0x36
+
+#define WM8940_MONOMIX 0x38
+
+#define WM8940_CACHEREGNUM 57
+
+
+/* Clock divider Id's */
+#define WM8940_BCLKDIV 0
+#define WM8940_MCLKDIV 1
+#define WM8940_OPCLKDIV 2
+
+/* Clock source */
+#define WM8940_MCLKIN 0
+#define WM8940_PLLOUT 1
+#define WM8940_MCLKIN_BCLKOUT 2
+
+/* MCLK clock dividers */
+#define WM8940_MCLKDIV_1 0
+#define WM8940_MCLKDIV_1_5 1
+#define WM8940_MCLKDIV_2 2
+#define WM8940_MCLKDIV_3 3
+#define WM8940_MCLKDIV_4 4
+#define WM8940_MCLKDIV_6 5
+#define WM8940_MCLKDIV_8 6
+#define WM8940_MCLKDIV_12 7
+
+/* BCLK clock dividers */
+#define WM8940_BCLKDIV_1 0
+#define WM8940_BCLKDIV_2 1
+#define WM8940_BCLKDIV_4 2
+#define WM8940_BCLKDIV_8 3
+#define WM8940_BCLKDIV_16 4
+#define WM8940_BCLKDIV_32 5
+
+/* PLL Out Dividers */
+#define WM8940_OPCLKDIV_1 0
+#define WM8940_OPCLKDIV_2 1
+#define WM8940_OPCLKDIV_3 2
+#define WM8940_OPCLKDIV_4 3
+
+#define WM8940_SYSCLK 0
+
+
+#endif /* _WM8940_H */
+
diff --git a/sound/soc/codecs/wm8974_amb.c b/sound/soc/codecs/wm8974_amb.c
new file mode 100644
index 00000000..40b8917a
--- /dev/null
+++ b/sound/soc/codecs/wm8974_amb.c
@@ -0,0 +1,800 @@
+/*
+ * wm8940_amb.c -- WM8940 ALSA Soc Audio driver
+ *
+ * Copyright 2011 Ambarella Ltd.
+ *
+ * Author: Wu Dongge <dgwu@ambarella.com>
+ *
+ * Based on wm8974.c
+ * Copyright 2006-2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Liam Girdwood <linux@wolfsonmicro.com>
+ *
+ * History:
+ * 2012/10/25 - [Wu Dongge] Created file
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+
+#include "wm8974_amb.h"
+
+static const u16 wm8974_reg[WM8974_CACHEREGNUM] = {
+ 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0050, 0x0000, 0x0140, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x00ff,
+ 0x0000, 0x0000, 0x0100, 0x00ff,
+ 0x0000, 0x0000, 0x012c, 0x002c,
+ 0x002c, 0x002c, 0x002c, 0x0000,
+ 0x0032, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0038, 0x000b, 0x0032, 0x0000,
+ 0x0008, 0x000c, 0x0093, 0x00e9,
+ 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0003, 0x0010, 0x0000, 0x0000,
+ 0x0000, 0x0002, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0039, 0x0000,
+ 0x0000,
+};
+
+#define WM8974_POWER1_BIASEN 0x08
+#define WM8974_POWER1_BUFIOEN 0x04
+
+struct wm8974_priv {
+ unsigned int sysclk;
+ enum snd_soc_control_type control_type;
+ void *control_data;
+};
+
+#define wm8974_reset(c) snd_soc_write(c, WM8974_RESET, 0)
+
+static const char *wm8974_companding[] = {"Off", "NC", "u-law", "A-law" };
+static const char *wm8974_deemp[] = {"None", "32kHz", "44.1kHz", "48kHz" };
+static const char *wm8974_eqmode[] = {"Capture", "Playback" };
+static const char *wm8974_bw[] = {"Narrow", "Wide" };
+static const char *wm8974_eq1[] = {"80Hz", "105Hz", "135Hz", "175Hz" };
+static const char *wm8974_eq2[] = {"230Hz", "300Hz", "385Hz", "500Hz" };
+static const char *wm8974_eq3[] = {"650Hz", "850Hz", "1.1kHz", "1.4kHz" };
+static const char *wm8974_eq4[] = {"1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz" };
+static const char *wm8974_eq5[] = {"5.3kHz", "6.9kHz", "9kHz", "11.7kHz" };
+static const char *wm8974_alc[] = {"ALC", "Limiter" };
+
+static const struct soc_enum wm8974_enum[] = {
+ SOC_ENUM_SINGLE(WM8974_COMP, 1, 4, wm8974_companding), /* adc */
+ SOC_ENUM_SINGLE(WM8974_COMP, 3, 4, wm8974_companding), /* dac */
+ SOC_ENUM_SINGLE(WM8974_DAC, 4, 4, wm8974_deemp),
+ SOC_ENUM_SINGLE(WM8974_EQ1, 8, 2, wm8974_eqmode),
+
+ SOC_ENUM_SINGLE(WM8974_EQ1, 5, 4, wm8974_eq1),
+ SOC_ENUM_SINGLE(WM8974_EQ2, 8, 2, wm8974_bw),
+ SOC_ENUM_SINGLE(WM8974_EQ2, 5, 4, wm8974_eq2),
+ SOC_ENUM_SINGLE(WM8974_EQ3, 8, 2, wm8974_bw),
+
+ SOC_ENUM_SINGLE(WM8974_EQ3, 5, 4, wm8974_eq3),
+ SOC_ENUM_SINGLE(WM8974_EQ4, 8, 2, wm8974_bw),
+ SOC_ENUM_SINGLE(WM8974_EQ4, 5, 4, wm8974_eq4),
+ SOC_ENUM_SINGLE(WM8974_EQ5, 8, 2, wm8974_bw),
+
+ SOC_ENUM_SINGLE(WM8974_EQ5, 5, 4, wm8974_eq5),
+ SOC_ENUM_SINGLE(WM8974_ALC3, 8, 2, wm8974_alc),
+};
+
+static const char *wm8974_auxmode_text[] = { "Buffer", "Mixer" };
+
+static const struct soc_enum wm8974_auxmode =
+ SOC_ENUM_SINGLE(WM8974_INPUT, 3, 2, wm8974_auxmode_text);
+
+static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1);
+static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
+static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1200, 75, 0);
+static const DECLARE_TLV_DB_SCALE(spk_tlv, -5700, 100, 0);
+
+static const struct snd_kcontrol_new wm8974_snd_controls[] = {
+
+SOC_SINGLE("Digital Loopback Switch", WM8974_COMP, 0, 1, 0),
+
+SOC_ENUM("DAC Companding", wm8974_enum[1]),
+SOC_ENUM("ADC Companding", wm8974_enum[0]),
+
+SOC_ENUM("Playback De-emphasis", wm8974_enum[2]),
+SOC_SINGLE("DAC Inversion Switch", WM8974_DAC, 0, 1, 0),
+
+SOC_SINGLE_TLV("PCM Volume", WM8974_DACVOL, 0, 255, 0, digital_tlv),
+
+SOC_SINGLE("High Pass Filter Switch", WM8974_ADC, 8, 1, 0),
+SOC_SINGLE("High Pass Cut Off", WM8974_ADC, 4, 7, 0),
+SOC_SINGLE("ADC Inversion Switch", WM8974_ADC, 0, 1, 0),
+
+SOC_SINGLE_TLV("Capture Volume", WM8974_ADCVOL, 0, 255, 0, digital_tlv),
+
+SOC_ENUM("Equaliser Function", wm8974_enum[3]),
+SOC_ENUM("EQ1 Cut Off", wm8974_enum[4]),
+SOC_SINGLE_TLV("EQ1 Volume", WM8974_EQ1, 0, 24, 1, eq_tlv),
+
+SOC_ENUM("Equaliser EQ2 Bandwith", wm8974_enum[5]),
+SOC_ENUM("EQ2 Cut Off", wm8974_enum[6]),
+SOC_SINGLE_TLV("EQ2 Volume", WM8974_EQ2, 0, 24, 1, eq_tlv),
+
+SOC_ENUM("Equaliser EQ3 Bandwith", wm8974_enum[7]),
+SOC_ENUM("EQ3 Cut Off", wm8974_enum[8]),
+SOC_SINGLE_TLV("EQ3 Volume", WM8974_EQ3, 0, 24, 1, eq_tlv),
+
+SOC_ENUM("Equaliser EQ4 Bandwith", wm8974_enum[9]),
+SOC_ENUM("EQ4 Cut Off", wm8974_enum[10]),
+SOC_SINGLE_TLV("EQ4 Volume", WM8974_EQ4, 0, 24, 1, eq_tlv),
+
+SOC_ENUM("Equaliser EQ5 Bandwith", wm8974_enum[11]),
+SOC_ENUM("EQ5 Cut Off", wm8974_enum[12]),
+SOC_SINGLE_TLV("EQ5 Volume", WM8974_EQ5, 0, 24, 1, eq_tlv),
+
+SOC_SINGLE("DAC Playback Limiter Switch", WM8974_DACLIM1, 8, 1, 0),
+SOC_SINGLE("DAC Playback Limiter Decay", WM8974_DACLIM1, 4, 15, 0),
+SOC_SINGLE("DAC Playback Limiter Attack", WM8974_DACLIM1, 0, 15, 0),
+
+SOC_SINGLE("DAC Playback Limiter Threshold", WM8974_DACLIM2, 4, 7, 0),
+SOC_SINGLE("DAC Playback Limiter Boost", WM8974_DACLIM2, 0, 15, 0),
+
+SOC_SINGLE("ALC Enable Switch", WM8974_ALC1, 8, 1, 0),
+SOC_SINGLE("ALC Capture Max Gain", WM8974_ALC1, 3, 7, 0),
+SOC_SINGLE("ALC Capture Min Gain", WM8974_ALC1, 0, 7, 0),
+
+SOC_SINGLE("ALC Capture ZC Switch", WM8974_ALC2, 8, 1, 0),
+SOC_SINGLE("ALC Capture Hold", WM8974_ALC2, 4, 15, 0),
+SOC_SINGLE("ALC Capture Target", WM8974_ALC2, 0, 15, 0),
+
+SOC_ENUM("ALC Capture Mode", wm8974_enum[13]),
+SOC_SINGLE("ALC Capture Decay", WM8974_ALC3, 4, 15, 0),
+SOC_SINGLE("ALC Capture Attack", WM8974_ALC3, 0, 15, 0),
+
+SOC_SINGLE("ALC Capture Noise Gate Switch", WM8974_NGATE, 3, 1, 0),
+SOC_SINGLE("ALC Capture Noise Gate Threshold", WM8974_NGATE, 0, 7, 0),
+
+SOC_SINGLE("Capture PGA ZC Switch", WM8974_INPPGA, 7, 1, 0),
+SOC_SINGLE_TLV("Capture PGA Volume", WM8974_INPPGA, 0, 63, 0, inpga_tlv),
+
+SOC_SINGLE("Speaker Playback ZC Switch", WM8974_SPKVOL, 7, 1, 0),
+SOC_SINGLE("Speaker Playback Switch", WM8974_SPKVOL, 6, 1, 1),
+SOC_SINGLE_TLV("Speaker Playback Volume", WM8974_SPKVOL, 0, 63, 0, spk_tlv),
+
+SOC_ENUM("Aux Mode", wm8974_auxmode),
+
+SOC_SINGLE("Capture Boost(+20dB)", WM8974_ADCBOOST, 8, 1, 0),
+SOC_SINGLE("Mono Playback Switch", WM8974_MONOMIX, 6, 1, 1),
+
+/* DAC / ADC oversampling */
+SOC_SINGLE("DAC 128x Oversampling Switch", WM8974_DAC, 3, 1, 0),
+SOC_SINGLE("ADC 128x Oversampling Switch", WM8974_ADC, 3, 1, 0),
+};
+
+/* Speaker Output Mixer */
+static const struct snd_kcontrol_new wm8974_speaker_mixer_controls[] = {
+SOC_DAPM_SINGLE("Line Bypass Switch", WM8974_SPKMIX, 1, 1, 0),
+SOC_DAPM_SINGLE("Aux Playback Switch", WM8974_SPKMIX, 5, 1, 0),
+SOC_DAPM_SINGLE("PCM Playback Switch", WM8974_SPKMIX, 0, 1, 0),
+};
+
+/* Mono Output Mixer */
+static const struct snd_kcontrol_new wm8974_mono_mixer_controls[] = {
+SOC_DAPM_SINGLE("Line Bypass Switch", WM8974_MONOMIX, 1, 1, 0),
+SOC_DAPM_SINGLE("Aux Playback Switch", WM8974_MONOMIX, 2, 1, 0),
+SOC_DAPM_SINGLE("PCM Playback Switch", WM8974_MONOMIX, 0, 1, 0),
+};
+
+static DECLARE_TLV_DB_SCALE(wm8974_boost_vol_tlv, -1500, 300, 1);
+/* Boost mixer */
+static const struct snd_kcontrol_new wm8974_boost_mixer[] = {
+ SOC_DAPM_SINGLE("Mic PGA Switch", WM8974_INPPGA, 6, 1, 1),
+ SOC_DAPM_SINGLE_TLV("Aux Volume", WM8974_ADCBOOST,
+ 0, 7, 0, wm8974_boost_vol_tlv),
+ SOC_DAPM_SINGLE_TLV("Mic Volume", WM8974_ADCBOOST,
+ 4, 7, 0, wm8974_boost_vol_tlv),
+};
+
+/* Input PGA */
+static const struct snd_kcontrol_new wm8974_inpga[] = {
+SOC_DAPM_SINGLE("Aux Switch", WM8974_INPUT, 2, 1, 0),
+SOC_DAPM_SINGLE("MicN Switch", WM8974_INPUT, 1, 1, 0),
+SOC_DAPM_SINGLE("MicP Switch", WM8974_INPUT, 0, 1, 0),
+};
+
+static const struct snd_soc_dapm_widget wm8974_dapm_widgets[] = {
+SND_SOC_DAPM_MIXER("Speaker Mixer", WM8974_POWER3, 2, 0,
+ &wm8974_speaker_mixer_controls[0],
+ ARRAY_SIZE(wm8974_speaker_mixer_controls)),
+SND_SOC_DAPM_MIXER("Mono Mixer", WM8974_POWER3, 3, 0,
+ &wm8974_mono_mixer_controls[0],
+ ARRAY_SIZE(wm8974_mono_mixer_controls)),
+SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8974_POWER3, 0, 0),
+
+SND_SOC_DAPM_PGA("SpkN Out", WM8974_POWER3, 5, 0, NULL, 0),
+SND_SOC_DAPM_PGA("SpkP Out", WM8974_POWER3, 6, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Mono Out", WM8974_POWER3, 7, 0, NULL, 0),
+SND_SOC_DAPM_OUTPUT("MONOOUT"),
+SND_SOC_DAPM_OUTPUT("SPKOUTP"),
+SND_SOC_DAPM_OUTPUT("SPKOUTN"),
+
+SND_SOC_DAPM_PGA("Aux Input", WM8974_POWER1, 6, 0, NULL, 0),
+SND_SOC_DAPM_ADC("ADC", "HiFi Capture", WM8974_POWER2, 0, 0),
+SND_SOC_DAPM_MIXER("Input PGA", WM8974_POWER2, 2, 0, &wm8974_inpga[0],
+ ARRAY_SIZE(wm8974_inpga)),
+SND_SOC_DAPM_MIXER("Boost Mixer", WM8974_POWER2, 4, 0,
+ &wm8974_boost_mixer[0], ARRAY_SIZE(wm8974_boost_mixer)),
+
+SND_SOC_DAPM_MICBIAS("Mic Bias", WM8974_POWER1, 4, 0),
+
+SND_SOC_DAPM_INPUT("MICN"),
+SND_SOC_DAPM_INPUT("MICP"),
+SND_SOC_DAPM_INPUT("AUX"),
+};
+
+static const struct snd_soc_dapm_route wm8974_dapm_routes[] = {
+ /* Mono output mixer */
+ {"Mono Mixer", "PCM Playback Switch", "DAC"},
+ {"Mono Mixer", "Aux Playback Switch", "Aux Input"},
+ {"Mono Mixer", "Line Bypass Switch", "Boost Mixer"},
+
+ /* Speaker output mixer */
+ {"Speaker Mixer", "PCM Playback Switch", "DAC"},
+ {"Speaker Mixer", "Aux Playback Switch", "Aux Input"},
+ {"Speaker Mixer", "Line Bypass Switch", "Boost Mixer"},
+
+ /* Outputs */
+ {"Mono Out", NULL, "Mono Mixer"},
+ {"MONOOUT", NULL, "Mono Out"},
+ {"SpkN Out", NULL, "Speaker Mixer"},
+ {"SpkP Out", NULL, "Speaker Mixer"},
+ {"SPKOUTN", NULL, "SpkN Out"},
+ {"SPKOUTP", NULL, "SpkP Out"},
+
+ /* Boost Mixer */
+ {"ADC", NULL, "Boost Mixer"},
+
+ {"Boost Mixer", "Aux Volume", "Aux Input"},
+ {"Boost Mixer", "Mic PGA Switch", "Input PGA"},
+ {"Boost Mixer", "Mic Volume", "MICP"},
+
+ /* Input PGA */
+ {"Input PGA", "Aux Switch", "AUX"},
+ {"Input PGA", "MicN Switch", "MICN"},
+ {"Input PGA", "MicP Switch", "MICP"},
+
+ /* Inputs */
+ //{"Aux Input", NULL, "AUX"},
+};
+
+struct pll_ {
+ unsigned int pre_div:1;
+ unsigned int n:4;
+ unsigned int k;
+};
+
+/* The size in bits of the pll divide multiplied by 10
+ * to allow rounding later */
+#define FIXED_PLL_SIZE ((1 << 24) * 10)
+
+static void pll_factors(struct pll_ *pll_div,
+ unsigned int target, unsigned int source)
+{
+ unsigned long long Kpart;
+ unsigned int K, Ndiv, Nmod;
+
+ /* There is a fixed divide by 4 in the output path */
+ target *= 4;
+
+ Ndiv = target / source;
+ if (Ndiv < 6) {
+ source /= 2;
+ pll_div->pre_div = 1;
+ Ndiv = target / source;
+ } else
+ pll_div->pre_div = 0;
+
+ if ((Ndiv < 6) || (Ndiv > 12))
+ printk(KERN_WARNING
+ "WM8974 N value %u outwith recommended range!\n",
+ Ndiv);
+
+ pll_div->n = Ndiv;
+ Nmod = target % source;
+ Kpart = FIXED_PLL_SIZE * (long long)Nmod;
+
+ do_div(Kpart, source);
+
+ K = Kpart & 0xFFFFFFFF;
+
+ /* Check if we need to round */
+ if ((K % 10) >= 5)
+ K += 5;
+
+ /* Move down to proper range now rounding is done */
+ K /= 10;
+
+ pll_div->k = K;
+}
+
+static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
+ int source, unsigned int freq_in, unsigned int freq_out)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct pll_ pll_div;
+ u16 reg;
+
+ if (freq_in == 0 || freq_out == 0) {
+ /* Clock CODEC directly from MCLK */
+ reg = snd_soc_read(codec, WM8974_CLOCK);
+ snd_soc_write(codec, WM8974_CLOCK, reg & 0x0ff);
+
+ /* Turn off PLL */
+ reg = snd_soc_read(codec, WM8974_POWER1);
+ snd_soc_write(codec, WM8974_POWER1, reg & 0x1df);
+ return 0;
+ }
+
+ pll_factors(&pll_div, freq_out, freq_in);
+
+ snd_soc_write(codec, WM8974_PLLN, (pll_div.pre_div << 4) | pll_div.n);
+ snd_soc_write(codec, WM8974_PLLK1, pll_div.k >> 18);
+ snd_soc_write(codec, WM8974_PLLK2, (pll_div.k >> 9) & 0x1ff);
+ snd_soc_write(codec, WM8974_PLLK3, pll_div.k & 0x1ff);
+ reg = snd_soc_read(codec, WM8974_POWER1);
+ snd_soc_write(codec, WM8974_POWER1, reg | 0x020);
+
+ /* Run CODEC from PLL instead of MCLK */
+ reg = snd_soc_read(codec, WM8974_CLOCK);
+ snd_soc_write(codec, WM8974_CLOCK, reg | 0x100);
+
+ return 0;
+}
+
+static int wm8974_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct wm8974_priv *wm8974 = snd_soc_codec_get_drvdata(codec);
+ u16 reg;
+
+ switch(clk_id) {
+ case WM8974_MCLKIN:
+ /* Clock CODEC directly from MCLK */
+ reg = snd_soc_read(codec, WM8974_CLOCK) & 0x0fe;
+ snd_soc_write(codec, WM8974_CLOCK, reg);
+
+ /* Turn off PLL */
+ reg = snd_soc_read(codec, WM8974_POWER1);
+ snd_soc_write(codec, WM8974_POWER1, reg & 0x1df);
+ break;
+ case WM8974_PLLOUT:
+ /* Clock CODEC is generated by PLL */
+ reg = snd_soc_read(codec, WM8974_CLOCK) & 0x0fe;
+ reg |= 0x100;
+ snd_soc_write(codec, WM8974_CLOCK, reg);
+
+ /* Turn on PLL */
+ reg = snd_soc_read(codec, WM8974_POWER1);
+ snd_soc_write(codec, WM8974_POWER1, reg | 0x020);
+
+// wm8974_set_dai_pll(codec_dai, clk_id, 0, freq, request_out);
+ break;
+ case WM8974_MCLKIN_BCLKOUT:
+ reg = snd_soc_read(codec, WM8974_CLOCK) & 0x0fe;
+ reg |= 0x001;
+ snd_soc_write(codec, WM8974_CLOCK, reg);
+
+ /* Turn on PLL */
+ reg = snd_soc_read(codec, WM8974_POWER1);
+ snd_soc_write(codec, WM8974_POWER1, reg | 0x020);
+
+// wm8974_set_dai_pll(codec_dai, clk_id, 0, freq, request_out);
+ break;
+
+ }
+
+
+ wm8974->sysclk = freq;
+ return 0;
+}
+
+/*
+ * Configure WM8974 clock dividers.
+ */
+static int wm8974_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
+ int div_id, int div)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 reg;
+
+ switch (div_id) {
+ case WM8974_OPCLKDIV:
+ reg = snd_soc_read(codec, WM8974_GPIO) & 0x1cf;
+ snd_soc_write(codec, WM8974_GPIO, reg | div);
+ break;
+ case WM8974_MCLKDIV:
+ reg = snd_soc_read(codec, WM8974_CLOCK) & 0x11f;
+ snd_soc_write(codec, WM8974_CLOCK, reg | div);
+ break;
+ case WM8974_BCLKDIV:
+ reg = snd_soc_read(codec, WM8974_CLOCK) & 0x1e3;
+ snd_soc_write(codec, WM8974_CLOCK, reg | div);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int wm8974_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 iface = 0;
+ u16 clk = snd_soc_read(codec, WM8974_CLOCK) & 0x1fe;
+
+ /* set master/slave audio interface */
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ clk |= 0x0001;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* interface format */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ iface |= 0x0010;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ iface |= 0x0008;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ iface |= 0x00018;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* clock inversion */
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ iface |= 0x0180;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ iface |= 0x0100;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ iface |= 0x0080;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_write(codec, WM8974_IFACE, iface);
+ snd_soc_write(codec, WM8974_CLOCK, clk);
+ return 0;
+}
+
+static int wm8974_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ u16 iface = snd_soc_read(codec, WM8974_IFACE) & 0x19f;
+ u16 adn = snd_soc_read(codec, WM8974_ADD) & 0x1f1;
+
+ /* bit size */
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ iface |= 0x0020;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ iface |= 0x0040;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ iface |= 0x0060;
+ break;
+ }
+
+ /* filter coefficient */
+ switch (params_rate(params)) {
+ case 8000:
+ adn |= (0x5 << 1);
+ break;
+ case 11025:
+ case 12000:
+ adn |= (0x4 << 1);
+ break;
+ case 16000:
+ adn |= (0x3 << 1);
+ break;
+ case 24000:
+ case 22050:
+ adn |= (0x2 << 1);
+ break;
+ case 32000:
+ adn |= (0x1 << 1);
+ break;
+ case 44100:
+ case 48000:
+ break;
+ }
+
+ snd_soc_write(codec, WM8974_IFACE, iface);
+ snd_soc_write(codec, WM8974_ADD, adn);
+ return 0;
+}
+
+static int wm8974_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ u16 mute_reg = snd_soc_read(codec, WM8974_DAC) & 0xffbf;
+
+ if (mute)
+ snd_soc_write(codec, WM8974_DAC, mute_reg | 0x40);
+ else
+ snd_soc_write(codec, WM8974_DAC, mute_reg);
+ return 0;
+}
+
+static int wm8974_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ u16 val = 0;
+ u16 pwr_reg = snd_soc_read(codec, WM8974_POWER1) & 0x170;
+ int ret = 0;
+
+ //printk("****wm8974_set_bias_level: level: %d\n", level);
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ /* ensure bufioen and biasen and micben */
+ pwr_reg |= (1 << 2) | (1 << 3) | (1 << 4);
+ /* Enable thermal shutdown */
+ val = snd_soc_read(codec, WM8974_OUTPUT);
+ ret = snd_soc_write(codec, WM8974_OUTPUT, val | 0x2);
+ if (ret)
+ break;
+ /* set vmid to 50k */
+ ret = snd_soc_write(codec, WM8974_POWER1, pwr_reg | 0x1);
+ break;
+ case SND_SOC_BIAS_PREPARE:
+ /* ensure bufioen and biasen */
+ pwr_reg |= (1 << 2) | (1 << 3);
+ ret = snd_soc_write(codec, WM8974_POWER1, pwr_reg | 0x1);
+ break;
+ case SND_SOC_BIAS_STANDBY:
+ /* ensure bufioen and biasen */
+ pwr_reg |= (1 << 2) | (1 << 3);
+ /* set vmid to 300k for standby */
+ ret = snd_soc_write(codec, WM8974_POWER1, pwr_reg | 0x2);
+ break;
+ case SND_SOC_BIAS_OFF:
+ ret = snd_soc_write(codec, WM8974_POWER1, 0);
+ ret = snd_soc_write(codec, WM8974_POWER2, 0);
+ ret = snd_soc_write(codec, WM8974_POWER3, 0);
+ break;
+ }
+
+ codec->dapm.bias_level = level;
+
+ return ret;
+}
+
+#define WM8974_RATES (SNDRV_PCM_RATE_8000_48000)
+
+#define WM8974_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
+ SNDRV_PCM_FMTBIT_S24_LE)
+
+static const struct snd_soc_dai_ops wm8974_ops = {
+ .hw_params = wm8974_pcm_hw_params,
+ .set_sysclk = wm8974_set_dai_sysclk,
+ .digital_mute = wm8974_mute,
+ .set_fmt = wm8974_set_dai_fmt,
+ .set_clkdiv = wm8974_set_dai_clkdiv,
+ .set_pll = wm8974_set_dai_pll,
+};
+
+static struct snd_soc_dai_driver wm8974_dai = {
+ .name = "wm8974-hifi",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 2, /* Only 1 channel of data */
+ .rates = WM8974_RATES,
+ .formats = WM8974_FORMATS,},
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2, /* Only 1 channel of data */
+ .rates = WM8974_RATES,
+ .formats = WM8974_FORMATS,},
+ .ops = &wm8974_ops,
+ .symmetric_rates = 1,
+};
+
+static int wm8974_suspend(struct snd_soc_codec *codec)
+{
+ wm8974_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static int wm8974_resume(struct snd_soc_codec *codec)
+{
+ snd_soc_cache_sync(codec);
+ wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ return 0;
+}
+
+static int wm8974_probe(struct snd_soc_codec *codec)
+{
+ int ret = 0;
+ printk(KERN_NOTICE "wm8974 audio codec is provided by amba Wu Dongge\n");
+
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
+ }
+
+ ret = wm8974_reset(codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to issue reset\n");
+ return ret;
+ }
+
+ wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ snd_soc_write(codec, WM8974_POWER1, 0x180);
+
+ /************************ RECORD PATH SETTINGS *******************************/
+ snd_soc_write(codec, WM8974_CLOCK, 0x0000); /*set MCLK, MCLKDIV 1, BCLKDIV 1, BCLK and frame clock are inputs*/
+ snd_soc_write(codec, WM8974_GPIO, 0x0000);
+ snd_soc_write(codec, WM8974_ADD, 0x0000);
+ snd_soc_write(codec, WM8974_INPUT, 0x0103);
+ snd_soc_write(codec, WM8974_INPPGA, 0x003f); /*set PGA gain max 35.25db*/
+ snd_soc_write(codec, WM8974_ADCBOOST, 0x0100); /*set PGB2BOOST, MICP2BOOSTVOL gain*/
+ snd_soc_write(codec, WM8974_ADC, 0x0188); /*Enable high pass filter, select audio mode*/
+ snd_soc_write(codec, WM8974_ADCVOL, 0x00ff); /*Set ADC vol, 0db*/
+
+ snd_soc_write(codec, WM8974_ALC1, 0x00134); /*Enable ALC, set max gain +29.25db and min gain +12db*/
+ snd_soc_write(codec, WM8974_ALC2, 0x003c); /* disable zero cross switch, hold = 11ms, target= -10.5db */
+ snd_soc_write(codec, WM8974_ALC3, 0x0098); /* ALC mode, Decay = 9, attack = 8*/
+
+ snd_soc_write(codec, WM8974_NGATE, 0x000c); /*Enable nosie gate and set threshold -63db*/
+
+ /************************ PLAYBACK PATH SETTINGS *******************************/
+ snd_soc_write(codec, WM8974_DAC, 0x0008); /*Disable soft mute, Disable DAC auto mute, no inversion*/
+ snd_soc_write(codec, WM8974_DACVOL, 0x00ff); /*Set DACVOL 0dB*/
+ snd_soc_write(codec, WM8974_DACLIM1, 0x0000); /*Disable DAC Limiter*/
+ snd_soc_write(codec, WM8974_DACLIM2, 0x000c); /*Set DAC boost 12dB*/
+ snd_soc_write(codec, WM8974_PLLN, 0x0080); /*PLL power OFF*/
+ snd_soc_write(codec, WM8974_SPKMIX, 0x0001); /*select output DAC to speaker mixer*/
+ snd_soc_write(codec, WM8974_SPKVOL, 0x003f); /*Eable speaker out and set speaker volume +6dB*/
+ snd_soc_write(codec, WM8974_MONOMIX, 0x0000); /*Not select DAC to mono*/
+
+ ret = snd_soc_add_codec_controls(codec, wm8974_snd_controls,
+ ARRAY_SIZE(wm8974_snd_controls));
+
+ return ret;
+}
+
+/* power down chip */
+static int wm8974_remove(struct snd_soc_codec *codec)
+{
+ wm8974_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_wm8974 = {
+ .probe = wm8974_probe,
+ .remove = wm8974_remove,
+ .suspend = wm8974_suspend,
+ .resume = wm8974_resume,
+ .set_bias_level = wm8974_set_bias_level,
+ .reg_cache_size = ARRAY_SIZE(wm8974_reg),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8974_reg,
+ .reg_cache_step = 1,
+ .dapm_widgets = wm8974_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(wm8974_dapm_widgets),
+ .dapm_routes = wm8974_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(wm8974_dapm_routes),
+};
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static int wm8974_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct wm8974_priv *wm8974;
+
+ wm8974 = devm_kzalloc(&i2c->dev, sizeof(struct wm8974_priv), GFP_KERNEL);
+ if (wm8974 == NULL)
+ return -ENOMEM;
+
+ i2c_set_clientdata(i2c, wm8974);
+
+ return snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8974, &wm8974_dai, 1);
+}
+
+static int wm8974_i2c_remove(struct i2c_client *client)
+{
+ snd_soc_unregister_codec(&client->dev);
+ return 0;
+}
+
+static struct of_device_id wm8974_of_match[] = {
+ { .compatible = "ambarella,wm8974",},
+ {},
+};
+MODULE_DEVICE_TABLE(of, wm8974_of_match);
+
+
+static const struct i2c_device_id wm8974_i2c_id[] = {
+ { "wm8974", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, wm8974_i2c_id);
+
+static struct i2c_driver wm8974_i2c_driver = {
+ .driver = {
+ .name = "wm8974-codec",
+ .owner = THIS_MODULE,
+ .of_match_table = wm8974_of_match,
+ },
+ .probe = wm8974_i2c_probe,
+ .remove = wm8974_i2c_remove,
+ .id_table = wm8974_i2c_id,
+};
+#endif
+
+static int __init wm8974_modinit(void)
+{
+ int ret = 0;
+
+ printk(KERN_INFO "wm8974_amb.c :: __init wm8974_modinit(void)\n");
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ ret = i2c_add_driver(&wm8974_i2c_driver);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register wm8974 I2C driver: %d\n",
+ ret);
+ }
+#endif
+ return ret;
+}
+module_init(wm8974_modinit);
+
+static void __exit wm8974_exit(void)
+{
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ i2c_del_driver(&wm8974_i2c_driver);
+#endif
+}
+module_exit(wm8974_exit);
+
+MODULE_DESCRIPTION("ASoC WM8974 driver");
+MODULE_AUTHOR("Wu Dongge");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8974_amb.h b/sound/soc/codecs/wm8974_amb.h
new file mode 100644
index 00000000..b82e31b8
--- /dev/null
+++ b/sound/soc/codecs/wm8974_amb.h
@@ -0,0 +1,94 @@
+/*
+ * wm8974_amb.h -- WM8974 Soc Audio driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _WM8974_AMB_H
+#define _WM8974_AMB_H
+
+/* WM8974 register space */
+
+#define WM8974_RESET 0x0
+#define WM8974_POWER1 0x1
+#define WM8974_POWER2 0x2
+#define WM8974_POWER3 0x3
+#define WM8974_IFACE 0x4
+#define WM8974_COMP 0x5
+#define WM8974_CLOCK 0x6
+#define WM8974_ADD 0x7
+#define WM8974_GPIO 0x8
+#define WM8974_DAC 0xa
+#define WM8974_DACVOL 0xb
+#define WM8974_ADC 0xe
+#define WM8974_ADCVOL 0xf
+#define WM8974_EQ1 0x12
+#define WM8974_EQ2 0x13
+#define WM8974_EQ3 0x14
+#define WM8974_EQ4 0x15
+#define WM8974_EQ5 0x16
+#define WM8974_DACLIM1 0x18
+#define WM8974_DACLIM2 0x19
+#define WM8974_NOTCH1 0x1b
+#define WM8974_NOTCH2 0x1c
+#define WM8974_NOTCH3 0x1d
+#define WM8974_NOTCH4 0x1e
+#define WM8974_ALC1 0x20
+#define WM8974_ALC2 0x21
+#define WM8974_ALC3 0x22
+#define WM8974_NGATE 0x23
+#define WM8974_PLLN 0x24
+#define WM8974_PLLK1 0x25
+#define WM8974_PLLK2 0x26
+#define WM8974_PLLK3 0x27
+#define WM8974_ATTEN 0x28
+#define WM8974_INPUT 0x2c
+#define WM8974_INPPGA 0x2d
+#define WM8974_ADCBOOST 0x2f
+#define WM8974_OUTPUT 0x31
+#define WM8974_SPKMIX 0x32
+#define WM8974_SPKVOL 0x36
+#define WM8974_MONOMIX 0x38
+
+#define WM8974_CACHEREGNUM 57
+
+/* Clock divider Id's */
+#define WM8974_OPCLKDIV 0
+#define WM8974_MCLKDIV 1
+#define WM8974_BCLKDIV 2
+
+/* Clock source */
+#define WM8974_MCLKIN 0
+#define WM8974_PLLOUT 1
+#define WM8974_MCLKIN_BCLKOUT 2
+
+/* PLL Out dividers */
+#define WM8974_OPCLKDIV_1 (0 << 4)
+#define WM8974_OPCLKDIV_2 (1 << 4)
+#define WM8974_OPCLKDIV_3 (2 << 4)
+#define WM8974_OPCLKDIV_4 (3 << 4)
+
+/* BCLK clock dividers */
+#define WM8974_BCLKDIV_1 (0 << 2)
+#define WM8974_BCLKDIV_2 (1 << 2)
+#define WM8974_BCLKDIV_4 (2 << 2)
+#define WM8974_BCLKDIV_8 (3 << 2)
+#define WM8974_BCLKDIV_16 (4 << 2)
+#define WM8974_BCLKDIV_32 (5 << 2)
+
+/* MCLK clock dividers */
+#define WM8974_MCLKDIV_1 (0 << 5)
+#define WM8974_MCLKDIV_1_5 (1 << 5)
+#define WM8974_MCLKDIV_2 (2 << 5)
+#define WM8974_MCLKDIV_3 (3 << 5)
+#define WM8974_MCLKDIV_4 (4 << 5)
+#define WM8974_MCLKDIV_6 (5 << 5)
+#define WM8974_MCLKDIV_8 (6 << 5)
+#define WM8974_MCLKDIV_12 (7 << 5)
+
+#define WM8974_SYSCLK 0
+
+
+#endif
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index cda3cf23..8d62148b 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -4218,7 +4218,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
break;
}
- wm_hubs_add_analogue_routes(codec, 0, 0);
+ wm_hubs_add_analogue_routes(codec, control->pdata.lineout1_diff,
+ control->pdata.lineout2_diff);
snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
switch (control->type) {
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 7a0466eb..875e211f 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -1104,8 +1104,8 @@ static const struct snd_soc_dapm_route lineout1_se_routes[] = {
};
static const struct snd_soc_dapm_route lineout2_diff_routes[] = {
- { "LINEOUT2 Mixer", "IN1L Switch", "IN1L PGA" },
- { "LINEOUT2 Mixer", "IN1R Switch", "IN1R PGA" },
+ { "LINEOUT2 Mixer", "IN2L Switch", "IN2L PGA" },
+ { "LINEOUT2 Mixer", "IN2R Switch", "IN2R PGA" },
{ "LINEOUT2 Mixer", "Output Switch", "Right Output PGA" },
{ "LINEOUT2N Driver", NULL, "LINEOUT2 Mixer" },
diff --git a/sound/soc/codecs/zl380tw.c b/sound/soc/codecs/zl380tw.c
new file mode 100644
index 00000000..328252ac
--- /dev/null
+++ b/sound/soc/codecs/zl380tw.c
@@ -0,0 +1,3114 @@
+/*
+ * zl380tw.c -- zl380tw ALSA Soc Audio driver
+ *
+ * Copyright 2014 Microsemi Inc.
+ * History:
+ * 2015/02/15 - created driver that combines a CHAR,
+ an ASLSA and a SPI/I2C driver in on single module
+ * 2015/03/24 - Added compatibility to linux kernel 2.6.x to 3.x.x
+ * - Verified with Linux kernels 2.6.38, and 3.10.50
+ * 2015/09/30 - Added option to compile the firmware/config in c format with the kernel
+ * 2015/10/7 - Updated the save config to flash to allow saving multiple config to flash
+ * This program is free software you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option)any later version.
+ */
+
+#define DEBUG
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/device.h>
+#include <linux/sysfs.h>
+#include <linux/slab.h>
+#include <linux/kthread.h>
+#include <linux/version.h>
+#include <linux/err.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+
+#include "zl380tw.h"
+#ifdef ZL380XX_TW_UPDATE_FIRMWARE
+#ifdef ZL380TW_INCLUDE_FIRMWARE_REQUEST_LIB
+#include <linux/firmware.h>
+#else
+/*compile the firmware.c and config.c in*/
+#include "zl380tw_firmware.c"
+#include "zl380tw_config.c"
+#endif /*ZL380TW_INCLUDE_FIRMWARE_REQUEST_LIB*/
+#endif /*ZL380XX_TW_UPDATE_FIRMWARE*/
+
+#ifdef SUPPORT_LINUX_DEVICE_TREE_OF_MATCHING
+#include <linux/compat.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#endif /*SUPPORT_LINUX_DEVICE_TREE_OF_MATCHING*/
+
+#ifdef MICROSEMI_HBI_SPI
+#include <linux/spi/spi.h>
+#endif
+
+#ifdef MICROSEMI_HBI_I2C
+#include <linux/i2c.h>
+#endif
+
+#ifdef ZL380XX_TW_ENABLE_ALSA_CODEC_DRIVER
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/initval.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/pcm_params.h>
+#include <sound/tlv.h>
+#endif
+
+#ifdef ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/uaccess.h>
+#endif
+
+/*define this macro for critical region protection*/
+#ifdef PROTECT_CRITICAL_SECTION
+#include <linux/mutex.h>
+#endif
+
+#define MSCCDEBUG
+#undef MSCCDEBUG2
+
+#ifdef MSCCDEBUG
+#define TW_DEBUG1(s, args...) \
+ pr_err("%s %d: "s, __func__, __LINE__, ##args);
+
+#else
+#define TW_DEBUG1(s, args...)
+#endif
+
+#ifdef MSCCDEBUG2
+#define TW_DEBUG2(s, args...) \
+ pr_err("%s %d: "s, __func__, __LINE__, ##args);
+
+#else
+#define TW_DEBUG2(s, args...)
+#endif
+
+
+/*TWOLF HBI ACCESS MACROS-------------------------------*/
+#define HBI_PAGED_READ(offset,length) \
+ ((u16)(((u16)(offset) << 8) | (length)))
+#define HBI_DIRECT_READ(offset,length) \
+ ((u16)(0x8000 | ((u16)(offset) << 8) | (length)))
+#define HBI_PAGED_WRITE(offset,length) \
+ ((u16)(HBI_PAGED_READ(offset,length) | 0x0080))
+#define HBI_DIRECT_WRITE(offset,length) \
+ ((u16)(HBI_DIRECT_READ(offset,length) | 0x0080))
+#define HBI_GLOBAL_DIRECT_WRITE(offset,length) \
+ ((u16)(0xFC00 | ((offset) << 4) | (length)))
+#define HBI_CONFIGURE(pinConfig) \
+ ((u16)(0xFD00 | (pinConfig)))
+#define HBI_SELECT_PAGE(page) \
+ ((u16)(0xFE00 | (page)))
+#define HBI_NO_OP \
+ ((u16)0xFFFF)
+
+/*HBI access type*/
+#define TWOLF_HBI_READ 0
+#define TWOLF_HBI_WRITE 1
+/*HBI address type*/
+#define TWOLF_HBI_DIRECT 2
+#define TWOLF_HBI_PAGED 3
+
+/* driver private data */
+struct zl380tw {
+#ifdef MICROSEMI_HBI_SPI
+ struct spi_device *spi;
+#endif
+#ifdef MICROSEMI_HBI_I2C
+ struct i2c_client *i2c;
+#endif
+ u8 *pData;
+ int sysclk_rate;
+#ifdef PROTECT_CRITICAL_SECTION
+ struct list_head device_entry;
+#endif
+ u8 flag;
+ u8 init_done;
+ int pwr_pin;
+ unsigned int pwr_active;
+ int rst_pin;
+ unsigned int rst_active;
+
+} *zl380tw_priv;
+
+#ifdef ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER
+dev_t t_dev;
+
+/* For registration of character device */
+static struct cdev c_dev;
+static ioctl_zl380tw zl380tw_ioctl_buf;
+#endif
+static int module_usage_count;
+
+static unsigned twHBImaxTransferSize =(MAX_TWOLF_ACCESS_SIZE_IN_BYTES);
+module_param(twHBImaxTransferSize, uint, S_IRUGO);
+MODULE_PARM_DESC(twHBImaxTransferSize, "total number of data bytes >= 264");
+
+#ifdef ZL380XX_TW_UPDATE_FIRMWARE
+#ifdef ZL380TW_INCLUDE_FIRMWARE_REQUEST_LIB
+static char *zl380tw_firmware_name = ZLS380TW0_TWOLF;
+module_param(zl380tw_firmware_name, charp, 0000);
+MODULE_PARM_DESC(zl380tw_firmware_name, "A character string");
+#ifdef ZL380XX_TW_UPDATE_CONFIG
+static char *zl380tw_config_name = ZLS380TW0_TWOLF_CRK;
+module_param(zl380tw_config_name, charp, 0000);
+MODULE_PARM_DESC(zl380tw_config_name, "A character string");
+#endif /*ZL380XX_TW_UPDATE_CONFIG*/
+#endif /*ZL380TW_INCLUDE_FIRMWARE_REQUEST_LIB*/
+#endif /*ZL380XX_TW_UPDATE_FIRMWARE*/
+
+/* if mutual exclusion is required for your particular platform
+ * then add mutex lock/unlock to this driver
+ */
+#ifdef PROTECT_CRITICAL_SECTION
+static DEFINE_MUTEX(lock);
+static DEFINE_MUTEX(zl380tw_list_lock);
+static LIST_HEAD(zl380tw_list);
+#endif
+
+/* if mutual exclusion is required for your particular platform
+ * then add mutex lock/unlock to this driver
+ */
+
+static void zl380twEnterCritical(void)
+{
+#ifdef PROTECT_CRITICAL_SECTION
+ mutex_lock(&lock);
+#endif
+}
+
+static void zl380twExitCritical(void)
+{
+#ifdef PROTECT_CRITICAL_SECTION
+ mutex_unlock(&lock);
+#endif
+}
+
+
+/* write up to 252 bytes data */
+/* zl380tw_nbytes_wr()- rewrite one or up to 252 bytes to the device
+ * \param[in] ptwdata pointer to the data to write
+ * \param[in] numbytes the number of bytes to write
+ *
+ * return ::status = the total number of bytes transferred successfully
+ * or a negative error code
+ */
+static int
+zl380tw_nbytes_wr(struct zl380tw *zl380tw,
+ int numbytes, u8 *pData)
+{
+
+ int status;
+#ifdef MICROSEMI_HBI_SPI
+ struct spi_message msg;
+ struct spi_transfer xfer = {
+ .len = numbytes,
+ .tx_buf = pData,
+ };
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ status = spi_sync(zl380tw->spi, &msg);
+#endif
+#ifdef MICROSEMI_HBI_I2C
+ status = i2c_master_send(zl380tw->i2c, pData, numbytes);
+#endif
+ if (status < 0)
+ return -EFAULT;
+
+ return 0;
+}
+
+/* zl38040_hbi_rd16()- Decode the 16-bit T-WOLF Regs Host address into
+ * page, offset and build the 16-bit command acordingly to the access type.
+ * then read the 16-bit word data and store it in pdata
+ * \param[in]
+ * .addr the 16-bit HBI address
+ * .pdata pointer to the data buffer read or write
+ *
+ * return ::status
+ */
+static int zl380tw_hbi_rd16(struct zl380tw *zl380tw,
+ u16 addr, u16 *pdata)
+{
+
+ u16 cmd;
+ u8 page;
+ u8 offset;
+ u8 i = 0;
+ u8 buf[4] = {0, 0, 0, 0};
+
+ int status =0;
+#ifdef MICROSEMI_HBI_I2C
+ struct i2c_msg msg[2];
+#endif
+
+ page = addr >> 8;
+ offset = (addr & 0xFF)>>1;
+
+ if (page == 0) /*Direct page access*/
+ {
+ cmd = HBI_DIRECT_READ(offset, 0);/*build the cmd*/
+ buf[i++] = (cmd >> 8) & 0xFF;
+ buf[i++] = (cmd & 0xFF);
+
+ } else { /*indirect page access*/
+ if (page != 0xFF) {
+ page -= 1;
+ }
+ cmd = HBI_SELECT_PAGE(page);
+ i = 0;
+ /*select the page*/
+ buf[i++] = (cmd >> 8) & 0xFF;
+ buf[i++] = (cmd & 0xFF);
+ cmd = HBI_PAGED_READ(offset, 0); /*build the cmd*/
+ buf[i++] = (cmd >> 8) & 0xFF;
+ buf[i++] = (cmd & 0xFF);
+ }
+ /*perform the HBI access*/
+
+#ifdef MICROSEMI_HBI_SPI
+ status = spi_write_then_read(zl380tw->spi, buf, i, buf, 2);
+#endif
+#ifdef MICROSEMI_HBI_I2C
+ memset(msg,0,sizeof(msg));
+
+ /* Make write msg 1st with write command */
+ msg[0].addr = zl380tw->i2c->addr;
+ msg[0].len = i;
+ msg[0].buf = buf;
+// TW_DEBUG2("i2c addr = 0x%04x\n", msg[0].addr);
+// TW_DEBUG2("numbytes:%d, cmdword = 0x%02x, %02x\n", numbytes, msg[0].buf[0], msg[0].buf[1]);
+ /* Make read msg */
+ msg[1].addr = zl380tw->i2c->addr;
+ msg[1].len = 2;
+ msg[1].buf = buf;
+ msg[1].flags = I2C_M_RD;
+ status = i2c_transfer(zl380tw->i2c->adapter, msg, 2);
+#endif
+ if (status <0)
+ return status;
+
+ *pdata = (buf[0]<<8) | buf[1] ; /* Byte_HI, Byte_LO */
+ return 0;
+}
+
+/* zl38040_hbi_wr16()- this function is used for single word access by the
+ * ioctl read. It decodes the 16-bit T-WOLF Regs Host address into
+ * page, offset and build the 16-bit command acordingly to the access type.
+ * then write the command and data to the device
+ * \param[in]
+ * .addr the 16-bit HBI address
+ * .data the 16-bit word to write
+ *
+ * return ::status
+ */
+static int zl380tw_hbi_wr16(struct zl380tw *zl380tw,
+ u16 addr, u16 data)
+{
+
+ u16 cmd;
+ u8 page;
+ u8 offset;
+ u8 i =0;
+ u8 buf[6] = {0, 0, 0, 0, 0, 0};
+ int status =0;
+ page = addr >> 8;
+ offset = (addr & 0xFF)>>1;
+
+ if (page == 0) /*Direct page access*/
+ {
+ cmd = HBI_DIRECT_WRITE(offset, 0);/*build the cmd*/
+ buf[i++] = (cmd >> 8) & 0xFF;
+ buf[i++] = (cmd & 0xFF);
+
+ } else { /*indirect page access*/
+ if (page != 0xFF) {
+ page -= 1;
+ }
+ cmd = HBI_SELECT_PAGE(page);
+ i = 0;
+ /*select the page*/
+ buf[i++] = (cmd >> 8) & 0xFF;
+ buf[i++] = (cmd & 0xFF);
+ cmd = HBI_PAGED_WRITE(offset, 0); /*build the cmd*/
+ buf[i++] = (cmd >> 8) & 0xFF;
+ buf[i++] = (cmd & 0xFF);
+ }
+ buf[i++] = (data >> 8) & 0xFF ;
+ buf[i++] = (data & 0xFF) ;
+
+ status = zl380tw_nbytes_wr(zl380tw, i, buf);
+ if (status <0)
+ return status;
+ return 0;
+}
+
+/*poll a specific bit of a register for clearance
+* [paran in] addr: the 16-bit register to poll
+* [paran in] bit: the bit position (0-15) to poll
+* [paran in] timeout: the if bit is not cleared within timeout exit loop
+*/
+static int zl380tw_monitor_bit(struct zl380tw *zl380tw, u16 addr, u8 bit, u16 timeout)
+{
+ u16 data = 0xBAD;
+ do {
+ zl380tw_hbi_rd16(zl380tw, addr, &data);
+ msleep(10);
+ } while ((((data & (1 << bit))>>bit) > 0) && (timeout-- >0));
+
+ if (timeout <= 0) {
+ TW_DEBUG1(" Operation Mode, in timeout = %d \n", timeout);
+ return -1;
+ }
+
+ return 0;
+}
+
+/* zl380tw_reset(): use this function to reset the device.
+ *
+ *
+ * Input Argument: mode - the supported reset modes:
+ * VPROC_ZL38040_RST_HARDWARE_ROM,
+ * VPROC_ZL38040_RST_HARDWARE_ROM,
+ * VPROC_ZL38040_RST_SOFT,
+ * VPROC_ZL38040_RST_AEC
+ * VPROC_ZL38040_RST_TO_BOOT
+ * Return: type error code (0 = success, else= fail)
+ */
+static int zl380tw_reset(struct zl380tw *zl380tw,
+ u16 mode)
+{
+
+ u16 addr = CLK_STATUS_REG;
+ u16 data = 0;
+ int monitor_bit = -1; /*the bit (range 0 - 15) of that register to monitor*/
+
+ /*PLATFORM SPECIFIC code*/
+ if (mode == ZL38040_RST_HARDWARE_RAM) { /*hard reset*/
+ /*hard reset*/
+ data = 0x0005;
+ } else if (mode == ZL38040_RST_HARDWARE_ROM) { /*power on reset*/
+ /*hard reset*/
+ data = 0x0009;
+ } else if (mode == ZL38040_RST_AEC) { /*AEC method*/
+ addr = 0x0300;
+ data = 0x0001;
+ monitor_bit = 0;
+ } else if (mode == ZL38040_RST_SOFTWARE) { /*soft reset*/
+ addr = 0x0006;
+ data = 0x0002;
+ monitor_bit = 1;
+ } else if (mode == ZL38040_RST_TO_BOOT) { /*reset to bootrom mode*/
+ data = 0x0001;
+ } else {
+ TW_DEBUG1("Invalid reset type\n");
+ return -EINVAL;
+ }
+ if (zl380tw_hbi_wr16(zl380tw, addr, data) < 0)
+ return -EFAULT;
+ msleep(50); /*wait for the HBI to settle*/
+
+ if (monitor_bit >= 0) {
+ if (zl380tw_monitor_bit(zl380tw, addr, monitor_bit, 1000) < 0)
+ return -EFAULT;
+ }
+ return 0;
+}
+
+
+/* tw_mbox_acquire(): use this function to
+ * check whether the host or the device owns the mailbox right
+ *
+ * Input Argument: None
+ * Return: error code (0 = success, else= fail)
+ */
+static int zl380tw_mbox_acquire(struct zl380tw *zl380tw)
+{
+
+ int status =0;
+ /*Check whether the host owns the command register*/
+ u16 i=0;
+ u16 temp = 0x0BAD;
+
+ for (i = 0; i < TWOLF_MBCMDREG_SPINWAIT; i++) {
+ status = zl380tw_hbi_rd16(zl380tw, ZL38040_SW_FLAGS_REG, &temp);
+ if ((status < 0)) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+ if (!(temp & ZL38040_SW_FLAGS_CMD)) {break;}
+ msleep(10); /*release*/
+ TW_DEBUG2("cmdbox =0x%04x timeout count = %d: \n", temp, i);
+ }
+ TW_DEBUG2("timeout count = %d: \n", i);
+ if ((i>= TWOLF_MBCMDREG_SPINWAIT) && (temp != ZL38040_SW_FLAGS_CMD)) {
+ return -EBUSY;
+ }
+ /*read the Host Command register*/
+ return 0;
+}
+
+/* zl380tw_cmdreg_acquire(): use this function to
+ * check whether the last command is completed
+ *
+ * Input Argument: None
+ * Return: error code (0 = success, else= fail)
+ */
+static int zl380tw_cmdreg_acquire(struct zl380tw *zl380tw)
+{
+
+ int status =0;
+ /*Check whether the host owns the command register*/
+ u16 i=0;
+ u16 temp = 0x0BAD;
+
+ for (i = 0; i < TWOLF_MBCMDREG_SPINWAIT; i++) {
+ status = zl380tw_hbi_rd16(zl380tw, ZL38040_CMD_REG, &temp);
+ if ((status < 0)) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+ if (temp == ZL38040_CMD_IDLE) {break;}
+ msleep(10); /*wait*/
+ TW_DEBUG2("cmdReg =0x%04x timeout count = %d: \n", temp, i);
+ }
+ TW_DEBUG2("timeout count = %d: \n", i);
+ if ((i>= TWOLF_MBCMDREG_SPINWAIT) && (temp != ZL38040_CMD_IDLE)) {
+ return -EBUSY;
+ }
+ /*read the Host Command register*/
+ return 0;
+}
+
+/* zl380tw_write_cmdreg(): use this function to
+ * access the host command register (mailbox access type)
+ *
+ * Input Argument: cmd - the command to send
+ * Return: error code (0 = success, else= fail)
+ */
+
+static int zl380tw_write_cmdreg(struct zl380tw *zl380tw, u16 cmd)
+{
+
+ int status = 0;
+ u16 buf = cmd;
+ /*Check whether the host owns the command register*/
+
+ status = zl380tw_mbox_acquire(zl380tw);
+ if ((status < 0)) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+ /*write the command into the Host Command register*/
+
+ status = zl380tw_hbi_wr16(zl380tw, ZL38040_CMD_REG, buf);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+ if ((cmd & 0x8000) >> 15)
+ buf = ZL38040_SW_FLAGS_CMD_NORST;
+ else
+ buf = ZL38040_SW_FLAGS_CMD;
+
+ /*Release the command reg*/
+ buf = ZL38040_SW_FLAGS_CMD;
+ status = zl380tw_hbi_wr16(zl380tw, ZL38040_SW_FLAGS_REG, buf);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+ return zl380tw_cmdreg_acquire(zl380tw);
+}
+
+/* Write 16bit HBI Register */
+/* zl380tw_wr16()- write a 16bit word
+ * \param[in] cmdword the 16-bit word to write
+ *
+ * return ::status
+ */
+static int zl380tw_wr16(struct zl380tw *zl380tw,
+ u16 cmdword)
+{
+
+ u8 buf[2] = {(cmdword >> 8) & 0xFF, (cmdword & 0xFF)};
+ int status = 0;
+#ifdef MICROSEMI_HBI_SPI
+ struct spi_message msg;
+ struct spi_transfer xfer = {
+ .len = 2,
+ .tx_buf = buf,
+ };
+
+ spi_message_init(&msg);
+
+ spi_message_add_tail(&xfer, &msg);
+ status = spi_sync(zl380tw->spi, &msg);
+#endif
+#ifdef MICROSEMI_HBI_I2C
+ status = i2c_master_send(zl380tw->i2c, buf, 2);
+#endif
+ return status;
+}
+
+/*To initialize the Twolf HBI interface
+ * Param[in] - cmd_config : the 16-bit HBI init command ored with the
+ * 8-bit configuration.
+ * The command format is cmd_config = 0xFD00 | CONFIG_VAL
+ * CONFIG_VAL: is you desired HBI config value
+ * (see device datasheet)
+ */
+static int zl380tw_hbi_init(struct zl380tw *zl380tw,
+ u16 cmd_config)
+{
+ return zl380tw_wr16(zl380tw, HBI_CONFIGURE(cmd_config));
+}
+
+
+#if defined(ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER) || defined(ZL380XX_TW_UPDATE_FIRMWARE)
+
+
+static int zl380tw_cmdresult_check(struct zl380tw *zl380tw)
+{
+ int status = 0;
+ u16 buf;
+ status = zl380tw_hbi_rd16(zl380tw, ZL38040_CMD_PARAM_RESULT_REG, &buf);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+
+ if (buf !=0) {
+ TW_DEBUG1("Command failed...Resultcode = 0x%04x\n", buf);
+ return buf;
+ }
+ return 0;
+}
+
+/*stop_fwr_to_bootmode - use this function to stop the firmware currently
+ *running
+ * And set the device in boot mode
+ * \param[in] none
+ *
+ * \retval ::0 success
+ * \retval ::-EINVAL or device error code
+ */
+static int zl380tw_stop_fwr_to_bootmode(struct zl380tw *zl380tw)
+{
+ return zl380tw_write_cmdreg(zl380tw, ZL38040_CMD_FWR_STOP);
+}
+
+/*start_fwr_from_ram - use this function to start/restart the firmware
+ * previously stopped with VprocTwolfFirmwareStop()
+ * \param[in] none
+ *
+ * \retval ::0 success
+ * \retval ::-EINVAL or device error code
+ */
+static int zl380tw_start_fwr_from_ram(struct zl380tw *zl380tw)
+{
+ if (zl380tw_write_cmdreg(zl380tw, ZL38040_CMD_FWR_GO) < 0) {
+ return -EFAULT;
+ }
+ zl380tw->init_done = 1; /*firmware is running in the device*/
+ return 0;
+}
+
+/*tw_init_check_flash - use this function to check if there is a flash on board
+ * and initialize it
+ * \param[in] none
+ *
+ * \retval ::0 success
+ * \retval ::-EINVAL or device error code
+ */
+static int zl380tw_init_check_flash(struct zl380tw *zl380tw)
+{
+ /*if there is a flash on board initialize it*/
+ return zl380tw_write_cmdreg(zl380tw, ZL38040_CMD_HOST_FLASH_INIT);
+}
+
+/*tw_erase_flash - use this function to erase all firmware image
+* and related config from flash
+ * previously stopped with VprocTwolfFirmwareStop()
+ * \param[in] none
+ *
+ * \retval ::0 success
+ * \retval ::-EINVAL or device error code
+ */
+static int zl380tw_erase_flash(struct zl380tw *zl380tw)
+{
+
+ int status =0;
+ /*if there is a flash on board initialize it*/
+ status = zl380tw_init_check_flash(zl380tw);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+
+ /*erase all config/fwr*/
+ status = zl380tw_hbi_wr16(zl380tw, ZL38040_CMD_PARAM_RESULT_REG, 0xAA55);
+ if (status < 0) {
+ return status;
+ }
+
+ /*erase firmware*/
+ return zl380tw_write_cmdreg(zl380tw, 0x0009);
+
+}
+/*erase_fwrcfg_from_flash - use this function to erase a psecific firmware image
+* and related config from flash
+ * previously stopped with VprocTwolfFirmwareStop()
+ * Input Argument: image_number - (range 1-14)
+ *
+ * \retval ::0 success
+ * \retval ::-EINVAL or device error code
+ */
+static int zl380tw_erase_fwrcfg_from_flash(struct zl380tw *zl380tw,
+ u16 image_number)
+{
+ int status = 0;
+ if (image_number <= 0) {
+ return -EINVAL;
+ }
+ /*save the config/fwr to flash position image_number */
+ status = zl380tw_stop_fwr_to_bootmode(zl380tw);
+ if (status < 0) {
+ return status;
+ }
+ msleep(50);
+ /*if there is a flash on board initialize it*/
+ status = zl380tw_init_check_flash(zl380tw);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+
+ status = zl380tw_hbi_wr16(zl380tw, ZL38040_CMD_PARAM_RESULT_REG, image_number);
+ if (status < 0) {
+ return status;
+ }
+ status = zl380tw_write_cmdreg(zl380tw, ZL38040_CMD_IMG_CFG_ERASE);
+ if (status < 0) {
+ return status;
+ }
+
+ return zl380tw_cmdresult_check(zl380tw);
+}
+
+
+/* tw_save_image_to_flash(): use this function to
+ * save both the config record and the firmware to flash. It Sets the bit
+ * which initiates a firmware save to flash when the device
+ * moves from a STOPPED state to a RUNNING state (by using the GO bit)
+ *
+ * Input Argument: None
+ * \retval ::0 success
+ * \retval ::-EINVAL or device error code
+ */
+static int zl380tw_save_image_to_flash(struct zl380tw *zl380tw)
+{
+ int status = 0;
+ /*Save firmware to flash*/
+
+#if 0
+ /*delete all applications on flash*/
+ status = zl380tw_erase_flash(zl380tw);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: tw_erase_flash\n", status);
+ return status;
+ }
+#else
+ /*if there is a flash on board initialize it*/
+ status = zl380tw_init_check_flash(zl380tw);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+#endif
+ /*save the image to flash*/
+ status = zl380tw_write_cmdreg(zl380tw, ZL38040_CMD_IMG_CFG_SAVE);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: zl380tw_write_cmdreg\n", status);
+ return status;
+ }
+ return zl380tw_cmdresult_check(zl380tw);
+ /*return status;*/
+}
+
+/*load_fwr_from_flash - use this function to load a specific firmware image
+* from flash
+ * previously stopped with VprocTwolfFirmwareStop()
+ * Input Argument: image_number - (range 1-14)
+ *
+ * \retval ::0 success
+ * \retval ::-EINVAL or device error code
+ */
+static int zl380tw_load_fwr_from_flash(struct zl380tw *zl380tw,
+ u16 image_number)
+{
+ int status = 0;
+
+ if (image_number <= 0) {
+ return -EINVAL;
+ }
+
+ status = zl380tw_stop_fwr_to_bootmode(zl380tw);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+
+ /*if there is a flash on board initialize it*/
+ status = zl380tw_init_check_flash(zl380tw);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+ /*load the fwr to flash position image_number */
+ status = zl380tw_hbi_wr16(zl380tw, ZL38040_CMD_PARAM_RESULT_REG, image_number);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+ status = zl380tw_write_cmdreg(zl380tw, ZL38040_CMD_IMG_LOAD);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+ return zl380tw_start_fwr_from_ram(zl380tw);
+}
+
+/*zl380tw_load_fwrcfg_from_flash - use this function to load a specific firmware image
+* related and config from flash
+ * previously stopped with VprocTwolfFirmwareStop()
+ * Input Argument: image_number - (range 1-14)
+ *
+ * \retval ::0 success
+ * \retval ::-EINVAL or device error code
+ */
+static int zl380tw_load_fwrcfg_from_flash(struct zl380tw *zl380tw,
+ u16 image_number)
+{
+
+ int status = 0;
+ if (image_number <= 0) {
+ return -EINVAL;
+ }
+ status = zl380tw_stop_fwr_to_bootmode(zl380tw);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+
+ /*if there is a flash on board initialize it*/
+ status = zl380tw_init_check_flash(zl380tw);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+
+ /*save the config to flash position image_number */
+ status = zl380tw_hbi_wr16(zl380tw, ZL38040_CMD_PARAM_RESULT_REG, image_number);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+ status = zl380tw_write_cmdreg(zl380tw, ZL38040_CMD_IMG_CFG_LOAD);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+
+ return zl380tw_start_fwr_from_ram(zl380tw);
+}
+
+
+
+/*zl380tw_load_cfg_from_flash - use this function to load a specific firmware image
+* from flash
+ * * Input Argument: image_number - (range 1-14)
+ *
+ * \retval ::0 success
+ * \retval ::-EINVAL or device error code
+ */
+static int zl380tw_load_cfg_from_flash(struct zl380tw *zl380tw,
+ u16 image_number)
+{
+ int status = 0;
+
+ if (image_number <= 0) {
+ return -EINVAL;
+ }
+ /*if there is a flash on board initialize it*/
+ status = zl380tw_init_check_flash(zl380tw);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+
+ /*load the config from flash position image_number */
+ status = zl380tw_hbi_wr16(zl380tw, ZL38040_CMD_PARAM_RESULT_REG, image_number);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+ return zl380tw_write_cmdreg(zl380tw, ZL38040_CMD_CFG_LOAD);
+}
+
+/* save_cfg_to_flash(): use this function to
+ * save the config record to flash. It Sets the bit
+ * which initiates a config save to flash when the device
+ * moves from a STOPPED state to a RUNNING state (by using the GO bit)
+ *
+ * \retval ::0 success
+ * \retval ::-EINVAL or device error code
+ */
+static int zl380tw_save_cfg_to_flash(struct zl380tw *zl380tw, u16 image_number)
+{
+ int status = 0;
+ u16 buf = 0;
+ /*Save config to flash*/
+
+ /*if there is a flash on board initialize it*/
+ status = zl380tw_init_check_flash(zl380tw);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+ /*check if a firmware exists on the flash*/
+ status = zl380tw_hbi_rd16(zl380tw, ZL38040_FWR_COUNT_REG, &buf);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+ if (buf ==0)
+ return -EBADSLT; /*There is no firmware on flash position image_number to save config for*/
+
+ /*save the config to flash position */
+ status = zl380tw_hbi_wr16(zl380tw, ZL38040_CMD_PARAM_RESULT_REG, image_number);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+
+ /*save the config to flash position */
+ status = zl380tw_hbi_wr16(zl380tw, ZL38040_CMD_REG, 0x8002);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+
+ /*save the config to flash position */
+ status = zl380tw_hbi_wr16(zl380tw, ZL38040_SW_FLAGS_REG, 0x0004);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+ status = zl380tw_cmdreg_acquire(zl380tw);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: tw_cmdreg_acquire\n", status);
+ return status;
+ }
+ /*Verify wheter the operation completed sucessfully*/
+ return zl380tw_cmdresult_check(zl380tw);
+}
+
+/*AsciiHexToHex() - to convert ascii char hex to integer hex
+ * pram[in] - str - pointer to the char to convert.
+ * pram[in] - len - the number of character to convert (2:u8, 4:u16, 8:u32).
+
+ */
+static unsigned int AsciiHexToHex(const char * str, unsigned char len)
+{
+ unsigned int val = 0;
+ char c;
+ unsigned char i = 0;
+ for (i = 0; i< len; i++)
+ {
+ c = *str++;
+ val <<= 4;
+
+ if (c >= '0' && c <= '9')
+ {
+ val += c & 0x0F;
+ continue;
+ }
+
+ c &= 0xDF;
+ if (c >= 'A' && c <= 'F')
+ {
+ val += (c & 0x07) + 9;
+ continue;
+ }
+ return 0;
+ }
+ return val;
+}
+
+/* These 3 functions provide an alternative method to loading an *.s3
+ * firmware image into the device
+ * Procedure:
+ * 1- Call zl380tw_boot_prepare() to put the device in boot mode
+ * 2- Call the zl380tw_boot_Write() repeatedly by passing it a pointer
+ * to one line of the *.s3 image at a time until the full image (all lines)
+ * are transferred to the device successfully.
+ * When the transfer of a line is complete, this function will return the sta-
+ * tus VPROC_STATUS_BOOT_LOADING_MORE_DATA. Then when all lines of the image
+ * are transferred the function will return the status
+ * VPROC_STATUS_BOOT_LOADING_CMP
+ * 3- zl380tw_boot_conclude() to complete and verify the completion status of
+ * the image boot loading process
+ *
+ */
+static int zl380tw_boot_prepare(struct zl380tw *zl380tw)
+{
+
+ u16 buf = 0;
+ int status = 0;
+ status = zl380tw_hbi_wr16(zl380tw, CLK_STATUS_REG, 1); /*go to boot rom mode*/
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+ msleep(50); /*required for the reset to cmplete*/
+ /*check whether the device has gone into boot mode as ordered*/
+ status = zl380tw_hbi_rd16(zl380tw, (u16)ZL38040_CMD_PARAM_RESULT_REG, &buf);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+
+ if ((buf != 0xD3D3)) {
+ TW_DEBUG1("ERROR: HBI is not accessible, cmdResultCheck = 0x%04x\n",
+ buf);
+ return -EFAULT;
+ }
+ return 0;
+}
+/*----------------------------------------------------------------------------*/
+
+static int zl380tw_boot_conclude(struct zl380tw *zl380tw)
+{
+ int status = 0;
+ status = zl380tw_write_cmdreg(zl380tw, ZL38040_CMD_HOST_LOAD_CMP); /*loading complete*/
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: \n", status);
+ return status;
+ }
+
+ /*check whether the device has gone into boot mode as ordered*/
+ return zl380tw_cmdresult_check(zl380tw);
+}
+
+/*----------------------------------------------------------------------------*/
+/* Read up to 256 bytes data */
+/* slave_zl380xx_nbytesrd()- read one or up to 256 bytes from the device
+ * \param[in] ptwdata pointer to the data read
+ * \param[in] numbytes the number of bytes to read
+ *
+ * return ::status = the total number of bytes received successfully
+ * or a negative error code
+ */
+static int
+zl380tw_nbytes_rd(struct zl380tw *zl380tw, u8 numbytes, u8 *pData, u8 hbiAddrType)
+{
+ int status = 0;
+ int tx_len = (hbiAddrType == TWOLF_HBI_PAGED) ? 4 : 2;
+ u8 tx_buf[4] = {pData[0], pData[1], pData[2], pData[3]};
+
+#ifdef MICROSEMI_HBI_SPI
+ struct spi_message msg;
+
+ struct spi_transfer txfer = {
+ .len = tx_len,
+ .tx_buf = tx_buf,
+ };
+ struct spi_transfer rxfer = {
+ .len = numbytes,
+ .rx_buf = zl380tw->pData,
+ };
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&txfer, &msg);
+ spi_message_add_tail(&rxfer, &msg);
+ status = spi_sync(zl380tw->spi, &msg);
+
+#endif
+#ifdef MICROSEMI_HBI_I2C
+ struct i2c_msg msg[2];
+ memset(msg,0,sizeof(msg));
+
+ msg[0].addr = zl380tw->i2c->addr;
+ msg[0].len = tx_len;
+ msg[0].buf = tx_buf;
+
+ msg[1].addr = zl380tw->i2c->addr;
+ msg[1].len = numbytes;
+ msg[1].buf = zl380tw->pData;
+ msg[1].flags = I2C_M_RD;
+ status = i2c_transfer(zl380tw->i2c->adapter, msg, 2);
+#endif
+ if (status <0)
+ return status;
+
+#ifdef MSCCDEBUG2
+ {
+ int i = 0;
+ printk("RD: Numbytes = %d, addrType = %d\n", numbytes, hbiAddrType);
+ for(i=0;i<numbytes;i++)
+ {
+ printk("0x%02x, ", zl380tw->pData[i]);
+ }
+ printk("\n");
+ }
+#endif
+ return 0;
+}
+
+
+static int
+zl380tw_hbi_access(struct zl380tw *zl380tw,
+ u16 addr, u16 numbytes, u8 *pData, u8 hbiAccessType)
+{
+
+ u16 cmd;
+ u8 page = addr >> 8;
+ u8 offset = (addr & 0xFF)>>1;
+ int i = 0;
+ u8 hbiAddrType = 0;
+ u8 buf[MAX_TWOLF_ACCESS_SIZE_IN_BYTES];
+ int status = 0;
+
+ u8 numwords = (numbytes/2);
+
+#ifdef MICROSEMI_HBI_SPI
+ if (zl380tw->spi == NULL) {
+ TW_DEBUG1("spi device is not available \n");
+ return -EFAULT;
+ }
+#endif
+#ifdef MICROSEMI_HBI_I2C
+ if (zl380tw->i2c == NULL) {
+ TW_DEBUG1("i2c device is not available \n");
+ return -EFAULT;
+ }
+#endif
+ if ((numbytes > MAX_TWOLF_ACCESS_SIZE_IN_BYTES) || (numbytes ==0))
+ return -EINVAL;
+
+ if (pData == NULL)
+ return -EINVAL;
+
+ if (!((hbiAccessType == TWOLF_HBI_WRITE) ||
+ (hbiAccessType == TWOLF_HBI_READ)))
+ return -EINVAL;
+
+ if (page == 0) /*Direct page access*/
+ {
+ if (hbiAccessType == TWOLF_HBI_WRITE)
+ cmd = HBI_DIRECT_WRITE(offset, numwords-1);/*build the cmd*/
+ else
+ cmd = HBI_DIRECT_READ(offset, numwords-1);/*build the cmd*/
+
+ buf[i++] = (cmd >> 8) & 0xFF ;
+ buf[i++] = (cmd & 0xFF) ;
+ hbiAddrType = TWOLF_HBI_DIRECT;
+ } else { /*indirect page access*/
+ i = 0;
+ if (page != 0xFF) {
+ page -= 1;
+ }
+ cmd = HBI_SELECT_PAGE(page);
+ /*select the page*/
+ buf[i++] = (cmd >> 8) & 0xFF ;
+ buf[i++] = (cmd & 0xFF) ;
+
+ /*address on the page to access*/
+ if (hbiAccessType == TWOLF_HBI_WRITE)
+ cmd = HBI_PAGED_WRITE(offset, numwords-1);
+ else
+ cmd = HBI_PAGED_READ(offset, numwords-1);/*build the cmd*/
+
+ buf[i++] = (cmd >> 8) & 0xFF ;
+ buf[i++] = (cmd & 0xFF) ;
+ hbiAddrType = TWOLF_HBI_PAGED;
+ }
+ memcpy(&buf[i], pData, numbytes);
+#ifdef MSCCDEBUG2
+ {
+ int j = 0;
+ int displaynum = numbytes;
+ if (hbiAccessType == TWOLF_HBI_WRITE)
+ displaynum = numbytes;
+ else
+ displaynum = i;
+
+ printk("SENDING:: Numbytes = %d, accessType = %d\n", numbytes, hbiAccessType);
+ for(j=0;j<numbytes;j++)
+ {
+ printk("0x%02x, ", pData[j]);
+ }
+ printk("\n");
+ }
+#endif
+ if (hbiAccessType == TWOLF_HBI_WRITE)
+ status = zl380tw_nbytes_wr(zl380tw, numbytes+i, buf);
+ else
+ status = zl380tw_nbytes_rd(zl380tw, numbytes, buf, hbiAddrType);
+ if (status < 0)
+ return -EFAULT;
+
+ return status;
+}
+/*
+ * __ Upload a romcode by blocks
+ * the user app will call this function by passing it one line from the *.s3
+ * file at a time.
+ * when the firmware boot loading process find the execution address
+ * in that block of data it will return the number 23
+ * indicating that the transfer on the image data is completed, otherwise,
+ * it will return 22 indicating tha tit expect more data.
+ * If error, then a negative error code will be reported
+ */
+static int zl380tw_boot_Write(struct zl380tw *zl380tw,
+ char *blockOfFwrData) /*0: HBI; 1:FLASH*/
+{
+
+/*Use this method to load the actual *.s3 file line by line*/
+ int status = 0;
+ int rec_type, i=0, j=0;
+ u8 numbytesPerLine = 0;
+ u8 buf[MAX_TWOLF_FIRMWARE_SIZE_IN_BYTES];
+ unsigned long address = 0;
+ u8 page255Offset = 0x00;
+ u16 cmd = 0;
+
+ TW_DEBUG2("firmware line# = %d :: blockOfFwrData = %s\n",++myCounter, blockOfFwrData);
+
+ if (blockOfFwrData == NULL) {
+ TW_DEBUG1("blockOfFwrData[0] = %c\n", blockOfFwrData[0]);
+ return -EINVAL;
+ }
+ /* if this line is not an srecord skip it */
+ if (blockOfFwrData[0] != 'S') {
+ TW_DEBUG1("blockOfFwrData[0] = %c\n", blockOfFwrData[0]);
+ return -EINVAL;
+ }
+ /* get the srecord type */
+ rec_type = blockOfFwrData[1] - '0';
+
+ numbytesPerLine = AsciiHexToHex(&blockOfFwrData[2], 2);
+ //TW_DEBUG2("numbytesPerLine = %d\n", numbytesPerLine);
+ if (numbytesPerLine == 0) {
+ TW_DEBUG1("blockOfFwrData[3] = %c\n", blockOfFwrData[3]);
+ return -EINVAL;
+ }
+
+ /* skip non-existent srecord types and block header */
+ if ((rec_type == 4) || (rec_type == 5) || (rec_type == 6) ||
+ (rec_type == 0)) {
+ return TWOLF_STATUS_NEED_MORE_DATA;
+ }
+
+ /* get the info based on srecord type (skip checksum) */
+ address = AsciiHexToHex(&blockOfFwrData[4], 8);
+ buf[0] = (u8)((address >> 24) & 0xFF);
+ buf[1] = (u8)((address >> 16) & 0xFF);
+ buf[2] = (u8)((address >> 8) & 0xFF);
+ buf[3] = 0;
+ page255Offset = (u8)(address & 0xFF);
+ /* store the execution address */
+ if ((rec_type == 7) || (rec_type == 8) || (rec_type == 9)) {
+ /* the address is the execution address for the program */
+ //TW_DEBUG2("execAddr = 0x%08lx\n", address);
+ /* program the program's execution start register */
+ buf[3] = (u8)(address & 0xFF);
+ status = zl380tw_hbi_access(zl380tw,
+ ZL38040_FWR_EXEC_REG, 4, buf, TWOLF_HBI_WRITE);
+
+ if(status < 0) {
+ TW_DEBUG1("ERROR % d: unable to program page 1 execution address\n", status);
+ return status;
+ }
+ TW_DEBUG2("Loading firmware data complete...\n");
+ return TWOLF_STATUS_BOOT_COMPLETE; /*BOOT_COMPLETE Sucessfully*/
+ }
+
+ /* put the address into our global target addr */
+
+
+ //TW_DEBUG2("TW_DEBUG2:gTargetAddr = 0x%08lx: \n", address);
+ status = zl380tw_hbi_access(zl380tw,
+ PAGE_255_BASE_HI_REG, 4, buf, TWOLF_HBI_WRITE);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: gTargetAddr = 0x%08lx: \n", status, address);
+ return -EFAULT;
+ }
+
+ /* get the data bytes */
+ j = 12;
+ //TW_DEBUG2("buf[]= 0x%02x, 0x%02x, \n", buf[0], buf[1]);
+ for (i = 0; i < numbytesPerLine - 5; i++) {
+ buf[i] = AsciiHexToHex(&blockOfFwrData[j], 2);
+ j +=2;
+ //TW_DEBUG2("0x%02x, ", buf[i+4]);
+ }
+ /* write the data to the device */
+ cmd = (u16)(0xFF<<8) | (u16)page255Offset;
+ status = zl380tw_hbi_access(zl380tw,
+ cmd, (numbytesPerLine - 5), buf, TWOLF_HBI_WRITE);
+ if(status < 0) {
+ return status;
+ }
+
+ //TW_DEBUG2("Provide next block of data...\n");
+ return TWOLF_STATUS_NEED_MORE_DATA; /*REQUEST STATUS_MORE_DATA*/
+}
+
+#endif
+
+
+/*----------------------------------------------------------------------*
+ * The kernel driver functions are defined below
+ *-------------------------DRIVER FUNCTIONs-----------------------------*/
+/* zl380tw_ldfwr()
+ * This function basically will load the firmware into the Timberwolf device
+ * at power up. this is convenient for host pluging system that does not have
+ * a slave EEPROM/FLASH to store the firmware, therefore, and that
+ * requires the device to be fully operational at power up
+*/
+#ifdef ZL380XX_TW_UPDATE_FIRMWARE
+#ifdef ZL380TW_INCLUDE_FIRMWARE_REQUEST_LIB
+static int zl380tw_ldfwr(struct zl380tw *zl380tw)
+{
+
+ int status = 0;
+
+ const struct firmware *twfw;
+ u8 numbytesPerLine = 0;
+ u32 j =0;
+ u8 block_size = 0;
+
+ zl380twEnterCritical();
+
+ if (ZLS380TW0_TWOLF == NULL){
+ TW_DEBUG1("err %d, invalid firmware filename %s\n",
+ status, ZLS380TW0_TWOLF);
+ zl380twExitCritical();
+ return -EINVAL;
+ }
+
+ status = request_firmware(&twfw, ZLS380TW0_TWOLF,
+#ifdef MICROSEMI_HBI_SPI
+ &zl380tw->spi->dev
+#endif
+#ifdef MICROSEMI_HBI_I2C
+ &zl380tw->i2c->dev
+#endif
+ );
+ if (status) {
+ TW_DEBUG1("err %d, request_firmware failed to load %s\n",
+ status, ZLS380TW0_TWOLF);
+ zl380twExitCritical();
+ return -EINVAL;
+ }
+
+ /*check validity of the S-record firmware file*/
+ if (twfw->data[0] != 'S') {
+ TW_DEBUG1("Invalid S-record %s file for this device\n", ZLS380TW0_TWOLF);
+ release_firmware(twfw);
+ zl380twExitCritical();
+ return -EINVAL;
+ }
+
+ /* Allocating memory for the data buffer if not already done*/
+ if (!zl380tw->pData) {
+ zl380tw->pData = kmalloc(MAX_TWOLF_FIRMWARE_SIZE_IN_BYTES, GFP_KERNEL);
+ if (!zl380tw->pData) {
+ TW_DEBUG1("can't allocate memory\n");
+ release_firmware(twfw);
+ zl380twExitCritical();
+ return -ENOMEM;
+ }
+ memset(zl380tw->pData, 0, MAX_TWOLF_FIRMWARE_SIZE_IN_BYTES);
+ }
+
+ status = zl380tw_boot_prepare(zl380tw);
+ if (status < 0) {
+ TW_DEBUG1("err %d, tw boot prepare failed\n", status);
+ goto fwr_cleanup;
+ }
+
+ TW_DEBUG1("loading firmware %s into the device ...\n", ZLS380TW0_TWOLF);
+
+ do {
+ numbytesPerLine = AsciiHexToHex(&twfw->data[j+2], 2);
+ block_size = (4 + (2*numbytesPerLine));
+
+ memcpy(zl380tw->pData, &twfw->data[j], block_size);
+ j += (block_size+2);
+
+ status = zl380tw_boot_Write(zl380tw, zl380tw->pData);
+ if ((status != (int)TWOLF_STATUS_NEED_MORE_DATA) &&
+ (status != (int)TWOLF_STATUS_BOOT_COMPLETE)) {
+ TW_DEBUG1("err %d, tw boot write failed\n", status);
+ goto fwr_cleanup;
+ }
+
+ } while ((j < twfw->size) && (status != TWOLF_STATUS_BOOT_COMPLETE));
+
+ status = zl380tw_boot_conclude(zl380tw);
+ if (status < 0) {
+ TW_DEBUG1("err %d, twfw->size = %d, tw boot conclude -firmware loading failed\n", status, twfw->size);
+ goto fwr_cleanup;
+ }
+#ifdef ZL38040_SAVE_FWR_TO_FLASH
+ status = zl380tw_save_image_to_flash(zl380tw);
+ if (status < 0) {
+ TW_DEBUG1("err %d, twfw->size = %d, saving firmware failed\n", status, twfw->size);
+ goto fwr_cleanup;
+ }
+#endif /*ZL38040_SAVE_FWR_TO_FLASH*/
+ status = zl380tw_start_fwr_from_ram(zl380tw);
+ if (status < 0) {
+ TW_DEBUG1("err %d, twfw->size = %d, starting firmware failed\n", status, twfw->size);
+ goto fwr_cleanup;
+ }
+/*loading the configuration record*/
+#ifdef ZL380XX_TW_UPDATE_CONFIG
+ {
+ u16 reg = 0 ,val =0;
+ release_firmware(twfw);
+ j = 6; /*skip the CR2K key word*/
+ numbytesPerLine = 10;
+ status = request_firmware(&twfw, ZLS380TW0_TWOLF_CRK,
+ #ifdef MICROSEMI_HBI_SPI
+ &zl380tw->spi->dev
+ #endif
+ #ifdef MICROSEMI_HBI_I2C
+ &zl380tw->i2c->dev
+ #endif
+ );
+ if (status) {
+ TW_DEBUG1("err %d, request_firmware failed to load %s\n",
+ status, ZLS380TW0_TWOLF_CRK);
+ goto fwr_cleanup;
+ }
+ TW_DEBUG1("loading config %s into the device ...\n", ZLS380TW0_TWOLF_CRK);
+
+ do {
+ if(twfw->data[j] == 'E')
+ break;
+
+ if((twfw->data[j] != 'C') && (twfw->data[j+1] != 'R')) {
+ reg = AsciiHexToHex(&twfw->data[j], 4);
+ val = AsciiHexToHex(&twfw->data[j+6], 4);
+ status = zl380tw_hbi_wr16(zl380tw, reg, val);
+ if (status < 0) {
+ TW_DEBUG1("err %d, tw config write failed\n", status);
+ goto fwr_cleanup;
+ }
+ //TW_DEBUG1("reg = 0x%04x, val=0x%04x\n", reg, val);
+ }
+ j += 12; /*move to next pair of values*/
+
+ } while (j < twfw->size);
+#ifdef ZL38040_SAVE_FWR_TO_FLASH
+ if (zl380tw_hbi_rd16(zl380tw, ZL38040_FWR_COUNT_REG, &val) < 0) {
+ return -EIO;
+ }
+ if (val == 0) {
+ TW_DEBUG1("err: there is no firmware on flash\n");
+ return -1;
+ }
+
+ status = zl380tw_save_cfg_to_flash(zl380tw, val);
+ if (status < 0) {
+ TW_DEBUG1("err %d, tw save config to flash failed\n", status);
+ }
+ TW_DEBUG1("zl380tw image/cfg saved to flash position %d - success...\n", val);
+
+#endif /*ZL38040_SAVE_FWR_TO_FLASH*/
+ }
+#endif /*ZL380XX_TW_UPDATE_CONFIG*/
+ /*status = zl380tw_reset(zl380tw, ZL38040_RST_SOFTWARE); */
+ goto fwr_cleanup;
+
+fwr_cleanup:
+ zl380twExitCritical();
+ release_firmware(twfw);
+
+ return status;
+}
+#else
+/*VprocTwolfLoadConfig() - use this function to load a custom or new config
+ * record into the device RAM to override the default config
+ * \retval ::VPROC_STATUS_SUCCESS
+ * \retval ::VPROC_STATUS_ERR_HBI
+ */
+static int zl380tw_load_config(struct zl380tw *zl380tw,
+ dataArr *pCr2Buf,
+ unsigned short numElements)
+{
+ int status = 0;
+ int i;
+ u8 buf[MAX_TWOLF_FIRMWARE_SIZE_IN_BYTES];
+ /*stop the current firmware but do not reset the device and do not go to boot mode*/
+
+ /*send the config to the device RAM*/
+ for (i=0; i<numElements; i++) {
+ u8 j=0, k=0;
+ for (k = 0; k < ZL380XX_CFG_BLOCK_SIZE; k++) {
+ buf[j] = (u8)((st_twConfig[i].value[k] >> 8) & 0xFF);
+ buf[j+1] = (u8)((st_twConfig[i].value[k]) & 0xFF);
+ j +=2;
+ }
+ status = zl380tw_hbi_access(zl380tw, st_twConfig[i].reg, ZL380XX_CFG_BLOCK_SIZE*2, buf, TWOLF_HBI_WRITE);
+ }
+
+ return status;
+}
+/* zl380tw_boot_alt Use this alternate method to load the st_twFirmware.c
+ *(converted *.s3 to c code) to the device
+ */
+static int zl380tw_ldfwr(struct zl380tw *zl380tw)
+{
+ u16 index = 0;
+ u8 buf[MAX_TWOLF_FIRMWARE_SIZE_IN_BYTES];
+ u8 page255Offset = 0x00;
+
+ int status = 0;
+
+ TW_DEBUG1("Using the firmware-config c code loading ...\n");
+ zl380twEnterCritical();
+ status = zl380tw_boot_prepare(zl380tw);
+ if (status < 0) {
+ TW_DEBUG1("err %d, tw boot prepare failed\n", status);
+ zl380twExitCritical();
+ return -1;
+ }
+
+ while (index < firmwareStreamLen) {
+ int i=0, j=0;
+ /* put the address into our global target addr */
+ buf[0] = (u8)((st_twFirmware[index].targetAddr >> 24) & 0xFF);
+ buf[1] = (u8)((st_twFirmware[index].targetAddr >> 16) & 0xFF);
+ buf[2] = (u8)((st_twFirmware[index].targetAddr >> 8) & 0xFF);
+ buf[3] = 0;
+ page255Offset = (u8)(st_twFirmware[index].targetAddr & 0xFF);
+ /* write the data to the device */
+ if (st_twFirmware[index].numWords != 0) {
+
+
+ status = zl380tw_hbi_access(zl380tw,
+ PAGE_255_BASE_HI_REG, 4, buf, TWOLF_HBI_WRITE);
+ if (status < 0) {
+ TW_DEBUG1("ERROR %d: gTargetAddr = 0x%08lx: \n", status, st_twFirmware[index].targetAddr);
+ zl380twExitCritical();
+ return -EFAULT;
+ }
+
+
+
+ for (i = 0; i < st_twFirmware[index].numWords; i++) {
+ buf[j] = (u8)((st_twFirmware[index].buf[i] >> 8) & 0xFF);
+ buf[j+1] = (u8)((st_twFirmware[index].buf[i]) & 0xFF);
+ j+=2;
+ //TW_DEBUG2("0x%02x, ", buf[i+4]);
+ }
+ /* write the data to the device */
+
+ status = zl380tw_hbi_access(zl380tw,((u16)(0xFF<<8) | (u16)page255Offset),
+ (st_twFirmware[index].numWords*2), buf, TWOLF_HBI_WRITE);
+ if(status < 0) {
+ zl380twExitCritical();
+ return status;
+ }
+ }
+ index++;
+ }
+
+ /*
+ * convert the number of bytes to two 16 bit
+ * values and write them to the requested page register
+ */
+ /* even number of bytes required */
+
+ /* program the program's execution start register */
+ buf[0] = (u8)((executionAddress >> 24) & 0xFF);
+ buf[1] = (u8)((executionAddress >> 16) & 0xFF);
+ buf[2] = (u8)((executionAddress >> 8) & 0xFF);
+ buf[3] = (u8)(executionAddress & 0xFF);
+ status = zl380tw_hbi_access(zl380tw,
+ ZL38040_FWR_EXEC_REG, 4, buf, TWOLF_HBI_WRITE);
+
+ if(status < 0) {
+ TW_DEBUG1("ERROR % d: unable to program page 1 execution address\n", status);
+ zl380twExitCritical();
+ return status;
+ }
+
+ /* print out the srecord program info */
+ TW_DEBUG2("prgmBase 0x%08lx\n", programBaseAddress);
+ TW_DEBUG2("execAddr 0x%08lx\n", executionAddress);
+
+ status = zl380tw_boot_conclude(zl380tw);
+ if (status < 0) {
+ TW_DEBUG1("err %d, tw boot conclude -firmware loading failed\n", status);
+ zl380twExitCritical();
+ return -1;
+ }
+
+#ifdef ZL38040_SAVE_FWR_TO_FLASH
+ status = zl380tw_save_image_to_flash(zl380tw);
+ if (status < 0) {
+ TW_DEBUG1("err %d, saving firmware to flash failed\n", status);
+ zl380twExitCritical();
+ return status;
+ }
+#endif /*ZL38040_SAVE_FWR_TO_FLASH*/
+ status = zl380tw_start_fwr_from_ram(zl380tw);
+ if (status < 0) {
+ TW_DEBUG1("err %d, starting firmware failed\n", status);
+ zl380twExitCritical();
+ return status;
+ }
+#ifdef ZL380XX_TW_UPDATE_CONFIG
+ zl380tw_load_config(zl380tw, (dataArr *)st_twConfig, (u16)configStreamLen);
+ if (status < 0) {
+ TW_DEBUG1("err %d, loading config failed\n", status);
+ zl380twExitCritical();
+ return status;
+ }
+#ifdef ZL38040_SAVE_FWR_TO_FLASH
+ {
+ u16 val = 0;
+ if (zl380tw_hbi_rd16(zl380tw, ZL38040_FWR_COUNT_REG, &val) < 0) {
+ return -EIO;
+ }
+ if (val == 0) {
+ TW_DEBUG1("err: there is no firmware on flash\n");
+ return -1;
+ }
+ status = zl380tw_save_cfg_to_flash(zl380tw, val);
+ if (status < 0) {
+ TW_DEBUG1("err %d, tw save config to flash failed\n", status);
+ zl380twExitCritical();
+ return status;
+ }
+ TW_DEBUG1("zl380tw image/cfg saved to flash position %d - success...\n", val);
+ }
+#endif /*ZL38040_SAVE_FWR_TO_FLASH*/
+#endif /*ZL380XX_TW_UPDATE_CONFIG*/
+ TW_DEBUG1("zl380tw boot init complete - success...\n");
+ zl380twExitCritical();
+ return 0;
+}
+#endif /*ZL380TW_INCLUDE_FIRMWARE_REQUEST_LIB*/
+#endif /*ZL380XX_TW_UPDATE_FIRMWARE*/
+
+
+/*--------------------------------------------------------------------
+ * ALSA SOC CODEC driver
+ *--------------------------------------------------------------------*/
+
+#ifdef ZL380XX_TW_ENABLE_ALSA_CODEC_DRIVER
+
+/* ALSA soc codec default Timberwolf register settings
+ * 3 Example audio cross-point configurations
+ */
+/* ALSA soc codec default Timberwolf register settings
+ * 3 Example audio cross-point configurations
+ */
+#define CODEC_CONFIG_REG_NUM 42
+
+u8 reg_stereo[] ={ 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+
+/*4-port m
+ode with AEC enabled - ROUT to DAC1
+ * MIC1 -> SIN (ADC)
+ * I2S-L -> RIN (TDM Rx path)
+ * SOUT -> I2S-L
+ * ROUT -> DACx
+ *reg 0x202 - 0x22A
+ */
+u8 reg_cache_default[CODEC_CONFIG_REG_NUM] ={0x0c, 0x05, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x0d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x01, 0x06, 0x05, 0x00, 0x02, 0x00, 0x00};
+
+
+
+/*Formatting for the Audio*/
+#define zl380tw_DAI_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000)
+#define zl380tw_DAI_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
+#define zl380tw_DAI_CHANNEL_MIN 1
+#define zl380tw_DAI_CHANNEL_MAX 2
+
+static void zl380tw_fill_codec_cache(struct snd_soc_codec *codec,
+ u8* pData, int numbytes)
+{
+ int i = 0;
+ u8* cache = codec->reg_cache;
+ for (i=0; i< numbytes; i++) {
+ cache[i] = pData[i];
+ //dev_info(codec->dev, "pData[%d]=0x%02x, cache[%d]=0x%02x\n", i, pData[i], i, cache[i]);
+ }
+}
+
+static u16 zl380tw_read_codec_cache(struct snd_soc_codec *codec, u16 reg)
+{
+ u8 i = reg - ZL38040_CACHED_ADDR_LO;
+ if (i < CODEC_CONFIG_REG_NUM) {
+ u8* cache = codec->reg_cache;
+ //dev_info(codec->dev, "cache: 0x%04x = 0x%04x\n", reg, (cache[i] << 8) | cache[i+1]);
+ return (cache[i] << 8) | cache[i+1];
+ }
+ return 0xFBAD;
+}
+
+static int zl380tw_find_index_codec_cache(struct snd_soc_codec *codec, u8 val)
+{
+ int i = 0;
+ u8* cache = codec->reg_cache;
+ /*start the search from reg 210h*/
+ for (i=14; i< CODEC_CONFIG_REG_NUM; i++) {
+ if (cache[i] == val) {
+ //dev_info(codec->dev, "cache[%d]=0x%02x\n", i, cache[i]);
+ if (i%2)
+ --i;
+ return i;
+ }
+ }
+ return -1;
+}
+
+static unsigned int zl380tw_reg_read(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ unsigned int value = 0;
+
+ struct zl380tw *zl380tw = snd_soc_codec_get_drvdata(codec);
+ u16 buf;
+ if (zl380tw_hbi_rd16(zl380tw, reg, &buf) < 0) {
+ return -EIO;
+ }
+ value = buf;
+
+ return value;
+
+}
+
+static int zl380tw_reg_write(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value)
+{
+ struct zl380tw *zl380tw = snd_soc_codec_get_drvdata(codec);
+
+ if (zl380tw_hbi_wr16(zl380tw, reg, value) < 0) {
+ return -EIO;
+ }
+ return 0;
+}
+
+
+/*ALSA- soc codec I2C/SPI read control functions*/
+static int zl380tw_control_read(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct zl380tw *zl380tw = snd_soc_codec_get_drvdata(codec);
+ struct soc_mixer_control *mc =
+ (struct soc_mixer_control *)kcontrol->private_value;
+ unsigned int reg = mc->reg;
+ unsigned int shift = mc->shift;
+ unsigned int mask = mc->max;
+ unsigned int invert = mc->invert;
+ u16 val;
+
+
+ zl380twEnterCritical();
+ if (zl380tw_hbi_rd16(zl380tw, reg, &val)) {
+ zl380twExitCritical();
+ return -EIO;
+ }
+ zl380twExitCritical();
+
+ ucontrol->value.integer.value[0] = ((val >> shift) & mask);
+
+ if (invert)
+ ucontrol->value.integer.value[0] =
+ mask - ucontrol->value.integer.value[0];
+
+ return 0;
+}
+/*ALSA- soc codec I2C/SPI write control functions*/
+static int zl380tw_control_write(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct zl380tw *zl380tw = snd_soc_codec_get_drvdata(codec);
+
+ struct soc_mixer_control *mc =
+ (struct soc_mixer_control *)kcontrol->private_value;
+ unsigned int reg = mc->reg;
+ unsigned int shift = mc->shift;
+ unsigned int mask = mc->max;
+ unsigned int invert = mc->invert;
+ unsigned int val = (ucontrol->value.integer.value[0] & mask);
+ u16 valt;
+
+ if (invert)
+ val = mask - val;
+
+ zl380twEnterCritical();
+ if (zl380tw_hbi_rd16(zl380tw, reg, &valt) < 0) {
+ zl380twExitCritical();
+ return -EIO;
+ }
+ if (((valt >> shift) & mask) == val) {
+ zl380twExitCritical();
+ return 0;
+ }
+ valt &= ~(mask << shift);
+ valt |= val << shift;
+
+ if (zl380tw_reg_write(codec, reg, valt) < 0) {
+ zl380twExitCritical();
+ return -EIO;
+ }
+ zl380twExitCritical();
+
+ return 0;
+}
+
+
+int zl380tw_mute_r(struct snd_soc_codec *codec, int on)
+{
+
+ struct zl380tw *zl380tw = snd_soc_codec_get_drvdata(codec);
+ u16 val;
+
+ zl380twEnterCritical();
+
+ if (zl380tw_hbi_rd16(zl380tw, ZL38040_AEC_CTRL_REG0, &val) < 0){
+ zl380twExitCritical();
+ return -EIO;
+ }
+ if (((val >> 7) & 1) == on){
+ zl380twExitCritical();
+ return 0;
+ }
+ val &= ~(1 << 7);
+ val |= on << 7;
+
+ if (zl380tw_reg_write(codec, ZL38040_AEC_CTRL_REG0, val) < 0){
+ zl380twExitCritical();
+ return -EIO;
+ }
+
+ zl380twExitCritical();
+ return 0;
+}
+
+int zl380tw_mute_s(struct snd_soc_codec *codec, int on)
+{
+ u16 val;
+ struct zl380tw *zl380tw = snd_soc_codec_get_drvdata(codec);
+
+ zl380twEnterCritical();
+
+ if (zl380tw_hbi_rd16(zl380tw, ZL38040_AEC_CTRL_REG0, &val)){
+ zl380twExitCritical();
+ return -EIO;
+ }
+ if (((val >> 8) & 1) == on){
+ zl380twExitCritical();
+ return 0;
+ }
+ val &= ~(1 << 8);
+ val |= on << 8;
+
+ if (zl380tw_reg_write(codec, ZL38040_AEC_CTRL_REG0, val)){
+ zl380twExitCritical();
+ return -EIO;
+ }
+
+ zl380twExitCritical();
+ return 0;
+}
+
+/* configure_codec() - configure the cross-point to either pure 2-channel stereo
+ * or for 4-port mode with Achoustic Echo Canceller
+ * mode: 0 -> Stereo bypass
+ * 1 -> 4-port mode AEC
+ * 2 ->
+ */
+static int zl380tw_configure_codec(struct snd_soc_codec *codec, u8 mode)
+{
+
+
+ struct zl380tw *zl380tw = snd_soc_codec_get_drvdata(codec);
+ u8 *pData;
+
+ switch (mode) {
+ case ZL38040_CR2_DEFAULT: {
+ pData = codec->reg_cache;
+ return zl380tw_hbi_access(zl380tw, ZL38040_OUTPUT_PATH_EN_REG, CODEC_CONFIG_REG_NUM, pData, TWOLF_HBI_WRITE);
+ }
+ case ZL38040_CR2_STEREO_BYPASS: {
+
+ u16 rin_src = zl380tw_read_codec_cache(codec, ZL38040_RIN_IN_PATH_REG);
+ u16 sin1_src = zl380tw_read_codec_cache(codec, ZL38040_SIN_IN_PATH_REG);
+
+ pData = reg_stereo;
+ if ((rin_src != 0) || (sin1_src != 0))
+ zl380tw_hbi_access(zl380tw, ZL38040_DAC1_IN_PATH_REG, 28, pData, TWOLF_HBI_WRITE);
+ if (rin_src != 0) {
+ int rout_crp = zl380tw_find_index_codec_cache(codec, ZL38040_ROUT_PATH);
+ /*find where ROUT is going*/
+ if (rout_crp >=0) {
+ zl380tw_hbi_wr16(zl380tw, ZL38040_CACHED_ADDR_LO+rout_crp, (rin_src & 0xFF));
+ //dev_info(codec->dev, "reg[rout]=0x%04x <-- rin_src = 0x%04x\n", ZL38040_CACHED_ADDR_LO+rout_crp, rin_src);
+ }
+ }
+
+ if (sin1_src != 0) {
+ int sout_crp = zl380tw_find_index_codec_cache(codec, ZL38040_SOUT_PATH);
+ /*find where ROUT is going*/
+ if (sout_crp >=0) {
+ zl380tw_hbi_wr16(zl380tw, ZL38040_CACHED_ADDR_LO+sout_crp, sin1_src);
+ //dev_info(codec->dev, "reg[sout]=0x%04x <-- sin1_src=0x%04x\n", ZL38040_CACHED_ADDR_LO+sout_crp, sin1_src);
+ }
+ }
+
+ return 0;
+ }
+
+ default: {
+ return -EINVAL;
+ }
+ }
+
+}
+/*The DACx, I2Sx, TDMx Gains can be used in both AEC mode or Stereo bypass mode
+ * however the AEC Gains can only be used when AEC is active.
+ * Each input source of the cross-points has two input sources A and B.
+ * The Gain for each source can be controlled independantly.
+ */
+static const struct snd_kcontrol_new zl380tw_snd_controls[] = {
+ SOC_SINGLE_EXT("DAC1 GAIN INA", ZL38040_DAC1_GAIN_REG, 0, 0x6, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("DAC2 GAIN INA", ZL38040_DAC2_GAIN_REG, 0, 0x6, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("I2S1L GAIN INA", ZL38040_I2S1L_GAIN_REG, 0, 0x6, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("I2S1R GAIN INA", ZL38040_I2S1R_GAIN_REG, 0, 0x6, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("I2S2L GAIN INA", ZL38040_I2S2L_GAIN_REG, 0, 0x6, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("I2S2R GAIN INA", ZL38040_I2S2R_GAIN_REG, 0, 0x6, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("TDMA3 GAIN INA", ZL38040_TDMA3_GAIN_REG, 0, 0x6, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("TDMA4 GAIN INA", ZL38040_TDMA4_GAIN_REG, 0, 0x6, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("TDMB3 GAIN INA", ZL38040_TDMB3_GAIN_REG, 0, 0x6, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("TDMB4 GAIN INA", ZL38040_TDMB4_GAIN_REG, 0, 0x6, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("DAC1 GAIN INB", ZL38040_DAC1_GAIN_REG, 8, 0x6, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("DAC2 GAIN INB", ZL38040_DAC2_GAIN_REG, 8, 0x6, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("I2S1L GAIN INB", ZL38040_I2S1L_GAIN_REG, 8, 0x6, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("I2S1R GAIN INB", ZL38040_I2S1R_GAIN_REG, 8, 0x6, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("I2S2L GAIN INB", ZL38040_I2S2L_GAIN_REG, 8, 0x6, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("I2S2R GAIN INB", ZL38040_I2S2R_GAIN_REG, 8, 0x6, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("TDMA3 GAIN INB", ZL38040_TDMA3_GAIN_REG, 8, 0x6, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("TDMA4 GAIN INB", ZL38040_TDMA4_GAIN_REG, 8, 0x6, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("TDMB3 GAIN INB", ZL38040_TDMB3_GAIN_REG, 8, 0x6, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("TDMB4 GAIN INB", ZL38040_TDMB4_GAIN_REG, 8, 0x6, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("AEC ROUT GAIN", ZL38040_USRGAIN, 0, 0x78, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("AEC ROUT GAIN EXT", ZL38040_USRGAIN, 7, 0x7, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("AEC SOUT GAIN", ZL38040_SYSGAIN, 8, 0xf, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("AEC SIN GAIN", ZL38040_SYSGAIN, 0, 0x1f, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("AEC MIC GAIN", ZL38040_MICGAIN, 0, 0x7, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("MUTE SPEAKER ROUT", ZL38040_AEC_CTRL_REG0, 7, 1, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("MUTE MIC SOUT", ZL38040_AEC_CTRL_REG0, 8, 1, 0,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("AEC Bypass", ZL38040_AEC_CTRL_REG0, 4, 1, 1,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("AEC Audio enh bypass", ZL38040_AEC_CTRL_REG0, 5, 1, 1,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("AEC Master Bypass", ZL38040_AEC_CTRL_REG0, 1, 1, 1,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("ALC GAIN", ZL38040_AEC_CTRL_REG1, 12, 1, 1,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("ALC Disable", ZL38040_AEC_CTRL_REG1, 10, 1, 1,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("AEC Tail disable", ZL38040_AEC_CTRL_REG1, 12, 1, 1,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("AEC Comfort Noise", ZL38040_AEC_CTRL_REG1, 6, 1, 1,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("NLAEC Disable", ZL38040_AEC_CTRL_REG1, 14, 1, 1,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("AEC Adaptation", ZL38040_AEC_CTRL_REG1, 1, 1, 1,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("NLP Disable", ZL38040_AEC_CTRL_REG1, 5, 1, 1,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("Noise Inject", ZL38040_AEC_CTRL_REG1, 6, 1, 1,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("LEC Disable", ZL38040_LEC_CTRL_REG, 4, 1, 1,
+ zl380tw_control_read, zl380tw_control_write),
+ SOC_SINGLE_EXT("LEC Adaptation", ZL38040_LEC_CTRL_REG, 1, 1, 1,
+ zl380tw_control_read, zl380tw_control_write),
+
+};
+
+
+int zl380tw_add_controls(struct snd_soc_codec *codec)
+{
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0))
+ return snd_soc_add_controls(codec, zl380tw_snd_controls,
+ ARRAY_SIZE(zl380tw_snd_controls));
+#else
+ return snd_soc_add_codec_controls(codec, zl380tw_snd_controls,
+ ARRAY_SIZE(zl380tw_snd_controls));
+#endif
+}
+
+static int zl380tw_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ struct zl380tw *zl380tw = snd_soc_codec_get_drvdata(codec);
+#ifdef MICROSEMI_DEMO_PLATFORM
+
+ unsigned int buf2, buf3, buf4;
+
+ unsigned int buf0 = zl380tw_reg_read(codec, ZL38040_TDMA_CLK_CFG_REG);
+
+ zl380twEnterCritical();
+ buf2 = zl380tw_reg_read(codec, ZL38040_TDMA_CH1_CFG_REG);
+ buf3 = zl380tw_reg_read(codec, ZL38040_TDMA_CH2_CFG_REG);
+ buf4 = zl380tw_reg_read(codec, ZL38040_AEC_CTRL_REG0);
+
+ if ((buf2 == 0x0BAD) || (buf3 == 0x0BAD)) {
+ zl380twExitCritical();
+ return -1;
+ }
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ buf2 |= (ZL38040_TDMA_16BIT_LIN);
+ buf3 |= (ZL38040_TDMA_16BIT_LIN);
+ buf3 |= 2; /*If PCM use 2 timeslots*/
+ break;
+ case SNDRV_PCM_FORMAT_MU_LAW:
+ buf2 |= (ZL38040_TDMA_8BIT_ULAW);
+ buf3 |= (ZL38040_TDMA_8BIT_ULAW);
+ buf3 |= 1; /*If PCM use 1 timeslots*/
+ break;
+ case SNDRV_PCM_FORMAT_A_LAW:
+ buf2 |= (ZL38040_TDMA_8BIT_ALAW );
+ buf3 |= (ZL38040_TDMA_8BIT_ALAW);
+ buf3 |= 1; /*If PCM use 1 timeslots*/
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ break;
+ default: {
+ zl380twExitCritical();
+ return -EINVAL;
+ }
+ }
+ zl380tw_reg_write(codec, ZL38040_TDMA_CLK_CFG_REG, buf0);
+
+ zl380tw_reg_write(codec, ZL38040_TDMA_CH1_CFG_REG, buf2);
+ zl380tw_reg_write(codec, ZL38040_TDMA_CH2_CFG_REG, buf3);
+ zl380twExitCritical();
+#endif
+ /* If the ZL38040 TDM is configured as a slace I2S/PCM,
+ * The rate settings are not necessary. The Zl38040 has the ability to
+ * auto-detect the master rate and configure itself accordingly
+ * If configured as master, the rate must be set acccordingly
+ */
+ zl380twEnterCritical();
+
+ //dev_info(codec->dev, "b4: init_done=%d, flag=%d\n", zl380tw->init_done , zl380tw->flag);
+ /*initialize codec cache to default config*/
+ if((zl380tw->init_done) /*&& (codec->reg_cache==NULL)*/) {
+
+ u8* cache = codec->reg_cache;
+ if(zl380tw_hbi_access(zl380tw, ZL38040_OUTPUT_PATH_EN_REG, CODEC_CONFIG_REG_NUM, cache, TWOLF_HBI_READ) < 0)
+ {
+ zl380twExitCritical();
+ return -EFAULT;
+ }
+ zl380tw_fill_codec_cache(codec, zl380tw->pData, CODEC_CONFIG_REG_NUM);
+ zl380tw->init_done = 0;
+ zl380tw->flag = 1;
+ }
+ //dev_info(codec->dev, "aft: init_done=%d, flag=%d\n", zl380tw->init_done , zl380tw->flag);
+ switch (params_rate(params)) {
+ case 8000:
+ case 16000:
+ if (zl380tw->flag > 1) {
+ if (zl380tw_configure_codec(codec, ZL38040_CR2_DEFAULT) >=0)
+ zl380tw->flag = 1;
+ }
+ break;
+ /*case 44100: */
+ case 48000:
+ if (zl380tw->flag ==1) {
+ zl380tw_configure_codec(codec, ZL38040_CR2_STEREO_BYPASS);
+ zl380tw->flag = 2;
+ }
+ break;
+ default: {
+ zl380twExitCritical();
+ return -EINVAL;
+ }
+ }
+ zl380tw_reset(zl380tw, ZL38040_RST_SOFTWARE);
+ zl380twExitCritical();
+
+ return 0;
+}
+
+static int zl380tw_mute(struct snd_soc_dai *codec_dai, int mute)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ /*zl380tw_mute_s(codec, mute);*/
+ return zl380tw_mute_r(codec, mute);
+}
+
+static int zl380tw_set_dai_fmt(struct snd_soc_dai *codec_dai,
+ unsigned int fmt)
+{
+#ifdef MICROSEMI_DEMO_PLATFORM
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct zl380tw *zl380tw = snd_soc_codec_get_drvdata(codec);
+ unsigned int buf, buf0;
+
+ zl380twEnterCritical();
+ buf = zl380tw_reg_read(codec, ZL38040_TDMA_CFG_REG);
+ buf0 = zl380tw_reg_read(codec, ZL38040_TDMA_CLK_CFG_REG);
+ if ((buf == 0x0BAD) || (buf0 == 0x0BAD)) {
+ zl380twExitCritical();
+ return -1;
+ }
+
+ dev_info(codec_dai->dev, "zl380tw_set_dai_fmt\n");
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_DSP_B:
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ if ((buf & ZL38040_TDMA_FSALIGN) >> 1)
+ buf &= (~ZL38040_TDMA_FSALIGN);
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ if (!((buf & ZL38040_TDMA_FSALIGN) >> 1))
+ buf |= (ZL38040_TDMA_FSALIGN);
+ break;
+ case SND_SOC_DAIFMT_I2S:
+ if (!((buf & ZL38040_TDM_I2S_CFG_VAL) >> 1)) {
+ buf |= (ZL38040_TDM_I2S_CFG_VAL );
+ }
+ break;
+ default: {
+ zl380twExitCritical();
+ return -EINVAL;
+ }
+ }
+
+ /* set master/slave TDM interface */
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ buf0 |= ZL38040_TDM_TDM_MASTER_VAL;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ if ((buf0 & ZL38040_TDM_TDM_MASTER_VAL) >> 1) {
+ buf0 &= (~ZL38040_TDM_TDM_MASTER_VAL);
+ }
+ break;
+ default: {
+ zl380twExitCritical();
+ return -EINVAL;
+ }
+ }
+
+ zl380tw_reg_write(codec, ZL38040_TDMA_CFG_REG, buf);
+ zl380tw_reg_write(codec, ZL38040_TDMA_CLK_CFG_REG, buf0);
+ zl380tw_reset(zl380tw, ZL38040_RST_SOFTWARE);
+ zl380twExitCritical();
+#endif
+ return 0;
+}
+
+static int zl380tw_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
+ unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct zl380tw *zl380tw = snd_soc_codec_get_drvdata(codec);
+
+ zl380tw->sysclk_rate = freq;
+
+ return 0;
+}
+
+static const struct snd_soc_dai_ops zl380tw_dai_ops = {
+ .set_fmt = zl380tw_set_dai_fmt,
+ .set_sysclk = zl380tw_set_dai_sysclk,
+ .hw_params = zl380tw_hw_params,
+ .digital_mute = zl380tw_mute,
+
+};
+
+static struct snd_soc_dai_driver zl380tw_dai = {
+ .name = "zl380tw-hifi",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = zl380tw_DAI_CHANNEL_MIN,
+ .channels_max = zl380tw_DAI_CHANNEL_MAX,
+ .rates = zl380tw_DAI_RATES,
+ .formats = zl380tw_DAI_FORMATS,
+ },
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = zl380tw_DAI_CHANNEL_MIN,
+ .channels_max = zl380tw_DAI_CHANNEL_MAX,
+ .rates = zl380tw_DAI_RATES,
+ .formats = zl380tw_DAI_FORMATS,
+ },
+ .ops = &zl380tw_dai_ops,
+};
+EXPORT_SYMBOL(zl380tw_dai);
+
+static int zl380tw_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ struct zl380tw *zl380tw = snd_soc_codec_get_drvdata(codec);
+
+ zl380twEnterCritical();
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ break;
+ case SND_SOC_BIAS_PREPARE:
+ break;
+ case SND_SOC_BIAS_STANDBY:
+ /*wake up from sleep*/
+ zl380tw_hbi_init(zl380tw, (HBI_CONFIG_VAL | HBI_CONFIG_WAKE));
+ msleep(10);
+ /*Clear the wake up bit*/
+ zl380tw_hbi_init(zl380tw, HBI_CONFIG_VAL);
+
+ break;
+ case SND_SOC_BIAS_OFF:
+ /*Low power sleep mode*/
+ zl380tw_write_cmdreg(zl380tw, ZL38040_CMD_APP_SLEEP);
+
+ break;
+ }
+ zl380twExitCritical();
+
+ //codec->dapm.bias_level = level;
+ return 0;
+}
+
+static int zl380tw_suspend(struct snd_soc_codec *codec
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0))
+ , pm_message_t state
+#endif
+)
+{
+ zl380twEnterCritical();
+ zl380tw_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ zl380twExitCritical();
+ return 0;
+}
+
+static int zl380tw_resume(struct snd_soc_codec *codec)
+{
+ zl380twEnterCritical();
+ zl380tw_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ zl380twExitCritical();
+ return 0;
+}
+
+static void zl380tw_sub_probe_clean(void);
+
+static int zl380tw_probe(struct snd_soc_codec *codec)
+{
+ dev_info(codec->dev, "Probing zl380tw SoC CODEC driver\n");
+ return zl380tw_add_controls(codec);
+}
+
+static int zl380tw_remove(struct snd_soc_codec *codec)
+{
+ return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_zl380tw = {
+ .probe = zl380tw_probe,
+ .remove = zl380tw_remove,
+ .suspend = zl380tw_suspend,
+ .resume = zl380tw_resume,
+ .read = zl380tw_reg_read,
+ .write = zl380tw_reg_write,
+ .set_bias_level = zl380tw_set_bias_level,
+ .reg_cache_size = CODEC_CONFIG_REG_NUM,
+ .reg_word_size = sizeof(u8),
+ .reg_cache_default = reg_cache_default,
+ .reg_cache_step = 1,
+};
+EXPORT_SYMBOL(soc_codec_dev_zl380tw);
+#endif /*ZL380XX_TW_ENABLE_ALSA_CODEC_DRIVER*/
+
+/*--------------------------------------------------------------------
+ * ALSA SOC CODEC driver - END
+ *--------------------------------------------------------------------*/
+
+
+/*--------------------------------------------------------------------
+ * CHARACTER type Host Interface driver
+ *--------------------------------------------------------------------*/
+#ifdef ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER
+
+/* read 16bit HBI Register */
+/* slave_rd16()- read a 16bit word
+ * \param[in] pointer the to where to store the data
+ *
+ * return ::status
+ */
+static int zl380tw_rd16(struct zl380tw *zl380tw, u16 *pdata)
+{
+ u8 buf[2] = {0, 0};
+ int status = 0;
+#ifdef MICROSEMI_HBI_SPI
+ struct spi_message msg;
+ struct spi_transfer xfer = {
+ .len = 2,
+ .rx_buf = buf,
+ };
+
+ spi_message_init(&msg);
+
+ spi_message_add_tail(&xfer, &msg);
+ status = spi_sync(zl380tw->spi, &msg);
+#endif
+#ifdef MICROSEMI_HBI_I2C
+ status = i2c_master_recv(zl380tw->i2c, buf, 2);
+#endif
+ if (status < 0) {
+ return status;
+ }
+
+ *pdata = (buf[0]<<8) | buf[1] ; /* Byte_HI, Byte_LO */
+ return 0;
+}
+
+
+ static long zl380tw_io_ioctl(
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))
+ struct inode *i,
+#endif
+ struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ int retval =0;
+ u16 buf =0;
+ struct zl380tw *zl380tw = filp->private_data;
+
+ switch (cmd) {
+
+ case TWOLF_HBI_WR16:
+ if (copy_from_user(&zl380tw_ioctl_buf,
+ (ioctl_zl380tw *)arg,
+ sizeof(ioctl_zl380tw)))
+ return -EFAULT;
+ zl380twEnterCritical();
+ retval = zl380tw_hbi_wr16(zl380tw, (u16)zl380tw_ioctl_buf.addr,
+ zl380tw_ioctl_buf.data);
+ zl380twExitCritical();
+ break;
+ case TWOLF_HBI_RD16:
+ if (copy_from_user(&zl380tw_ioctl_buf,
+ (ioctl_zl380tw *)arg,
+ sizeof(ioctl_zl380tw)))
+ return -EFAULT;
+ zl380twEnterCritical();
+ retval = zl380tw_hbi_rd16(zl380tw, (u16)zl380tw_ioctl_buf.addr,
+ &zl380tw_ioctl_buf.data);
+ zl380twExitCritical();
+ if (!retval) {
+ if (copy_to_user((ioctl_zl380tw *)arg,
+ &zl380tw_ioctl_buf,
+ sizeof(ioctl_zl380tw)))
+ return -EFAULT;
+ } else
+ return -EAGAIN;
+ break;
+ case TWOLF_BOOT_PREPARE :
+ zl380twEnterCritical();
+ retval = zl380tw_boot_prepare(zl380tw);
+ zl380twExitCritical();
+ break;
+ case TWOLF_BOOT_SEND_MORE_DATA: {
+ if (copy_from_user(zl380tw->pData,
+ (char *)arg,
+ MAX_TWOLF_ACCESS_SIZE_IN_BYTES))
+ return -EFAULT;
+ zl380twEnterCritical();
+ retval = zl380tw_boot_Write(zl380tw, zl380tw->pData);
+ zl380twExitCritical();
+ break;
+ }
+ case TWOLF_BOOT_CONCLUDE :
+ zl380twEnterCritical();
+ retval = zl380tw_boot_conclude(zl380tw);
+ zl380twExitCritical();
+ break;
+
+ case TWOLF_CMD_PARAM_REG_ACCESS :
+ retval = __get_user(buf, (u16 __user *)arg);
+ if (retval ==0) {
+ zl380twEnterCritical();
+ retval = zl380tw_write_cmdreg(zl380tw, buf);
+ zl380twExitCritical();
+ }
+ break;
+ case TWOLF_CMD_PARAM_RESULT_CHECK :
+ zl380twEnterCritical();
+ retval = zl380tw_cmdresult_check(zl380tw);
+ zl380twExitCritical();
+ break;
+ case TWOLF_RESET :
+ retval = __get_user(buf, (u16 __user *)arg);
+ if (retval ==0) {
+ zl380twEnterCritical();
+ retval = zl380tw_reset(zl380tw, buf);
+ zl380twExitCritical();
+ }
+ break;
+ case TWOLF_SAVE_FWR_TO_FLASH :
+ zl380twEnterCritical();
+ retval = zl380tw_save_image_to_flash(zl380tw);
+ zl380twExitCritical();
+ break;
+ case TWOLF_LOAD_FWR_FROM_FLASH :
+ retval = __get_user(buf, (u16 __user *)arg);
+ if (retval ==0) {
+ zl380twEnterCritical();
+ retval = zl380tw_load_fwr_from_flash(zl380tw, buf);
+ zl380twExitCritical();
+ }
+ break;
+ case TWOLF_SAVE_CFG_TO_FLASH :
+ retval = __get_user(buf, (u16 __user *)arg);
+ if (retval ==0) {
+ zl380twEnterCritical();
+ retval = zl380tw_save_cfg_to_flash(zl380tw, buf);
+ zl380twExitCritical();
+ }
+ break;
+ case TWOLF_LOAD_CFG_FROM_FLASH :
+ retval = __get_user(buf, (u16 __user *)arg);
+ if (retval ==0) {
+ zl380twEnterCritical();
+ retval = zl380tw_load_cfg_from_flash(zl380tw, buf);
+ zl380twExitCritical();
+ }
+ break;
+ case TWOLF_ERASE_IMGCFG_FLASH :
+ retval = __get_user(buf, (u16 __user *)arg);
+ if (retval ==0) {
+ zl380twEnterCritical();
+ retval = zl380tw_erase_fwrcfg_from_flash(zl380tw, buf);
+ zl380twExitCritical();
+ }
+ break;
+ case TWOLF_LOAD_FWRCFG_FROM_FLASH :
+ retval = __get_user(buf, (u16 __user *)arg);
+ if (retval ==0) {
+ zl380twEnterCritical();
+ retval = zl380tw_load_fwrcfg_from_flash(zl380tw, buf);
+ zl380twExitCritical();
+ }
+ break;
+ case TWOLF_HBI_WR_ARB_SINGLE_WORD :
+ retval = __get_user(buf, (u16 __user *)arg);
+ if (retval ==0) {
+ zl380twEnterCritical();
+ retval = zl380tw_wr16(zl380tw, buf);
+ zl380twExitCritical();
+ }
+ break;
+ case TWOLF_HBI_RD_ARB_SINGLE_WORD :
+ zl380twEnterCritical();
+ retval = zl380tw_rd16(zl380tw, &buf);
+ zl380twExitCritical();
+ if (retval ==0)
+ retval = __put_user(buf, (__u16 __user *)arg);
+ break;
+ case TWOLF_HBI_INIT :
+ retval = __get_user(buf, (u16 __user *)arg);
+ if (retval ==0) {
+ zl380twEnterCritical();
+ retval = zl380tw_hbi_init(zl380tw, buf);
+ zl380twExitCritical();
+ }
+ break;
+ case TWOLF_ERASE_ALL_FLASH :
+ zl380twEnterCritical();
+ retval = zl380tw_reset(zl380tw, ZL38040_RST_TO_BOOT);
+ if (retval ==0)
+ retval = zl380tw_erase_flash(zl380tw);
+ zl380twExitCritical();
+ break;
+ case TWOLF_STOP_FWR :
+ zl380twEnterCritical();
+ retval = zl380tw_stop_fwr_to_bootmode(zl380tw);
+ zl380twExitCritical();
+ break;
+ case TWOLF_START_FWR :
+ zl380twEnterCritical();
+ retval = zl380tw_start_fwr_from_ram(zl380tw);
+ zl380twExitCritical();
+ break;
+
+ default:
+ printk(KERN_DEBUG "ioctl: Invalid Command Value");
+ retval = -EINVAL;
+ }
+ return retval;
+}
+
+
+
+/*----------------------------------------------------------------------*
+ * The ZL38040/05x/06x/08x kernel specific aceess functions are defined below
+ *-------------------------ZL380xx FUNCTIONs-----------------------------*/
+
+/* This function is best used to simply retrieve pending data following a
+ * previously sent write command
+ * The data is returned in bytes format. Up to 256 data bytes.
+ */
+
+static ssize_t zl380tw_io_read(struct file *filp, char __user *buf, size_t count,
+ loff_t *f_pos)
+{
+ /* This access uses the spi/i2c command frame format - where both
+ * the whole data is read in one active chip_select
+ */
+
+ struct zl380tw *zl380tw = filp->private_data;
+
+ int status = 0;
+ u16 cmd = 0;
+ if (count > twHBImaxTransferSize)
+ return -EMSGSIZE;
+
+#ifdef MICROSEMI_HBI_SPI
+ if (zl380tw->spi == NULL) {
+ TW_DEBUG1("spi device is not available \n");
+ return -ESHUTDOWN;
+ }
+#endif
+#ifdef MICROSEMI_HBI_I2C
+ if (zl380tw->i2c == NULL) {
+ TW_DEBUG1("zl380tw_io_read::i2c device is not available \n");
+ return -ESHUTDOWN;
+ }
+
+#endif
+ zl380twEnterCritical();
+ if (copy_from_user(zl380tw->pData, buf, count)) {
+ zl380twExitCritical();
+ return -EFAULT;
+ }
+ cmd = (*(zl380tw->pData + 0) << 8) | (*(zl380tw->pData + 1));
+ /*read the data*/
+ status = zl380tw_hbi_access(zl380tw,
+ cmd, count, zl380tw->pData, TWOLF_HBI_READ);
+ if (status < 0) {
+ zl380twExitCritical();
+ return -EFAULT;
+ }
+ if (copy_to_user(buf, zl380tw->pData, count)) {
+ zl380twExitCritical();
+ return -EFAULT;
+ }
+ zl380twExitCritical();
+ return 0;
+}
+
+/* Write multiple bytes (up to 254) to the device
+ * the data should be formatted as follows
+ * cmd_type,
+ * cmd_byte_low,
+ * cmd_byte_hi,
+ * data0_byte_low,
+ * data0_byte_hi
+ * ...
+ * datan_byte_low, datan_byte_hi (n < 254)
+ */
+
+static ssize_t zl380tw_io_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *f_pos)
+{
+ /* This access use the spi/i2c command frame format - where both
+ * the command and the data to write are sent in one active chip_select
+ */
+ struct zl380tw *zl380tw = filp->private_data;
+
+ int status = 0;
+ u16 cmd = 0;
+
+ if (count > twHBImaxTransferSize)
+ return -EMSGSIZE;
+ zl380twEnterCritical();
+ if (copy_from_user(zl380tw->pData, buf, count)) {
+ zl380twExitCritical();
+ return -EFAULT;
+ }
+ cmd = (*(zl380tw->pData + 0) << 8) | (*(zl380tw->pData + 1));
+ TW_DEBUG2("count = %d\n",count);
+ /*remove the cmd numbytes from the count*/
+ status = zl380tw_hbi_access(zl380tw,
+ cmd, count-2, (zl380tw->pData+2), TWOLF_HBI_WRITE);
+ if (status < 0) {
+ zl380twExitCritical();
+ return -EFAULT;
+ }
+ zl380twExitCritical();
+ return status;
+}
+
+static int zl380tw_io_open(struct inode *inode, struct file *filp)
+{
+
+ if (module_usage_count) {
+ printk(KERN_ERR "microsemi_slave_zl380xx device alrady opened\n");
+ return -EBUSY;
+ }
+
+ module_usage_count++;
+ filp->private_data = zl380tw_priv;
+
+ return 0;
+}
+
+static int zl380tw_io_close(struct inode *inode, struct file *filp)
+{
+
+ //struct zl380tw *zl380tw = filp->private_data;
+ filp->private_data = NULL;
+
+ if (module_usage_count) {
+ module_usage_count--;
+ }
+
+ return 0;
+}
+
+static const struct file_operations zl380tw_fops = {
+ .owner = THIS_MODULE,
+ .open = zl380tw_io_open,
+ .read = zl380tw_io_read,
+ .write = zl380tw_io_write,
+ .release = zl380tw_io_close,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))
+ .ioctl = zl380tw_io_ioctl
+#else
+ .unlocked_ioctl = zl380tw_io_ioctl
+#endif
+};
+
+/*----------------------------------------------------------------------------*/
+
+
+
+static struct class *zl380tw_class;
+#endif /*ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER */
+ /*--------------------------------------------------------------------
+ * CHARACTER type Host Interface driver - END
+ *--------------------------------------------------------------------*/
+
+#ifdef SUPPORT_LINUX_DEVICE_TREE_OF_MATCHING
+/*IMPORTANT note: Change this controller string maching accordingly per your *.dts or *dtsi compatible definition file*/
+static struct of_device_id zl380tw_of_match[] = {
+ { .compatible = "ambarella,zl380tw",},
+ {},
+};
+MODULE_DEVICE_TABLE(of, zl380tw_of_match);
+#endif /*SUPPORT_LINUX_DEVICE_TREE_OF_MATCHING*/
+
+static int zl380tw_sub_probe(void)
+{
+ /* Allocate driver data */
+ zl380tw_priv = kzalloc(sizeof(*zl380tw_priv), GFP_KERNEL);
+ if (zl380tw_priv == NULL)
+ return -ENOMEM;
+
+ /* Allocating memory for the data buffer */
+ zl380tw_priv->pData = kmalloc(twHBImaxTransferSize, GFP_KERNEL);
+ if (!zl380tw_priv->pData) {
+ printk(KERN_ERR "Error allocating %d bytes pdata memory",
+ twHBImaxTransferSize);
+ kfree(zl380tw_priv);
+ return -ENOMEM;
+ }
+ memset(zl380tw_priv->pData, 0, twHBImaxTransferSize);
+ return 0;
+}
+
+static void zl380tw_sub_probe_clean(void)
+{
+ kfree(zl380tw_priv);
+ kfree((void *)zl380tw_priv->pData);
+ zl380tw_priv->pData = NULL;
+}
+
+
+#ifdef ZL380TW_DEV_BIND_SLAVE_TO_MASTER
+/* Bind the client driver to a master (SPI or I2C) adapter */
+
+static int zl380xx_slaveMaster_binding(void) {
+#ifdef MICROSEMI_HBI_SPI
+ struct spi_board_info spi_device_info = {
+ .modalias = "zl380tw",
+ .max_speed_hz = SPIM_CLK_SPEED,
+ .bus_num = SPIM_BUS_NUM,
+ .chip_select = SPIM_CHIP_SELECT,
+ .mode = SPIM_MODE,
+ };
+ struct spi_device *client;
+ struct spi_master *master;
+ /* create a new slave device, given the master and device info
+ * if another device is alread assigned to that bus.cs, then this will fail
+ */
+ /* get the master device, given SPI the bus number*/
+ master = spi_busnum_to_master( spi_device_info.bus_num );
+ if( !master )
+ return -ENODEV;
+ printk(KERN_INFO "SPI master device found at bus = %d\n", master->bus_num);
+
+ client = spi_new_device( master, &spi_device_info );
+ if( !client )
+ return -ENODEV;
+ printk(KERN_INFO "SPI slave device %s, module alias %s added at bus = %d, cs =%d\n",
+ client->dev.driver->name, client->modalias, client->master->bus_num, client->chip_select);
+#endif
+#ifdef MICROSEMI_HBI_I2C /*#ifdef MICROSEMI_HBI_I2C*/
+ struct i2c_board_info i2c_device_info = {
+ I2C_BOARD_INFO("zl380tw", MICROSEMI_I2C_ADDR),
+ .platform_data = NULL,
+ };
+ struct i2c_client *client;
+ /*create a new client for that adapter*/
+ /*get the i2c adapter*/
+ struct i2c_adapter *master = i2c_get_adapter(CONTROLLER_I2C_BUS_NUM);
+ if( !master )
+ return -ENODEV;
+ printk(KERN_INFO "found I2C master device %s \n", master->name);
+
+ client = i2c_new_device( master, &i2c_device_info);
+ if( !client)
+ return -ENODEV;
+
+ printk(KERN_INFO "I2C slave device %s, module alias %s attached to I2C master device %s\n",
+ client->dev.driver->name, client->name, master->name);
+
+ i2c_put_adapter(master);
+#endif /*MICROSEMI_HBI_SPI/I2C interface selection macro*/
+
+ return 0;
+
+}
+
+static int zl380tw_slaveMaster_unbind(void)
+{
+#ifdef MICROSEMI_HBI_SPI
+ spi_unregister_device(zl380tw_priv->spi);
+#endif
+#ifdef MICROSEMI_HBI_I2C /*#ifdef MICROSEMI_HBI_I2C*/
+ i2c_unregister_device(zl380tw_priv->i2c);
+#endif
+
+ return 0;
+}
+
+#endif //ZL380TW_DEV_BIND_SLAVE_TO_MASTER
+/*--------------------------------------------------------------------
+* SPI driver registration
+*--------------------------------------------------------------------*/
+
+#ifdef MICROSEMI_HBI_SPI
+static int zl380tw_spi_probe(struct spi_device *spi)
+{
+
+ int err, ret;
+ enum of_gpio_flags flags;
+
+ err = zl380tw_sub_probe();
+ if (err < 0) {
+ return err;
+ }
+ dev_dbg(&spi->dev, "probing zl380tw spi device\n");
+
+ spi->master->bus_num = 1;//SPIM_BUS_NUM;
+ spi->mode = SPI_MODE_0;
+ spi->max_speed_hz = SPIM_CLK_SPEED;
+ spi->chip_select = SPIM_CHIP_SELECT;
+ spi->bits_per_word = 8;
+
+ err = spi_setup(spi);
+ if (err < 0) {
+ zl380tw_sub_probe_clean();
+ return err;
+ }
+
+ /* Initialize the driver data */
+ spi_set_drvdata(spi, zl380tw_priv);
+ zl380tw_priv->spi = spi;
+
+ zl380tw_priv->pwr_pin = of_get_named_gpio_flags(spi->dev.of_node, "zl380,pwr-gpio", 0, &flags);
+ zl380tw_priv->pwr_active = !!(flags & OF_GPIO_ACTIVE_LOW);
+
+ if(zl380tw_priv->pwr_pin < 0 || !gpio_is_valid(zl380tw_priv->pwr_pin)) {
+ printk(KERN_ERR "zl380 power pin is invalid\n");
+ zl380tw_priv->pwr_pin = -1;
+ return -1;
+ }
+
+ if(gpio_is_valid(zl380tw_priv->pwr_pin)) {
+ ret = devm_gpio_request(&spi->dev, zl380tw_priv->pwr_pin, "zl380xx pwr");
+ if(ret < 0) {
+ dev_err(&spi->dev, "Failed to request pwr pin for zl380xx: %d\n", ret);
+ return ret;
+ }
+ gpio_direction_output(zl380tw_priv->pwr_pin, zl380tw_priv->pwr_active);
+ }
+
+ zl380tw_priv->rst_pin = of_get_named_gpio_flags(spi->dev.of_node, "zl380,rst-gpio", 0, &flags);
+ zl380tw_priv->rst_active = !!(flags & OF_GPIO_ACTIVE_LOW);
+
+ if(zl380tw_priv->rst_pin < 0 || !gpio_is_valid(zl380tw_priv->rst_pin)) {
+ printk(KERN_ERR "zl380 power pin is invalid\n");
+ zl380tw_priv->rst_pin = -1;
+ return -1;
+ }
+
+ if(gpio_is_valid(zl380tw_priv->rst_pin)) {
+ ret = devm_gpio_request(&spi->dev, zl380tw_priv->rst_pin, "zl380xx reset");
+ if(ret < 0) {
+ dev_err(&spi->dev, "Failed to request reset pin for zl380xx: %d\n", ret);
+ return ret;
+ }
+ gpio_direction_output(zl380tw_priv->rst_pin, zl380tw_priv->rst_active);
+ msleep(10);
+ gpio_direction_output(zl380tw_priv->rst_pin, !zl380tw_priv->rst_active);
+ }
+
+#ifdef ZL380XX_TW_ENABLE_ALSA_CODEC_DRIVER
+ {
+ u16 buf = 0;
+
+ zl380tw_priv->flag = 0;
+
+ zl380tw_hbi_rd16(zl380tw_priv, ZL38040_DEVICE_ID_REG, &buf);
+ if((buf > 38000) && (buf < 38090)) {
+ zl380tw_priv->init_done =1;
+ printk("SPI slave device %d found at bus::cs = %d::%d\n", buf, spi->master->bus_num, spi->chip_select);
+
+ } else {
+ zl380tw_priv->init_done =0;
+ }
+ }
+
+ err = snd_soc_register_codec(&spi->dev, &soc_codec_dev_zl380tw, &zl380tw_dai, 1);
+ if(err < 0) {
+ zl380tw_sub_probe_clean();
+ dev_dbg(&spi->dev, "zl380tw spi device not created!!!\n");
+ return err;
+ }
+#endif
+
+#ifdef ZL380XX_TW_UPDATE_FIRMWARE
+ if (zl380tw_ldfwr(zl380tw_priv) < 0) {
+ dev_dbg(&spi->dev, "error loading the firmware into the codec\n");
+#ifdef ZL380XX_TW_ENABLE_ALSA_CODEC_DRIVER
+ snd_soc_unregister_codec(&spi->dev);
+#endif
+ zl380tw_sub_probe_clean();
+ return -ENODEV;
+ }
+#endif
+ dev_dbg(&spi->dev, "zl380tw codec device created...\n");
+
+ return 0;
+}
+
+static int zl380tw_spi_remove(struct spi_device *spi)
+{
+
+#ifdef ZL380XX_TW_ENABLE_ALSA_CODEC_DRIVER
+ snd_soc_unregister_codec(&spi->dev);
+#endif
+ kfree(spi_get_drvdata(spi));
+ if (!module_usage_count) {
+
+ kfree((void *)zl380tw_priv->pData);
+ zl380tw_priv->pData = NULL;
+ }
+ return 0;
+}
+
+static struct spi_driver zl380tw_spi_driver = {
+ .driver = {
+ .name = "zl380tw",
+ .owner = THIS_MODULE,
+#ifdef SUPPORT_LINUX_DEVICE_TREE_OF_MATCHING
+ .of_match_table = zl380tw_of_match,
+#endif
+ },
+ .probe = zl380tw_spi_probe,
+ .remove = zl380tw_spi_remove,
+};
+#endif
+
+#ifdef MICROSEMI_HBI_I2C
+
+static int zl380tw_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ int err = zl380tw_sub_probe();
+ if (err < 0) {
+ return err;
+ }
+
+ dev_dbg(&i2c->dev, "probing zl380tw I2C device\n");
+ //i2c->addr = MICROSEMI_I2C_ADDR;
+
+ i2c_set_clientdata(i2c, zl380tw_priv);
+ zl380tw_priv->i2c = i2c;
+ printk(KERN_ERR "i2c slave device address = 0x%04x\n", i2c->addr);
+
+#ifdef ZL380XX_TW_ENABLE_ALSA_CODEC_DRIVER
+ {
+ u16 buf = 0;
+
+ zl380tw_priv->flag = 0;
+
+ zl380tw_hbi_rd16(zl380tw_priv, ZL38040_DEVICE_ID_REG, &buf);
+ if((buf > 38000) && (buf < 38090)) {
+ zl380tw_priv->init_done =1;
+ printk(KERN_ERR "I2C slave device %d found at address = 0x%04x\n", buf, i2c->addr);
+
+ } else {
+ zl380tw_priv->init_done =0;
+ }
+ }
+
+ err = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_zl380tw, &zl380tw_dai, 1);
+ if(err < 0) {
+ zl380tw_sub_probe_clean();
+ dev_dbg(&i2c->dev, "zl380tw I2c device not created!!!\n");
+ return err;
+ }
+#endif
+
+#ifdef ZL380XX_TW_UPDATE_FIRMWARE
+ if (zl380tw_ldfwr(zl380tw_priv) < 0) {
+ dev_dbg(&i2c->dev, "error loading the firmware into the codec\n");
+#ifdef ZL380XX_TW_ENABLE_ALSA_CODEC_DRIVER
+ snd_soc_unregister_codec(&i2c->dev);
+#endif
+ zl380tw_sub_probe_clean();
+ return -ENODEV;
+ }
+#endif
+ dev_dbg(&i2c->dev, "zl380tw I2C codec device created...\n");
+ return err;
+}
+
+static int zl380tw_i2c_remove(struct i2c_client *i2c)
+{
+
+#ifdef ZL380XX_TW_ENABLE_ALSA_CODEC_DRIVER
+ snd_soc_unregister_codec(&i2c->dev);
+#endif
+ kfree(i2c_get_clientdata(i2c));
+ if (!module_usage_count) {
+
+ kfree((void *)zl380tw_priv->pData);
+ zl380tw_priv->pData = NULL;
+ }
+ return 0;
+}
+
+static struct i2c_device_id zl380tw_id_table[] = {
+ {"zl380tw", 0 },
+ {}
+ };
+
+static struct i2c_driver zl380tw_i2c_driver = {
+ .driver = {
+ .name = "zl380tw",
+ .owner = THIS_MODULE,
+#ifdef SUPPORT_LINUX_DEVICE_TREE_OF_MATCHING
+ .of_match_table = zl380tw_of_match,
+#endif
+ },
+ .probe = zl380tw_i2c_probe,
+ .remove = zl380tw_i2c_remove,
+ .id_table = zl380tw_id_table,
+};
+
+#endif
+
+
+static int __init zl380tw_init(void)
+{
+ int status;
+
+#ifdef ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER
+ struct device *dev;
+ status = alloc_chrdev_region(&t_dev, FIRST_MINOR, NUMBER_OF_ZL380xx_DEVICES,
+ "zl380tw");
+ if (status < 0) {
+ printk(KERN_ERR "Failed to register character device");
+ return status;
+ }
+
+ /*create the device class*/
+ zl380tw_class = class_create(THIS_MODULE, "zl380tw");
+ if (zl380tw_class == NULL) {
+ printk(KERN_ERR "Error %d creating class zl380tw", status);
+ unregister_chrdev_region(t_dev, NUMBER_OF_ZL380xx_DEVICES);
+ return -1;
+ }
+
+ /* registration of character device */
+ dev = device_create(zl380tw_class, NULL,
+ t_dev, NULL, "zl380tw");
+ if (IS_ERR(dev)) {
+ printk(KERN_ERR "Error %d creating device zl380tw", status);
+ class_destroy(zl380tw_class);
+ unregister_chrdev_region(t_dev, NUMBER_OF_ZL380xx_DEVICES);
+ }
+ status = IS_ERR(dev) ? PTR_ERR(dev) : 0;
+ if (status == 0) {
+ /* Initialize of character device */
+ cdev_init(&c_dev, &zl380tw_fops);
+ /* addding character device */
+ status = cdev_add(&c_dev, t_dev, NUMBER_OF_ZL380xx_DEVICES);
+ if (status < 0) {
+ printk(KERN_ERR "Error %d adding zl380tw", status);
+ class_destroy(zl380tw_class);
+ device_destroy(zl380tw_class, t_dev);
+ cdev_del(&c_dev);
+ unregister_chrdev_region(t_dev, NUMBER_OF_ZL380xx_DEVICES);
+ return -1;
+ }
+ }
+#endif
+#ifdef MICROSEMI_HBI_SPI
+ status = spi_register_driver(&zl380tw_spi_driver);
+#endif
+#ifdef MICROSEMI_HBI_I2C
+ status = i2c_add_driver(&zl380tw_i2c_driver);
+#endif
+ if (status < 0) {
+#ifdef ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER
+ class_destroy(zl380tw_class);
+ cdev_del(&c_dev);
+ unregister_chrdev_region(t_dev, NUMBER_OF_ZL380xx_DEVICES);
+#endif
+ }
+#ifdef ZL380TW_DEV_BIND_SLAVE_TO_MASTER
+ status = zl380xx_slaveMaster_binding();
+ if (status < 0) {
+ printk(KERN_ERR "error =%d\n", status);
+#ifdef ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER
+ class_destroy(zl380tw_class);
+ device_destroy(zl380tw_class, t_dev);
+ cdev_del(&c_dev);
+ unregister_chrdev_region(t_dev, NUMBER_OF_ZL380xx_DEVICES);
+#endif
+#ifdef MICROSEMI_HBI_SPI
+ spi_unregister_driver(&zl380tw_spi_driver);
+#endif
+#ifdef MICROSEMI_HBI_I2C
+ i2c_del_driver(&zl380tw_i2c_driver);
+#endif
+ return -1;
+ }
+ status =0;
+#endif
+ return status;
+}
+module_init(zl380tw_init);
+
+static void __exit zl380tw_exit(void)
+{
+#ifdef ZL380TW_DEV_BIND_SLAVE_TO_MASTER
+ zl380tw_slaveMaster_unbind();
+#endif
+#ifdef MICROSEMI_HBI_SPI
+ spi_unregister_driver(&zl380tw_spi_driver);
+#endif
+#ifdef MICROSEMI_HBI_I2C
+ i2c_del_driver(&zl380tw_i2c_driver);
+#endif
+#ifdef ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER
+ device_destroy(zl380tw_class, t_dev);
+ class_destroy(zl380tw_class);
+ cdev_del(&c_dev);
+ unregister_chrdev_region(t_dev, NUMBER_OF_ZL380xx_DEVICES);
+#endif
+}
+module_exit(zl380tw_exit);
+
+MODULE_AUTHOR("Jean Bony <jean.bony@microsemi.com>");
+MODULE_DESCRIPTION(" Microsemi Timberwolf i2c/spi/char/alsa codec driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/zl380tw.h b/sound/soc/codecs/zl380tw.h
new file mode 100644
index 00000000..44aa7416
--- /dev/null
+++ b/sound/soc/codecs/zl380tw.h
@@ -0,0 +1,334 @@
+#ifndef __ZL380TW_H
+#define __ZL380TW_H
+
+#undef MICROSEMI_DEMO_PLATFORM /*leave this macro undefined unless requested by Microsemi*/
+/*-------------------------------------------------------------*
+ * HOST MACROS - Define/undefine as desired
+ * -----------------------------------------
+ * Supported combinations:
+ * ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER + ZL380XX_TW_ENABLE_ALSA_CODEC_DRIVER + MICROSEMI_HBI_I2C or MICROSEMI_HBI_SPI
+ * ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER + MICROSEMI_HBI_I2C or MICROSEMI_HBI_SPI
+ * ZL380XX_TW_ENABLE_ALSA_CODEC_DRIVER + MICROSEMI_HBI_I2C or MICROSEMI_HBI_SPI
+ *
+ * all of the above can be used with the ZL380XX_TW_UPDATE_FIRMWARE
+ *-------------------------------------------------------------*/
+#define ZL380XX_TW_ENABLE_ALSA_CODEC_DRIVER /*Define this macro to create a /sound/soc ALSA codec device driver*/
+#define ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER /*Define this macro to create a character device driver*/
+
+/*Enable either one of this macro to create a SPI or an I2C device driver
+* to be used as the low-level transport for the ALSA and/or CHAR device read/write accesses
+*/
+#undef MICROSEMI_HBI_I2C /*Enable this macro if the HBI interface between the host CPU and the Twolf is I2C*/
+#ifdef MICROSEMI_HBI_I2C
+ #undef MICROSEMI_HBI_SPI
+ #define MICROSEMI_I2C_ADDR 0x45 /*if DIN pin is tied to ground, else if DIN is tied to 3.3V address must be 0x52*/
+ #define CONTROLLER_I2C_BUS_NUM 0
+#else
+ #define MICROSEMI_HBI_SPI
+ /*Define the SPI master signal config*/
+ #define SPIM_CLK_SPEED 15000000
+ #define SPIM_CHIP_SELECT 0
+ #define SPIM_MODE SPI_MODE_0
+ #define SPIM_BUS_NUM 0
+#endif
+
+//#undef ZL380XX_TW_UPDATE_FIRMWARE /*define if you want to update current firmware with a new one at power up*/
+//#undef ZL380XX_TW_UPDATE_FIRMWARE
+#define ZL380XX_TW_UPDATE_FIRMWARE
+
+#ifdef ZL380XX_TW_UPDATE_FIRMWARE
+//#define ZL380TW_INCLUDE_FIRMWARE_REQUEST_LIB
+/*NOTE: Rename the *s3 firmware file as per below or simply change the file name below as per the firmware file name
+* If there is more than 1 device create new path name and pass them to the firmware loading function accordingly
+*/
+ #define ZLS380TW0_TWOLF "ZLS38062.0_E1.1.0_App.s3" /*firmware for your zl380xx device 0*/
+
+#define ZL380XX_TW_UPDATE_CONFIG
+#ifdef ZL380XX_TW_UPDATE_CONFIG
+ #define ZLS380TW0_TWOLF_CRK "ZLS38062_20151223_AMBA.CR2" /*configuration record for your zl380xx device 0*/
+#endif
+#endif /*ZL380XX_TW_UPDATE_FIRMWARE*/
+
+#undef ZL38040_SAVE_FWR_TO_FLASH /*define if a slave flash is connected to the zl380tw and you want to save the loaded firmware/config to flash*/
+
+
+
+/*HBI access to the T-wolf must not be interrupted by another process*/
+#define PROTECT_CRITICAL_SECTION /*define this macro to protect HBI critical section*/
+
+/*The zl380tw device registration can be done using the Linux device OF matching scheme or
+* or by using the old method via the board init file
+* This driver includes the method to auto-detect the SPI or I2C master and register itself to that
+* master as per the defined bus info above
+*/
+#define SUPPORT_LINUX_DEVICE_TREE_OF_MATCHING /*define this if you are using the linux device tree (*dts, *dtb, etc.. of maching lib*/
+#ifdef SUPPORT_LINUX_DEVICE_TREE_OF_MATCHING
+#define CONTROLLER_DTS_STRING "ambarella" /*Change the string name accordingly to your device tree controller/driver maching name*/
+#else
+/*define this macro if the board_info registration is not already done in your board init file
+* This macro will cause a new slave device (SPI or I2C) to be created and attached to the master
+* device controller
+* If you already assigned the ressource for this zl380tw driver in your board init file, then undef this macro.
+*/
+#define ZL380TW_DEV_BIND_SLAVE_TO_MASTER
+#endif
+
+
+/*Define the ZL380TW interrupt pin drive mode 1:TTL, 0: Open Drain(default)*/
+#define HBI_CONFIG_INT_PIN_DRIVE_MODE 0
+/*-------------------------------------------------------------*
+ * HOST MACROS - end
+ *-------------------------------------------------------------*/
+
+
+/* local defines */
+#define MAX_TWOLF_ACCESS_SIZE_IN_BYTES 264 /*127 16-bit words*/
+#define MAX_TWOLF_FIRMWARE_SIZE_IN_BYTES 128 /*128 8-bit words*/
+
+/*The timberwolf device reset modes*/
+#define ZL38040_RST_HARDWARE_RAM 0
+#define ZL38040_RST_HARDWARE_ROM 1
+#define ZL38040_RST_SOFTWARE 2
+#define ZL38040_RST_AEC 3
+#define ZL38040_RST_TO_BOOT 4
+
+#ifdef ZL380XX_TW_ENABLE_CHAR_DEV_DRIVER
+
+#define NUMBER_OF_ZL380xx_DEVICES 1
+#define FIRST_MINOR 0
+/*structure for IOCL access*/
+typedef struct {
+ __u16 addr;
+ __u16 data;
+} ioctl_zl380tw;
+
+
+/* ioctl() calls that are permitted to the /dev/microsemi_spis_tw interface. */
+#define TWOLF_MAGIC 'q' /*Change this accordingly to your system*/
+#define TWOLF_HBI_RD16 _IOWR(TWOLF_MAGIC, 1, ioctl_zl380tw *)
+#define TWOLF_HBI_WR16 _IOW(TWOLF_MAGIC, 2, ioctl_zl380tw *)
+#define TWOLF_HBI_INIT _IOW(TWOLF_MAGIC, 3, __u16)
+#define TWOLF_RESET _IOW(TWOLF_MAGIC, 4, __u16)
+#define TWOLF_SAVE_FWR_TO_FLASH _IO(TWOLF_MAGIC, 5)
+#define TWOLF_LOAD_FWR_FROM_FLASH _IOW(TWOLF_MAGIC, 6, __u16)
+#define TWOLF_SAVE_CFG_TO_FLASH _IOW(TWOLF_MAGIC, 7, __u16)
+#define TWOLF_LOAD_CFG_FROM_FLASH _IOW(TWOLF_MAGIC, 8, __u16)
+#define TWOLF_ERASE_IMGCFG_FLASH _IOW(TWOLF_MAGIC, 9, __u16)
+#define TWOLF_ERASE_ALL_FLASH _IO(TWOLF_MAGIC, 10)
+#define TWOLF_STOP_FWR _IO(TWOLF_MAGIC, 11)
+#define TWOLF_START_FWR _IO(TWOLF_MAGIC, 12)
+#define TWOLF_LOAD_FWRCFG_FROM_FLASH _IOW(TWOLF_MAGIC, 13, __u16)
+#define TWOLF_HBI_WR_ARB_SINGLE_WORD _IOW(TWOLF_MAGIC, 14, __u16)
+#define TWOLF_HBI_RD_ARB_SINGLE_WORD _IOW(TWOLF_MAGIC, 15, __u16)
+#define TWOLF_CMD_PARAM_REG_ACCESS _IOW(TWOLF_MAGIC, 16, __u16)
+#define TWOLF_CMD_PARAM_RESULT_CHECK _IO(TWOLF_MAGIC, 17)
+#define TWOLF_BOOT_PREPARE _IO(TWOLF_MAGIC, 18)
+#define TWOLF_BOOT_SEND_MORE_DATA _IOW(TWOLF_MAGIC, 19, int)
+#define TWOLF_BOOT_CONCLUDE _IO(TWOLF_MAGIC, 20)
+#define TWOLF_LOAD_CFG _IOW(TWOLF_MAGIC, 21, int)
+#endif
+/*------------------------------------------------------*/
+/*TWOLF REGisters*/
+#define ZL38040_CMD_REG 0x0032 /*Host Command register*/
+#define ZL38040_CMD_IDLE 0x0000 /*idle/ operation complete*/
+#define ZL38040_CMD_NO_OP 0x0001 /*no-op*/
+#define ZL38040_CMD_IMG_CFG_LOAD 0x0002 /*load firmware and CR from flash*/
+#define ZL38040_CMD_IMG_LOAD 0x0003 /*load firmware only from flash*/
+#define ZL38040_CMD_IMG_CFG_SAVE 0x0004 /*save a firmware and CR to flash*/
+#define ZL38040_CMD_IMG_CFG_ERASE 0x0005 /*erase a firmware and CR in flash*/
+#define ZL38040_CMD_CFG_LOAD 0x0006 /*Load CR from flash*/
+#define ZL38040_CMD_CFG_SAVE 0x0007 /*save CR to flash*/
+#define ZL38040_CMD_FWR_GO 0x0008 /*start/restart firmware (GO)*/
+#define ZL38040_CMD_HOST_LOAD_CMP 0x000D /*Host Application Load Complete*/
+#define ZL38040_CMD_HOST_FLASH_INIT 0x000B /*Host Application flash discovery*/
+#define ZL38040_CMD_FWR_STOP 0x8000 /*stop firmware */
+#define ZL38040_CMD_CMD_IN_PROGRESS 0xFFFF /*wait command is in progress */
+#define ZL38040_CMD_APP_SLEEP 0x8005 /*codec low power mode*/
+
+#define PAGE_255_CHKSUM_LO_REG 0x000A
+#define PAGE_255_CHKSUM_HI_REG 0x0008
+#define CLK_STATUS_REG 0x0014 /*Clock status register*/
+#define PAGE_255_BASE_LO_REG 0x000E
+#define PAGE_255_BASE_HI_REG 0x000C
+#define ZL38040_SW_FLAGS_REG 0x0006
+#define ZL38040_SW_FLAGS_CMD 0x0001
+#define ZL38040_SW_FLAGS_CMD_NORST 0x0004
+
+#define ZL38040_DEVICE_ID_REG 0x0022
+
+#define TWOLF_CLK_STATUS_HBI_BOOT 0x0001
+
+#define HBI_CONFIG_REG 0xFD00
+#define HBI_CONFIG_WAKE 1<<7
+#define HBI_CONFIG_VAL (HBI_CONFIG_INT_PIN_DRIVE_MODE<<1)
+
+#define ZL38040_CMD_PARAM_RESULT_REG 0x0034 /*Host Command Param/Result register*/
+#define ZL38040_FWR_COUNT_REG 0x0026 /*Fwr on flash count register*/
+#define ZL38040_FWR_EXEC_REG 0x012C /*Fwr EXEC register*/
+
+#define TOTAL_FWR_DATA_WORD_PER_LINE 24
+#define TOTAL_FWR_DATA_BYTE_PER_LINE 128
+#define TWOLF_STATUS_NEED_MORE_DATA 22
+#define TWOLF_STATUS_BOOT_COMPLETE 23
+
+#define TWOLF_MBCMDREG_SPINWAIT 10000
+/*--------------------------------------------------------------------
+ * ALSA
+ *--------------------------------------------------------------------*/
+ /*Macros to enable one of the pre-defined audio cross-points*/
+#define ZL38040_CR2_DEFAULT 0
+#define ZL38040_CR2_STEREO_BYPASS 1
+#define ZL38040_ADDA_LOOPBACK 2
+
+/*Cached register range*/
+#define ZL38040_CACHED_ADDR_LO 0x202
+#define ZL38040_CACHED_ADDR_HI 0x23E
+#define ZL38040_HBI_OFFSET_RANGE 128
+#define ZL38040_CACHE_INDEX_TO_ADDR(index) (ZL38040_CACHED_ADDR_LO+(2*index))
+#define ZL38040_ADDR_TO_CACHE_INDEX(addr) ((addr - ZL38040_CACHED_ADDR_LO)/2)
+
+
+/*Page 1 registers*/
+#define ZL38040_OUTPUT_PATH_EN_REG 0x202
+#define ZL38040_DAC1_EN (1 << 0)
+#define ZL38040_DAC2_EN (1 << 1)
+#define ZL38040_TDMA1_EN (1 << 2)
+#define ZL38040_TDMA2_EN (1 << 3)
+#define ZL38040_TDMA3_EN (1 << 4)
+#define ZL38040_TDMA4_EN (1 << 5)
+#define ZL38040_TDMB1_EN (1 << 6)
+#define ZL38040_TDMB2_EN (1 << 7)
+#define ZL38040_TDMB3_EN (1 << 8)
+#define ZL38040_TDMB4_EN (1 << 9)
+#define ZL38040_MIC_SIN_EN (1 << 10)
+#define ZL38040_TDM_SOUT_EN (1 << 11)
+/*Cross-point Audio config registers*/
+#define ZL38040_DAC1_IN_PATH_REG 0x210
+#define ZL38040_DAC2_IN_PATH_REG 0x212
+#define ZL38040_TDM1L_IN_PATH_REG 0x214
+#define ZL38040_TDM1R_IN_PATH_REG 0x216
+#define ZL38040_TDMA3_IN_PATH_REG 0x218
+#define ZL38040_TDMA4_IN_PATH_REG 0x21A
+#define ZL38040_TDM2L_IN_PATH_REG 0x21C
+#define ZL38040_TDM2R_IN_PATH_REG 0x21E
+#define ZL38040_TDMB3_IN_PATH_REG 0x220
+#define ZL38040_TDMB4_IN_PATH_REG 0x222
+#define ZL38040_SIN_IN_PATH_REG 0x224
+#define ZL38040_RIN_IN_PATH_REG 0x226
+/*Cross-point Audio config values*/
+#define ZL38040_MIC1_PATH 0x01
+#define ZL38040_MIC2_PATH 0x02
+#define ZL38040_MIC3_PATH 0x03
+#define ZL38040_MIC4_PATH 0x04
+#define ZL38040_MIC_SELECT ZL38040_MIC1_PATH /*Change this accordingly*/
+#define ZL38040_TDMA1L_PATH 0x05
+#define ZL38040_TDMA1R_PATH 0x06
+#define ZL38040_TDMA3_PATH 0x07
+#define ZL38040_TDMA4_PATH 0x08
+#define ZL38040_TDMB2L_PATH 0x09
+#define ZL38040_TDMB2R_PATH 0x0A
+#define ZL38040_TDMB3_PATH 0x0B
+#define ZL38040_TDMB4_PATH 0x0C
+#define ZL38040_ROUT_PATH 0x0D
+#define ZL38040_SOUT_PATH 0x0E
+#define ZL38040_TGEN1_PATH 0x0F
+#define ZL38040_TGEN2_PATH 0x10
+
+#define ZL38040_TDMA_CFG_REG 0x260
+#define ZL38040_TDM_I2S_CFG_VAL 0x8000
+#define ZL38040_TDM_PCM_CFG_VAL 0x0000
+#define ZL38040_TDM_CLK_POL_VAL 0x0004
+#define ZL38040_TDMA_FSALIGN 0x01 /*left justified*/
+#define ZL38040_TDMA_CLK_CFG_REG 0x262
+#define ZL38040_TDM_TDM_MASTER_VAL (1<<15)
+#define ZL38040_TDMA_CH1_CFG_REG 0x268
+#define ZL38040_TDMA_CH2_CFG_REG 0x26A
+/*TDM - Channel configuration*/
+#define ZL38040_TDMA_16BIT_LIN (1<<8)
+#define ZL38040_TDMA_8BIT_ALAW (2<<8)
+#define ZL38040_TDMA_8BIT_ULAW (3<<8)
+#define ZL38040_TDMA_8BIT_G722 (4<<8)
+#define ZL38040_TDMA_16BIT_LINHFS (6<<8)
+
+#define ZL38040_TDMA_FSRATE_8KHZ (1)
+#define ZL38040_TDMA_FSRATE_16KHZ (2)
+#define ZL38040_TDMA_FSRATE_24KHZ (3)
+#define ZL38040_TDMA_FSRATE_44_1KHZ (5)
+#define ZL38040_TDMA_FSRATE_48KHZ (6)
+
+#define ZL38040_MIC_EN_REG 0x2B0
+#define ZL38040_MIC1_EN 0x01
+#define ZL38040_MIC2_EN 0x02
+#define ZL38040_MIC3_EN 0x04
+#define ZL38040_MIC4_EN 0x08
+
+#define ZL38040_LOW_POWER_REG 0x0206
+
+#define ZL38040_DAC1_EN_REG 0x02A0
+#define ZL38040_DAC2_EN_REG 0x02A2
+#define ZL38040_DACx_P_EN (1<<15)
+#define ZL38040_DACx_M_EN (1<<14)
+
+
+
+
+/*Page 2 registers*/
+#define ZL38040_USRGAIN 0x30A
+#define ZL38040_SYSGAIN 0x30C
+#define ZL38040_MICGAIN 0x2B2 /*Range 0-7 step +/-1 = 6dB each*/
+
+#define ZL38040_DAC_CTRL_REG 0x030A /*ROUT GAIN control*/
+#define ZL38040_DAC_VOL_MAX 0x78 /*Max volume control for Speaker +21dB*/
+#define ZL38040_DAC_VOL_MAX_EXT 0x82 /*Max volume control for Speaker +29dB*/
+#define ZL38040_DAC_VOL_MIN 0x00 /*Min volume control for Speaker -24dB*/
+#define ZL38040_DAC_VOL_STEP 0x01 /*volume step control for Speaker -/+0.375dB*/
+
+#define ZL38040_MIC_VOL_CTRL_REG 0x030C /*SIN GAIN control*/
+#define ZL38040_MIC_VOL_MAX 0x1F /*Max volume control for Speaker +22.5dB*/
+#define ZL38040_MIC_VOL_MIN 0x00 /*Min volume control for Speaker -24dB*/
+#define ZL38040_MIC_VOL_STEP 0x01 /*volume step control for Speaker -/+1.5dB*/
+#define ZL38040_SOUT_VOL_CTRL_REG 0x030C /*SOUT DIGITAL GAIN control*/
+#define ZL38040_SOUT_VOL_MAX 0x0F /*Max volume control for Speaker +21dB*/
+#define ZL38040_SOUT_VOL_MIN 0x00 /*Min volume control for Speaker -24dB*/
+#define ZL38040_SOUT_VOL_STEP 0x01 /*volume step control for Speaker -/+3.0dB*/
+
+#define ZL38040_DAC1_GAIN_REG 0x0238
+#define ZL38040_DAC2_GAIN_REG 0x023A
+#define ZL38040_I2S1L_GAIN_REG 0x023C
+#define ZL38040_I2S1R_GAIN_REG 0x023E
+#define ZL38040_I2S2L_GAIN_REG 0x0244
+#define ZL38040_I2S2R_GAIN_REG 0x0246
+#define ZL38040_TDMA3_GAIN_REG 0x0240
+#define ZL38040_TDMA4_GAIN_REG 0x0242
+#define ZL38040_TDMB3_GAIN_REG 0x0248
+#define ZL38040_TDMB4_GAIN_REG 0x024A
+
+
+
+#define ZL38040_AEC_CTRL_REG1 0x0302
+#define ZL38040_AEC_CTRL_REG0 0x0300
+#define ZL38040_EAC_RST_EN (1 << 0)
+#define ZL38040_MASTER_BYPASS_EN (1 << 1)
+#define ZL38040_EQ_RCV_DIS_EN (1 << 2)
+#define ZL38040_AEC_BYPASS_EN (1 << 4)
+#define ZL38040_AUD_ENH_BYPASS_EN (1 << 5)
+#define ZL38040_SPKR_LIN_EN (1 << 6)
+#define ZL38040_MUTE_ROUT_EN (1 << 7)
+#define ZL38040_MUTE_SOUT_EN (1 << 8)
+#define ZL38040_MUTE_ALL_EN (ZL38040_MUTE_ROUT_EN | ZL38040_MUTE_SOUT_EN)
+#define ZL38040_RIN_HPF_DIS_EN (1 << 9)
+#define ZL38040_SIN_HPF_DIS_EN (1 << 10)
+#define ZL38040_HOWLING_DIS_EN (1 << 11)
+#define ZL38040_AGC_DIS_EN (1 << 12)
+#define ZL38040_NB_DIS_EN (1 << 13)
+#define ZL38040_SATT_DIS_EN (1 << 14)
+#define ZL38040_HOWLING_MB_DIS_EN (1 << 15)
+#define ZL38040_HPF_DIS (ZL38040_RIN_HPF_DIS_EN | ZL38040_SIN_HPF_DIS_EN)
+
+#define ZL38040_LEC_CTRL_REG 0x037A
+
+#define ZL38040_AEC_HPF_NULL_REG 0x0310
+
+
+#endif /* __MICROSEMI_SPIS_TW_H */
+
diff --git a/sound/soc/codecs/zl380tw_config.c b/sound/soc/codecs/zl380tw_config.c
new file mode 100644
index 00000000..e1e070b3
--- /dev/null
+++ b/sound/soc/codecs/zl380tw_config.c
@@ -0,0 +1,1032 @@
+/*Source file ZLS38051_defaults.cr2, modified: Thu Oct 08 12:11:44 2015
+ */
+#include "zl380tw_config.h"
+
+const dataArr st_twConfig[] ={
+ {0x0200, {0x0000}},
+ {0x0202, {0x1C0F}},
+ {0x0204, {0x0010}},
+ {0x0206, {0x0016}},
+ {0x0208, {0x0001}},
+ {0x020A, {0x0000}},
+ {0x020C, {0x0000}},
+ {0x020E, {0x0000}},
+ {0x0210, {0x000D}},
+ {0x0212, {0x000E}},
+ {0x0214, {0x000E}},
+ {0x0216, {0x0000}},
+ {0x0218, {0x0000}},
+ {0x021A, {0x0000}},
+ {0x021C, {0x0000}},
+ {0x021E, {0x0000}},
+ {0x0220, {0x0000}},
+ {0x0222, {0x0000}},
+ {0x0224, {0x0002}},
+ {0x0226, {0x0005}},
+ {0x0228, {0x0004}},
+ {0x022A, {0x0000}},
+ {0x022C, {0x0000}},
+ {0x022E, {0x0000}},
+ {0x0230, {0x0000}},
+ {0x0232, {0x0000}},
+ {0x0234, {0x0000}},
+ {0x0236, {0x0000}},
+ {0x0238, {0x0000}},
+ {0x023A, {0x0000}},
+ {0x023C, {0x0000}},
+ {0x023E, {0x0000}},
+ {0x0240, {0x0000}},
+ {0x0242, {0x0000}},
+ {0x0244, {0x0000}},
+ {0x0246, {0x0000}},
+ {0x0248, {0x0000}},
+ {0x024A, {0x0000}},
+ {0x024C, {0x0000}},
+ {0x024E, {0x0000}},
+ {0x0250, {0x0000}},
+ {0x0252, {0x0000}},
+ {0x0254, {0x0000}},
+ {0x0256, {0x0000}},
+ {0x0258, {0x0000}},
+ {0x025A, {0x0000}},
+ {0x025C, {0x0000}},
+ {0x025E, {0x0000}},
+ {0x0260, {0x8004}},
+ {0x0262, {0x01F2}},
+ {0x0264, {0xC0C0}},
+ {0x0266, {0x0000}},
+ {0x0268, {0x0100}},
+ {0x026A, {0x0101}},
+ {0x026C, {0x0004}},
+ {0x026E, {0x0006}},
+ {0x0270, {0x0000}},
+ {0x0272, {0x0000}},
+ {0x0274, {0x0000}},
+ {0x0276, {0x0000}},
+ {0x0278, {0x0000}},
+ {0x027A, {0x0000}},
+ {0x027C, {0x4040}},
+ {0x027E, {0x0000}},
+ {0x0280, {0x0000}},
+ {0x0282, {0x0002}},
+ {0x0284, {0x0004}},
+ {0x0286, {0x0006}},
+ {0x0288, {0x0000}},
+ {0x028A, {0x0000}},
+ {0x028C, {0x0000}},
+ {0x028E, {0x0000}},
+ {0x0290, {0x0000}},
+ {0x0292, {0x0000}},
+ {0x0294, {0x0000}},
+ {0x0296, {0x0000}},
+ {0x0298, {0x0000}},
+ {0x029A, {0x0000}},
+ {0x029C, {0x0000}},
+ {0x029E, {0x0000}},
+ {0x02A0, {0xC000}},
+ {0x02A2, {0xC000}},
+ {0x02A4, {0x0000}},
+ {0x02A6, {0x0000}},
+ {0x02A8, {0x0000}},
+ {0x02AA, {0x0000}},
+ {0x02AC, {0x0000}},
+ {0x02AE, {0x0000}},
+ {0x02B0, {0x000E}},
+ {0x02B2, {0x0004}},
+ {0x02B4, {0x000C}},
+ {0x02B6, {0x0000}},
+ {0x02B8, {0x815E}},
+ {0x02BA, {0xFFF1}},
+ {0x02BC, {0x81E0}},
+ {0x02BE, {0xFFF1}},
+ {0x02C0, {0x03EC}},
+ {0x02C2, {0xFFF6}},
+ {0x02C4, {0x0000}},
+ {0x02C6, {0x0000}},
+ {0x02C8, {0x0000}},
+ {0x02CA, {0x0000}},
+ {0x02CC, {0x0000}},
+ {0x02CE, {0x0000}},
+ {0x02D0, {0x0000}},
+ {0x02D2, {0x0000}},
+ {0x02D4, {0x0000}},
+ {0x02D6, {0x0000}},
+ {0x02D8, {0x0000}},
+ {0x02DA, {0x0000}},
+ {0x02DC, {0x0000}},
+ {0x02DE, {0x0000}},
+ {0x02E0, {0x0000}},
+ {0x02E2, {0x0000}},
+ {0x02E4, {0x0000}},
+ {0x02E6, {0x0000}},
+ {0x02E8, {0x0000}},
+ {0x02EA, {0x0000}},
+ {0x02EC, {0x0000}},
+ {0x02EE, {0x0000}},
+ {0x02F0, {0x0000}},
+ {0x02F2, {0x0000}},
+ {0x02F4, {0x0000}},
+ {0x02F6, {0x0000}},
+ {0x02F8, {0x0000}},
+ {0x02FA, {0x0000}},
+ {0x02FC, {0x0000}},
+ {0x02FE, {0x0000}},
+ {0x0300, {0xDC04}},
+ {0x0302, {0x5820}},
+ {0x0304, {0x0000}},
+ {0x0306, {0x0000}},
+ {0x0308, {0x0000}},
+ {0x030A, {0x0040}},
+ {0x030C, {0x0810}},
+ {0x030E, {0xA000}},
+ {0x0310, {0x0093}},
+ {0x0312, {0x7FFF}},
+ {0x0314, {0x0000}},
+ {0x0316, {0x7FFF}},
+ {0x0318, {0x0000}},
+ {0x031A, {0x0000}},
+ {0x031C, {0x7FFF}},
+ {0x031E, {0x7FFF}},
+ {0x0320, {0x7FFF}},
+ {0x0322, {0x7FFF}},
+ {0x0324, {0x0400}},
+ {0x0326, {0x001F}},
+ {0x0328, {0x3040}},
+ {0x032A, {0x0080}},
+ {0x032C, {0x0006}},
+ {0x032E, {0x0A1F}},
+ {0x0330, {0x08A1}},
+ {0x0332, {0x003F}},
+ {0x0334, {0x0020}},
+ {0x0336, {0x0400}},
+ {0x0338, {0x4801}},
+ {0x033A, {0x0096}},
+ {0x033C, {0x0002}},
+ {0x033E, {0x0004}},
+ {0x0340, {0x0000}},
+ {0x0342, {0x0400}},
+ {0x0344, {0x0000}},
+ {0x0346, {0x0005}},
+ {0x0348, {0x0000}},
+ {0x034A, {0x0000}},
+ {0x034C, {0x0000}},
+ {0x034E, {0x0000}},
+ {0x0350, {0x0000}},
+ {0x0352, {0x0000}},
+ {0x0354, {0x1122}},
+ {0x0356, {0x3344}},
+ {0x0358, {0x0806}},
+ {0x035A, {0x0228}},
+ {0x035C, {0xA000}},
+ {0x035E, {0x0000}},
+ {0x0360, {0x0026}},
+ {0x0362, {0x0F10}},
+ {0x0364, {0x0A00}},
+ {0x0366, {0x4000}},
+ {0x0368, {0x0026}},
+ {0x036A, {0x1A00}},
+ {0x036C, {0x0800}},
+ {0x036E, {0x0400}},
+ {0x0370, {0x0320}},
+ {0x0372, {0x0000}},
+ {0x0374, {0x0B0B}},
+ {0x0376, {0x0000}},
+ {0x0378, {0x0000}},
+ {0x037A, {0x0010}},
+ {0x037C, {0x00AA}},
+ {0x037E, {0x2008}},
+ {0x0380, {0x0400}},
+ {0x0382, {0x0200}},
+ {0x0384, {0x7801}},
+ {0x0386, {0x0280}},
+ {0x0388, {0x0023}},
+ {0x038A, {0x003C}},
+ {0x038C, {0x2801}},
+ {0x038E, {0x08A1}},
+ {0x0390, {0x0000}},
+ {0x0392, {0xA000}},
+ {0x0394, {0x0000}},
+ {0x0396, {0x0000}},
+ {0x0398, {0x0000}},
+ {0x039A, {0x0000}},
+ {0x039C, {0x0000}},
+ {0x039E, {0x0000}},
+ {0x03A0, {0x0000}},
+ {0x03A2, {0x0080}},
+ {0x03A4, {0x0002}},
+ {0x03A6, {0x0064}},
+ {0x03A8, {0x000F}},
+ {0x03AA, {0x3333}},
+ {0x03AC, {0x7FBE}},
+ {0x03AE, {0x3333}},
+ {0x03B0, {0x7EB8}},
+ {0x03B2, {0x7FFF}},
+ {0x03B4, {0x0001}},
+ {0x03B6, {0x7FDF}},
+ {0x03B8, {0x0002}},
+ {0x03BA, {0x7333}},
+ {0x03BC, {0x7333}},
+ {0x03BE, {0x0031}},
+ {0x03C0, {0x0000}},
+ {0x03C2, {0x6666}},
+ {0x03C4, {0x0001}},
+ {0x03C6, {0x6666}},
+ {0x03C8, {0x7FFF}},
+ {0x03CA, {0x0100}},
+ {0x03CC, {0x0002}},
+ {0x03CE, {0x0000}},
+ {0x03D0, {0x0000}},
+ {0x03D2, {0x7213}},
+ {0x03D4, {0x0002}},
+ {0x03D6, {0x6000}},
+ {0x03D8, {0x0CCC}},
+ {0x03DA, {0x0000}},
+ {0x03DC, {0x0000}},
+ {0x03DE, {0x0000}},
+ {0x03E0, {0x0000}},
+ {0x03E2, {0x0000}},
+ {0x03E4, {0x0000}},
+ {0x03E6, {0x0002}},
+ {0x03E8, {0x01F0}},
+ {0x03EA, {0x0078}},
+ {0x03EC, {0x0032}},
+ {0x03EE, {0x0004}},
+ {0x03F0, {0x01F0}},
+ {0x03F2, {0x0078}},
+ {0x03F4, {0x0032}},
+ {0x03F6, {0x087A}},
+ {0x03F8, {0x0000}},
+ {0x03FA, {0x0000}},
+ {0x03FC, {0x0004}},
+ {0x03FE, {0x000E}},
+ {0x0400, {0x0714}},
+ {0x0402, {0x0320}},
+ {0x0404, {0x0033}},
+ {0x0406, {0x0000}},
+ {0x0408, {0x0B27}},
+ {0x040A, {0x1358}},
+ {0x040C, {0x0C52}},
+ {0x040E, {0x1560}},
+ {0x0410, {0x0DA2}},
+ {0x0412, {0x17A2}},
+ {0x0414, {0x0F0E}},
+ {0x0416, {0x1A21}},
+ {0x0418, {0x123D}},
+ {0x041A, {0x170A}},
+ {0x041C, {0x0000}},
+ {0x041E, {0x0000}},
+ {0x0420, {0x0000}},
+ {0x0422, {0x0000}},
+ {0x0424, {0x0000}},
+ {0x0426, {0x0000}},
+ {0x0428, {0x0190}},
+ {0x042A, {0x0190}},
+ {0x042C, {0x0000}},
+ {0x042E, {0x0000}},
+ {0x0430, {0x0000}},
+ {0x0432, {0x0000}},
+ {0x0434, {0x0000}},
+ {0x0436, {0x0000}},
+ {0x0438, {0x0000}},
+ {0x043A, {0x7FFF}},
+ {0x043C, {0x0001}},
+ {0x043E, {0x0000}},
+ {0x0440, {0x0000}},
+ {0x0442, {0x0000}},
+ {0x0444, {0x0000}},
+ {0x0446, {0x0000}},
+ {0x0448, {0x0000}},
+ {0x044A, {0x0000}},
+ {0x044C, {0x0000}},
+ {0x044E, {0x0000}},
+ {0x0450, {0x0000}},
+ {0x0452, {0x0000}},
+ {0x0454, {0x0000}},
+ {0x0456, {0x0000}},
+ {0x0458, {0x0000}},
+ {0x045A, {0x0000}},
+ {0x045C, {0x0000}},
+ {0x045E, {0x3000}},
+ {0x0460, {0x3FFF}},
+ {0x0462, {0x020C}},
+ {0x0464, {0x0000}},
+ {0x0466, {0x0000}},
+ {0x0468, {0x0000}},
+ {0x046A, {0x0000}},
+ {0x046C, {0x0000}},
+ {0x046E, {0x0000}},
+ {0x0470, {0x0000}},
+ {0x0472, {0x0000}},
+ {0x0474, {0x0000}},
+ {0x0476, {0x0000}},
+ {0x0478, {0x0000}},
+ {0x047A, {0x0000}},
+ {0x047C, {0x0000}},
+ {0x047E, {0x0000}},
+ {0x0480, {0x0000}},
+ {0x0482, {0x0000}},
+ {0x0484, {0x0000}},
+ {0x0486, {0x0000}},
+ {0x0488, {0x00C8}},
+ {0x048A, {0x000F}},
+ {0x048C, {0x0000}},
+ {0x048E, {0x02BC}},
+ {0x0490, {0x0000}},
+ {0x0492, {0x0514}},
+ {0x0494, {0x0064}},
+ {0x0496, {0x1999}},
+ {0x0498, {0x0CCC}},
+ {0x049A, {0x0005}},
+ {0x049C, {0x0005}},
+ {0x049E, {0x4026}},
+ {0x04A0, {0x5A67}},
+ {0x04A2, {0x4026}},
+ {0x04A4, {0x7FB2}},
+ {0x04A6, {0x0104}},
+ {0x04A8, {0x2026}},
+ {0x04AA, {0x0CCC}},
+ {0x04AC, {0x78D6}},
+ {0x04AE, {0x0D8F}},
+ {0x04B0, {0x0004}},
+ {0x04B2, {0x0000}},
+ {0x04B4, {0x0000}},
+ {0x04B6, {0x0000}},
+ {0x04B8, {0x0000}},
+ {0x04BA, {0x0000}},
+ {0x04BC, {0x0000}},
+ {0x04BE, {0x0000}},
+ {0x04C0, {0x0002}},
+ {0x04C2, {0x003C}},
+ {0x04C4, {0x005A}},
+ {0x04C6, {0x0014}},
+ {0x04C8, {0x0000}},
+ {0x04CA, {0x0000}},
+ {0x04CC, {0x0000}},
+ {0x04CE, {0x7333}},
+ {0x04D0, {0x0029}},
+ {0x04D2, {0x0200}},
+ {0x04D4, {0x0008}},
+ {0x04D6, {0x000C}},
+ {0x04D8, {0x0011}},
+ {0x04DA, {0x2666}},
+ {0x04DC, {0x0A81}},
+ {0x04DE, {0x0020}},
+ {0x04E0, {0x0005}},
+ {0x04E2, {0x0000}},
+ {0x04E4, {0x0002}},
+ {0x04E6, {0x0000}},
+ {0x04E8, {0x0000}},
+ {0x04EA, {0x0000}},
+ {0x04EC, {0x0000}},
+ {0x04EE, {0x0000}},
+ {0x04F0, {0x0000}},
+ {0x04F2, {0x0000}},
+ {0x04F4, {0x0000}},
+ {0x04F6, {0x0000}},
+ {0x04F8, {0x0000}},
+ {0x04FA, {0x0000}},
+ {0x04FC, {0x0000}},
+ {0x04FE, {0x0000}},
+ {0x0500, {0x0000}},
+ {0x0502, {0x0000}},
+ {0x0504, {0x0009}},
+ {0x0506, {0x03E8}},
+ {0x0508, {0x0200}},
+ {0x050A, {0x0000}},
+ {0x050C, {0x0009}},
+ {0x050E, {0x03E8}},
+ {0x0510, {0x0200}},
+ {0x0512, {0x0000}},
+ {0x0514, {0x0009}},
+ {0x0516, {0x03E8}},
+ {0x0518, {0x0200}},
+ {0x051A, {0x0000}},
+ {0x051C, {0x0009}},
+ {0x051E, {0x03E8}},
+ {0x0520, {0x0200}},
+ {0x0522, {0x0000}},
+ {0x0524, {0x0009}},
+ {0x0526, {0x03E8}},
+ {0x0528, {0x0200}},
+ {0x052A, {0x0000}},
+ {0x052C, {0x0009}},
+ {0x052E, {0x03E8}},
+ {0x0530, {0x0200}},
+ {0x0532, {0x0000}},
+ {0x0534, {0x0009}},
+ {0x0536, {0x03E8}},
+ {0x0538, {0x0200}},
+ {0x053A, {0x0000}},
+ {0x053C, {0x0009}},
+ {0x053E, {0x03E8}},
+ {0x0540, {0x0200}},
+ {0x0542, {0x0000}},
+ {0x0544, {0x0003}},
+ {0x0546, {0x0000}},
+ {0x0548, {0x0002}},
+ {0x054A, {0x00C8}},
+ {0x054C, {0x00C0}},
+ {0x054E, {0x0000}},
+ {0x0550, {0x0002}},
+ {0x0552, {0x00C8}},
+ {0x0554, {0x00C0}},
+ {0x0556, {0x0000}},
+ {0x0558, {0x0009}},
+ {0x055A, {0x03E8}},
+ {0x055C, {0x0200}},
+ {0x055E, {0x0000}},
+ {0x0560, {0x0009}},
+ {0x0562, {0x03E8}},
+ {0x0564, {0x0200}},
+ {0x0566, {0x0000}},
+ {0x0568, {0x0009}},
+ {0x056A, {0x03E8}},
+ {0x056C, {0x0200}},
+ {0x056E, {0x0000}},
+ {0x0570, {0x0009}},
+ {0x0572, {0x03E8}},
+ {0x0574, {0x0200}},
+ {0x0576, {0x0000}},
+ {0x0578, {0x0009}},
+ {0x057A, {0x03E8}},
+ {0x057C, {0x0200}},
+ {0x057E, {0x0000}},
+ {0x0580, {0x0009}},
+ {0x0582, {0x03E8}},
+ {0x0584, {0x0200}},
+ {0x0586, {0x0000}},
+ {0x0588, {0x0000}},
+ {0x058A, {0x0000}},
+ {0x058C, {0x0000}},
+ {0x058E, {0x0000}},
+ {0x0590, {0x0000}},
+ {0x0592, {0x0000}},
+ {0x0594, {0x0000}},
+ {0x0596, {0x0000}},
+ {0x0598, {0x0000}},
+ {0x059A, {0x0000}},
+ {0x059C, {0x0000}},
+ {0x059E, {0x0000}},
+ {0x05A0, {0x0000}},
+ {0x05A2, {0x0000}},
+ {0x05A4, {0x0000}},
+ {0x05A6, {0x0000}},
+ {0x05A8, {0x0000}},
+ {0x05AA, {0x0000}},
+ {0x05AC, {0x0000}},
+ {0x05AE, {0x0000}},
+ {0x05B0, {0x0000}},
+ {0x05B2, {0x0000}},
+ {0x05B4, {0x0000}},
+ {0x05B6, {0x0000}},
+ {0x05B8, {0x0000}},
+ {0x05BA, {0x0000}},
+ {0x05BC, {0x0000}},
+ {0x05BE, {0x0000}},
+ {0x05C0, {0x0000}},
+ {0x05C2, {0x0000}},
+ {0x05C4, {0x0000}},
+ {0x05C6, {0x0000}},
+ {0x05C8, {0x0000}},
+ {0x05CA, {0x0000}},
+ {0x05CC, {0x0000}},
+ {0x05CE, {0x0000}},
+ {0x05D0, {0x0000}},
+ {0x05D2, {0x0000}},
+ {0x05D4, {0x0000}},
+ {0x05D6, {0x0000}},
+ {0x05D8, {0x0000}},
+ {0x05DA, {0x0000}},
+ {0x05DC, {0x0000}},
+ {0x05DE, {0x0000}},
+ {0x05E0, {0x0000}},
+ {0x05E2, {0x0000}},
+ {0x05E4, {0x0000}},
+ {0x05E6, {0x0000}},
+ {0x05E8, {0x0000}},
+ {0x05EA, {0x0000}},
+ {0x05EC, {0x0000}},
+ {0x05EE, {0x0000}},
+ {0x05F0, {0x0000}},
+ {0x05F2, {0x0000}},
+ {0x05F4, {0x0000}},
+ {0x05F6, {0x0000}},
+ {0x05F8, {0x0000}},
+ {0x05FA, {0x0000}},
+ {0x05FC, {0x0000}},
+ {0x05FE, {0x0000}},
+ {0x0600, {0x3E80}},
+ {0x0602, {0x0000}},
+ {0x0604, {0x0400}},
+ {0x0606, {0x0000}},
+ {0x0608, {0xF700}},
+ {0x060A, {0x0100}},
+ {0x060C, {0x0002}},
+ {0x060E, {0x0200}},
+ {0x0610, {0xD300}},
+ {0x0612, {0x0080}},
+ {0x0614, {0x0066}},
+ {0x0616, {0x0133}},
+ {0x0618, {0xFE00}},
+ {0x061A, {0x0600}},
+ {0x061C, {0x0002}},
+ {0x061E, {0x0200}},
+ {0x0620, {0x3E80}},
+ {0x0622, {0x0010}},
+ {0x0624, {0x0000}},
+ {0x0626, {0x0000}},
+ {0x0628, {0xF700}},
+ {0x062A, {0x0100}},
+ {0x062C, {0x0002}},
+ {0x062E, {0x0200}},
+ {0x0630, {0xD300}},
+ {0x0632, {0x0080}},
+ {0x0634, {0x0066}},
+ {0x0636, {0x0133}},
+ {0x0638, {0xFE00}},
+ {0x063A, {0x0600}},
+ {0x063C, {0x0002}},
+ {0x063E, {0x0200}},
+ {0x0640, {0x3E80}},
+ {0x0642, {0x0002}},
+ {0x0644, {0x0600}},
+ {0x0646, {0x0000}},
+ {0x0648, {0xF700}},
+ {0x064A, {0x0100}},
+ {0x064C, {0x0002}},
+ {0x064E, {0x0200}},
+ {0x0650, {0xD300}},
+ {0x0652, {0x0080}},
+ {0x0654, {0x0066}},
+ {0x0656, {0x0133}},
+ {0x0658, {0xFE00}},
+ {0x065A, {0x0500}},
+ {0x065C, {0x0001}},
+ {0x065E, {0x0200}},
+ {0x0660, {0x0000}},
+ {0x0662, {0xEE80}},
+ {0x0664, {0x0000}},
+ {0x0666, {0x0000}},
+ {0x0668, {0x0000}},
+ {0x066A, {0x0000}},
+ {0x066C, {0x0000}},
+ {0x066E, {0x0000}},
+ {0x0670, {0x0000}},
+ {0x0672, {0xEE80}},
+ {0x0674, {0x0000}},
+ {0x0676, {0x0000}},
+ {0x0678, {0x0000}},
+ {0x067A, {0x0000}},
+ {0x067C, {0x0000}},
+ {0x067E, {0x0000}},
+ {0x0680, {0x0000}},
+ {0x0682, {0xEE80}},
+ {0x0684, {0x0000}},
+ {0x0686, {0x0000}},
+ {0x0688, {0x0000}},
+ {0x068A, {0x0000}},
+ {0x068C, {0x0000}},
+ {0x068E, {0x0000}},
+ {0x0690, {0x0000}},
+ {0x0692, {0x0000}},
+ {0x0694, {0x0000}},
+ {0x0696, {0x0000}},
+ {0x0698, {0x0000}},
+ {0x069A, {0x0000}},
+ {0x069C, {0x0000}},
+ {0x069E, {0x0000}},
+ {0x06A0, {0x0000}},
+ {0x06A2, {0x0000}},
+ {0x06A4, {0x0000}},
+ {0x06A6, {0x0000}},
+ {0x06A8, {0x0000}},
+ {0x06AA, {0x0000}},
+ {0x06AC, {0x0000}},
+ {0x06AE, {0x0000}},
+ {0x06B0, {0x0000}},
+ {0x06B2, {0x0000}},
+ {0x06B4, {0x0000}},
+ {0x06B6, {0x0000}},
+ {0x06B8, {0x0000}},
+ {0x06BA, {0x0000}},
+ {0x06BC, {0x0000}},
+ {0x06BE, {0x0000}},
+ {0x06C0, {0x0000}},
+ {0x06C2, {0x0000}},
+ {0x06C4, {0x0000}},
+ {0x06C6, {0x0000}},
+ {0x06C8, {0x0000}},
+ {0x06CA, {0x0000}},
+ {0x06CC, {0x0000}},
+ {0x06CE, {0x0000}},
+ {0x06D0, {0x0000}},
+ {0x06D2, {0x0000}},
+ {0x06D4, {0x0000}},
+ {0x06D6, {0x0000}},
+ {0x06D8, {0x0000}},
+ {0x06DA, {0x0000}},
+ {0x06DC, {0x0000}},
+ {0x06DE, {0x0000}},
+ {0x06E0, {0x0000}},
+ {0x06E2, {0x0000}},
+ {0x06E4, {0x0000}},
+ {0x06E6, {0x0000}},
+ {0x06E8, {0x0000}},
+ {0x06EA, {0x0000}},
+ {0x06EC, {0x0000}},
+ {0x06EE, {0x0000}},
+ {0x06F0, {0x0000}},
+ {0x06F2, {0x0000}},
+ {0x06F4, {0x0000}},
+ {0x06F6, {0x0000}},
+ {0x06F8, {0x0000}},
+ {0x06FA, {0x0000}},
+ {0x06FC, {0x0000}},
+ {0x06FE, {0x0000}},
+ {0x0700, {0x0000}},
+ {0x0702, {0x0000}},
+ {0x0704, {0x0000}},
+ {0x0706, {0x0000}},
+ {0x0708, {0x0000}},
+ {0x070A, {0x0000}},
+ {0x070C, {0x0000}},
+ {0x070E, {0x0000}},
+ {0x0710, {0x0000}},
+ {0x0712, {0x0000}},
+ {0x0714, {0x0000}},
+ {0x0716, {0x0000}},
+ {0x0718, {0x0000}},
+ {0x071A, {0x0000}},
+ {0x071C, {0x0000}},
+ {0x071E, {0x0000}},
+ {0x0720, {0x0000}},
+ {0x0722, {0x0000}},
+ {0x0724, {0x0000}},
+ {0x0726, {0x0000}},
+ {0x0728, {0x0000}},
+ {0x072A, {0x0000}},
+ {0x072C, {0x0000}},
+ {0x072E, {0x0000}},
+ {0x0730, {0x0000}},
+ {0x0732, {0x0000}},
+ {0x0734, {0x0000}},
+ {0x0736, {0x0000}},
+ {0x0738, {0x0000}},
+ {0x073A, {0x0000}},
+ {0x073C, {0x0000}},
+ {0x073E, {0x0000}},
+ {0x0740, {0x0000}},
+ {0x0742, {0x0000}},
+ {0x0744, {0x0000}},
+ {0x0746, {0x0000}},
+ {0x0748, {0x0000}},
+ {0x074A, {0x0000}},
+ {0x074C, {0x0000}},
+ {0x074E, {0x0000}},
+ {0x0750, {0x0000}},
+ {0x0752, {0x0000}},
+ {0x0754, {0x0000}},
+ {0x0756, {0x0000}},
+ {0x0758, {0x0000}},
+ {0x075A, {0x0000}},
+ {0x075C, {0x0000}},
+ {0x075E, {0x0000}},
+ {0x0760, {0x0000}},
+ {0x0762, {0x0000}},
+ {0x0764, {0x0000}},
+ {0x0766, {0x0000}},
+ {0x0768, {0x0000}},
+ {0x076A, {0x0000}},
+ {0x076C, {0x0000}},
+ {0x076E, {0x0000}},
+ {0x0770, {0x0000}},
+ {0x0772, {0x0000}},
+ {0x0774, {0x0000}},
+ {0x0776, {0x0000}},
+ {0x0778, {0x0000}},
+ {0x077A, {0x0000}},
+ {0x077C, {0x0000}},
+ {0x077E, {0x0000}},
+ {0x0780, {0x0000}},
+ {0x0782, {0x0000}},
+ {0x0784, {0x0000}},
+ {0x0786, {0x0000}},
+ {0x0788, {0x0000}},
+ {0x078A, {0x0000}},
+ {0x078C, {0x0000}},
+ {0x078E, {0x0000}},
+ {0x0790, {0x0000}},
+ {0x0792, {0x0000}},
+ {0x0794, {0x0000}},
+ {0x0796, {0x0000}},
+ {0x0798, {0x0000}},
+ {0x079A, {0x0000}},
+ {0x079C, {0x0000}},
+ {0x079E, {0x0000}},
+ {0x07A0, {0x0000}},
+ {0x07A2, {0x0000}},
+ {0x07A4, {0x0000}},
+ {0x07A6, {0x0000}},
+ {0x07A8, {0x0000}},
+ {0x07AA, {0x0000}},
+ {0x07AC, {0x0000}},
+ {0x07AE, {0x0000}},
+ {0x07B0, {0x0000}},
+ {0x07B2, {0x0000}},
+ {0x07B4, {0x0000}},
+ {0x07B6, {0x0000}},
+ {0x07B8, {0x0000}},
+ {0x07BA, {0x0000}},
+ {0x07BC, {0x0000}},
+ {0x07BE, {0x0000}},
+ {0x07C0, {0x0000}},
+ {0x07C2, {0x0000}},
+ {0x07C4, {0x0000}},
+ {0x07C6, {0x0000}},
+ {0x07C8, {0x0000}},
+ {0x07CA, {0x0000}},
+ {0x07CC, {0x0000}},
+ {0x07CE, {0x0000}},
+ {0x07D0, {0x0000}},
+ {0x07D2, {0x0000}},
+ {0x07D4, {0x0000}},
+ {0x07D6, {0x0000}},
+ {0x07D8, {0x0000}},
+ {0x07DA, {0x0000}},
+ {0x07DC, {0x0000}},
+ {0x07DE, {0x0000}},
+ {0x07E0, {0x0000}},
+ {0x07E2, {0x0000}},
+ {0x07E4, {0x0000}},
+ {0x07E6, {0x0000}},
+ {0x07E8, {0x0000}},
+ {0x07EA, {0x0000}},
+ {0x07EC, {0x0000}},
+ {0x07EE, {0x0000}},
+ {0x07F0, {0x0000}},
+ {0x07F2, {0x0000}},
+ {0x07F4, {0x0000}},
+ {0x07F6, {0x0000}},
+ {0x07F8, {0x0000}},
+ {0x07FA, {0x0000}},
+ {0x07FC, {0x0000}},
+ {0x07FE, {0x0000}},
+ {0x0800, {0x0000}},
+ {0x0802, {0x0000}},
+ {0x0804, {0x0000}},
+ {0x0806, {0x0000}},
+ {0x0808, {0x0000}},
+ {0x080A, {0x0000}},
+ {0x080C, {0x0000}},
+ {0x080E, {0x0000}},
+ {0x0810, {0x0000}},
+ {0x0812, {0x0000}},
+ {0x0814, {0x0000}},
+ {0x0816, {0x0000}},
+ {0x0818, {0x0000}},
+ {0x081A, {0x0000}},
+ {0x081C, {0x0000}},
+ {0x081E, {0x0000}},
+ {0x0820, {0x0000}},
+ {0x0822, {0x0000}},
+ {0x0824, {0x0000}},
+ {0x0826, {0x0000}},
+ {0x0828, {0x0000}},
+ {0x082A, {0x0000}},
+ {0x082C, {0x0000}},
+ {0x082E, {0x0000}},
+ {0x0830, {0x0000}},
+ {0x0832, {0x0000}},
+ {0x0834, {0x0000}},
+ {0x0836, {0x0000}},
+ {0x0838, {0x0000}},
+ {0x083A, {0x0000}},
+ {0x083C, {0x0000}},
+ {0x083E, {0x0000}},
+ {0x0840, {0x0000}},
+ {0x0842, {0x0000}},
+ {0x0844, {0x0000}},
+ {0x0846, {0x0000}},
+ {0x0848, {0x0000}},
+ {0x084A, {0x0000}},
+ {0x084C, {0x0000}},
+ {0x084E, {0x0000}},
+ {0x0850, {0x0000}},
+ {0x0852, {0x0000}},
+ {0x0854, {0x0000}},
+ {0x0856, {0x0000}},
+ {0x0858, {0x0000}},
+ {0x085A, {0x0000}},
+ {0x085C, {0x0000}},
+ {0x085E, {0x0000}},
+ {0x0860, {0x0000}},
+ {0x0862, {0x0000}},
+ {0x0864, {0x0000}},
+ {0x0866, {0x0000}},
+ {0x0868, {0x0000}},
+ {0x086A, {0x0000}},
+ {0x086C, {0x0000}},
+ {0x086E, {0x0000}},
+ {0x0870, {0x0000}},
+ {0x0872, {0x0000}},
+ {0x0874, {0x0000}},
+ {0x0876, {0x0000}},
+ {0x0878, {0x0000}},
+ {0x087A, {0x0000}},
+ {0x087C, {0x0000}},
+ {0x087E, {0x0000}},
+ {0x0880, {0x0000}},
+ {0x0882, {0x0000}},
+ {0x0884, {0x0000}},
+ {0x0886, {0x0000}},
+ {0x0888, {0x0000}},
+ {0x088A, {0x0000}},
+ {0x088C, {0x0000}},
+ {0x088E, {0x0000}},
+ {0x0890, {0x0000}},
+ {0x0892, {0x0000}},
+ {0x0894, {0x0000}},
+ {0x0896, {0x0000}},
+ {0x0898, {0x0000}},
+ {0x089A, {0x0000}},
+ {0x089C, {0x0000}},
+ {0x089E, {0x0000}},
+ {0x08A0, {0x0000}},
+ {0x08A2, {0x0000}},
+ {0x08A4, {0x0000}},
+ {0x08A6, {0x0000}},
+ {0x08A8, {0x0000}},
+ {0x08AA, {0x0000}},
+ {0x08AC, {0x0000}},
+ {0x08AE, {0x0000}},
+ {0x08B0, {0x0000}},
+ {0x08B2, {0x0000}},
+ {0x08B4, {0x0000}},
+ {0x08B6, {0x0000}},
+ {0x08B8, {0x0000}},
+ {0x08BA, {0x0000}},
+ {0x08BC, {0x0000}},
+ {0x08BE, {0x0000}},
+ {0x08C0, {0x0000}},
+ {0x08C2, {0x0000}},
+ {0x08C4, {0x0000}},
+ {0x08C6, {0x0000}},
+ {0x08C8, {0x0000}},
+ {0x08CA, {0x0000}},
+ {0x08CC, {0x0000}},
+ {0x08CE, {0x0000}},
+ {0x08D0, {0x0000}},
+ {0x08D2, {0x0000}},
+ {0x08D4, {0x0000}},
+ {0x08D6, {0x0000}},
+ {0x08D8, {0x0000}},
+ {0x08DA, {0x0000}},
+ {0x08DC, {0x0000}},
+ {0x08DE, {0x0000}},
+ {0x08E0, {0x0000}},
+ {0x08E2, {0x0000}},
+ {0x08E4, {0x0000}},
+ {0x08E6, {0x0000}},
+ {0x08E8, {0x0000}},
+ {0x08EA, {0x0000}},
+ {0x08EC, {0x0000}},
+ {0x08EE, {0x0000}},
+ {0x08F0, {0x0000}},
+ {0x08F2, {0x0000}},
+ {0x08F4, {0x0000}},
+ {0x08F6, {0x0000}},
+ {0x08F8, {0x0000}},
+ {0x08FA, {0x0000}},
+ {0x08FC, {0x0000}},
+ {0x08FE, {0x0000}},
+ {0x0900, {0x0000}},
+ {0x0902, {0x0000}},
+ {0x0904, {0x0000}},
+ {0x0906, {0x0000}},
+ {0x0908, {0x0000}},
+ {0x090A, {0x0000}},
+ {0x090C, {0x0000}},
+ {0x090E, {0x0000}},
+ {0x0910, {0x0000}},
+ {0x0912, {0x0000}},
+ {0x0914, {0x0000}},
+ {0x0916, {0x0000}},
+ {0x0918, {0x0000}},
+ {0x091A, {0x0000}},
+ {0x091C, {0x0000}},
+ {0x091E, {0x0000}},
+ {0x0920, {0x0000}},
+ {0x0922, {0x0000}},
+ {0x0924, {0x0000}},
+ {0x0926, {0x0000}},
+ {0x0928, {0x0000}},
+ {0x092A, {0x0000}},
+ {0x092C, {0x0000}},
+ {0x092E, {0x0000}},
+ {0x0930, {0x0000}},
+ {0x0932, {0x0000}},
+ {0x0934, {0x0000}},
+ {0x0936, {0x0000}},
+ {0x0938, {0x0000}},
+ {0x093A, {0x0000}},
+ {0x093C, {0x0000}},
+ {0x093E, {0x0000}},
+ {0x0940, {0x0000}},
+ {0x0942, {0x0000}},
+ {0x0944, {0x0000}},
+ {0x0946, {0x0000}},
+ {0x0948, {0x0000}},
+ {0x094A, {0x0000}},
+ {0x094C, {0x0000}},
+ {0x094E, {0x0000}},
+ {0x0950, {0x0000}},
+ {0x0952, {0x0000}},
+ {0x0954, {0x0000}},
+ {0x0956, {0x0000}},
+ {0x0958, {0x0000}},
+ {0x095A, {0x0000}},
+ {0x095C, {0x0000}},
+ {0x095E, {0x0000}},
+ {0x0960, {0x0000}},
+ {0x0962, {0x0000}},
+ {0x0964, {0x0000}},
+ {0x0966, {0x0000}},
+ {0x0968, {0x0000}},
+ {0x096A, {0x0000}},
+ {0x096C, {0x0000}},
+ {0x096E, {0x0000}},
+ {0x0970, {0x0000}},
+ {0x0972, {0x0000}},
+ {0x0974, {0x0000}},
+ {0x0976, {0x0000}},
+ {0x0978, {0x0000}},
+ {0x097A, {0x0000}},
+ {0x097C, {0x0000}},
+ {0x097E, {0x0000}},
+ {0x0980, {0x0000}},
+ {0x0982, {0x0000}},
+ {0x0984, {0x0000}},
+ {0x0986, {0x0000}},
+ {0x0988, {0x0000}},
+ {0x098A, {0x0000}},
+ {0x098C, {0x0000}},
+ {0x098E, {0x0000}},
+ {0x0990, {0x0000}},
+ {0x0992, {0x0000}},
+ {0x0994, {0x0000}},
+ {0x0996, {0x0000}},
+ {0x0998, {0x0000}},
+ {0x099A, {0x0000}},
+ {0x099C, {0x0000}},
+ {0x099E, {0x0000}},
+ {0x09A0, {0x0000}},
+ {0x09A2, {0x0000}},
+ {0x09A4, {0x0000}},
+ {0x09A6, {0x0000}},
+ {0x09A8, {0x0000}},
+ {0x09AA, {0x0000}},
+ {0x09AC, {0x0000}},
+ {0x09AE, {0x0000}},
+ {0x09B0, {0x0000}},
+ {0x09B2, {0x0000}},
+ {0x09B4, {0x0000}},
+ {0x09B6, {0x0000}},
+ {0x09B8, {0x0000}},
+ {0x09BA, {0x0000}},
+ {0x09BC, {0x0000}},
+ {0x09BE, {0x0000}},
+ {0x09C0, {0x0000}},
+ {0x09C2, {0x0000}},
+ {0x09C4, {0x0000}},
+ {0x09C6, {0x0000}},
+ {0x09C8, {0x0000}},
+ {0x09CA, {0x0000}},
+ {0x09CC, {0x0000}},
+ {0x09CE, {0x0000}},
+ {0x09D0, {0x0000}},
+ {0x09D2, {0x0000}},
+ {0x09D4, {0x0000}},
+ {0x09D6, {0x0000}},
+ {0x09D8, {0x0000}},
+ {0x09DA, {0x0000}},
+ {0x09DC, {0x0000}},
+ {0x09DE, {0x0000}},
+ {0x09E0, {0x0000}},
+ {0x09E2, {0x0000}},
+ {0x09E4, {0x0000}},
+ {0x09E6, {0x0000}},
+ {0x09E8, {0x0000}},
+ {0x09EA, {0x0000}},
+ {0x09EC, {0x0000}},
+ {0x09EE, {0x0000}},
+ {0x09F0, {0x0000}},
+ {0x09F2, {0x0000}},
+ {0x09F4, {0x0000}},
+ {0x09F6, {0x0000}},
+ {0x09F8, {0x0000}},
+ {0x09FA, {0x0000}},
+ {0x09FC, {0x0000}},
+ {0x09FE, {0x0000}},
+};
+const unsigned short zl_configBlockSize = 1;
+const unsigned short configStreamLen = 1024;
diff --git a/sound/soc/codecs/zl380tw_config.h b/sound/soc/codecs/zl380tw_config.h
new file mode 100644
index 00000000..c765c21e
--- /dev/null
+++ b/sound/soc/codecs/zl380tw_config.h
@@ -0,0 +1,13 @@
+#ifndef __ZL380TW_CONFIG_H_
+#define __ZL380TW_CONFIG_H_
+
+#define ZL380XX_CFG_BLOCK_SIZE 1
+typedef struct {
+ unsigned short reg; /*the register */
+ unsigned short value[ZL380XX_CFG_BLOCK_SIZE]; /*the value to write into reg */
+} dataArr;
+
+extern const unsigned short configStreamLen;
+extern const dataArr st_twConfig[];
+extern const unsigned short zl_configBlockSize;
+#endif
diff --git a/sound/soc/codecs/zl380tw_firmware.c b/sound/soc/codecs/zl380tw_firmware.c
new file mode 100644
index 00000000..17702e81
--- /dev/null
+++ b/sound/soc/codecs/zl380tw_firmware.c
@@ -0,0 +1,4715 @@
+/*Source file Microsemi_ZLS38051_P2.0.2_firmware.s3, modified: Thu Dec 08 16:32:27 2016
+ */
+#include "zl380tw_firmware.h"
+
+const twFwr st_twFirmware[] ={
+ {{0x0000, 0x1c0f, 0x0010, 0x0016, 0x0001, 0x0000, 0x0000, 0x0000, 0x000d, 0x000e, 0x000e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080200, 1},
+ {{0x0000, 0x0000, 0x0002, 0x0005, 0x0004, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080220, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080240, 1},
+ {{0x8004, 0x01f2, 0xc0c0, 0x0000, 0x0100, 0x0101, 0x0004, 0x0006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4040, 0x0000 }, 16, 0x00080260, 1},
+ {{0x0000, 0x0002, 0x0004, 0x0006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080280, 1},
+ {{0xc000, 0xc000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000e, 0x0004, 0x000c, 0x0000, 0x815e, 0xfff1, 0x81e0, 0xfff1 }, 16, 0x000802a0, 1},
+ {{0x03ec, 0xfff6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000802c0, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000802e0, 1},
+ {{0xdc04, 0x5820, 0x0000, 0x0000, 0x0000, 0x0040, 0x0810, 0xa000, 0x0093, 0x7fff, 0x0000, 0x7fff, 0x0000, 0x0000, 0x7fff, 0x7fff }, 16, 0x00080300, 1},
+ {{0x7fff, 0x7fff, 0x0400, 0x001f, 0x3040, 0x0080, 0x0006, 0x0a1f, 0x08a1, 0x003f, 0x0020, 0x0400, 0x4801, 0x0096, 0x0002, 0x0004 }, 16, 0x00080320, 1},
+ {{0x0000, 0x0400, 0x0000, 0x0005, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1122, 0x3344, 0x0806, 0x0228, 0xa000, 0x0000 }, 16, 0x00080340, 1},
+ {{0x0026, 0x0f10, 0x0a00, 0x4000, 0x0026, 0x1a00, 0x0800, 0x0400, 0x0320, 0x0000, 0x0b0b, 0x0000, 0x0000, 0x0010, 0x00aa, 0x2008 }, 16, 0x00080360, 1},
+ {{0x0400, 0x0200, 0x7801, 0x0280, 0x0023, 0x003c, 0x2801, 0x08a1, 0x0000, 0xa000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080380, 1},
+ {{0x0000, 0x0080, 0x0002, 0x0064, 0x000f, 0x3333, 0x7fbe, 0x3333, 0x7eb8, 0x7fff, 0x0001, 0x7fdf, 0x0002, 0x7333, 0x7333, 0x0031 }, 16, 0x000803a0, 1},
+ {{0x0000, 0x6666, 0x0001, 0x6666, 0x7fff, 0x0100, 0x0002, 0x0000, 0x0000, 0x7213, 0x0002, 0x6000, 0x0ccc, 0x0000, 0x0000, 0x0000 }, 16, 0x000803c0, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0002, 0x01f0, 0x0078, 0x0032, 0x0004, 0x01f0, 0x0078, 0x0032, 0x087a, 0x0000, 0x0000, 0x0004, 0x000e }, 16, 0x000803e0, 1},
+ {{0x0714, 0x0320, 0x0033, 0x0000, 0x0b27, 0x1358, 0x0c52, 0x1560, 0x0da2, 0x17a2, 0x0f0e, 0x1a21, 0x123d, 0x170a, 0x0000, 0x0000 }, 16, 0x00080400, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0190, 0x0190, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7fff, 0x0001, 0x0000 }, 16, 0x00080420, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3000 }, 16, 0x00080440, 1},
+ {{0x3fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080460, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080480, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000804a0, 1},
+ {{0x0002, 0x003c, 0x005a, 0x0014, 0x0000, 0x0000, 0x0000, 0x7333, 0x0129, 0x0004, 0x000c, 0x000a, 0x0011, 0x2666, 0x0a5a, 0x0030 }, 16, 0x000804c0, 1},
+ {{0x0005, 0x0000, 0x0002, 0x1000, 0x7fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000804e0, 1},
+ {{0x0000, 0x0000, 0x0009, 0x03e8, 0x0200, 0x0000, 0x0009, 0x03e8, 0x0200, 0x0000, 0x0009, 0x03e8, 0x0200, 0x0000, 0x0009, 0x03e8 }, 16, 0x00080500, 1},
+ {{0x0200, 0x0000, 0x0009, 0x03e8, 0x0200, 0x0000, 0x0009, 0x03e8, 0x0200, 0x0000, 0x0009, 0x03e8, 0x0200, 0x0000, 0x0009, 0x03e8 }, 16, 0x00080520, 1},
+ {{0x0200, 0x0000, 0x0003, 0x0000, 0x0002, 0x00c8, 0x00c0, 0x0000, 0x0002, 0x00c8, 0x00c0, 0x0000, 0x0009, 0x03e8, 0x0200, 0x0000 }, 16, 0x00080540, 1},
+ {{0x0009, 0x03e8, 0x0200, 0x0000, 0x0009, 0x03e8, 0x0200, 0x0000, 0x0009, 0x03e8, 0x0200, 0x0000, 0x0009, 0x03e8, 0x0200, 0x0000 }, 16, 0x00080560, 1},
+ {{0x0009, 0x03e8, 0x0200, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080580, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000805a0, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000805c0, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000805e0, 1},
+ {{0x3e80, 0x0000, 0x0400, 0x0000, 0xf700, 0x0100, 0x0002, 0x0200, 0xd300, 0x0080, 0x0066, 0x0133, 0xfe00, 0x0600, 0x0002, 0x0200 }, 16, 0x00080600, 1},
+ {{0x3e80, 0x0010, 0x0000, 0x0000, 0xf700, 0x0100, 0x0002, 0x0200, 0xd300, 0x0080, 0x0066, 0x0133, 0xfe00, 0x0600, 0x0002, 0x0200 }, 16, 0x00080620, 1},
+ {{0x3e80, 0x0002, 0x0600, 0x0000, 0xf700, 0x0100, 0x0002, 0x0200, 0xd300, 0x0080, 0x0066, 0x0133, 0xfe00, 0x0500, 0x0001, 0x0200 }, 16, 0x00080640, 1},
+ {{0x0000, 0xee80, 0x0000, 0x0000, 0x8000, 0x8000, 0x0000, 0x0000, 0x0000, 0xee80, 0x0000, 0x0000, 0x8000, 0x8000, 0x0000, 0x0000 }, 16, 0x00080660, 1},
+ {{0x0000, 0xee80, 0x0000, 0x0000, 0x8000, 0x8000, 0x0000, 0x0000, 0x0001, 0xffe2, 0x01f4, 0x0003, 0x0006, 0x00c8, 0x0000, 0x0000 }, 16, 0x00080680, 1},
+ {{0x07ff, 0x0c10, 0x0f08, 0x100a, 0x0508, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000806a0, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000806c0, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000806e0, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080700, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080720, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080740, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080760, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080780, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000807a0, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000807c0, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000807e0, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080800, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080820, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080840, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080860, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080880, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000808a0, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000808c0, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000808e0, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080900, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080920, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080940, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080960, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080980, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000809a0, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000809c0, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000809e0, 1},
+ {{0x0008, 0x5014, 0x0008, 0x50ec, 0x0008, 0x501c, 0x0000, 0x0018, 0x0000, 0x0000, 0x0008, 0xd090, 0x0008, 0x5104, 0x0000, 0x0010 }, 16, 0x00084000, 1},
+ {{0x0000, 0x0000, 0x0008, 0xd0d0, 0x0008, 0x5114, 0x0000, 0x0010, 0x0000, 0x0000, 0x0008, 0xd0f0, 0x0008, 0x5124, 0x0000, 0x0000 }, 16, 0x00084020, 1},
+ {{0x0000, 0x000c, 0x0008, 0xd10c, 0x0008, 0x5130, 0x0000, 0x0000, 0x0000, 0x0004, 0x0008, 0xd114, 0x0008, 0x5134, 0x0000, 0x0000 }, 16, 0x00084040, 1},
+ {{0x0000, 0x0004, 0x0008, 0xd8ac, 0x0008, 0x5138, 0x0000, 0x0002, 0x0000, 0x0000, 0x0008, 0xd8ae, 0x0008, 0x513a, 0x0000, 0x0002 }, 16, 0x00084060, 1},
+ {{0x0000, 0x0000, 0x0008, 0xd8b4, 0x0008, 0x513c, 0x0000, 0x0002, 0x0000, 0x0000, 0x0008, 0xd8b8, 0x0008, 0x513e, 0x0000, 0x0000 }, 16, 0x00084080, 1},
+ {{0x0000, 0x0001, 0x0008, 0xd8bb, 0x0008, 0x513f, 0x0000, 0x0000, 0x0000, 0x0001, 0x0008, 0xd8d0, 0x0008, 0x5180, 0x0000, 0x0004 }, 16, 0x000840a0, 1},
+ {{0x0000, 0x0000, 0x0008, 0xd8d4, 0x0008, 0x5184, 0x0000, 0x0000, 0x0000, 0x0001, 0x0008, 0xd8d5, 0x0008, 0x5185, 0x0000, 0x0000 }, 16, 0x000840c0, 1},
+ {{0x0000, 0x0001, 0x0008, 0xf038, 0x0008, 0x51b0, 0x0000, 0x000c, 0x0000, 0x0000, 0x0008, 0xf044, 0x0008, 0x51bc, 0x0000, 0x000c }, 16, 0x000840e0, 1},
+ {{0x0000, 0x0000, 0x0008, 0xf050, 0x0008, 0x51c8, 0x0000, 0x0000, 0x0000, 0x0004, 0x0008, 0xf054, 0x0008, 0x51cc, 0x0000, 0x0000 }, 16, 0x00084100, 1},
+ {{0x0000, 0x0004, 0x0008, 0xf058, 0x0008, 0x51d0, 0x0000, 0x0000, 0x0000, 0x0004, 0x0008, 0xf05c, 0x0008, 0x51d4, 0x0000, 0x0000 }, 16, 0x00084120, 1},
+ {{0x0000, 0x0004, 0x0008, 0xf060, 0x0008, 0x51d8, 0x0000, 0x0000, 0x0000, 0x0004, 0x0008, 0xf064, 0x0008, 0x51dc, 0x0000, 0x0000 }, 16, 0x00084140, 1},
+ {{0x0000, 0x0004, 0x0008, 0xf068, 0x0008, 0x51e0, 0x0000, 0x0002, 0x0000, 0x0000, 0x0008, 0xf06a, 0x0008, 0x51e2, 0x0000, 0x0002 }, 16, 0x00084160, 1},
+ {{0x0000, 0x0000, 0x0008, 0xf06c, 0x0008, 0x51e4, 0x0000, 0x0000, 0x0000, 0x0001, 0x0008, 0xf570, 0x0008, 0x55e8, 0x0000, 0x0018 }, 16, 0x00084180, 1},
+ {{0x0000, 0x0000, 0x0008, 0xf5b0, 0x0008, 0x5600, 0x0000, 0x000c, 0x0000, 0x0000, 0x0008, 0xf5bc, 0x0008, 0x560c, 0x0000, 0x0004 }, 16, 0x000841a0, 1},
+ {{0x0000, 0x0000, 0x0008, 0xf5c0, 0x0008, 0x5610, 0x0000, 0x0000, 0x0000, 0x0004, 0x0008, 0xf5c4, 0x0008, 0x5614, 0x0000, 0x0004 }, 16, 0x000841c0, 1},
+ {{0x0000, 0x0000, 0x0008, 0xf5c8, 0x0008, 0x5618, 0x0000, 0x0000, 0x0000, 0x0004, 0x0008, 0xf7cc, 0x0008, 0x561c, 0x0000, 0x0002 }, 16, 0x000841e0, 1},
+ {{0x0000, 0x0000, 0x0008, 0xf7ce, 0x0008, 0x561e, 0x0000, 0x0000, 0x0000, 0x0001, 0x0008, 0xf7cf, 0x0008, 0x561f, 0x0000, 0x0000 }, 16, 0x00084200, 1},
+ {{0x0000, 0x0001, 0x0008, 0xf7d0, 0x0008, 0x5620, 0x0000, 0x0000, 0x0000, 0x0001, 0x0009, 0x24e8, 0x0008, 0x5624, 0x0000, 0x0020 }, 16, 0x00084220, 1},
+ {{0x0000, 0x0000, 0x0009, 0x2508, 0x0008, 0x5644, 0x0000, 0x0020, 0x0000, 0x0000, 0x0009, 0x2528, 0x0008, 0x5664, 0x0000, 0x0010 }, 16, 0x00084240, 1},
+ {{0x0000, 0x0000, 0x0009, 0x2538, 0x0008, 0x5674, 0x0000, 0x0010, 0x0000, 0x0000, 0x0009, 0x2548, 0x0008, 0x5684, 0x0000, 0x0010 }, 16, 0x00084260, 1},
+ {{0x0000, 0x0000, 0x0009, 0x2558, 0x0008, 0x5694, 0x0000, 0x0010, 0x0000, 0x0000, 0x0009, 0x2778, 0x0008, 0x56a4, 0x0000, 0x00f0 }, 16, 0x00084280, 1},
+ {{0x0000, 0x0010, 0x0009, 0x2878, 0x0008, 0x57a4, 0x0000, 0x0018, 0x0000, 0x0000, 0x0009, 0x2890, 0x0008, 0x57bc, 0x0000, 0x0010 }, 16, 0x000842a0, 1},
+ {{0x0000, 0x0000, 0x0009, 0x28a0, 0x0008, 0x57cc, 0x0000, 0x0000, 0x0000, 0x0004, 0x0009, 0x28a8, 0x0008, 0x57d0, 0x0000, 0x0004 }, 16, 0x000842c0, 1},
+ {{0x0000, 0x0000, 0x0009, 0x28ac, 0x0008, 0x57d4, 0x0000, 0x0000, 0x0000, 0x0004, 0x0009, 0x28b0, 0x0008, 0x57d8, 0x0000, 0x0004 }, 16, 0x000842e0, 1},
+ {{0x0000, 0x0000, 0x0009, 0x28b4, 0x0008, 0x57dc, 0x0000, 0x0004, 0x0000, 0x0000, 0x0009, 0x28b8, 0x0008, 0x57e0, 0x0000, 0x0004 }, 16, 0x00084300, 1},
+ {{0x0000, 0x0000, 0x0009, 0x28c0, 0x0008, 0x57e4, 0x0000, 0x0000, 0x0000, 0x0004, 0x0009, 0x28c4, 0x0008, 0x57e8, 0x0000, 0x0000 }, 16, 0x00084320, 1},
+ {{0x0000, 0x0004, 0x0009, 0x2cd6, 0x0008, 0x57ec, 0x0000, 0x003d, 0x0000, 0x0001, 0x0009, 0x2d14, 0x0008, 0x582a, 0x0000, 0x0037 }, 16, 0x00084340, 1},
+ {{0x0000, 0x0001, 0x0009, 0x2d4c, 0x0008, 0x5862, 0x0000, 0x0037, 0x0000, 0x0001, 0x0009, 0x2d84, 0x0008, 0x589a, 0x0000, 0x0036 }, 16, 0x00084360, 1},
+ {{0x0000, 0x0001, 0x0009, 0x2dbb, 0x0008, 0x58d1, 0x0000, 0x0032, 0x0000, 0x0001, 0x0009, 0x2dee, 0x0008, 0x5904, 0x0000, 0x0032 }, 16, 0x00084380, 1},
+ {{0x0000, 0x0001, 0x0009, 0x2e21, 0x0008, 0x5937, 0x0000, 0x002f, 0x0000, 0x0001, 0x0009, 0x2e51, 0x0008, 0x5967, 0x0000, 0x002c }, 16, 0x000843a0, 1},
+ {{0x0000, 0x0001, 0x0009, 0x2e7e, 0x0008, 0x5994, 0x0000, 0x002b, 0x0000, 0x0001, 0x0009, 0x2eaa, 0x0008, 0x59c0, 0x0000, 0x002a }, 16, 0x000843c0, 1},
+ {{0x0000, 0x0001, 0x0009, 0x2ed5, 0x0008, 0x59eb, 0x0000, 0x0028, 0x0000, 0x0001, 0x0009, 0x2efe, 0x0008, 0x5a14, 0x0000, 0x0027 }, 16, 0x000843e0, 1},
+ {{0x0000, 0x0001, 0x0009, 0x2f26, 0x0008, 0x5a3c, 0x0000, 0x0026, 0x0000, 0x0001, 0x0009, 0x2f4d, 0x0008, 0x5a63, 0x0000, 0x0026 }, 16, 0x00084400, 1},
+ {{0x0000, 0x0001, 0x0009, 0x2f74, 0x0008, 0x5a8a, 0x0000, 0x0024, 0x0000, 0x0001, 0x0009, 0x2f99, 0x0008, 0x5aaf, 0x0000, 0x0023 }, 16, 0x00084420, 1},
+ {{0x0000, 0x0001, 0x0009, 0x2fbd, 0x0008, 0x5ad3, 0x0000, 0x0021, 0x0000, 0x0001, 0x0009, 0x2fdf, 0x0008, 0x5af5, 0x0000, 0x0020 }, 16, 0x00084440, 1},
+ {{0x0000, 0x0001, 0x0009, 0x3000, 0x0008, 0x5b16, 0x0000, 0x0020, 0x0000, 0x0001, 0x0009, 0x3021, 0x0008, 0x5b37, 0x0000, 0x0020 }, 16, 0x00084460, 1},
+ {{0x0000, 0x0001, 0x0009, 0x3042, 0x0008, 0x5b58, 0x0000, 0x001e, 0x0000, 0x0001, 0x0009, 0x3061, 0x0008, 0x5b77, 0x0000, 0x001e }, 16, 0x00084480, 1},
+ {{0x0000, 0x0001, 0x0009, 0x3080, 0x0008, 0x5b96, 0x0000, 0x001d, 0x0000, 0x0001, 0x0009, 0x309e, 0x0008, 0x5bb4, 0x0000, 0x001c }, 16, 0x000844a0, 1},
+ {{0x0000, 0x0001, 0x0009, 0x30bb, 0x0008, 0x5bd1, 0x0000, 0x001b, 0x0000, 0x0001, 0x0009, 0x30d7, 0x0008, 0x5bed, 0x0000, 0x001b }, 16, 0x000844c0, 1},
+ {{0x0000, 0x0001, 0x0009, 0x30f3, 0x0008, 0x5c09, 0x0000, 0x0019, 0x0000, 0x0001, 0x0009, 0x310d, 0x0008, 0x5c23, 0x0000, 0x0017 }, 16, 0x000844e0, 1},
+ {{0x0000, 0x0001, 0x0009, 0x3125, 0x0008, 0x5c3b, 0x0000, 0x0017, 0x0000, 0x0001, 0x0009, 0x313d, 0x0008, 0x5c53, 0x0000, 0x0016 }, 16, 0x00084500, 1},
+ {{0x0000, 0x0001, 0x0009, 0x3154, 0x0008, 0x5c6a, 0x0000, 0x0016, 0x0000, 0x0001, 0x0009, 0x316b, 0x0008, 0x5c81, 0x0000, 0x0016 }, 16, 0x00084520, 1},
+ {{0x0000, 0x0001, 0x0009, 0x3182, 0x0008, 0x5c98, 0x0000, 0x0016, 0x0000, 0x0001, 0x0009, 0x3199, 0x0008, 0x5caf, 0x0000, 0x0015 }, 16, 0x00084540, 1},
+ {{0x0000, 0x0001, 0x0009, 0x31af, 0x0008, 0x5cc5, 0x0000, 0x0015, 0x0000, 0x0001, 0x0009, 0x31c5, 0x0008, 0x5cdb, 0x0000, 0x0015 }, 16, 0x00084560, 1},
+ {{0x0000, 0x0001, 0x0009, 0x31db, 0x0008, 0x5cf1, 0x0000, 0x0015, 0x0000, 0x0001, 0x0009, 0x31f1, 0x0008, 0x5d07, 0x0000, 0x0014 }, 16, 0x00084580, 1},
+ {{0x0000, 0x0001, 0x0009, 0x3206, 0x0008, 0x5d1c, 0x0000, 0x000f, 0x0000, 0x0001, 0x0009, 0x3216, 0x0008, 0x5d2c, 0x0000, 0x000d }, 16, 0x000845a0, 1},
+ {{0x0000, 0x0001, 0x0009, 0x3224, 0x0008, 0x5d3a, 0x0000, 0x000b, 0x0000, 0x0001, 0x0009, 0x3230, 0x0008, 0x5d46, 0x0000, 0x0008 }, 16, 0x000845c0, 1},
+ {{0x0000, 0x0001, 0x0009, 0x3239, 0x0008, 0x5d4f, 0x0000, 0x0007, 0x0000, 0x0001, 0x0009, 0x3241, 0x0008, 0x5d57, 0x0000, 0x0007 }, 16, 0x000845e0, 1},
+ {{0x0000, 0x0001, 0x0009, 0x3249, 0x0008, 0x5d5f, 0x0000, 0x0007, 0x0000, 0x0001, 0x0009, 0x3251, 0x0008, 0x5d67, 0x0000, 0x0006 }, 16, 0x00084600, 1},
+ {{0x0000, 0x0001, 0x0009, 0x3258, 0x0008, 0x5d6e, 0x0000, 0x0006, 0x0000, 0x0001, 0x0009, 0x325f, 0x0008, 0x5d75, 0x0000, 0x0005 }, 16, 0x00084620, 1},
+ {{0x0000, 0x0001, 0x0009, 0x3265, 0x0008, 0x5d7b, 0x0000, 0x0004, 0x0000, 0x0001, 0x0009, 0x326a, 0x0008, 0x5d80, 0x0000, 0x0004 }, 16, 0x00084640, 1},
+ {{0x0000, 0x0001, 0x0009, 0x326f, 0x0008, 0x5d85, 0x0000, 0x0004, 0x0000, 0x0001, 0x0009, 0x3274, 0x0008, 0x5d8a, 0x0000, 0x0004 }, 16, 0x00084660, 1},
+ {{0x0000, 0x0001, 0x0009, 0x3279, 0x0008, 0x5d8f, 0x0000, 0x0003, 0x0000, 0x0001, 0x0009, 0x3281, 0x0008, 0x5d93, 0x0000, 0x0003 }, 16, 0x00084680, 1},
+ {{0x0000, 0x0001, 0x0009, 0x3285, 0x0008, 0x5d97, 0x0000, 0x0003, 0x0000, 0x0001, 0x0009, 0x3289, 0x0008, 0x5d9b, 0x0000, 0x0003 }, 16, 0x000846a0, 1},
+ {{0x0000, 0x0001, 0x0009, 0x328d, 0x0008, 0x5d9f, 0x0000, 0x0002, 0x0000, 0x0001, 0x0009, 0x3290, 0x0008, 0x5da2, 0x0000, 0x0002 }, 16, 0x000846c0, 1},
+ {{0x0000, 0x0001, 0x0009, 0x3293, 0x0008, 0x5da5, 0x0000, 0x0002, 0x0000, 0x0001, 0x0009, 0x3296, 0x0008, 0x5da8, 0x0000, 0x0002 }, 16, 0x000846e0, 1},
+ {{0x0000, 0x0001, 0x0009, 0x3299, 0x0008, 0x5dab, 0x0000, 0x0002, 0x0000, 0x0001, 0x0009, 0x329c, 0x0008, 0x5dae, 0x0000, 0x0002 }, 16, 0x00084700, 1},
+ {{0x0000, 0x0001, 0x0009, 0x329f, 0x0008, 0x5db1, 0x0000, 0x0002, 0x0000, 0x0001, 0x0009, 0x32a2, 0x0008, 0x5db4, 0x0000, 0x0002 }, 16, 0x00084720, 1},
+ {{0x0000, 0x0001, 0x0009, 0x32a5, 0x0008, 0x5db7, 0x0000, 0x0001, 0x0000, 0x0001, 0x0009, 0x32a7, 0x0008, 0x5db9, 0x0000, 0x0000 }, 16, 0x00084740, 1},
+ {{0x0000, 0x0001, 0x0009, 0x32a8, 0x0008, 0x5dba, 0x0000, 0x0000, 0x0000, 0x0001, 0x0009, 0x32a9, 0x0008, 0x5dbb, 0x0000, 0x0000 }, 16, 0x00084760, 1},
+ {{0x0000, 0x0001, 0x0009, 0x32aa, 0x0008, 0x5dbc, 0x0000, 0x0000, 0x0000, 0x0001, 0x0009, 0x32ab, 0x0008, 0x5dbd, 0x0000, 0x0000 }, 16, 0x00084780, 1},
+ {{0x0000, 0x0001, 0x0009, 0x32ac, 0x0008, 0x5dbe, 0x0000, 0x0001, 0x0000, 0x0000, 0x0009, 0x32fc, 0x0008, 0x6094, 0x0000, 0x000c }, 16, 0x000847a0, 1},
+ {{0x0000, 0x0000, 0x0009, 0x3308, 0x0008, 0x60a0, 0x0000, 0x0000, 0x0000, 0x0004, 0x0009, 0x3314, 0x0008, 0x60a4, 0x0000, 0x0000 }, 16, 0x000847c0, 1},
+ {{0x0000, 0x0004, 0x0009, 0x3320, 0x0008, 0x60a8, 0x0000, 0x0004, 0x0000, 0x0000, 0x0009, 0x3334, 0x0008, 0x60ac, 0x0000, 0x0004 }, 16, 0x000847e0, 1},
+ {{0x0000, 0x0000, 0x0009, 0x333c, 0x0008, 0x60b0, 0x0000, 0x0000, 0x0000, 0x0004, 0x0009, 0x3340, 0x0008, 0x60b4, 0x0000, 0x0000 }, 16, 0x00084800, 1},
+ {{0x0000, 0x0004, 0x0009, 0x3344, 0x0008, 0x60b8, 0x0000, 0x0000, 0x0000, 0x0004, 0x0009, 0x334c, 0x0008, 0x60bc, 0x0000, 0x0000 }, 16, 0x00084820, 1},
+ {{0x0000, 0x0004, 0x0009, 0x3350, 0x0008, 0x60c0, 0x0000, 0x0000, 0x0000, 0x0004, 0x0009, 0x3358, 0x0008, 0x60c4, 0x0000, 0x0000 }, 16, 0x00084840, 1},
+ {{0x0000, 0x0004, 0x0009, 0x335c, 0x0008, 0x60c8, 0x0000, 0x0000, 0x0000, 0x0004, 0x0009, 0x3360, 0x0008, 0x60cc, 0x0000, 0x0000 }, 16, 0x00084860, 1},
+ {{0x0000, 0x0004, 0x0009, 0x3364, 0x0008, 0x60d0, 0x0000, 0x0002, 0x0000, 0x0000, 0x0009, 0x3366, 0x0008, 0x60d2, 0x0000, 0x0002 }, 16, 0x00084880, 1},
+ {{0x0000, 0x0000, 0x0009, 0x3369, 0x0008, 0x60d5, 0x0000, 0x0000, 0x0000, 0x0001, 0x0009, 0x336a, 0x0008, 0x60d6, 0x0000, 0x0001 }, 16, 0x000848a0, 1},
+ {{0x0000, 0x0000, 0x0009, 0x336c, 0x0008, 0x60d8, 0x0000, 0x0048, 0x0000, 0x0000, 0x0009, 0x33b4, 0x0008, 0x6120, 0x0000, 0x0000 }, 16, 0x000848c0, 1},
+ {{0x0000, 0x00c0, 0x0009, 0x3474, 0x0008, 0x61e0, 0x0000, 0x0000, 0x0000, 0x00c0, 0x0009, 0x3534, 0x0008, 0x69e8, 0x0000, 0x0000 }, 16, 0x000848e0, 1},
+ {{0x0000, 0x0004, 0x0009, 0x3538, 0x0008, 0x69ec, 0x0000, 0x0008, 0x0000, 0x0000, 0x0009, 0x3540, 0x0008, 0x69f4, 0x0000, 0x0002 }, 16, 0x00084900, 1},
+ {{0x0000, 0x0000, 0x0009, 0x3544, 0x0008, 0x69f8, 0x0000, 0x0010, 0x0000, 0x0000, 0x0009, 0x3590, 0x0008, 0x6a08, 0x0000, 0x000c }, 16, 0x00084920, 1},
+ {{0x0000, 0x0000, 0x0009, 0x359c, 0x0008, 0x6a14, 0x0000, 0x000a, 0x0000, 0x0002, 0x0009, 0x35a8, 0x0008, 0x6a20, 0x0000, 0x0003 }, 16, 0x00084940, 1},
+ {{0x0000, 0x0000, 0x0009, 0x35ab, 0x0008, 0x6a23, 0x0000, 0x0003, 0x0000, 0x0000, 0x0009, 0x3690, 0x0008, 0x6a28, 0x0000, 0x0000 }, 16, 0x00084960, 1},
+ {{0x0000, 0x0004, 0x0009, 0x37c4, 0x0008, 0x6a2c, 0x0000, 0x0000, 0x0000, 0x0004, 0x0009, 0x37d4, 0x0008, 0x6a50, 0x0000, 0x0058 }, 16, 0x00084980, 1},
+ {{0x0000, 0x0000, 0x0009, 0x382c, 0x0008, 0x6aa8, 0x0000, 0x0010, 0x0000, 0x0000, 0x0009, 0x3c48, 0x0008, 0x6ac4, 0x0000, 0x0014 }, 16, 0x000849a0, 1},
+ {{0x0000, 0x0000, 0x0009, 0x3c5c, 0x0008, 0x6ad8, 0x0000, 0x000c, 0x0000, 0x0000, 0x0009, 0x3c68, 0x0008, 0x6ae4, 0x0000, 0x0000 }, 16, 0x000849c0, 1},
+ {{0x0000, 0x0004, 0x0009, 0x3c6c, 0x0008, 0x6ce8, 0x0000, 0x0000, 0x0000, 0x0001, 0x0009, 0x3c70, 0x0008, 0x6cec, 0x0000, 0x0000 }, 16, 0x000849e0, 1},
+ {{0x0000, 0x0004, 0x0009, 0x4e74, 0x0008, 0x6cf0, 0x0000, 0x0004, 0x0000, 0x0000, 0x0009, 0x4e80, 0x0008, 0x6cf4, 0x0000, 0x002c }, 16, 0x00084a00, 1},
+ {{0x0000, 0x0000, 0x0009, 0x4eac, 0x0008, 0x6d78, 0x0000, 0x0000, 0x0000, 0x0002, 0x0009, 0x82d0, 0x0008, 0x6d7c, 0x0000, 0x0004 }, 16, 0x00084a20, 1},
+ {{0x0000, 0x0000, 0x0009, 0x82d4, 0x0008, 0x6d80, 0x0000, 0x0004, 0x0000, 0x0000, 0x0009, 0x82d8, 0x0008, 0x6d84, 0x0000, 0x0004 }, 16, 0x00084a40, 1},
+ {{0x0000, 0x0000, 0x0009, 0x82dc, 0x0008, 0x6d88, 0x0000, 0x0004, 0x0000, 0x0000, 0x0009, 0x8ca0, 0x0008, 0x6d8c, 0x0000, 0x0000 }, 16, 0x00084a60, 1},
+ {{0x0000, 0x0002, 0x0009, 0x8ca2, 0x0008, 0x6d90, 0x0000, 0x0000, 0x0000, 0x0002, 0x0009, 0xb3b8, 0x0008, 0x6d94, 0x0000, 0x0000 }, 16, 0x00084a80, 1},
+ {{0x0000, 0x0004, 0x0009, 0xb3bc, 0x0008, 0x6d98, 0x0000, 0x0002, 0x0000, 0x0000, 0x0009, 0xb3be, 0x0008, 0x6d9a, 0x0000, 0x0002 }, 16, 0x00084aa0, 1},
+ {{0x0000, 0x0000, 0x0009, 0xb3c0, 0x0008, 0x6d9c, 0x0000, 0x0002, 0x0000, 0x0000, 0x0009, 0xbbc8, 0x0008, 0x6da0, 0x0000, 0x0538 }, 16, 0x00084ac0, 1},
+ {{0x0000, 0x0000, 0x0009, 0xc100, 0x0008, 0x72d8, 0x0000, 0x0004, 0x0000, 0x0000, 0x0009, 0xc2bc, 0x0008, 0x72fc, 0x0000, 0x0004 }, 16, 0x00084ae0, 1},
+ {{0x0000, 0x0000, 0x0009, 0xc2c0, 0x0008, 0x7300, 0x0000, 0x0004, 0x0000, 0x0000, 0x0009, 0xc2c4, 0x0008, 0x7304, 0x0000, 0x0004 }, 16, 0x00084b00, 1},
+ {{0x0000, 0x0000, 0x0009, 0xc2c8, 0x0008, 0x7308, 0x0000, 0x0004, 0x0000, 0x0000, 0x0009, 0xc2cc, 0x0008, 0x730c, 0x0000, 0x0002 }, 16, 0x00084b20, 1},
+ {{0x0000, 0x0000, 0x0009, 0xc30c, 0x0008, 0x7310, 0x0000, 0x000c, 0x0000, 0x0000, 0x0009, 0xc31c, 0x0008, 0x731c, 0x0000, 0x0000 }, 16, 0x00084b40, 1},
+ {{0x0000, 0x0001, 0x0009, 0xc31d, 0x0008, 0x731d, 0x0000, 0x0000, 0x0000, 0x0001, 0x0009, 0xc31e, 0x0008, 0x731e, 0x0000, 0x0000 }, 16, 0x00084b60, 1},
+ {{0x0000, 0x0001, 0x0009, 0xc360, 0x0008, 0x7320, 0x0000, 0x0000, 0x0000, 0x0004, 0x0009, 0xc364, 0x0008, 0x7324, 0x0000, 0x0000 }, 16, 0x00084b80, 1},
+ {{0x0000, 0x0004, 0x0009, 0xc368, 0x0008, 0x7328, 0x0000, 0x0000, 0x0000, 0x0004, 0x0009, 0xc36c, 0x0008, 0x732c, 0x0000, 0x0000 }, 16, 0x00084ba0, 1},
+ {{0x0000, 0x0004, 0x0009, 0xc372, 0x0008, 0x7330, 0x0000, 0x0000, 0x0000, 0x0002, 0x0009, 0xc390, 0x0008, 0x7334, 0x0000, 0x0030 }, 16, 0x00084bc0, 1},
+ {{0x0000, 0x0000, 0x0009, 0xc3c0, 0x0008, 0x7364, 0x0000, 0x0010, 0x0000, 0x0000, 0x0009, 0xc3d0, 0x0008, 0x7374, 0x0000, 0x02c2 }, 16, 0x00084be0, 1},
+ {{0x0000, 0x0000, 0x0009, 0xc692, 0x0008, 0x7636, 0x0000, 0x007e, 0x0000, 0x0002, 0x0009, 0xc712, 0x0008, 0x76b6, 0x0000, 0x0080 }, 16, 0x00084c00, 1},
+ {{0x0000, 0x0000, 0x0009, 0xc792, 0x0008, 0x7736, 0x0000, 0x0080, 0x0000, 0x0000, 0x0009, 0xc812, 0x0008, 0x77b6, 0x0000, 0x0040 }, 16, 0x00084c20, 1},
+ {{0x0000, 0x0000, 0x0009, 0xc852, 0x0008, 0x77f6, 0x0000, 0x0040, 0x0000, 0x0000, 0x0009, 0xc892, 0x0008, 0x7836, 0x0000, 0x003e }, 16, 0x00084c40, 1},
+ {{0x0000, 0x0000, 0x0009, 0xc8d0, 0x0008, 0x7874, 0x0000, 0x003e, 0x0000, 0x0000, 0x0009, 0xc90e, 0x0008, 0x78b2, 0x0000, 0x0010 }, 16, 0x00084c60, 1},
+ {{0x0000, 0x0010, 0x0009, 0xc92e, 0x0008, 0x78d2, 0x0000, 0x001e, 0x0000, 0x0002, 0x0009, 0xc94e, 0x0008, 0x78f2, 0x0000, 0x0020 }, 16, 0x00084c80, 1},
+ {{0x0000, 0x0000, 0x0009, 0xc96e, 0x0008, 0x7912, 0x0000, 0x001e, 0x0000, 0x0002, 0x0009, 0xc98e, 0x0008, 0x7932, 0x0000, 0x001e }, 16, 0x00084ca0, 1},
+ {{0x0000, 0x0002, 0x0009, 0xc9ae, 0x0008, 0x7952, 0x0000, 0x0010, 0x0000, 0x0010, 0x0009, 0xc9ce, 0x0008, 0x7972, 0x0000, 0x0010 }, 16, 0x00084cc0, 1},
+ {{0x0000, 0x0000, 0x0009, 0xc9de, 0x0008, 0x7982, 0x0000, 0x0010, 0x0000, 0x0000, 0x0009, 0xc9ee, 0x0008, 0x7992, 0x0000, 0x0010 }, 16, 0x00084ce0, 1},
+ {{0x0000, 0x0000, 0x0009, 0xc9fe, 0x0008, 0x79a2, 0x0000, 0x000c, 0x0000, 0x0000, 0x0009, 0xca0a, 0x0008, 0x79ae, 0x0000, 0x0008 }, 16, 0x00084d00, 1},
+ {{0x0000, 0x0000, 0x0009, 0xca12, 0x0008, 0x79b6, 0x0000, 0x0004, 0x0000, 0x0004, 0x0009, 0xca1a, 0x0008, 0x79be, 0x0000, 0x0008 }, 16, 0x00084d20, 1},
+ {{0x0000, 0x0000, 0x0009, 0xca22, 0x0008, 0x79c6, 0x0000, 0x0006, 0x0000, 0x0000, 0x0009, 0xca28, 0x0008, 0x79cc, 0x0000, 0x0006 }, 16, 0x00084d40, 1},
+ {{0x0000, 0x0000, 0x0009, 0xca30, 0x0008, 0x79d4, 0x0000, 0x000c, 0x0000, 0x0000, 0x0009, 0xca3c, 0x0008, 0x79e0, 0x0000, 0x0000 }, 16, 0x00084d60, 1},
+ {{0x0000, 0x0004, 0x0009, 0xca40, 0x0008, 0x79e4, 0x0000, 0x0000, 0x0000, 0x0002, 0x0009, 0xca44, 0x0008, 0x79e8, 0x0000, 0x0044 }, 16, 0x00084d80, 1},
+ {{0x0000, 0x0000, 0x0009, 0xca88, 0x0008, 0x7a2c, 0x0000, 0x0030, 0x0000, 0x0000, 0x0009, 0xcabc, 0x0008, 0x7a5c, 0x0000, 0x0000 }, 16, 0x00084da0, 1},
+ {{0x0000, 0x0010, 0x0009, 0xcace, 0x0008, 0x7a6c, 0x0000, 0x0059, 0x0000, 0x0001, 0x0009, 0xcb28, 0x0008, 0x7ac6, 0x0000, 0x0059 }, 16, 0x00084dc0, 1},
+ {{0x0000, 0x0001, 0x0009, 0xcb82, 0x0008, 0x7b20, 0x0000, 0x0059, 0x0000, 0x0001, 0x0009, 0xcbdc, 0x0008, 0x7b7a, 0x0000, 0x0059 }, 16, 0x00084de0, 1},
+ {{0x0000, 0x0001, 0x0009, 0xcd38, 0x0008, 0x7bd4, 0x0000, 0x00f4, 0x0000, 0x0000, 0x0009, 0xce2c, 0x0008, 0x7cc8, 0x0000, 0x0028 }, 16, 0x00084e00, 1},
+ {{0x0000, 0x0000, 0x0009, 0xce54, 0x0008, 0x7cf0, 0x0000, 0x001c, 0x0000, 0x0000, 0x0009, 0xce70, 0x0008, 0x7d0c, 0x0000, 0x0014 }, 16, 0x00084e20, 1},
+ {{0x0000, 0x0008, 0x0009, 0xce8c, 0x0008, 0x7d28, 0x0000, 0x0010, 0x0000, 0x0004, 0x0009, 0xcea0, 0x0008, 0x7d3c, 0x0000, 0x0008 }, 16, 0x00084e40, 1},
+ {{0x0000, 0x0000, 0x0009, 0xceac, 0x0008, 0x7d44, 0x0000, 0x0004, 0x0000, 0x0000, 0x0009, 0xceb0, 0x0008, 0x7d48, 0x0000, 0x0004 }, 16, 0x00084e60, 1},
+ {{0x0000, 0x0000, 0x0009, 0xceb4, 0x0008, 0x7d4c, 0x0000, 0x028c, 0x0000, 0x0004, 0x0009, 0xd144, 0x0008, 0x7fdc, 0x0000, 0x028c }, 16, 0x00084e80, 1},
+ {{0x0000, 0x0004, 0x0009, 0xd3d4, 0x0008, 0x826c, 0x0000, 0x0232, 0x0000, 0x0002, 0x0009, 0xd608, 0x0008, 0x84a0, 0x0000, 0x0010 }, 16, 0x00084ea0, 1},
+ {{0x0000, 0x0004, 0x0009, 0xd61c, 0x0008, 0x84b4, 0x0000, 0x0000, 0x0000, 0x000c, 0x0009, 0xd628, 0x0008, 0x84c0, 0x0000, 0x0000 }, 16, 0x00084ec0, 1},
+ {{0x0000, 0x0004, 0x0009, 0xd630, 0x0008, 0x84c4, 0x0000, 0x0004, 0x0000, 0x0000, 0x0009, 0xd634, 0x0008, 0x84c8, 0x0000, 0x0004 }, 16, 0x00084ee0, 1},
+ {{0x0000, 0x0000, 0x0009, 0xd638, 0x0008, 0x84cc, 0x0000, 0x0004, 0x0000, 0x0000, 0x0009, 0xd63c, 0x0008, 0x84d0, 0x0000, 0x0004 }, 16, 0x00084f00, 1},
+ {{0x0000, 0x0000, 0x0009, 0xd640, 0x0008, 0x84d4, 0x0000, 0x0004, 0x0000, 0x0000, 0x0009, 0xd644, 0x0008, 0x84d8, 0x0000, 0x0004 }, 16, 0x00084f20, 1},
+ {{0x0000, 0x0000, 0x0009, 0xd648, 0x0008, 0x84dc, 0x0000, 0x0000, 0x0000, 0x0004, 0x000b, 0xfa00, 0x0008, 0x84e0, 0x0000, 0x0000 }, 16, 0x00084f40, 1},
+ {{0x0000, 0x0c18, 0x000c, 0x20f4, 0x0008, 0x90f8, 0x0000, 0x0000, 0x0000, 0x0004, 0x000c, 0x20f8, 0x0008, 0x90fc, 0x0000, 0x0000 }, 16, 0x00084f60, 1},
+ {{0x0000, 0x0004, 0x000c, 0x20fc, 0x0008, 0x9100, 0x0000, 0x0000, 0x0000, 0x0004, 0x000c, 0x2100, 0x0008, 0x9104, 0x0000, 0x0000 }, 16, 0x00084f80, 1},
+ {{0x0000, 0x0004, 0x000c, 0x2660, 0x0008, 0x9108, 0x0000, 0x0010, 0x0000, 0x0000, 0x0009, 0xd664, 0x0008, 0x9308, 0x0000, 0x0000 }, 16, 0x00084fa0, 1},
+ {{0x0000, 0x0004, 0x0009, 0xd668, 0x0008, 0x930c, 0x0000, 0x0008, 0x0000, 0x0000, 0x0009, 0xd670, 0x0008, 0x9314, 0x0000, 0x0010 }, 16, 0x00084fc0, 1},
+ {{0x0000, 0x0000, 0x0009, 0xd680, 0x0008, 0x9324, 0x0000, 0x0000, 0x0000, 0x0004, 0x0009, 0xd684, 0x0008, 0x9328, 0x0000, 0x0000 }, 16, 0x00084fe0, 1},
+ {{0x0000, 0x0004, 0x0009, 0xd688, 0x0008, 0x932c, 0x0000, 0x0004, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, }, 14, 0x00085000, 1},
+ {{0x000c, 0x5600, 0x000c, 0x5500, 0x000c, 0xa000, 0x0000, 0x0100, 0x000c, 0xa000, 0x0000, 0x0000, }, 12, 0x0008501c, 1},
+ {{0x0008, 0x9800, 0x0001, 0x3ea0, 0x000b, 0xfa00, 0x0000, 0x35f4, 0x0000, 0x0002, }, 10, 0x00085034, 1},
+ {{0x6874, 0x7470, 0x3a2f, 0x2f61, 0x7573, 0x7376, 0x6e30, 0x312f, 0x7376, 0x6e2f, 0x7469, 0x6d62, 0x6572, 0x776f, 0x6c66, 0x2d73 }, 16, 0x00085048, 1},
+ {{0x772f, 0x6669, 0x726d, 0x7761, 0x7265, 0x2f7a, 0x6c73, 0x3338, 0x3035, 0x312f, 0x6272, 0x616e, 0x6368, 0x6573, 0x2f4d, 0x6169 }, 16, 0x00085068, 1},
+ {{0x6e74, 0x656e, 0x616e, 0x6365, 0x2f56, 0x6572, 0x5f32, 0x5f30, 0x5f31, 0x0038, 0x3231, 0x3600, 0x556e, 0x6d6f, 0x6469, 0x6669 }, 16, 0x00085088, 1},
+ {{0x6564, 0x0032, 0x3031, 0x362f, 0x3130, 0x2f32, 0x3620, 0x3132, 0x3a32, 0x393a, 0x3137, 0x0032, 0x3031, 0x362f, 0x3130, 0x2f32 }, 16, 0x000850a8, 1},
+ {{0x3620, 0x3132, 0x3a33, 0x333a, 0x3531, 0x0000, 0x0008, 0x5048, 0x0008, 0x509b, 0x0008, 0x50a0, 0x0008, 0x50ab, 0x0008, 0x50bf }, 16, 0x000850c8, 1},
+ {{0x2018, 0x0000, 0x000c, 0x5600, 0x000c, 0x5500, 0x000c, 0xa000, 0x0000, 0x0100, 0x000c, 0xa000, 0x0000, 0x0000, 0x0008, 0xd41c }, 16, 0x000850e8, 1},
+ {{0x0008, 0xd7dc, 0x0008, 0xd11c, 0x0008, 0xd1dc, 0x0008, 0xc1c0, 0x0008, 0xc040, 0x0008, 0xbe00, 0x0008, 0xbf80, 0x0000, 0x0000 }, 16, 0x00085108, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0010, 0x0010, 0x0001, 0x0000, 0x0008, 0x0008, 0x0010, 0x0018 }, 16, 0x00085128, 1},
+ {{0x0020, 0x002c, 0x0030, 0x0028, 0x1f40, 0x1f40, 0x3e80, 0x5dc0, 0x7d00, 0xac44, 0xbb80, 0x9c40, 0x0030, 0x0008, 0x0010, 0x0018 }, 16, 0x00085148, 1},
+ {{0x0030, 0x0030, 0x0030, 0x0030, 0x0001, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0005, 0x0008, 0x0200, 0x0000, 0x496e }, 16, 0x00085168, 1},
+ {{0x636f, 0x6d70, 0x6174, 0x6962, 0x6c65, 0x2041, 0x7070, 0x6c69, 0x6361, 0x7469, 0x6f6e, 0x0a00, 0x556e, 0x7472, 0x696d, 0x6d65 }, 16, 0x00085188, 1},
+ {{0x6420, 0x5061, 0x7274, 0x0a00, 0x000a, 0x224a, 0x000a, 0x22ca, 0x000a, 0x234a, 0x000a, 0x1f66, 0x000a, 0x1fde, 0x000a, 0x205a }, 16, 0x000851a8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0010, 0x0030, 0x0000, 0x0000 }, 16, 0x000851c8, 1},
+ {{0x0000, 0x00c9, 0x0192, 0x025b, 0x0324, 0x03ed, 0x04b6, 0x057f, 0x0648, 0x0711, 0x07d9, 0x08a2, 0x096b, 0x0a33, 0x0afb, 0x0bc4 }, 16, 0x000851e8, 1},
+ {{0x0c8c, 0x0d54, 0x0e1c, 0x0ee4, 0x0fab, 0x1073, 0x113a, 0x1201, 0x12c8, 0x138f, 0x1455, 0x151c, 0x15e2, 0x16a8, 0x176e, 0x1833 }, 16, 0x00085208, 1},
+ {{0x18f9, 0x19be, 0x1a83, 0x1b47, 0x1c0c, 0x1cd0, 0x1d93, 0x1e57, 0x1f1a, 0x1fdd, 0x209f, 0x2162, 0x2224, 0x22e5, 0x23a7, 0x2467 }, 16, 0x00085228, 1},
+ {{0x2528, 0x25e8, 0x26a8, 0x2768, 0x2827, 0x28e5, 0x29a4, 0x2a62, 0x2b1f, 0x2bdc, 0x2c99, 0x2d55, 0x2e11, 0x2ecc, 0x2f87, 0x3042 }, 16, 0x00085248, 1},
+ {{0x30fc, 0x31b5, 0x326e, 0x3327, 0x33df, 0x3497, 0x354e, 0x3604, 0x36ba, 0x3770, 0x3825, 0x38d9, 0x398d, 0x3a40, 0x3af3, 0x3ba5 }, 16, 0x00085268, 1},
+ {{0x3c57, 0x3d08, 0x3db8, 0x3e68, 0x3f17, 0x3fc6, 0x4074, 0x4121, 0x41ce, 0x427a, 0x4326, 0x43d1, 0x447b, 0x4524, 0x45cd, 0x4675 }, 16, 0x00085288, 1},
+ {{0x471d, 0x47c4, 0x486a, 0x490f, 0x49b4, 0x4a58, 0x4afb, 0x4b9e, 0x4c40, 0x4ce1, 0x4d81, 0x4e21, 0x4ec0, 0x4f5e, 0x4ffb, 0x5098 }, 16, 0x000852a8, 1},
+ {{0x5134, 0x51cf, 0x5269, 0x5303, 0x539b, 0x5433, 0x54ca, 0x5560, 0x55f6, 0x568a, 0x571e, 0x57b1, 0x5843, 0x58d4, 0x5964, 0x59f4 }, 16, 0x000852c8, 1},
+ {{0x5a82, 0x5b10, 0x5b9d, 0x5c29, 0x5cb4, 0x5d3e, 0x5dc8, 0x5e50, 0x5ed7, 0x5f5e, 0x5fe4, 0x6068, 0x60ec, 0x616f, 0x61f1, 0x6272 }, 16, 0x000852e8, 1},
+ {{0x62f2, 0x6371, 0x63ef, 0x646c, 0x64e9, 0x6564, 0x65de, 0x6657, 0x66d0, 0x6747, 0x67bd, 0x6832, 0x68a7, 0x691a, 0x698c, 0x69fd }, 16, 0x00085308, 1},
+ {{0x6a6e, 0x6add, 0x6b4b, 0x6bb8, 0x6c24, 0x6c8f, 0x6cf9, 0x6d62, 0x6dca, 0x6e31, 0x6e97, 0x6efb, 0x6f5f, 0x6fc2, 0x7023, 0x7083 }, 16, 0x00085328, 1},
+ {{0x70e3, 0x7141, 0x719e, 0x71fa, 0x7255, 0x72af, 0x7308, 0x735f, 0x73b6, 0x740b, 0x7460, 0x74b3, 0x7505, 0x7556, 0x75a6, 0x75f4 }, 16, 0x00085348, 1},
+ {{0x7642, 0x768e, 0x76d9, 0x7723, 0x776c, 0x77b4, 0x77fb, 0x7840, 0x7885, 0x78c8, 0x790a, 0x794a, 0x798a, 0x79c9, 0x7a06, 0x7a42 }, 16, 0x00085368, 1},
+ {{0x7a7d, 0x7ab7, 0x7aef, 0x7b27, 0x7b5d, 0x7b92, 0x7bc6, 0x7bf9, 0x7c2a, 0x7c5a, 0x7c89, 0x7cb7, 0x7ce4, 0x7d0f, 0x7d3a, 0x7d63 }, 16, 0x00085388, 1},
+ {{0x7d8a, 0x7db1, 0x7dd6, 0x7dfb, 0x7e1e, 0x7e3f, 0x7e60, 0x7e7f, 0x7e9d, 0x7eba, 0x7ed6, 0x7ef0, 0x7f0a, 0x7f22, 0x7f38, 0x7f4e }, 16, 0x000853a8, 1},
+ {{0x7f62, 0x7f75, 0x7f87, 0x7f98, 0x7fa7, 0x7fb5, 0x7fc2, 0x7fce, 0x7fd9, 0x7fe2, 0x7fea, 0x7ff1, 0x7ff6, 0x7ffa, 0x7ffe, 0x7fff }, 16, 0x000853c8, 1},
+ {{0x00c9, 0x00c9, 0x00c9, 0x00c9, 0x00c9, 0x00c9, 0x00c9, 0x00c9, 0x00c9, 0x00c8, 0x00c9, 0x00c9, 0x00c8, 0x00c8, 0x00c9, 0x00c8 }, 16, 0x000853e8, 1},
+ {{0x00c8, 0x00c8, 0x00c8, 0x00c7, 0x00c8, 0x00c7, 0x00c7, 0x00c7, 0x00c7, 0x00c6, 0x00c7, 0x00c6, 0x00c6, 0x00c6, 0x00c5, 0x00c6 }, 16, 0x00085408, 1},
+ {{0x00c5, 0x00c5, 0x00c4, 0x00c5, 0x00c4, 0x00c3, 0x00c4, 0x00c3, 0x00c3, 0x00c2, 0x00c3, 0x00c2, 0x00c1, 0x00c2, 0x00c0, 0x00c1 }, 16, 0x00085428, 1},
+ {{0x00c0, 0x00c0, 0x00c0, 0x00bf, 0x00be, 0x00bf, 0x00be, 0x00bd, 0x00bd, 0x00bd, 0x00bc, 0x00bc, 0x00bb, 0x00bb, 0x00bb, 0x00ba }, 16, 0x00085448, 1},
+ {{0x00b9, 0x00b9, 0x00b9, 0x00b8, 0x00b8, 0x00b7, 0x00b6, 0x00b6, 0x00b6, 0x00b5, 0x00b4, 0x00b4, 0x00b3, 0x00b3, 0x00b2, 0x00b2 }, 16, 0x00085468, 1},
+ {{0x00b1, 0x00b0, 0x00b0, 0x00af, 0x00af, 0x00ae, 0x00ad, 0x00ad, 0x00ac, 0x00ac, 0x00ab, 0x00aa, 0x00a9, 0x00a9, 0x00a8, 0x00a8 }, 16, 0x00085488, 1},
+ {{0x00a7, 0x00a6, 0x00a5, 0x00a5, 0x00a4, 0x00a3, 0x00a3, 0x00a2, 0x00a1, 0x00a0, 0x00a0, 0x009f, 0x009e, 0x009d, 0x009d, 0x009c }, 16, 0x000854a8, 1},
+ {{0x009b, 0x009a, 0x009a, 0x0098, 0x0098, 0x0097, 0x0096, 0x0096, 0x0094, 0x0094, 0x0093, 0x0092, 0x0091, 0x0090, 0x0090, 0x008e }, 16, 0x000854c8, 1},
+ {{0x008e, 0x008d, 0x008c, 0x008b, 0x008a, 0x008a, 0x0088, 0x0087, 0x0087, 0x0086, 0x0084, 0x0084, 0x0083, 0x0082, 0x0081, 0x0080 }, 16, 0x000854e8, 1},
+ {{0x007f, 0x007e, 0x007d, 0x007d, 0x007b, 0x007a, 0x0079, 0x0079, 0x0077, 0x0076, 0x0075, 0x0075, 0x0073, 0x0072, 0x0071, 0x0071 }, 16, 0x00085508, 1},
+ {{0x006f, 0x006e, 0x006d, 0x006c, 0x006b, 0x006a, 0x0069, 0x0068, 0x0067, 0x0066, 0x0064, 0x0064, 0x0063, 0x0061, 0x0060, 0x0060 }, 16, 0x00085528, 1},
+ {{0x005e, 0x005d, 0x005c, 0x005b, 0x005a, 0x0059, 0x0057, 0x0057, 0x0055, 0x0055, 0x0053, 0x0052, 0x0051, 0x0050, 0x004e, 0x004e }, 16, 0x00085548, 1},
+ {{0x004c, 0x004b, 0x004a, 0x0049, 0x0048, 0x0047, 0x0045, 0x0045, 0x0043, 0x0042, 0x0040, 0x0040, 0x003f, 0x003d, 0x003c, 0x003b }, 16, 0x00085568, 1},
+ {{0x003a, 0x0038, 0x0038, 0x0036, 0x0035, 0x0034, 0x0033, 0x0031, 0x0030, 0x002f, 0x002e, 0x002d, 0x002b, 0x002b, 0x0029, 0x0027 }, 16, 0x00085588, 1},
+ {{0x0027, 0x0025, 0x0025, 0x0023, 0x0021, 0x0021, 0x001f, 0x001e, 0x001d, 0x001c, 0x001a, 0x001a, 0x0018, 0x0016, 0x0016, 0x0014 }, 16, 0x000855a8, 1},
+ {{0x0013, 0x0012, 0x0011, 0x000f, 0x000e, 0x000d, 0x000c, 0x000b, 0x0009, 0x0008, 0x0007, 0x0005, 0x0004, 0x0004, 0x0001, 0x0001 }, 16, 0x000855c8, 1},
+ {{0x000a, 0x349a, 0x000a, 0x32e4, 0x000a, 0x335e, 0x000a, 0x33ac, 0x000a, 0x343a, 0x000a, 0x349a, 0x000a, 0x27fe, 0x000a, 0x27ee }, 16, 0x000855e8, 1},
+ {{0x000a, 0x27f4, 0x0008, 0xf59c, 0x0000, 0x0000, 0x0008, 0xf588, 0x0000, 0x0000, 0x0010, 0x0000, 0x0000, 0x0000, 0x0009, 0x1140 }, 16, 0x00085608, 1},
+ {{0x0009, 0x0f80, 0x0009, 0x1040, 0x0009, 0x1180, 0x0009, 0x10c0, 0x0009, 0x0fc0, 0x0009, 0x1000, 0x0009, 0x1100, 0x0009, 0x0000 }, 16, 0x00085628, 1},
+ {{0x0008, 0xfc00, 0x0009, 0x0400, 0x0009, 0x0a00, 0x0009, 0x0c00, 0x0008, 0xf800, 0x0009, 0x0800, 0x0009, 0x0200, 0x0009, 0x12dc }, 16, 0x00085648, 1},
+ {{0x0009, 0x19bc, 0x0009, 0x18e0, 0x0009, 0x1ee4, 0x0009, 0x1a98, 0x0009, 0x13b8, 0x0009, 0x1e08, 0x0009, 0x2254, 0x0009, 0x1fc0 }, 16, 0x00085668, 1},
+ {{0x0009, 0x1c50, 0x0009, 0x240c, 0x0009, 0x209c, 0x0009, 0x1728, 0x0009, 0x164c, 0x0009, 0x1570, 0x0009, 0x2330, 0x0009, 0x32a5 }, 16, 0x00085688, 1},
+ {{0x0009, 0x3224, 0x0008, 0x5eb7, 0x000a, 0x5300, 0x0009, 0x329f, 0x0009, 0x31af, 0x0009, 0x2e7e, 0x0001, 0xfba6, 0x0009, 0x3296 }, 16, 0x000856a8, 1},
+ {{0x0009, 0x3000, 0x0009, 0x2e51, 0x0001, 0xfbac, 0x0009, 0x3289, 0x0009, 0x3216, 0x0009, 0x2cd6, 0x0001, 0xf858, 0x0009, 0x32a2 }, 16, 0x000856c8, 1},
+ {{0x0009, 0x3199, 0x0009, 0x2dbb, 0x0001, 0xf828, 0x0009, 0x3299, 0x0009, 0x31db, 0x0009, 0x2dee, 0x0001, 0xf82e, 0x0009, 0x3285 }, 16, 0x000856e8, 1},
+ {{0x0009, 0x3154, 0x0009, 0x2d14, 0x0001, 0xf834, 0x0009, 0x3290, 0x0009, 0x2fdf, 0x0009, 0x2eaa, 0x0001, 0xf840, 0x0009, 0x329c }, 16, 0x00085708, 1},
+ {{0x0009, 0x3021, 0x0009, 0x2e51, 0x0001, 0xf846, 0x0009, 0x3279, 0x0009, 0x2f99, 0x0009, 0x2e21, 0x0001, 0xf84c, 0x0009, 0x3265 }, 16, 0x00085728, 1},
+ {{0x0009, 0x3042, 0x0009, 0x2efe, 0x0001, 0xf852, 0x0009, 0x3251, 0x0009, 0x3251, 0x0009, 0x3125, 0x0001, 0xf864, 0x0009, 0x3241 }, 16, 0x00085748, 1},
+ {{0x0009, 0x3241, 0x0009, 0x3080, 0x0001, 0xf85e, 0x0009, 0x3274, 0x0009, 0x3274, 0x0009, 0x309e, 0x000a, 0x53f0, 0x0009, 0x3249 }, 16, 0x00085768, 1},
+ {{0x0009, 0x3249, 0x0009, 0x2f74, 0x000a, 0x5560, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000a, 0x469c }, 16, 0x00085788, 1},
+ {{0x000a, 0x4708, 0x000a, 0x4b02, 0x000a, 0x4764, 0x000a, 0x4856, 0x000a, 0x481c, 0x000a, 0x43c2, 0x000a, 0x4434, 0x000a, 0x4606 }, 16, 0x000857a8, 1},
+ {{0x000a, 0x44de, 0x0000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0x0008, 0x5dc0, 0x0009, 0x28ce, 0x0009, 0x28ce, 0x0000, 0x0000 }, 16, 0x000857c8, 1},
+ {{0x0000, 0x0000, 0x4578, 0x6563, 0x7574, 0x6573, 0x2061, 0x204a, 0x5352, 0x2069, 0x6e73, 0x7472, 0x7563, 0x7469, 0x6f6e, 0x2028 }, 16, 0x000857e8, 1},
+ {{0x6a75, 0x6d70, 0x2074, 0x6f20, 0x7375, 0x6272, 0x6f75, 0x7469, 0x6e65, 0x2061, 0x7420, 0x3c61, 0x6464, 0x7265, 0x7373, 0x3e29 }, 16, 0x00085808, 1},
+ {{0x2e00, 0x5265, 0x6164, 0x7320, 0x5b6c, 0x656e, 0x6774, 0x685d, 0x206c, 0x6f6e, 0x6720, 0x776f, 0x7264, 0x7320, 0x6f66, 0x2064 }, 16, 0x00085828, 1},
+ {{0x6174, 0x6120, 0x7374, 0x6172, 0x7469, 0x6e67, 0x2061, 0x7420, 0x3c61, 0x6464, 0x7265, 0x7373, 0x3e00, 0x7075, 0x7473, 0x2070 }, 16, 0x00085848, 1},
+ {{0x726f, 0x6365, 0x7373, 0x6f72, 0x2074, 0x6f20, 0x736c, 0x6565, 0x702c, 0x2077, 0x7269, 0x7465, 0x2030, 0x7846, 0x4438, 0x3020 }, 16, 0x00085868, 1},
+ {{0x746f, 0x2048, 0x4249, 0x2074, 0x6f20, 0x7761, 0x6b65, 0x2075, 0x7000, 0x5772, 0x6974, 0x6573, 0x2075, 0x7020, 0x746f, 0x2031 }, 16, 0x00085888, 1},
+ {{0x3030, 0x2077, 0x6f72, 0x6428, 0x7329, 0x206f, 0x6620, 0x6461, 0x7461, 0x2073, 0x7461, 0x7274, 0x696e, 0x6720, 0x6174, 0x203c }, 16, 0x000858a8, 1},
+ {{0x6164, 0x6472, 0x6573, 0x733e, 0x0052, 0x6561, 0x6473, 0x205b, 0x6c65, 0x6e67, 0x7468, 0x5d20, 0x6279, 0x7465, 0x7320, 0x6f66 }, 16, 0x000858c8, 1},
+ {{0x2064, 0x6174, 0x6120, 0x7374, 0x6172, 0x7469, 0x6e67, 0x2061, 0x7420, 0x3c61, 0x6464, 0x7265, 0x7373, 0x3e00, 0x5265, 0x6164 }, 16, 0x000858e8, 1},
+ {{0x7320, 0x5b6c, 0x656e, 0x6774, 0x685d, 0x2077, 0x6f72, 0x6473, 0x206f, 0x6620, 0x6461, 0x7461, 0x2073, 0x7461, 0x7274, 0x696e }, 16, 0x00085908, 1},
+ {{0x6720, 0x6174, 0x203c, 0x6164, 0x6472, 0x6573, 0x733e, 0x0057, 0x7269, 0x7465, 0x7320, 0x6120, 0x6c77, 0x6f72, 0x6428, 0x7329 }, 16, 0x00085928, 1},
+ {{0x206f, 0x6620, 0x6461, 0x7461, 0x2073, 0x7461, 0x7274, 0x696e, 0x6720, 0x6174, 0x203c, 0x6164, 0x6472, 0x6573, 0x733e, 0x0057 }, 16, 0x00085948, 1},
+ {{0x7269, 0x7465, 0x7320, 0x776f, 0x7264, 0x2873, 0x2920, 0x6f66, 0x2064, 0x6174, 0x6120, 0x7374, 0x6172, 0x7469, 0x6e67, 0x2061 }, 16, 0x00085968, 1},
+ {{0x7420, 0x3c61, 0x6464, 0x7265, 0x7373, 0x3e00, 0x5265, 0x6164, 0x7320, 0x5b6c, 0x656e, 0x6774, 0x685d, 0x2077, 0x6f72, 0x6473 }, 16, 0x00085988, 1},
+ {{0x206f, 0x6620, 0x6461, 0x7461, 0x2066, 0x726f, 0x6d20, 0x3c61, 0x6464, 0x7265, 0x7373, 0x3e00, 0x5772, 0x6974, 0x6573, 0x2062 }, 16, 0x000859a8, 1},
+ {{0x7974, 0x6573, 0x206f, 0x6620, 0x6461, 0x7461, 0x2073, 0x7461, 0x7274, 0x696e, 0x6720, 0x6174, 0x203c, 0x6164, 0x6472, 0x6573 }, 16, 0x000859c8, 1},
+ {{0x733e, 0x0077, 0x7220, 0x3c61, 0x6464, 0x7265, 0x7373, 0x3e20, 0x3c77, 0x6f72, 0x6430, 0x3e20, 0x5b77, 0x6f72, 0x6431, 0x5d20 }, 16, 0x000859e8, 1},
+ {{0x2e2e, 0x2e5b, 0x776f, 0x7264, 0x3939, 0x5d00, 0x4669, 0x6c6c, 0x7320, 0x6d65, 0x6d6f, 0x7279, 0x2077, 0x6974, 0x6820, 0x6120 }, 16, 0x00085a08, 1},
+ {{0x3332, 0x2d62, 0x6974, 0x2068, 0x6578, 0x2070, 0x6174, 0x7465, 0x726e, 0x2e00, 0x576f, 0x7273, 0x7420, 0x3530, 0x6d73, 0x2069 }, 16, 0x00085a28, 1},
+ {{0x6e74, 0x6572, 0x7661, 0x6c20, 0x2020, 0x2020, 0x3a20, 0x2533, 0x642e, 0x2531, 0x6425, 0x2525, 0x250a, 0x0043, 0x7572, 0x7265 }, 16, 0x00085a48, 1},
+ {{0x6e74, 0x2043, 0x5055, 0x2075, 0x7469, 0x6c69, 0x7a61, 0x7469, 0x6f6e, 0x203a, 0x2025, 0x3364, 0x2e25, 0x3164, 0x2525, 0x2525 }, 16, 0x00085a68, 1},
+ {{0x0a00, 0x4469, 0x7370, 0x6c61, 0x7920, 0x7468, 0x6520, 0x4761, 0x6c69, 0x6c65, 0x6f20, 0x5072, 0x6f66, 0x696c, 0x6572, 0x2043 }, 16, 0x00085a88, 1},
+ {{0x6f75, 0x6e74, 0x732e, 0x0077, 0x6c77, 0x203c, 0x6164, 0x6472, 0x6573, 0x733e, 0x203c, 0x6c77, 0x6f72, 0x6430, 0x3e20, 0x5b6c }, 16, 0x00085aa8, 1},
+ {{0x776f, 0x7264, 0x315d, 0x202e, 0x2e2e, 0x0049, 0x646c, 0x6520, 0x6675, 0x6e63, 0x2063, 0x616c, 0x6c20, 0x636f, 0x756e, 0x7420 }, 16, 0x00085ac8, 1},
+ {{0x3a20, 0x2535, 0x642c, 0x2530, 0x2e33, 0x640a, 0x0077, 0x6220, 0x3c61, 0x6464, 0x7265, 0x7373, 0x3e20, 0x3c62, 0x7974, 0x6530 }, 16, 0x00085ae8, 1},
+ {{0x3e20, 0x5b62, 0x7974, 0x6531, 0x5d20, 0x2e2e, 0x2e00, 0x7772, 0x203c, 0x6164, 0x6472, 0x6573, 0x733e, 0x203c, 0x776f, 0x7264 }, 16, 0x00085b08, 1},
+ {{0x303e, 0x205b, 0x776f, 0x7264, 0x315d, 0x202e, 0x2e2e, 0x0077, 0x7720, 0x3c61, 0x6464, 0x7265, 0x7373, 0x3e20, 0x3c77, 0x6f72 }, 16, 0x00085b28, 1},
+ {{0x6430, 0x3e20, 0x5b77, 0x6f72, 0x6431, 0x5d20, 0x2e2e, 0x2e00, 0x6669, 0x6c6c, 0x203c, 0x6164, 0x6472, 0x6573, 0x733e, 0x203c }, 16, 0x00085b48, 1},
+ {{0x6c65, 0x6e3e, 0x203c, 0x7061, 0x7474, 0x6572, 0x6e3e, 0x0052, 0x6561, 0x6420, 0x5379, 0x7374, 0x656d, 0x2049, 0x6e74, 0x6572 }, 16, 0x00085b68, 1},
+ {{0x7275, 0x7074, 0x2052, 0x6567, 0x6973, 0x7465, 0x7200, 0x466f, 0x7263, 0x6520, 0x616e, 0x2069, 0x6c6c, 0x6567, 0x616c, 0x2069 }, 16, 0x00085b88, 1},
+ {{0x6e73, 0x7472, 0x7563, 0x7469, 0x6f6e, 0x2e00, 0x4469, 0x7370, 0x6c61, 0x7920, 0x7468, 0x6520, 0x6370, 0x7520, 0x7574, 0x696c }, 16, 0x00085ba8, 1},
+ {{0x697a, 0x6174, 0x696f, 0x6e2e, 0x0049, 0x646c, 0x6520, 0x7469, 0x636b, 0x7320, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x3a20 }, 16, 0x00085bc8, 1},
+ {{0x2539, 0x640a, 0x0042, 0x7573, 0x7920, 0x7469, 0x636b, 0x7320, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x3a20, 0x2539, 0x640a }, 16, 0x00085be8, 1},
+ {{0x002a, 0x2a2a, 0x2a2a, 0x2049, 0x6e20, 0x3420, 0x7365, 0x636f, 0x6e64, 0x7320, 0x2a2a, 0x2a2a, 0x2a0a, 0x0054, 0x7572, 0x6e20 }, 16, 0x00085c08, 1},
+ {{0x6368, 0x6172, 0x6163, 0x7465, 0x7220, 0x6563, 0x686f, 0x206f, 0x6666, 0x0043, 0x6175, 0x7365, 0x2061, 0x2068, 0x6172, 0x6477 }, 16, 0x00085c28, 1},
+ {{0x6172, 0x6520, 0x7265, 0x626f, 0x6f74, 0x0044, 0x6973, 0x706c, 0x6179, 0x2061, 0x7070, 0x2073, 0x766e, 0x206e, 0x756d, 0x6265 }, 16, 0x00085c48, 1},
+ {{0x7200, 0x726c, 0x7720, 0x3c61, 0x6464, 0x7265, 0x7373, 0x3e20, 0x5b6c, 0x656e, 0x6774, 0x685d, 0x0066, 0x6c43, 0x7220, 0x3c61 }, 16, 0x00085c68, 1},
+ {{0x7070, 0x4e75, 0x6d20, 0x6f70, 0x7469, 0x6f6e, 0x616c, 0x3e00, 0x5475, 0x726e, 0x2063, 0x6861, 0x7261, 0x6374, 0x6572, 0x2065 }, 16, 0x00085c88, 1},
+ {{0x6368, 0x6f20, 0x6f6e, 0x0072, 0x6220, 0x3c61, 0x6464, 0x7265, 0x7373, 0x3e20, 0x5b6c, 0x656e, 0x6774, 0x685d, 0x0072, 0x6420 }, 16, 0x00085ca8, 1},
+ {{0x3c61, 0x6464, 0x7265, 0x7373, 0x3e20, 0x5b6c, 0x656e, 0x6774, 0x685d, 0x0052, 0x6570, 0x726f, 0x6772, 0x616d, 0x2043, 0x5220 }, 16, 0x00085cc8, 1},
+ {{0x696e, 0x2066, 0x6c61, 0x7368, 0x0072, 0x7720, 0x3c61, 0x6464, 0x7265, 0x7373, 0x3e20, 0x5b6c, 0x656e, 0x6774, 0x685d, 0x0045 }, 16, 0x00085ce8, 1},
+ {{0x7374, 0x2043, 0x5055, 0x2063, 0x6c6f, 0x636b, 0x203a, 0x2025, 0x3964, 0x0a00, 0x5375, 0x7065, 0x7255, 0x7365, 0x7220, 0x4d6f }, 16, 0x00085d08, 1},
+ {{0x6465, 0x0a00, 0x6a73, 0x7220, 0x3c61, 0x6464, 0x7265, 0x7373, 0x3e00, 0x3f20, 0x5b63, 0x6f6d, 0x6d61, 0x6e64, 0x5d00, 0x2d2d }, 16, 0x00085d28, 1},
+ {{0x2d2d, 0x2d2d, 0x2d0a, 0x0045, 0x6368, 0x6f4f, 0x6666, 0x0069, 0x6c6c, 0x6567, 0x616c, 0x0067, 0x616c, 0x7072, 0x6f66, 0x0072 }, 16, 0x00085d48, 1},
+ {{0x6562, 0x6f6f, 0x7400, 0x4563, 0x686f, 0x4f6e, 0x0073, 0x6c65, 0x6570, 0x0066, 0x696c, 0x6c00, 0x666c, 0x4372, 0x0072, 0x6453 }, 16, 0x00085d68, 1},
+ {{0x6900, 0x7368, 0x6f77, 0x0077, 0x6c77, 0x0076, 0x6572, 0x0072, 0x6c77, 0x006a, 0x7372, 0x0054, 0x5700, 0x7762, 0x0073, 0x7500 }, 16, 0x00085d88, 1},
+ {{0x7772, 0x0072, 0x7700, 0x7777, 0x0072, 0x6400, 0x7262, 0x003f, 0x0000, 0x0000, 0x0000, 0x0100, 0x0009, 0x32a5, 0x0009, 0x3224 }, 16, 0x00085da8, 1},
+ {{0x0008, 0x5f82, 0x000a, 0x5210, 0x0009, 0x329f, 0x0009, 0x31af, 0x0009, 0x2e7e, 0x0001, 0xfba6, 0x0009, 0x3296, 0x0009, 0x2ed5 }, 16, 0x00085dc8, 1},
+ {{0x0009, 0x2d84, 0x0001, 0xfbac, 0x0009, 0x3281, 0x0009, 0x3281, 0x0009, 0x313d, 0x000a, 0x5090, 0x0009, 0x326a, 0x0009, 0x316b }, 16, 0x00085de8, 1},
+ {{0x0009, 0x31c5, 0x000a, 0x5110, 0x0009, 0x326f, 0x0009, 0x326f, 0x0009, 0x3061, 0x000a, 0x51c0, 0x0009, 0x3239, 0x0009, 0x3239 }, 16, 0x00085e08, 1},
+ {{0x0009, 0x310d, 0x000a, 0x51b0, 0x0009, 0x3258, 0x0009, 0x3258, 0x0009, 0x3182, 0x000a, 0x51a0, 0x0009, 0x325f, 0x0009, 0x325f }, 16, 0x00085e28, 1},
+ {{0x0009, 0x2d4c, 0x000a, 0x5590, 0x0009, 0x3293, 0x0009, 0x32aa, 0x0009, 0x32aa, 0x000a, 0x5580, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00085e48, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0a21, 0x2020, 0x5356, 0x4e20, 0x494e, 0x464f, 0x3a0a, 0x2109, 0x5265, 0x7669, 0x7369, 0x6f6e }, 16, 0x00085e68, 1},
+ {{0x3a20, 0x2573, 0x202d, 0x2d20, 0x2573, 0x0a21, 0x0943, 0x6f6d, 0x6d69, 0x7420, 0x5469, 0x6d65, 0x3a20, 0x2573, 0x0a21, 0x0942 }, 16, 0x00085e88, 1},
+ {{0x7569, 0x6c64, 0x2054, 0x696d, 0x653a, 0x2025, 0x730a, 0x0044, 0x6973, 0x706c, 0x6179, 0x7320, 0x636f, 0x6d6d, 0x616e, 0x6420 }, 16, 0x00085ea8, 1},
+ {{0x6c69, 0x7374, 0x2c20, 0x6f72, 0x2069, 0x6e66, 0x6f72, 0x6d61, 0x7469, 0x6f6e, 0x206f, 0x6e20, 0x5b63, 0x6f6d, 0x6d61, 0x6e64 }, 16, 0x00085ec8, 1},
+ {{0x5d00, 0x0a53, 0x7973, 0x7465, 0x6d20, 0x496e, 0x7465, 0x7272, 0x7570, 0x7420, 0x496e, 0x6469, 0x6361, 0x7469, 0x6f6e, 0x2052 }, 16, 0x00085ee8, 1},
+ {{0x6567, 0x6973, 0x7465, 0x723a, 0x000a, 0x5072, 0x6573, 0x7320, 0x4573, 0x6320, 0x746f, 0x2052, 0x6574, 0x7572, 0x6e20, 0x746f }, 16, 0x00085f08, 1},
+ {{0x204e, 0x6f72, 0x6d61, 0x6c20, 0x4d6f, 0x6465, 0x3a0a, 0x0041, 0x7070, 0x6c69, 0x6361, 0x7469, 0x6f6e, 0x2043, 0x6f6d, 0x6d61 }, 16, 0x00085f28, 1},
+ {{0x6e64, 0x2043, 0x6f6e, 0x7465, 0x7874, 0x0a00, 0x4572, 0x726f, 0x723a, 0x2055, 0x6e6b, 0x6e6f, 0x776e, 0x2063, 0x6f6d, 0x6d61 }, 16, 0x00085f48, 1},
+ {{0x6e64, 0x2000, 0x4164, 0x6472, 0x6573, 0x7320, 0x6d75, 0x7374, 0x2062, 0x6520, 0x6865, 0x782e, 0x0a00, 0x4469, 0x7370, 0x6c61 }, 16, 0x00085f68, 1},
+ {{0x7973, 0x2063, 0x6f6d, 0x6d61, 0x6e64, 0x206c, 0x6973, 0x7400, 0x0a20, 0x7377, 0x5265, 0x6741, 0x7070, 0x5265, 0x7643, 0x6f64 }, 16, 0x00085f88, 1},
+ {{0x6520, 0x3d20, 0x004e, 0x6f20, 0x666c, 0x6173, 0x6820, 0x7072, 0x6573, 0x656e, 0x742e, 0x0a00, 0x4261, 0x6420, 0x496d, 0x6167 }, 16, 0x00085fa8, 1},
+ {{0x6520, 0x4e75, 0x6d62, 0x6572, 0x2e0a, 0x000a, 0x2050, 0x726f, 0x6475, 0x6374, 0x2049, 0x4420, 0x3d20, 0x5a4c, 0x5300, 0x4e6f }, 16, 0x00085fc8, 1},
+ {{0x7420, 0x706f, 0x7373, 0x6962, 0x6c65, 0x2025, 0x640a, 0x2000, 0x4e6f, 0x7420, 0x706f, 0x7373, 0x6962, 0x6c65, 0x2025, 0x640a }, 16, 0x00085fe8, 1},
+ {{0x2000, 0x5573, 0x6167, 0x653a, 0x0a20, 0x2573, 0x0a0a, 0x2573, 0x0a0a, 0x0045, 0x6e74, 0x7279, 0x2054, 0x6f6f, 0x204c, 0x6f6e }, 16, 0x00086008, 1},
+ {{0x670a, 0x2000, 0x5573, 0x6167, 0x653a, 0x0a20, 0x2573, 0x0a0a, 0x2573, 0x0a0a, 0x000a, 0x436f, 0x6d6d, 0x616e, 0x6473, 0x3a0a }, 16, 0x00086028, 1},
+ {{0x000a, 0x436f, 0x6d6d, 0x616e, 0x6473, 0x3a0a, 0x004c, 0x454e, 0x2025, 0x3478, 0x0a20, 0x0020, 0x2534, 0x7820, 0x2534, 0x780a }, 16, 0x00086048, 1},
+ {{0x0045, 0x6368, 0x6f4f, 0x6666, 0x0a00, 0x2225, 0x7322, 0x200a, 0x0020, 0x2573, 0x0a00, 0x2025, 0x730a, 0x0025, 0x733e, 0x2000 }, 16, 0x00086068, 1},
+ {{0x0820, 0x080a, 0x2000, 0x200a, 0x0000, 0x0000, 0x000a, 0x5c7c, 0x000a, 0x5c8e, 0x000a, 0x5ce2, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086088, 1},
+ {{0x7fff, 0xffff, 0x7fff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000860a8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0000, 0x0600, 0x0009, 0x3474, 0x0008, 0xe118, 0x0008, 0xe058, 0x0008, 0xded8 }, 16, 0x000860c8, 1},
+ {{0x0008, 0xdf98, 0x0008, 0xc1c0, 0x0008, 0xc040, 0x0008, 0xbe00, 0x0008, 0xbf80, 0x0008, 0xd41c, 0x0008, 0xd7dc, 0x0008, 0xd11c }, 16, 0x000860e8, 1},
+ {{0x0008, 0xd1dc, 0x0009, 0x8b20, 0x0009, 0x89a0, 0x0009, 0xc124, 0x0009, 0xc1fc, 0x0009, 0x33b4, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086108, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086128, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086148, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086168, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086188, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000861a8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000861c8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000861e8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086208, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086228, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086248, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086268, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0076, 0xfefb, 0x003b, 0x0160 }, 16, 0x00086288, 1},
+ {{0x006e, 0x0350, 0xfa43, 0x023a, 0xf8ba, 0x0736, 0x0998, 0xf256, 0x068e, 0xd4e8, 0x1eba, 0x086a, 0x3fd2, 0xd002, 0xdc63, 0x1929 }, 16, 0x000862a8, 1},
+ {{0x3fd3, 0x2ff3, 0xdda3, 0xe4d4, 0x068d, 0x2b2b, 0x1e60, 0xfafa, 0xf8ba, 0xf8c3, 0x093d, 0x0c53, 0x006e, 0xfcad, 0xfaa6, 0xfd68 }, 16, 0x000862c8, 1},
+ {{0x0076, 0x010f, 0x0054, 0xffd8, 0x0003, 0xfff1, 0x00b5, 0xfee7, 0xfe50, 0x00a6, 0x00ba, 0xff81, 0x04e4, 0xffab, 0xf301, 0x0320 }, 16, 0x000862e8, 1},
+ {{0x0553, 0xfbdb, 0x0d96, 0x0000, 0xf09c, 0x0425, 0x02a1, 0xfce0, 0x033d, 0x0055, 0xfe3d, 0x007f, 0x018c, 0xff5a, 0x0001, 0x0000 }, 16, 0x00086308, 1},
+ {{0xffff, 0xfff8, 0xfff4, 0xfff0, 0xffee, 0xfff0, 0xfff7, 0x0005, 0x0018, 0x002e, 0x0043, 0x0051, 0x0054, 0x0049, 0x002f, 0x000a }, 16, 0x00086328, 1},
+ {{0xffde, 0xffb6, 0xff9b, 0xff96, 0xffaa, 0xffd8, 0x0017, 0x005c, 0x0095, 0x00b4, 0x00ac, 0x0079, 0x0023, 0xffb7, 0xff4f, 0xff03 }, 16, 0x00086348, 1},
+ {{0xfeea, 0xff11, 0xff78, 0x000d, 0x00b2, 0x0141, 0x0194, 0x018f, 0x0129, 0x006e, 0xff83, 0xfe9a, 0xfded, 0xfdad, 0xfdf6, 0xfec6 }, 16, 0x00086368, 1},
+ {{0xfff9, 0x0151, 0x027d, 0x0330, 0x0330, 0x026a, 0x00f8, 0xff22, 0xfd4f, 0xfbf1, 0xfb6a, 0xfbf1, 0xfd85, 0xffde, 0x0282, 0x04d3 }, 16, 0x00086388, 1},
+ {{0x0639, 0x0642, 0x04c5, 0x01f2, 0xfe53, 0xfaaf, 0xf7ea, 0xf6ca, 0xf7ca, 0xfaf0, 0xffbf, 0x0545, 0x0a44, 0x0d72, 0x0dc2, 0x0ab0 }, 16, 0x000863a8, 1},
+ {{0x046a, 0xfbe7, 0xf2c8, 0xeb22, 0xe71a, 0xe880, 0xf06c, 0xfef5, 0x1316, 0x2ac2, 0x4329, 0x5928, 0x69c8, 0x72b9, 0x72b9, 0x69c8 }, 16, 0x000863c8, 1},
+ {{0x5928, 0x4329, 0x2ac2, 0x1316, 0xfef5, 0xf06c, 0xe880, 0xe71a, 0xeb22, 0xf2c8, 0xfbe7, 0x046a, 0x0ab0, 0x0dc2, 0x0d72, 0x0a44 }, 16, 0x000863e8, 1},
+ {{0x0545, 0xffbf, 0xfaf0, 0xf7ca, 0xf6ca, 0xf7ea, 0xfaaf, 0xfe53, 0x01f2, 0x04c5, 0x0642, 0x0639, 0x04d3, 0x0282, 0xffde, 0xfd85 }, 16, 0x00086408, 1},
+ {{0xfbf1, 0xfb6a, 0xfbf1, 0xfd4f, 0xff22, 0x00f8, 0x026a, 0x0330, 0x0330, 0x027d, 0x0151, 0xfff9, 0xfec6, 0xfdf6, 0xfdad, 0xfded }, 16, 0x00086428, 1},
+ {{0xfe9a, 0xff83, 0x006e, 0x0129, 0x018f, 0x0194, 0x0141, 0x00b2, 0x000d, 0xff78, 0xff11, 0xfeea, 0xff03, 0xff4f, 0xffb7, 0x0023 }, 16, 0x00086448, 1},
+ {{0x0079, 0x00ac, 0x00b4, 0x0095, 0x005c, 0x0017, 0xffd8, 0xffaa, 0xff96, 0xff9b, 0xffb6, 0xffde, 0x000a, 0x002f, 0x0049, 0x0054 }, 16, 0x00086468, 1},
+ {{0x0051, 0x0043, 0x002e, 0x0018, 0x0005, 0xfff7, 0xfff0, 0xffee, 0xfff0, 0xfff4, 0xfff8, 0xffff, 0x0000, 0x0001, 0xffed, 0xffe1 }, 16, 0x00086488, 1},
+ {{0xffce, 0xffb9, 0xffa5, 0xff96, 0xff92, 0xff9a, 0xffb2, 0xffd7, 0x0005, 0x0035, 0x005e, 0x0078, 0x007c, 0x0068, 0x003e, 0x0005 }, 16, 0x000864a8, 1},
+ {{0xffca, 0xff98, 0xff7e, 0xff84, 0xffaa, 0xffed, 0x003f, 0x008e, 0x00c6, 0x00d9, 0x00be, 0x0075, 0x000d, 0xff9a, 0xff36, 0xfefd }, 16, 0x000864c8, 1},
+ {{0xfefe, 0xff40, 0xffb9, 0x0052, 0x00e9, 0x015a, 0x0185, 0x015a, 0x00db, 0x001e, 0xff4b, 0xfe93, 0xfe24, 0xfe20, 0xfe92, 0xff68 }, 16, 0x000864e8, 1},
+ {{0x0079, 0x0189, 0x0254, 0x02a6, 0x025e, 0x0180, 0x0033, 0xfebf, 0xfd78, 0xfcb2, 0xfca8, 0xfd6f, 0xfeea, 0x00ce, 0x02b1, 0x041e }, 16, 0x00086508, 1},
+ {{0x04b1, 0x0432, 0x02a3, 0x0048, 0xfd9f, 0xfb43, 0xf9cf, 0xf9b7, 0xfb29, 0xfdfb, 0x01a8, 0x0569, 0x0858, 0x09a1, 0x08b7, 0x057c }, 16, 0x00086528, 1},
+ {{0x0057, 0xfa31, 0xf456, 0xf03e, 0xef49, 0xf279, 0xfa35, 0x062b, 0x1549, 0x25e1, 0x35e5, 0x4339, 0x4c0c, 0x4f21, 0x4c0c, 0x4339 }, 16, 0x00086548, 1},
+ {{0x35e5, 0x25e1, 0x1549, 0x062b, 0xfa35, 0xf279, 0xef49, 0xf03e, 0xf456, 0xfa31, 0x0057, 0x057c, 0x08b7, 0x09a1, 0x0858, 0x0569 }, 16, 0x00086568, 1},
+ {{0x01a8, 0xfdfb, 0xfb29, 0xf9b7, 0xf9cf, 0xfb43, 0xfd9f, 0x0048, 0x02a3, 0x0432, 0x04b1, 0x041e, 0x02b1, 0x00ce, 0xfeea, 0xfd6f }, 16, 0x00086588, 1},
+ {{0xfca8, 0xfcb2, 0xfd78, 0xfebf, 0x0033, 0x0180, 0x025e, 0x02a6, 0x0254, 0x0189, 0x0079, 0xff68, 0xfe92, 0xfe20, 0xfe24, 0xfe93 }, 16, 0x000865a8, 1},
+ {{0xff4b, 0x001e, 0x00db, 0x015a, 0x0185, 0x015a, 0x00e9, 0x0052, 0xffb9, 0xff40, 0xfefe, 0xfefd, 0xff36, 0xff9a, 0x000d, 0x0075 }, 16, 0x000865c8, 1},
+ {{0x00be, 0x00d9, 0x00c6, 0x008e, 0x003f, 0xffed, 0xffaa, 0xff84, 0xff7e, 0xff98, 0xffca, 0x0005, 0x003e, 0x0068, 0x007c, 0x0078 }, 16, 0x000865e8, 1},
+ {{0x005e, 0x0035, 0x0005, 0xffd7, 0xffb2, 0xff9a, 0xff92, 0xff96, 0xffa5, 0xffb9, 0xffce, 0xffe1, 0xffed, 0x0000, 0xff64, 0xe39e }, 16, 0x00086608, 1},
+ {{0xcadd, 0xb4ce, 0xa124, 0x8f9e, 0x8000, 0x7214, 0x65ac, 0x5a9d, 0x50c3, 0x47fa, 0x4026, 0x392c, 0x32f5, 0x2d6a, 0x287a, 0x2413 }, 16, 0x00086628, 1},
+ {{0x2026, 0x1ca7, 0x198a, 0x16c3, 0x1449, 0x1214, 0x101d, 0x0e5c, 0x0ccc, 0x0b68, 0x0a2a, 0x090f, 0x0813, 0x0732, 0x066a, 0x05b7 }, 16, 0x00086648, 1},
+ {{0x0518, 0x048a, 0x040c, 0x039b, 0x0337, 0x02dd, 0x028d, 0x0246, 0x0207, 0x01ce, 0x019c, 0x016f, 0x0147, 0x0124, 0x0104, 0x00e7 }, 16, 0x00086668, 1},
+ {{0x00ce, 0x00b8, 0x00a4, 0x0092, 0x0082, 0x0074, 0x0067, 0x005c, 0x0052, 0x0049, 0x0041, 0x003a, 0x0033, 0x002e, 0x0029, 0x0024 }, 16, 0x00086688, 1},
+ {{0x0020, 0x001d, 0x001a, 0x0017, 0x0014, 0x0012, 0x0010, 0x000e, 0x000d, 0x000b, 0x000a, 0x0009, 0x0008, 0x0007, 0x0006, 0x0005 }, 16, 0x000866a8, 1},
+ {{0x0005, 0x0004, 0x0004, 0x0003, 0x0003, 0x0002, 0x0002, 0x0002, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0xffef }, 16, 0x000866c8, 1},
+ {{0xffc8, 0xff9d, 0xff85, 0xffa3, 0xfff4, 0x004d, 0x006c, 0x002e, 0xffba, 0xff6f, 0xff9b, 0x0031, 0x00b9, 0x00b1, 0x0000, 0xff29 }, 16, 0x000866e8, 1},
+ {{0xfef1, 0xffad, 0x00de, 0x017a, 0x00d0, 0xff40, 0xfe19, 0xfe86, 0x006e, 0x024a, 0x0254, 0x002a, 0xfd6e, 0xfc9e, 0xfee0, 0x02a8 }, 16, 0x00086708, 1},
+ {{0x04a9, 0x029a, 0xfd96, 0xf9c6, 0xfb20, 0x019f, 0x084f, 0x08af, 0x004f, 0xf44e, 0xef41, 0xfa2c, 0x1540, 0x35dd, 0x4c04, 0x4c04 }, 16, 0x00086728, 1},
+ {{0x35dd, 0x1540, 0xfa2c, 0xef41, 0xf44e, 0x004f, 0x08af, 0x084f, 0x019f, 0xfb20, 0xf9c6, 0xfd96, 0x029a, 0x04a9, 0x02a8, 0xfee0 }, 16, 0x00086748, 1},
+ {{0xfc9e, 0xfd6e, 0x002a, 0x0254, 0x024a, 0x006e, 0xfe86, 0xfe19, 0xff40, 0x00d0, 0x017a, 0x00de, 0xffad, 0xfef1, 0xff29, 0x0000 }, 16, 0x00086768, 1},
+ {{0x00b1, 0x00b9, 0x0031, 0xff9b, 0xff6f, 0xffba, 0x002e, 0x006c, 0x004d, 0xfff4, 0xffa3, 0xff85, 0xff9d, 0xffc8, 0xffef, 0xffef }, 16, 0x00086788, 1},
+ {{0xffbe, 0xff84, 0xff5d, 0xff7c, 0xffe4, 0x0060, 0x0096, 0x004c, 0xffad, 0xff39, 0xff66, 0x0030, 0x00fb, 0x0106, 0x001a, 0xfee2 }, 16, 0x000867a8, 1},
+ {{0xfe76, 0xff6b, 0x0120, 0x021d, 0x0149, 0xff12, 0xfd4c, 0xfdc1, 0x0071, 0x033a, 0x0377, 0x0071, 0xfc69, 0xfb08, 0xfe25, 0x03ac }, 16, 0x000867c8, 1},
+ {{0x06cb, 0x0402, 0xfcb7, 0xf6f4, 0xf8b0, 0x0219, 0x0c0a, 0x0cdb, 0x00be, 0xef0b, 0xe75e, 0xf72d, 0x1eec, 0x4efc, 0x6fb0, 0x6fb0 }, 16, 0x000867e8, 1},
+ {{0x4efc, 0x1eec, 0xf72d, 0xe75e, 0xef0b, 0x00be, 0x0cdb, 0x0c0a, 0x0219, 0xf8b0, 0xf6f4, 0xfcb7, 0x0402, 0x06cb, 0x03ac, 0xfe25 }, 16, 0x00086808, 1},
+ {{0xfb08, 0xfc69, 0x0071, 0x0377, 0x033a, 0x0071, 0xfdc1, 0xfd4c, 0xff12, 0x0149, 0x021d, 0x0120, 0xff6b, 0xfe76, 0xfee2, 0x001a }, 16, 0x00086828, 1},
+ {{0x0106, 0x00fb, 0x0030, 0xff66, 0xff39, 0xffad, 0x004c, 0x0096, 0x0060, 0xffe4, 0xff7c, 0xff5d, 0xff84, 0xffbe, 0xffef, 0xffda }, 16, 0x00086848, 1},
+ {{0xff78, 0xff4b, 0xffcc, 0x008c, 0x0067, 0xff6f, 0xff46, 0x0087, 0x0126, 0xffa8, 0xfe5c, 0xfff4, 0x0225, 0x00b1, 0xfd66, 0xfe5c }, 16, 0x00086868, 1},
+ {{0x02e9, 0x02f0, 0xfd08, 0xfb5d, 0x029d, 0x06d2, 0xfe5f, 0xf64e, 0xff95, 0x0dcd, 0x049b, 0xeaeb, 0xf09d, 0x2c3c, 0x6c63, 0x6c63 }, 16, 0x00086888, 1},
+ {{0x2c3c, 0xf09d, 0xeaeb, 0x049b, 0x0dcd, 0xff95, 0xf64e, 0xfe5f, 0x06d2, 0x029d, 0xfb5d, 0xfd08, 0x02f0, 0x02e9, 0xfe5c, 0xfd66 }, 16, 0x000868a8, 1},
+ {{0x00b1, 0x0225, 0xfff4, 0xfe5c, 0xffa8, 0x0126, 0x0087, 0xff46, 0xff6f, 0x0067, 0x008c, 0xffcc, 0xff4b, 0xff78, 0xffda, 0x0080 }, 16, 0x000868c8, 1},
+ {{0xfe65, 0xff40, 0x00b3, 0x0135, 0x00f4, 0x0024, 0xff43, 0xfeb5, 0xfed5, 0xff9f, 0x00be, 0x019f, 0x01b8, 0x00d8, 0xff53, 0xfde8 }, 16, 0x000868e8, 1},
+ {{0xfd6e, 0xfe5a, 0x006e, 0x02b8, 0x03f2, 0x0326, 0x0042, 0xfc5b, 0xf95e, 0xf957, 0xfd82, 0x0599, 0x0fc2, 0x1911, 0x1e9f, 0x1e9f }, 16, 0x00086908, 1},
+ {{0x1911, 0x0fc2, 0x0599, 0xfd82, 0xf957, 0xf95e, 0xfc5b, 0x0042, 0x0326, 0x03f2, 0x02b8, 0x006e, 0xfe5a, 0xfd6e, 0xfde8, 0xff53 }, 16, 0x00086928, 1},
+ {{0x00d8, 0x01b8, 0x019f, 0x00be, 0xff9f, 0xfed5, 0xfeb5, 0xff43, 0x0024, 0x00f4, 0x0135, 0x00b3, 0xff40, 0xfe65, 0x0080, 0xfffe }, 16, 0x00086948, 1},
+ {{0x0019, 0xffea, 0xffe3, 0x001b, 0x0037, 0xffde, 0xffa0, 0x001f, 0x009a, 0xfff8, 0xff1c, 0xffd3, 0x013a, 0x0090, 0xfe71, 0xfed0 }, 16, 0x00086968, 1},
+ {{0x01d2, 0x021a, 0xfe1a, 0xfca4, 0x01a4, 0x0507, 0xff31, 0xf8cd, 0xfef9, 0x0a1d, 0x04f4, 0xf19e, 0xf0fe, 0x152b, 0x3e82, 0x3e82 }, 16, 0x00086988, 1},
+ {{0x152b, 0xf0fe, 0xf19e, 0x04f4, 0x0a1d, 0xfef9, 0xf8cd, 0xff31, 0x0507, 0x01a4, 0xfca4, 0xfe1a, 0x021a, 0x01d2, 0xfed0, 0xfe71 }, 16, 0x000869a8, 1},
+ {{0x0090, 0x013a, 0xffd3, 0xff1c, 0xfff8, 0x009a, 0x001f, 0xffa0, 0xffde, 0x0037, 0x001b, 0xffe3, 0xffea, 0x0019, 0xfffe, 0x0000 }, 16, 0x000869c8, 1},
+ {{0x0000, 0x0000, 0x0400, 0x04c1, 0x05a6, 0x06b7, 0x0008, 0x0000, 0x0400, 0x042d, 0x045c, 0x048d, 0x04c1, 0x04f7, 0x0531, 0x0569 }, 16, 0x000869e8, 1},
+ {{0x7fff, 0xa000, 0x7fff, 0xa100, 0x7fff, 0xa200, 0x0200, 0x0000, 0x0400, 0x0000, 0x0800, 0x0000, 0x1c1d, 0x1e34, 0x3638, 0x0000 }, 16, 0x00086a08, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x4000, 0x2aab, 0x2000, 0x199a, 0x1555, 0x1249, 0x1000, 0x0e39, 0x0ccd, 0x0ba3, 0x0aab }, 16, 0x00086a28, 1},
+ {{0x09d9, 0x0925, 0x0889, 0x0800, 0x0000, 0x0002, 0x0000, 0x0002, 0x0000, 0x0002, 0x0000, 0x0002, 0x0000, 0x0002, 0x0000, 0x0002 }, 16, 0x00086a48, 1},
+ {{0x0000, 0x0002, 0x0000, 0x0003, 0x0000, 0x0003, 0x0000, 0x0003, 0x0000, 0x0004, 0x0000, 0x0004, 0x0000, 0x0005, 0x0000, 0x0006 }, 16, 0x00086a68, 1},
+ {{0x0000, 0x0007, 0x0000, 0x0007, 0x0000, 0x0008, 0x0000, 0x0009, 0x0000, 0x000b, 0x0000, 0x000c, 0x0000, 0x000f, 0x0000, 0x0012 }, 16, 0x00086a88, 1},
+ {{0x0022, 0x1140, 0x7fff, 0x2bcc, 0x061d, 0x00ac, 0x0011, 0x0001, 0x0ccd, 0x3333, 0x7fff, 0x3333, 0x0ccd, 0x0000, 0x000a, 0xa8ae }, 16, 0x00086aa8, 1},
+ {{0x000a, 0xa8ae, 0x000a, 0x8d42, 0x000a, 0xa67c, 0x000a, 0xa68c, 0x000a, 0x99ba, 0x000a, 0x9922, 0x000a, 0x98e6, 0x0000, 0x0000 }, 16, 0x00086ac8, 1},
+ {{0x0005, 0x0014, 0x002c, 0x004f, 0x007b, 0x00b1, 0x00f1, 0x013b, 0x018e, 0x01eb, 0x0251, 0x02c1, 0x033b, 0x03be, 0x044a, 0x04df }, 16, 0x00086ae8, 1},
+ {{0x057e, 0x0625, 0x06d5, 0x078f, 0x0850, 0x091b, 0x09ee, 0x0ac9, 0x0bad, 0x0c98, 0x0d8c, 0x0e87, 0x0f8a, 0x1094, 0x11a6, 0x12bf }, 16, 0x00086b08, 1},
+ {{0x13de, 0x1505, 0x1632, 0x1766, 0x18a0, 0x19e0, 0x1b26, 0x1c71, 0x1dc2, 0x1f19, 0x2074, 0x21d5, 0x2339, 0x24a3, 0x2610, 0x2782 }, 16, 0x00086b28, 1},
+ {{0x28f7, 0x2a70, 0x2bec, 0x2d6c, 0x2eee, 0x3073, 0x31fa, 0x3383, 0x350f, 0x369c, 0x382a, 0x39ba, 0x3b4a, 0x3cdc, 0x3e6e, 0x4000 }, 16, 0x00086b48, 1},
+ {{0x4192, 0x4324, 0x44b5, 0x4646, 0x47d5, 0x4964, 0x4af1, 0x4c7c, 0x4e05, 0x4f8d, 0x5112, 0x5294, 0x5413, 0x558f, 0x5708, 0x587e }, 16, 0x00086b68, 1},
+ {{0x59ef, 0x5b5d, 0x5cc6, 0x5e2b, 0x5f8b, 0x60e7, 0x623d, 0x638e, 0x64da, 0x6620, 0x6760, 0x6899, 0x69cd, 0x6afa, 0x6c21, 0x6d41 }, 16, 0x00086b88, 1},
+ {{0x6e5a, 0x6f6b, 0x7076, 0x7179, 0x7274, 0x7367, 0x7453, 0x7536, 0x7612, 0x76e5, 0x77af, 0x7871, 0x792a, 0x79da, 0x7a82, 0x7b20 }, 16, 0x00086ba8, 1},
+ {{0x7bb6, 0x7c42, 0x7cc5, 0x7d3e, 0x7dae, 0x7e14, 0x7e71, 0x7ec5, 0x7f0e, 0x7f4e, 0x7f84, 0x7fb1, 0x7fd3, 0x7fec, 0x7ffb, 0x7fff }, 16, 0x00086bc8, 1},
+ {{0x7ffb, 0x7fec, 0x7fd3, 0x7fb1, 0x7f84, 0x7f4e, 0x7f0e, 0x7ec5, 0x7e71, 0x7e14, 0x7dae, 0x7d3e, 0x7cc5, 0x7c42, 0x7bb6, 0x7b20 }, 16, 0x00086be8, 1},
+ {{0x7a82, 0x79da, 0x792a, 0x7871, 0x77af, 0x76e5, 0x7612, 0x7536, 0x7453, 0x7367, 0x7274, 0x7179, 0x7076, 0x6f6b, 0x6e5a, 0x6d41 }, 16, 0x00086c08, 1},
+ {{0x6c21, 0x6afa, 0x69cd, 0x6899, 0x6760, 0x6620, 0x64da, 0x638e, 0x623d, 0x60e7, 0x5f8b, 0x5e2b, 0x5cc6, 0x5b5d, 0x59ef, 0x587e }, 16, 0x00086c28, 1},
+ {{0x5708, 0x558f, 0x5413, 0x5294, 0x5112, 0x4f8d, 0x4e05, 0x4c7c, 0x4af1, 0x4964, 0x47d5, 0x4646, 0x44b5, 0x4324, 0x4192, 0x4000 }, 16, 0x00086c48, 1},
+ {{0x3e6e, 0x3cdc, 0x3b4a, 0x39ba, 0x382a, 0x369c, 0x350f, 0x3383, 0x31fa, 0x3073, 0x2eee, 0x2d6c, 0x2bec, 0x2a70, 0x28f7, 0x2782 }, 16, 0x00086c68, 1},
+ {{0x2610, 0x24a3, 0x2339, 0x21d5, 0x2074, 0x1f19, 0x1dc2, 0x1c71, 0x1b26, 0x19e0, 0x18a0, 0x1766, 0x1632, 0x1505, 0x13de, 0x12bf }, 16, 0x00086c88, 1},
+ {{0x11a6, 0x1094, 0x0f8a, 0x0e87, 0x0d8c, 0x0c98, 0x0bad, 0x0ac9, 0x09ee, 0x091b, 0x0850, 0x078f, 0x06d5, 0x0625, 0x057e, 0x04df }, 16, 0x00086ca8, 1},
+ {{0x044a, 0x03be, 0x033b, 0x02c1, 0x0251, 0x01eb, 0x018e, 0x013b, 0x00f1, 0x00b1, 0x007b, 0x004f, 0x002c, 0x0014, 0x0005, 0x0000 }, 16, 0x00086cc8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0009, 0x4474, 0x7fff, 0x042a, 0x015b, 0x00b1, 0x006b, 0x0046, 0x0030, 0x0021, 0x0017, 0x0010 }, 16, 0x00086ce8, 1},
+ {{0x000d, 0x000b, 0x0008, 0x0005, 0x0004, 0x0004, 0x0006, 0x000c, 0x0029, 0x0047, 0x0058, 0x0077, 0x60a9, 0x44e1, 0x38ac, 0x3175 }, 16, 0x00086d08, 1},
+ {{0x2c92, 0x28fe, 0x263c, 0x2408, 0x2238, 0x20b3, 0x1f67, 0x1e48, 0x1d4d, 0x1c6f, 0x1baa, 0x1af8, 0x1a59, 0x19c8, 0x1943, 0x18ca }, 16, 0x00086d28, 1},
+ {{0x185b, 0x17f4, 0x1795, 0x173c, 0x16ea, 0x169e, 0x1656, 0x1613, 0x15d4, 0x1598, 0x1560, 0x152b, 0x152b, 0x12f8, 0x11db, 0x1137 }, 16, 0x00086d48, 1},
+ {{0x10d2, 0x1091, 0x1066, 0x1048, 0x1033, 0x1025, 0x101b, 0x0000, 0x0000, 0x0000, 0x0009, 0x82ac, 0x0009, 0x82c4, 0x0009, 0x82a0 }, 16, 0x00086d68, 1},
+ {{0x0009, 0x82b8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0010, 0x0020, 0x0010, 0x0000, 0x0013, 0x4000, 0x0a00, 0x4001 }, 16, 0x00086d88, 1},
+ {{0x0320, 0x0000, 0x0000, 0x0000, 0x0026, 0x1a00, 0x0800, 0x0400, 0x0000, 0x0000, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x0280, 0x2008 }, 16, 0x00086da8, 1},
+ {{0x0002, 0x01f0, 0x0078, 0x0032, 0x0004, 0x01f0, 0x0078, 0x0032, 0x000f, 0x5004, 0x0004, 0x0000, 0x01aa, 0x0000, 0x7800, 0x000f }, 16, 0x00086dc8, 1},
+ {{0x003c, 0x4801, 0x08a1, 0x0040, 0x8230, 0x001f, 0x7801, 0x000f, 0x003c, 0x2801, 0x08a1, 0x0040, 0xa000, 0x001f, 0x0080, 0x0002 }, 16, 0x00086de8, 1},
+ {{0x0064, 0x000f, 0x3333, 0x7fbe, 0x3333, 0x7eb8, 0x7fff, 0x0001, 0x7fdf, 0x0002, 0x7333, 0x7333, 0x0019, 0x0001, 0x6666, 0x0001 }, 16, 0x00086e08, 1},
+ {{0x6666, 0x0400, 0x4026, 0x7213, 0x0080, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6000, 0x0000, 0x4000, 0x0000, 0x0000 }, 16, 0x00086e28, 1},
+ {{0x880c, 0xa008, 0x0109, 0x7593, 0x7f00, 0x0000, 0x7fff, 0x0000, 0x0000, 0x087a, 0x0006, 0x0096, 0x0002, 0x0a1f, 0x3040, 0x0000 }, 16, 0x00086e48, 1},
+ {{0x7800, 0x0ccc, 0x0000, 0x0000, 0x0340, 0x0000, 0x0000, 0x1410, 0x0000, 0x0010, 0x0000, 0x0600, 0x3344, 0x1122, 0x0000, 0x0000 }, 16, 0x00086e68, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0005, 0x0000, 0x0600, 0x0200, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086e88, 1},
+ {{0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086ea8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086ec8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086ee8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086f08, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086f28, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086f48, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086f68, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086f88, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086fa8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086fc8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00086fe8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087008, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087028, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087048, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087068, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087088, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000870a8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000870c8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000870e8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087108, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087128, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087148, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087168, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087188, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000871a8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000871c8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000871e8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087208, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087228, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087248, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087268, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087288, 1},
+ {{0x0000, 0x0000, 0x0400, 0x0320, 0x0033, 0x0000, 0x0b27, 0x1358, 0x0c52, 0x1560, 0x0da2, 0x17a2, 0x0f0e, 0x1a21, 0x123d, 0x170a }, 16, 0x000872a8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0190, 0x0190, 0x0009, 0xbbc8, 0x8000, 0x5a82, 0x49e7, 0x4000, 0x393e, 0x3441 }, 16, 0x000872c8, 1},
+ {{0x3061, 0x2d41, 0x2aab, 0x287a, 0x2698, 0x24f3, 0x2380, 0x2236, 0x210d, 0x2000, 0x7fff, 0xffff, 0x2311, 0x8963, 0x0000, 0x0001 }, 16, 0x000872e8, 1},
+ {{0x9678, 0x5429, 0x0010, 0x0000, 0x7fff, 0x4000, 0x2aab, 0x2000, 0x199a, 0x1555, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087308, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006, 0xffea, 0xffea, 0x006a, 0x0018, 0xfec8, 0x0040, 0x02d4, 0xfe5c, 0xf9b6 }, 16, 0x00087328, 1},
+ {{0x076e, 0x1e48, 0x1e48, 0x076e, 0xf9b6, 0xfe5c, 0x02d4, 0x0040, 0xfec8, 0x0018, 0x006a, 0xffea, 0xffea, 0x0006, 0x000b, 0x0630 }, 16, 0x00087348, 1},
+ {{0x000b, 0x0630, 0x000b, 0x0668, 0x000b, 0x06b4, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001 }, 16, 0x00087368, 1},
+ {{0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002 }, 16, 0x00087388, 1},
+ {{0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003 }, 16, 0x000873a8, 1},
+ {{0x0003, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005 }, 16, 0x000873c8, 1},
+ {{0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0008, 0x0008, 0x0008, 0x0008 }, 16, 0x000873e8, 1},
+ {{0x0008, 0x0009, 0x0009, 0x0009, 0x0009, 0x000a, 0x000a, 0x000a, 0x000a, 0x000b, 0x000b, 0x000b, 0x000b, 0x000c, 0x000c, 0x000c }, 16, 0x00087408, 1},
+ {{0x000d, 0x000d, 0x000d, 0x000d, 0x000e, 0x000e, 0x000f, 0x000f, 0x000f, 0x0010, 0x0010, 0x0010, 0x0011, 0x0011, 0x0012, 0x0012 }, 16, 0x00087428, 1},
+ {{0x0012, 0x0013, 0x0013, 0x0014, 0x0014, 0x0015, 0x0015, 0x0016, 0x0016, 0x0017, 0x0017, 0x0018, 0x0018, 0x0019, 0x0019, 0x001a }, 16, 0x00087448, 1},
+ {{0x001b, 0x001b, 0x001c, 0x001c, 0x001d, 0x001e, 0x001f, 0x001f, 0x0020, 0x0021, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0025 }, 16, 0x00087468, 1},
+ {{0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0036 }, 16, 0x00087488, 1},
+ {{0x0037, 0x0038, 0x0039, 0x003a, 0x003c, 0x003d, 0x003f, 0x0040, 0x0041, 0x0043, 0x0044, 0x0046, 0x0047, 0x0049, 0x004b, 0x004c }, 16, 0x000874a8, 1},
+ {{0x004e, 0x0050, 0x0052, 0x0053, 0x0055, 0x0057, 0x0059, 0x005b, 0x005d, 0x005f, 0x0061, 0x0063, 0x0066, 0x0068, 0x006a, 0x006d }, 16, 0x000874c8, 1},
+ {{0x006f, 0x0071, 0x0074, 0x0076, 0x0079, 0x007c, 0x007f, 0x0081, 0x0084, 0x0087, 0x008a, 0x008d, 0x0090, 0x0093, 0x0097, 0x009a }, 16, 0x000874e8, 1},
+ {{0x009d, 0x00a1, 0x00a5, 0x00a8, 0x00ac, 0x00b0, 0x00b4, 0x00b8, 0x00bc, 0x00c0, 0x00c4, 0x00c8, 0x00cd, 0x00d1, 0x00d6, 0x00db }, 16, 0x00087508, 1},
+ {{0x00df, 0x00e4, 0x00e9, 0x00ee, 0x00f4, 0x00f9, 0x00ff, 0x0104, 0x010a, 0x0110, 0x0116, 0x011c, 0x0122, 0x0128, 0x012f, 0x0136 }, 16, 0x00087528, 1},
+ {{0x013c, 0x0143, 0x014b, 0x0152, 0x0159, 0x0161, 0x0169, 0x0171, 0x0179, 0x0181, 0x0189, 0x0192, 0x019b, 0x01a4, 0x01ad, 0x01b7 }, 16, 0x00087548, 1},
+ {{0x01c0, 0x01ca, 0x01d4, 0x01de, 0x01e9, 0x01f4, 0x01ff, 0x020a, 0x0215, 0x0221, 0x022d, 0x0239, 0x0246, 0x0252, 0x025f, 0x026d }, 16, 0x00087568, 1},
+ {{0x027a, 0x0288, 0x0297, 0x02a5, 0x02b4, 0x02c3, 0x02d3, 0x02e3, 0x02f3, 0x0303, 0x0314, 0x0326, 0x0337, 0x0349, 0x035c, 0x036f }, 16, 0x00087588, 1},
+ {{0x0382, 0x0396, 0x03aa, 0x03be, 0x03d3, 0x03e9, 0x03ff, 0x0415, 0x042c, 0x0444, 0x045b, 0x0474, 0x048d, 0x04a6, 0x04c0, 0x04db }, 16, 0x000875a8, 1},
+ {{0x04f6, 0x0512, 0x052f, 0x054c, 0x056a, 0x0588, 0x05a7, 0x05c7, 0x05e7, 0x0608, 0x062a, 0x064d, 0x0670, 0x0694, 0x06b9, 0x06df }, 16, 0x000875c8, 1},
+ {{0x0705, 0x072d, 0x0755, 0x077e, 0x07a8, 0x07d3, 0x07ff, 0x082c, 0x085a, 0x0889, 0x08b8, 0x08e9, 0x091b, 0x094e, 0x0982, 0x09b8 }, 16, 0x000875e8, 1},
+ {{0x09ee, 0x0a26, 0x0a5f, 0x0a99, 0x0ad5, 0x0b11, 0x0b4f, 0x0b8f, 0x0bd0, 0x0c12, 0x0c55, 0x0c9b, 0x0ce1, 0x0d2a, 0x0d73, 0x0dbf }, 16, 0x00087608, 1},
+ {{0x0e0c, 0x0e5b, 0x0eab, 0x0efd, 0x0f51, 0x0fa7, 0x0fff, 0x0000, 0x003f, 0x003e, 0x001f, 0x001e, 0x001d, 0x001c, 0x001b, 0x001a }, 16, 0x00087628, 1},
+ {{0x0019, 0x0018, 0x0017, 0x0016, 0x0015, 0x0014, 0x0013, 0x0012, 0x0011, 0x0010, 0x000f, 0x000e, 0x000d, 0x000c, 0x000b, 0x000a }, 16, 0x00087648, 1},
+ {{0x0009, 0x0008, 0x0007, 0x0006, 0x0005, 0x0004, 0x0000, 0x0000, 0x003d, 0x003c, 0x003b, 0x003a, 0x0039, 0x0038, 0x0037, 0x0036 }, 16, 0x00087668, 1},
+ {{0x0035, 0x0034, 0x0033, 0x0032, 0x0031, 0x0030, 0x002f, 0x002e, 0x002d, 0x002c, 0x002b, 0x002a, 0x0029, 0x0028, 0x0027, 0x0026 }, 16, 0x00087688, 1},
+ {{0x0025, 0x0024, 0x0023, 0x0022, 0x0021, 0x0020, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x001e, 0x001d, 0x001c, 0x001b, 0x001a }, 16, 0x000876a8, 1},
+ {{0x0019, 0x0018, 0x0017, 0x0016, 0x0015, 0x0014, 0x0013, 0x0012, 0x0011, 0x0010, 0x000f, 0x000e, 0x000d, 0x000c, 0x000b, 0x000a }, 16, 0x000876c8, 1},
+ {{0x0009, 0x0008, 0x0007, 0x0006, 0x0005, 0x0004, 0x0003, 0x001e, 0x001d, 0x001c, 0x001b, 0x001a, 0x0019, 0x0018, 0x0017, 0x0016 }, 16, 0x000876e8, 1},
+ {{0x0015, 0x0014, 0x0013, 0x0012, 0x0011, 0x0010, 0x000f, 0x000e, 0x000d, 0x000c, 0x000b, 0x000a, 0x0009, 0x0008, 0x0007, 0x0006 }, 16, 0x00087708, 1},
+ {{0x0005, 0x0004, 0x0003, 0x0002, 0x0001, 0x0002, 0x0001, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff }, 16, 0x00087728, 1},
+ {{0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff }, 16, 0x00087748, 1},
+ {{0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087768, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087788, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff }, 16, 0x000877a8, 1},
+ {{0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000877c8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0001, 0x0001, 0x000f, 0x000e, 0x000d, 0x000c, 0x000b, 0x000a, 0x0009 }, 16, 0x000877e8, 1},
+ {{0x0008, 0x0007, 0x0006, 0x0005, 0x0004, 0x0003, 0x0002, 0x000f, 0x000e, 0x000d, 0x000c, 0x000b, 0x000a, 0x0009, 0x0008, 0x0007 }, 16, 0x00087808, 1},
+ {{0x0006, 0x0005, 0x0004, 0x0003, 0x0002, 0x0001, 0x0001, 0x0000, 0x0011, 0x0036, 0x005b, 0x0082, 0x00aa, 0x00d3, 0x00fe, 0x012c }, 16, 0x00087828, 1},
+ {{0x015b, 0x018c, 0x01bf, 0x01f5, 0x022e, 0x026a, 0x02aa, 0x02ee, 0x0336, 0x0383, 0x03d6, 0x0430, 0x0492, 0x04ff, 0x0577, 0x05ff }, 16, 0x00087848, 1},
+ {{0x0699, 0x0751, 0x0828, 0x0948, 0x0ab2, 0x0c1d, 0x0000, 0x0023, 0x0048, 0x006e, 0x0096, 0x00be, 0x00e9, 0x0114, 0x0143, 0x0172 }, 16, 0x00087868, 1},
+ {{0x01a6, 0x01d9, 0x0212, 0x024b, 0x028a, 0x02ca, 0x0312, 0x035a, 0x03ac, 0x03ff, 0x0461, 0x04c3, 0x053b, 0x05b2, 0x064c, 0x06e5 }, 16, 0x00087888, 1},
+ {{0x07bc, 0x0893, 0x09fd, 0x0b67, 0x0c80, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0x0000, 0x0000 }, 16, 0x000878a8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0007, 0x0006, 0x0005, 0x0004, 0x0003, 0x0002, 0x0001, 0x0007, 0x0006, 0x0005 }, 16, 0x000878c8, 1},
+ {{0x0004, 0x0003, 0x0002, 0x0001, 0x0000, 0x0000, 0x0023, 0x006e, 0x00be, 0x0114, 0x0172, 0x01d9, 0x024b, 0x02ca, 0x035a, 0x03ff }, 16, 0x000878e8, 1},
+ {{0x04c3, 0x05b2, 0x06e5, 0x0893, 0x0b67, 0x0000, 0x0007, 0x0006, 0x0005, 0x0004, 0x0003, 0x0002, 0x0001, 0x0007, 0x0006, 0x0005 }, 16, 0x00087908, 1},
+ {{0x0004, 0x0003, 0x0002, 0x0001, 0x0000, 0x0000, 0x0007, 0x0006, 0x0005, 0x0004, 0x0003, 0x0002, 0x0001, 0x0007, 0x0006, 0x0005 }, 16, 0x00087928, 1},
+ {{0x0004, 0x0003, 0x0002, 0x0001, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0x0000, 0x0000 }, 16, 0x00087948, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffc4, 0xffe2, 0x003a, 0x00ac, 0x014e, 0x021a, 0x04ae, 0x0be2, 0x0000, 0x0096, 0x0143 }, 16, 0x00087968, 1},
+ {{0x0212, 0x0312, 0x0461, 0x064c, 0x09fd, 0x0000, 0x0096, 0x0143, 0x0212, 0x0312, 0x0461, 0x064c, 0x09fd, 0x0000, 0x0001, 0x0000 }, 16, 0x00087988, 1},
+ {{0x0000, 0x0003, 0x0002, 0x0002, 0x0001, 0x0002, 0x0001, 0xffff, 0xffff, 0x0000, 0x0000, 0x0002, 0x0001, 0x0002, 0x0001, 0x0000 }, 16, 0x000879a8, 1},
+ {{0x00ca, 0x039e, 0x0000, 0xff2a, 0x031e, 0x0000, 0x000b, 0x11ee, 0x000b, 0x1216, 0x000b, 0x1236, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000879c8, 1},
+ {{0x000b, 0x1c1c, 0x000b, 0x1a84, 0x000b, 0x1aa2, 0x000b, 0x1ac2, 0x000b, 0x1ae2, 0x000b, 0x1b02, 0x000b, 0x1b02, 0x000b, 0x1b02 }, 16, 0x000879e8, 1},
+ {{0x000b, 0x1b02, 0x000b, 0x1b8e, 0x000b, 0x1b8e, 0x000b, 0x1b8e, 0x000b, 0x1b8e, 0x000b, 0x1c0c, 0x000b, 0x1c0c, 0x000b, 0x1c18 }, 16, 0x00087a08, 1},
+ {{0x000b, 0x1c18, 0x000b, 0x1974, 0x000b, 0x1974, 0x000b, 0x1992, 0x000b, 0x1992, 0x000b, 0x1992, 0x000b, 0x1992, 0x000b, 0x19f2 }, 16, 0x00087a28, 1},
+ {{0x000b, 0x19f2, 0x000b, 0x19f2, 0x000b, 0x19f2, 0x000b, 0x1a52, 0x000b, 0x1a52, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087a48, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0004, 0x0404, 0x0404, 0x0000, 0x0020, 0x2004, 0x0404, 0x0400, 0x0020, 0x0020, 0x0404, 0x0404, 0x0000 }, 16, 0x00087a68, 1},
+ {{0x2020, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404 }, 16, 0x00087a88, 1},
+ {{0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0000, 0x0004, 0x0404, 0x0404, 0x0000, 0x0000, 0x0404, 0x0404, 0x0400, 0x0000 }, 16, 0x00087aa8, 1},
+ {{0x0004, 0x0000, 0x1004, 0x0000, 0x0020, 0x2000, 0x0010, 0x0400, 0x0020, 0x0020, 0x0000, 0x1004, 0x0000, 0x2020, 0x0404, 0x0410 }, 16, 0x00087ac8, 1},
+ {{0x0404, 0x0000, 0x0004, 0x0020, 0x1020, 0x0000, 0x0000, 0x0420, 0x0010, 0x2000, 0x1010, 0x1010, 0x1010, 0x1010, 0x1000, 0x0000 }, 16, 0x00087ae8, 1},
+ {{0x0404, 0x0410, 0x2004, 0x0000, 0x0004, 0x0000, 0x1004, 0x0000, 0x0000, 0x0400, 0x0010, 0x0400, 0x0000, 0x0004, 0x0404, 0x0404 }, 16, 0x00087b08, 1},
+ {{0x0000, 0x0020, 0x2000, 0x0404, 0x0400, 0x0020, 0x0020, 0x0400, 0x0404, 0x0000, 0x2020, 0x0404, 0x0404, 0x0404, 0x0000, 0x0004 }, 16, 0x00087b28, 1},
+ {{0x0404, 0x0404, 0x0400, 0x0000, 0x0404, 0x0404, 0x0404, 0x0004, 0x0404, 0x0404, 0x0404, 0x0400, 0x0404, 0x0004, 0x0404, 0x0404 }, 16, 0x00087b48, 1},
+ {{0x0000, 0x0004, 0x0404, 0x0404, 0x0000, 0x0000, 0x0404, 0x0404, 0x0400, 0x0000, 0x0004, 0x0000, 0x1004, 0x0000, 0x0020, 0x2000 }, 16, 0x00087b68, 1},
+ {{0x0010, 0x0400, 0x0020, 0x0020, 0x0000, 0x1004, 0x0000, 0x2020, 0x0404, 0x0410, 0x0404, 0x0000, 0x0004, 0x0020, 0x1020, 0x0000 }, 16, 0x00087b88, 1},
+ {{0x0000, 0x0420, 0x0010, 0x2000, 0x1010, 0x1010, 0x1010, 0x1010, 0x1000, 0x0000, 0x0404, 0x0410, 0x0404, 0x0000, 0x0004, 0x0000 }, 16, 0x00087ba8, 1},
+ {{0x1004, 0x0000, 0x0000, 0x0400, 0x0010, 0x0400, 0x0000, 0x0207, 0x0000, 0x0246, 0x0000, 0x028d, 0x0000, 0x02dd, 0x0000, 0x0337 }, 16, 0x00087bc8, 1},
+ {{0x0000, 0x039b, 0x0000, 0x040c, 0x0000, 0x048a, 0x0000, 0x0518, 0x0000, 0x05b7, 0x0000, 0x066a, 0x0000, 0x0732, 0x0000, 0x0813 }, 16, 0x00087be8, 1},
+ {{0x0000, 0x090f, 0x0000, 0x0a2a, 0x0000, 0x0b68, 0x0000, 0x0ccc, 0x0000, 0x0e5c, 0x0000, 0x101d, 0x0000, 0x1214, 0x0000, 0x1449 }, 16, 0x00087c08, 1},
+ {{0x0000, 0x16c3, 0x0000, 0x198a, 0x0000, 0x1ca7, 0x0000, 0x2026, 0x0000, 0x2413, 0x0000, 0x287a, 0x0000, 0x2d6a, 0x0000, 0x32f5 }, 16, 0x00087c28, 1},
+ {{0x0000, 0x392c, 0x0000, 0x4026, 0x0000, 0x47fa, 0x0000, 0x50c3, 0x0000, 0x5a9d, 0x0000, 0x65ac, 0x0000, 0x7214, 0x0000, 0x8000 }, 16, 0x00087c48, 1},
+ {{0x0000, 0x8f9e, 0x0000, 0xa124, 0x0000, 0xb4ce, 0x0000, 0xcadd, 0x0000, 0xe39e, 0x0000, 0xff64, 0x0001, 0x1e8e, 0x0001, 0x4185 }, 16, 0x00087c68, 1},
+ {{0x0001, 0x68c0, 0x0001, 0x94c5, 0x0001, 0xc629, 0x0001, 0xfd93, 0x0002, 0x3bc1, 0x0002, 0x8185, 0x0002, 0xcfcc, 0x0003, 0x27a0 }, 16, 0x00087c88, 1},
+ {{0x0003, 0x8a2b, 0x0003, 0xf8bd, 0x0004, 0x74cd, 0x0005, 0x0000, 0x0005, 0x9c2f, 0x0006, 0x4b6c, 0x0007, 0x100c, 0x0007, 0xeca9 }, 16, 0x00087ca8, 1},
+ {{0x000b, 0x3e7a, 0x000b, 0x3ef0, 0x000b, 0x3f7a, 0x000b, 0x4010, 0x000b, 0x408e, 0x000b, 0x410a, 0x000b, 0x4220, 0x000b, 0x45f8 }, 16, 0x00087cc8, 1},
+ {{0x000b, 0x49dc, 0x000b, 0x4a3e, 0x00aa, 0xaaab, 0x0066, 0x6666, 0x0049, 0x2492, 0x0038, 0xe38a, 0x002e, 0x8cc9, 0x0027, 0x3413 }, 16, 0x00087ce8, 1},
+ {{0x0025, 0xe225, 0x0009, 0xcc38, 0x0009, 0xcc38, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00087d08, 1},
+ {{0x002a, 0xaaaa, 0xffff, 0x49f5, 0x0000, 0x0455, 0xffff, 0xffe5, 0x0000, 0x0000, 0x0001, 0xf2ba, 0x002a, 0x8240, 0x0000, 0x0418 }, 16, 0x00087d28, 1},
+ {{0x0006, 0x6666, 0x0000, 0x0000, 0xb000, 0x0028, 0x0003, 0x0000, 0xb000, 0x0028, 0x0003, 0x0000, 0xb100, 0x0028, 0x0004, 0x0000 }, 16, 0x00087d48, 1},
+ {{0xb200, 0x0027, 0x0004, 0x0000, 0xb300, 0x0027, 0x0005, 0x0000, 0xb400, 0x0026, 0x0005, 0x0000, 0xb500, 0x0026, 0x0006, 0x0000 }, 16, 0x00087d68, 1},
+ {{0xb600, 0x0025, 0x0007, 0x0000, 0xb700, 0x0025, 0x0008, 0x0000, 0xb800, 0x0024, 0x0009, 0x0000, 0xb900, 0x0024, 0x000a, 0x0000 }, 16, 0x00087d88, 1},
+ {{0xba00, 0x0023, 0x000b, 0x0000, 0xbb00, 0x0023, 0x000d, 0x0000, 0xbc00, 0x0022, 0x000e, 0x0000, 0xbd00, 0x0022, 0x0010, 0x0000 }, 16, 0x00087da8, 1},
+ {{0xbe00, 0x0021, 0x0012, 0x0000, 0xbf00, 0x0021, 0x0014, 0x0000, 0xc000, 0x0020, 0x0017, 0x0000, 0xc100, 0x0020, 0x001a, 0x0000 }, 16, 0x00087dc8, 1},
+ {{0xc200, 0x001f, 0x001d, 0x0000, 0xc300, 0x001f, 0x0020, 0x0000, 0xc400, 0x001e, 0x0024, 0x0000, 0xc500, 0x001e, 0x0029, 0x0000 }, 16, 0x00087de8, 1},
+ {{0xc600, 0x001d, 0x002e, 0x0000, 0xc700, 0x001d, 0x0033, 0x0000, 0xc800, 0x001c, 0x003a, 0x0000, 0xc900, 0x001c, 0x0041, 0x0000 }, 16, 0x00087e08, 1},
+ {{0xca00, 0x001b, 0x0049, 0x0000, 0xcb00, 0x001b, 0x0052, 0x0000, 0xcc00, 0x001a, 0x005c, 0x0000, 0xcd00, 0x001a, 0x0067, 0x0000 }, 16, 0x00087e28, 1},
+ {{0xce00, 0x0019, 0x0074, 0x0000, 0xcf00, 0x0019, 0x0082, 0x0000, 0xd000, 0x0018, 0x0092, 0x0000, 0xd100, 0x0018, 0x00a4, 0x0000 }, 16, 0x00087e48, 1},
+ {{0xd200, 0x0017, 0x00b8, 0x0000, 0xd300, 0x0017, 0x00ce, 0x0000, 0xd400, 0x0016, 0x00e7, 0x0000, 0xd500, 0x0016, 0x0104, 0x0000 }, 16, 0x00087e68, 1},
+ {{0xd600, 0x0015, 0x0124, 0x0000, 0xd700, 0x0015, 0x0147, 0x0000, 0xd800, 0x0014, 0x016f, 0x0000, 0xd900, 0x0014, 0x019c, 0x0000 }, 16, 0x00087e88, 1},
+ {{0xda00, 0x0013, 0x01ce, 0x0000, 0xdb00, 0x0013, 0x0207, 0x0000, 0xdc00, 0x0012, 0x0246, 0x0000, 0xdd00, 0x0012, 0x028d, 0x0000 }, 16, 0x00087ea8, 1},
+ {{0xde00, 0x0011, 0x02dd, 0x0000, 0xdf00, 0x0011, 0x0337, 0x0000, 0xe000, 0x0010, 0x039b, 0x0000, 0xe100, 0x0010, 0x040c, 0x0000 }, 16, 0x00087ec8, 1},
+ {{0xe200, 0x000f, 0x048a, 0x0000, 0xe300, 0x000f, 0x0518, 0x0000, 0xe400, 0x000e, 0x05b7, 0x0000, 0xe500, 0x000e, 0x066a, 0x0000 }, 16, 0x00087ee8, 1},
+ {{0xe600, 0x000d, 0x0732, 0x0000, 0xe700, 0x000d, 0x0813, 0x0000, 0xe800, 0x000c, 0x090f, 0x0000, 0xe900, 0x000c, 0x0a2a, 0x0000 }, 16, 0x00087f08, 1},
+ {{0xea00, 0x000b, 0x0b68, 0x0000, 0xeb00, 0x000b, 0x0ccc, 0x0000, 0xec00, 0x000a, 0x0e5c, 0x0000, 0xed00, 0x000a, 0x101d, 0x0000 }, 16, 0x00087f28, 1},
+ {{0xee00, 0x0009, 0x1214, 0x0000, 0xef00, 0x0009, 0x1449, 0x0000, 0xf000, 0x0008, 0x16c2, 0x0000, 0xf100, 0x0008, 0x1989, 0x0000 }, 16, 0x00087f48, 1},
+ {{0xf200, 0x0007, 0x1ca7, 0x0000, 0xf300, 0x0007, 0x2026, 0x0000, 0xf400, 0x0006, 0x2412, 0x0000, 0xf500, 0x0006, 0x2879, 0x0000 }, 16, 0x00087f68, 1},
+ {{0xf600, 0x0005, 0x2d6a, 0x0000, 0xf700, 0x0005, 0x32f4, 0x0000, 0xf800, 0x0004, 0x392c, 0x0000, 0xf900, 0x0004, 0x4026, 0x0000 }, 16, 0x00087f88, 1},
+ {{0xfa00, 0x0003, 0x47fa, 0x0000, 0xfb00, 0x0003, 0x50c2, 0x0000, 0xfc00, 0x0002, 0x5a9d, 0x0000, 0xfd00, 0x0002, 0x65ab, 0x0000 }, 16, 0x00087fa8, 1},
+ {{0xfe00, 0x0001, 0x7213, 0x0000, 0xff00, 0x0001, 0x7fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xb000, 0x0028, 0x0000, 0x002a }, 16, 0x00087fc8, 1},
+ {{0xb000, 0x0028, 0x0000, 0x0036, 0xb100, 0x0028, 0x0000, 0x0044, 0xb200, 0x0027, 0x0000, 0x0055, 0xb300, 0x0027, 0x0000, 0x006b }, 16, 0x00087fe8, 1},
+ {{0xb400, 0x0026, 0x0000, 0x0087, 0xb500, 0x0026, 0x0000, 0x00aa, 0xb600, 0x0025, 0x0000, 0x00d7, 0xb700, 0x0025, 0x0000, 0x010e }, 16, 0x00088008, 1},
+ {{0xb800, 0x0024, 0x0000, 0x0155, 0xb900, 0x0024, 0x0000, 0x01ad, 0xba00, 0x0023, 0x0000, 0x021c, 0xbb00, 0x0023, 0x0000, 0x02a8 }, 16, 0x00088028, 1},
+ {{0xbc00, 0x0022, 0x0000, 0x0358, 0xbd00, 0x0022, 0x0000, 0x0436, 0xbe00, 0x0021, 0x0000, 0x054e, 0xbf00, 0x0021, 0x0000, 0x06ad }, 16, 0x00088048, 1},
+ {{0xc000, 0x0020, 0x0000, 0x0868, 0xc100, 0x0020, 0x0000, 0x0a95, 0xc200, 0x001f, 0x0000, 0x0d53, 0xc300, 0x001f, 0x0000, 0x10c6 }, 16, 0x00088068, 1},
+ {{0xc400, 0x001e, 0x0000, 0x151f, 0xc500, 0x001e, 0x0000, 0x1a97, 0xc600, 0x001d, 0x0000, 0x2179, 0xc700, 0x001d, 0x0000, 0x2a24 }, 16, 0x00088088, 1},
+ {{0xc800, 0x001c, 0x0000, 0x350d, 0xc900, 0x001c, 0x0000, 0x42ca, 0xca00, 0x001b, 0x0000, 0x5415, 0xcb00, 0x001b, 0x0000, 0x69db }, 16, 0x000880a8, 1},
+ {{0xcc00, 0x001a, 0x0000, 0x8544, 0xcd00, 0x001a, 0x0000, 0xa7c5, 0xce00, 0x0019, 0x0000, 0xd336, 0xcf00, 0x0019, 0x0001, 0x09e6 }, 16, 0x000880c8, 1},
+ {{0xd000, 0x0018, 0x0001, 0x4ebf, 0xd100, 0x0018, 0x0001, 0xa56c, 0xd200, 0x0017, 0x0002, 0x128a, 0xd300, 0x0017, 0x0002, 0x9be9 }, 16, 0x000880e8, 1},
+ {{0xd400, 0x0016, 0x0003, 0x48da, 0xd500, 0x0016, 0x0004, 0x2292, 0xd600, 0x0015, 0x0005, 0x34a9, 0xd700, 0x0015, 0x0006, 0x8db8 }, 16, 0x00088108, 1},
+ {{0xd800, 0x0014, 0x0008, 0x4020, 0xd900, 0x0014, 0x000a, 0x6302, 0xda00, 0x0013, 0x000d, 0x137e, 0xdb00, 0x0013, 0x0010, 0x763f }, 16, 0x00088128, 1},
+ {{0xdc00, 0x0012, 0x0014, 0xb96b, 0xdd00, 0x0012, 0x001a, 0x1721, 0xde00, 0x0011, 0x0020, 0xd886, 0xdf00, 0x0011, 0x0029, 0x59b5 }, 16, 0x00088148, 1},
+ {{0xe000, 0x0010, 0x0034, 0x0e9d, 0xe100, 0x0010, 0x0041, 0x8937, 0xe200, 0x000f, 0x0052, 0x8143, 0xe300, 0x000f, 0x0067, 0xde18 }, 16, 0x00088168, 1},
+ {{0xe400, 0x000e, 0x0082, 0xc2f2, 0xe500, 0x000e, 0x00a4, 0x9e76, 0xe600, 0x000d, 0x00cf, 0x3e37, 0xe700, 0x000d, 0x0104, 0xe74c }, 16, 0x00088188, 1},
+ {{0xe800, 0x000c, 0x0148, 0x7543, 0xe900, 0x000c, 0x019d, 0x8113, 0xea00, 0x000b, 0x0208, 0x9229, 0xeb00, 0x000b, 0x028f, 0x5c28 }, 16, 0x000881a8, 1},
+ {{0xec00, 0x000a, 0x0339, 0x0ca2, 0xed00, 0x000a, 0x040e, 0xacf4, 0xee00, 0x0009, 0x051b, 0x9d77, 0xef00, 0x0009, 0x066e, 0x309c }, 16, 0x000881c8, 1},
+ {{0xf000, 0x0008, 0x0818, 0x6e27, 0xf100, 0x0008, 0x0a31, 0x08ff, 0xf200, 0x0007, 0x0cd4, 0x94a5, 0xf300, 0x0007, 0x1027, 0x0ac3 }, 16, 0x000881e8, 1},
+ {{0xf400, 0x0006, 0x1455, 0xb5a2, 0xf500, 0x0006, 0x1999, 0x9999, 0xf600, 0x0005, 0x203a, 0x7e5b, 0xf700, 0x0005, 0x2892, 0xc18a }, 16, 0x00088208, 1},
+ {{0xf800, 0x0004, 0x3314, 0x26ae, 0xf900, 0x0004, 0x404d, 0xe61f, 0xfa00, 0x0003, 0x50f4, 0x4d88, 0xfb00, 0x0003, 0x65ea, 0x59fd }, 16, 0x00088228, 1},
+ {{0xfc00, 0x0002, 0x804d, 0xce79, 0xfd00, 0x0002, 0xa186, 0x6ba7, 0xfe00, 0x0001, 0xcb59, 0x185d, 0xff00, 0x0001, 0xffff, 0xffff }, 16, 0x00088248, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0007, 0x0000, 0x0007, 0x0000, 0x0008, 0x0000, 0x0009, 0x0000, 0x000a, 0x0000, 0x000c, 0x0000, 0x000d }, 16, 0x00088268, 1},
+ {{0x0000, 0x000f, 0x0000, 0x0010, 0x0000, 0x0012, 0x0000, 0x0015, 0x0000, 0x0017, 0x0000, 0x001a, 0x0000, 0x001d, 0x0000, 0x0021 }, 16, 0x00088288, 1},
+ {{0x0000, 0x0025, 0x0000, 0x0029, 0x0000, 0x002e, 0x0000, 0x0034, 0x0000, 0x003a, 0x0000, 0x0042, 0x0000, 0x004a, 0x0000, 0x0053 }, 16, 0x000882a8, 1},
+ {{0x0000, 0x005d, 0x0000, 0x0068, 0x0000, 0x0075, 0x0000, 0x0083, 0x0000, 0x0093, 0x0000, 0x00a5, 0x0000, 0x00b9, 0x0000, 0x00cf }, 16, 0x000882c8, 1},
+ {{0x0000, 0x00e9, 0x0000, 0x0105, 0x0000, 0x0125, 0x0000, 0x0148, 0x0000, 0x0171, 0x0000, 0x019e, 0x0000, 0x01d0, 0x0000, 0x0209 }, 16, 0x000882e8, 1},
+ {{0x0000, 0x0248, 0x0000, 0x028f, 0x0000, 0x02df, 0x0000, 0x0339, 0x0000, 0x039e, 0x0000, 0x040f, 0x0000, 0x048d, 0x0000, 0x051c }, 16, 0x00088308, 1},
+ {{0x0000, 0x05bb, 0x0000, 0x066e, 0x0000, 0x0737, 0x0000, 0x0818, 0x0000, 0x0915, 0x0000, 0x0a31, 0x0000, 0x0b6f, 0x0000, 0x0cd5 }, 16, 0x00088328, 1},
+ {{0x0000, 0x0e65, 0x0000, 0x1027, 0x0000, 0x1220, 0x0000, 0x1456, 0x0000, 0x16d1, 0x0000, 0x199a, 0x0000, 0x1cb9, 0x0000, 0x203a }, 16, 0x00088348, 1},
+ {{0x0000, 0x2429, 0x0000, 0x2893, 0x0000, 0x2d86, 0x0000, 0x3314, 0x0000, 0x3950, 0x0000, 0x404e, 0x0000, 0x4827, 0x0000, 0x50f4 }, 16, 0x00088368, 1},
+ {{0x0000, 0x5ad5, 0x0000, 0x65ea, 0x0000, 0x725a, 0x0000, 0x804e, 0x0000, 0x8ff6, 0x0000, 0xa186, 0x0000, 0xb53c, 0x0000, 0xcb59 }, 16, 0x00088388, 1},
+ {{0x0000, 0xe429, 0x0001, 0x0000, 0x0001, 0x1f3d, 0x0001, 0x4249, 0x0001, 0x699c, 0x0001, 0x95bc, 0x0001, 0xc73d, 0x0001, 0xfeca }, 16, 0x000883a8, 1},
+ {{0x0002, 0x3d1d, 0x0002, 0x830b, 0x0002, 0xd182, 0x0003, 0x298b, 0x0003, 0x8c53, 0x0003, 0xfb28, 0x0004, 0x7783, 0x0005, 0x030a }, 16, 0x000883c8, 1},
+ {{0x0005, 0x9f98, 0x0006, 0x4f40, 0x0007, 0x1457, 0x0007, 0xf17b, 0x0008, 0xe99a, 0x000a, 0x0000, 0x000b, 0x385e, 0x000c, 0x96d9 }, 16, 0x000883e8, 1},
+ {{0x000e, 0x2019, 0x000f, 0xd954, 0x0011, 0xc865, 0x0013, 0xf3df, 0x0016, 0x6320, 0x0019, 0x1e6e, 0x001c, 0x2f0f, 0x001f, 0x9f6e }, 16, 0x00088408, 1},
+ {{0x0023, 0x7b39, 0x0027, 0xcf8b, 0x002c, 0xab1a, 0x0032, 0x1e65, 0x0038, 0x3bf0, 0x003f, 0x1882, 0x0046, 0xcb69, 0x004f, 0x6ece }, 16, 0x00088428, 1},
+ {{0x0059, 0x2006, 0x0064, 0x0000, 0x0070, 0x33ac, 0x007d, 0xe47e, 0x008d, 0x40f6, 0x009e, 0x7d44, 0x00b1, 0xd3f4, 0x00c7, 0x86b7 }, 16, 0x00088448, 1},
+ {{0x00df, 0xdf43, 0x00fb, 0x304b, 0x0119, 0xd69a, 0x013c, 0x3a4f, 0x0162, 0xd03a, 0x018e, 0x1b70, 0x01be, 0xaf00, 0x01f5, 0x2fef }, 16, 0x00088468, 1},
+ {{0x0232, 0x5761, 0x0276, 0xf515, 0x02c3, 0xf21f, 0x031a, 0x5407, 0x037b, 0x403d, 0x03e8, 0x0000, 0x002a, 0xaaaa, 0xffff, 0x49f5 }, 16, 0x00088488, 1},
+ {{0x0000, 0x0455, 0xffff, 0xffe5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0600, 0x0003 }, 16, 0x000884a8, 1},
+ {{0x1800, 0x000c, 0x1800, 0x000c, 0x0300, 0x0001, 0xb000, 0x0028, 0x3c00, 0x001e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000884c8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000884e8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088508, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088528, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088548, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088568, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088588, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000885a8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000885c8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000885e8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088608, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088628, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088648, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088668, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088688, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000886a8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000886c8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000886e8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088708, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088728, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088748, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088768, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088788, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000887a8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000887c8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000887e8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088808, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088828, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088848, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088868, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088888, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000888a8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000888c8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000888e8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088908, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088928, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088948, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088968, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088988, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000889a8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000889c8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000889e8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088a08, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088a28, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088a48, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088a68, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088a88, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088aa8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088ac8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088ae8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088b08, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088b28, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088b48, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088b68, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088b88, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088ba8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088bc8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088be8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088c08, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088c28, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088c48, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088c68, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088c88, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088ca8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088cc8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088ce8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088d08, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088d28, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088d48, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088d68, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088d88, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088da8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088dc8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088de8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088e08, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088e28, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088e48, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088e68, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088e88, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088ea8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088ec8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088ee8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088f08, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088f28, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088f48, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088f68, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088f88, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088fa8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088fc8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00088fe8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00089008, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00089028, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00089048, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00089068, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00089088, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000890a8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000890c8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000890e8, 1},
+ {{0x000b, 0x7c66, 0x000b, 0x7bf4, 0x000b, 0x7c0a, 0x000b, 0x7c50, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, 0x0700, 0x0800 }, 16, 0x00089108, 1},
+ {{0x0900, 0x0a00, 0x0b00, 0x0c00, 0x0d00, 0x0e00, 0x0f00, 0x1000, 0x1100, 0x1200, 0x1300, 0x1400, 0x1500, 0x1600, 0x1700, 0x1800 }, 16, 0x00089128, 1},
+ {{0x1900, 0x1a00, 0x1b00, 0x1c00, 0x1d00, 0x1e00, 0x1f00, 0x2000, 0x2100, 0x2200, 0x2300, 0x2400, 0x2500, 0x2600, 0x2700, 0x2800 }, 16, 0x00089148, 1},
+ {{0x2900, 0x2a00, 0x2b00, 0x2c00, 0x2d00, 0x2e00, 0x2f00, 0x3000, 0x3100, 0x3200, 0x3300, 0x3400, 0x3500, 0x3600, 0x3700, 0x3800 }, 16, 0x00089168, 1},
+ {{0x3900, 0x3a00, 0x3b00, 0x3c00, 0x3d00, 0x3e00, 0x3f00, 0x4000, 0x4100, 0x4200, 0x4300, 0x4400, 0x4500, 0x4600, 0x4700, 0x4800 }, 16, 0x00089188, 1},
+ {{0x4900, 0x4a00, 0x4b00, 0x4c00, 0x4d00, 0x4e00, 0x4f00, 0x5000, 0x5100, 0x5200, 0x5300, 0x5400, 0x5500, 0x5600, 0x5700, 0x5800 }, 16, 0x000891a8, 1},
+ {{0x5900, 0x5a00, 0x5b00, 0x5c00, 0x5d00, 0x5e00, 0x5f00, 0x6000, 0x6100, 0x6200, 0x6300, 0x6400, 0x6500, 0x6600, 0x6700, 0x6800 }, 16, 0x000891c8, 1},
+ {{0x6900, 0x6a00, 0x6b00, 0x6c00, 0x6d00, 0x6e00, 0x6f00, 0x7000, 0x7100, 0x7200, 0x7300, 0x7400, 0x7500, 0x7600, 0x7700, 0x7800 }, 16, 0x000891e8, 1},
+ {{0x7900, 0x7a00, 0x7b00, 0x7c00, 0x7d00, 0x7e00, 0x7f00, 0x7fff, 0x7fff, 0x7fff, 0x7214, 0x65ac, 0x5a9d, 0x50c3, 0x47fa, 0x4026 }, 16, 0x00089208, 1},
+ {{0x392c, 0x32f5, 0x2d6a, 0x287a, 0x2413, 0x2026, 0x1ca7, 0x198a, 0x16c3, 0x1449, 0x1214, 0x101d, 0x0e5c, 0x0ccc, 0x0b68, 0x0a2a }, 16, 0x00089228, 1},
+ {{0x090f, 0x0813, 0x0732, 0x066a, 0x05b7, 0x0518, 0x048a, 0x040c, 0x039b, 0x0337, 0x02dd, 0x028d, 0x0246, 0x0207, 0x01ce, 0x019c }, 16, 0x00089248, 1},
+ {{0x016f, 0x0147, 0x0124, 0x0104, 0x00e7, 0x00ce, 0x00b8, 0x00a4, 0x0092, 0x0082, 0x0074, 0x0067, 0x005c, 0x0052, 0x0049, 0x0041 }, 16, 0x00089268, 1},
+ {{0x003a, 0x0033, 0x002e, 0x0029, 0x0024, 0x0020, 0x0000, 0x7fff, 0x7f82, 0x7e0d, 0x7ba2, 0x7847, 0x7401, 0x6ed9, 0x68d9, 0x620d }, 16, 0x00089288, 1},
+ {{0x5a82, 0x5246, 0x496a, 0x3fff, 0x3618, 0x2bc7, 0x2121, 0x163a, 0x0b28, 0x0000, 0xf4d8, 0xe9c6, 0xdedf, 0xd439, 0xc9e8, 0xc001 }, 16, 0x000892a8, 1},
+ {{0xb696, 0xadba, 0xa57e, 0x9df3, 0x9727, 0x9127, 0x8bff, 0x87b9, 0x845e, 0x81f3, 0x807e, 0x8001, 0x0005, 0x0a0f, 0x1419, 0x1e23 }, 16, 0x000892c8, 1},
+ {{0x282d, 0x3237, 0x3c41, 0x464b, 0x5055, 0x5a5f, 0x6469, 0x6e73, 0x787d, 0x8287, 0x8c91, 0x969b, 0xa0a5, 0xaaaf, 0xb400, 0x0000 }, 16, 0x000892e8, 1},
+ {{0x0000, 0x0000, 0x7fff, 0x4000, 0x2aab, 0x2000, 0x000b, 0xab6e, 0x000b, 0xaba2, 0x000b, 0xac72, 0x000b, 0xaddc, 0x0000, 0x0000 }, 16, 0x00089308, 1},
+ {{0x0000, 0x0000, 0xffff, 0xffff, 0x0001, 0x0304, 0x0607, 0x090a, 0x0b0d, 0x0e10, 0x1112, 0x1415, 0x1618, 0x191a, 0x1c1d, 0x1e20 }, 16, 0x00089328, 1},
+ {{0x2122, 0x2425, 0x2628, 0x292a, 0x2c2d, 0x2e2f, 0x3132, 0x3334, 0x3637, 0x3839, 0x3b3c, 0x3d3e, 0x3f41, 0x4243, 0x4445, 0x4748 }, 16, 0x00089348, 1},
+ {{0x494a, 0x4b4d, 0x4e4f, 0x5051, 0x5254, 0x5556, 0x5758, 0x595a, 0x5c5d, 0x5e5f, 0x6061, 0x6263, 0x6466, 0x6768, 0x696a, 0x6b6c }, 16, 0x00089368, 1},
+ {{0x6d6e, 0x6f70, 0x7172, 0x7475, 0x7677, 0x7879, 0x7a7b, 0x7c7d, 0x7e7f, 0x8081, 0x8283, 0x8485, 0x8687, 0x8889, 0x8a8b, 0x8c8d }, 16, 0x00089388, 1},
+ {{0x8e8f, 0x9091, 0x9293, 0x9495, 0x9697, 0x9899, 0x9a9b, 0x9b9c, 0x9d9e, 0x9fa0, 0xa1a2, 0xa3a4, 0xa5a6, 0xa7a8, 0xa9a9, 0xaaab }, 16, 0x000893a8, 1},
+ {{0xacad, 0xaeaf, 0xb0b1, 0xb2b2, 0xb3b4, 0xb5b6, 0xb7b8, 0xb9b9, 0xbabb, 0xbcbd, 0xbebf, 0xc0c0, 0xc1c2, 0xc3c4, 0xc5c6, 0xc6c7 }, 16, 0x000893c8, 1},
+ {{0xc8c9, 0xcacb, 0xcbcc, 0xcdce, 0xcfd0, 0xd0d1, 0xd2d3, 0xd4d4, 0xd5d6, 0xd7d8, 0xd8d9, 0xdadb, 0xdcdc, 0xddde, 0xdfe0, 0xe0e1 }, 16, 0x000893e8, 1},
+ {{0xe2e3, 0xe4e4, 0xe5e6, 0xe7e7, 0xe8e9, 0xeaea, 0xebec, 0xedee, 0xeeef, 0xf0f1, 0xf1f2, 0xf3f4, 0xf4f5, 0xf6f7, 0xf7f8, 0xf9f9 }, 16, 0x00089408, 1},
+ {{0xfafb, 0xfcfc, 0xfdfe, 0xffff, }, 4, 0x00089428, 1},
+ {{0x0000, 0x2018, }, 2, 0x00089430, 1},
+ {{0x31e4, 0x21cc, 0x8009, 0x3503, 0x200c, 0x80e4, 0x0846, 0x30ec, 0x8008, 0x3103, 0x3000, 0x8000, 0x90c0, 0xe7e8, 0x90c0, 0x90c0 }, 16, 0x0009e100, 1},
+ {{0x944e, 0x3928, 0x2000, 0xbfff, 0x3000, 0x2000, 0x8000, 0x92c8, 0x4099, 0x9f7c, 0x3304, 0x3520, 0x800a, 0x31e4, 0x21c8, 0x8009 }, 16, 0x0009e120, 1},
+ {{0x3503, 0x200c, 0x80e4, 0x90c0, 0x90c0, 0x94c0, 0xc080, 0xc180, 0x9cc0, 0x7550, 0x7650, 0x75d1, 0x76d1, 0xc980, 0xca80, 0x3e00 }, 16, 0x0009e140, 1},
+ {{0xa00a, 0x7750, 0x7450, 0x77d1, 0x74d1, 0xcb80, 0xcc80, 0x3e00, 0xa00f, 0x7550, 0x7650, 0x75d1, 0x76d1, 0xede9, 0xeee9, 0x3a00 }, 16, 0x0009e160, 1},
+ {{0xa10c, 0x7750, 0x77d1, 0xefe9, 0xe8e9, 0x3680, 0xa100, 0xe9e9, 0xeae9, 0x3680, 0xa100, 0xebe9, 0xece9, 0x3680, 0xa100, 0xede9 }, 16, 0x0009e180, 1},
+ {{0xeee9, 0x3680, 0xa000, 0xefe9, 0xe0e9, 0x94c0, 0xe1e9, 0xe2e9, 0x94c0, 0xe3e9, 0xc760, 0x94c0, 0xcc50, 0xcd50, 0x94c0, 0xce50 }, 16, 0x0009e1a0, 1},
+ {{0xcf50, 0x31e4, 0x2100, 0x8009, 0x9f79, 0x9f71, 0x0146, 0x3044, 0x8008, 0x3a40, 0x3038, 0x8008, 0x24ea, 0x3d40, 0x3034, 0x8008 }, 16, 0x0009e1c0, 1},
+ {{0x8447, 0x96c0, 0x9b41, 0x2b03, 0x8008, 0x2c30, 0x1492, 0x5395, 0x266a, 0x34f8, 0x3fff, 0xbfff, 0x8427, 0x6cd3, 0x7261, 0x96c1 }, 16, 0x0009e1e0, 1},
+ {{0x6d30, 0x31e0, 0x9fff, 0x94c3, 0xcc40, 0xc843, 0x7841, 0x92c3, 0xec18, 0x92c3, 0x929c, 0x5292, 0x7170, 0x81e1, 0x90c0, 0x92d0 }, 16, 0x0009e200, 1},
+ {{0xed48, 0xea48, 0x90c0, 0x3840, 0x2004, 0x8008, 0x6c10, 0x5a98, 0x90c0, 0x2a0a, 0x8001, 0xeaf1, 0xea61, 0x35e4, 0x2106, 0x8009 }, 16, 0x0009e220, 1},
+ {{0x5998, 0x5b98, 0x5c98, 0x9f4b, 0x90c0, 0x2103, 0x800a, 0x92d0, 0x9de1, 0x9d82, 0x9f4c, 0x90c0, 0x21e3, 0x9fd7, 0x92c8, 0x9082 }, 16, 0x0009e240, 1},
+ {{0x8fcf, 0x9f71, 0x9f71, 0x9f71, 0x90c0, 0x90c0, 0x9f71, 0x3480, 0xa000, 0x9f63, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x0009e260, 1},
+ {{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x6469, 0x7750, 0x9620, 0xc08e, 0x8411, 0x33e4, 0x39ea }, 16, 0x0009e280, 1},
+ {{0x8001, 0xc484, 0x04c1, 0x38b9, 0x8008, 0x94c0, 0xd321, 0xc08f, 0x8411, 0x33e4, 0x39ea, 0x8001, 0xc384, 0x03c1, 0x38b7, 0x8008 }, 16, 0x0009e2a0, 1},
+ {{0x9621, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x6469, 0x77d0, 0x9e20, 0x9720, 0x845b, 0x01c5, 0x38b9 }, 16, 0x0009e2c0, 1},
+ {{0x8008, 0x64e9, 0x8051, 0x9ac0, 0xd0a3, 0x3dc0, 0x30fc, 0x8008, 0xc0a6, 0x8043, 0x1495, 0x38e8, 0x2c00, 0xbfff, 0x3ae8, 0x2c04 }, 16, 0x0009e2e0, 1},
+ {{0xbfff, 0x0490, 0x39e0, 0x3f80, 0x8009, 0x33a1, 0x3800, 0x8008, 0x32e4, 0x3a5c, 0x8001, 0x4392, 0x32e4, 0x3a62, 0x8001, 0x94c0 }, 16, 0x0009e300, 1},
+ {{0xc184, 0xc0a6, 0x32e4, 0x39e4, 0x8001, 0xc08e, 0xc383, 0x03c1, 0x38b9, 0x8008, 0x98c0, 0xd3a1, 0x00c5, 0x38b7, 0x8008, 0x846f }, 16, 0x0009e320, 1},
+ {{0x6469, 0x806b, 0x98c0, 0xd023, 0x3cc0, 0x3100, 0x8008, 0x805f, 0x1394, 0x38e8, 0x2800, 0xbfff, 0x98c0, 0x3ee8, 0x2804, 0xbfff }, 16, 0x0009e340, 1},
+ {{0xc0a2, 0x0390, 0x3900, 0x2680, 0x800a, 0x37a1, 0x3c00, 0x8008, 0x4796, 0x0ac6, 0x38d0, 0x8008, 0x90c0, 0x2a0a, 0x8078, 0x52d2 }, 16, 0x0009e360, 1},
+ {{0x355c, 0x8000, 0x3454, 0x8000, 0x8015, 0x33e4, 0x3a5c, 0x8001, 0x32e4, 0x3a62, 0x8001, 0x94c0, 0xc184, 0xc0a2, 0x32e4, 0x39e4 }, 16, 0x0009e380, 1},
+ {{0x8001, 0xc08f, 0xc483, 0x04c1, 0x38b7, 0x8008, 0x94c0, 0x9e21, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x0009e3a0, 1},
+ {{0x96c0, 0x6f90, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x96c0, 0xe8f1, 0x270b, 0x8020, 0x2418, 0x83c8, 0x94c0, 0xe7eb, 0xc281 }, 16, 0x0009e3c0, 1},
+ {{0x98c0, 0x3de8, 0x3c14, 0xbfff, 0xf245, 0x98c0, 0x34f1, 0x3fff, 0xbfff, 0xf59d, 0x1395, 0x3be8, 0x3c04, 0xbfff, 0x98c0, 0xde03 }, 16, 0x0009e3e0, 1},
+ {{0x3fc8, 0x3c10, 0xbfff, 0x0495, 0x30e9, 0x3fff, 0xb000, 0x3441, 0x2e00, 0x9200, 0x0493, 0x3ec8, 0x3c10, 0xbfff, 0x1197, 0x3fc8 }, 16, 0x0009e400, 1},
+ {{0x3c10, 0xbfff, 0x98c0, 0xdc01, 0x3ac8, 0x3c00, 0xbfff, 0x4097, 0x5196, 0x0991, 0xa000, 0x98c0, 0x4196, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x0009e420, 1},
+ {{0x3e00, 0xa008, 0x7bc1, 0x6c10, 0x5097, 0x3300, 0x2000, 0x8042, 0x96c0, 0x318e, 0x8000, 0xc112, 0x6769, 0x92c3, 0x6e10, 0x94c6 }, 16, 0x0009e440, 1},
+ {{0x72f7, 0xc481, 0x92c2, 0x6f10, 0x94c7, 0xd4c3, 0xc681, 0x1505, 0xa001, 0x90c0, 0x3e26, 0xb000, 0x90c0, 0xc312, 0x90c0, 0x64e0 }, 16, 0x0009e460, 1},
+ {{0xc081, 0xd440, 0x3a06, 0xa200, 0x90c0, 0xf143, 0xd440, 0x65e0, 0x2461, 0xf044, 0x7170, 0x802b, 0x7160, 0x840b, 0x70e3, 0x8023 }, 16, 0x0009e480, 1},
+ {{0x70fb, 0x841f, 0x90c0, 0x94c0, 0xc112, 0xf2c4, 0x3170, 0x24e0, 0xf3c3, 0x94c0, 0x65e0, 0x81f3, 0x7160, 0x8407, 0x71f9, 0x81e7 }, 16, 0x0009e4a0, 1},
+ {{0x6669, 0x96c0, 0xf2c5, 0x2718, 0x8690, 0x6769, 0x8175, 0xf2c5, 0x6560, 0x2669, 0x3700, 0x2000, 0x8200, 0x2518, 0x813e, 0x98c0 }, 16, 0x0009e4c0, 1},
+ {{0x3ee8, 0x3c38, 0xbfff, 0xf946, 0x94c0, 0xf847, 0xf245, 0x1396, 0xce44, 0x32e4, 0x39d2, 0x8001, 0x37ff, 0x9fff, 0x32e4, 0x3c4e }, 16, 0x0009e4e0, 1},
+ {{0x8001, 0x96c0, 0x74ff, 0xf2c5, 0xce4c, 0x2660, 0x2560, 0x3fc8, 0x3c10, 0xbfff, 0x33a1, 0x33b0, 0x8000, 0x307b, 0x1597, 0x3381 }, 16, 0x0009e500, 1},
+ {{0x2020, 0x8000, 0x96c0, 0x3b0f, 0x87ff, 0x8036, 0x94c6, 0xdb8f, 0xce86, 0x707b, 0x8026, 0x92c2, 0xce85, 0x3670, 0x8018, 0x801c }, 16, 0x0009e520, 1},
+ {{0x92c2, 0xce84, 0x3650, 0x8010, 0x8012, 0x92c2, 0xce83, 0x3630, 0x8008, 0x90c0, 0x94c1, 0xce81, 0xce82, 0x98c0, 0x3d40, 0x3170 }, 16, 0x0009e540, 1},
+ {{0x8008, 0xf245, 0x0ec1, 0x38b8, 0x8008, 0xeefc, 0xee1d, 0x1bd6, 0xce44, 0x98c0, 0xcb4e, 0x33e4, 0x39d2, 0x8001, 0x98c0, 0x05c5 }, 16, 0x0009e560, 1},
+ {{0x38b8, 0x8008, 0xf9c6, 0x9ac0, 0x75e5, 0x3a40, 0x3150, 0x8008, 0xf8c7, 0x96c0, 0x7dc1, 0xf2c5, 0xce4c, 0xcb43, 0x90c0, 0xea1b }, 16, 0x0009e580, 1},
+ {{0x5ad2, 0x98c0, 0xca49, 0x32e4, 0x3c4e, 0x8001, 0x64e0, 0x3fc4, 0x2660, 0x2560, 0x3a40, 0x3170, 0x8008, 0x3820, 0xa000, 0x02c5 }, 16, 0x0009e5a0, 1},
+ {{0x38b8, 0x8008, 0x3e00, 0xa808, 0x75e2, 0x3a01, 0x8006, 0xeb1a, 0x280d, 0x8006, 0x3e00, 0xb000, 0xdd9f, 0xd891, 0x57d3, 0x3ac8 }, 16, 0x0009e5c0, 1},
+ {{0x3c18, 0xbfff, 0x98c0, 0x3603, 0x8006, 0x7fdc, 0x4315, 0x98c0, 0xd5c1, 0x06c5, 0x38b8, 0x8008, 0x3f44, 0x0913, 0xa200, 0x98c0 }, 16, 0x0009e5e0, 1},
+ {{0xdf9b, 0x06c0, 0x38b0, 0x8008, 0x5192, 0x3318, 0x8003, 0x6469, 0x90c0, 0x94c2, 0x0997, 0xa000, 0x96c0, 0x6669, 0x280b, 0x8004 }, 16, 0x0009e600, 1},
+ {{0x96c0, 0x55d3, 0x2718, 0x8168, 0x3481, 0x2000, 0x8000, 0x9ac0, 0x3b9e, 0x8000, 0x767c, 0x2b0a, 0x8002, 0x3266, 0x3ec8, 0x3c10 }, 16, 0x0009e620, 1},
+ {{0xbfff, 0x98c7, 0x2718, 0x813e, 0x90c0, 0x6d10, 0x1696, 0x3ec8, 0x3c10, 0xbfff, 0x98c0, 0x30e9, 0x3fff, 0xb000, 0xf946, 0x9ac0 }, 16, 0x0009e640, 1},
+ {{0xdc06, 0x3cc8, 0x3c10, 0xbfff, 0xf847, 0x0096, 0xf245, 0x14d3, 0x5196, 0x397c, 0x9ff0, 0x7e64, 0x94c0, 0xd994, 0xcf44, 0xdd99 }, 16, 0x0009e660, 1},
+ {{0x4396, 0x1694, 0xeeea, 0x0916, 0xa800, 0x0694, 0xcb4e, 0x51d3, 0x3319, 0x8007, 0x32e4, 0x39d2, 0x8001, 0x01c1, 0x38b8, 0x8008 }, 16, 0x0009e680, 1},
+ {{0x94c0, 0xcb46, 0xcf4c, 0x9ac0, 0x7a41, 0x3d40, 0x3150, 0x8008, 0xf9c6, 0x11d3, 0xf8c7, 0x98c0, 0x331b, 0x8007, 0xf2c5, 0xeaee }, 16, 0x0009e6a0, 1},
+ {{0x7dc1, 0xcf43, 0x90c0, 0xef1d, 0x11d7, 0x32e4, 0x3c4e, 0x8001, 0x3681, 0x8001, 0x9cc0, 0x30cb, 0x87c1, 0x6560, 0x3a01, 0x8004 }, 16, 0x0009e6c0, 1},
+ {{0xcc40, 0x9ac0, 0xdb11, 0xc553, 0x3ee8, 0x3c24, 0xbfff, 0x98c0, 0xec61, 0x3de8, 0x3c20, 0xbfff, 0x3a00, 0xa100, 0x3601, 0x8004 }, 16, 0x0009e6e0, 1},
+ {{0xcc4d, 0xed61, 0x3c20, 0xa000, 0xd4c6, 0x3fe8, 0x3c14, 0xbfff, 0x4d96, 0x09b5, 0xa000, 0x0595, 0x3d40, 0x3170, 0x8008, 0x1097 }, 16, 0x0009e700, 1},
+ {{0x3c40, 0x3140, 0x8008, 0x0950, 0xa000, 0x4097, 0x03c5, 0x38b8, 0x8008, 0x7463, 0x96c0, 0x311c, 0x8007, 0xcf40, 0x7e41, 0x94c0 }, 16, 0x0009e720, 1},
+ {{0xce44, 0xeffc, 0xef1c, 0xee1d, 0x1dd7, 0x55d6, 0x3655, 0x7edc, 0x9ac0, 0x3623, 0x8004, 0xedfc, 0x3a21, 0x8004, 0x98c0, 0xd891 }, 16, 0x0009e740, 1},
+ {{0x0dc0, 0x38b0, 0x8008, 0x14d3, 0xd5c1, 0x96c0, 0x397c, 0x9ff0, 0xdf9b, 0x9ac0, 0xdc1c, 0xdf9d, 0x30e4, 0x2788, 0x8009, 0x4012 }, 16, 0x0009e760, 1},
+ {{0x02c1, 0x38b8, 0x8008, 0x4212, 0x98c0, 0x3a00, 0x20e0, 0x8008, 0xe846, 0x1cd0, 0x3be8, 0x3c04, 0xbfff, 0x4c12, 0x4793, 0x9ac0 }, 16, 0x0009e780, 1},
+ {{0x6e10, 0xe9f1, 0x3fe8, 0x3c14, 0xbfff, 0x96c0, 0xf79d, 0x2518, 0x8372, 0x1197, 0x33e9, 0x3fff, 0xbfff, 0x9ac0, 0xdd81, 0x3be8 }, 16, 0x0009e7a0, 1},
+ {{0x3c08, 0xbfff, 0xf245, 0x0397, 0x38c8, 0x3c10, 0xbfff, 0x3341, 0x2e00, 0x9000, 0x0393, 0x3179, 0x3000, 0xbfff, 0x1090, 0x3cc8 }, 16, 0x0009e7c0, 1},
+ {{0x3c10, 0xbfff, 0x98c0, 0xdc80, 0x3ac8, 0x3c00, 0xbfff, 0x4190, 0x5190, 0x0981, 0xa000, 0x98c0, 0x4190, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x0009e7e0, 1},
+ {{0x3e00, 0xa008, 0x7a41, 0x6e10, 0x5594, 0x3300, 0x2000, 0x8042, 0x96c0, 0x3b9d, 0x8000, 0xc112, 0x66e9, 0x92c3, 0x6e90, 0x94c6 }, 16, 0x0009e800, 1},
+ {{0x73f4, 0xc581, 0x92c2, 0x6f10, 0x94c7, 0xd4c3, 0xc681, 0x1505, 0xa001, 0x90c0, 0x3e26, 0xb000, 0x90c0, 0xc312, 0x90c0, 0x64e0 }, 16, 0x0009e820, 1},
+ {{0xc481, 0xd444, 0x3a06, 0xa200, 0x90c0, 0xf143, 0xd444, 0x65e0, 0x2461, 0xf044, 0x7170, 0x802b, 0x7160, 0x840b, 0x70e3, 0x8023 }, 16, 0x0009e840, 1},
+ {{0x70fb, 0x841f, 0x90c0, 0x94c0, 0xc112, 0xf3c4, 0x31f0, 0x24e0, 0xf2c3, 0x94c0, 0x6560, 0x81f3, 0x71e0, 0x8407, 0x7179, 0x81e7 }, 16, 0x0009e860, 1},
+ {{0x66e9, 0x96c0, 0xf2c5, 0x2718, 0x82d8, 0x6769, 0x8175, 0x37d5, 0xf2c5, 0x6560, 0x27e9, 0x2f10, 0x3be8, 0x3c38, 0xbfff, 0x96c0 }, 16, 0x0009e880, 1},
+ {{0xf642, 0x2518, 0x8108, 0x1393, 0xf946, 0x96c0, 0x37ed, 0x9fff, 0xf245, 0x3acd, 0x8410, 0x3755, 0x33e4, 0x39d2, 0x8001, 0x32e4 }, 16, 0x0009e8a0, 1},
+ {{0x3c4e, 0x8001, 0x34fe, 0x27e0, 0xf2c5, 0x2560, 0x38c8, 0x3c10, 0xbfff, 0x33a1, 0x33b0, 0x8000, 0x307b, 0x1490, 0x3181, 0x2020 }, 16, 0x0009e8c0, 1},
+ {{0x8000, 0x96c0, 0x391e, 0x87ff, 0x8036, 0x92c2, 0xcd86, 0x7079, 0x8028, 0x92c2, 0xcd85, 0x3670, 0x8018, 0x801e, 0x92c2, 0xcd84 }, 16, 0x0009e8e0, 1},
+ {{0x3650, 0x8010, 0x8014, 0x92c2, 0xcd83, 0x3630, 0x8008, 0x90c0, 0x94c1, 0xcd81, 0xcd82, 0x90c0, 0x98c0, 0xeeed, 0x32e4, 0x39d2 }, 16, 0x0009e900, 1},
+ {{0x8001, 0x98c0, 0xf245, 0x0dc1, 0x38bb, 0x8008, 0x9ac0, 0x67e0, 0x04c5, 0x38bb, 0x8008, 0xf9c6, 0x9ac0, 0x7664, 0x3b40, 0x3150 }, 16, 0x0009e920, 1},
+ {{0x8008, 0xf2c5, 0x3e41, 0xce4b, 0xcd44, 0x90c0, 0xed1b, 0x5dd5, 0x98c0, 0xcd49, 0x32e4, 0x3c4e, 0x8001, 0x64e0, 0x3f44, 0x2560 }, 16, 0x0009e940, 1},
+ {{0x04c5, 0x38bb, 0x8008, 0x9ac0, 0x3a65, 0x8000, 0x74e4, 0x290d, 0x8006, 0x98c0, 0xdc9e, 0x04c5, 0x38bb, 0x8008, 0x9cc0, 0x3865 }, 16, 0x0009e960, 1},
+ {{0x8000, 0x7664, 0x3660, 0x8000, 0x4115, 0x9ac0, 0xd895, 0x7e5c, 0x06c5, 0x38bb, 0x8008, 0x3f44, 0xd4c0, 0x98c0, 0xde19, 0x06c0 }, 16, 0x0009e980, 1},
+ {{0x38b2, 0x8008, 0xf442, 0x96c0, 0x67e9, 0x290e, 0x8004, 0x96c0, 0x55d6, 0x2718, 0x8156, 0x3081, 0x2000, 0x8000, 0x9ac0, 0x3b9f }, 16, 0x0009e9a0, 1},
+ {{0x8000, 0x74f8, 0x2e0f, 0x8002, 0x30e7, 0x3bc8, 0x3c10, 0xbfff, 0x98c7, 0x2718, 0x812c, 0x90c0, 0x6d10, 0x1093, 0x3779, 0x3000 }, 16, 0x0009e9c0, 1},
+ {{0xbfff, 0x9ac0, 0xdf80, 0x38c8, 0x3c10, 0xbfff, 0xf946, 0x0793, 0x3ac8, 0x3c10, 0xbfff, 0x14d6, 0x5390, 0x96c0, 0x397f, 0x9ff0 }, 16, 0x0009e9e0, 1},
+ {{0xf245, 0x7fe4, 0xdd9f, 0x4390, 0x5592, 0x0905, 0xa800, 0x4592, 0x53d6, 0x371e, 0x8007, 0x32e4, 0x39d2, 0x8001, 0x06c1, 0x38bb }, 16, 0x0009ea00, 1},
+ {{0x8008, 0x9ac0, 0x7bc1, 0x06c5, 0x38bb, 0x8008, 0xf9c6, 0x9ac0, 0x7666, 0x3840, 0x3150, 0x8008, 0xf2c5, 0x7e41, 0xca44, 0x90c0 }, 16, 0x0009ea20, 1},
+ {{0xea18, 0x13d2, 0x32e4, 0x3c4e, 0x8001, 0x36e1, 0x8003, 0x9ec0, 0x30cb, 0x87c1, 0x6560, 0x3a01, 0x8007, 0xc840, 0xf5c2, 0x9ac0 }, 16, 0x0009ea40, 1},
+ {{0xda11, 0xcd43, 0x3ce8, 0x3c24, 0xbfff, 0x98c0, 0xe861, 0x3be8, 0x3c20, 0xbfff, 0x98c0, 0x3603, 0x8007, 0xc84e, 0xed61, 0x9ac0 }, 16, 0x0009ea60, 1},
+ {{0xd5c4, 0x3ae8, 0x3c14, 0xbfff, 0x4d94, 0x09b6, 0xa000, 0x0693, 0x3840, 0x3170, 0x8008, 0x1192, 0x3c40, 0x3140, 0x8008, 0x0991 }, 16, 0x0009ea80, 1},
+ {{0xa000, 0x4192, 0x01c5, 0x38bb, 0x8008, 0x7761, 0x96c0, 0x3d1c, 0x8007, 0xcd46, 0x7e41, 0x94c0, 0xca44, 0xedfc, 0xed1c, 0x1bd5 }, 16, 0x0009eaa0, 1},
+ {{0xea18, 0x51d2, 0x3651, 0x3cdc, 0xebfc, 0x9ac0, 0x3660, 0x8004, 0x90c0, 0x3a64, 0x8004, 0x98c0, 0xda14, 0x0bc0, 0x38b2, 0x8008 }, 16, 0x0009eac0, 1},
+ {{0x13d6, 0xd444, 0x96c0, 0xde98, 0x3778, 0x9ff0, 0x9ac0, 0xdf18, 0xde99, 0x30e4, 0x2b04, 0x8009, 0x0617, 0xf542, 0x02c1, 0x38bb }, 16, 0x0009eae0, 1},
+ {{0x8008, 0x4217, 0x98c0, 0x3800, 0x20e2, 0x8008, 0xe946, 0x1bd1, 0x3ce8, 0x3c08, 0xbfff, 0x4b10, 0xf0c2, 0x4094, 0x2704, 0x8e64 }, 16, 0x0009eb00, 1},
+ {{0x90c0, 0x90c0, 0x90c8, 0x2560, 0x3ac8, 0x3c10, 0xbfff, 0x96c0, 0x746a, 0x27eb, 0x9fe0, 0x98c0, 0x3dc8, 0x3c10, 0xbfff, 0xe7eb }, 16, 0x0009eb20, 1},
+ {{0x94c0, 0x9e21, 0x9f21, 0x5192, 0x94c0, 0x9621, 0x9721, 0x9f70, 0x4195, 0x2560, 0x31e4, 0x24d2, 0x8009, 0x2560, 0x37d5, 0x31e4 }, 16, 0x0009eb40, 1},
+ {{0x2894, 0x8009, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6469, 0xc841, 0xe748, 0x96c0, 0xf389, 0x27e9, 0x9ff8 }, 16, 0x0009eb60, 1},
+ {{0x98c6, 0xe8fe, 0x3ba0, 0x3800, 0x8008, 0x98c7, 0xd1a1, 0x3ba0, 0x3c00, 0x8008, 0x90c0, 0x96c6, 0xeb18, 0x12fc, 0x9fec, 0x96c7 }, 16, 0x0009eb80, 1},
+ {{0x5193, 0x14fc, 0x9fec, 0x98c6, 0xf142, 0x34e9, 0x810a, 0xf38b, 0x9cc1, 0x38e9, 0x811a, 0xf28b, 0x36e9, 0x8280, 0xf142, 0x96c7 }, 16, 0x0009eba0, 1},
+ {{0xf142, 0x34e9, 0x8290, 0x94c7, 0x6469, 0xf142, 0x5291, 0x98c6, 0xe768, 0x3da0, 0x3800, 0x8008, 0x96c3, 0x39a0, 0x3c00, 0x8008 }, 16, 0x0009ebc0, 1},
+ {{0x92c2, 0xe81d, 0x94c7, 0x9f70, 0xe819, 0x4290, 0x90c0, 0x90c0, 0x98c0, 0x3118, 0x8700, 0x9620, 0x9f20, 0x6469, 0x809d, 0x96c0 }, 16, 0x0009ebe0, 1},
+ {{0x3410, 0x8500, 0xc68b, 0x8089, 0x98c0, 0x3410, 0x8400, 0xc481, 0xc689, 0x806d, 0x96c0, 0x3410, 0x8300, 0xc68f, 0x8059, 0x96c0 }, 16, 0x0009ec00, 1},
+ {{0x3410, 0x8200, 0xc68e, 0x8045, 0x96c0, 0x3410, 0x8700, 0xc68d, 0x8031, 0x98c0, 0x3410, 0x8600, 0xc281, 0xc68a, 0x8015, 0x98c0 }, 16, 0x0009ec20, 1},
+ {{0x3410, 0x8100, 0xc082, 0xc68a, 0x8451, 0x31e4, 0x2c9c, 0x8009, 0x30e4, 0x2c9c, 0x8009, 0x98c0, 0xc082, 0x02c1, 0x38bc, 0x8008 }, 16, 0x0009ec40, 1},
+ {{0x98c0, 0xc085, 0x31e4, 0x2c9c, 0x8009, 0x98c0, 0xc086, 0x31e4, 0x2c9c, 0x8009, 0x98c0, 0xc087, 0x31e4, 0x2c9c, 0x8009, 0x30e4 }, 16, 0x0009ec60, 1},
+ {{0x2c9c, 0x8009, 0x98c0, 0xc081, 0x04c1, 0x38bc, 0x8008, 0x98c0, 0xc083, 0x31e4, 0x2c9c, 0x8009, 0x2c10, 0x6f10, 0xd0a1, 0xd358 }, 16, 0x0009ec80, 1},
+ {{0x96c0, 0x747e, 0x9621, 0x9f21, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x64e9, 0xcd50, 0xc59c, 0x94c0, 0x9620, 0x9720, 0x94c0 }, 16, 0x0009eca0, 1},
+ {{0xcd5e, 0xcc51, 0x96c0, 0x7b61, 0x9e20, 0x9f20, 0x9cc0, 0x36c2, 0x8005, 0xcd56, 0x34c5, 0x8005, 0xe748, 0x98c0, 0xda15, 0x03c6 }, 16, 0x0009ecc0, 1},
+ {{0x30fc, 0x8008, 0x98c0, 0xd642, 0x36cd, 0x8041, 0x843b, 0x9ac0, 0x66e9, 0x39c8, 0x3c10, 0xbfff, 0xce44, 0x3fc0, 0x2280, 0x8008 }, 16, 0x0009ece0, 1},
+ {{0x94c7, 0x5291, 0xc881, 0x90c0, 0x98c6, 0x350a, 0x87ff, 0xee1f, 0xe838, 0x9ac0, 0xda0a, 0xc84a, 0x31e4, 0x2d4e, 0x8009, 0x98c0 }, 16, 0x0009ed00, 1},
+ {{0x02c6, 0x3100, 0x8008, 0xce44, 0x34cd, 0x8041, 0x26e9, 0x3bc8, 0x3c10, 0xbfff, 0x3cc0, 0x22f0, 0x8008, 0x94c7, 0x5293, 0xc881 }, 16, 0x0009ed20, 1},
+ {{0x90c0, 0x98c6, 0x351c, 0x87ff, 0xee1c, 0xe838, 0xc84a, 0x94c0, 0xee42, 0xc781, 0x96c0, 0xd7c4, 0x50d6, 0xee4a, 0x98c0, 0x3ece }, 16, 0x0009ed40, 1},
+ {{0x8743, 0xce50, 0x5316, 0x98c0, 0x34f3, 0x9fff, 0xf191, 0xf792, 0x3a00, 0xa001, 0x2e08, 0x8002, 0x7651, 0xcf56, 0x1410, 0x4116 }, 16, 0x0009ed60, 1},
+ {{0x94c0, 0x4710, 0x8081, 0x3e00, 0xa003, 0x70e3, 0x74d3, 0x7452, 0x74d4, 0xcc58, 0xcd5e, 0x96c0, 0x7f42, 0xc581, 0x806b, 0x3b42 }, 16, 0x0009ed80, 1},
+ {{0xf501, 0x9ac0, 0x6e90, 0xf603, 0x32e4, 0x2b70, 0x8009, 0x36d3, 0xf502, 0x3c00, 0xaa00, 0x7550, 0x75d5, 0x7651, 0xce58, 0xc181 }, 16, 0x0009eda0, 1},
+ {{0x756a, 0x3600, 0xa008, 0x6569, 0x7452, 0x8437, 0x33e4, 0x2bf0, 0x8009, 0x94c0, 0xd02a, 0xcc58, 0x92c2, 0x79c1, 0x3a22, 0xa004 }, 16, 0x0009edc0, 1},
+ {{0x6e90, 0x74f3, 0xc681, 0xf603, 0x96c2, 0x32e4, 0x2b70, 0x8009, 0x3662, 0xa000, 0xf601, 0xf502, 0x3600, 0xb800, 0x7550, 0x7651 }, 16, 0x0009ede0, 1},
+ {{0x34f4, 0x9fff, 0x8077, 0x3e00, 0xa003, 0x73e4, 0x74d4, 0x7452, 0x74d4, 0xcc58, 0xcd5e, 0x96c0, 0x7f42, 0xc582, 0x8065, 0x96c0 }, 16, 0x0009ee00, 1},
+ {{0x6e90, 0xf501, 0xf603, 0x32e4, 0x2b70, 0x8009, 0xf502, 0x3800, 0xa800, 0x7550, 0xce58, 0xc182, 0x756a, 0x3600, 0xa008, 0x6569 }, 16, 0x0009ee20, 1},
+ {{0x7452, 0x8439, 0x33e4, 0x2bf0, 0x8009, 0x3800, 0xb000, 0xd022, 0x7651, 0xcc58, 0x92c2, 0x7a41, 0x3a22, 0xa000, 0x6d90, 0x74f4 }, 16, 0x0009ee40, 1},
+ {{0xc782, 0xf603, 0x96c2, 0x32e4, 0x2b70, 0x8009, 0x3642, 0xa000, 0xf302, 0xf701, 0x3400, 0xa800, 0x7550, 0x32e4, 0x2bf0, 0x8009 }, 16, 0x0009ee60, 1},
+ {{0x3800, 0xa004, 0x7452, 0xce58, 0xc181, 0x3a00, 0xb000, 0x76d0, 0x74d4, 0xcd5e, 0xcc5b, 0x3a00, 0xa004, 0x76d6, 0x7453, 0xc681 }, 16, 0x0009ee80, 1},
+ {{0xf502, 0x3600, 0xa800, 0x75d5, 0xf601, 0x7dc2, 0x3c00, 0xa004, 0x76d3, 0x79c2, 0x32e4, 0x2b70, 0x8009, 0x3800, 0xa004, 0x74d3 }, 16, 0x0009eea0, 1},
+ {{0x7753, 0xf303, 0x3a00, 0xb200, 0x75d6, 0x7768, 0x74d4, 0xcc58, 0x6769, 0x848f, 0xd2aa, 0x3602, 0xa004, 0x3303, 0x8001, 0x3822 }, 16, 0x0009eec0, 1},
+ {{0xa800, 0x74f3, 0xc281, 0xc088, 0x94c2, 0xf201, 0xf303, 0x96c2, 0x32e4, 0x2b70, 0x8009, 0x3422, 0xa000, 0xf002, 0x3800, 0xa804 }, 16, 0x0009eee0, 1},
+ {{0x75f1, 0xce58, 0xcf5b, 0x3e40, 0xa402, 0x311a, 0x8700, 0xcc58, 0x3701, 0x8004, 0xc281, 0x96c0, 0x3412, 0x8600, 0x7573, 0x94c0 }, 16, 0x0009ef00, 1},
+ {{0x7542, 0x8443, 0x3820, 0xa804, 0x6dc8, 0xf502, 0xf201, 0x32e4, 0x2b70, 0x8009, 0x3640, 0xa800, 0x74f3, 0xf103, 0x3860, 0xa800 }, 16, 0x0009ef20, 1},
+ {{0x7673, 0xc488, 0xc281, 0x3820, 0xa000, 0x7a41, 0xcc58, 0xf103, 0x32e4, 0x2b70, 0x8009, 0x3860, 0xa000, 0x74f4, 0xf201, 0xf402 }, 16, 0x0009ef40, 1},
+ {{0x32e4, 0x2bf0, 0x8009, 0x94c0, 0xce58, 0xc182, 0x3c20, 0xa004, 0x77d0, 0x74d7, 0x6760, 0xcc5c, 0xc482, 0x3860, 0xa000, 0x7454 }, 16, 0x0009ef60, 1},
+ {{0xf503, 0xf401, 0x32e4, 0x2b70, 0x8009, 0x3420, 0xa000, 0xf702, 0x3800, 0xb000, 0x6769, 0x75d5, 0xcc58, 0x8499, 0x3400, 0xa004 }, 16, 0x0009ef80, 1},
+ {{0xd3a2, 0x94c2, 0x3f06, 0x8001, 0x3842, 0xa000, 0x74f6, 0xc388, 0xc582, 0x94c2, 0xf303, 0xf501, 0x96c2, 0x32e4, 0x2b70, 0x8009 }, 16, 0x0009efa0, 1},
+ {{0x3422, 0xa000, 0xf302, 0x94c0, 0xce58, 0xcf5b, 0x3c20, 0xa001, 0x311e, 0x8700, 0x7773, 0xcc58, 0xc582, 0x3a00, 0xa201, 0x3416 }, 16, 0x0009efc0, 1},
+ {{0x8600, 0x7746, 0xcd5e, 0x3800, 0xa004, 0x3d04, 0x8004, 0x844d, 0x3860, 0xa040, 0x6f5f, 0xf702, 0xf501, 0x3c00, 0xa004, 0x7e42 }, 16, 0x0009efe0, 1},
+ {{0x74f6, 0x32e4, 0x2b70, 0x8009, 0x3420, 0xa000, 0xf403, 0x3840, 0xa004, 0x74f6, 0xc088, 0xc682, 0x3820, 0xa004, 0x78c1, 0xcc58 }, 16, 0x0009f000, 1},
+ {{0xf403, 0x32e4, 0x2b70, 0x8009, 0x3820, 0xa800, 0x74f1, 0xf601, 0xf002, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721 }, 16, 0x0009f020, 1},
+ {{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x9ac0, 0x6469, 0x9620, 0x06c5, 0x38b9, 0x8008, 0x94c0, 0x9e20 }, 16, 0x0009f040, 1},
+ {{0x846f, 0x98c0, 0xd323, 0x05c6, 0x3104, 0x8008, 0x96c0, 0x845f, 0x0905, 0xa300, 0x06c4, 0x38b0, 0x8008, 0x98c0, 0xdf1d, 0x3ee8 }, 16, 0x0009f060, 1},
+ {{0x2c08, 0xbfff, 0x06c2, 0x3108, 0x8008, 0x4696, 0x06c5, 0x38b6, 0x8008, 0x6769, 0x92c3, 0x6c90, 0x98c2, 0xc681, 0x34a1, 0x2800 }, 16, 0x0009f080, 1},
+ {{0x8008, 0x96c3, 0x33a1, 0x3000, 0x8008, 0x96c2, 0x04c2, 0x3104, 0x8008, 0x96c2, 0x06c1, 0x38b6, 0x8008, 0x96c3, 0x03c2, 0x3104 }, 16, 0x0009f0a0, 1},
+ {{0x8008, 0x96c3, 0x01c1, 0x38b6, 0x8008, 0x98c0, 0xd021, 0x06c5, 0x38b7, 0x8008, 0x846b, 0x98c0, 0xd323, 0x04c6, 0x3118, 0x8008 }, 16, 0x0009f0c0, 1},
+ {{0x96c0, 0x845f, 0x0904, 0xa300, 0x00c4, 0x38b2, 0x8008, 0x98c0, 0xdc1c, 0x3ae8, 0x2808, 0xbfff, 0x00c2, 0x3110, 0x8008, 0x4092 }, 16, 0x0009f0e0, 1},
+ {{0x00c5, 0x38ba, 0x8008, 0x6469, 0x92c3, 0x6c90, 0x98c2, 0xc081, 0x34a1, 0x2000, 0x8008, 0x96c3, 0x3681, 0x3800, 0x8008, 0x96c2 }, 16, 0x0009f100, 1},
+ {{0x04c2, 0x3118, 0x8008, 0x96c2, 0x00c1, 0x38ba, 0x8008, 0x96c3, 0x06c2, 0x3118, 0x8008, 0x96c3, 0x01c1, 0x38ba, 0x8008, 0x9e21 }, 16, 0x0009f120, 1},
+ {{0x9621, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6e90, 0x9620, 0x9720, 0x96c0, 0x6c90, 0x9e20, 0x9f20 }, 16, 0x0009f140, 1},
+ {{0x98c0, 0x3bc0, 0x30ac, 0x8008, 0xeae9, 0x98c0, 0x3fc0, 0x308c, 0x8008, 0xece8, 0x0593, 0xe9eb, 0x0597, 0xeeef, 0x96c0, 0xee64 }, 16, 0x0009f160, 1},
+ {{0x270d, 0x8020, 0x0596, 0xe964, 0x0591, 0xe7ed, 0x96c0, 0xeb68, 0x2300, 0x8200, 0x0593, 0xef68, 0x0597, 0xf341, 0x98c0, 0xfa43 }, 16, 0x0009f180, 1},
+ {{0x38a0, 0x3800, 0x8008, 0x98c0, 0x05c2, 0x3080, 0x8008, 0xeeec, 0x05c1, 0x38b9, 0x8008, 0x32e4, 0x3c8a, 0x8001, 0x05c2, 0x30a0 }, 16, 0x0009f1a0, 1},
+ {{0x8008, 0x9ac0, 0x6f10, 0x38c0, 0x30bc, 0x8008, 0xc281, 0x2c90, 0x3dc0, 0x30cc, 0x8008, 0x0690, 0xefe8, 0x0695, 0xebed, 0x98c0 }, 16, 0x0009f1c0, 1},
+ {{0xe868, 0x07a6, 0x3800, 0x8008, 0x98c0, 0x3cef, 0x804f, 0xeb64, 0xed68, 0x96c0, 0xef64, 0x2400, 0x8200, 0x0690, 0x4693, 0x0695 }, 16, 0x0009f1e0, 1},
+ {{0x4697, 0x98c0, 0xf441, 0x38a0, 0x3c00, 0x8008, 0x07a2, 0x3800, 0x8008, 0x02c1, 0x38b9, 0x8008, 0x06c1, 0x38b7, 0x8008, 0x06c2 }, 16, 0x0009f200, 1},
+ {{0x30c0, 0x8008, 0x32e4, 0x3c8a, 0x8001, 0x06c2, 0x30b0, 0x8008, 0x9cc0, 0x6d10, 0x6c90, 0x06a6, 0x3c00, 0x8008, 0xc581, 0x9ac0 }, 16, 0x0009f220, 1},
+ {{0x6c10, 0x3d00, 0x20e0, 0x8008, 0xeef1, 0x96c0, 0x34ee, 0x804f, 0xfac3, 0x3800, 0x20e2, 0x8008, 0x05c1, 0x38b7, 0x8008, 0x06a2 }, 16, 0x0009f240, 1},
+ {{0x3c00, 0x8008, 0x4215, 0x4210, 0x02c1, 0x38b8, 0x8008, 0x01c1, 0x38bb, 0x8008, 0x2418, 0x8666, 0x01c1, 0x38bc, 0x8008, 0x33e4 }, 16, 0x0009f260, 1},
+ {{0x2290, 0x8009, 0x9ac0, 0x6c10, 0x03c5, 0x38b9, 0x8008, 0xecee, 0x65e9, 0x90c0, 0x98c7, 0x32e4, 0x22d0, 0x8009, 0x5394, 0x96c3 }, 16, 0x0009f280, 1},
+ {{0x03c2, 0x30fc, 0x8008, 0x94c0, 0xc185, 0xe939, 0x32e4, 0x23c0, 0x8009, 0x94c0, 0xf101, 0xe8ee, 0x9cc0, 0x6469, 0x6c10, 0xecee }, 16, 0x0009f2a0, 1},
+ {{0x03c6, 0x30fc, 0x8008, 0x98c0, 0x36cd, 0x8041, 0xec48, 0x841b, 0x33e4, 0x2290, 0x8009, 0x98c0, 0xfac3, 0x31e4, 0x38da, 0x8009 }, 16, 0x0009f2c0, 1},
+ {{0x9cc0, 0x66e9, 0x6f10, 0x3dc8, 0x3c10, 0xbfff, 0xc7ff, 0x96c0, 0xc283, 0x2000, 0x8080, 0x94c2, 0x5195, 0xc581, 0x96c1, 0xc482 }, 16, 0x0009f2e0, 1},
+ {{0x32c9, 0x82d0, 0x98c6, 0x31a2, 0x3800, 0x8008, 0xd6c1, 0x96c6, 0xc385, 0x3acc, 0x8743, 0x9ac0, 0x7674, 0x3111, 0x2000, 0x8000 }, 16, 0x0009f300, 1},
+ {{0xc587, 0x3c20, 0xa000, 0x6c7d, 0x3bc0, 0x2282, 0x8008, 0xc386, 0x3a40, 0xa000, 0x7a61, 0x05c4, 0x38b0, 0x8008, 0x3e00, 0xa700 }, 16, 0x0009f320, 1},
+ {{0x2b0e, 0x8002, 0x6929, 0x69ad, 0x7e42, 0xc255, 0x3a00, 0xb988, 0x6af6, 0x6a2d, 0xcf44, 0xc945, 0x3a80, 0xa000, 0xeafc, 0x0dc6 }, 16, 0x0009f340, 1},
+ {{0x38d0, 0x8008, 0x3620, 0xa000, 0xef19, 0xe9fe, 0x0197, 0x3122, 0x336c, 0x8009, 0x14dc, 0xed54, 0x3800, 0xa100, 0x4413, 0x2d08 }, 16, 0x0009f360, 1},
+ {{0x8028, 0x3820, 0xa000, 0x451e, 0x2800, 0x8052, 0x461e, 0x3420, 0xa000, 0x451e, 0x3420, 0xa000, 0x451e, 0x471e, 0x4716, 0x16dc }, 16, 0x0009f380, 1},
+ {{0xee50, 0x96c0, 0x4616, 0x2e0f, 0x8002, 0x421f, 0x3420, 0xa000, 0x4a1f, 0x3420, 0xa000, 0x451f, 0x3420, 0xa000, 0x451f, 0x471f }, 16, 0x0009f3a0, 1},
+ {{0x4717, 0x12dc, 0xef50, 0x3800, 0xa100, 0x4217, 0x2f0a, 0x8002, 0x3480, 0xa000, 0x431a, 0x3480, 0xa000, 0x491a, 0x34a0, 0xa000 }, 16, 0x0009f3c0, 1},
+ {{0x451a, 0x34a0, 0xa000, 0x451a, 0x3480, 0xa000, 0x471a, 0x3480, 0xa000, 0x4712, 0x3600, 0xa100, 0x53d4, 0xea50, 0x38c0, 0xa000 }, 16, 0x0009f3e0, 1},
+ {{0x4312, 0x2a09, 0x8002, 0x3640, 0xa000, 0x4519, 0xfa44, 0x3420, 0xa000, 0x4419, 0x3420, 0xa000, 0x4519, 0x3420, 0xa000, 0x4519 }, 16, 0x0009f400, 1},
+ {{0x4719, 0x3600, 0xa100, 0x4711, 0xeee9, 0x3600, 0xa100, 0x52d5, 0xee38, 0x96c0, 0x351a, 0x80ff, 0xf945, 0x7d42, 0xcd42, 0x90c0 }, 16, 0x0009f420, 1},
+ {{0x3420, 0xa000, 0xed19, 0x5695, 0x3480, 0xa000, 0x4696, 0x3480, 0xa000, 0x53d0, 0x371d, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7465 }, 16, 0x0009f440, 1},
+ {{0x96c0, 0xf9c5, 0x2402, 0x804a, 0x98c0, 0x0dc6, 0x38d0, 0x8008, 0xc8b6, 0x3680, 0xa100, 0xebe9, 0xe9e9, 0x36a0, 0xa000, 0xeb3c }, 16, 0x0009f460, 1},
+ {{0xed56, 0x3680, 0xa100, 0x4013, 0xe938, 0x13d5, 0x3022, 0x336c, 0x8009, 0x9ac0, 0x2d08, 0x8028, 0x90c0, 0x371f, 0x80ff, 0x7fc2 }, 16, 0x0009f480, 1},
+ {{0xcd47, 0x90c0, 0x3420, 0xa000, 0xed18, 0x5295, 0x3480, 0xa000, 0x4291, 0x52d0, 0x351e, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7466 }, 16, 0x0009f4a0, 1},
+ {{0x94c0, 0xf9c5, 0xcdae, 0x3022, 0x336c, 0x8009, 0x3a20, 0xa000, 0x0fc6, 0x38d0, 0x8008, 0xe8e9, 0xe83d, 0x3600, 0xa100, 0x4010 }, 16, 0x0009f4c0, 1},
+ {{0xef58, 0x3680, 0xa000, 0x56d7, 0xede9, 0x3c40, 0xa000, 0x3d1f, 0x80ff, 0xed7a, 0x2f08, 0x8028, 0x7fc2, 0xc357, 0x90c0, 0x34a0 }, 16, 0x0009f4e0, 1},
+ {{0xa000, 0xeb18, 0x3480, 0xa000, 0x5293, 0x4295, 0x52d0, 0x351c, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7464, 0x98c0, 0xf9c5, 0x08c6 }, 16, 0x0009f500, 1},
+ {{0x38d0, 0x8008, 0x3d20, 0x336c, 0x8009, 0x3680, 0xa000, 0xefe9, 0xe85a, 0x3680, 0xa000, 0xef72, 0xe942, 0x3680, 0xa000, 0x4017 }, 16, 0x0009f520, 1},
+ {{0xf945, 0x96c0, 0x53d0, 0x2808, 0x8028, 0x371a, 0x80ff, 0x7d42, 0xc552, 0x90c0, 0x3480, 0xa000, 0xed1d, 0x3480, 0xa000, 0x5495 }, 16, 0x0009f540, 1},
+ {{0x4491, 0x52d0, 0x351e, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7466, 0x3a40, 0xa000, 0xf9c5, 0x0cc6, 0x38d0, 0x8008, 0x2602, 0x8058 }, 16, 0x0009f560, 1},
+ {{0x3600, 0xa100, 0xe948, 0xec54, 0x0011, 0xede9, 0x36c0, 0xa000, 0x56d4, 0xed3e, 0x9ac0, 0x7f68, 0x3820, 0x336c, 0x8009, 0xf945 }, 16, 0x0009f580, 1},
+ {{0x3840, 0xa100, 0x7f42, 0x2c0c, 0x8028, 0xc656, 0x90c0, 0x3480, 0xa000, 0xee18, 0x3480, 0xa000, 0x5196, 0x4195, 0x3480, 0xa000 }, 16, 0x0009f5a0, 1},
+ {{0x51d4, 0x3ce8, 0x3244, 0x3d90, 0x800a, 0x7461, 0x96c0, 0xf9c5, 0x2002, 0x8052, 0x98c0, 0x0dc6, 0x38d0, 0x8008, 0xc8bc, 0x3680 }, 16, 0x0009f5c0, 1},
+ {{0xa100, 0xefe9, 0xebe9, 0x36a0, 0xa000, 0xef38, 0xed56, 0x3680, 0xa100, 0x4017, 0xeb38, 0x13d5, 0x3022, 0x336c, 0x8009, 0x96c0 }, 16, 0x0009f5e0, 1},
+ {{0x7de8, 0x2d08, 0x8028, 0x7dc2, 0xcd43, 0x90c0, 0x3420, 0xa000, 0xed18, 0x5695, 0x3480, 0xa000, 0x4693, 0x53d0, 0x3de8, 0x3244 }, 16, 0x0009f600, 1},
+ {{0x3d90, 0x800a, 0x7463, 0x94c0, 0xf9c5, 0xc8b6, 0x3820, 0xa000, 0x0ec6, 0x38d0, 0x8008, 0x3a80, 0xa000, 0xece9, 0x3d20, 0x336c }, 16, 0x0009f620, 1},
+ {{0x8009, 0x3680, 0xa100, 0xec38, 0xee58, 0x36c0, 0xa000, 0x4014, 0xcca0, 0x3680, 0xa000, 0x55d6, 0xe8e9, 0x3ae0, 0xa000, 0x7ee8 }, 16, 0x0009f640, 1},
+ {{0xe83c, 0x2e0b, 0x8028, 0x7ec2, 0xc455, 0x90c0, 0x3480, 0xa000, 0xec1d, 0x3480, 0xa000, 0x5594, 0x4590, 0x3480, 0xa000, 0x52d3 }, 16, 0x0009f660, 1},
+ {{0x3d68, 0x3244, 0x3d90, 0x800a, 0x7462, 0x3a40, 0xa000, 0xf9c5, 0x0cc6, 0x38d0, 0x8008, 0x3820, 0x336c, 0x8009, 0x3600, 0xa100 }, 16, 0x0009f680, 1},
+ {{0xede9, 0xec5a, 0x3840, 0xa100, 0xed7a, 0x2c0b, 0x8028, 0x4015, 0x3680, 0xa000, 0x52d4, 0xede9, 0x3d68, 0xed64, 0x7d42, 0xc052 }, 16, 0x0009f6a0, 1},
+ {{0x90c0, 0x3480, 0xa000, 0xe818, 0x3480, 0xa000, 0x5490, 0x4495, 0x3480, 0xa000, 0x57d3, 0x3fe8, 0x3244, 0x3d90, 0x800a, 0x7467 }, 16, 0x0009f6c0, 1},
+ {{0x98c0, 0xf9c5, 0x3bc0, 0x2282, 0x8008, 0x3a20, 0xa000, 0xfac4, 0x0dc6, 0x38d0, 0x8008, 0xe942, 0x4011, 0x15d3, 0x57d6, 0x9ac0 }, 16, 0x0009f6e0, 1},
+ {{0x3b19, 0x80ff, 0x90c0, 0x3f1d, 0x80ff, 0x96c0, 0x72e1, 0x2d09, 0x8002, 0x90c0, 0x94c2, 0x0907, 0xa0ff, 0x92c2, 0x4716, 0x16d7 }, 16, 0x0009f700, 1},
+ {{0x53d3, 0x9ac0, 0x3d1a, 0x80ff, 0x90c0, 0x371d, 0x80ff, 0x7165, 0x90c0, 0x94c2, 0x0906, 0xa0ff, 0x92c2, 0x4617, 0x3600, 0xa100 }, 16, 0x0009f720, 1},
+ {{0x54d3, 0x55d2, 0x9ac0, 0x391e, 0x80ff, 0x90c0, 0x3b1b, 0x80ff, 0x71e6, 0x90c0, 0x94c2, 0x0905, 0xa0ff, 0x3482, 0xa000, 0x4512 }, 16, 0x0009f740, 1},
+ {{0x12d7, 0x56d6, 0x9ac0, 0x351f, 0x80ff, 0x90c0, 0x3d1e, 0x80ff, 0x73e6, 0x90c0, 0x94c2, 0x0902, 0xa0ff, 0x92c2, 0x4217, 0x3680 }, 16, 0x0009f760, 1},
+ {{0xa000, 0x51d2, 0x53d6, 0x9ac0, 0x331c, 0x80ff, 0x90c0, 0x371a, 0x80ff, 0x7262, 0x90c0, 0x94c2, 0x0901, 0xa0ff, 0x3482, 0xa000 }, 16, 0x0009f780, 1},
+ {{0x4112, 0x3600, 0xa100, 0x54d7, 0x52d2, 0x9ac0, 0x391d, 0x80ff, 0x90c0, 0x3519, 0x80ff, 0x70e5, 0x90c0, 0x94c2, 0x0902, 0xa0ff }, 16, 0x0009f7a0, 1},
+ {{0x3482, 0xa000, 0x4212, 0x54d1, 0x391c, 0x8004, 0x6669, 0x92c3, 0x6c90, 0x94c3, 0x55d3, 0xc081, 0x94c3, 0x3b1e, 0x80ff, 0x96c3 }, 16, 0x0009f7c0, 1},
+ {{0x32e4, 0x2cb0, 0x8009, 0x94c3, 0xf601, 0xf602, 0x08c6, 0x38d0, 0x8008, 0x90c0, 0x2808, 0x8002, 0x55d0, 0x3b1e, 0x8008, 0x6769 }, 16, 0x0009f7e0, 1},
+ {{0x92c3, 0x6c90, 0x94c3, 0x55d6, 0xc082, 0x94c3, 0x3b1c, 0x80ff, 0x96c3, 0x32e4, 0x2cb0, 0x8009, 0x94c3, 0xf402, 0xf401, 0x0dc6 }, 16, 0x0009f800, 1},
+ {{0x38d0, 0x8008, 0x90c0, 0x2d08, 0x8002, 0x52d0, 0x351c, 0x8010, 0x6669, 0x92c3, 0x6c90, 0x94c3, 0x56d7, 0xc083, 0x94c3, 0x3d1f }, 16, 0x0009f820, 1},
+ {{0x80ff, 0x96c3, 0x32e4, 0x2cb0, 0x8009, 0x94c3, 0xf702, 0xf701, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0xed42, 0x55d5, 0x3b1b, 0x8020 }, 16, 0x0009f840, 1},
+ {{0x65e9, 0x92c3, 0x6c90, 0x3683, 0xa000, 0x55d2, 0xc084, 0x94c3, 0x3b1d, 0x80ff, 0x96c3, 0x32e4, 0x2cb0, 0x8009, 0x94c3, 0xf502 }, 16, 0x0009f860, 1},
+ {{0xf501, 0x98c0, 0x3fc0, 0x26a0, 0x8008, 0xc784, 0x3ec0, 0x2360, 0x8008, 0x3204, 0x2f80, 0x800b, 0xe8ef, 0x3204, 0x2e90, 0x800b }, 16, 0x0009f880, 1},
+ {{0xe8ee, 0x9ac0, 0x2f0f, 0x80d0, 0x7be1, 0x2e0e, 0x80d0, 0x67ea, 0x81e3, 0x9ac0, 0x6c10, 0xc381, 0x36a1, 0x2800, 0x8008, 0x03c1 }, 16, 0x0009f8a0, 1},
+ {{0x38b6, 0x8008, 0x32e4, 0x3050, 0x8009, 0x06c2, 0x3104, 0x8008, 0x32e4, 0x3050, 0x8009, 0x6c10, 0xfac3, 0x9ac0, 0x6f10, 0x07c5 }, 16, 0x0009f8c0, 1},
+ {{0x38b8, 0x8008, 0xc081, 0x3567, 0x3840, 0x3160, 0x8008, 0x3d41, 0x03c5, 0x38bc, 0x8008, 0x9ac0, 0x65e9, 0xcd42, 0x06c1, 0x38bc }, 16, 0x0009f8e0, 1},
+ {{0x8008, 0x90c0, 0xed18, 0x5d15, 0xcd4f, 0x92c3, 0xedfc, 0x94c7, 0xeaf1, 0xcd4f, 0x2418, 0x85ce, 0x07c0, 0x38ae, 0x8008, 0x33e4 }, 16, 0x0009f900, 1},
+ {{0x2290, 0x8009, 0x98c0, 0x06c5, 0x38b7, 0x8008, 0xfac3, 0x2769, 0xc081, 0x90c0, 0x98c7, 0x32e4, 0x22d0, 0x8009, 0x5192, 0x96c3 }, 16, 0x0009f920, 1},
+ {{0x01c2, 0x3100, 0x8008, 0x94c0, 0xfac3, 0xc685, 0x94c0, 0xf601, 0xe838, 0x32e4, 0x23c0, 0x8009, 0xe9ea, 0x98c0, 0x6469, 0x6f10 }, 16, 0x0009f940, 1},
+ {{0xfac3, 0xc081, 0x94c0, 0xc2ff, 0x8413, 0x33e4, 0x2290, 0x8009, 0x31e4, 0x3ee2, 0x8009, 0x98c0, 0x0dc6, 0x38d0, 0x8008, 0xceb4 }, 16, 0x0009f960, 1},
+ {{0x98c0, 0x01c6, 0x3100, 0x8008, 0xea48, 0x3c20, 0xa004, 0x32cb, 0x8041, 0xc183, 0x2d0d, 0x8078, 0x15d5, 0x38c8, 0x3c10, 0xbfff }, 16, 0x0009f980, 1},
+ {{0x3c80, 0xa000, 0x3b5b, 0x8000, 0xeded, 0x2000, 0x8080, 0x9ac0, 0x3453, 0x8000, 0xed3e, 0x2602, 0x8052, 0x3a40, 0xa000, 0x39a0 }, 16, 0x0009f9a0, 1},
+ {{0x3c00, 0x8008, 0xc685, 0x3826, 0xa000, 0xc490, 0x2202, 0x805c, 0x3e66, 0xa008, 0x90c0, 0xc587, 0x04c0, 0x38b2, 0x8008, 0x65e9 }, 16, 0x0009f9c0, 1},
+ {{0x3a40, 0xa000, 0x3111, 0x2000, 0x8000, 0xc286, 0x94c2, 0x5590, 0xc481, 0x96c1, 0xc582, 0x3acb, 0x82c0, 0x98c6, 0x3bc0, 0x22f2 }, 16, 0x0009f9e0, 1},
+ {{0x8008, 0xd643, 0x3a46, 0xa100, 0x90c0, 0xed3a, 0x38cd, 0x8743, 0x3675, 0x03c4, 0x38b2, 0x8008, 0x3e00, 0xa826, 0x2b0f, 0x8002 }, 16, 0x0009fa00, 1},
+ {{0x6c7d, 0x68b9, 0x6bae, 0xc843, 0x3e00, 0xb000, 0x7a61, 0x6aad, 0x3022, 0x336c, 0x8009, 0xc453, 0x3800, 0xa088, 0x7e42, 0x683d }, 16, 0x0009fa20, 1},
+ {{0xe8fc, 0x3600, 0xa100, 0xce44, 0xecfe, 0x90c0, 0xee19, 0x4196, 0x54da, 0x4413, 0x431f, 0x461f, 0x431f, 0x431f, 0x421f, 0x4217 }, 16, 0x0009fa40, 1},
+ {{0x14da, 0xef50, 0x96c0, 0x4417, 0x2f0e, 0x8002, 0x3420, 0xa000, 0x411e, 0x481e, 0x431e, 0x431e, 0x421e, 0x4216, 0x11da, 0xee50 }, 16, 0x0009fa60, 1},
+ {{0x96c0, 0x4116, 0x2e08, 0x8002, 0x3420, 0xa000, 0x4718, 0x3420, 0xa000, 0x4c18, 0x4318, 0x4318, 0x4218, 0x4210, 0x11d2, 0xe850 }, 16, 0x0009fa80, 1},
+ {{0x96c0, 0x4110, 0x2809, 0x8002, 0x0519, 0xf846, 0x3420, 0xa000, 0x4019, 0x4319, 0x4319, 0x4219, 0x3600, 0xa100, 0x4211, 0xefe9 }, 16, 0x0009faa0, 1},
+ {{0x36c0, 0xa100, 0x56d5, 0xef3e, 0x96c0, 0x3d1a, 0x80ff, 0xf947, 0x7d42, 0xc352, 0x90c0, 0x34a0, 0xa000, 0xeb18, 0x3480, 0xa000 }, 16, 0x0009fac0, 1},
+ {{0x5193, 0x3480, 0xa000, 0x4197, 0x56d5, 0x3d19, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7461, 0x96c0, 0xf9c7, 0x2202, 0x804a, 0x3a20 }, 16, 0x0009fae0, 1},
+ {{0xa000, 0x0ec6, 0x38d0, 0x8008, 0xcdb6, 0x3680, 0xa100, 0xebe9, 0xefe9, 0x36a0, 0xa100, 0xeb3a, 0xee5e, 0x3680, 0xa100, 0x4013 }, 16, 0x0009fb00, 1},
+ {{0xef3d, 0x3a80, 0xa000, 0x51d6, 0x3022, 0x336c, 0x8009, 0x3c20, 0xa000, 0x2e0d, 0x8028, 0x90c0, 0x331b, 0x80ff, 0x7dc2, 0xc653 }, 16, 0x0009fb20, 1},
+ {{0x90c0, 0x34a0, 0xa000, 0xee18, 0x3480, 0xa000, 0x5296, 0x3480, 0xa000, 0x4297, 0x55d5, 0x3b1a, 0x80ff, 0x3244, 0x3d90, 0x800a }, 16, 0x0009fb40, 1},
+ {{0x7462, 0x3640, 0xa000, 0xf9c7, 0xcaae, 0x3820, 0xa000, 0x0bc6, 0x38d0, 0x8008, 0x98c0, 0xede9, 0x3622, 0x336c, 0x8009, 0x3860 }, 16, 0x0009fb60, 1},
+ {{0xa100, 0xed3a, 0x2b0f, 0x8020, 0x3600, 0xa100, 0x4015, 0xe8e9, 0x3680, 0xa100, 0x53d7, 0xe87a, 0x3c20, 0xa000, 0x2f0d, 0x8028 }, 16, 0x0009fb80, 1},
+ {{0x90c0, 0x371b, 0x80ff, 0x7dc2, 0xc453, 0x90c0, 0x34a0, 0xa000, 0xec1e, 0x3480, 0xa000, 0x5494, 0x3480, 0xa000, 0x4490, 0x51d5 }, 16, 0x0009fba0, 1},
+ {{0x331c, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7464, 0x3a40, 0xa000, 0xf9c7, 0x0dc6, 0x38d0, 0x8008, 0x3d20, 0x336c, 0x8009, 0x38c0 }, 16, 0x0009fbc0, 1},
+ {{0xa100, 0xefe9, 0x2d0a, 0x8022, 0x38c0, 0xa100, 0xef72, 0x2a08, 0x8028, 0x3680, 0xa000, 0x4017, 0xe942, 0x3680, 0xa000, 0x54d2 }, 16, 0x0009fbe0, 1},
+ {{0xf947, 0x391c, 0x80ff, 0x7e42, 0xc254, 0x90c0, 0x3480, 0xa000, 0xea1d, 0x3480, 0xa000, 0x5692, 0x4691, 0x3480, 0xa000, 0x51d0 }, 16, 0x0009fc00, 1},
+ {{0x331e, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7466, 0x3a40, 0xa000, 0xf9c7, 0x09c6, 0x38d0, 0x8008, 0x3622, 0x336c, 0x8009, 0x3600 }, 16, 0x0009fc20, 1},
+ {{0xa100, 0xe948, 0xe95c, 0x96c0, 0x4011, 0x2002, 0x8058, 0x3680, 0xa000, 0x51d1, 0xede9, 0x3ae0, 0xa000, 0x7ce8, 0xed38, 0x2909 }, 16, 0x0009fc40, 1},
+ {{0x8028, 0x3cc2, 0xf947, 0xc451, 0x90c0, 0x34a0, 0xa000, 0xec1e, 0x3480, 0xa000, 0x5594, 0x4595, 0x3480, 0xa000, 0x56d1, 0x3f68 }, 16, 0x0009fc60, 1},
+ {{0x3244, 0x3d90, 0x800a, 0x7466, 0x96c0, 0xf9c7, 0x2102, 0x8052, 0x3a20, 0xa000, 0x08c6, 0x38d0, 0x8008, 0xcdbc, 0x3a80, 0xa000 }, 16, 0x0009fc80, 1},
+ {{0xede9, 0x3222, 0x336c, 0x8009, 0x36a0, 0xa100, 0xed39, 0xe85e, 0x3480, 0xa000, 0x4015, 0x3680, 0xa100, 0x52d0, 0xede9, 0x3600 }, 16, 0x0009fca0, 1},
+ {{0xa100, 0x7d68, 0xed3d, 0x3840, 0xa000, 0x7d42, 0x280d, 0x8028, 0xc352, 0x90c0, 0x34a0, 0xa000, 0xeb1a, 0x3480, 0xa000, 0x5493 }, 16, 0x0009fcc0, 1},
+ {{0x3480, 0xa000, 0x4495, 0x54d5, 0x3e68, 0x3244, 0x3d90, 0x800a, 0x7464, 0x3640, 0xa000, 0xf9c7, 0xcab6, 0x3a20, 0xa000, 0x0ec6 }, 16, 0x0009fce0, 1},
+ {{0x38d0, 0x8008, 0xcda0, 0x3a80, 0xa000, 0xebe9, 0x3122, 0x336c, 0x8009, 0x38e0, 0xa100, 0xeb3a, 0x2e0d, 0x8020, 0x3680, 0xa100 }, 16, 0x0009fd00, 1},
+ {{0x4013, 0xece9, 0x3680, 0xa100, 0x54d5, 0xec3d, 0x3840, 0xa000, 0x7e68, 0x2d0d, 0x8028, 0x7e42, 0xc754, 0x90c0, 0x34a0, 0xa000 }, 16, 0x0009fd20, 1},
+ {{0xef19, 0x3480, 0xa000, 0x5697, 0x3480, 0xa000, 0x4694, 0x52d5, 0x3d68, 0x3244, 0x3d90, 0x800a, 0x7462, 0x3a40, 0xa000, 0xf9c7 }, 16, 0x0009fd40, 1},
+ {{0x0ec6, 0x38d0, 0x8008, 0x3322, 0x336c, 0x8009, 0x3840, 0xa100, 0xede9, 0x2e0a, 0x8022, 0x3840, 0xa100, 0xed7a, 0x2a0c, 0x8028 }, 16, 0x0009fd60, 1},
+ {{0x4015, 0x3680, 0xa000, 0x54d2, 0xede9, 0x3e68, 0xed64, 0x7e42, 0xc554, 0x90c0, 0x34a0, 0xa000, 0xed1b, 0x3480, 0xa000, 0x5595 }, 16, 0x0009fd80, 1},
+ {{0x4595, 0x3480, 0xa000, 0x51d4, 0x3ce8, 0x3244, 0x3d90, 0x800a, 0x7461, 0x98c0, 0xf9c7, 0x0dc6, 0x38d0, 0x8008, 0x3bc0, 0x22f2 }, 16, 0x0009fda0, 1},
+ {{0x8008, 0x96c0, 0xe942, 0x2d0d, 0x8002, 0x4011, 0x56d5, 0x3d1a, 0x8040, 0x6569, 0x90c0, 0x94c3, 0x56d3, 0xc181, 0x96c3, 0x3d1d }, 16, 0x0009fdc0, 1},
+ {{0x80ff, 0xc081, 0x96c3, 0x32e4, 0x2cb0, 0x8009, 0x94c3, 0xf502, 0xf501, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0d, 0x8002, 0x55d5 }, 16, 0x0009fde0, 1},
+ {{0x3b1a, 0x8080, 0x6569, 0x90c0, 0x94c3, 0x56d7, 0xc181, 0x96c3, 0x3d1a, 0x80ff, 0xc082, 0x96c3, 0x32e4, 0x2cb0, 0x8009, 0x94c3 }, 16, 0x0009fe00, 1},
+ {{0xf202, 0xf201, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0d, 0x8002, 0x52d5, 0x351b, 0x8100, 0x65e9, 0x90c0, 0x94c3, 0x55d6, 0xc181 }, 16, 0x0009fe20, 1},
+ {{0x96c3, 0x3b1c, 0x80ff, 0xc083, 0x96c3, 0x32e4, 0x2cb0, 0x8009, 0x94c3, 0xf402, 0xf401, 0x98c0, 0x0dc6, 0x38d0, 0x8008, 0xf8c6 }, 16, 0x0009fe40, 1},
+ {{0x90c0, 0xed42, 0x56d5, 0x3d1c, 0x8200, 0x6669, 0x90c0, 0x94c3, 0x53d0, 0xc084, 0x96c3, 0x371d, 0x80ff, 0xc181, 0x96c3, 0x32e4 }, 16, 0x0009fe60, 1},
+ {{0x2cb0, 0x8009, 0x94c3, 0xf501, 0xf502, 0x98c0, 0x3ec0, 0x29e0, 0x8008, 0xc684, 0x3fc0, 0x2d20, 0x8008, 0x3204, 0x2f80, 0x800b }, 16, 0x0009fe80, 1},
+ {{0xe8ee, 0x3204, 0x2e90, 0x800b, 0xe8ef, 0x9ac0, 0x2e0e, 0x80d0, 0x7b61, 0x2f0f, 0x80d0, 0x676a, 0x81e3, 0x98c0, 0xc281, 0x34a1 }, 16, 0x0009fea0, 1},
+ {{0x2000, 0x8008, 0x98c0, 0xc081, 0x02c1, 0x38ba, 0x8008, 0x32e4, 0x3050, 0x8009, 0x04c2, 0x3118, 0x8008, 0x32e4, 0x3050, 0x8009 }, 16, 0x0009fec0, 1},
+ {{0xc081, 0x01c5, 0x38bb, 0x8008, 0x36e1, 0x3d40, 0x3160, 0x8008, 0x3ec1, 0x04c5, 0x38bc, 0x8008, 0x9ac0, 0x6669, 0xc845, 0x01c5 }, 16, 0x0009fee0, 1},
+ {{0x38b8, 0x8008, 0x3661, 0x01c5, 0x38bb, 0x8008, 0x3761, 0xe81d, 0x5d10, 0xcd4a, 0x98c7, 0x02c0, 0x38ac, 0x8008, 0xedfc, 0x92c3 }, 16, 0x0009ff00, 1},
+ {{0xcd4a, 0x98c7, 0x6669, 0x02c0, 0x38ac, 0x8008, 0x8407, 0x6769, 0xd3da, 0x98c0, 0x7777, 0x74f2, 0xc0b0, 0xc290, 0x7656, 0x2c7d }, 16, 0x0009ff20, 1},
+ {{0x00c4, 0x38ae, 0x8008, 0x7754, 0x2e7c, 0x3224, 0x3880, 0x800a, 0xf601, 0x96c0, 0x7456, 0x27e8, 0x9fe0, 0xe7e8, 0x94c0, 0x9e21 }, 16, 0x0009ff40, 1},
+ {{0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x0009ff60, 1},
+ {{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x96c0, 0xc0a6, 0x270d, 0x8038, 0x32e4, 0x3a68, 0x8001, 0xe7ed, 0x98c0, 0x3e00 }, 16, 0x0009ff80, 1},
+ {{0x20ec, 0x8008, 0xc784, 0x38a8, 0x3c20, 0xbfff, 0x0226, 0x3350, 0x8009, 0x0296, 0x3d00, 0x20ec, 0x8008, 0x1a90, 0x3c00, 0x20ec }, 16, 0x0009ffa0, 1},
+ {{0x8008, 0x0a22, 0x3350, 0x8009, 0x1b95, 0x3dc0, 0x2282, 0x8008, 0x3ec0, 0x21c0, 0x8008, 0x98c0, 0xea3b, 0x32c2, 0x30d0, 0x8008 }, 16, 0x0009ffc0, 1},
+ {{0x3600, 0xa100, 0x4a94, 0xe8ed, 0x13d5, 0x0424, 0x3364, 0x8009, 0x9ac0, 0x371a, 0x8700, 0x7a41, 0x2d0a, 0x8004, 0x96c0, 0x3412 }, 16, 0x0009ffe0, 1},
+ {{0x8600, 0x5f12, 0x2618, 0x8168, 0x98c0, 0x0420, 0x3364, 0x8009, 0xc490, 0x98c0, 0xea44, 0x09c6, 0x3104, 0x8008, 0x1612, 0xc948 }, 16, 0x000a0000, 1},
+ {{0x9ac0, 0x676a, 0x05c4, 0x38b0, 0x8008, 0xeffc, 0x96c0, 0x6815, 0xef19, 0x841d, 0x96c0, 0x9b46, 0x2b03, 0x800a, 0xc840, 0x521f }, 16, 0x000a0020, 1},
+ {{0x92d0, 0x421e, 0x5718, 0x471e, 0x9ac0, 0x2a08, 0x8014, 0x90c0, 0x2a0b, 0x8018, 0x14d0, 0xc194, 0x96c0, 0x391e, 0x8700, 0x5813 }, 16, 0x000a0040, 1},
+ {{0x96c0, 0x3416, 0x8600, 0xeb44, 0x94c0, 0x5213, 0x843f, 0x9ac0, 0x656a, 0x0fc6, 0x3104, 0x8008, 0xe8fc, 0x98c0, 0xcf4e, 0x07c4 }, 16, 0x000a0060, 1},
+ {{0x38b0, 0x8008, 0x8422, 0x9ac0, 0x6b07, 0xe81f, 0x3bc0, 0x2040, 0x8008, 0x96c0, 0x9b42, 0x2b03, 0x800a, 0xcf46, 0x5418, 0x92d0 }, 16, 0x000a0080, 1},
+ {{0x441b, 0x541f, 0x441b, 0x9ac0, 0x2a09, 0x8030, 0x90c0, 0x2a08, 0x8034, 0x12d1, 0xc798, 0x96c0, 0x351e, 0x8700, 0x5c10, 0x96c0 }, 16, 0x000a00a0, 1},
+ {{0x3416, 0x8600, 0xe844, 0x94c0, 0x5310, 0x843f, 0x9ac0, 0x65ea, 0x0bc6, 0x3104, 0x8008, 0xecfc, 0x98c0, 0xcb49, 0x05c4, 0x38b0 }, 16, 0x000a00c0, 1},
+ {{0x8008, 0x8422, 0x9ac0, 0x689b, 0xec1b, 0x38a0, 0x3e00, 0x8008, 0x96c0, 0x9b43, 0x2b03, 0x800a, 0xcf41, 0x551c, 0x92d0, 0x4518 }, 16, 0x000a00e0, 1},
+ {{0x551f, 0x4518, 0x9ac0, 0x2a09, 0x804c, 0x90c0, 0x2a0c, 0x8050, 0x15d1, 0xc09c, 0x96c0, 0x3b1d, 0x8700, 0x5914, 0x96c0, 0x3415 }, 16, 0x000a0100, 1},
+ {{0x8600, 0xec44, 0x96c0, 0x5214, 0x2718, 0x8148, 0x9ac0, 0x656a, 0x0cc6, 0x3104, 0x8008, 0xe9fc, 0x98c0, 0xcc4e, 0x07c4, 0x38b0 }, 16, 0x000a0120, 1},
+ {{0x8008, 0x2618, 0x812a, 0x9ac0, 0x6b03, 0xe91c, 0x3fa0, 0x3f80, 0x8008, 0x96c0, 0x9b42, 0x2b03, 0x800a, 0xc846, 0x5419, 0x92d0 }, 16, 0x000a0140, 1},
+ {{0x441f, 0x5618, 0x461f, 0x3104, 0x226c, 0x800a, 0x96c0, 0xfd45, 0x2d0e, 0x8008, 0x3a80, 0xa000, 0xe9ee, 0x3fc0, 0x26a0, 0x8008 }, 16, 0x000a0160, 1},
+ {{0x3480, 0xa000, 0xe964, 0x3680, 0xa100, 0x51d0, 0x5b11, 0x98c0, 0x331e, 0x8700, 0x5416, 0x5316, 0x3880, 0xa000, 0x3416, 0x8400 }, 16, 0x000a0180, 1},
+ {{0x5a92, 0x848d, 0x9ac0, 0x666a, 0xebfc, 0x0cc6, 0x3104, 0x8008, 0x8417, 0x9f44, 0x98c0, 0x3ac0, 0x34dc, 0x8008, 0xeb1c, 0x90c0 }, 16, 0x000a01a0, 1},
+ {{0x92d0, 0x90a3, 0x401a, 0x98c0, 0x00c4, 0x38b4, 0x8008, 0xff42, 0x94c0, 0xf402, 0xf001, 0x3a40, 0xa000, 0x39c0, 0x359c, 0x8008 }, 16, 0x000a01c0, 1},
+ {{0xf946, 0x98c0, 0xc25e, 0x3204, 0x2fd0, 0x800b, 0x3a40, 0xa000, 0x38c0, 0x34dc, 0x8008, 0xf847, 0x1816, 0xc256, 0x3640, 0xa000 }, 16, 0x000a01e0, 1},
+ {{0xc84c, 0xf9c6, 0x3c00, 0xa100, 0x7e41, 0x5b92, 0x38c0, 0x359c, 0x8008, 0x3640, 0xa000, 0x666a, 0xf8c7, 0x8431, 0x9f44, 0x90c0 }, 16, 0x000a0200, 1},
+ {{0x90c0, 0x92d0, 0x5518, 0x451b, 0x3104, 0x224a, 0x800a, 0x9ac0, 0x65ea, 0x08c6, 0x3104, 0x8008, 0xebfc, 0x8410, 0xeb18, 0x9f43 }, 16, 0x000a0220, 1},
+ {{0x90c0, 0x90c0, 0x92d0, 0x531b, 0x431a, 0x3880, 0xa000, 0x7be1, 0xee5c, 0xe85c, 0x3a00, 0xa100, 0x67ea, 0xe95c, 0x2f0f, 0x80d0 }, 16, 0x000a0240, 1},
+ {{0x3880, 0xa000, 0xea44, 0x2dff, 0x9f27, 0xfdc5, 0x98c0, 0x05c4, 0x38ae, 0x8008, 0xc684, 0x98c0, 0xd2a8, 0x3ec0, 0x30d0, 0x8008 }, 16, 0x000a0260, 1},
+ {{0x8431, 0x98c0, 0x3f20, 0x2528, 0x8009, 0xfd45, 0x92c0, 0x90c0, 0x189f, 0xc390, 0x3224, 0x3a38, 0x800a, 0x1996, 0xf301, 0x9760 }, 16, 0x000a0280, 1},
+ {{0x5b9e, 0x92d0, 0x5718, 0x471b, 0x7b61, 0x676a, 0x81e5, 0xfdc5, 0x98c0, 0x0425, 0x336a, 0x8009, 0xfd45, 0x75e4, 0xd1a1, 0x90c0 }, 16, 0x000a02a0, 1},
+ {{0x96c2, 0x3344, 0x3ad0, 0x800a, 0x94c0, 0xfdc5, 0xc684, 0x94c0, 0xc189, 0xf648, 0x3800, 0xa100, 0xf149, 0x2d0c, 0x8002, 0x3840 }, 16, 0x000a02c0, 1},
+ {{0xa000, 0xc781, 0x2c0e, 0x8004, 0x2e0f, 0x800c, 0x3680, 0xa000, 0x2f09, 0x8004, 0x3aa0, 0xa000, 0xeee9, 0x3222, 0x2538, 0x8009 }, 16, 0x000a02e0, 1},
+ {{0x3a80, 0xa000, 0xee68, 0x30c2, 0x2360, 0x8008, 0x15d5, 0x5b16, 0x3a80, 0xa100, 0x3b1d, 0x8700, 0x5996, 0x5851, 0x98c0, 0x3415 }, 16, 0x000a0300, 1},
+ {{0x8400, 0xebfc, 0x5697, 0x94c0, 0xcb4c, 0x84e1, 0x98c0, 0xf642, 0x38c0, 0x2100, 0x8008, 0x94c0, 0xf105, 0xf001, 0x94c0, 0xf406 }, 16, 0x000a0320, 1},
+ {{0xf707, 0x3640, 0xa000, 0xfd45, 0xf84a, 0x3660, 0xa000, 0xfc4b, 0xf94c, 0x32e4, 0x208e, 0x800a, 0x3620, 0xa000, 0xfe4d, 0xc25e }, 16, 0x000a0340, 1},
+ {{0x3640, 0xa000, 0x5816, 0xf8ca, 0x98c0, 0xc84c, 0x3cc0, 0x2100, 0x8008, 0x7e41, 0x266a, 0x36d4, 0xe8ec, 0x96c0, 0x76c5, 0x5858 }, 16, 0x000a0360, 1},
+ {{0x8425, 0x3ae1, 0x3c62, 0x7ce2, 0x9f45, 0x90c0, 0x2103, 0x8010, 0x94d0, 0x485c, 0x5858, 0x3c62, 0x7ce2, 0xc781, 0x4854, 0x3620 }, 16, 0x000a0380, 1},
+ {{0xa000, 0xf842, 0xf441, 0x39c0, 0x371c, 0x8008, 0x3204, 0x2ee0, 0x800b, 0x38c0, 0x2100, 0x8008, 0x3a20, 0xa000, 0xfccb, 0x0bc6 }, 16, 0x000a03a0, 1},
+ {{0x3104, 0x8008, 0x3620, 0xa000, 0xf8ca, 0x5316, 0x3820, 0xa100, 0x65ea, 0x5814, 0xf9cc, 0x3620, 0xa000, 0xfecd, 0xfdc5, 0x94c0 }, 16, 0x000a03c0, 1},
+ {{0xe8fc, 0xc256, 0x96c0, 0xe81b, 0x2718, 0x81ea, 0x9f43, 0x3bc0, 0x371c, 0x8008, 0x90c0, 0x92d0, 0x511b, 0x9180, 0x98c0, 0xc781 }, 16, 0x000a03e0, 1},
+ {{0x3104, 0x25ce, 0x800a, 0x3a00, 0xa100, 0x3415, 0x8600, 0x5a16, 0x5996, 0x3680, 0xa000, 0x5851, 0x84b1, 0x1697, 0xeafc, 0x94c0 }, 16, 0x000a0400, 1},
+ {{0xca4c, 0xf642, 0x94c0, 0xf001, 0xf406, 0x98c0, 0x38c0, 0x2100, 0x8008, 0xf105, 0x94c0, 0xf707, 0xfd45, 0x3660, 0xa000, 0xf84a }, 16, 0x000a0420, 1},
+ {{0xfc4b, 0x98c0, 0xc25e, 0x32e4, 0x208e, 0x800a, 0x3660, 0xa000, 0xf94c, 0xfe4d, 0x3620, 0xa000, 0xfccb, 0xc256, 0x98c0, 0x06c4 }, 16, 0x000a0440, 1},
+ {{0x38b0, 0x8008, 0xf3c9, 0x3c00, 0xa100, 0x6b2e, 0x5c14, 0x0bc6, 0x3104, 0x8008, 0x3640, 0xa000, 0xc946, 0xf9cc, 0x1516, 0xecfc }, 16, 0x000a0460, 1},
+ {{0x96c0, 0x66ea, 0xe9fc, 0xfdc5, 0x3a20, 0xa000, 0xf8ca, 0x3ac0, 0x2100, 0x8008, 0x96c0, 0xe91b, 0x2618, 0x813a, 0x3620, 0xa000 }, 16, 0x000a0480, 1},
+ {{0xfecd, 0xec1b, 0x96c0, 0x9b45, 0x2b03, 0x800a, 0x90c0, 0x551a, 0x92d0, 0x451c, 0x531a, 0x4319, 0x98c0, 0xc781, 0x3104, 0x25ce }, 16, 0x000a04a0, 1},
+ {{0x800a, 0x1616, 0x01c4, 0x38ae, 0x8008, 0x3800, 0xa100, 0xd0a8, 0x5996, 0x5597, 0x94c6, 0x84a1, 0x7f41, 0x3680, 0xa000, 0x5851 }, 16, 0x000a04c0, 1},
+ {{0xf606, 0x94c0, 0xf542, 0xf707, 0x94c0, 0xf105, 0xf001, 0x98c0, 0x38c0, 0x2100, 0x8008, 0xfd45, 0x3660, 0xa000, 0xf84a, 0xfc4b }, 16, 0x000a04e0, 1},
+ {{0x98c0, 0xc25e, 0x32e4, 0x208e, 0x800a, 0x3660, 0xa000, 0xf94c, 0xfe4d, 0x94c0, 0xc256, 0xc290, 0x98c0, 0xf201, 0x39c0, 0x2100 }, 16, 0x000a0500, 1},
+ {{0x8008, 0x3224, 0x3990, 0x800a, 0x3480, 0xa000, 0x5892, 0x3620, 0xa000, 0xfccb, 0xc256, 0x3a20, 0xa000, 0xf8ca, 0x0ac6, 0x3104 }, 16, 0x000a0520, 1},
+ {{0x8008, 0x3680, 0xa100, 0x5c14, 0x5892, 0x9750, 0x94c0, 0xe84c, 0xecfc, 0x3640, 0xa000, 0x5b90, 0xfecd, 0x3640, 0xa000, 0xfdc5 }, 16, 0x000a0540, 1},
+ {{0xf9cc, 0xec1a, 0x92d0, 0x531b, 0x431c, 0x98c0, 0xc781, 0x3104, 0x25ce, 0x800a, 0x3a80, 0xa000, 0x5814, 0x0bc6, 0x3104, 0x8008 }, 16, 0x000a0560, 1},
+ {{0x3680, 0xa000, 0x5851, 0xf606, 0x94c0, 0xe8fc, 0xf105, 0x94c0, 0xf542, 0xf001, 0x94c0, 0xe81b, 0xf707, 0x3640, 0xa000, 0xfd45 }, 16, 0x000a0580, 1},
+ {{0xf84a, 0x3660, 0xa000, 0xfc4b, 0xf94c, 0x32e4, 0x208e, 0x800a, 0x3620, 0xa000, 0xfe4d, 0xc25e, 0x94c0, 0xfdc5, 0xc256, 0x3660 }, 16, 0x000a05a0, 1},
+ {{0xa000, 0xf8ca, 0xfccb, 0x3660, 0xa000, 0xf9cc, 0xfecd, 0x94c0, 0xf2c8, 0xf3c9, 0x3a00, 0xa100, 0x7961, 0x79c2, 0xed5c, 0xee5c }, 16, 0x000a05c0, 1},
+ {{0x3880, 0xa000, 0x656a, 0xf349, 0xe95c, 0x94c0, 0xef5c, 0xf248, 0x3600, 0xa100, 0xee5c, 0xec5c, 0x2cff, 0x9d15, 0x38c0, 0xa100 }, 16, 0x000a05e0, 1},
+ {{0xea44, 0x2808, 0x80d0, 0x9ac0, 0x6c10, 0x39e8, 0x2c0c, 0xbfff, 0xc181, 0x0bc6, 0x310c, 0x8008, 0x1491, 0x36a1, 0x2800, 0x8008 }, 16, 0x000a0600, 1},
+ {{0x96c0, 0x38cd, 0x8200, 0xeb41, 0x66e9, 0x8429, 0x01c1, 0x38b6, 0x8008, 0x0bc2, 0x310c, 0x8008, 0x32e4, 0x3050, 0x8009, 0x06c2 }, 16, 0x000a0620, 1},
+ {{0x3104, 0x8008, 0x32e4, 0x3050, 0x8009, 0x6c10, 0x3104, 0x265a, 0x800a, 0x32e4, 0x3050, 0x8009, 0x6c10, 0x27e9, 0x9fc8, 0xe7e9 }, 16, 0x000a0640, 1},
+ {{0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a0660, 1},
+ {{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x96c0, 0xc0a2, 0x270b, 0x8038, 0x32e4, 0x3a68, 0x8001, 0xe7eb, 0x98c0, 0x38a8 }, 16, 0x000a0680, 1},
+ {{0x3c20, 0xbfff, 0xc090, 0x0e26, 0x3350, 0x8009, 0x1990, 0x3c00, 0x20f8, 0x8008, 0x0922, 0x335c, 0x8009, 0x98c0, 0xe93e, 0x36c2 }, 16, 0x000a06a0, 1},
+ {{0x22f2, 0x8008, 0x0994, 0x3ac0, 0x341c, 0x8008, 0x3a80, 0xa000, 0x55d6, 0x0324, 0x3366, 0x8009, 0x3e60, 0xa100, 0x2e0e, 0x8004 }, 16, 0x000a06c0, 1},
+ {{0x79c1, 0x3b1a, 0x8700, 0xe8ee, 0x3c40, 0xa000, 0x3412, 0x8600, 0x5916, 0x2e0f, 0x8008, 0x2618, 0x8140, 0x98c0, 0x0320, 0x3366 }, 16, 0x000a06e0, 1},
+ {{0x8009, 0xee44, 0x1116, 0x0dc6, 0x3118, 0x8008, 0x96c0, 0x64ea, 0xcd4d, 0xe9fc, 0x98c0, 0x07c4, 0x38b2, 0x8008, 0xe91d, 0x94c0 }, 16, 0x000a0700, 1},
+ {{0x6a83, 0x841b, 0x96c0, 0x9b41, 0x2b03, 0x800a, 0xcb45, 0x5519, 0x92d0, 0x451a, 0x501b, 0x401a, 0x9ac0, 0x2e08, 0x8014, 0x90c0 }, 16, 0x000a0720, 1},
+ {{0x2e0c, 0x8018, 0x12d0, 0xc094, 0x96c0, 0x351c, 0x8700, 0x5f14, 0x98c0, 0x3414, 0x8600, 0xec44, 0xcd4c, 0x96c0, 0x6a03, 0x5514 }, 16, 0x000a0740, 1},
+ {{0x842f, 0x9ac0, 0x66ea, 0xeffc, 0x38c0, 0x37dc, 0x8008, 0x94c0, 0xef1d, 0x841b, 0x96c0, 0x9b45, 0x2b03, 0x800a, 0xc944, 0x561f }, 16, 0x000a0760, 1},
+ {{0x92d0, 0x4618, 0x5619, 0x4618, 0x9ac0, 0x2e09, 0x8030, 0x90c0, 0x2e08, 0x8034, 0x13d1, 0xc698, 0x98c0, 0x371b, 0x8700, 0x5b10 }, 16, 0x000a0780, 1},
+ {{0xcd48, 0x98c0, 0x3413, 0x8600, 0x681f, 0xe844, 0x94c0, 0x5110, 0x842d, 0x9ac0, 0x64ea, 0xebfc, 0x3ac0, 0x311c, 0x8008, 0x94c0 }, 16, 0x000a07a0, 1},
+ {{0xeb1d, 0x841b, 0x96c0, 0x9b41, 0x2b03, 0x800a, 0xc840, 0x501b, 0x92d0, 0x401a, 0x5618, 0x461a, 0x96c0, 0xc69c, 0x2e0b, 0x804c }, 16, 0x000a07c0, 1},
+ {{0x15d3, 0x38c0, 0x22da, 0x8008, 0x9ac0, 0x2e0b, 0x8054, 0x90c0, 0x3b19, 0x8700, 0x98c0, 0x3411, 0x8600, 0xcd49, 0x5c10, 0x98c0 }, 16, 0x000a07e0, 1},
+ {{0x689f, 0x5413, 0x2718, 0x812e, 0x9ac0, 0x666a, 0xecfc, 0x3bc0, 0x31dc, 0x8008, 0x96c0, 0xec1d, 0x2718, 0x8118, 0x96c0, 0x9b44 }, 16, 0x000a0800, 1},
+ {{0x2b03, 0x800a, 0xc941, 0x541c, 0x92d0, 0x441b, 0x5019, 0x401b, 0x3104, 0x292c, 0x800a, 0x94c0, 0xedef, 0xc784, 0x98c0, 0x3bc0 }, 16, 0x000a0820, 1},
+ {{0x3090, 0x8008, 0xed64, 0x3a40, 0xa000, 0x3ec0, 0x29e0, 0x8008, 0xfe45, 0x3680, 0xa000, 0x51d0, 0x5815, 0x98c0, 0x331b, 0x8700 }, 16, 0x000a0840, 1},
+ {{0x5217, 0x5117, 0x96c0, 0x3413, 0x8400, 0x5a93, 0x8485, 0x9ac0, 0x656a, 0xe8fc, 0x0cc6, 0x3118, 0x8008, 0x8417, 0x9f42, 0x98c0 }, 16, 0x000a0860, 1},
+ {{0x3ac0, 0x335c, 0x8008, 0xe81c, 0x90c0, 0x92d0, 0x93a0, 0x431a, 0x98c0, 0x05c4, 0x38b4, 0x8008, 0xfe42, 0x94c0, 0xf202, 0xf501 }, 16, 0x000a0880, 1},
+ {{0x98c0, 0x39c0, 0x329c, 0x8008, 0xfd46, 0x98c0, 0xcb4e, 0x3204, 0x2fd0, 0x800b, 0x3a40, 0xa000, 0x38c0, 0x335c, 0x8008, 0xf847 }, 16, 0x000a08a0, 1},
+ {{0x1c17, 0xcb46, 0x94c0, 0xcc49, 0xfdc6, 0x3cc1, 0x1a93, 0x3cc0, 0x329c, 0x8008, 0x3640, 0xa000, 0x64ea, 0xf8c7, 0x8431, 0x9f41 }, 16, 0x000a08c0, 1},
+ {{0x90c0, 0x90c0, 0x92d0, 0x541c, 0x441a, 0x3104, 0x290c, 0x800a, 0x9ac0, 0x64ea, 0x0cc6, 0x3118, 0x8008, 0xe8fc, 0x8410, 0xe81c }, 16, 0x000a08e0, 1},
+ {{0x9f41, 0x90c0, 0x90c0, 0x92d0, 0x5218, 0x421a, 0x3880, 0xa000, 0x7be1, 0xef5c, 0xe85c, 0x98c0, 0x67ea, 0xed5c, 0x2e0e, 0x80d0 }, 16, 0x000a0900, 1},
+ {{0x94c0, 0xeb44, 0x8133, 0x3420, 0xa000, 0xfec5, 0x06c4, 0x38ac, 0x8008, 0x9ac0, 0xd328, 0xc684, 0x3ec0, 0x3090, 0x8008, 0x8437 }, 16, 0x000a0920, 1},
+ {{0x3a40, 0xa000, 0x3f20, 0x2548, 0x8009, 0xfe45, 0x92c0, 0x90c0, 0x189f, 0xc590, 0x3224, 0x3a38, 0x800a, 0x1996, 0xf501, 0x9760 }, 16, 0x000a0940, 1},
+ {{0x5c9e, 0x92d0, 0x5718, 0x471c, 0x7b61, 0x676a, 0x81e5, 0x3420, 0xa000, 0xfec5, 0x3a40, 0xa000, 0x0425, 0x336a, 0x8009, 0xfe45 }, 16, 0x000a0960, 1},
+ {{0x7764, 0xd325, 0x90c0, 0x96c2, 0x3344, 0x3ad0, 0x800a, 0x3620, 0xa000, 0xfec5, 0xc584, 0x94c0, 0xc489, 0xf548, 0x3840, 0xa100 }, 16, 0x000a0980, 1},
+ {{0xf449, 0x2e0a, 0x8002, 0x3840, 0xa000, 0xc781, 0x2a0e, 0x8004, 0x2e0f, 0x800c, 0x3680, 0xa000, 0x2f0f, 0x8004, 0x3aa0, 0xa000 }, 16, 0x000a09a0, 1},
+ {{0xebef, 0x3522, 0x2558, 0x8009, 0x3a80, 0xa000, 0xeb68, 0x34c2, 0x2d20, 0x8008, 0x3680, 0xa000, 0x52d6, 0x5a16, 0x3a80, 0xa000 }, 16, 0x000a09c0, 1},
+ {{0x3518, 0x8700, 0x5993, 0x5497, 0x96c0, 0x3410, 0x8400, 0xeafc, 0x96c0, 0xca4d, 0x2718, 0x80ec, 0x3a80, 0xa000, 0x5857, 0x38a0 }, 16, 0x000a09e0, 1},
+ {{0x3ec0, 0x8008, 0x94c0, 0xf105, 0xf001, 0x94c0, 0xf506, 0xf707, 0x3640, 0xa000, 0xf442, 0xfe45, 0x3660, 0xa000, 0xfd4a, 0xfc4b }, 16, 0x000a0a00, 1},
+ {{0x3660, 0xa000, 0xfa4c, 0xff4d, 0x32e4, 0x208e, 0x800a, 0x3420, 0xa000, 0xfb4e, 0x3640, 0xa000, 0x5816, 0xfccb, 0x98c0, 0xc84a }, 16, 0x000a0a20, 1},
+ {{0x38a0, 0x3ec0, 0x8008, 0x7d41, 0x256a, 0x3652, 0xece8, 0x96c0, 0x7644, 0x585c, 0x8425, 0x3a61, 0x3c62, 0x7ce2, 0x9f44, 0x90c0 }, 16, 0x000a0a40, 1},
+ {{0x2103, 0x8010, 0x94d0, 0x4858, 0x585c, 0x3c62, 0x7ce2, 0xc781, 0x4850, 0x3620, 0xa000, 0xfc42, 0xf241, 0x39c0, 0x365c, 0x8008 }, 16, 0x000a0a60, 1},
+ {{0x3204, 0x2ee0, 0x800b, 0x38a0, 0x3ec0, 0x8008, 0x3a20, 0xa000, 0xfacc, 0x0dc6, 0x3118, 0x8008, 0x3620, 0xa000, 0xfccb, 0x5616 }, 16, 0x000a0a80, 1},
+ {{0x3820, 0xa100, 0x676a, 0x5c12, 0xffcd, 0x3660, 0xa000, 0xfbce, 0xfec5, 0x3640, 0xa000, 0xecfc, 0xfdca, 0x96c0, 0xec1d, 0x2718 }, 16, 0x000a0aa0, 1},
+ {{0x81fc, 0x9f46, 0x3dc0, 0x365c, 0x8008, 0x90c0, 0x92d0, 0x501d, 0x9084, 0x98c0, 0xc781, 0x3104, 0x2cb6, 0x800a, 0x3a00, 0xa100 }, 16, 0x000a0ac0, 1},
+ {{0x3410, 0x8600, 0x5d16, 0x5993, 0x3680, 0xa000, 0x5857, 0x84bb, 0x1297, 0xedfc, 0x98c0, 0xcd4c, 0x38a0, 0x3ec0, 0x8008, 0x94c0 }, 16, 0x000a0ae0, 1},
+ {{0xf001, 0xf406, 0x94c0, 0xf105, 0xf707, 0x3640, 0xa000, 0xf242, 0xfe45, 0x3660, 0xa000, 0xfd4a, 0xfc4b, 0x3660, 0xa000, 0xfa4c }, 16, 0x000a0b00, 1},
+ {{0xff4d, 0x32e4, 0x208e, 0x800a, 0x3420, 0xa000, 0xfb4e, 0x3a20, 0xa000, 0xfacc, 0x05c4, 0x38b2, 0x8008, 0x98c0, 0xf0c9, 0x08c6 }, 16, 0x000a0b20, 1},
+ {{0x3118, 0x8008, 0x3820, 0xa100, 0x6a21, 0x5d12, 0xfdca, 0x1316, 0xca44, 0x3820, 0xa000, 0x65ea, 0xedfc, 0xfec5, 0x3640, 0xa000 }, 16, 0x000a0b40, 1},
+ {{0xeafc, 0xfbce, 0x3a20, 0xa000, 0xffcd, 0x3ba0, 0x3ec0, 0x8008, 0x96c0, 0xea18, 0x2618, 0x8146, 0x3620, 0xa000, 0xfccb, 0xed18 }, 16, 0x000a0b60, 1},
+ {{0x96c0, 0x9b43, 0x2b03, 0x8010, 0x90c0, 0x94c0, 0x90c0, 0x90c0, 0x92d0, 0x585b, 0x401d, 0x411a, 0x98c0, 0xc781, 0x3104, 0x2cb6 }, 16, 0x000a0b80, 1},
+ {{0x800a, 0x1216, 0x06c4, 0x38ac, 0x8008, 0x3800, 0xa100, 0xd328, 0x5993, 0x5497, 0x94c6, 0x84a7, 0x7d41, 0x3680, 0xa000, 0x5857 }, 16, 0x000a0ba0, 1},
+ {{0xf442, 0x94c0, 0xf707, 0xf206, 0x94c0, 0xf105, 0xf001, 0x3a40, 0xa000, 0x38a0, 0x3ec0, 0x8008, 0xfe45, 0x3660, 0xa000, 0xfd4a }, 16, 0x000a0bc0, 1},
+ {{0xfc4b, 0x3660, 0xa000, 0xfa4c, 0xff4d, 0x32e4, 0x208e, 0x800a, 0x3420, 0xa000, 0xfb4e, 0x3620, 0xa000, 0xfdca, 0xc690, 0x98c0 }, 16, 0x000a0be0, 1},
+ {{0xf601, 0x39a0, 0x3ec0, 0x8008, 0x3224, 0x3990, 0x800a, 0x3480, 0xa000, 0x5895, 0x3660, 0xa000, 0xfdca, 0xfacc, 0x3a20, 0xa000 }, 16, 0x000a0c00, 1},
+ {{0xfccb, 0x08c6, 0x3118, 0x8008, 0x3680, 0xa100, 0x5c12, 0x5d95, 0x9750, 0x94c0, 0xed4c, 0xecfc, 0x3640, 0xa000, 0x5995, 0xfbce }, 16, 0x000a0c20, 1},
+ {{0x3660, 0xa000, 0xfec5, 0xffcd, 0xec18, 0x92d0, 0x5219, 0x421c, 0x98c0, 0xc781, 0x3104, 0x2cb6, 0x800a, 0x3a80, 0xa000, 0x5812 }, 16, 0x000a0c40, 1},
+ {{0x0dc6, 0x3118, 0x8008, 0x3680, 0xa000, 0x5857, 0xf206, 0x94c0, 0xe8fc, 0xf105, 0x94c0, 0xf442, 0xf001, 0x94c0, 0xe81d, 0xf707 }, 16, 0x000a0c60, 1},
+ {{0x3660, 0xa000, 0xfe45, 0xfd4a, 0x3660, 0xa000, 0xfc4b, 0xfa4c, 0x32e4, 0x208e, 0x800a, 0x3660, 0xa000, 0xff4d, 0xfb4e, 0x3660 }, 16, 0x000a0c80, 1},
+ {{0xa000, 0xfec5, 0xfdca, 0x3660, 0xa000, 0xfccb, 0xfacc, 0x3660, 0xa000, 0xffcd, 0xfbce, 0x94c0, 0xf1c8, 0xf0c9, 0x3a80, 0xa100 }, 16, 0x000a0ca0, 1},
+ {{0x78e1, 0x7842, 0xee5c, 0xeb5c, 0x3880, 0xa000, 0x64ea, 0xf049, 0xef5c, 0x94c0, 0xef5c, 0xf148, 0x3600, 0xa100, 0xee5c, 0xea5c }, 16, 0x000a0cc0, 1},
+ {{0x2cff, 0x9cf5, 0x38c0, 0xa100, 0xed44, 0x2c0c, 0x80d0, 0x98c0, 0x39e8, 0x280c, 0xbfff, 0xc081, 0x0fc6, 0x3114, 0x8008, 0x1291 }, 16, 0x000a0ce0, 1},
+ {{0x34a1, 0x2000, 0x8008, 0x96c0, 0x34ce, 0x8200, 0xef41, 0x2769, 0xc681, 0x8429, 0x06c1, 0x38ba, 0x8008, 0x0fc2, 0x3114, 0x8008 }, 16, 0x000a0d00, 1},
+ {{0x32e4, 0x3050, 0x8009, 0x04c2, 0x3118, 0x8008, 0x32e4, 0x3050, 0x8009, 0xc081, 0x3104, 0x2d42, 0x800a, 0x32e4, 0x3050, 0x8009 }, 16, 0x000a0d20, 1},
+ {{0xc081, 0x27e8, 0x9fc8, 0xe7e8, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a0d40, 1},
+ {{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a0d60, 1},
+ {{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x3ce8, 0x2404, 0xbfff, 0xc090, 0x21e0, 0x83ff, 0x1294 }, 16, 0x000a0d80, 1},
+ {{0x3900, 0x2de0, 0x800a, 0x98c0, 0xdc82, 0x32e4, 0x3a5c, 0x8001, 0x4194, 0x32e4, 0x3a62, 0x8001, 0x94c0, 0xc186, 0xc090, 0x32e4 }, 16, 0x000a0da0, 1},
+ {{0x3a5c, 0x8001, 0x98c0, 0x3900, 0x2ec0, 0x800a, 0xc08c, 0x30e4, 0x3a62, 0x8001, 0x94c0, 0xc186, 0xc08c, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a0dc0, 1},
+ {{0x96c0, 0x7468, 0x9620, 0x9720, 0x32e4, 0x3a68, 0x8001, 0x94c0, 0x9e20, 0x9f20, 0x3d00, 0x20e4, 0x8008, 0x3ec0, 0x30f8, 0x8008 }, 16, 0x000a0de0, 1},
+ {{0x15d5, 0x3bc8, 0x3c14, 0xbfff, 0x3ac1, 0x3900, 0x2040, 0x8008, 0x2c10, 0x0515, 0x3a00, 0x2040, 0x8008, 0x5f96, 0x90c0, 0xef41 }, 16, 0x000a0e00, 1},
+ {{0x4f96, 0x5293, 0x96c0, 0x350c, 0x8400, 0x52d1, 0x9cc0, 0x351b, 0x8fff, 0x6669, 0x35ff, 0x90ff, 0xc481, 0x96c0, 0x3706, 0x9000 }, 16, 0x000a0e20, 1},
+ {{0x806d, 0x32e4, 0x2290, 0x8009, 0x4612, 0x32e4, 0x2290, 0x8009, 0xc081, 0x32e4, 0x3a7a, 0x8001, 0xc0aa, 0x32e4, 0x3a7a, 0x8001 }, 16, 0x000a0e40, 1},
+ {{0xc0ac, 0x32e4, 0x3a7a, 0x8001, 0xc0a2, 0x32e4, 0x3a7a, 0x8001, 0xc0a6, 0x32e4, 0x3a7a, 0x8001, 0xc0b2, 0x32e4, 0x3a7a, 0x8001 }, 16, 0x000a0e60, 1},
+ {{0xc0b4, 0x32e4, 0x3a7a, 0x8001, 0xc0b6, 0x32e4, 0x3a7a, 0x8001, 0xc0ae, 0x3de8, 0x3c0c, 0xbfff, 0x3001, 0x2ccc, 0x8f58, 0x0095 }, 16, 0x000a0e80, 1},
+ {{0x3104, 0x2eb2, 0x800a, 0x3f03, 0x8300, 0x4312, 0x04c1, 0x38d5, 0x8008, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71 }, 16, 0x000a0ea0, 1},
+ {{0x98c0, 0x7750, 0x7468, 0x9620, 0x9720, 0x32e4, 0x3a68, 0x8001, 0x94c0, 0x9e20, 0x9f20, 0x2d90, 0x3dc8, 0x3c14, 0xbfff, 0x3453 }, 16, 0x000a0ec0, 1},
+ {{0x34d3, 0x38c0, 0x2040, 0x8008, 0x1795, 0x3dc0, 0x21c0, 0x8008, 0x3f0a, 0x8100, 0x2569, 0x3553, 0x3ea0, 0x3e00, 0x8008, 0x8019 }, 16, 0x000a0ee0, 1},
+ {{0x9758, 0x39a0, 0x3f80, 0x8008, 0x90c0, 0x94d0, 0xc819, 0xc81e, 0x94c0, 0xc818, 0xc81d, 0x2760, 0x3ec8, 0x3c18, 0xbfff, 0xd32c }, 16, 0x000a0f00, 1},
+ {{0x8435, 0x1796, 0x3ac8, 0x3c10, 0xbfff, 0x3f1d, 0x8003, 0x66e9, 0x8425, 0x5092, 0x310b, 0x8800, 0x65e9, 0x90c0, 0x96c2, 0x3ce8 }, 16, 0x000a0f20, 1},
+ {{0x3c04, 0xbfff, 0x90c0, 0x92c2, 0x5294, 0x94c2, 0x0992, 0xa000, 0x92c2, 0x4294, 0x98c0, 0xc946, 0x3bc0, 0x30f0, 0x8008, 0x90c0 }, 16, 0x000a0f40, 1},
+ {{0xe96c, 0xc94f, 0x3ecf, 0x87c1, 0x7fc2, 0xce47, 0x90c0, 0xee1b, 0x5b96, 0x90c0, 0xeb41, 0x4b96, 0x94c0, 0x9e21, 0x9f21, 0x94c0 }, 16, 0x000a0f60, 1},
+ {{0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x3820, 0xa000, 0x0ac6, 0x38d0, 0x8008, 0x94c0, 0x9620, 0x9720 }, 16, 0x000a0f80, 1},
+ {{0x3620, 0xa000, 0x2a0b, 0x803c, 0x53d3, 0x98c0, 0x371f, 0x80ff, 0x9e20, 0x9f20, 0x3244, 0x3d90, 0x800a, 0x7467, 0x3ec0, 0x2298 }, 16, 0x000a0fa0, 1},
+ {{0x8008, 0x0bc6, 0x38d0, 0x8008, 0x4016, 0x2b08, 0x803e, 0x55d0, 0x3b19, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7461, 0x98c0, 0x0ac6 }, 16, 0x000a0fc0, 1},
+ {{0x38d0, 0x8008, 0xee5c, 0x4016, 0x2a0f, 0x8040, 0x54d7, 0x391f, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7467, 0x98c0, 0x0dc6, 0x38d0 }, 16, 0x000a0fe0, 1},
+ {{0x8008, 0xee5c, 0x4016, 0x2d0d, 0x8042, 0x55d5, 0x3b1b, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7463, 0x98c0, 0x0ac6, 0x38d0, 0x8008 }, 16, 0x000a1000, 1},
+ {{0xee5c, 0x4016, 0x2a09, 0x803c, 0x52d1, 0x3d68, 0x3244, 0x3d90, 0x800a, 0x7462, 0x96c0, 0xe8ee, 0x2c00, 0x8052, 0x09c6, 0x38d0 }, 16, 0x000a1020, 1},
+ {{0x8008, 0xe83c, 0x96c0, 0x4010, 0x290b, 0x803e, 0x50d3, 0x3c68, 0x3244, 0x3d90, 0x800a, 0x7460, 0x98c0, 0xcfb6, 0x0dc6, 0x38d0 }, 16, 0x000a1040, 1},
+ {{0x8008, 0xecee, 0x96c0, 0xec3f, 0x2d09, 0x8040, 0x4014, 0x53d1, 0x3de8, 0x3244, 0x3d90, 0x800a, 0x7463, 0x98c0, 0x0bc6, 0x38d0 }, 16, 0x000a1060, 1},
+ {{0x8008, 0xecee, 0xec7a, 0x96c0, 0x4014, 0x2b08, 0x8042, 0x52d0, 0x3d68, 0x3244, 0x3d90, 0x800a, 0x7462, 0x98c0, 0x0ac6, 0x38d0 }, 16, 0x000a1080, 1},
+ {{0x8008, 0xee42, 0x4016, 0x2a09, 0x8044, 0x56d1, 0x3d19, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7461, 0x3ec0, 0x2308, 0x8008, 0x0dc6 }, 16, 0x000a10a0, 1},
+ {{0x38d0, 0x8008, 0x4016, 0x2d08, 0x8046, 0x51d0, 0x331d, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7465, 0x98c0, 0x0cc6, 0x38d0, 0x8008 }, 16, 0x000a10c0, 1},
+ {{0xee5c, 0x4016, 0x2c0d, 0x8048, 0x53d5, 0x371e, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7466, 0x98c0, 0x0fc6, 0x38d0, 0x8008, 0xee5c }, 16, 0x000a10e0, 1},
+ {{0x4016, 0x2f0c, 0x804a, 0x55d4, 0x3b1d, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7465, 0x98c0, 0x0ac6, 0x38d0, 0x8008, 0xee5c, 0x4016 }, 16, 0x000a1100, 1},
+ {{0x2a09, 0x8044, 0x54d1, 0x3e68, 0x3244, 0x3d90, 0x800a, 0x7464, 0x96c0, 0xefee, 0x2a00, 0x8052, 0x0dc6, 0x38d0, 0x8008, 0xef3a }, 16, 0x000a1120, 1},
+ {{0x96c0, 0x4017, 0x2d0c, 0x8046, 0x53d4, 0x3de8, 0x3244, 0x3d90, 0x800a, 0x7463, 0x98c0, 0xc9b6, 0x08c6, 0x38d0, 0x8008, 0xefee }, 16, 0x000a1140, 1},
+ {{0x96c0, 0xef39, 0x280d, 0x8048, 0x4017, 0x50d5, 0x3c68, 0x3244, 0x3d90, 0x800a, 0x7460, 0x98c0, 0x08c6, 0x38d0, 0x8008, 0xefee }, 16, 0x000a1160, 1},
+ {{0xef7a, 0x96c0, 0x4017, 0x280c, 0x804a, 0x51d4, 0x3ce8, 0x3244, 0x3d90, 0x800a, 0x7461, 0xee42, 0x4016, 0x94c0, 0x9e21, 0x9f21 }, 16, 0x000a1180, 1},
+ {{0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x3610, 0x802a, 0x77d0, 0x9720, 0x8419, 0x3204, 0x30c0 }, 16, 0x000a11a0, 1},
+ {{0x800b, 0x30e1, 0x3000, 0x8003, 0x2744, 0x8650, 0x90c0, 0x90c0, 0x90c8, 0x2500, 0x9800, 0x283b, 0x3204, 0x30c0, 0x800b, 0x6460 }, 16, 0x000a11c0, 1},
+ {{0x9ac0, 0x2100, 0x9800, 0x90c0, 0x3e17, 0x8300, 0x32e4, 0x3c48, 0x8001, 0x7457, 0x3be8, 0x3c04, 0xbfff, 0x3300, 0x2000, 0x9200 }, 16, 0x000a11e0, 1},
+ {{0x98c0, 0xdd98, 0x39e8, 0x3c08, 0xbfff, 0x2744, 0x8e20, 0x0393, 0x0910, 0xb000, 0x4091, 0x90c8, 0x3cc8, 0x3c14, 0xbfff, 0x3400 }, 16, 0x000a1200, 1},
+ {{0x2d40, 0x8003, 0x1594, 0x3cc8, 0x3c14, 0xbfff, 0x3b0b, 0x8400, 0x65e9, 0x8015, 0x90c0, 0x7a61, 0x666a, 0x840d, 0x5094, 0x310b }, 16, 0x000a1220, 1},
+ {{0x8400, 0x65e9, 0x85f1, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x9f20, 0xe748, 0x9f7d, 0x1015, 0xa0e0 }, 16, 0x000a1240, 1},
+ {{0x90c0, 0x1115, 0xa0e0, 0x90c0, 0x9f7c, 0x1105, 0xa004, 0x90c0, 0x1105, 0xa008, 0x90c0, 0x90c0, 0x3344, 0x3a30, 0x800a, 0x32e4 }, 16, 0x000a1260, 1},
+ {{0x3aaa, 0x8001, 0xc083, 0x33e4, 0x3a56, 0x8001, 0x32e4, 0x3a74, 0x8001, 0x38e0, 0x3aa4, 0x8001, 0x32e4, 0x3a5c, 0x8001, 0x98c0 }, 16, 0x000a1280, 1},
+ {{0x39e0, 0x3bca, 0x8001, 0xc0ba, 0x32e4, 0x3a62, 0x8001, 0x94c0, 0xc182, 0xc0ba, 0x98c0, 0x3fc8, 0x3800, 0xbfff, 0xc782, 0x98c0 }, 16, 0x000a12a0, 1},
+ {{0x3900, 0x3880, 0x800a, 0xc0bc, 0x32e4, 0x3a5c, 0x8001, 0x4797, 0x32e4, 0x3a62, 0x8001, 0x94c0, 0xc182, 0xc0bc, 0x98c0, 0x3ac8 }, 16, 0x000a12c0, 1},
+ {{0x3800, 0xbfff, 0xc584, 0x98c0, 0x3900, 0x3850, 0x800a, 0xc0be, 0x32e4, 0x3a5c, 0x8001, 0x4592, 0x32e4, 0x3a62, 0x8001, 0x94c0 }, 16, 0x000a12e0, 1},
+ {{0xc182, 0xc0be, 0x32e4, 0x37c8, 0x8001, 0x6c10, 0x32e4, 0x37c2, 0x8001, 0x6c10, 0x32e4, 0x3a7a, 0x8001, 0xc084, 0x98c0, 0x0b06 }, 16, 0x000a1300, 1},
+ {{0x357c, 0x8008, 0xc3fd, 0x94c0, 0xc186, 0xc084, 0xeb4c, 0x56d3, 0x98c0, 0xdd86, 0x32e4, 0x3a62, 0x8001, 0x4313, 0x3204, 0x3270 }, 16, 0x000a1320, 1},
+ {{0x800b, 0xc08a, 0x9ac0, 0x6c10, 0x36e1, 0x3990, 0x8001, 0xc182, 0x32e4, 0x395a, 0x8001, 0xf641, 0x98c0, 0x34e1, 0x3990, 0x8001 }, 16, 0x000a1340, 1},
+ {{0xc182, 0x32e4, 0x395a, 0x8001, 0x94c0, 0xf441, 0xc081, 0x9f7d, 0x1015, 0xa0e0, 0x90c0, 0x9f7c, 0x9f7c, 0xe768, 0x9f21, 0x94c0 }, 16, 0x000a1360, 1},
+ {{0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x3800, 0x201c, 0x8008, 0x3d40, 0x30e8, 0x8008, 0x0267, 0x3f82 }, 16, 0x000a1380, 1},
+ {{0x8004, 0x0210, 0x3a00, 0x201e, 0x8008, 0x11d5, 0x3900, 0x2022, 0x8008, 0x0112, 0x3c00, 0x2024, 0x8008, 0x2b80, 0x94a3, 0x0b11 }, 16, 0x000a13a0, 1},
+ {{0x3aa8, 0x3c58, 0xbfff, 0x2020, 0x8002, 0x0014, 0x3d00, 0x2048, 0x8008, 0x5492, 0x98c0, 0x39eb, 0x9fff, 0x9620, 0x9720, 0x98c0 }, 16, 0x000a13c0, 1},
+ {{0x36c8, 0x8410, 0x9e20, 0x9f20, 0x0015, 0xe748, 0x3244, 0x37b0, 0x800a, 0x00a4, 0x33bc, 0x8009, 0x3304, 0x3a80, 0x800a, 0x3244 }, 16, 0x000a13e0, 1},
+ {{0x35a0, 0x800a, 0x38c0, 0x38c0, 0x8008, 0x3224, 0x2620, 0x800a, 0x38c0, 0x38c0, 0x8008, 0x32c4, 0x36e0, 0x800a, 0x00a4, 0x33bc }, 16, 0x000a1400, 1},
+ {{0x8009, 0x3224, 0x3720, 0x800a, 0x00a4, 0x33be, 0x8009, 0x9f7d, 0x02c5, 0x38b8, 0x8008, 0x37e2, 0x0fc6, 0x38d0, 0x8008, 0x67e9 }, 16, 0x000a1420, 1},
+ {{0x94c0, 0xef42, 0x845e, 0x92c3, 0xcd81, 0x96c0, 0x52d7, 0x2f0e, 0x80ae, 0x96c0, 0x351b, 0x8003, 0x56d6, 0x96c0, 0x65e9, 0x3d18 }, 16, 0x000a1440, 1},
+ {{0x8003, 0x843c, 0x92c3, 0xcd82, 0x96c0, 0x6469, 0x3d1e, 0x800c, 0x842e, 0x92c3, 0xcd83, 0x2769, 0xcfb6, 0x8424, 0x92c3, 0xcd84 }, 16, 0x000a1460, 1},
+ {{0xee3f, 0x55d6, 0x9ac0, 0x3b1e, 0x8007, 0x90c0, 0x3b9a, 0x8000, 0x6769, 0x800b, 0x6569, 0x8408, 0x92c3, 0xcd85, 0xcd86, 0x3204 }, 16, 0x000a1480, 1},
+ {{0x3c60, 0x800b, 0x0d21, 0x336a, 0x8009, 0x3f00, 0x2066, 0x8008, 0x3224, 0x2b00, 0x800a, 0x4017, 0x3304, 0x2d90, 0x800a, 0x33e4 }, 16, 0x000a14a0, 1},
+ {{0x2180, 0x800a, 0x96c0, 0x6c90, 0x2200, 0x8200, 0x32e4, 0x3c8a, 0x8001, 0x98c0, 0xf241, 0x3820, 0x2ad6, 0x8009, 0x0425, 0x336a }, 16, 0x000a14c0, 1},
+ {{0x8009, 0x7764, 0xd321, 0x90c0, 0x94c1, 0xe838, 0xc283, 0x96c3, 0x3244, 0x3a50, 0x800a, 0x96c2, 0x0221, 0x3369, 0x8009, 0x9f7d }, 16, 0x000a14e0, 1},
+ {{0x1015, 0xa0e0, 0x90c0, 0x9f7c, 0x9f7c, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a1500, 1},
+ {{0x2f90, 0x2c90, 0x2f10, 0x3f00, 0x20e4, 0x8008, 0x3cc8, 0x3c00, 0xbfff, 0x0717, 0x3d00, 0x2048, 0x8008, 0x1394, 0x3800, 0x2064 }, 16, 0x000a1520, 1},
+ {{0x8008, 0x0395, 0x3f00, 0x2060, 0x8008, 0x0110, 0x3e00, 0x2062, 0x8008, 0x0117, 0x38e8, 0x3c00, 0xbfff, 0x0116, 0x35f9, 0x3fff }, 16, 0x000a1540, 1},
+ {{0xbff0, 0x1490, 0x39e8, 0x3c00, 0xbfff, 0x98c0, 0xde05, 0x3bc8, 0x2428, 0xbfff, 0x0914, 0xa009, 0x0491, 0x3fa8, 0x3c50, 0xbfff }, 16, 0x000a1560, 1},
+ {{0x1293, 0x3e00, 0x2034, 0x8008, 0x0902, 0xa080, 0x4293, 0x0601, 0x3c4a, 0x8008, 0x9ac0, 0x6e90, 0x3ce8, 0x2404, 0xbfff, 0xc486 }, 16, 0x000a1580, 1},
+ {{0x05c1, 0x38d5, 0x8008, 0x0421, 0x336a, 0x8009, 0x1394, 0x37f9, 0x3fff, 0xbffe, 0xdf83, 0x4794, 0x03a4, 0x33c0, 0x8009, 0x9f7d }, 16, 0x000a15a0, 1},
+ {{0x1015, 0xa0e0, 0x90c0, 0x1115, 0xa0e0, 0x90c0, 0x9f7c, 0x98c0, 0xd1a8, 0x09c6, 0x38d0, 0x8008, 0x843f, 0x2908, 0x8078, 0x15d0 }, 16, 0x000a15c0, 1},
+ {{0xebe8, 0x98c0, 0x3b58, 0x8000, 0xeb76, 0xe842, 0x2469, 0x11d3, 0x54d0, 0x96c0, 0x391c, 0x8007, 0x8425, 0x3318, 0x8007, 0x2c7c }, 16, 0x000a15e0, 1},
+ {{0xc09a, 0xd621, 0x8013, 0x3304, 0x31b0, 0x800a, 0x98c0, 0xc69a, 0x3104, 0x3620, 0x800a, 0x3204, 0x31b0, 0x800a, 0xc0ae, 0xc6ae }, 16, 0x000a1600, 1},
+ {{0x3304, 0x3250, 0x800a, 0x3920, 0x32d8, 0x8009, 0x3244, 0x3800, 0x800a, 0x3820, 0x32b8, 0x8009, 0x0ac6, 0x38d0, 0x8008, 0x3920 }, 16, 0x000a1620, 1},
+ {{0x32d8, 0x8009, 0x2a0a, 0x807a, 0x10d2, 0x3820, 0x32b8, 0x8009, 0x311c, 0x8007, 0x6669, 0x8015, 0x33e4, 0x3150, 0x8009, 0x3004 }, 16, 0x000a1640, 1},
+ {{0x3680, 0x800a, 0x00a0, 0x33bc, 0x8009, 0x32e4, 0x3150, 0x8009, 0x98c0, 0xe939, 0x3820, 0x32b8, 0x8009, 0x00a0, 0x33bc, 0x8009 }, 16, 0x000a1660, 1},
+ {{0x9ac0, 0xd028, 0xcc40, 0x0ac6, 0x38d0, 0x8008, 0x90c0, 0x94c6, 0xecfc, 0xc288, 0x98c7, 0x0ca0, 0x33be, 0x8009, 0xc290, 0x98c0 }, 16, 0x000a1680, 1},
+ {{0x02a0, 0x33c0, 0x8009, 0xea44, 0x4212, 0x03a4, 0x33c0, 0x8009, 0x98c0, 0xd1a8, 0x0cc6, 0x38d0, 0x8008, 0x8415, 0x2c0b, 0x8078 }, 16, 0x000a16a0, 1},
+ {{0x50d3, 0x315a, 0x8000, 0x6569, 0x8008, 0x92c2, 0xc79a, 0xc7ae, 0x73f6, 0x2dff, 0x9eed, 0x33a4, 0x3270, 0x800a, 0x2d90, 0x3204 }, 16, 0x000a16c0, 1},
+ {{0x3390, 0x800a, 0x03c0, 0x2a40, 0x8009, 0x3ca8, 0x3c58, 0xbfff, 0x90c0, 0x5294, 0x35fd, 0x9fff, 0x66e9, 0x8423, 0x1797, 0x3840 }, 16, 0x000a16e0, 1},
+ {{0x31a0, 0x8008, 0x3f1c, 0x8800, 0x6669, 0x8413, 0x33e4, 0x37da, 0x8001, 0x98c0, 0xc78c, 0x3104, 0x371e, 0x800a, 0xc78b, 0x3ca8 }, 16, 0x000a1700, 1},
+ {{0x3c58, 0xbfff, 0x90c0, 0x5094, 0x31fb, 0x9fff, 0x3413, 0x8033, 0x807b, 0x5694, 0x3dfe, 0x9fff, 0x6769, 0x840f, 0x5097, 0x311b }, 16, 0x000a1720, 1},
+ {{0x8800, 0x3413, 0x8800, 0x8065, 0x3204, 0x31b0, 0x800a, 0xc09a, 0x32e4, 0x37da, 0x8001, 0x3840, 0x3186, 0x8008, 0x32e4, 0x3a7a }, 16, 0x000a1740, 1},
+ {{0x8001, 0xc094, 0x32e4, 0x3a7a, 0x8001, 0xc092, 0x32e4, 0x3a7a, 0x8001, 0xc0a2, 0x32e4, 0x3a7a, 0x8001, 0xc0a6, 0x32e4, 0x3a7a }, 16, 0x000a1760, 1},
+ {{0x8001, 0xc0aa, 0x32e4, 0x3a7a, 0x8001, 0xc0ac, 0x32e4, 0x3a7a, 0x8001, 0xc0ae, 0x32e4, 0x3a7a, 0x8001, 0xc090, 0x2e90, 0x3004 }, 16, 0x000a1780, 1},
+ {{0x37ac, 0x800a, 0x05c1, 0x38d5, 0x8008, 0x6f90, 0x2e10, 0x0716, 0x3b00, 0x2032, 0x8008, 0x31e1, 0x2268, 0x8009, 0x4413, 0x00c5 }, 16, 0x000a17a0, 1},
+ {{0x38d5, 0x8008, 0x2469, 0x0102, 0x3b30, 0x8008, 0x92c0, 0x8455, 0x3244, 0x2e20, 0x800a, 0x3800, 0x3c4c, 0x8008, 0x33e4, 0x3060 }, 16, 0x000a17c0, 1},
+ {{0x800a, 0x33e4, 0x22e0, 0x800a, 0x04c5, 0x38d4, 0x8008, 0x6669, 0x8011, 0x3304, 0x38a0, 0x800b, 0x6d90, 0x03c1, 0x38d4, 0x8008 }, 16, 0x000a17e0, 1},
+ {{0x32e4, 0x39f6, 0x8001, 0x2000, 0x83e8, 0x33a4, 0x28d0, 0x800a, 0x3344, 0x3ba0, 0x800a, 0x01c5, 0x38d5, 0x8008, 0x64e9, 0x81b3 }, 16, 0x000a1800, 1},
+ {{0x33e4, 0x3a38, 0x8001, 0x2764, 0x9530, 0x90c0, 0x90c0, 0x90c8, 0x3fa8, 0x3c50, 0xbfff, 0x3004, 0x3594, 0x800a, 0x3e00, 0x2034 }, 16, 0x000a1820, 1},
+ {{0x8008, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0xc840, 0xccba, 0x98c0, 0x39c8, 0x3800, 0xbfff, 0xc181 }, 16, 0x000a1840, 1},
+ {{0x94c0, 0xe83c, 0xc081, 0xc84a, 0x34cd, 0x87c1, 0xd495, 0x94c0, 0x4191, 0x9f70, 0x00c1, 0x38d4, 0x8008, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a1860, 1},
+ {{0x96c0, 0x6c90, 0xc940, 0xcdba, 0x98c0, 0x38c8, 0x3800, 0xbfff, 0xc581, 0x98c0, 0xe93d, 0x3ac8, 0x2400, 0xbfff, 0x96c0, 0xc94b }, 16, 0x000a1880, 1},
+ {{0x2704, 0x8060, 0x36cb, 0x87c1, 0x98c0, 0xd693, 0x39e0, 0x3078, 0x8008, 0x0590, 0x38e0, 0x31f8, 0x8008, 0xc582, 0x4592, 0x94c8 }, 16, 0x000a18a0, 1},
+ {{0x4118, 0x4119, 0x3de8, 0x3c0c, 0xbfff, 0x30f9, 0x3fff, 0xbffe, 0x96c0, 0x5295, 0x2704, 0x83e8, 0xdc02, 0x4095, 0x90c8, 0x98c0 }, 16, 0x000a18c0, 1},
+ {{0x3b00, 0x2042, 0x8008, 0xc281, 0x3cc8, 0x3c00, 0xbfff, 0x13d3, 0x3d00, 0x2044, 0x8008, 0x79c1, 0x4313, 0x5094, 0x94c0, 0x4095 }, 16, 0x000a18e0, 1},
+ {{0x9f70, 0x02c1, 0x38d5, 0x8008, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a1900, 1},
+ {{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x9cc0, 0x6f10, 0x7650, 0x6d10, 0x6c90, 0x9620, 0x9720, 0x96c0 }, 16, 0x000a1920, 1},
+ {{0x6d90, 0x7456, 0x9750, 0x94c0, 0x9e20, 0x9f20, 0x3ae0, 0x2258, 0x8008, 0x3fe0, 0x2358, 0x8008, 0x38e0, 0x22d8, 0x8008, 0x39e0 }, 16, 0x000a1940, 1},
+ {{0x21d8, 0x8008, 0x90c0, 0x94d0, 0xc819, 0xc818, 0x94c0, 0xc81a, 0xc81f, 0x96c0, 0x7750, 0x7454, 0x9758, 0x2460, 0x3be0, 0x2118 }, 16, 0x000a1960, 1},
+ {{0x8008, 0x3650, 0x3456, 0x39e0, 0x2058, 0x8008, 0x3cc0, 0x3f98, 0x8008, 0x3ec0, 0x3ed8, 0x8008, 0x90c0, 0x94d0, 0xc81c, 0xc81e }, 16, 0x000a1980, 1},
+ {{0x94c0, 0xc819, 0xc81b, 0x3454, 0x3fe0, 0x301c, 0x8008, 0x2460, 0x3ce0, 0x302c, 0x8008, 0x2469, 0x31e1, 0x2358, 0x8008, 0x9cc6 }, 16, 0x000a19a0, 1},
+ {{0x36e1, 0x22d8, 0x8008, 0x6e90, 0x90c0, 0x6d90, 0x98c7, 0x01e2, 0x3018, 0x8008, 0xc581, 0x019f, 0x06e2, 0x3028, 0x8008, 0x069c }, 16, 0x000a19c0, 1},
+ {{0x3de0, 0x300c, 0x8008, 0x98c7, 0x3be0, 0x2ffc, 0x8008, 0xc381, 0x9cc1, 0xc081, 0x3161, 0x2966, 0x8008, 0x90c0, 0x6d10, 0x3c41 }, 16, 0x000a19e0, 1},
+ {{0xa000, 0x4194, 0x3461, 0x28e6, 0x8008, 0x6c10, 0x3a27, 0xa000, 0x4494, 0x37e1, 0x21d8, 0x8008, 0x98c6, 0x34e1, 0x2258, 0x8008 }, 16, 0x000a1a00, 1},
+ {{0x4197, 0x3a27, 0xa000, 0x4497, 0x07e2, 0x2ff8, 0x8008, 0x079b, 0x04e2, 0x3008, 0x8008, 0x96c0, 0x449d, 0x2c0e, 0x8004, 0x94c6 }, 16, 0x000a1a20, 1},
+ {{0x4516, 0x4195, 0x3641, 0xa000, 0x4193, 0x4495, 0x3827, 0xa000, 0x4493, 0x2f08, 0x8004, 0x94c0, 0x9e21, 0x9f21, 0x98c7, 0x2b0a }, 16, 0x000a1a40, 1},
+ {{0x8004, 0x90c0, 0xc281, 0x96c0, 0x4310, 0x2d09, 0x8004, 0x94c0, 0x9621, 0x9721, 0x9f70, 0x0012, 0x4211, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a1a60, 1},
+ {{0x9cc0, 0x6d10, 0x76d0, 0x6c10, 0x6d90, 0x9620, 0x9720, 0x94c0, 0x74d2, 0x9758, 0x94c0, 0x9e20, 0x9f20, 0x3fc0, 0x38d8, 0x8008 }, 16, 0x000a1a80, 1},
+ {{0x3ec0, 0x3a58, 0x8008, 0x3cc0, 0x3d58, 0x8008, 0x38c0, 0x3bd8, 0x8008, 0x90c0, 0x94d0, 0xc818, 0xc81c, 0x94c0, 0xc81f, 0xc81e }, 16, 0x000a1aa0, 1},
+ {{0x9ac0, 0x66e9, 0x3bc8, 0x3000, 0xbfff, 0xc483, 0x3cc8, 0x3008, 0xbfff, 0x96c6, 0x5093, 0x2500, 0x814d, 0x3119, 0x8001, 0x64e9 }, 16, 0x000a1ac0, 1},
+ {{0x803b, 0x1094, 0x3fc8, 0x3000, 0xbfff, 0x9ac0, 0x2e20, 0x8000, 0x90c0, 0x3118, 0x8fff, 0x3278, 0x3bc8, 0x3008, 0xbfff, 0x841d }, 16, 0x000a1ae0, 1},
+ {{0xee61, 0xeef1, 0x8017, 0x5097, 0x311e, 0x8001, 0x6769, 0x800d, 0x5193, 0x3318, 0x8fff, 0x7278, 0x81e9, 0x98c0, 0x3ec8, 0x3000 }, 16, 0x000a1b00, 1},
+ {{0xbfff, 0xc182, 0x98c0, 0x3fc8, 0x3400, 0xbfff, 0xc283, 0x0196, 0x3cc8, 0x3408, 0xbfff, 0x5697, 0x3d18, 0x8001, 0x6469, 0x803b }, 16, 0x000a1b20, 1},
+ {{0x1494, 0x3fc8, 0x3400, 0xbfff, 0x9ac0, 0x2820, 0x8000, 0x90c0, 0x3918, 0x8fff, 0x3178, 0x3ac8, 0x3408, 0xbfff, 0x841d, 0xe861 }, 16, 0x000a1b40, 1},
+ {{0xe8f1, 0x8017, 0x5097, 0x3118, 0x8001, 0x6469, 0x800d, 0x5692, 0x3d18, 0x8fff, 0x7178, 0x81e9, 0x98c0, 0x3ec8, 0x3400, 0xbfff }, 16, 0x000a1b60, 1},
+ {{0xc781, 0x96c0, 0x3b1a, 0x80ff, 0xc690, 0x0196, 0xd7c2, 0x3820, 0xa000, 0x05e4, 0x306a, 0x8008, 0x3a00, 0xa004, 0xd2a8, 0x03e1 }, 16, 0x000a1b80, 1},
+ {{0x306c, 0x8008, 0x801d, 0x3600, 0xa004, 0x3415, 0x8030, 0x8023, 0x3400, 0xa004, 0xd2b8, 0x801b, 0x3400, 0xa004, 0xd2b0, 0x8013 }, 16, 0x000a1ba0, 1},
+ {{0x96c0, 0x67e0, 0xc381, 0xc6a0, 0x27ee, 0x03e1, 0x306c, 0x8008, 0x98c0, 0x746b, 0xcc47, 0x21e0, 0x9f00, 0xdc85, 0xec61, 0x98c0 }, 16, 0x000a1bc0, 1},
+ {{0xcc4f, 0x3204, 0x3930, 0x800a, 0xd7c1, 0x3e00, 0xa00a, 0x3f18, 0x8100, 0x6d10, 0x3f19, 0x8200, 0x6f90, 0x3e40, 0xa000, 0x3f19 }, 16, 0x000a1be0, 1},
+ {{0x8400, 0x6469, 0x3f1d, 0x8800, 0xc281, 0x3e00, 0xa001, 0x3f3b, 0x8000, 0x6e10, 0x3ecc, 0x8088, 0xc0aa, 0x3a01, 0xa009, 0xe939 }, 16, 0x000a1c00, 1},
+ {{0x64e9, 0x64e9, 0xc981, 0x02e2, 0x23e8, 0x8008, 0x98c1, 0x64e9, 0xee3e, 0xce81, 0x64e9, 0x3c00, 0xa802, 0x3eea, 0x805f, 0x90c0 }, 16, 0x000a1c20, 1},
+ {{0x3ec8, 0x808a, 0x98c1, 0x66e9, 0xea3a, 0xca81, 0x66e9, 0x02e2, 0x23e8, 0x8008, 0x3a01, 0xa009, 0xeb3b, 0x66ea, 0x66ea, 0xcb81 }, 16, 0x000a1c40, 1},
+ {{0x3a07, 0xb004, 0x7ac7, 0x3eea, 0x805e, 0x65e9, 0x3a00, 0xa004, 0x7ee3, 0x02e2, 0x23e8, 0x8008, 0x3800, 0xb800, 0xd995, 0x34ea }, 16, 0x000a1c60, 1},
+ {{0x805d, 0x3466, 0x8006, 0x98c0, 0xcc46, 0x02e2, 0x23e8, 0x8008, 0x0ce0, 0x3068, 0x8008, 0x98c6, 0x3fe0, 0x23ec, 0x8008, 0xecf8 }, 16, 0x000a1c80, 1},
+ {{0x98c6, 0x35e1, 0x29f8, 0x8008, 0xecfc, 0x98c6, 0xd223, 0x0ce0, 0x3068, 0x8008, 0x98c0, 0xecf8, 0x38e0, 0x23dc, 0x8008, 0x98c0 }, 16, 0x000a1ca0, 1},
+ {{0xecfc, 0x3dc8, 0x3820, 0xbfff, 0x94c0, 0xcc4b, 0xcc4e, 0x98c6, 0x09e1, 0x306f, 0x8008, 0x75fb, 0x3e06, 0xa008, 0x90c0, 0x0be1 }, 16, 0x000a1cc0, 1},
+ {{0x306e, 0x8008, 0x7dc1, 0xd023, 0x98c6, 0x36ea, 0x8310, 0x90c0, 0x777e, 0x98c6, 0x02e2, 0x23e8, 0x8008, 0x7f41, 0x3600, 0xa800 }, 16, 0x000a1ce0, 1},
+ {{0x34ea, 0x804f, 0x02e2, 0x23e8, 0x8008, 0x059f, 0x0ae1, 0x306d, 0x8008, 0x2e10, 0x0ee1, 0x3071, 0x8008, 0x2c90, 0x0497, 0x3900 }, 16, 0x000a1d00, 1},
+ {{0x3eb0, 0x800a, 0x1497, 0x32e1, 0x23f8, 0x8008, 0x3600, 0xa800, 0x34ec, 0x805f, 0x4497, 0x5497, 0x3600, 0xa800, 0x34ec, 0x805e }, 16, 0x000a1d20, 1},
+ {{0x4497, 0x5497, 0x3600, 0xa800, 0x34ec, 0x805d, 0x4497, 0x5597, 0x36ed, 0x8310, 0x4597, 0x5597, 0x3600, 0xa800, 0x34ed, 0x804f }, 16, 0x000a1d40, 1},
+ {{0x459f, 0x4297, 0x3820, 0xa000, 0x04e2, 0x23d8, 0x8008, 0x3600, 0xa004, 0x32ec, 0x805f, 0x3820, 0xa000, 0x04e2, 0x23d8, 0x8008 }, 16, 0x000a1d60, 1},
+ {{0x3600, 0xa004, 0x32ec, 0x805e, 0x3820, 0xa000, 0x04e2, 0x23d8, 0x8008, 0x3600, 0xa804, 0x34ec, 0x805d, 0x3820, 0xa000, 0x04e2 }, 16, 0x000a1d80, 1},
+ {{0x23d8, 0x8008, 0x3600, 0xa004, 0x3cec, 0x8310, 0x3820, 0xa000, 0x04e2, 0x23d8, 0x8008, 0x3600, 0xa804, 0x34ec, 0x804f, 0x3820 }, 16, 0x000a1da0, 1},
+ {{0xa000, 0x04e2, 0x23d8, 0x8008, 0x35e1, 0x26f8, 0x8008, 0x4598, 0x4190, 0x1290, 0x35e1, 0x2cf8, 0x8008, 0x3600, 0xa800, 0x34ea }, 16, 0x000a1dc0, 1},
+ {{0x805f, 0x4290, 0x5290, 0x3600, 0xa800, 0x34ea, 0x805e, 0x4290, 0x5490, 0x3600, 0xa800, 0x34ec, 0x805d, 0x4490, 0x5290, 0x3cea }, 16, 0x000a1de0, 1},
+ {{0x8310, 0x4290, 0x5390, 0x3600, 0xa800, 0x34eb, 0x804f, 0x4398, 0x4590, 0x3201, 0x2000, 0x8030, 0x32e4, 0x3a5c, 0x8001, 0x4295 }, 16, 0x000a1e00, 1},
+ {{0x32e4, 0x3a62, 0x8001, 0x94c0, 0xc184, 0xc0aa, 0x32e4, 0x3a5c, 0x8001, 0x98c0, 0x3900, 0x3eb0, 0x800a, 0xc0ac, 0x32e4, 0x3a62 }, 16, 0x000a1e20, 1},
+ {{0x8001, 0x94c0, 0xc184, 0xc0ac, 0x9f7d, 0x9ac0, 0x3f1c, 0x8300, 0x90c0, 0x3f1d, 0x8c00, 0x2669, 0x39e8, 0x3c2c, 0xbfff, 0x90c0 }, 16, 0x000a1e40, 1},
+ {{0x98c7, 0x4791, 0x33e0, 0x23e8, 0x8008, 0x94c3, 0x0903, 0xa001, 0x98c7, 0x66e9, 0x03e2, 0x3064, 0x8008, 0x90c0, 0x96c3, 0x36e0 }, 16, 0x000a1e60, 1},
+ {{0x23d8, 0x8008, 0x94c3, 0x0906, 0xa001, 0x96c3, 0x06e2, 0x305c, 0x8008, 0x9f7c, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721 }, 16, 0x000a1e80, 1},
+ {{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x3410, 0x802a, 0x9620, 0x9720, 0x3a20, 0xa000, 0x08c6 }, 16, 0x000a1ea0, 1},
+ {{0x38d0, 0x8008, 0xc0aa, 0x94c0, 0x9e20, 0x9f20, 0x3840, 0xa000, 0xe748, 0x280e, 0x80b2, 0x1616, 0x3da8, 0x3c20, 0xbfff, 0x9ac0 }, 16, 0x000a1ec0, 1},
+ {{0x2618, 0x82fc, 0x90c0, 0x3d1e, 0x8007, 0x3ee8, 0x3c2c, 0xbfff, 0x1395, 0x32e4, 0x3a68, 0x8001, 0x0322, 0x334c, 0x8009, 0x1496 }, 16, 0x000a1ee0, 1},
+ {{0x3ac8, 0x3004, 0xbfff, 0x96c0, 0x391a, 0x8f00, 0xcf82, 0x9ac0, 0xdd28, 0x5892, 0x39e0, 0x23e8, 0x8008, 0x3518, 0x8003, 0x94c0 }, 16, 0x000a1f00, 1},
+ {{0xce40, 0xe9a8, 0x90c0, 0x98c7, 0xee61, 0x39e0, 0x29f8, 0x8008, 0x98c6, 0xee8f, 0x39e0, 0x23f8, 0x8008, 0x96c0, 0xeefe, 0x2518 }, 16, 0x000a1f20, 1},
+ {{0x820a, 0x3fe0, 0x3044, 0x8008, 0x07e7, 0x3068, 0x8008, 0x9ac0, 0x67ea, 0xee1f, 0x03e7, 0x3068, 0x8008, 0x1a96, 0x02e7, 0x3068 }, 16, 0x000a1f40, 1},
+ {{0x8008, 0x90c0, 0x9a61, 0x98c0, 0x67e1, 0x5119, 0x2718, 0x81de, 0x3be1, 0x02e6, 0x3058, 0x8008, 0x9ac0, 0x34c8, 0x950c, 0x9b47 }, 16, 0x000a1f60, 1},
+ {{0x2b03, 0x802c, 0x2e91, 0x3fc0, 0x3a58, 0x8008, 0xd545, 0x34cf, 0x950c, 0x2ca7, 0x02e2, 0x3058, 0x8008, 0xd496, 0x96c0, 0x64e1 }, 16, 0x000a1f80, 1},
+ {{0x2103, 0x8032, 0x98c0, 0x34c8, 0x950c, 0x7cc8, 0x5319, 0x2e13, 0x64e5, 0x3cc8, 0xd544, 0x96c0, 0x34cc, 0x950c, 0x74d9, 0x9ad0 }, 16, 0x000a1fa0, 1},
+ {{0x6cac, 0x415f, 0x02e2, 0x3058, 0x8008, 0xd496, 0x64e1, 0x7cc8, 0x64e5, 0x7cc8, 0x34d9, 0x3024, 0x2144, 0x800a, 0x4157, 0x25ea }, 16, 0x000a1fc0, 1},
+ {{0x25e1, 0x1219, 0x05e6, 0x3050, 0x8008, 0x9ac0, 0x3ac9, 0x950c, 0x79e1, 0x2718, 0x815a, 0x98c0, 0x6c98, 0x9b43, 0x2b03, 0x802a }, 16, 0x000a1fe0, 1},
+ {{0x98c0, 0xd6c1, 0x3fc0, 0x38d8, 0x8008, 0x3acb, 0x950c, 0x2c3d, 0x05e2, 0x3050, 0x8008, 0xd416, 0x96c0, 0x6461, 0x2103, 0x8032 }, 16, 0x000a2000, 1},
+ {{0x98c0, 0x3acc, 0x950c, 0x7c48, 0x5319, 0x2fac, 0x6465, 0x3c48, 0xd6c7, 0x96c0, 0x3acc, 0x950c, 0x7458, 0x9ad0, 0x6c2c, 0x405f }, 16, 0x000a2020, 1},
+ {{0x05e2, 0x3050, 0x8008, 0xd416, 0x6461, 0x7c48, 0x6465, 0x7c48, 0x3458, 0x3024, 0x2144, 0x800a, 0x4057, 0x256a, 0x2561, 0x1119 }, 16, 0x000a2040, 1},
+ {{0x07e6, 0x3058, 0x8008, 0x9ac0, 0x3ecd, 0x950c, 0x7961, 0x5019, 0x84df, 0x9ac0, 0x6d21, 0x03e6, 0x3050, 0x8008, 0x9b42, 0x9ac0 }, 16, 0x000a2060, 1},
+ {{0x36cc, 0x950c, 0xd7c2, 0x2b03, 0x8052, 0x96c0, 0x6e24, 0x3ecd, 0x950c, 0x9ac0, 0xd5c4, 0x6d21, 0x3fc0, 0x3a58, 0x8008, 0x96c0 }, 16, 0x000a2080, 1},
+ {{0x36cc, 0x950c, 0xd516, 0x2ea4, 0x2561, 0x3cc0, 0x38d8, 0x8008, 0x98c0, 0xd696, 0x03e2, 0x3050, 0x8008, 0x26e1, 0x07e2, 0x3058 }, 16, 0x000a20a0, 1},
+ {{0x8008, 0x9cc0, 0x2103, 0x806e, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x3d48, 0x3ec8, 0x1419, 0x03e6, 0x3050, 0x8008, 0x3e00, 0xa004 }, 16, 0x000a20c0, 1},
+ {{0x3ecd, 0x950c, 0x6565, 0x36c9, 0x950c, 0x5019, 0x3a00, 0xa088, 0x66e5, 0x6e21, 0x6c84, 0x7d48, 0x3a00, 0xb000, 0x7ec8, 0xd7c4 }, 16, 0x000a20e0, 1},
+ {{0xd5c1, 0x755a, 0x9cc0, 0x36c9, 0x950c, 0x76dd, 0x3eca, 0x950c, 0x425f, 0x9cd0, 0x6e84, 0x6d32, 0x455c, 0x03e2, 0x3050, 0x8008 }, 16, 0x000a2100, 1},
+ {{0x9ac0, 0xd696, 0xd516, 0x07e2, 0x3058, 0x8008, 0x26e1, 0x6561, 0x3ec8, 0x7d48, 0x26e5, 0x6565, 0x3ec8, 0x7d48, 0x36dd, 0x755a }, 16, 0x000a2120, 1},
+ {{0x0554, 0x4257, 0x3ce0, 0x3024, 0x8008, 0x01e5, 0x306f, 0x8008, 0x3561, 0x1614, 0x07e7, 0x3068, 0x8008, 0x2569, 0x7b41, 0xd79e }, 16, 0x000a2140, 1},
+ {{0x98c3, 0xc281, 0x35e1, 0x3018, 0x8008, 0x94c3, 0xf204, 0xf703, 0x98c3, 0xf541, 0x39e0, 0x2118, 0x8008, 0x96c3, 0x3224, 0x3afe }, 16, 0x000a2160, 1},
+ {{0x800a, 0x96c3, 0x38c0, 0x3a58, 0x8008, 0x03e5, 0x3071, 0x8008, 0x75e3, 0x65e9, 0x90c0, 0x98c3, 0xc181, 0x34e1, 0x3008, 0x8008 }, 16, 0x000a2180, 1},
+ {{0x94c3, 0xf104, 0xf703, 0x98c3, 0xf441, 0x39e0, 0x2058, 0x8008, 0x96c3, 0x3224, 0x3afe, 0x800a, 0x96c3, 0x38c0, 0x38d8, 0x8008 }, 16, 0x000a21a0, 1},
+ {{0x0725, 0x336a, 0x8009, 0x7567, 0xd123, 0x2718, 0x82f0, 0x3344, 0x3ad0, 0x800a, 0x3124, 0x24ba, 0x800a, 0x1595, 0xc0ac, 0x32e4 }, 16, 0x000a21c0, 1},
+ {{0x3a68, 0x8001, 0x0522, 0x3314, 0x8009, 0x1496, 0x38c8, 0x3404, 0xbfff, 0x96c0, 0x391c, 0x8f00, 0xcc82, 0x9ac0, 0xde2a, 0x3be0 }, 16, 0x000a21e0, 1},
+ {{0x23d8, 0x8008, 0x5e90, 0xcd44, 0xebae, 0x98c0, 0xed61, 0x3be0, 0x3038, 0x8008, 0x96c2, 0x39e0, 0x2cf8, 0x8008, 0x98c7, 0xed8c }, 16, 0x000a2200, 1},
+ {{0x39e0, 0x26f8, 0x8008, 0x96c0, 0xedfe, 0x2518, 0x8204, 0x98c0, 0xed1b, 0x00e7, 0x3068, 0x8008, 0x246a, 0x1895, 0x04e7, 0x3068 }, 16, 0x000a2220, 1},
+ {{0x8008, 0x05e7, 0x3068, 0x8008, 0x9861, 0x98c0, 0x6461, 0x5419, 0x2718, 0x81e0, 0x3861, 0x03e6, 0x3054, 0x8008, 0x9ac0, 0x36c9 }, 16, 0x000a2240, 1},
+ {{0x950c, 0x9b40, 0x2b03, 0x8034, 0x2f84, 0x38c0, 0x3d58, 0x8008, 0xd5c7, 0x36cd, 0x950c, 0x2eb5, 0x03e2, 0x3054, 0x8008, 0xd696 }, 16, 0x000a2260, 1},
+ {{0x9ec0, 0x66e1, 0x2103, 0x803a, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x36ca, 0x950c, 0x7ec8, 0x5119, 0x2d38, 0x66e5, 0x3ec8 }, 16, 0x000a2280, 1},
+ {{0xd5c2, 0x96c0, 0x36ca, 0x950c, 0x76dd, 0x9ad0, 0x6eb8, 0x4558, 0x03e2, 0x3054, 0x8008, 0xd696, 0x66e1, 0x7ec8, 0x66e5, 0x7ec8 }, 16, 0x000a22a0, 1},
+ {{0x36dd, 0x3024, 0x242a, 0x800a, 0x4550, 0x266a, 0x2661, 0x1219, 0x00e6, 0x3060, 0x8008, 0x9ac0, 0x30cd, 0x950c, 0x7a61, 0x2718 }, 16, 0x000a22c0, 1},
+ {{0x8154, 0x98c0, 0x6fa9, 0x9b44, 0x2b03, 0x802e, 0x98c0, 0xd447, 0x3dc0, 0x3bd8, 0x8008, 0x30cf, 0x950c, 0x2e2b, 0x00e2, 0x3060 }, 16, 0x000a22e0, 1},
+ {{0x8008, 0xd616, 0x9ac0, 0x6661, 0x2103, 0x8036, 0x90c0, 0x90c0, 0x98c0, 0x30c9, 0x950c, 0x7e48, 0x5319, 0x2d19, 0x6665, 0x3e48 }, 16, 0x000a2300, 1},
+ {{0xd442, 0x96c0, 0x30cf, 0x950c, 0x765c, 0x9ad0, 0x6e2f, 0x445d, 0x00e2, 0x3060, 0x8008, 0xd616, 0x6661, 0x7e48, 0x6665, 0x7e48 }, 16, 0x000a2320, 1},
+ {{0x365c, 0x3024, 0x242a, 0x800a, 0x4455, 0x26ea, 0x26e1, 0x1019, 0x07e6, 0x3054, 0x8008, 0x9ac0, 0x3ec9, 0x950c, 0x7ae1, 0x5419 }, 16, 0x000a2340, 1},
+ {{0x84d5, 0x9ac0, 0x6c84, 0x03e6, 0x3060, 0x8008, 0x9b45, 0x9ac0, 0x36ca, 0x950c, 0xd7c1, 0x2b03, 0x8046, 0x96c0, 0x6eb2, 0x3eca }, 16, 0x000a2360, 1},
+ {{0x950c, 0x98c0, 0xd5c5, 0x3fc0, 0x3d58, 0x8008, 0x36cd, 0x950c, 0x2c21, 0x2e88, 0x3cc0, 0x3bd8, 0x8008, 0x9ac0, 0xd416, 0xd696 }, 16, 0x000a2380, 1},
+ {{0x03e2, 0x3060, 0x8008, 0x2461, 0x26e1, 0x07e2, 0x3054, 0x8008, 0x2103, 0x8066, 0x3c48, 0x3ec8, 0x1219, 0x04e6, 0x3060, 0x8008 }, 16, 0x000a23a0, 1},
+ {{0x3e00, 0xa004, 0x3eca, 0x950c, 0x6465, 0x38cb, 0x950c, 0x5119, 0x3a00, 0xa088, 0x66e5, 0x6e38, 0x6dbd, 0x7c48, 0x3a00, 0xb000 }, 16, 0x000a23c0, 1},
+ {{0x7ec8, 0xd7c4, 0xd643, 0x7458, 0x98c0, 0x76dd, 0x3ec8, 0x950c, 0x405c, 0x96c0, 0x38cd, 0x950c, 0x455f, 0x9ad0, 0x6c29, 0x6e91 }, 16, 0x000a23e0, 1},
+ {{0x04e2, 0x3060, 0x8008, 0x9ac0, 0xd416, 0xd696, 0x07e2, 0x3054, 0x8008, 0x2461, 0x66e1, 0x3c48, 0x7ec8, 0x2465, 0x66e5, 0x3c48 }, 16, 0x000a2400, 1},
+ {{0x7ec8, 0x3458, 0x76dd, 0x0054, 0x4557, 0x3de0, 0x3034, 0x8008, 0x05e5, 0x306d, 0x8008, 0x3465, 0x1515, 0x07e7, 0x3068, 0x8008 }, 16, 0x000a2420, 1},
+ {{0x2469, 0x7ac1, 0xd79d, 0x98c3, 0xc681, 0x32e1, 0x3028, 0x8008, 0x94c3, 0xf604, 0xf703, 0x98c3, 0xf241, 0x39c0, 0x3ed8, 0x8008 }, 16, 0x000a2440, 1},
+ {{0x96c3, 0x3224, 0x3afe, 0x800a, 0x96c3, 0x38c0, 0x3d58, 0x8008, 0x01e5, 0x306e, 0x8008, 0x7461, 0x6469, 0x90c0, 0x98c3, 0xc581 }, 16, 0x000a2460, 1},
+ {{0x33e1, 0x2ff8, 0x8008, 0x94c3, 0xf504, 0xf703, 0x98c3, 0xf341, 0x39c0, 0x3f98, 0x8008, 0x96c3, 0x3224, 0x3afe, 0x800a, 0x96c3 }, 16, 0x000a2480, 1},
+ {{0x38c0, 0x3bd8, 0x8008, 0x0025, 0x336a, 0x8009, 0x77e0, 0xd3a4, 0x90c0, 0x96c2, 0x3344, 0x3ad0, 0x800a, 0xe768, 0x94c0, 0x9e21 }, 16, 0x000a24a0, 1},
+ {{0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a24c0, 1},
+ {{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x04c4, 0x22cc, 0x8009, 0xe748, 0x94c0, 0xd230, 0xf004 }, 16, 0x000a24e0, 1},
+ {{0x8045, 0x3414, 0x8030, 0x802d, 0x96c0, 0x3414, 0x8060, 0x7540, 0x94c0, 0xd892, 0x801f, 0x96c0, 0x3414, 0x8020, 0x7440, 0x94c0 }, 16, 0x000a2500, 1},
+ {{0xd990, 0x8427, 0x3024, 0x2544, 0x800a, 0x03fe, 0x9ff8, 0x01fe, 0x9ff8, 0x9ac0, 0x03fc, 0x9ff8, 0x90c0, 0x2521, 0x8aaa, 0x64ad }, 16, 0x000a2520, 1},
+ {{0x01fe, 0x9ff8, 0x98c0, 0xf284, 0x3181, 0x2937, 0x8000, 0x98c0, 0x2400, 0x8041, 0xd992, 0xe768, 0x3465, 0x8001, 0x96c0, 0xd81d }, 16, 0x000a2540, 1},
+ {{0x3ac9, 0x8343, 0x6808, 0x7c4d, 0x94c0, 0x6461, 0x9f70, 0xd441, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a2560, 1},
+ {{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x34d0, 0x2460, 0x3211, 0x2000, 0x8000, 0x3160, 0x24e6, 0x2461 }, 16, 0x000a2580, 1},
+ {{0x3508, 0x2000, 0x8000, 0x98c6, 0x33e1, 0x3fff, 0x803f, 0x6c90, 0x334c, 0x8000, 0x2669, 0x3b40, 0x31e8, 0x8008, 0x3940, 0x33e8 }, 16, 0x000a25a0, 1},
+ {{0x8008, 0x94c3, 0xca41, 0xcd42, 0x90c0, 0x92c3, 0xed3a, 0x92c3, 0xcd49, 0x72e1, 0x90c0, 0x98c6, 0x6468, 0x31e0, 0x3fff, 0xbfff }, 16, 0x000a25c0, 1},
+ {{0x96c0, 0xdd81, 0x32c9, 0x9296, 0x96c0, 0x7cc1, 0x36ca, 0x8647, 0x94c0, 0xd892, 0xca41, 0x90c0, 0xeb1a, 0x1313, 0xea19, 0x1052 }, 16, 0x000a25e0, 1},
+ {{0xda93, 0x66e1, 0x6291, 0x92c3, 0x66e4, 0x94c0, 0x76cd, 0x9f70, 0xd81d, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a2600, 1},
+ {{0x98c0, 0x3bc8, 0x2400, 0xbfff, 0xc482, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x0493, 0xefe8, 0x3a20, 0xa000, 0x08c6 }, 16, 0x000a2620, 1},
+ {{0x38d0, 0x8008, 0x5397, 0x98c0, 0x03e2, 0x35c0, 0x8008, 0xe748, 0x3a80, 0xa000, 0xe850, 0x3d20, 0x336c, 0x8009, 0x3a80, 0xa000 }, 16, 0x000a2640, 1},
+ {{0x51d0, 0x3ee0, 0x35a0, 0x8008, 0x3c20, 0xa000, 0x2808, 0x8028, 0x90c0, 0x331d, 0x80ff, 0x3ec2, 0x3621, 0x3474, 0x8009, 0xcc45 }, 16, 0x000a2660, 1},
+ {{0x90c0, 0xec1d, 0x5394, 0x03e2, 0x359c, 0x8008, 0x3480, 0xa000, 0x55d0, 0x3ac9, 0x8208, 0xc941, 0x90c0, 0xe9fe, 0xe91d, 0x5391 }, 16, 0x000a2680, 1},
+ {{0x439e, 0x4696, 0x53d0, 0x371d, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7465, 0x98c0, 0x09c6, 0x38d0, 0x8008, 0xee44, 0x4016, 0x290a }, 16, 0x000a26a0, 1},
+ {{0x8038, 0x54d2, 0x38cc, 0x8208, 0x3244, 0x3d90, 0x800a, 0x7464, 0x9ac0, 0x6f10, 0x0ac6, 0x38d0, 0x8008, 0xee42, 0x001e, 0x3c20 }, 16, 0x000a26c0, 1},
+ {{0x336c, 0x8009, 0x0616, 0xea52, 0x12d2, 0x3ee0, 0x358c, 0x8008, 0x9ac0, 0x2a0b, 0x8028, 0x90c0, 0x351c, 0x80ff, 0x3e42, 0x3321 }, 16, 0x000a26e0, 1},
+ {{0x3474, 0x8009, 0xc944, 0x90c0, 0xe91c, 0x5791, 0x07e2, 0x3588, 0x8008, 0x56d2, 0x3ccd, 0x8208, 0xc945, 0x90c0, 0xe9fe, 0xe91c }, 16, 0x000a2700, 1},
+ {{0x5491, 0x449e, 0x4396, 0x53d3, 0x3719, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7461, 0x98c0, 0x09c6, 0x38d0, 0x8008, 0xee44, 0x4016 }, 16, 0x000a2720, 1},
+ {{0x290b, 0x803a, 0x52d3, 0x34cc, 0x8208, 0x3244, 0x3d90, 0x800a, 0x7464, 0x9ac0, 0x6d10, 0x6e90, 0x6c90, 0xee42, 0x9770, 0x3455 }, 16, 0x000a2740, 1},
+ {{0x401e, 0x0216, 0x32e1, 0x359c, 0x8008, 0x33e1, 0x3588, 0x8008, 0x3ee0, 0x31f8, 0x8008, 0x3de0, 0x3078, 0x8008, 0x03e2, 0x35c4 }, 16, 0x000a2760, 1},
+ {{0x8008, 0x02e2, 0x35bc, 0x8008, 0x94c8, 0xc01e, 0xc01d, 0x98c0, 0x09e6, 0x35c0, 0x8008, 0xc782, 0x3401, 0x2000, 0x8030, 0xe9f1 }, 16, 0x000a2780, 1},
+ {{0x39e0, 0x35b0, 0x8008, 0x96c2, 0x3101, 0x2605, 0x8020, 0x96c2, 0x01e2, 0x35c0, 0x8008, 0x05e6, 0x35c0, 0x8008, 0x9ac0, 0x3b09 }, 16, 0x000a27a0, 1},
+ {{0x8030, 0x90c0, 0x3b1e, 0x8300, 0x3261, 0xdf28, 0x92c3, 0x6c90, 0x96c6, 0x737f, 0xc181, 0x7f42, 0x8026, 0x98c0, 0x01e1, 0x37cf }, 16, 0x000a27c0, 1},
+ {{0x8008, 0xcb46, 0xcca0, 0xeb19, 0x5a93, 0x90c0, 0x9a61, 0x3124, 0x2800, 0x800a, 0x3024, 0x2800, 0x800a, 0x2c00, 0x8060, 0xcc90 }, 16, 0x000a27e0, 1},
+ {{0x9ec0, 0x6e90, 0x6e10, 0x64e9, 0x0ce0, 0x37cc, 0x8008, 0xc681, 0x9ac0, 0x6f90, 0xecf8, 0x05e2, 0x3378, 0x8008, 0x98c0, 0x38ed }, 16, 0x000a2800, 1},
+ {{0x805f, 0xecfc, 0xc0ae, 0x98c0, 0xcc4b, 0x05e2, 0x3378, 0x8008, 0x98c7, 0x38ed, 0x805e, 0x90c0, 0x75fb, 0x98c7, 0x05e2, 0x3378 }, 16, 0x000a2820, 1},
+ {{0x8008, 0x7dc1, 0x96c0, 0x3ced, 0x805d, 0x6e10, 0x05e2, 0x3378, 0x8008, 0x36ed, 0x8310, 0x3be0, 0x337c, 0x8008, 0x05e2, 0x3378 }, 16, 0x000a2840, 1},
+ {{0x8008, 0x3eed, 0x804f, 0x31e1, 0x3078, 0x8008, 0x05e2, 0x3378, 0x8008, 0x419b, 0x4793, 0x1193, 0x32e1, 0x31f8, 0x8008, 0x3ce9 }, 16, 0x000a2860, 1},
+ {{0x805f, 0x4193, 0x5193, 0x3ce9, 0x805e, 0x4193, 0x5793, 0x3cef, 0x805d, 0x4793, 0x5793, 0x36ef, 0x8310, 0x4793, 0x5193, 0x38e9 }, 16, 0x000a2880, 1},
+ {{0x804f, 0x019b, 0x32e4, 0x3a68, 0x8001, 0x4293, 0x32e4, 0x3a5c, 0x8001, 0x98c0, 0x3920, 0x2f60, 0x800a, 0xc0ae, 0x32e4, 0x3a62 }, 16, 0x000a28a0, 1},
+ {{0x8001, 0x94c0, 0xc184, 0xc0ae, 0x32e4, 0x3a68, 0x8001, 0xc09a, 0x32e4, 0x3a5c, 0x8001, 0x98c0, 0x3920, 0x34d0, 0x800a, 0xc09a }, 16, 0x000a28c0, 1},
+ {{0x32e4, 0x3a62, 0x8001, 0x94c0, 0xc184, 0xc09a, 0x9f7d, 0x9ac0, 0x6c90, 0x3ac8, 0x2418, 0xbfff, 0xc7b0, 0x98c0, 0xf741, 0x3bc8 }, 16, 0x000a28e0, 1},
+ {{0x2418, 0xbfff, 0x1592, 0x39c8, 0x241c, 0xbfff, 0x96c0, 0x3b0f, 0x8010, 0xef44, 0x27e9, 0x38e0, 0x3540, 0x8008, 0x90c0, 0x96c2 }, 16, 0x000a2900, 1},
+ {{0x02e6, 0x35c0, 0x8008, 0x96c2, 0x36f9, 0x3fff, 0xbfef, 0x98c1, 0x05e6, 0x35c0, 0x8008, 0xdf02, 0x94c1, 0x4592, 0x4692, 0x5593 }, 16, 0x000a2920, 1},
+ {{0x3b0d, 0x8020, 0x66e9, 0x90c0, 0x96c2, 0x3cc8, 0x2418, 0xbfff, 0x96c3, 0x3ac8, 0x2418, 0xbfff, 0x96c2, 0x07e6, 0x35c0, 0x8008 }, 16, 0x000a2940, 1},
+ {{0x96c2, 0x33f9, 0x3fff, 0xbfdf, 0x98c1, 0x04e6, 0x35c0, 0x8008, 0xdd87, 0x94c1, 0x4492, 0x4394, 0x1797, 0x32e4, 0x3c8a, 0x8001 }, 16, 0x000a2960, 1},
+ {{0x4791, 0x3ac8, 0x241c, 0xbfff, 0x39e0, 0x3544, 0x8008, 0x1192, 0x3cc8, 0x241c, 0xbfff, 0x96c0, 0x331a, 0x8f00, 0xebe9, 0x94c0 }, 16, 0x000a2980, 1},
+ {{0xdd28, 0xeb62, 0x0211, 0x4213, 0x1194, 0xe94c, 0x96c0, 0x33f8, 0x9000, 0xeae9, 0x9ac0, 0xdc2c, 0xea62, 0x3bc8, 0x241c, 0xbfff }, 16, 0x000a29a0, 1},
+ {{0x0011, 0x4012, 0x1494, 0xe94c, 0x96c0, 0x390b, 0x800f, 0xece9, 0x9ac0, 0xd80b, 0xec62, 0x3ae8, 0x3c30, 0xbfff, 0x0011, 0x4014 }, 16, 0x000a29c0, 1},
+ {{0x1693, 0xe94c, 0x3d0f, 0x80f0, 0x98c0, 0xdfb4, 0x3309, 0x20ff, 0x9f55, 0x4709, 0x4711, 0x4392, 0x02e6, 0x35c0, 0x8008, 0x350f }, 16, 0x000a29e0, 1},
+ {{0x8030, 0x67e9, 0x90c0, 0x98c3, 0x32e0, 0x3378, 0x8008, 0xc783, 0x94c3, 0x0902, 0xa001, 0x96c3, 0x02e2, 0x35c8, 0x8008, 0x96c3 }, 16, 0x000a2a00, 1},
+ {{0x07e1, 0x37d0, 0x8008, 0x9f7c, 0x00e7, 0x37cc, 0x8008, 0x32e4, 0x3c48, 0x8001, 0x01a4, 0x33be, 0x8009, 0x9ec0, 0x77f0, 0x7750 }, 16, 0x000a2a20, 1},
+ {{0x6e90, 0xc2a0, 0x39e0, 0x378c, 0x8008, 0x9ac0, 0xd3a1, 0x38e0, 0x3464, 0x8008, 0xc381, 0x8087, 0x94c0, 0xf602, 0xf542, 0x3224 }, 16, 0x000a2a40, 1},
+ {{0x3600, 0x800a, 0xf201, 0x96c0, 0x6e10, 0xc2a0, 0xf602, 0x94c0, 0xf442, 0xf201, 0x39e0, 0x374c, 0x8008, 0x3224, 0x3600, 0x800a }, 16, 0x000a2a60, 1},
+ {{0x38e0, 0x3388, 0x8008, 0x9ac0, 0xd3a6, 0x6d10, 0x3be0, 0x346c, 0x8008, 0x841d, 0x3ce0, 0x3390, 0x8008, 0x3561, 0x2324, 0x8008 }, 16, 0x000a2a80, 1},
+ {{0x0593, 0x4594, 0x94c0, 0xeb52, 0xec52, 0x0213, 0x4214, 0x9ac0, 0xd3a3, 0x6f10, 0x39e0, 0x346c, 0x8008, 0x8433, 0x3be0, 0x3390 }, 16, 0x000a2aa0, 1},
+ {{0x8008, 0x3761, 0x27a6, 0x8008, 0x0791, 0x4793, 0x94c0, 0xe952, 0xeb52, 0x3024, 0x2aec, 0x800a, 0x0611, 0x4613, 0x39e0, 0x3476 }, 16, 0x000a2ac0, 1},
+ {{0x8008, 0x3be0, 0x339a, 0x8008, 0x4311, 0x4313, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0 }, 16, 0x000a2ae0, 1},
+ {{0x3e00, 0xa10c, 0x74d7, 0x7456, 0x07c5, 0x38b8, 0x8008, 0xe8ee, 0x3667, 0x0ec6, 0x38d0, 0x8008, 0xd226, 0x9ac0, 0x2e0e, 0x8010 }, 16, 0x000a2b00, 1},
+ {{0x90c0, 0x2718, 0x8184, 0x52d6, 0x351d, 0x80ff, 0xd2a5, 0x8025, 0xd2a6, 0x8021, 0xd2a7, 0x801d, 0xd2a8, 0x90c0, 0x98c3, 0x38e0 }, 16, 0x000a2b20, 1},
+ {{0x35ae, 0x8008, 0xc3fe, 0x90c0, 0x94c7, 0x843a, 0x5710, 0x92c3, 0xdd87, 0x9ac0, 0x6f90, 0x38e0, 0x35a4, 0x8008, 0xc081, 0x03e6 }, 16, 0x000a2b40, 1},
+ {{0x359c, 0x8008, 0x0390, 0x3221, 0x3474, 0x8009, 0xe848, 0xeae8, 0xea64, 0x5412, 0x4418, 0x02e2, 0x359c, 0x8008, 0x4712, 0x5310 }, 16, 0x000a2b60, 1},
+ {{0xdd98, 0x4310, 0x54d6, 0x38ca, 0x8208, 0x6561, 0xd125, 0x8025, 0xd126, 0x8021, 0xd127, 0x801d, 0xd128, 0x90c0, 0x98c3, 0x39e0 }, 16, 0x000a2b80, 1},
+ {{0x35ae, 0x8008, 0xc0fd, 0x90c0, 0x94c7, 0x8436, 0x5411, 0x92c3, 0xdc04, 0x9ac0, 0x6d90, 0x39e0, 0x35a4, 0x8008, 0xc182, 0x3621 }, 16, 0x000a2ba0, 1},
+ {{0x3474, 0x8009, 0xece9, 0xec64, 0x5594, 0x4591, 0xe948, 0xede9, 0xed62, 0x5415, 0x4419, 0x4694, 0x4315, 0x5011, 0xdc19, 0x0011 }, 16, 0x000a2bc0, 1},
+ {{0xee42, 0x56d6, 0x3d1e, 0x80ff, 0xd325, 0x8025, 0xd326, 0x8021, 0xd327, 0x801d, 0xd328, 0x90c0, 0x98c3, 0x38e0, 0x359a, 0x8008 }, 16, 0x000a2be0, 1},
+ {{0xc3fe, 0x90c0, 0x94c7, 0x843a, 0x5110, 0x92c3, 0xdd81, 0x9ac0, 0x6e90, 0x38e0, 0x3590, 0x8008, 0xc281, 0x06e6, 0x3588, 0x8008 }, 16, 0x000a2c00, 1},
+ {{0x0690, 0x3121, 0x3474, 0x8009, 0xe848, 0xebe8, 0xeb64, 0x5713, 0x4718, 0x01e2, 0x3588, 0x8008, 0x1310, 0x4513, 0xdd9a, 0x4310 }, 16, 0x000a2c20, 1},
+ {{0x52d6, 0x34ca, 0x8208, 0x6561, 0xd125, 0x8029, 0xd126, 0x8025, 0xd127, 0x8021, 0xd128, 0x90c0, 0x98c3, 0x3ae0, 0x359a, 0x8008 }, 16, 0x000a2c40, 1},
+ {{0xc5fd, 0x90c0, 0x92c3, 0x5212, 0x94c7, 0x8436, 0xde82, 0x92c3, 0x4512, 0x2f90, 0x3be0, 0x3590, 0x8008, 0x3221, 0x3474, 0x8009 }, 16, 0x000a2c60, 1},
+ {{0xe9eb, 0xe964, 0x5591, 0x4593, 0xeb48, 0xe8eb, 0xe862, 0x5010, 0x401b, 0x4291, 0x4710, 0x5013, 0x0900, 0xa002, 0x4013, 0x07c5 }, 16, 0x000a2c80, 1},
+ {{0x38bb, 0x8008, 0x7767, 0xd326, 0x8009, 0xd325, 0x2718, 0x8124, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0xec50, 0x53d4, 0x371b, 0x80ff }, 16, 0x000a2ca0, 1},
+ {{0xd1a9, 0x800f, 0xd1aa, 0x800b, 0xd1ab, 0x8007, 0xd1ac, 0x8433, 0x2d10, 0x3de0, 0x35a4, 0x8008, 0x07e6, 0x359c, 0x8008, 0x0795 }, 16, 0x000a2cc0, 1},
+ {{0x3021, 0x3474, 0x8009, 0xed48, 0xeaed, 0xea64, 0x5112, 0x411d, 0x00e2, 0x359c, 0x8008, 0x4212, 0x5515, 0x0905, 0xa001, 0x4515 }, 16, 0x000a2ce0, 1},
+ {{0x51d4, 0x32cf, 0x8208, 0x67e1, 0xd3a9, 0x800f, 0xd3aa, 0x800b, 0xd3ab, 0x8007, 0xd3ac, 0x842f, 0x2e90, 0x39e0, 0x35a4, 0x8008 }, 16, 0x000a2d00, 1},
+ {{0x3021, 0x3474, 0x8009, 0xe8e9, 0xe864, 0x5390, 0x4391, 0xe948, 0xeee9, 0xee62, 0x5616, 0x4619, 0x4090, 0x4516, 0x5611, 0x0906 }, 16, 0x000a2d20, 1},
+ {{0xa002, 0x4611, 0xec42, 0x53d4, 0x3718, 0x80ff, 0xd029, 0x800f, 0xd02a, 0x800b, 0xd02b, 0x8007, 0xd02c, 0x8433, 0x2e10, 0x3ae0 }, 16, 0x000a2d40, 1},
+ {{0x3590, 0x8008, 0x06e6, 0x3588, 0x8008, 0x0692, 0x3721, 0x3474, 0x8009, 0xea48, 0xebea, 0xeb64, 0x5213, 0x421a, 0x07e2, 0x3588 }, 16, 0x000a2d60, 1},
+ {{0x8008, 0x4413, 0x5312, 0x0903, 0xa001, 0x4312, 0x56d4, 0x3ccb, 0x8208, 0x65e1, 0xd1a9, 0x800f, 0xd1aa, 0x800b, 0xd1ab, 0x8007 }, 16, 0x000a2d80, 1},
+ {{0xd1ac, 0x842f, 0x2f10, 0x3ce0, 0x3590, 0x8008, 0x3421, 0x3474, 0x8009, 0xe8ec, 0xe864, 0x5790, 0x4794, 0xec48, 0xedec, 0xed62 }, 16, 0x000a2da0, 1},
+ {{0x5715, 0x471c, 0x4490, 0x4615, 0x5114, 0x0901, 0xa002, 0x4114, 0x3a20, 0xb800, 0x77d1, 0x7750, 0xeee8, 0x9f71, 0x90c0, 0x90c0 }, 16, 0x000a2dc0, 1},
+ {{0x0ae6, 0x35bc, 0x8008, 0x3820, 0xa000, 0x0ec6, 0x38d0, 0x8008, 0xea52, 0x94c0, 0x9620, 0x9720, 0x3840, 0xa100, 0x5712, 0x2e0d }, 16, 0x000a2de0, 1},
+ {{0x8038, 0x3880, 0xa000, 0x3f1b, 0x8001, 0x52d5, 0x9ac0, 0x65e9, 0x3519, 0x80ff, 0x9e20, 0x9f20, 0x94c0, 0x7461, 0x8017, 0x3344 }, 16, 0x000a2e00, 1},
+ {{0x3d90, 0x800a, 0x98c0, 0xc590, 0x3124, 0x2e38, 0x800a, 0x3244, 0x3d90, 0x800a, 0x7461, 0xc58c, 0x98c0, 0xcb45, 0x09e6, 0x35bc }, 16, 0x000a2e20, 1},
+ {{0x8008, 0x90c0, 0xeb19, 0x4013, 0x0ee6, 0x35bc, 0x8008, 0x0cc6, 0x38d0, 0x8008, 0xee52, 0x96c0, 0x5416, 0x2c0c, 0x8038, 0x96c0 }, 16, 0x000a2e40, 1},
+ {{0x3918, 0x8002, 0x56d4, 0x96c0, 0x6469, 0x3cc9, 0x8208, 0x94c0, 0x7461, 0x8017, 0x3344, 0x3d90, 0x800a, 0x98c0, 0xc390, 0x3124 }, 16, 0x000a2e60, 1},
+ {{0x2e92, 0x800a, 0x3cc9, 0x8208, 0x3244, 0x3d90, 0x800a, 0x7461, 0xc38e, 0x98c0, 0x0ce6, 0x35bc, 0x8008, 0xc843, 0x90c0, 0xe81c }, 16, 0x000a2e80, 1},
+ {{0x4010, 0x0fe6, 0x35c4, 0x8008, 0x0dc6, 0x38d0, 0x8008, 0xef52, 0x96c0, 0x5017, 0x2d0c, 0x803a, 0x96c0, 0x311e, 0x8001, 0x50d4 }, 16, 0x000a2ea0, 1},
+ {{0x6769, 0x96c7, 0x801b, 0x3118, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7460, 0x98c0, 0xc590, 0x3124, 0x2eea, 0x800a, 0x311c, 0x80ff }, 16, 0x000a2ec0, 1},
+ {{0x3244, 0x3d90, 0x800a, 0x7464, 0xc58c, 0x98c0, 0xcf45, 0x0de6, 0x35c4, 0x8008, 0x90c0, 0xef1d, 0x4017, 0x0be6, 0x35c4, 0x8008 }, 16, 0x000a2ee0, 1},
+ {{0x0dc6, 0x38d0, 0x8008, 0xeb52, 0x96c0, 0x5113, 0x2d08, 0x803a, 0x96c0, 0x331f, 0x8002, 0x55d0, 0x96c0, 0x67e9, 0x3ac8, 0x8208 }, 16, 0x000a2f00, 1},
+ {{0x94c0, 0x7460, 0x8017, 0x3344, 0x3d90, 0x800a, 0x98c0, 0xc590, 0x3124, 0x2f44, 0x800a, 0x3acd, 0x8208, 0x3244, 0x3d90, 0x800a }, 16, 0x000a2f20, 1},
+ {{0x7465, 0xc58e, 0x98c0, 0xcd45, 0x09e6, 0x35c4, 0x8008, 0x94c0, 0x9e21, 0x9f21, 0xed19, 0x94c0, 0x9621, 0x9721, 0x9f70, 0x4015 }, 16, 0x000a2f40, 1},
+ {{0x94c0, 0x9620, 0x9720, 0x98c0, 0x36aa, 0x3c20, 0xbfff, 0xc0ae, 0x94c0, 0x9e20, 0x9f20, 0x3680, 0xa000, 0x5696, 0xe750, 0x0622 }, 16, 0x000a2f60, 1},
+ {{0x333c, 0x8009, 0x3ee0, 0x35cc, 0x8008, 0x32e4, 0x3a68, 0x8001, 0x3fe0, 0x368c, 0x8008, 0x0125, 0x336a, 0x8009, 0x7461, 0xd022 }, 16, 0x000a2f80, 1},
+ {{0x90c0, 0x96c2, 0x3344, 0x3ad0, 0x800a, 0x3324, 0x2de0, 0x800a, 0x2f10, 0x3dc8, 0x3c14, 0xbfff, 0x39c0, 0x2040, 0x8008, 0x1295 }, 16, 0x000a2fa0, 1},
+ {{0x3dc0, 0x21c0, 0x8008, 0x3509, 0x8100, 0x24e9, 0x3ba0, 0x3e00, 0x8008, 0x8019, 0x2704, 0x8060, 0x3ca0, 0x3f80, 0x8008, 0x90c0 }, 16, 0x000a2fc0, 1},
+ {{0x94d0, 0x461c, 0x461b, 0x0619, 0x461d, 0x98c0, 0x0ae6, 0x35bc, 0x8008, 0xc781, 0x98c0, 0xf707, 0x02a4, 0x33be, 0x8009, 0x1992 }, 16, 0x000a2fe0, 1},
+ {{0xea4c, 0x1412, 0xecea, 0x94c0, 0xea42, 0xec68, 0x1794, 0x5312, 0x94c0, 0xf206, 0xf742, 0x94c0, 0xf305, 0xf401, 0x32e4, 0x208e }, 16, 0x000a3000, 1},
+ {{0x800a, 0x38e0, 0x35cc, 0x8008, 0x98c0, 0x0ce6, 0x35c4, 0x8008, 0xc681, 0x98c0, 0x01a4, 0x33be, 0x8009, 0xf607, 0x1994, 0xec4c }, 16, 0x000a3020, 1},
+ {{0x1714, 0xedec, 0x94c0, 0xed68, 0xec42, 0x1495, 0x5514, 0x94c0, 0xf106, 0xf442, 0x94c0, 0xf505, 0xf701, 0x32e4, 0x208e, 0x800a }, 16, 0x000a3040, 1},
+ {{0x38e0, 0x368c, 0x8008, 0x02e6, 0x35c0, 0x8008, 0x3508, 0x8010, 0x2469, 0x3ae0, 0x3476, 0x8008, 0x802b, 0x1612, 0x39e0, 0x35cc }, 16, 0x000a3060, 1},
+ {{0x8008, 0x98c0, 0xd321, 0x06a4, 0x33be, 0x8009, 0x8017, 0x3224, 0x3a38, 0x800a, 0x98c0, 0xf601, 0x38e0, 0x3464, 0x8008, 0x90c0 }, 16, 0x000a3080, 1},
+ {{0xeee8, 0x03e6, 0x35c0, 0x8008, 0x3708, 0x8020, 0x2469, 0x3de0, 0x339a, 0x8008, 0x802b, 0x1715, 0x00a4, 0x33be, 0x8009, 0x98c0 }, 16, 0x000a30a0, 1},
+ {{0xd3a1, 0x39e0, 0x368c, 0x8008, 0x8017, 0x3224, 0x3a38, 0x800a, 0x98c0, 0xf001, 0x38e0, 0x3388, 0x8008, 0x90c0, 0xefe8, 0x98c0 }, 16, 0x000a30c0, 1},
+ {{0x0de6, 0x35bc, 0x8008, 0xc281, 0x98c0, 0x06e4, 0x37cc, 0x8008, 0xe9ee, 0x98c0, 0xed50, 0x3481, 0x2000, 0x8000, 0x1715, 0xed68 }, 16, 0x000a30e0, 1},
+ {{0x27e9, 0x1195, 0xe8ee, 0x8017, 0x94c0, 0xf207, 0xf606, 0x94c0, 0xf705, 0xf142, 0x32e4, 0x208e, 0x800a, 0xf401, 0x98c0, 0x0de6 }, 16, 0x000a3100, 1},
+ {{0x35c4, 0x8008, 0xc581, 0x98c0, 0x04e4, 0x37cc, 0x8008, 0xe9ef, 0x98c0, 0xed50, 0x3381, 0x2000, 0x8000, 0x1015, 0xed68, 0x2469 }, 16, 0x000a3120, 1},
+ {{0x1795, 0xe8ef, 0x8017, 0x94c0, 0xf507, 0xf406, 0x94c0, 0xf005, 0xf742, 0x32e4, 0x208e, 0x800a, 0xf301, 0x3ac8, 0x2404, 0xbfff }, 16, 0x000a3140, 1},
+ {{0x3be0, 0x3378, 0x8008, 0x1c92, 0x01e5, 0x37cf, 0x8008, 0x02e7, 0x37cc, 0x8008, 0xebac, 0x90c0, 0x96c2, 0x3ce0, 0x31f8, 0x8008 }, 16, 0x000a3160, 1},
+ {{0x98c7, 0x64e9, 0x3ce0, 0x3078, 0x8008, 0x8043, 0x9ac0, 0x656a, 0x3de0, 0x355e, 0x8008, 0xcaa4, 0x8499, 0x1015, 0xed4c, 0x1415 }, 16, 0x000a3180, 1},
+ {{0xe8ed, 0x96c0, 0x6c7c, 0xe83a, 0xed78, 0x96c0, 0x9b42, 0x2b03, 0x800e, 0x1110, 0x5515, 0x6d7c, 0x521f, 0xd51c, 0x421c, 0x92d0 }, 16, 0x000a31a0, 1},
+ {{0x521e, 0xd51d, 0x421c, 0x3124, 0x3230, 0x800a, 0x02e6, 0x35c0, 0x8008, 0x350a, 0x8010, 0x2569, 0x00e7, 0x37cc, 0x8008, 0x802b }, 16, 0x000a31c0, 1},
+ {{0x246a, 0x38e0, 0x3546, 0x8008, 0x8449, 0x1310, 0xe84c, 0x96c0, 0x9b40, 0x2b03, 0x800c, 0x5710, 0x6f7c, 0x92d0, 0x521e, 0xd51f }, 16, 0x000a31e0, 1},
+ {{0x421c, 0x3124, 0x3230, 0x800a, 0x07e7, 0x37cc, 0x8008, 0x27ea, 0x38e0, 0x355e, 0x8008, 0x841b, 0x1010, 0xe84c, 0x96c0, 0x9b47 }, 16, 0x000a3200, 1},
+ {{0x2b03, 0x800c, 0x5410, 0x6c7c, 0x92d0, 0x501f, 0xd41c, 0x401c, 0x9cc0, 0x6e90, 0x6c90, 0x00e5, 0x37ce, 0x8008, 0xc298, 0x9ac0 }, 16, 0x000a3220, 1},
+ {{0x6469, 0x3ae0, 0x3542, 0x8008, 0xc088, 0x2518, 0x826a, 0x96c0, 0x9344, 0x2a0e, 0x8004, 0x96c0, 0xe8ee, 0x2b03, 0x802a, 0x98c0 }, 16, 0x000a3240, 1},
+ {{0x3de0, 0x3540, 0x8008, 0xe862, 0x3cc8, 0x241c, 0xbfff, 0x39c8, 0x2420, 0xbfff, 0x3fc8, 0x2418, 0xbfff, 0x94c0, 0x2e0b, 0x8002 }, 16, 0x000a3260, 1},
+ {{0x94c0, 0x97bd, 0x5413, 0x67e9, 0x2518, 0x8212, 0x3820, 0xa000, 0x6669, 0xc581, 0xcb85, 0x98c7, 0x2618, 0x8204, 0x90c0, 0x7a61 }, 16, 0x000a3280, 1},
+ {{0x92c3, 0x4413, 0x3a20, 0xa000, 0x9dbd, 0x30e2, 0x3570, 0x8008, 0x90c0, 0x34a0, 0xa000, 0xed8b, 0x3880, 0xa000, 0xedfe, 0x2518 }, 16, 0x000a32a0, 1},
+ {{0x81e2, 0x36a0, 0xa000, 0xed18, 0xc783, 0x3840, 0xa100, 0xd791, 0x5e95, 0x5316, 0x94c0, 0xc483, 0xc683, 0x3880, 0xa000, 0xd611 }, 16, 0x000a32c0, 1},
+ {{0xd711, 0x9e61, 0x1391, 0x5410, 0x98c0, 0xdf83, 0x7a41, 0x5310, 0xc683, 0x67e0, 0x27e9, 0xc78f, 0x94c0, 0xd790, 0x8041, 0x25e9 }, 16, 0x000a32e0, 1},
+ {{0x39e1, 0xc78f, 0x94c0, 0xd790, 0x801f, 0x96c0, 0xdb07, 0xd590, 0x4310, 0x5794, 0xdf07, 0x98c0, 0xdd9e, 0x3024, 0x332c, 0x800a }, 16, 0x000a3300, 1},
+ {{0x4394, 0x1616, 0xc382, 0x7b41, 0x4616, 0x939d, 0x98c0, 0xc7b2, 0x3024, 0x349a, 0x800a, 0x4713, 0x3a00, 0xa004, 0xda07, 0xd610 }, 16, 0x000a3320, 1},
+ {{0x4410, 0xc3b2, 0x5794, 0x3400, 0xa004, 0xde07, 0x3400, 0xa800, 0xde1c, 0x4494, 0x0313, 0x3024, 0x349a, 0x800a, 0x969d, 0x1491 }, 16, 0x000a3340, 1},
+ {{0xc783, 0x94c0, 0xd791, 0xc6b2, 0xdf84, 0x67e0, 0x27e9, 0xc784, 0x94c6, 0x8031, 0x79e1, 0x39c1, 0xc781, 0x3673, 0x0316, 0xd792 }, 16, 0x000a3360, 1},
+ {{0x94c0, 0xd230, 0xdb87, 0x840f, 0x5397, 0xdf83, 0x4797, 0x3420, 0xa000, 0x9b9d, 0x98c0, 0xc6b2, 0x3024, 0x349a, 0x800a, 0x4613 }, 16, 0x000a3380, 1},
+ {{0x4316, 0x0613, 0x3024, 0x349a, 0x800a, 0x979d, 0x1791, 0x5610, 0x1310, 0xde07, 0x6660, 0x2669, 0x5412, 0x8041, 0x98c0, 0x6769 }, 16, 0x000a33a0, 1},
+ {{0x7b61, 0xc78f, 0xc481, 0x94c0, 0xd790, 0x801f, 0x96c0, 0xdb87, 0xd710, 0x4610, 0x5394, 0xdf83, 0x98c0, 0xdf1f, 0x3024, 0x33ec }, 16, 0x000a33c0, 1},
+ {{0x800a, 0x4694, 0x1616, 0xc482, 0x7b41, 0x4616, 0x94c0, 0x949d, 0xc7b2, 0x0713, 0x3124, 0x349a, 0x800a, 0x98c0, 0x7263, 0x79c1 }, 16, 0x000a33e0, 1},
+ {{0xc68f, 0xc4b2, 0x96c0, 0xd710, 0xc783, 0x802d, 0x3800, 0xa004, 0xdb06, 0xd590, 0x4310, 0x5694, 0x3400, 0xa004, 0xdf06, 0x3400 }, 16, 0x000a3400, 1},
+ {{0xa800, 0xdd9e, 0x4394, 0x0413, 0x3024, 0x349a, 0x800a, 0x979d, 0x2d90, 0x3024, 0x349a, 0x800a, 0x939d, 0x5491, 0xdf04, 0x6760 }, 16, 0x000a3420, 1},
+ {{0x6769, 0x90c0, 0x94c3, 0x5716, 0xc4b2, 0x94c3, 0x7bc1, 0xc682, 0x92c3, 0x4716, 0x94c7, 0x8446, 0x4413, 0x92c3, 0x969d, 0x1416 }, 16, 0x000a3440, 1},
+ {{0xc38f, 0x2669, 0xd590, 0x3607, 0xa008, 0x7a61, 0xdb03, 0x94c3, 0x4416, 0xc6b2, 0x94c7, 0x8427, 0x4613, 0x1710, 0xc6b2, 0x3bc1 }, 16, 0x000a3460, 1},
+ {{0xc483, 0x0710, 0xd790, 0x5394, 0x3400, 0xa004, 0xdf03, 0x3400, 0xa800, 0xdf9e, 0x4794, 0x4613, 0x949d, 0x9ad0, 0x78c2, 0x7844 }, 16, 0x000a3480, 1},
+ {{0x7941, 0xeb4c, 0xe84c, 0x94c0, 0xee4c, 0xea4c, 0xed4c, 0x05e1, 0x37ce, 0x8008, 0xe770, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621 }, 16, 0x000a34a0, 1},
+ {{0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x32e4, 0x3a68, 0x8001, 0xc09a, 0x94c0, 0xc181, 0x9f70, 0x01e1 }, 16, 0x000a34c0, 1},
+ {{0x37ce, 0x8008, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a34e0, 1},
+ {{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6e90, 0x9720, 0x4998, 0x94c0, 0x9e20, 0x9f20, 0x0990 }, 16, 0x000a3500, 1},
+ {{0xf38d, 0x96c0, 0x65ea, 0xe84c, 0xc2a0, 0x4310, 0x94c0, 0xe846, 0x8412, 0x4210, 0x9f43, 0x90c0, 0x90c0, 0x92c8, 0x4519, 0x98c0 }, 16, 0x000a3520, 1},
+ {{0x6e90, 0x6d90, 0xf4c8, 0xefe8, 0x98c0, 0x6669, 0xef6a, 0x2304, 0x8060, 0x96c0, 0xebe8, 0x2b03, 0x8016, 0x96c1, 0x4497, 0x2f09 }, 16, 0x000a3540, 1},
+ {{0x8010, 0x94c6, 0xeb6a, 0x4997, 0x3ac2, 0x1d93, 0xce45, 0x90d0, 0xed1e, 0x4315, 0x94c0, 0xebe8, 0xf78e, 0x94c0, 0xd3a2, 0xeb64 }, 16, 0x000a3560, 1},
+ {{0x94c0, 0x4713, 0x8055, 0xd3a1, 0x8043, 0x9ac0, 0xd3a3, 0x3561, 0x26e6, 0x8008, 0xc381, 0x96c0, 0x8029, 0x2200, 0x8060, 0x9ac0 }, 16, 0x000a3580, 1},
+ {{0xd3a6, 0x3061, 0x24a4, 0x8008, 0xc382, 0x96c0, 0x842b, 0x2200, 0x80c0, 0xe86e, 0x0090, 0x3024, 0x35ee, 0x800a, 0xe84c, 0xe86e }, 16, 0x000a35a0, 1},
+ {{0x0590, 0x3024, 0x35ee, 0x800a, 0xe84c, 0x98c0, 0xe862, 0x3124, 0x35ee, 0x800a, 0x94c0, 0xc082, 0xe86e, 0x0013, 0x3261, 0x2866 }, 16, 0x000a35c0, 1},
+ {{0x8008, 0x0290, 0xc381, 0x96c0, 0xe84c, 0x2200, 0x8040, 0x4310, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0xe844, 0x9721, 0x9f70, 0x4210 }, 16, 0x000a35e0, 1},
+ {{0x96c0, 0x6f10, 0x9620, 0x9720, 0x0998, 0xc0a0, 0x94c0, 0x9e20, 0x9f20, 0x0990, 0xf38d, 0x25ea, 0xe84c, 0x4310, 0x94c0, 0xe846 }, 16, 0x000a3600, 1},
+ {{0x8412, 0x4010, 0x9f43, 0x90c0, 0x90c0, 0x92c8, 0x4619, 0x98c0, 0x6f90, 0x6e90, 0xf4c8, 0xeae8, 0x98c0, 0x6669, 0xea6a, 0x2304 }, 16, 0x000a3620, 1},
+ {{0x8060, 0x96c0, 0xefe8, 0x2b03, 0x8016, 0x96c1, 0x4492, 0x2a0e, 0x8010, 0x94c6, 0xef6a, 0x4e92, 0x3bc2, 0x1997, 0xcb47, 0x90d0 }, 16, 0x000a3640, 1},
+ {{0xe91b, 0x4511, 0x94c0, 0xede8, 0xf18e, 0x94c0, 0xd0a2, 0xed64, 0x94c0, 0x4115, 0x8073, 0xd0a1, 0x805f, 0x9ac0, 0xd0a3, 0x3461 }, 16, 0x000a3660, 1},
+ {{0x26e6, 0x8008, 0xc381, 0x96c0, 0x8037, 0x2000, 0x8060, 0x9ac0, 0xd0a6, 0x3461, 0x24a4, 0x8008, 0xc782, 0x96c0, 0x8449, 0x2340 }, 16, 0x000a3680, 1},
+ {{0x8000, 0x96c0, 0xe86e, 0x2000, 0x80c0, 0x4490, 0xe84c, 0x4710, 0x98c0, 0xe846, 0x3024, 0x3704, 0x800a, 0x4308, 0xe86e, 0x96c0 }, 16, 0x000a36a0, 1},
+ {{0x4490, 0x2440, 0x8000, 0xe84c, 0x4310, 0x98c0, 0xe846, 0x3024, 0x3704, 0x800a, 0x4408, 0xe862, 0x0510, 0x3024, 0x3704, 0x800a }, 16, 0x000a36c0, 1},
+ {{0xe844, 0x96c0, 0x6c90, 0xc582, 0xe86e, 0x0515, 0x3761, 0x2866, 0x8008, 0x0790, 0xc381, 0x96c0, 0xe84c, 0x2000, 0x8040, 0x4310 }, 16, 0x000a36e0, 1},
+ {{0xe846, 0x4108, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f70, 0x4010, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a3700, 1},
+ {{0x3e00, 0xa10c, 0x7456, 0x74d7, 0x02a4, 0x33be, 0x8009, 0xe8ef, 0x98c0, 0x3612, 0x8020, 0xe748, 0xc481, 0x2718, 0x8102, 0x9ac0 }, 16, 0x000a3720, 1},
+ {{0x2200, 0x80c0, 0x90c0, 0x3412, 0x8030, 0x98c0, 0x3181, 0x26a0, 0x8009, 0xf201, 0x94c1, 0xc783, 0xc782, 0x94c0, 0xf142, 0xf702 }, 16, 0x000a3740, 1},
+ {{0x39e0, 0x3a00, 0x8008, 0x3224, 0x3510, 0x800a, 0x3820, 0x2178, 0x8009, 0x98c0, 0x3081, 0x23a0, 0x8009, 0xf702, 0x96c0, 0xf042 }, 16, 0x000a3760, 1},
+ {{0x2400, 0x80c0, 0x98c0, 0xf401, 0x3900, 0x2e00, 0x8009, 0x3224, 0x3510, 0x800a, 0x3800, 0x3804, 0x8009, 0x98c0, 0x3181, 0x22e0 }, 16, 0x000a3780, 1},
+ {{0x8009, 0xf702, 0x96c0, 0xf142, 0x2000, 0x80c0, 0x98c0, 0xf001, 0x3900, 0x2600, 0x8009, 0x3224, 0x3510, 0x800a, 0x3800, 0x3494 }, 16, 0x000a37a0, 1},
+ {{0x8009, 0x98c0, 0x3281, 0x25e0, 0x8009, 0xf702, 0x96c0, 0xf242, 0x2600, 0x80c0, 0x98c0, 0xf601, 0x39e0, 0x3e00, 0x8008, 0x3224 }, 16, 0x000a37c0, 1},
+ {{0x3510, 0x800a, 0x3800, 0x3200, 0x8009, 0x98c0, 0x3481, 0x29a0, 0x8009, 0xc6a0, 0x94c0, 0xf442, 0xf702, 0x98c0, 0xf601, 0x3900 }, 16, 0x000a37e0, 1},
+ {{0x3080, 0x8009, 0x3224, 0x3600, 0x800a, 0x3800, 0x3d2c, 0x8009, 0x98c0, 0x3481, 0x2b20, 0x8009, 0xc5a0, 0x94c0, 0xf442, 0xf702 }, 16, 0x000a3800, 1},
+ {{0x98c0, 0xf501, 0x3900, 0x31c0, 0x8009, 0x3224, 0x3600, 0x800a, 0x3800, 0x3b74, 0x8009, 0x3124, 0x386c, 0x800a, 0x3a00, 0x3d3e }, 16, 0x000a3820, 1},
+ {{0x8009, 0x3800, 0x3b86, 0x8009, 0x0412, 0x3920, 0x218a, 0x8009, 0x0410, 0x3d00, 0x3816, 0x8009, 0x0411, 0x3c00, 0x34a6, 0x8009 }, 16, 0x000a3840, 1},
+ {{0x0415, 0x3f00, 0x3212, 0x8009, 0x4414, 0x4417, 0x3a40, 0xb800, 0x77d1, 0x7750, 0xe768, 0xefe8, 0x9f71, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a3860, 1},
+ {{0x3e80, 0xa10b, 0xd028, 0x75d6, 0x76d7, 0x7451, 0xe8ee, 0xe9ef, 0x98c0, 0x3e20, 0x24e8, 0x8009, 0xc784, 0x98c0, 0xe748, 0x3c20 }, 16, 0x000a3880, 1},
+ {{0x2508, 0x8009, 0x3a40, 0xa000, 0x3f20, 0x2538, 0x8009, 0xc4a0, 0x94c1, 0xc681, 0xc682, 0x3222, 0x2528, 0x8009, 0x3620, 0xa000 }, 16, 0x000a38a0, 1},
+ {{0x2100, 0x80c0, 0x3800, 0xa100, 0x6d90, 0x589a, 0x599e, 0x94c0, 0xf342, 0xf602, 0x3224, 0x3600, 0x800a, 0x3420, 0xa000, 0xf401 }, 16, 0x000a38c0, 1},
+ {{0x2d10, 0x189f, 0x599c, 0x94c0, 0xf242, 0xf602, 0x3224, 0x3510, 0x800a, 0x3420, 0xa000, 0xf101, 0x7be1, 0x67ea, 0x81c9, 0x3c00 }, 16, 0x000a38e0, 1},
+ {{0xa800, 0x74d0, 0xc784, 0x3c20, 0x2518, 0x8009, 0x3c20, 0xa000, 0xd0a8, 0x3f20, 0x24f8, 0x8009, 0xc0a0, 0x3e20, 0x2558, 0x8009 }, 16, 0x000a3900, 1},
+ {{0x94c1, 0xc681, 0xc682, 0x3622, 0x2548, 0x8009, 0x3620, 0xa000, 0x2200, 0x80c0, 0x3800, 0xa100, 0x6d90, 0x589e, 0x599f, 0x94c0 }, 16, 0x000a3920, 1},
+ {{0xf342, 0xf602, 0x3224, 0x3600, 0x800a, 0x3420, 0xa000, 0xf001, 0x2e10, 0x189e, 0x599c, 0x94c0, 0xf442, 0xf602, 0x3224, 0x3510 }, 16, 0x000a3940, 1},
+ {{0x800a, 0x3420, 0xa000, 0xf201, 0x7be1, 0x67ea, 0x81c9, 0x3a40, 0xb800, 0x77d5, 0x7753, 0xe768, 0xefe9, 0x3620, 0xa000, 0xeee8 }, 16, 0x000a3960, 1},
+ {{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x3600, 0xa100, 0xf185, 0xefe8, 0x9730, 0x94c0, 0x9c22, 0x9530 }, 16, 0x000a3980, 1},
+ {{0x1c98, 0x1005, 0xa004, 0x3420, 0xa000, 0x5c98, 0x3820, 0xa000, 0x5898, 0x2803, 0x8040, 0x3420, 0xa000, 0x5e98, 0x3640, 0xa100 }, 16, 0x000a39a0, 1},
+ {{0x5018, 0xeaec, 0x1418, 0x6c50, 0x1518, 0xcc50, 0x94c0, 0x9841, 0x5018, 0x3420, 0xa000, 0x5118, 0x3620, 0xa008, 0x5018, 0x64ed }, 16, 0x000a39c0, 1},
+ {{0x3a40, 0xa000, 0x3703, 0x2800, 0x8008, 0xe8ee, 0x9d44, 0x3420, 0xa000, 0xebe8, 0x90c0, 0x92d0, 0x5059, 0x903c, 0x2c10, 0xeaec }, 16, 0x000a39e0, 1},
+ {{0x3420, 0xa000, 0x9d41, 0x90c0, 0x125a, 0x535b, 0x96c8, 0x601d, 0x525a, 0x535b, 0x641d, 0x92d0, 0xd41d, 0x7458, 0x94c0, 0x9028 }, 16, 0x000a3a00, 1},
+ {{0x6c10, 0x94c0, 0x9c23, 0x9531, 0x90c0, 0x90c0, 0x9731, 0x9f70, 0x36c0, 0xa000, 0x4c97, 0xe8ee, 0x3600, 0xa100, 0xf185, 0xefe8 }, 16, 0x000a3a20, 1},
+ {{0x9730, 0x94c0, 0x9b22, 0x9c22, 0x94c0, 0x9530, 0x5c98, 0x3820, 0xa000, 0x5c98, 0x1005, 0xa004, 0x3420, 0xa000, 0x5898, 0x3420 }, 16, 0x000a3a40, 1},
+ {{0xa000, 0x5e98, 0x3640, 0xa100, 0x5018, 0xeaec, 0x98c0, 0x6c50, 0x5418, 0x2803, 0x802e, 0x1518, 0xcc50, 0x3620, 0xa000, 0x5118 }, 16, 0x000a3a60, 1},
+ {{0x9841, 0x1018, 0xcb54, 0x3c40, 0xa004, 0x64ed, 0x5058, 0x3703, 0x2800, 0x8008, 0x3420, 0xa000, 0xe8ee, 0x96c0, 0x9944, 0x2903 }, 16, 0x000a3a80, 1},
+ {{0x8012, 0x5059, 0x3640, 0xa000, 0x983c, 0xede8, 0x3420, 0xa000, 0x9e41, 0x94c0, 0xebed, 0xeaec, 0x3640, 0xa000, 0x6c10, 0x571d }, 16, 0x000a3aa0, 1},
+ {{0x125a, 0x537b, 0x96c8, 0x601d, 0x525a, 0x537b, 0x3610, 0xa008, 0x601d, 0x6469, 0x3611, 0xb000, 0x7448, 0x6410, 0x4058, 0x3620 }, 16, 0x000a3ac0, 1},
+ {{0xa000, 0x574c, 0x6c10, 0x9531, 0x90c0, 0x90c0, 0x94c0, 0x9b23, 0x9c23, 0x9731, 0x9f70, 0x36c0, 0xa000, 0x4c97, 0xe8ee, 0xfbc3 }, 16, 0x000a3ae0, 1},
+ {{0xf287, 0x94c0, 0x9530, 0x9822, 0x94c0, 0x9730, 0x9c22, 0x3820, 0xa000, 0x5a9b, 0x1005, 0xa004, 0x1a9b, 0xedeb, 0x96c0, 0x5c9b }, 16, 0x000a3b00, 1},
+ {{0x2803, 0x8028, 0x94c0, 0x9842, 0x5313, 0x9ac0, 0x2c02, 0x8080, 0x90c0, 0x187a, 0x9fe0, 0x3703, 0x2800, 0x8000, 0x3680, 0xa000 }, 16, 0x000a3b20, 1},
+ {{0xe8ec, 0x65e9, 0x957f, 0x94c1, 0xc118, 0x5198, 0x94c1, 0xc01a, 0x419a, 0x115a, 0x105c, 0x6d10, 0x96d8, 0x6111, 0x505c, 0x515a }, 16, 0x000a3b40, 1},
+ {{0x3840, 0xa000, 0x6511, 0xece8, 0x65e9, 0x4261, 0x94c0, 0x9731, 0x9c23, 0x94c0, 0x9531, 0x9823, 0x90c0, 0x90c0, 0x9f70, 0x4a95 }, 16, 0x000a3b60, 1},
+ {{0x3620, 0xa100, 0xf785, 0xe9e8, 0x3680, 0xa000, 0xca47, 0xe9e8, 0x3600, 0xa008, 0x9730, 0x74d1, 0x94c0, 0x9c22, 0x9530, 0x3c02 }, 16, 0x000a3b80, 1},
+ {{0x2016, 0x8000, 0x94c0, 0x9632, 0x9732, 0x94c0, 0x9620, 0x9720, 0x1005, 0xa004, 0xe90a, 0x3703, 0x2080, 0x8000, 0x3a60, 0x22a0 }, 16, 0x000a3ba0, 1},
+ {{0x8008, 0x944a, 0x2c10, 0x2c90, 0x2d10, 0x6d90, 0x3640, 0xa000, 0x4dda, 0x5059, 0x3e48, 0xa0f0, 0x6000, 0x6081, 0x6102, 0x6183 }, 16, 0x000a3bc0, 1},
+ {{0x4dda, 0x5059, 0x3a00, 0xa0f0, 0x6000, 0x6081, 0x6102, 0x6183, 0x2465, 0x24e5, 0x2565, 0x65e5, 0x3600, 0xb800, 0x7651, 0x76d1 }, 16, 0x000a3be0, 1},
+ {{0x3600, 0xa004, 0x3683, 0x8005, 0x3400, 0xa804, 0xd99b, 0x3600, 0xa004, 0x3883, 0x8005, 0x3600, 0xa004, 0x38a3, 0x8004, 0x3600 }, 16, 0x000a3c00, 1},
+ {{0xa804, 0xd99b, 0xda1c, 0x3600, 0xa004, 0x3883, 0x8005, 0x3800, 0xba01, 0x7653, 0x76d3, 0x7551, 0x3c00, 0xa846, 0x3645, 0x8003 }, 16, 0x000a3c20, 1},
+ {{0x90c0, 0x3686, 0x8005, 0x3600, 0xb80c, 0xda9d, 0xdb1e, 0x3c00, 0xa846, 0x3845, 0x8003, 0x90c0, 0x3886, 0x8005, 0x3c00, 0xa846 }, 16, 0x000a3c40, 1},
+ {{0x3865, 0x8002, 0x90c0, 0x38a6, 0x8004, 0x3a00, 0xba0d, 0xda9d, 0xdb1e, 0xd91a, 0xda1c, 0x3c00, 0xa846, 0x3845, 0x8003, 0x90c0 }, 16, 0x000a3c60, 1},
+ {{0x3886, 0x8005, 0x3800, 0xa00d, 0x7451, 0x7552, 0x7653, 0x3c00, 0xac60, 0x3605, 0x8001, 0x90c0, 0x3646, 0x8003, 0x3a00, 0xa840 }, 16, 0x000a3c80, 1},
+ {{0x3687, 0x8005, 0xda9d, 0xdb1e, 0x3c00, 0xac60, 0x3805, 0x8001, 0xdb9f, 0x3846, 0x8003, 0x3600, 0xa840, 0x3887, 0x8005, 0x3c00 }, 16, 0x000a3ca0, 1},
+ {{0xac60, 0x3025, 0x8000, 0x90c0, 0x3066, 0x8002, 0x3a00, 0xa840, 0x30a7, 0x8004, 0xda9d, 0xdb1e, 0x3a00, 0xb603, 0xdb9f, 0xda19 }, 16, 0x000a3cc0, 1},
+ {{0xd99b, 0xdb9d, 0x3c00, 0xac20, 0x3085, 0x8000, 0x90c0, 0x3066, 0x8002, 0x3600, 0xa840, 0x30e7, 0x8004, 0x3600, 0xa004, 0x6fc1 }, 16, 0x000a3ce0, 1},
+ {{0x6cdf, 0x3400, 0xa804, 0x6fc7, 0x3400, 0xa004, 0x6769, 0x90c0, 0x96c2, 0x3124, 0x3dc4, 0x800a, 0x3a60, 0x22f8, 0x8008, 0x944a }, 16, 0x000a3d00, 1},
+ {{0x2c10, 0x6c90, 0x3640, 0xa000, 0x5d5a, 0x5059, 0x3a48, 0xa0c0, 0x6000, 0x6081, 0x5d5a, 0x5059, 0x3a00, 0xa6c3, 0x6000, 0x6081 }, 16, 0x000a3d20, 1},
+ {{0x7651, 0x76d6, 0x3600, 0xa840, 0x3683, 0x8005, 0xd99b, 0x3600, 0xa840, 0x3883, 0x8005, 0x3600, 0xa840, 0x38a3, 0x8004, 0x3600 }, 16, 0x000a3d40, 1},
+ {{0xb008, 0xd99b, 0xda1c, 0x3a00, 0xa841, 0x3883, 0x8005, 0x7650, 0x7551, 0x3c00, 0xa840, 0x3684, 0x8005, 0x90c0, 0x3645, 0x8003 }, 16, 0x000a3d60, 1},
+ {{0x94c0, 0xda1c, 0xda9d, 0x3c00, 0xa840, 0x3884, 0x8005, 0x90c0, 0x3845, 0x8003, 0x3c00, 0xa840, 0x30a4, 0x8004, 0x90c0, 0x3065 }, 16, 0x000a3d80, 1},
+ {{0x8002, 0x3a00, 0xa200, 0xda1c, 0xda9d, 0xdb1d, 0xdb9b, 0x3c00, 0xa800, 0x30c4, 0x8004, 0x90c0, 0x30e5, 0x8002, 0x6d55, 0x3400 }, 16, 0x000a3da0, 1},
+ {{0xa804, 0x6fcb, 0x3600, 0xa808, 0x745f, 0x67e5, 0x94c0, 0x9621, 0x9721, 0x94c0, 0x9633, 0x9733, 0x94c0, 0x9531, 0x9c23, 0x90c0 }, 16, 0x000a3dc0, 1},
+ {{0x90c0, 0x9731, 0x9f70, 0x3400, 0xa800, 0x7457, 0x9730, 0x94c0, 0x9c22, 0x9530, 0x5c58, 0x1a98, 0x6d54, 0x2d5c, 0x1998, 0xece8 }, 16, 0x000a3de0, 1},
+ {{0x3800, 0xa100, 0x7a61, 0xe9e8, 0xcc52, 0x1005, 0xa004, 0x3703, 0x2080, 0x8000, 0x9c44, 0x4191, 0x2c10, 0x2c90, 0x135a, 0x5299 }, 16, 0x000a3e00, 1},
+ {{0x98c8, 0x6c61, 0x609d, 0x535a, 0x5299, 0x2c61, 0x609d, 0x1489, 0xd818, 0x2c51, 0x4994, 0xd415, 0x94c0, 0x9531, 0x9c23, 0x90c0 }, 16, 0x000a3e20, 1},
+ {{0x90c0, 0x94c0, 0x9731, 0x7458, 0x9f70, 0xd818, 0x90c0, 0x90c0, 0x3a00, 0xa004, 0x7450, 0x0226, 0x28a0, 0x8009, 0x98c0, 0x3412 }, 16, 0x000a3e40, 1},
+ {{0x8208, 0x9620, 0x9720, 0x2618, 0x8108, 0x94c0, 0x9e20, 0x9f20, 0x3121, 0x2ad6, 0x8009, 0x0526, 0x28a0, 0x8009, 0x66e9, 0x2518 }, 16, 0x000a3e60, 1},
+ {{0x80d8, 0x98c0, 0x0f06, 0x357c, 0x8008, 0xc68f, 0x90c0, 0x2f0c, 0x8008, 0x5294, 0x351a, 0x8f00, 0x98c0, 0xdd28, 0x0424, 0x28a2 }, 16, 0x000a3e80, 1},
+ {{0x8009, 0x76fa, 0x6c1a, 0x6c7d, 0x9f7d, 0x377c, 0x0926, 0x28b8, 0x8009, 0x2769, 0x0a06, 0x357c, 0x8008, 0x8095, 0x96c0, 0x7b61 }, 16, 0x000a3ea0, 1},
+ {{0x9cb9, 0xea42, 0x94c0, 0x4c12, 0x9b46, 0x0826, 0x28b8, 0x8009, 0x0726, 0x28a0, 0x8009, 0x98c0, 0x7be1, 0xe841, 0x2b03, 0x8020 }, 16, 0x000a3ec0, 1},
+ {{0x98c0, 0xc84c, 0x0722, 0x28a0, 0x8009, 0x30fc, 0x0822, 0x28b8, 0x8009, 0x2103, 0x804a, 0x96c3, 0x3f20, 0x28ce, 0x8009, 0x96c3 }, 16, 0x000a3ee0, 1},
+ {{0x0f22, 0x28b8, 0x8009, 0x0c26, 0x28b8, 0x8009, 0x0806, 0x357c, 0x8008, 0x9fbc, 0xe842, 0x4f10, 0x0d26, 0x28b8, 0x8009, 0x0626 }, 16, 0x000a3f00, 1},
+ {{0x28a0, 0x8009, 0x3b61, 0xed41, 0x98d0, 0xcd4d, 0x0d22, 0x28b8, 0x8009, 0x30fd, 0x0622, 0x28a0, 0x8009, 0x90c0, 0x90c0, 0x96c3 }, 16, 0x000a3f20, 1},
+ {{0x3f20, 0x28ce, 0x8009, 0x96c3, 0x0f22, 0x28b8, 0x8009, 0x9f7c, 0x3124, 0x3f58, 0x800a, 0x90c0, 0x0326, 0x28a0, 0x8009, 0x3413 }, 16, 0x000a3f40, 1},
+ {{0x8208, 0x2dff, 0x9f15, 0x3400, 0xa800, 0x7450, 0x6460, 0xc569, 0x9f7d, 0x0426, 0x28a0, 0x8009, 0x2669, 0x0906, 0x357c, 0x8008 }, 16, 0x000a3f60, 1},
+ {{0x8419, 0xe948, 0x5691, 0x3d1d, 0x8020, 0x66e9, 0x90c0, 0x94c7, 0x844e, 0xe966, 0x92c3, 0x4011, 0x0626, 0x28a0, 0x8009, 0x3b41 }, 16, 0x000a3f80, 1},
+ {{0x3b20, 0x2ad6, 0x8009, 0x0622, 0x28a0, 0x8009, 0x0926, 0x28b4, 0x8009, 0x90c0, 0x9099, 0x0e26, 0x28b4, 0x8009, 0x90c0, 0xee41 }, 16, 0x000a3fa0, 1},
+ {{0x98c0, 0xeb8e, 0x0e22, 0x28b4, 0x8009, 0x90c0, 0x96c3, 0x3521, 0x28ce, 0x8009, 0x96c3, 0x0522, 0x28b4, 0x8009, 0xc561, 0x90c0 }, 16, 0x000a3fc0, 1},
+ {{0x9f7c, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x98c0, 0x77d0, 0x6f10, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20 }, 16, 0x000a3fe0, 1},
+ {{0x98c0, 0xefe9, 0x3224, 0x3e50, 0x800a, 0x96c0, 0xe750, 0x2000, 0x8082, 0x3224, 0x3e50, 0x800a, 0x107c, 0x9fd7, 0x3c00, 0xa002 }, 16, 0x000a4000, 1},
+ {{0x147c, 0x9fd7, 0x90c0, 0x3ece, 0x8208, 0x3800, 0xb000, 0x6669, 0x746e, 0xf441, 0x2718, 0x8228, 0x3324, 0x3e50, 0x800a, 0x3600 }, 16, 0x000a4020, 1},
+ {{0xa004, 0x3f1d, 0x80ff, 0x3224, 0x3e50, 0x800a, 0x3400, 0xa800, 0x746d, 0x9ac0, 0x67ea, 0xe9ef, 0x3ec8, 0x3800, 0xbfff, 0x2718 }, 16, 0x000a4040, 1},
+ {{0x81dc, 0x3a40, 0xa000, 0x3ac8, 0x3c10, 0xbfff, 0xf642, 0x3420, 0xa000, 0xf543, 0x3f00, 0x200e, 0x8008, 0x3800, 0x200c, 0x8008 }, 16, 0x000a4060, 1},
+ {{0xefa9, 0x2518, 0x8166, 0x98c0, 0xe8a9, 0x3d00, 0x200a, 0x8008, 0x2518, 0x8158, 0x98c0, 0xeda9, 0x3c00, 0x2008, 0x8008, 0x2518 }, 16, 0x000a4080, 1},
+ {{0x814a, 0xeca9, 0x2518, 0x8144, 0x3c00, 0x2004, 0x8008, 0x3800, 0x201a, 0x8008, 0xeca9, 0x2518, 0x8132, 0x98c0, 0xe8a9, 0x3c00 }, 16, 0x000a40a0, 1},
+ {{0x2018, 0x8008, 0x2518, 0x8116, 0x98c0, 0xeca9, 0x38e8, 0x2418, 0xbfff, 0x2518, 0x80fc, 0x3c00, 0x2016, 0x8008, 0x3d00, 0x2014 }, 16, 0x000a40c0, 1},
+ {{0x8008, 0x98c0, 0xeca9, 0x3bc8, 0x3c14, 0xbfff, 0x80db, 0x98c0, 0xeda9, 0x3b00, 0x2012, 0x8008, 0x80bb, 0x98c0, 0xeba9, 0x3c00 }, 16, 0x000a40e0, 1},
+ {{0x2010, 0x8008, 0x80a7, 0x98c0, 0xeca9, 0x3f00, 0x2006, 0x8008, 0x808f, 0x98c0, 0xefa9, 0x3b00, 0x2002, 0x8008, 0x807b, 0x98c0 }, 16, 0x000a4100, 1},
+ {{0xeba9, 0x3d00, 0x2000, 0x8008, 0x8063, 0x98c0, 0xeda9, 0x3be8, 0x2400, 0xbfff, 0x84b5, 0x1193, 0x3820, 0x28c0, 0x8009, 0x96c0 }, 16, 0x000a4120, 1},
+ {{0x33eb, 0x9fff, 0xefe9, 0x98c0, 0xd1a0, 0x0122, 0x28c0, 0x8009, 0x842b, 0x33e4, 0x3a92, 0x8001, 0x98c0, 0x0b26, 0x28c0, 0x8009 }, 16, 0x000a4140, 1},
+ {{0xe9ef, 0x90c0, 0xebf1, 0x3be8, 0x2400, 0xbfff, 0x90c0, 0x92c2, 0x5293, 0x96c2, 0x0222, 0x28c0, 0x8009, 0x0426, 0x28c0, 0x8009 }, 16, 0x000a4160, 1},
+ {{0x3044, 0x21ea, 0x800a, 0x38ca, 0x8410, 0x3044, 0x21ea, 0x800a, 0x0227, 0x28c2, 0x8009, 0x1296, 0x3144, 0x21ea, 0x800a, 0x1192 }, 16, 0x000a4180, 1},
+ {{0x3044, 0x21ea, 0x800a, 0x32ca, 0x8410, 0x1292, 0x3144, 0x21ea, 0x800a, 0x3bc8, 0x3c14, 0xbfff, 0x90c0, 0x1393, 0x3044, 0x21ea }, 16, 0x000a41a0, 1},
+ {{0x800a, 0x36ca, 0x8410, 0x1293, 0x3144, 0x21ea, 0x800a, 0x1290, 0x3044, 0x21ea, 0x800a, 0x34ca, 0x8410, 0x38e8, 0x2418, 0xbfff }, 16, 0x000a41c0, 1},
+ {{0x3044, 0x21ea, 0x800a, 0x5290, 0x52d1, 0x377a, 0x757e, 0x96c0, 0x3ccc, 0x8208, 0xefe9, 0x35ec, 0x346c, 0x3224, 0x3e50, 0x800a }, 16, 0x000a41e0, 1},
+ {{0x3400, 0xa004, 0x6e3d, 0x3600, 0xb000, 0x6760, 0x76fc, 0x3d1c, 0x80ff, 0x346c, 0x366c, 0x3224, 0x3e50, 0x800a, 0x6f15, 0x9ac0 }, 16, 0x000a4200, 1},
+ {{0x7be1, 0xe9ef, 0x3ac8, 0x3c10, 0xbfff, 0x27ea, 0xe942, 0x2dff, 0x9e47, 0x3660, 0xa000, 0xf6c2, 0xf5c3, 0x3600, 0xa008, 0x777e }, 16, 0x000a4220, 1},
+ {{0x6761, 0x3c16, 0x8082, 0x747e, 0x3400, 0xa040, 0x6d22, 0x36fa, 0x3044, 0x2262, 0x800a, 0x3400, 0xa040, 0x6366, 0x36e1, 0x3f7e }, 16, 0x000a4240, 1},
+ {{0x8000, 0x36fe, 0xf4c1, 0x6f15, 0x77fe, 0x3ece, 0x8208, 0x3224, 0x3e50, 0x800a, 0x746e, 0x67e0, 0x3f1e, 0x80ff, 0x3224, 0x3e50 }, 16, 0x000a4260, 1},
+ {{0x800a, 0x746e, 0x2d90, 0xe770, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f70, 0x0322, 0x28c4, 0x8009, 0x90c0, 0x90c0 }, 16, 0x000a4280, 1},
+ {{0x3224, 0x3e50, 0x800a, 0x3800, 0xa004, 0x77d0, 0x2000, 0x8092, 0x3224, 0x3e50, 0x800a, 0x3400, 0xa800, 0x7457, 0x30e1, 0x3f6e }, 16, 0x000a42a0, 1},
+ {{0x8000, 0x74f8, 0x3400, 0xa044, 0x6f27, 0x3600, 0xa800, 0x3cc9, 0x8208, 0x3224, 0x3e50, 0x800a, 0x7469, 0x3400, 0xa800, 0x757e }, 16, 0x000a42c0, 1},
+ {{0x351b, 0x80ff, 0x3224, 0x3e50, 0x800a, 0x746b, 0x94c0, 0x6d90, 0x9f70, 0x0322, 0x28c4, 0x8009, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a42e0, 1},
+ {{0x98c0, 0x6f10, 0x77d1, 0x9620, 0x9720, 0x96c0, 0x6c90, 0x9e20, 0x9f20, 0x94c0, 0xeee8, 0xe750, 0x32e4, 0x3a14, 0x8001, 0xe838 }, 16, 0x000a4300, 1},
+ {{0x9cc0, 0x6469, 0x6e90, 0xce4b, 0x0806, 0x3c00, 0x8008, 0x96c0, 0xcb43, 0x2518, 0x8aa2, 0x96c0, 0xe848, 0x057c, 0x9ff0, 0x1c90 }, 16, 0x000a4320, 1},
+ {{0x0e26, 0x28c4, 0x8009, 0x96c0, 0xc181, 0x27e8, 0x9ff0, 0x9c62, 0x94c0, 0xee1b, 0xefeb, 0x9ac0, 0x6469, 0xebef, 0x0425, 0x32a7 }, 16, 0x000a4340, 1},
+ {{0x8009, 0x98c7, 0x2718, 0x8aa0, 0x90c0, 0x6c10, 0x96c0, 0xd620, 0xcf44, 0xcc83, 0x2718, 0x82ba, 0x96c0, 0xef61, 0x2700, 0x80c8 }, 16, 0x000a4360, 1},
+ {{0x98c0, 0xef8c, 0x0722, 0x28a8, 0x8009, 0x96c0, 0xeffe, 0x2518, 0x827c, 0x98c0, 0x3820, 0x2890, 0x8009, 0xcc82, 0x98c0, 0x0b26 }, 16, 0x000a4380, 1},
+ {{0x28a4, 0x8009, 0xce82, 0x98c0, 0xef18, 0x3a20, 0x327d, 0x8009, 0x1997, 0xc884, 0x3f20, 0x327d, 0x8009, 0x96c0, 0x9961, 0x157c }, 16, 0x000a43a0, 1},
+ {{0x9ff0, 0x9ac0, 0x6f90, 0x0926, 0x28a4, 0x8009, 0xc282, 0x147c, 0x9ff0, 0x98c0, 0xef19, 0x3a20, 0x3280, 0x8009, 0x94c0, 0xe941 }, 16, 0x000a43c0, 1},
+ {{0x949f, 0x98c0, 0xe8a9, 0x0922, 0x28a4, 0x8009, 0x96c0, 0xeeea, 0x2718, 0x823a, 0x94c0, 0x90ba, 0xea62, 0x98c0, 0x0325, 0x327d }, 16, 0x000a43e0, 1},
+ {{0x8009, 0xee61, 0x96c0, 0x7dd8, 0x95ba, 0x94be, 0x9ac0, 0xdb15, 0x7e48, 0x0221, 0x32a7, 0x8009, 0x98c0, 0xdf1b, 0x0722, 0x28a4 }, 16, 0x000a4400, 1},
+ {{0x8009, 0xdf1c, 0x98c0, 0xdf18, 0x3044, 0x2626, 0x800a, 0x0622, 0x28bc, 0x8009, 0x98c0, 0x3920, 0x327d, 0x8009, 0xc684, 0x90c0 }, 16, 0x000a4420, 1},
+ {{0xe91b, 0x96c0, 0x6e90, 0xeb41, 0x9599, 0x98c0, 0xecab, 0x0b22, 0x28a4, 0x8009, 0x2718, 0x81d2, 0x3c20, 0x327e, 0x8009, 0x0425 }, 16, 0x000a4440, 1},
+ {{0x327d, 0x8009, 0x9ac0, 0x7e48, 0x92bc, 0x0522, 0x28a4, 0x8009, 0x98c0, 0xdd1c, 0x0621, 0x32a7, 0x8009, 0x36fa, 0x0220, 0x28c8 }, 16, 0x000a4460, 1},
+ {{0x8009, 0x9ac0, 0x3615, 0x8100, 0x7475, 0x2700, 0x80e3, 0x2718, 0x8198, 0x077c, 0x9fff, 0x3224, 0x3ff0, 0x800a, 0x0926, 0x28bc }, 16, 0x000a4480, 1},
+ {{0x8009, 0x9ac0, 0x6d10, 0x0705, 0x3c4a, 0x8008, 0xc6ff, 0x27e9, 0x0221, 0x32a7, 0x8009, 0x2418, 0x8170, 0x0622, 0x28a8, 0x8009 }, 16, 0x000a44a0, 1},
+ {{0x0427, 0x28c8, 0x8009, 0x98c0, 0xf442, 0x3461, 0x2055, 0x8008, 0x32e4, 0x37e6, 0x8001, 0xf441, 0x3144, 0x2626, 0x800a, 0x98c0 }, 16, 0x000a44c0, 1},
+ {{0x0c26, 0x28a4, 0x8009, 0xcd80, 0x157c, 0x9ff0, 0x98c0, 0xea1c, 0x0226, 0x28bc, 0x8009, 0x9cc0, 0x34cf, 0x8208, 0xec41, 0x3518 }, 16, 0x000a44e0, 1},
+ {{0x80ff, 0x959a, 0x9ac0, 0xd7c0, 0xeeac, 0x0c22, 0x28a4, 0x8009, 0x9ac0, 0x2718, 0x8116, 0x90c0, 0x34ce, 0x8210, 0x98c0, 0xd7c6 }, 16, 0x000a4500, 1},
+ {{0x34cd, 0x8218, 0xc942, 0x94c0, 0xc845, 0xcc47, 0x0627, 0x28c8, 0x8009, 0x9ac0, 0x3ccc, 0x8208, 0xec18, 0x3d1b, 0x80ff, 0x9ac0 }, 16, 0x000a4520, 1},
+ {{0x6661, 0xed3c, 0x3f20, 0x327e, 0x8009, 0x9ac0, 0x6fcc, 0xcd48, 0x0525, 0x327d, 0x8009, 0x96c0, 0x7678, 0x7ec8, 0x93bf, 0x2e37 }, 16, 0x000a4540, 1},
+ {{0xdd9d, 0x36fc, 0x347b, 0x0320, 0x28cc, 0x8009, 0x3c15, 0x8081, 0x37fd, 0x3401, 0x2000, 0x8008, 0x3067, 0x7476, 0x8017, 0x2600 }, 16, 0x000a4560, 1},
+ {{0x80e5, 0x3224, 0x3ff0, 0x800a, 0x067c, 0x9fff, 0x3144, 0x25f0, 0x800a, 0x327a, 0x3001, 0x3000, 0x8008, 0x8043, 0x3178, 0x75d6 }, 16, 0x000a4580, 1},
+ {{0x94c0, 0xd5c2, 0x803d, 0x9cc0, 0x2400, 0x80e4, 0x6e90, 0x71f8, 0x7476, 0xc942, 0x8413, 0x3224, 0x3ff0, 0x800a, 0x047c, 0x9fff }, 16, 0x000a45a0, 1},
+ {{0x3144, 0x25f0, 0x800a, 0x3224, 0x3ff0, 0x800a, 0x98c0, 0x7476, 0xc942, 0x057c, 0x9fff, 0x3144, 0x25f0, 0x800a, 0x98c0, 0x2500 }, 16, 0x000a45c0, 1},
+ {{0x80e2, 0x7476, 0xc942, 0x3224, 0x3ff0, 0x800a, 0x057c, 0x9fff, 0x2c10, 0xc7ff, 0x0021, 0x32a7, 0x8009, 0x3044, 0x2626, 0x800a }, 16, 0x000a45e0, 1},
+ {{0x0722, 0x28a8, 0x8009, 0x0005, 0x3c4a, 0x8008, 0x6469, 0x90c0, 0x98c3, 0x3041, 0x3fe6, 0x8008, 0xf442, 0x96c3, 0x32e4, 0x37e6 }, 16, 0x000a4600, 1},
+ {{0x8001, 0x92c3, 0xf041, 0x2c10, 0x3144, 0x2e02, 0x800a, 0x98c0, 0x0025, 0x32a8, 0x8009, 0xcf85, 0x94c0, 0xd420, 0xc940, 0x9ac0 }, 16, 0x000a4620, 1},
+ {{0x157c, 0x9ff0, 0x90c0, 0x2718, 0x84ec, 0x96c0, 0xe961, 0x2400, 0x87d0, 0x98c0, 0xe98f, 0x0422, 0x28a8, 0x8009, 0x96c0, 0xe9fe }, 16, 0x000a4640, 1},
+ {{0x2518, 0x84a6, 0x9cc0, 0x6d10, 0x6c90, 0x3c20, 0x2878, 0x8009, 0xca82, 0x98c0, 0x0e26, 0x28a4, 0x8009, 0xc882, 0x98c0, 0xe91c }, 16, 0x000a4660, 1},
+ {{0x0d26, 0x28a4, 0x8009, 0x1c91, 0x0926, 0x28a4, 0x8009, 0x0627, 0x28c8, 0x8009, 0x96c0, 0x9c61, 0x147c, 0x9ff0, 0x9ac0, 0x6d10 }, 16, 0x000a4680, 1},
+ {{0x3b20, 0x327d, 0x8009, 0xcc84, 0xc082, 0xeb1e, 0x94c0, 0xee41, 0x949b, 0x98c0, 0xecae, 0x0e22, 0x28a4, 0x8009, 0x2718, 0x8466 }, 16, 0x000a46a0, 1},
+ {{0x3b20, 0x3280, 0x8009, 0x0525, 0x327d, 0x8009, 0x96c0, 0x7ed8, 0xefeb, 0x97bb, 0x94c0, 0xeb62, 0xef61, 0x94c0, 0x94bb, 0x96bf }, 16, 0x000a46c0, 1},
+ {{0x9ac0, 0xd994, 0x7f48, 0x0021, 0x32a8, 0x8009, 0x98c0, 0xdd9d, 0x0222, 0x28a4, 0x8009, 0xdd9e, 0x98c0, 0xdd9f, 0x3044, 0x2b22 }, 16, 0x000a46e0, 1},
+ {{0x800a, 0x0322, 0x28bc, 0x8009, 0x98c0, 0x3e20, 0x327d, 0x8009, 0xc384, 0x107c, 0x9ff0, 0x98c0, 0xee19, 0x0220, 0x28ca, 0x8009 }, 16, 0x000a4700, 1},
+ {{0x96c0, 0x6c10, 0xe941, 0x909e, 0x98c0, 0xeaa9, 0x0922, 0x28a4, 0x8009, 0x2718, 0x83f0, 0x3f20, 0x327e, 0x8009, 0x0625, 0x327d }, 16, 0x000a4720, 1},
+ {{0x8009, 0x9ac0, 0x7f48, 0x95bf, 0x0321, 0x32a8, 0x8009, 0x98c0, 0xde9e, 0x0022, 0x28a4, 0x8009, 0x3044, 0x2b22, 0x800a, 0x0520 }, 16, 0x000a4740, 1},
+ {{0x28c8, 0x8009, 0x9ac0, 0x6f10, 0x3e20, 0x327d, 0x8009, 0xc982, 0x177c, 0x9ff0, 0x98c0, 0xee1d, 0x3a20, 0x327e, 0x8009, 0x94c0 }, 16, 0x000a4760, 1},
+ {{0xed41, 0x979e, 0x98c0, 0xe9ad, 0x0d22, 0x28a4, 0x8009, 0x96c0, 0x92ba, 0x2718, 0x8394, 0x0e27, 0x28ca, 0x8009, 0x0525, 0x327d }, 16, 0x000a4780, 1},
+ {{0x8009, 0x9ac0, 0x7ec8, 0x0426, 0x28bc, 0x8009, 0xeefc, 0x9ac0, 0xdd1d, 0x3001, 0x2000, 0x8008, 0xee1b, 0x3278, 0x0622, 0x28a4 }, 16, 0x000a47a0, 1},
+ {{0x8009, 0x844b, 0x3501, 0x3000, 0x8008, 0x327d, 0x0727, 0x28c8, 0x8009, 0x803b, 0x3617, 0x8100, 0x8035, 0x2f90, 0x4216, 0x0327 }, 16, 0x000a47c0, 1},
+ {{0x28ca, 0x8009, 0x39c1, 0x0527, 0x28c8, 0x8009, 0x367b, 0x0320, 0x28ca, 0x8009, 0x72fc, 0x2518, 0x832c, 0x0f21, 0x32a8, 0x8009 }, 16, 0x000a47e0, 1},
+ {{0x3044, 0x2b22, 0x800a, 0x0722, 0x28a4, 0x8009, 0x98c0, 0xc286, 0x3044, 0x2b22, 0x800a, 0x0221, 0x32a8, 0x8009, 0x9ac0, 0x2000 }, 16, 0x000a4800, 1},
+ {{0x80e3, 0x90c0, 0x3616, 0x8100, 0x840f, 0x3344, 0x22a0, 0x800a, 0x3144, 0x2840, 0x800a, 0x3244, 0x22a0, 0x800a, 0x2000, 0x80e2 }, 16, 0x000a4820, 1},
+ {{0x2f90, 0xc0ff, 0x0721, 0x32a8, 0x8009, 0x3044, 0x2b22, 0x800a, 0x0022, 0x28a8, 0x8009, 0x98c0, 0x3a20, 0x327d, 0x8009, 0xeeeb }, 16, 0x000a4840, 1},
+ {{0x0d26, 0x28a4, 0x8009, 0x147c, 0x9ff0, 0x98c0, 0xea1d, 0x0527, 0x28ca, 0x8009, 0x96c0, 0x7ec1, 0xed41, 0x949a, 0x98c0, 0xe8ad }, 16, 0x000a4860, 1},
+ {{0x0d22, 0x28a4, 0x8009, 0x2718, 0x829c, 0x26ea, 0x3a20, 0x327e, 0x8009, 0x0325, 0x327d, 0x8009, 0x9ac0, 0x7dc8, 0x90ba, 0x0d26 }, 16, 0x000a4880, 1},
+ {{0x28bc, 0x8009, 0x94c0, 0xdc1b, 0x841a, 0x0020, 0x28cc, 0x8009, 0x9f45, 0x90c0, 0x90c0, 0x94d0, 0x76f9, 0x93a3, 0x6c8d, 0x9ac0 }, 16, 0x000a48a0, 1},
+ {{0x7778, 0x0426, 0x28bc, 0x8009, 0xcc41, 0x9ac0, 0x391d, 0x80ff, 0x90c0, 0x38cb, 0x8208, 0x9cc0, 0x38cd, 0x8210, 0xd5c5, 0x38c8 }, 16, 0x000a48c0, 1},
+ {{0x8218, 0xecf8, 0x9ac0, 0xd5c5, 0xcf40, 0x0027, 0x28c8, 0x8009, 0x9ac0, 0x30cd, 0x8208, 0xcb43, 0x311a, 0x80ff, 0x66e1, 0x2d49 }, 16, 0x000a48e0, 1},
+ {{0xeb1f, 0xec3b, 0xcc4f, 0x76ff, 0x6d09, 0x757a, 0x3c12, 0x8091, 0x77fa, 0x3367, 0x3701, 0x3000, 0x8008, 0x8013, 0x3244, 0x22a0 }, 16, 0x000a4900, 1},
+ {{0x800a, 0x2000, 0x80e5, 0x3144, 0x2aec, 0x800a, 0x36d0, 0x6f10, 0xd6c4, 0x72ff, 0x8413, 0x3244, 0x22a0, 0x800a, 0x2000, 0x80e4 }, 16, 0x000a4920, 1},
+ {{0x3144, 0x2aec, 0x800a, 0x2469, 0x0620, 0x28ca, 0x8009, 0x2518, 0x8196, 0x3cc8, 0x3804, 0xbfff, 0x3fc8, 0x3c10, 0xbfff, 0x39c8 }, 16, 0x000a4940, 1},
+ {{0x3c12, 0xbfff, 0x38c8, 0x3c14, 0xbfff, 0x3ac8, 0x3c16, 0xbfff, 0x3be8, 0x2418, 0xbfff, 0x98c0, 0x30ea, 0x241a, 0xbfff, 0x90c0 }, 16, 0x000a4960, 1},
+ {{0x0126, 0x28bc, 0x8009, 0x3701, 0x2000, 0x8008, 0x33f9, 0x3501, 0x201a, 0x8008, 0x2518, 0x8128, 0x9ac0, 0x70fd, 0xc551, 0x3402 }, 16, 0x000a4980, 1},
+ {{0x200e, 0x8008, 0x96c0, 0x50d6, 0x2518, 0x8118, 0x34a0, 0xa000, 0xecad, 0x2518, 0x80fa, 0x3402, 0x200c, 0x8008, 0x3302, 0x200a }, 16, 0x000a49a0, 1},
+ {{0x8008, 0x34a0, 0xa000, 0xecad, 0x2518, 0x80e4, 0x34a0, 0xa000, 0xebad, 0x2518, 0x80da, 0x3302, 0x2008, 0x8008, 0x3602, 0x2004 }, 16, 0x000a49c0, 1},
+ {{0x8008, 0x34a0, 0xa000, 0xebad, 0x80c5, 0x34a0, 0xa000, 0xeead, 0x80bd, 0x98c0, 0x3602, 0x2002, 0x8008, 0xc157, 0x90c0, 0x34a0 }, 16, 0x000a49e0, 1},
+ {{0xa000, 0xeead, 0x80a9, 0x36a0, 0xa000, 0xe9ad, 0xc355, 0x809f, 0x3aa0, 0xa000, 0xebad, 0x3102, 0x2018, 0x8008, 0x8085, 0x34a0 }, 16, 0x000a4a00, 1},
+ {{0xa000, 0xe9ad, 0x8075, 0x3102, 0x2016, 0x8008, 0x3302, 0x2014, 0x8008, 0x34a0, 0xa000, 0xe9ad, 0x8059, 0x3aa0, 0xa000, 0xebad }, 16, 0x000a4a20, 1},
+ {{0x3602, 0x2012, 0x8008, 0x8043, 0x3aa0, 0xa000, 0xeead, 0x3302, 0x2010, 0x8008, 0x802d, 0x3aa0, 0xa000, 0xebad, 0x3602, 0x2006 }, 16, 0x000a4a40, 1},
+ {{0x8008, 0x8017, 0x38a0, 0xa000, 0x31fc, 0x9fff, 0xeead, 0x843f, 0x0494, 0x3144, 0x2ac0, 0x800a, 0x0017, 0x3144, 0x2ac0, 0x800a }, 16, 0x000a4a60, 1},
+ {{0x0011, 0x3144, 0x2ac0, 0x800a, 0x0010, 0x3144, 0x2ac0, 0x800a, 0x0012, 0x3144, 0x2ac0, 0x800a, 0x0013, 0x3144, 0x2ac0, 0x800a }, 16, 0x000a4a80, 1},
+ {{0x3a80, 0xa000, 0x4010, 0x3144, 0x2ac0, 0x800a, 0xd7c1, 0xc657, 0x3044, 0x2ac0, 0x800a, 0x3480, 0xa000, 0x4016, 0x51d6, 0x4115 }, 16, 0x000a4aa0, 1},
+ {{0x98c0, 0x0427, 0x28ca, 0x8009, 0xee42, 0x9ac0, 0x7a41, 0x0227, 0x28c8, 0x8009, 0xed42, 0x36fc, 0x0420, 0x28ca, 0x8009, 0x717d }, 16, 0x000a4ac0, 1},
+ {{0x2dff, 0x9ea1, 0x3244, 0x22a0, 0x800a, 0x6c10, 0x2d10, 0xc4ff, 0x0221, 0x32a8, 0x8009, 0x3044, 0x2b22, 0x800a, 0x0422, 0x28a8 }, 16, 0x000a4ae0, 1},
+ {{0x8009, 0x0405, 0x3c4a, 0x8008, 0x6669, 0x90c0, 0x98c3, 0xf042, 0x3041, 0x3ff8, 0x8008, 0x96c3, 0x32e4, 0x37e6, 0x8001, 0x92c3 }, 16, 0x000a4b00, 1},
+ {{0xf041, 0x2c10, 0x3144, 0x2e02, 0x800a, 0x98c0, 0x3415, 0x8081, 0x6d90, 0xc281, 0x94c0, 0x6c90, 0x844d, 0x98c0, 0xc684, 0x3820 }, 16, 0x000a4b20, 1},
+ {{0x327d, 0x8009, 0x98c0, 0xf641, 0x0221, 0x32a7, 0x8009, 0x0322, 0x28a4, 0x8009, 0x0320, 0x28c8, 0x8009, 0x0301, 0x3c4a, 0x8008 }, 16, 0x000a4b40, 1},
+ {{0x32e4, 0x3c8a, 0x8001, 0x0322, 0x28bc, 0x8009, 0x96c0, 0x6c10, 0x2200, 0x80c8, 0x3044, 0x2e02, 0x800a, 0x0222, 0x28a8, 0x8009 }, 16, 0x000a4b60, 1},
+ {{0x96c0, 0x3415, 0x8091, 0xc381, 0x94c6, 0x844f, 0x6f10, 0x9ac0, 0x6c90, 0xc784, 0x3820, 0x327d, 0x8009, 0x98c0, 0xf741, 0x0321 }, 16, 0x000a4b80, 1},
+ {{0x32a8, 0x8009, 0x0622, 0x28a4, 0x8009, 0x0620, 0x28c8, 0x8009, 0x0601, 0x3c4a, 0x8008, 0x32e4, 0x3c8a, 0x8001, 0x0622, 0x28bc }, 16, 0x000a4ba0, 1},
+ {{0x8009, 0x96c0, 0x6c10, 0x2300, 0x80c8, 0x3044, 0x2e02, 0x800a, 0x0322, 0x28a8, 0x8009, 0x3415, 0x8083, 0x8415, 0x3224, 0x3e50 }, 16, 0x000a4bc0, 1},
+ {{0x800a, 0x2000, 0x8084, 0x2c10, 0x3144, 0x2e02, 0x800a, 0x96c0, 0x3415, 0x8085, 0x6c90, 0x841b, 0x2000, 0x8086, 0x3224, 0x3e50 }, 16, 0x000a4be0, 1},
+ {{0x800a, 0x0101, 0x3c4a, 0x8008, 0x2c10, 0x3144, 0x2e02, 0x800a, 0x96c0, 0x3415, 0x8087, 0xc281, 0x841b, 0x2000, 0x8088, 0x3224 }, 16, 0x000a4c00, 1},
+ {{0x3e50, 0x800a, 0x0201, 0x3c4a, 0x8008, 0x2c10, 0x3144, 0x2e02, 0x800a, 0x6669, 0x2718, 0x81cc, 0x6469, 0x2718, 0x81c6, 0xd2aa }, 16, 0x000a4c20, 1},
+ {{0x2518, 0x812a, 0x94c0, 0xd2ad, 0xc28a, 0x2518, 0x811c, 0xd2a5, 0x2518, 0x8100, 0x96c0, 0x3415, 0x803b, 0xc481, 0x80c5, 0x3415 }, 16, 0x000a4c40, 1},
+ {{0x807f, 0x8077, 0xd2a8, 0x8073, 0xd2bb, 0x90c0, 0x96c2, 0x3341, 0x3dc0, 0x8008, 0x2418, 0x812c, 0x96c2, 0x0322, 0x28b0, 0x8009 }, 16, 0x000a4c60, 1},
+ {{0x66e9, 0x2518, 0x811e, 0x3615, 0x807f, 0x2518, 0x8116, 0x0225, 0x32a9, 0x8009, 0x96c0, 0x6569, 0x27e8, 0x9ff0, 0x90c0, 0x92c2 }, 16, 0x000a4c80, 1},
+ {{0x959e, 0x96c2, 0x0126, 0x28c4, 0x8009, 0x98c6, 0x0525, 0x32ac, 0x8009, 0x78c1, 0x9ac6, 0x66e9, 0x0122, 0x28c4, 0x8009, 0xc181 }, 16, 0x000a4ca0, 1},
+ {{0x80e1, 0x0906, 0x3c00, 0x8008, 0x90c0, 0xe944, 0x5f91, 0x90c0, 0x9f63, 0x3144, 0x2da0, 0x800a, 0x0526, 0x28c4, 0x8009, 0x26ea }, 16, 0x000a4cc0, 1},
+ {{0x0225, 0x32ac, 0x8009, 0x84bb, 0x6569, 0x90c0, 0x98c3, 0x0f06, 0x3c00, 0x8008, 0xc183, 0x96c3, 0x3860, 0x2088, 0x8008, 0x92c3 }, 16, 0x000a4ce0, 1},
+ {{0xef44, 0x92c3, 0x5b97, 0x90c0, 0x92c3, 0x9b63, 0x0426, 0x28c4, 0x8009, 0x3a61, 0x3044, 0x2da0, 0x800a, 0x0422, 0x28c4, 0x8009 }, 16, 0x000a4d00, 1},
+ {{0x0125, 0x32ac, 0x8009, 0x9ac0, 0x64e9, 0x0421, 0x32a9, 0x8009, 0xc181, 0x96c0, 0x806f, 0x27e8, 0x9ff0, 0x0f06, 0x3c00, 0x8008 }, 16, 0x000a4d20, 1},
+ {{0x90c0, 0xef44, 0x5e97, 0x90c0, 0x9e63, 0x3144, 0x2da0, 0x800a, 0x959e, 0x0426, 0x28c4, 0x8009, 0x3a41, 0x3044, 0x2da0, 0x800a }, 16, 0x000a4d40, 1},
+ {{0x0422, 0x28c4, 0x8009, 0x027c, 0x9ff0, 0x6d10, 0x9286, 0x0325, 0x32ac, 0x8009, 0x65e9, 0x90c0, 0x98c3, 0x0c06, 0x3c00, 0x8008 }, 16, 0x000a4d60, 1},
+ {{0xc181, 0x94c3, 0x27e8, 0x9ff0, 0x92c3, 0xec44, 0x92c3, 0x5f94, 0x90c0, 0x92c3, 0x9f63, 0x6d10, 0x929e, 0x0221, 0x32a9, 0x8009 }, 16, 0x000a4d80, 1},
+ {{0x3be1, 0x0026, 0x28c4, 0x8009, 0x33f0, 0x3860, 0x201b, 0x8008, 0x800f, 0x33e4, 0x37da, 0x8001, 0xc58a, 0x057c, 0x9ff0, 0x177c }, 16, 0x000a4da0, 1},
+ {{0x9ff0, 0xd3aa, 0x843d, 0x98c0, 0xc681, 0x3144, 0x2e00, 0x800a, 0x0726, 0x28a8, 0x8009, 0x67ea, 0x8429, 0x67ed, 0x98c6, 0x0722 }, 16, 0x000a4dc0, 1},
+ {{0x28a8, 0x8009, 0x6c90, 0x98c2, 0xc2ff, 0x0121, 0x32a8, 0x8009, 0x96c2, 0x0121, 0x32a7, 0x8009, 0x96c2, 0x0222, 0x28a8, 0x8009 }, 16, 0x000a4de0, 1},
+ {{0x7456, 0xe770, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a4e00, 1},
+ {{0x94c0, 0x9620, 0x9720, 0x98c0, 0x0626, 0x28a0, 0x8009, 0x9f20, 0x2769, 0xe750, 0x2518, 0x80de, 0x98c0, 0x0a06, 0x357c, 0x8008 }, 16, 0x000a4e20, 1},
+ {{0xc68f, 0x90c0, 0x2a0d, 0x8008, 0x5295, 0x351a, 0x8f00, 0x98c0, 0xdd28, 0x0424, 0x28a2, 0x8009, 0x74fa, 0x6c06, 0x6c7d, 0x9f7d }, 16, 0x000a4e40, 1},
+ {{0x34fc, 0x0d26, 0x28b8, 0x8009, 0x24e9, 0x38e1, 0x0c06, 0x357c, 0x8008, 0x8099, 0x94c0, 0x97bd, 0xec42, 0x94c0, 0x4714, 0x9b41 }, 16, 0x000a4e60, 1},
+ {{0x0a26, 0x28b8, 0x8009, 0x0726, 0x28a0, 0x8009, 0x98c0, 0x7be1, 0xea41, 0x2b03, 0x8026, 0x98c0, 0x3321, 0x2ad6, 0x8009, 0xca4d }, 16, 0x000a4e80, 1},
+ {{0x31fd, 0x0722, 0x28a0, 0x8009, 0x0a22, 0x28b8, 0x8009, 0x2103, 0x804a, 0x96c3, 0x3c20, 0x28ce, 0x8009, 0x96c3, 0x0c22, 0x28b8 }, 16, 0x000a4ea0, 1},
+ {{0x8009, 0x0a26, 0x28b8, 0x8009, 0x0806, 0x357c, 0x8008, 0x95ba, 0xe842, 0x4510, 0x0f26, 0x28b8, 0x8009, 0x0126, 0x28a0, 0x8009 }, 16, 0x000a4ec0, 1},
+ {{0x38e1, 0xef41, 0x98d0, 0xcf4e, 0x0f22, 0x28b8, 0x8009, 0x31fe, 0x0122, 0x28a0, 0x8009, 0x90c0, 0x90c0, 0x96c3, 0x3c20, 0x28ce }, 16, 0x000a4ee0, 1},
+ {{0x8009, 0x96c3, 0x0c22, 0x28b8, 0x8009, 0x9f7c, 0x3144, 0x2f14, 0x800a, 0x90c0, 0x33e4, 0x3a20, 0x8001, 0x0225, 0x32ab, 0x8009 }, 16, 0x000a4f00, 1},
+ {{0x2569, 0x3621, 0x328d, 0x8009, 0x841d, 0x98c0, 0x3061, 0x2083, 0x8008, 0xf642, 0x32e4, 0x37e6, 0x8001, 0xf041, 0xc781, 0x0721 }, 16, 0x000a4f20, 1},
+ {{0x32ab, 0x8009, 0x2100, 0x8200, 0x3244, 0x2300, 0x800a, 0x3820, 0x2ad6, 0x8009, 0x96c0, 0xd021, 0x27e9, 0x9ff0, 0x2718, 0x8128 }, 16, 0x000a4f40, 1},
+ {{0x98c0, 0xf941, 0x3920, 0x2568, 0x8009, 0x32e4, 0x3816, 0x8001, 0x3820, 0x2ad6, 0x8009, 0x96c0, 0x6c10, 0xf6c4, 0xc185, 0x9ac0 }, 16, 0x000a4f60, 1},
+ {{0x6769, 0xc481, 0x0926, 0x2568, 0x8009, 0x96c0, 0x8053, 0x27e8, 0x9ff4, 0x32e4, 0x3ca2, 0x8001, 0x96c0, 0xf441, 0x017c, 0x9ff4 }, 16, 0x000a4f80, 1},
+ {{0x2469, 0x3860, 0x2069, 0x8008, 0x8423, 0x33e4, 0x37da, 0x8001, 0x6d90, 0x0321, 0x32ac, 0x8009, 0x0321, 0x32ab, 0x8009, 0x3044 }, 16, 0x000a4fa0, 1},
+ {{0x3084, 0x800a, 0x0322, 0x28c4, 0x8009, 0x0926, 0x2568, 0x8009, 0x32e4, 0x3804, 0x8001, 0x0826, 0x28b0, 0x8009, 0x2468, 0x2f10 }, 16, 0x000a4fc0, 1},
+ {{0x3840, 0x3f54, 0x8008, 0x94c0, 0xf1c4, 0x8055, 0x33e4, 0x37da, 0x8001, 0x0426, 0x28c4, 0x8009, 0x6669, 0x90c0, 0x96c3, 0x0426 }, 16, 0x000a4fe0, 1},
+ {{0x2568, 0x8009, 0x98c3, 0x3261, 0x2072, 0x8008, 0xf442, 0x96c3, 0x32e4, 0x37e6, 0x8001, 0x92c3, 0xf241, 0x32e4, 0x37da, 0x8001 }, 16, 0x000a5000, 1},
+ {{0x3860, 0x208e, 0x8008, 0x6e90, 0x0521, 0x32ab, 0x8009, 0x3044, 0x3084, 0x800a, 0x0522, 0x28c4, 0x8009, 0x24e9, 0x0622, 0x28c4 }, 16, 0x000a5020, 1},
+ {{0x8009, 0x94c6, 0x8042, 0x6d10, 0x96c2, 0x0221, 0x32ab, 0x8009, 0x24e9, 0x3c44, 0x0f26, 0x28b0, 0x8009, 0x94c0, 0xca40, 0x8023 }, 16, 0x000a5040, 1},
+ {{0x90c0, 0xea1f, 0xea4c, 0x5392, 0x65e9, 0x90c0, 0x98c3, 0xc943, 0x3820, 0x2568, 0x8009, 0x90c0, 0x92c3, 0x9963, 0x6d90, 0x0321 }, 16, 0x000a5060, 1},
+ {{0x32ab, 0x8009, 0xe770, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x98c0, 0x9620, 0x3840, 0x3fd3, 0x8008, 0x32e4, 0x37da, 0x8001 }, 16, 0x000a5080, 1},
+ {{0xe758, 0x32e4, 0x37e0, 0x8001, 0x98c0, 0xc184, 0x3081, 0x34a3, 0x8000, 0x3d00, 0x2024, 0x8008, 0x3840, 0x3f98, 0x8008, 0x10d5 }, 16, 0x000a50a0, 1},
+ {{0x32e4, 0x37da, 0x8001, 0x7750, 0x9ac0, 0x7456, 0xc194, 0x32e4, 0x37e0, 0x8001, 0x6460, 0x32e4, 0x37da, 0x8001, 0x3860, 0x208b }, 16, 0x000a50c0, 1},
+ {{0x8008, 0x3b40, 0x30d8, 0x8008, 0x3041, 0x3e70, 0x8008, 0x159b, 0xf041, 0x109b, 0xf542, 0x149b, 0xf043, 0x1293, 0xf444, 0x32e4 }, 16, 0x000a50e0, 1},
+ {{0x37e6, 0x8001, 0xf245, 0xe778, 0x9621, 0x9f71, 0x90c0, 0x90c0, 0x96c0, 0xd4a1, 0xe748, 0xc481, 0x94c0, 0xf442, 0x842f, 0x96c0 }, 16, 0x000a5100, 1},
+ {{0xc181, 0x27ea, 0x9ff8, 0x32e4, 0x389a, 0x8001, 0xfa41, 0x34f0, 0x9fff, 0x8415, 0x32e4, 0x37da, 0x8001, 0x3840, 0x3f6c, 0x8008 }, 16, 0x000a5120, 1},
+ {{0x3144, 0x3192, 0x800a, 0x3204, 0x33b0, 0x800b, 0x10fc, 0x9ffa, 0x98c0, 0xd026, 0x0105, 0x3c4a, 0x8008, 0x8419, 0x24e9, 0x3840 }, 16, 0x000a5140, 1},
+ {{0x3fad, 0x8008, 0x802f, 0x33e4, 0x37da, 0x8001, 0x3144, 0x3192, 0x800a, 0x98c0, 0xd021, 0x0405, 0x3c4a, 0x8008, 0x8417, 0x6669 }, 16, 0x000a5160, 1},
+ {{0x90c0, 0x96c3, 0x32e4, 0x37da, 0x8001, 0x96c3, 0x3840, 0x3fc0, 0x8008, 0xe768, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a5180, 1},
+ {{0x94c0, 0xc481, 0x9f70, 0x0421, 0x32ac, 0x8009, 0x90c0, 0x90c0, 0x94c0, 0x6c10, 0x9f70, 0x0021, 0x32ac, 0x8009, 0x90c0, 0x90c0 }, 16, 0x000a51a0, 1},
+ {{0x98c0, 0x3de8, 0x2400, 0xbfff, 0xe750, 0x3840, 0x3eea, 0x8008, 0x1395, 0x32e4, 0x37da, 0x8001, 0x0322, 0x28ac, 0x8009, 0x0126 }, 16, 0x000a51c0, 1},
+ {{0x28ac, 0x8009, 0x9ac0, 0x32ca, 0x8410, 0x90c0, 0x33f9, 0x9fff, 0x98c0, 0x3061, 0x205f, 0x8008, 0xf143, 0x32e4, 0x37e6, 0x8001 }, 16, 0x000a51e0, 1},
+ {{0x94c0, 0xf242, 0xf041, 0xe770, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0xd0a1, 0x7751, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20 }, 16, 0x000a5200, 1},
+ {{0x94c0, 0xeee8, 0xe750, 0x96c2, 0x32e4, 0x37da, 0x8001, 0x96c2, 0x3840, 0x3f37, 0x8008, 0x9ac0, 0xd721, 0xee44, 0x0826, 0x28b0 }, 16, 0x000a5220, 1},
+ {{0x8009, 0x94c0, 0x5996, 0x843f, 0x33e4, 0x3804, 0x8001, 0x2468, 0x3c44, 0x0826, 0x28b0, 0x8009, 0x94c0, 0xca40, 0x848b, 0x3461 }, 16, 0x000a5240, 1},
+ {{0x200a, 0x8008, 0x94c0, 0xea18, 0xf441, 0xea44, 0x529a, 0x1292, 0xf242, 0x32e4, 0x37e6, 0x8001, 0xf243, 0x3144, 0x32e2, 0x800a }, 16, 0x000a5260, 1},
+ {{0x32e4, 0x37da, 0x8001, 0x3860, 0x203d, 0x8008, 0x9ac0, 0x6f90, 0x0826, 0x28b0, 0x8009, 0xef3f, 0x90c0, 0x5690, 0x6769, 0x8045 }, 16, 0x000a5280, 1},
+ {{0xe81f, 0x5e90, 0x90c0, 0x90fe, 0x3410, 0x802e, 0x90c0, 0x98c3, 0xe844, 0x3261, 0x2079, 0x8008, 0x94c3, 0x5390, 0xf241, 0x96c3 }, 16, 0x000a52a0, 1},
+ {{0x32e4, 0x37e6, 0x8001, 0x92c3, 0xf342, 0x9ac0, 0x7bd0, 0x0826, 0x28b0, 0x8009, 0xef50, 0xcb47, 0x90c0, 0xeb18, 0x5293, 0x6569 }, 16, 0x000a52c0, 1},
+ {{0x85c1, 0xe770, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a52e0, 1},
+ {{0x96c0, 0xd0a1, 0x7751, 0x9620, 0x94c0, 0x9e20, 0x9f20, 0x94c0, 0xeee8, 0xe750, 0x96c2, 0x32e4, 0x37da, 0x8001, 0x96c2, 0x3820 }, 16, 0x000a5300, 1},
+ {{0x3206, 0x8009, 0x9ac0, 0xd721, 0xee44, 0x3820, 0x2778, 0x8009, 0x94c0, 0x5996, 0x843f, 0x33e4, 0x3804, 0x8001, 0x2468, 0x3c44 }, 16, 0x000a5320, 1},
+ {{0x3f20, 0x2778, 0x8009, 0x94c0, 0xca40, 0x8487, 0x3161, 0x202c, 0x8008, 0x94c0, 0xea1f, 0xf141, 0xea44, 0x519a, 0x1192, 0xf142 }, 16, 0x000a5340, 1},
+ {{0x32e4, 0x37e6, 0x8001, 0xf143, 0x3144, 0x33cc, 0x800a, 0x32e4, 0x37da, 0x8001, 0x3860, 0x2049, 0x8008, 0x0426, 0x2778, 0x8009 }, 16, 0x000a5360, 1},
+ {{0x2669, 0x3c20, 0x2778, 0x8009, 0x8045, 0x3f20, 0x2778, 0x8009, 0x3e20, 0x277c, 0x8009, 0x5d97, 0x90c0, 0x92fd, 0x3412, 0x802e }, 16, 0x000a5380, 1},
+ {{0x90c0, 0x98c3, 0x5296, 0x3661, 0x207e, 0x8008, 0x94c3, 0xf641, 0xf242, 0x98c7, 0xcc4e, 0x33e4, 0x37e6, 0x8001, 0x94c0, 0xcc46 }, 16, 0x000a53a0, 1},
+ {{0xee50, 0xef50, 0xec50, 0x5694, 0x6769, 0x85cd, 0x32e4, 0x37da, 0x8001, 0x3840, 0x3f11, 0x8008, 0xe770, 0x94c0, 0x9e21, 0x9f21 }, 16, 0x000a53c0, 1},
+ {{0x9621, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x98c0, 0xe750 }, 16, 0x000a53e0, 1},
+ {{0x3621, 0x30f3, 0x8009, 0x32e4, 0x37e6, 0x8001, 0xf641, 0x0626, 0x3318, 0x8009, 0x98c0, 0x3421, 0x30d7, 0x8009, 0xf642, 0x32e4 }, 16, 0x000a5400, 1},
+ {{0x37e6, 0x8001, 0xf441, 0x0226, 0x330c, 0x8009, 0x98c0, 0x3621, 0x30bb, 0x8009, 0xf242, 0x32e4, 0x37e6, 0x8001, 0xf641, 0x0126 }, 16, 0x000a5420, 1},
+ {{0x3330, 0x8009, 0x98c0, 0x0626, 0x3338, 0x8009, 0xf143, 0x98c0, 0x3521, 0x2fbd, 0x8009, 0xf642, 0x32e4, 0x37e6, 0x8001, 0xf541 }, 16, 0x000a5440, 1},
+ {{0x0026, 0x3328, 0x8009, 0x32e4, 0x3c4e, 0x8001, 0x96c0, 0x6460, 0x2100, 0x83e8, 0x34d0, 0x0026, 0x3318, 0x8009, 0x32e4, 0x3c4e }, 16, 0x000a5460, 1},
+ {{0x8001, 0x6460, 0x32e4, 0x3c4e, 0x8001, 0x3750, 0xc18a, 0x94c0, 0xc78a, 0xca46, 0x9ac0, 0x3a00, 0x8007, 0xf042, 0x3607, 0x8007 }, 16, 0x000a5480, 1},
+ {{0x98c0, 0xda90, 0x3421, 0x2f4d, 0x8009, 0x94c0, 0xd7c5, 0xf441, 0xcf47, 0x90c0, 0x98c0, 0xea3f, 0x32e4, 0x37e6, 0x8001, 0xfa43 }, 16, 0x000a54a0, 1},
+ {{0x0026, 0x332c, 0x8009, 0x32e4, 0x3c4e, 0x8001, 0x96c0, 0x6460, 0x2100, 0x83e8, 0x34d0, 0x0026, 0x3324, 0x8009, 0x32e4, 0x3c4e }, 16, 0x000a54c0, 1},
+ {{0x8001, 0x6460, 0x98c0, 0x2000, 0x83e8, 0x7650, 0xc18a, 0x2c7d, 0x32a4, 0x3540, 0x800b, 0x7454, 0x98c0, 0x3e10, 0x800a, 0xf042 }, 16, 0x000a54e0, 1},
+ {{0xc844, 0x98c0, 0xcf40, 0x3721, 0x2f26, 0x8009, 0xf741, 0x98c0, 0xe83f, 0x32e4, 0x37e6, 0x8001, 0xf843, 0x0326, 0x3328, 0x8009 }, 16, 0x000a5500, 1},
+ {{0x36cd, 0x8782, 0x98c0, 0xf542, 0x3521, 0x31f1, 0x8009, 0x32e4, 0x37e6, 0x8001, 0xf541, 0x3421, 0x3230, 0x8009, 0x32e4, 0x37e6 }, 16, 0x000a5520, 1},
+ {{0x8001, 0xf441, 0xe770, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a5540, 1},
+ {{0x98c0, 0xe748, 0x31a1, 0x33c6, 0x8009, 0x32e4, 0x37e6, 0x8001, 0xf141, 0xe768, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a5560, 1},
+ {{0x98c0, 0x3021, 0x2778, 0x8009, 0x9f70, 0x0022, 0x28b0, 0x8009, 0x3004, 0x34a0, 0x800b, 0x6c10, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a5580, 1},
+ {{0x3c80, 0xa105, 0x7456, 0x6e10, 0x74d7, 0xe9ef, 0xe8ee, 0x98c0, 0x3fe8, 0x3c00, 0xbfff, 0xce87, 0x98c0, 0x0dc6, 0x38d0, 0x8008 }, 16, 0x000a55a0, 1},
+ {{0xe748, 0x1697, 0x3a00, 0x2048, 0x8008, 0x9ac0, 0x2d0b, 0x8002, 0x90c0, 0x3d28, 0x9f00, 0x13d3, 0x17d2, 0xdc38, 0x9ac0, 0x371d }, 16, 0x000a55c0, 1},
+ {{0x8001, 0x646e, 0x371e, 0x8002, 0x9ac0, 0x3f5f, 0x8000, 0xcf40, 0x2b0a, 0x809e, 0x90c0, 0xef61, 0x94c0, 0xee8f, 0xff42, 0x90c0 }, 16, 0x000a55e0, 1},
+ {{0x92c2, 0xcf4a, 0x94c2, 0x0902, 0xa400, 0x98c6, 0x66e9, 0xf242, 0x25a0, 0x9fff, 0xf3c2, 0x98c7, 0x0903, 0xa200, 0x90c0, 0xc481 }, 16, 0x000a5600, 1},
+ {{0x94c3, 0x0913, 0xa010, 0x96c7, 0x6769, 0x0913, 0xa001, 0x92c3, 0x7a41, 0x96c3, 0x7e52, 0x0913, 0xa020, 0x96c7, 0x67e9, 0xdd9c }, 16, 0x000a5620, 1},
+ {{0x57d2, 0x98c0, 0x0943, 0xb800, 0xde87, 0x8025, 0x96c0, 0x4512, 0x24a0, 0x9fff, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c0c, 0x80a2 }, 16, 0x000a5640, 1},
+ {{0x55d4, 0xde05, 0x4414, 0x3c40, 0xa000, 0x6f90, 0x0ac6, 0x38d0, 0x8008, 0xe768, 0x3420, 0xa000, 0xeee8, 0x3620, 0xa000, 0x2a0b }, 16, 0x000a5660, 1},
+ {{0x80a0, 0x56db, 0x9ac0, 0x3ccd, 0x804e, 0x52d3, 0x3cce, 0x804f, 0x9cc0, 0x34cc, 0x804f, 0x7f58, 0x34c9, 0x804e, 0x7ed9, 0x3e5a }, 16, 0x000a5680, 1},
+ {{0x3cdb, 0xdd9e, 0xdd9d, 0xdd9c, 0xdd99, 0x4398, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c0a, 0x80a2, 0x56ca, 0x9ac0, 0x3cc9, 0x8082 }, 16, 0x000a56a0, 1},
+ {{0x54d2, 0x3d18, 0x8003, 0x9cc0, 0x3919, 0x8003, 0xda91, 0x38ca, 0x8082, 0x7c54, 0x9ac0, 0x7ccc, 0x7d48, 0xde98, 0x3cc8, 0x8084 }, 16, 0x000a56c0, 1},
+ {{0x9cc0, 0x3cc9, 0x8086, 0x7c46, 0x38cb, 0x8084, 0xde99, 0x9ac0, 0xde9a, 0x7cc4, 0x7dc2, 0x38ce, 0x8086, 0xde98, 0xde99, 0xde9b }, 16, 0x000a56e0, 1},
+ {{0xde9e, 0x4590, 0x98c0, 0x0ac6, 0x38d0, 0x8008, 0xe845, 0xefe8, 0x94c0, 0xea50, 0xef61, 0x94c0, 0x51d2, 0x979f, 0x331e, 0x80ff }, 16, 0x000a5700, 1},
+ {{0x9698, 0x98c0, 0x0ac6, 0x38d0, 0x8008, 0xe842, 0xebe8, 0x94c0, 0xea52, 0xeb61, 0x3800, 0xa800, 0x77d1, 0x56d2, 0x979b, 0x3800 }, 16, 0x000a5720, 1},
+ {{0xa200, 0x3d1c, 0x80ff, 0x7750, 0x9498, 0x98c0, 0x0bc6, 0x38d0, 0x8008, 0xe842, 0xeae8, 0x96c0, 0xea61, 0x2b0b, 0x8038, 0x51d3 }, 16, 0x000a5740, 1},
+ {{0x3319, 0x80ff, 0x9198, 0x98c0, 0x09c6, 0x38d0, 0x8008, 0xe842, 0x90c0, 0x290b, 0x8038, 0x50d3, 0x7c68, 0x909a, 0x0fc6, 0x38d0 }, 16, 0x000a5760, 1},
+ {{0x8008, 0x90c0, 0x3820, 0xa000, 0xefe9, 0x2f09, 0x803a, 0x51d1, 0x331b, 0x80ff, 0x9388, 0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x2b0c }, 16, 0x000a5780, 1},
+ {{0x803a, 0x54d4, 0x94c0, 0x7e68, 0x9f70, 0x9498, 0x90c0, 0x90c0, 0x3ce8, 0x3c00, 0xbfff, 0x2460, 0x00e0, 0x306a, 0x8008, 0x34d0 }, 16, 0x000a57a0, 1},
+ {{0x5494, 0x3928, 0x9f00, 0x98c0, 0xdc38, 0x32e4, 0x3c4e, 0x8001, 0x3e10, 0x8018, 0x98c0, 0x09c6, 0x38d0, 0x8008, 0xca40, 0x90c0 }, 16, 0x000a57c0, 1},
+ {{0x96c0, 0xea61, 0x2909, 0x80b0, 0x13d1, 0xca48, 0x371a, 0x800f, 0x7d48, 0x94c0, 0xdc1a, 0x9f70, 0x6460, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a57e0, 1},
+ {{0x3e00, 0xa10c, 0x7456, 0x74d7, 0x0dc6, 0x38d0, 0x8008, 0xeaef, 0x3519, 0x27fd, 0xbfff, 0x3680, 0xa000, 0x2d08, 0x8064, 0x3680 }, 16, 0x000a5800, 1},
+ {{0xa100, 0x51d0, 0xe864, 0x3c00, 0xa100, 0xdb11, 0x52d0, 0x3419, 0x27ff, 0xbfff, 0x96c0, 0xdf1a, 0x3599, 0x8000, 0x24e9, 0xdf05 }, 16, 0x000a5820, 1},
+ {{0x0906, 0xa200, 0x94c3, 0x0906, 0xa002, 0x4698, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0a, 0x8062, 0x56d2, 0x4610, 0x98c0, 0x0fc6 }, 16, 0x000a5840, 1},
+ {{0x38d0, 0x8008, 0xe844, 0x90c0, 0x2f0f, 0x8068, 0x51d7, 0x4118, 0x0fc6, 0x38d0, 0x8008, 0x90c0, 0x2f0c, 0x806a, 0x53d4, 0x4318 }, 16, 0x000a5860, 1},
+ {{0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c0b, 0x806c, 0x50d3, 0x4018, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c0a, 0x806e, 0x55d2, 0x4518 }, 16, 0x000a5880, 1},
+ {{0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x2b0a, 0x803c, 0x56d2, 0x4618, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0b, 0x803e, 0x52d3, 0x4218 }, 16, 0x000a58a0, 1},
+ {{0x0fc6, 0x38d0, 0x8008, 0x90c0, 0x2f0a, 0x8040, 0x56d2, 0x4618, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0f, 0x8042, 0x56d7, 0x4618 }, 16, 0x000a58c0, 1},
+ {{0x0dc6, 0x38d0, 0x8008, 0x90c0, 0xed54, 0x53d5, 0x4318, 0x0ac6, 0x38d0, 0x8008, 0x90c0, 0xea56, 0x51d2, 0x4118, 0x0dc6, 0x38d0 }, 16, 0x000a58e0, 1},
+ {{0x8008, 0x90c0, 0xed58, 0x57d5, 0x4718, 0x0ac6, 0x38d0, 0x8008, 0x90c0, 0xea5a, 0x51d2, 0x4110, 0x0fc6, 0x38d0, 0x8008, 0x90c0 }, 16, 0x000a5900, 1},
+ {{0x2f0b, 0x807c, 0x15d3, 0xeb64, 0x13d3, 0xdb95, 0x96c0, 0xdf9b, 0x379e, 0x8000, 0x3800, 0xa200, 0x6769, 0xdf84, 0x7750, 0x0907 }, 16, 0x000a5920, 1},
+ {{0xa200, 0x94c3, 0x0907, 0xa002, 0x4799, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0d, 0x807a, 0x54d5, 0x4411, 0x98c0, 0x0dc6, 0x38d0 }, 16, 0x000a5940, 1},
+ {{0x8008, 0xe944, 0x90c0, 0x2d0c, 0x8080, 0x53d4, 0x4319, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0b, 0x8082, 0x52d3, 0x4219, 0x0cc6 }, 16, 0x000a5960, 1},
+ {{0x38d0, 0x8008, 0x90c0, 0x2c0b, 0x8084, 0x53d3, 0x4319, 0x0fc6, 0x38d0, 0x8008, 0x90c0, 0x2f0c, 0x8086, 0x51d4, 0x4119, 0x0ac6 }, 16, 0x000a5980, 1},
+ {{0x38d0, 0x8008, 0x90c0, 0x2a0f, 0x8044, 0x3640, 0xa000, 0x52d7, 0xefea, 0x4219, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0a, 0x8046 }, 16, 0x000a59a0, 1},
+ {{0x50d2, 0x4019, 0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x2b0b, 0x8048, 0x57d3, 0x4719, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c0b, 0x804a }, 16, 0x000a59c0, 1},
+ {{0x54d3, 0x4419, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0xed5c, 0x57d5, 0x4719, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0xed5e, 0x52d5, 0x4219 }, 16, 0x000a59e0, 1},
+ {{0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c0c, 0x8020, 0x57d4, 0x3600, 0xa800, 0x77d1, 0x4719, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0b }, 16, 0x000a5a00, 1},
+ {{0x8022, 0x94c0, 0x54d3, 0x9f70, 0x4411, 0x90c0, 0x90c0, 0x90c0, 0x3be8, 0x3c0c, 0xbfff, 0x32f9, 0x3ccc, 0xbf59, 0x0293, 0x3ba8 }, 16, 0x000a5a20, 1},
+ {{0x3c00, 0xbfff, 0x98c0, 0x3201, 0x2020, 0x8020, 0x9f70, 0x4293, 0x39a8, 0x3c20, 0xbfff, 0x90c0, 0x5191, 0x0122, 0x333c, 0x8009 }, 16, 0x000a5a40, 1},
+ {{0x9f7d, 0x2c90, 0x04e6, 0x3064, 0x8008, 0x6669, 0x90c0, 0x96c3, 0x38c8, 0x3000, 0xbfff, 0x90c0, 0x92c3, 0x4490, 0x05e6, 0x305c }, 16, 0x000a5a60, 1},
+ {{0x8008, 0x66e9, 0x90c0, 0x96c3, 0x38c8, 0x3400, 0xbfff, 0x90c0, 0x92c3, 0x4590, 0x04e6, 0x35c8, 0x8008, 0x6669, 0x90c0, 0x96c3 }, 16, 0x000a5a80, 1},
+ {{0x3dc8, 0x2400, 0xbfff, 0x90c0, 0x92c3, 0x4495, 0x01e2, 0x305c, 0x8008, 0x01e2, 0x3064, 0x8008, 0x01e2, 0x35c8, 0x8008, 0x9f7c }, 16, 0x000a5aa0, 1},
+ {{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x9720, 0x0826, 0x3308, 0x8009, 0x94c0, 0x9e20, 0x9f20 }, 16, 0x000a5ac0, 1},
+ {{0x98c0, 0x3fa8, 0x3c20, 0xbfff, 0xe841, 0x98c0, 0x0325, 0x3369, 0x8009, 0xe748, 0x37e3, 0x1097, 0x0822, 0x3308, 0x8009, 0x27e9 }, 16, 0x000a5ae0, 1},
+ {{0x0022, 0x3344, 0x8009, 0x803f, 0x27ed, 0xc081, 0x8438, 0x0721, 0x3369, 0x8009, 0x33e4, 0x394e, 0x8001, 0x98c0, 0x3541, 0x3a50 }, 16, 0x000a5b00, 1},
+ {{0x800a, 0xc184, 0x32e4, 0x395a, 0x8001, 0x94c0, 0xf541, 0xc081, 0x98c0, 0xc081, 0x31e1, 0x2664, 0x8000, 0x3204, 0x3190, 0x800b }, 16, 0x000a5b20, 1},
+ {{0x007c, 0x9fff, 0x3304, 0x2f90, 0x800a, 0x33c4, 0x38e0, 0x800a, 0x0ec6, 0x38d0, 0x8008, 0x90c0, 0x2e0d, 0x8026, 0x15d5, 0xed62 }, 16, 0x000a5b40, 1},
+ {{0x26e9, 0x55d5, 0x8427, 0x26e9, 0x2c10, 0x3c80, 0x29a0, 0x8009, 0x841b, 0x2704, 0x8060, 0x3d80, 0x2b20, 0x8009, 0x90c0, 0x94c8 }, 16, 0x000a5b60, 1},
+ {{0x401d, 0x401c, 0x3144, 0x3b90, 0x800a, 0x33a4, 0x37e0, 0x800a, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x9721, 0x9f71, 0x90c0, 0x90c0 }, 16, 0x000a5b80, 1},
+ {{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x9f7d, 0x09c6, 0x38d0, 0x8008, 0x90c0, 0xe946, 0x5511, 0x3b1c, 0x8001, 0x6669 }, 16, 0x000a5ba0, 1},
+ {{0x8017, 0x33a4, 0x2930, 0x800a, 0x6469, 0x800d, 0x9f78, 0x9f7c, 0x3144, 0x3d7c, 0x800a, 0x9f7c, 0x98c0, 0x0526, 0x3358, 0x8009 }, 16, 0x000a5bc0, 1},
+ {{0xc281, 0x98c0, 0xd6c2, 0x3ba8, 0x3c24, 0xbfff, 0x0522, 0x3358, 0x8009, 0x3ea8, 0x3c20, 0xbfff, 0x5893, 0x5396, 0x5493, 0xcd44 }, 16, 0x000a5be0, 1},
+ {{0x90c0, 0xeda8, 0x85f5, 0x98c0, 0x0026, 0x3360, 0x8009, 0xc7a0, 0x9cc0, 0x6469, 0xd617, 0x0026, 0x3340, 0x8009, 0xc782, 0x98c0 }, 16, 0x000a5c00, 1},
+ {{0xd5c4, 0x3c20, 0x32fc, 0x8009, 0x96c2, 0x3ec8, 0x3c00, 0xbfff, 0x90c0, 0x92c2, 0x5896, 0x90c0, 0x92c2, 0xe842, 0x9cc6, 0x7c42 }, 16, 0x000a5c20, 1},
+ {{0x90c0, 0x707f, 0x0822, 0x3360, 0x8009, 0x96c0, 0xcb40, 0x2518, 0x8124, 0x2f10, 0x0126, 0x32b4, 0x8009, 0x9ac0, 0x64e0, 0xeb1c }, 16, 0x000a5c40, 1},
+ {{0x39c8, 0x3c00, 0xbfff, 0x9ac0, 0xd881, 0x5d93, 0x0426, 0x3334, 0x8009, 0x2660, 0x0a26, 0x3360, 0x8009, 0x9d61, 0x0222, 0x3340 }, 16, 0x000a5c60, 1},
+ {{0x8009, 0x3044, 0x3d6e, 0x800a, 0x0622, 0x3348, 0x8009, 0x9f7d, 0x9ac0, 0x65e0, 0x0726, 0x32b4, 0x8009, 0xc281, 0x27e0, 0x3453 }, 16, 0x000a5c80, 1},
+ {{0x0426, 0x3334, 0x8009, 0x2660, 0xdb07, 0x98c0, 0xd742, 0x0226, 0x3348, 0x8009, 0x3941, 0xd446, 0x96c0, 0x6460, 0x3612, 0x8032 }, 16, 0x000a5ca0, 1},
+ {{0x2c7d, 0x0222, 0x3348, 0x8009, 0x84a6, 0x0422, 0x3334, 0x8009, 0x9f7c, 0x98c0, 0xc082, 0x3044, 0x3d6e, 0x800a, 0x0022, 0x3340 }, 16, 0x000a5cc0, 1},
+ {{0x8009, 0x25e0, 0x1d91, 0xc681, 0x9ac0, 0x7553, 0xd4c6, 0x0626, 0x3320, 0x8009, 0x9cc0, 0xd541, 0x6760, 0xedaa, 0x3141, 0x2d90 }, 16, 0x000a5ce0, 1},
+ {{0x8004, 0x6560, 0x3452, 0x6e7d, 0x2c7d, 0x0622, 0x3320, 0x8009, 0x845e, 0x0422, 0x3334, 0x8009, 0x9ac0, 0x3aa0, 0x8004, 0x90c0 }, 16, 0x000a5d00, 1},
+ {{0x36a2, 0x8004, 0x38a0, 0x8004, 0xd810, 0x98c0, 0xd442, 0x32e4, 0x3c4e, 0x8001, 0x6460, 0x98c0, 0x2800, 0x83e8, 0x6e10, 0xce40 }, 16, 0x000a5d20, 1},
+ {{0x3d00, 0x20d0, 0x8008, 0x98c0, 0x3fc8, 0x3c00, 0xbfff, 0xe83e, 0x0815, 0x36e9, 0x3fff, 0xbfff, 0x1897, 0x0622, 0x3320, 0x8009 }, 16, 0x000a5d40, 1},
+ {{0x0422, 0x3358, 0x8009, 0xe842, 0x0822, 0x3360, 0x8009, 0x2e10, 0x0322, 0x32b4, 0x8009, 0x0422, 0x32b0, 0x8009, 0x94c0, 0x9e21 }, 16, 0x000a5d60, 1},
+ {{0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x20e0, 0x9fa6, 0x7650, 0xc586, 0x9ac0, 0x6c7c, 0xc286 }, 16, 0x000a5d80, 1},
+ {{0x3c60, 0x2624, 0x8008, 0x74e4, 0x6d7d, 0x7665, 0x6e28, 0x7e41, 0xc944, 0x90c0, 0x94c0, 0xe91c, 0x9f70, 0x50d1, 0x90c0, 0x90c0 }, 16, 0x000a5da0, 1},
+ {{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0xe844, 0x1490, 0xe858, 0x98c0, 0x399e, 0x8000, 0x9620, 0x9720 }, 16, 0x000a5dc0, 1},
+ {{0x2769, 0x1010, 0xc68f, 0x841e, 0x98c0, 0x30ca, 0x8104, 0x9e20, 0x9f20, 0x2561, 0xc081, 0x6e0a, 0xd414, 0x2461, 0x3044, 0x3e14 }, 16, 0x000a5de0, 1},
+ {{0x800a, 0x6464, 0x98c0, 0x30cb, 0x8108, 0xc28f, 0xc081, 0x65e1, 0x6cbd, 0xd411, 0x9ac0, 0x280f, 0x823e, 0x6461, 0x2160, 0x9fff }, 16, 0x000a5e00, 1},
+ {{0x1217, 0x3284, 0x20f0, 0x800a, 0xd442, 0x98c0, 0x2c00, 0x823e, 0x7650, 0xeaef, 0x94c0, 0xc38f, 0xc081, 0x96c0, 0xea3c, 0x2f0e }, 16, 0x000a5e20, 1},
+ {{0x8024, 0x1612, 0xcca6, 0x9ac0, 0x3d1d, 0x800f, 0xedee, 0x2120, 0x8000, 0x2fad, 0xed3c, 0x94c0, 0xd417, 0xecee, 0x2461, 0xec62 }, 16, 0x000a5e40, 1},
+ {{0x6c7c, 0x2ea0, 0x4417, 0x96c0, 0x3b65, 0x9fff, 0x5316, 0x9ac0, 0x3480, 0x8003, 0x6d7c, 0x3686, 0x8003, 0x3080, 0x8003, 0xd810 }, 16, 0x000a5e60, 1},
+ {{0xd446, 0x30cc, 0x944f, 0x4416, 0x0515, 0xee64, 0x5616, 0xd916, 0x3440, 0x8005, 0x7c6f, 0x4014, 0x4016, 0x94c0, 0x9e21, 0x9f21 }, 16, 0x000a5e80, 1},
+ {{0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6c90, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x96c0 }, 16, 0x000a5ea0, 1},
+ {{0xe748, 0x2000, 0x82c0, 0x98c0, 0xc94e, 0x32e4, 0x3c8a, 0x8001, 0x94c0, 0xf041, 0xeee8, 0x3a80, 0xa000, 0x6d10, 0xc946, 0x2e0d }, 16, 0x000a5ec0, 1},
+ {{0x800c, 0x9ac0, 0x2102, 0x8150, 0x90c0, 0x2402, 0x80f8, 0x90c0, 0x96c0, 0x57d9, 0x2202, 0x8268, 0x3880, 0xa000, 0x471d, 0x2600 }, 16, 0x000a5ee0, 1},
+ {{0x8200, 0x96c0, 0x57d9, 0x2b00, 0x8184, 0x3880, 0xa000, 0x471d, 0x2800, 0x8210, 0x96c0, 0x5519, 0x2702, 0x8296, 0x3880, 0xa000 }, 16, 0x000a5f00, 1},
+ {{0x451d, 0x2f00, 0x8294, 0x96c0, 0x5119, 0x2d00, 0x8298, 0x3880, 0xa000, 0x411d, 0x2540, 0x8000, 0x96c0, 0x5719, 0x2420, 0x8000 }, 16, 0x000a5f20, 1},
+ {{0x3880, 0xa000, 0x471d, 0x2100, 0x9000, 0x1711, 0xe948, 0x3880, 0xa000, 0x471d, 0x2002, 0x81dc, 0x3880, 0xa000, 0x421d, 0x2602 }, 16, 0x000a5f40, 1},
+ {{0x8250, 0x3480, 0xa000, 0x421d, 0x3840, 0xa000, 0x5319, 0x2d0a, 0x8242, 0x3880, 0xa000, 0x4315, 0x2a0c, 0x804a, 0x96c0, 0x50d9 }, 16, 0x000a5f60, 1},
+ {{0x2502, 0x813c, 0x4012, 0x5319, 0x431c, 0x1211, 0xe944, 0x021c, 0xc288, 0x5019, 0x96c0, 0x401c, 0x20e0, 0x8000, 0x1311, 0xe944 }, 16, 0x000a5f80, 1},
+ {{0x431c, 0x5319, 0x4314, 0x1799, 0xec44, 0x479c, 0x1711, 0xeaec, 0x3620, 0xa000, 0xea3c, 0x4714, 0x3600, 0xa100, 0x4692, 0xecec }, 16, 0x000a5fa0, 1},
+ {{0x3600, 0xa100, 0xeaec, 0xec3b, 0x3600, 0xa100, 0xea38, 0x4694, 0x0692, 0xebec, 0x3600, 0xa100, 0xeaec, 0xecec, 0x94c0, 0xea3d }, 16, 0x000a5fc0, 1},
+ {{0xeb3f, 0x36a0, 0xa000, 0xec3f, 0x4512, 0x3600, 0xa100, 0x4413, 0x4114, 0x98c0, 0x0fc6, 0x2100, 0x8009, 0xe8ec, 0x94c0, 0xedec }, 16, 0x000a5fe0, 1},
+ {{0xe96e, 0x3820, 0xa100, 0xe838, 0x2f0f, 0x80d4, 0x3680, 0xa000, 0x55df, 0xebec, 0x36c0, 0xa000, 0x57d7, 0xed3a, 0x9ac0, 0x2202 }, 16, 0x000a6000, 1},
+ {{0x8254, 0xdb97, 0x2f00, 0x8138, 0x3a40, 0xa000, 0x2002, 0x81c8, 0xdf9d, 0xeb39, 0x3600, 0xa100, 0x4796, 0xefec, 0x3600, 0xa100 }, 16, 0x000a6020, 1},
+ {{0x5711, 0xebec, 0x96c0, 0x4710, 0x2800, 0x81c4, 0x3680, 0xa000, 0xe9ec, 0xeeec, 0x0713, 0xeaec, 0x0715, 0xea3f, 0x3a00, 0xa100 }, 16, 0x000a6040, 1},
+ {{0x0220, 0x3540, 0x8009, 0xef38, 0x36e0, 0xa000, 0xe93e, 0xee3d, 0x36e0, 0xa000, 0xeb38, 0xec3a, 0x3600, 0xa100, 0x4692, 0x4697 }, 16, 0x000a6060, 1},
+ {{0x3680, 0xa000, 0x4691, 0x4016, 0x32c4, 0x3330, 0x800a, 0x3680, 0xa000, 0x4013, 0x4014, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0 }, 16, 0x000a6080, 1},
+ {{0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x9f20, 0x2100, 0x8078, 0x280f, 0x82b8, 0x1417, 0x3284 }, 16, 0x000a60a0, 1},
+ {{0x20f0, 0x800a, 0x3918, 0x807f, 0x98c0, 0x311c, 0x8007, 0x5117, 0x9f21, 0x3e41, 0x3d20, 0x3544, 0x8009, 0x9ac0, 0x331b, 0x8008 }, 16, 0x000a60c0, 1},
+ {{0xca44, 0x3318, 0x807f, 0x9ac0, 0x30cd, 0x80c4, 0x65e9, 0x32ca, 0x80c7, 0xea1d, 0x96c7, 0x53d2, 0x2000, 0x85a6, 0x94c3, 0x3601 }, 16, 0x000a60e0, 1},
+ {{0x8003, 0x94c3, 0x32cb, 0x958a, 0xd595, 0x65e1, 0xd59a, 0x3700, 0x8008, 0x94c0, 0x7c64, 0x9f70, 0x7470, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a6100, 1},
+ {{0x6466, 0x30f0, 0x2d31, 0x7cc1, 0x92c2, 0x7d69, 0xd541, 0x94c0, 0x75c2, 0x9f70, 0x7473, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a6120, 1},
+ {{0x96c0, 0x6f10, 0x9620, 0x9720, 0xe958, 0x94c0, 0x9e20, 0x9f20, 0x98c0, 0xefe8, 0x3284, 0x20b0, 0x800a, 0x1091, 0xc94f, 0x37d0 }, 16, 0x000a6140, 1},
+ {{0xc947, 0x90c0, 0x290e, 0x8058, 0x3284, 0x20b0, 0x800a, 0x5096, 0x9ac0, 0x6f83, 0xee44, 0x3284, 0x20b0, 0x800a, 0x5096, 0x96c0 }, 16, 0x000a6160, 1},
+ {{0x6760, 0x2f09, 0x82a8, 0x1311, 0xe942, 0x31f0, 0x5311, 0x801f, 0x71f7, 0x90c0, 0x94c7, 0xd7af, 0xc681, 0x90c0, 0x92c2, 0xee52 }, 16, 0x000a6180, 1},
+ {{0x92c2, 0x5516, 0x92c2, 0x7ac1, 0x92c2, 0x4516, 0x96c0, 0x7456, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0 }, 16, 0x000a61a0, 1},
+ {{0xe848, 0x96c0, 0x5490, 0x280a, 0x8018, 0x98c0, 0x395c, 0x8000, 0x9620, 0x9720, 0x96c0, 0x6669, 0x9e20, 0x9f20, 0x94c0, 0x5092 }, 16, 0x000a61c0, 1},
+ {{0x84a9, 0x3284, 0x20b0, 0x800a, 0x94c0, 0xc84f, 0xeeea, 0x3750, 0xebee, 0x98c0, 0xeb68, 0x3284, 0x20b0, 0x800a, 0x5093, 0x96c0 }, 16, 0x000a61e0, 1},
+ {{0x6f02, 0xeaee, 0xc847, 0x35d6, 0xea5a, 0x98c0, 0x7dc1, 0xe9ea, 0x2a0f, 0x800c, 0x25e1, 0xe972, 0x6f4e, 0x3d01, 0x8004, 0x7ce3 }, 16, 0x000a6200, 1},
+ {{0x4112, 0x1017, 0x5711, 0x9ac0, 0x3610, 0x81ff, 0x7841, 0x3f1c, 0x80ff, 0x96c0, 0x3ecd, 0x9608, 0x801d, 0x001f, 0x3284, 0x2120 }, 16, 0x000a6220, 1},
+ {{0x800a, 0x1012, 0x5117, 0x0017, 0x3164, 0x2284, 0x800a, 0x9ac0, 0x2f09, 0x8002, 0x90c0, 0x2f0b, 0x8006, 0x1111, 0x5013, 0x32f1 }, 16, 0x000a6240, 1},
+ {{0x7841, 0x94c0, 0x76f0, 0x801d, 0x3275, 0x2c90, 0x0013, 0xc2df, 0x800f, 0x4113, 0x5690, 0x0946, 0xa000, 0xdd06, 0x4290, 0x6f10 }, 16, 0x000a6260, 1},
+ {{0x4611, 0x4617, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a6280, 1},
+ {{0xe848, 0x94c0, 0x9620, 0x9720, 0x5690, 0x98c0, 0x3d1c, 0x8010, 0x9e20, 0x9f20, 0x96c0, 0x6669, 0x280f, 0x8038, 0x94c0, 0x5097 }, 16, 0x000a62a0, 1},
+ {{0x807b, 0x3384, 0x20b0, 0x800a, 0x96c0, 0x77d0, 0xcca0, 0xebef, 0x90c0, 0x98c0, 0xeb3c, 0x3284, 0x20b0, 0x800a, 0x5093, 0x96c0 }, 16, 0x000a62c0, 1},
+ {{0x6e83, 0xeeef, 0xe8ef, 0x96c0, 0x77d5, 0xee68, 0xe862, 0x3fc1, 0xebef, 0x96c0, 0x67e1, 0xeb64, 0xef44, 0x6edb, 0x96c0, 0x3b07 }, 16, 0x000a62e0, 1},
+ {{0x8004, 0x6e90, 0x7fe3, 0x4716, 0x1410, 0x5013, 0x3a41, 0x1617, 0xd7c0, 0x9ac0, 0x7574, 0x3ccb, 0x9704, 0x4713, 0x4410, 0x98c0 }, 16, 0x000a6300, 1},
+ {{0x3612, 0x80ff, 0x6c8e, 0x5013, 0x94c0, 0x7c64, 0x840f, 0x2ed1, 0x0513, 0x4510, 0x4517, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621 }, 16, 0x000a6320, 1},
+ {{0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x3e00, 0xa004, 0x311f, 0x800f, 0xf9c3, 0x30c8, 0x8104, 0xc3a0 }, 16, 0x000a6340, 1},
+ {{0x9cc0, 0x6461, 0x2160, 0x9ff0, 0x7551, 0x2580, 0x8010, 0x3820, 0xa000, 0x6d93, 0x7651, 0x5591, 0x3400, 0xa804, 0x7755, 0x3600 }, 16, 0x000a6360, 1},
+ {{0xa80c, 0xd71f, 0x7bc1, 0x3c00, 0xa066, 0x34c1, 0x8003, 0x90c0, 0x36c0, 0x8003, 0x3400, 0xa804, 0xda11, 0x3400, 0xa804, 0xd640 }, 16, 0x000a6380, 1},
+ {{0x3600, 0xa804, 0x38cb, 0x96c5, 0x3400, 0xa844, 0x6d0d, 0x3400, 0xa044, 0x6f5c, 0x3640, 0xa840, 0x6d1a, 0x4691, 0x3400, 0xa004 }, 16, 0x000a63a0, 1},
+ {{0x76d2, 0x3400, 0xa804, 0xd69f, 0x3c00, 0xa064, 0x34a0, 0x8003, 0x90c0, 0x36a3, 0x8003, 0x3400, 0xa804, 0xdb90, 0x3400, 0xa004 }, 16, 0x000a63c0, 1},
+ {{0xd7c3, 0x3600, 0xa804, 0x3ec9, 0x96c5, 0x3400, 0xa040, 0x6c18, 0x6c7d, 0x74d4, 0x94c0, 0x6d7c, 0x9f70, 0x7455, 0x90c0, 0x90c0 }, 16, 0x000a63e0, 1},
+ {{0x3284, 0x20f0, 0x800a, 0x2160, 0x9fff, 0x3084, 0x2120, 0x800a, 0x2180, 0x8001, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a6400, 1},
+ {{0x96c0, 0x5011, 0x280c, 0x826c, 0x0014, 0xfdc3, 0xec50, 0x0014, 0xe8ec, 0x1215, 0xe86e, 0x0210, 0xec42, 0x9f70, 0x4214, 0x90c0 }, 16, 0x000a6420, 1},
+ {{0x96c0, 0xcda2, 0x2808, 0x827c, 0x96c0, 0x5410, 0x280a, 0x8024, 0x0411, 0xecea, 0x94c0, 0xec3d, 0xfbc3, 0x5114, 0x94c0, 0x4112 }, 16, 0x000a6440, 1},
+ {{0x9f70, 0x4113, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x38a0, 0x3070, 0x8009, 0x9f71, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a6460, 1},
+ {{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x32c4, 0x20c0, 0x800a, 0xe748, 0x1e90, 0x33a4, 0x34b0, 0x800b, 0x9ac0, 0x6c90 }, 16, 0x000a6480, 1},
+ {{0xefe8, 0x0cc6, 0x2100, 0x8009, 0x1396, 0xe8ee, 0x9ac0, 0x2300, 0x82c0, 0x90c0, 0x371f, 0x8001, 0x96c0, 0x67e9, 0x2c0c, 0x80a8 }, 16, 0x000a64a0, 1},
+ {{0x96c0, 0xcc4e, 0x2518, 0x8284, 0x32e4, 0x3c8a, 0x8001, 0xf341, 0x3a80, 0xa000, 0x6f90, 0xcc46, 0x2e0a, 0x800c, 0x9ac0, 0x2402 }, 16, 0x000a64c0, 1},
+ {{0x8268, 0x90c0, 0x2302, 0x8150, 0x90c0, 0x96c0, 0x52dc, 0x2502, 0x8294, 0x3880, 0xa000, 0x421a, 0x2702, 0x80f8, 0x96c0, 0x51dc }, 16, 0x000a64e0, 1},
+ {{0x2600, 0x8200, 0x3880, 0xa000, 0x411a, 0x2900, 0x8210, 0x96c0, 0x551c, 0x2800, 0x8184, 0x3880, 0xa000, 0x451a, 0x2602, 0x8296 }, 16, 0x000a6500, 1},
+ {{0x96c0, 0x501c, 0x2a00, 0x8298, 0x3880, 0xa000, 0x401a, 0x2540, 0x8000, 0x96c0, 0x531c, 0x2200, 0x9000, 0x3880, 0xa000, 0x431a }, 16, 0x000a6520, 1},
+ {{0x2420, 0x8000, 0x1114, 0xec48, 0x3880, 0xa000, 0x411a, 0x2002, 0x81dc, 0x3880, 0xa000, 0x471a, 0x23e0, 0x8000, 0x3480, 0xa000 }, 16, 0x000a6540, 1},
+ {{0x471a, 0x3840, 0xa000, 0x511c, 0x2a0b, 0x8242, 0x3880, 0xa000, 0x4112, 0x2b0d, 0x804a, 0x96c0, 0x50dc, 0x2202, 0x8138, 0x4013 }, 16, 0x000a6560, 1},
+ {{0x511c, 0x411d, 0x1014, 0xec44, 0x001d, 0xc088, 0x511c, 0x411d, 0x1714, 0xec44, 0x471d, 0x511c, 0x4115, 0x179c, 0xed44, 0x479d }, 16, 0x000a6580, 1},
+ {{0x1714, 0xebed, 0x3620, 0xa000, 0xeb3f, 0x4715, 0x3600, 0xa100, 0x4693, 0xefed, 0x3600, 0xa100, 0xebed, 0xef38, 0x3600, 0xa100 }, 16, 0x000a65a0, 1},
+ {{0xeb39, 0x4697, 0x0693, 0xe9ed, 0x3600, 0xa100, 0xebed, 0xefed, 0x3660, 0xa100, 0xe93d, 0xef3e, 0x0411, 0xeb3a, 0x3600, 0xa100 }, 16, 0x000a65c0, 1},
+ {{0x4513, 0x4217, 0x3a20, 0xa000, 0x0dc6, 0x2100, 0x8009, 0xeaed, 0x94c0, 0xe8ed, 0xec6e, 0x3840, 0xa100, 0xe9ed, 0x2d0e, 0x80d4 }, 16, 0x000a65e0, 1},
+ {{0x36c0, 0xa000, 0x52de, 0xe83b, 0x36c0, 0xa000, 0x57d6, 0xea3c, 0x3820, 0xa100, 0xda97, 0xeded, 0xe938, 0x9ac0, 0x2402, 0x8254 }, 16, 0x000a6600, 1},
+ {{0xde9a, 0x2002, 0x81c8, 0x96c0, 0x4596, 0x2302, 0x813c, 0x3640, 0xa100, 0x5714, 0xed3a, 0x96c0, 0x4712, 0x2a00, 0x8250, 0x96c0 }, 16, 0x000a6620, 1},
+ {{0x4710, 0x2800, 0x81c4, 0x3680, 0xa000, 0xeeed, 0xeced, 0x3680, 0xa100, 0xe9ed, 0xeaed, 0x3600, 0xa100, 0x4711, 0xee38, 0x3a00 }, 16, 0x000a6640, 1},
+ {{0xa100, 0x0020, 0x3540, 0x8009, 0xea3a, 0x3660, 0xa100, 0xec3b, 0xe938, 0x3620, 0xa100, 0xed3c, 0x4695, 0x3680, 0xa100, 0x4696 }, 16, 0x000a6660, 1},
+ {{0x4692, 0x3600, 0xa100, 0x4314, 0x4311, 0x32c4, 0x3330, 0x800a, 0x4315, 0x98c0, 0x09c6, 0x2100, 0x8009, 0xe8ef, 0x32a4, 0x32d0 }, 16, 0x000a6680, 1},
+ {{0x800b, 0xe948, 0x2f90, 0xc683, 0x3457, 0x0cc6, 0x2100, 0x8009, 0x3264, 0x3890, 0x800a, 0x2c09, 0x8038, 0x3457, 0x0fc6, 0x2100 }, 16, 0x000a66a0, 1},
+ {{0x8009, 0x3264, 0x3c90, 0x800a, 0x2f09, 0x8044, 0x3224, 0x3ef0, 0x800c, 0x7457, 0x3457, 0x08c6, 0x2100, 0x8009, 0x3264, 0x3400 }, 16, 0x000a66c0, 1},
+ {{0x800a, 0x2809, 0x8030, 0x3457, 0x09c6, 0x2100, 0x8009, 0x3264, 0x2ee0, 0x800a, 0x2909, 0x80dc, 0x3b61, 0x7bc1, 0x676a, 0x81ab }, 16, 0x000a66e0, 1},
+ {{0x3224, 0x3ef0, 0x800c, 0xc083, 0x98c0, 0x0fc6, 0x2100, 0x8009, 0xc083, 0x3264, 0x3400, 0x800a, 0x2f09, 0x8028, 0x98c0, 0x0fc6 }, 16, 0x000a6700, 1},
+ {{0x2100, 0x8009, 0xc2fe, 0x94c0, 0xc3fe, 0xc081, 0x2f0d, 0x80d4, 0x56d5, 0xdd06, 0x4215, 0x5596, 0x98c0, 0xdd85, 0x3064, 0x2746 }, 16, 0x000a6720, 1},
+ {{0x800a, 0x4396, 0x6c10, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a6740, 1},
+ {{0x94c0, 0x5390, 0x9e20, 0x96c0, 0x370b, 0x8010, 0xe844, 0x98c0, 0x65e9, 0x5390, 0x280e, 0x82a0, 0x96c0, 0x379d, 0x8000, 0x804f }, 16, 0x000a6760, 1},
+ {{0x98c0, 0x66e9, 0x5096, 0x2e0b, 0x8008, 0x96c0, 0x7861, 0x5213, 0x8017, 0x3284, 0x2110, 0x800a, 0x6c90, 0x3164, 0x27a6, 0x800a }, 16, 0x000a6780, 1},
+ {{0x3518, 0x8fff, 0x7c4a, 0x2469, 0x0096, 0xcbb2, 0x94c0, 0xee48, 0x841b, 0x1216, 0xe8ee, 0x3d6c, 0xe83b, 0x1510, 0xcbb0, 0xd69a }, 16, 0x000a67a0, 1},
+ {{0x0510, 0xee3b, 0x4516, 0x9e21, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x94c0, 0xf38f }, 16, 0x000a67c0, 1},
+ {{0xf790, 0x96c0, 0x6aaf, 0xf4c7, 0xf3c7, 0x94c0, 0xd618, 0xd699, 0x2fac, 0xde15, 0x2668, 0xd7c5, 0x94c0, 0x7657, 0x840d, 0xde13 }, 16, 0x000a67e0, 1},
+ {{0x6668, 0xd3db, 0x3457, 0x3284, 0x20b0, 0x800a, 0x6466, 0x94c0, 0xcf40, 0xf0c9, 0x3284, 0x20b0, 0x800a, 0xeffc, 0x3284, 0x2110 }, 16, 0x000a6800, 1},
+ {{0x800a, 0x2100, 0x807d, 0x94c0, 0xcd40, 0xf0ca, 0x3284, 0x20b0, 0x800a, 0xef3d, 0x3284, 0x2110, 0x800a, 0x2100, 0x807d, 0x96c0 }, 16, 0x000a6820, 1},
+ {{0x7457, 0xc940, 0xcf4c, 0x94c0, 0xc94e, 0xfdcb, 0x96c0, 0x6cb6, 0x25e0, 0x9faa, 0x96c0, 0x6d7c, 0x9e21, 0x9f21, 0x94c0, 0x9621 }, 16, 0x000a6840, 1},
+ {{0x9721, 0x9f70, 0x4515, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x77d1, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x96c0 }, 16, 0x000a6860, 1},
+ {{0xeee8, 0x270d, 0x8060, 0x32c4, 0x20c0, 0x800a, 0xe7ed, 0x94c0, 0xee4e, 0xc39a, 0x96c0, 0xce49, 0x2000, 0x808c, 0x96c0, 0xd5c1 }, 16, 0x000a6880, 1},
+ {{0x5116, 0xca47, 0x9ac0, 0x33fc, 0x9000, 0x74d3, 0x280c, 0x8058, 0x9cc0, 0x6883, 0x7e6c, 0xeafe, 0x0224, 0x3540, 0x8009, 0x94c0 }, 16, 0x000a68a0, 1},
+ {{0xc841, 0xea1c, 0x90c0, 0x96c0, 0x5892, 0x280b, 0x8020, 0x96c0, 0x5593, 0x2b0a, 0x804a, 0x3600, 0xa004, 0x7655, 0x5112, 0x3600 }, 16, 0x000a68c0, 1},
+ {{0xa008, 0x68f4, 0xd61c, 0x3600, 0xa080, 0xd49a, 0x6d15, 0x3600, 0xa004, 0xde11, 0xd541, 0x3600, 0xa004, 0x6668, 0x74d2, 0x94c0 }, 16, 0x000a68e0, 1},
+ {{0xdc95, 0x840b, 0x64e8, 0xd15d, 0x0293, 0xe84e, 0x3a20, 0xa000, 0x0526, 0x3534, 0x8009, 0x5510, 0x3e00, 0xa804, 0x3b1f, 0x8001 }, 16, 0x000a6900, 1},
+ {{0xc9ba, 0x3ac9, 0x810c, 0x5512, 0x3a40, 0xa004, 0x67e9, 0x6af6, 0xecea, 0x5512, 0x3c00, 0xa42e, 0xd052, 0xd15a, 0x7ee6, 0x68f6 }, 16, 0x000a6920, 1},
+ {{0xec39, 0x3a01, 0xa009, 0xe9ec, 0xd519, 0x6464, 0xe9ec, 0x3a01, 0xa089, 0xe96c, 0x6dbc, 0xd419, 0xe96c, 0x3646, 0xa044, 0x6dd2 }, 16, 0x000a6940, 1},
+ {{0x5691, 0x3600, 0xb040, 0x6c4d, 0x74d6, 0x4094, 0x3a20, 0xa000, 0x5410, 0x0524, 0x3540, 0x8009, 0x3800, 0xa805, 0x38cf, 0x810c }, 16, 0x000a6960, 1},
+ {{0xd49d, 0x3400, 0xa800, 0xd49f, 0x3600, 0xb800, 0x6e86, 0xdc91, 0x3600, 0xb000, 0x64e8, 0xd6c1, 0x94c0, 0x7555, 0x8415, 0x3400 }, 16, 0x000a6980, 1},
+ {{0xa800, 0xdd16, 0x6568, 0x3400, 0xa800, 0xd2de, 0x96c0, 0x4591, 0x2a0e, 0x8006, 0x1296, 0x5512, 0x3c20, 0xa000, 0x74d2, 0x6af6 }, 16, 0x000a69a0, 1},
+ {{0x0424, 0x3540, 0x8009, 0x3600, 0xb000, 0xd49c, 0xd69c, 0x3600, 0xa004, 0x6d98, 0xdc95, 0x3600, 0xa008, 0x64e8, 0xd5c5, 0x3600 }, 16, 0x000a69c0, 1},
+ {{0xa800, 0x74d3, 0x8413, 0xdc92, 0x64e8, 0x3400, 0xa004, 0xd1da, 0x3640, 0xa000, 0xc153, 0x4396, 0x0324, 0x3540, 0x8009, 0x3620 }, 16, 0x000a69e0, 1},
+ {{0xa000, 0x290e, 0x8264, 0x1196, 0xedee, 0x36d1, 0xed7c, 0x1215, 0xd69c, 0x3600, 0xa004, 0x68bc, 0x6d25, 0x3400, 0xa004, 0xd49b }, 16, 0x000a6a00, 1},
+ {{0x3600, 0xb800, 0xde91, 0xd541, 0x26e8, 0x76d2, 0x94c0, 0xde91, 0x840b, 0x66e8, 0xd159, 0x94c0, 0xcfaa, 0xedea, 0x3840, 0xa100 }, 16, 0x000a6a20, 1},
+ {{0x4296, 0x290d, 0x8252, 0x3680, 0xa000, 0x5215, 0xed3f, 0x293c, 0x1395, 0x0124, 0x3540, 0x8009, 0x34d3, 0xd519, 0xd49c, 0x2e99 }, 16, 0x000a6a40, 1},
+ {{0xdc92, 0x24e8, 0xd6c2, 0x94c0, 0x7555, 0x840d, 0xdd13, 0x6568, 0xd2db, 0x3880, 0xa100, 0xebeb, 0x2a08, 0x8002, 0x3680, 0xa000 }, 16, 0x000a6a60, 1},
+ {{0xeb68, 0x4595, 0x3680, 0xa100, 0x5110, 0x5293, 0x36d2, 0x29f4, 0x0124, 0x3540, 0x8009, 0x94c0, 0xd69c, 0xd599, 0x2ca9, 0xde93 }, 16, 0x000a6a80, 1},
+ {{0x26e8, 0xd4c3, 0x94c0, 0x76d1, 0x840d, 0xde92, 0x66e8, 0xd0da, 0x3680, 0xa000, 0x4193, 0xcfbe, 0x1510, 0x0326, 0x3534, 0x8009 }, 16, 0x000a6aa0, 1},
+ {{0x3ea0, 0xa100, 0x371b, 0x8001, 0x5510, 0x3acd, 0x810c, 0xe9ea, 0x3ac0, 0xb180, 0x65e9, 0x6976, 0xe93f, 0x5510, 0x3ca0, 0xa42a }, 16, 0x000a6ac0, 1},
+ {{0xd1d1, 0xd059, 0x7d66, 0x69f6, 0xeee9, 0x3a81, 0xa108, 0xee70, 0xd41d, 0x65e4, 0xee70, 0x3ae1, 0xa188, 0x5296, 0x6f11, 0xd59d }, 16, 0x000a6ae0, 1},
+ {{0x5296, 0x3606, 0xb004, 0x6f59, 0x74d2, 0x3400, 0xa804, 0x6e4a, 0x34a0, 0xa000, 0x4491, 0x3a20, 0xa000, 0x5110, 0x0524, 0x3540 }, 16, 0x000a6b00, 1},
+ {{0x8009, 0x3800, 0xa805, 0x32cf, 0x810c, 0xd59d, 0x3400, 0xa800, 0xd49f, 0x3600, 0xb800, 0x6d98, 0xdc93, 0x3600, 0xb000, 0x64e8 }, 16, 0x000a6b20, 1},
+ {{0xd5c3, 0x94c0, 0x7553, 0x8415, 0x3400, 0xa800, 0xdd12, 0x6568, 0x3400, 0xa800, 0xd1da, 0x3680, 0xa100, 0xeaea, 0x4396, 0x3a80 }, 16, 0x000a6b40, 1},
+ {{0xa000, 0xea7a, 0x0224, 0x3540, 0x8009, 0x38c0, 0xa000, 0x5192, 0x2a0e, 0x801e, 0x36d1, 0x5316, 0x29f5, 0xd69c, 0x2d25, 0xd59a }, 16, 0x000a6b60, 1},
+ {{0x94c0, 0xde93, 0xd543, 0x26e8, 0x75d2, 0x94c0, 0xdd91, 0x840b, 0x65e8, 0xd159, 0x3680, 0xa100, 0x4292, 0xecea, 0x3600, 0xa100 }, 16, 0x000a6b80, 1},
+ {{0x5510, 0xec76, 0x3a00, 0xa100, 0x3aca, 0x810c, 0x5116, 0x5594, 0x3c20, 0xa000, 0x69f4, 0x74d5, 0x0124, 0x3540, 0x8009, 0x3600 }, 16, 0x000a6ba0, 1},
+ {{0xb000, 0xd49a, 0xd599, 0x2d05, 0xdc93, 0x24e8, 0xd543, 0x94c0, 0x74d2, 0x840d, 0xdc95, 0x64e8, 0xd15d, 0x96c0, 0x5116, 0x2a0f }, 16, 0x000a6bc0, 1},
+ {{0x800a, 0x3880, 0xa000, 0x6af4, 0x5397, 0x4294, 0x34d3, 0x0224, 0x3540, 0x8009, 0x94c0, 0xd69a, 0xd49c, 0x2c19, 0xdc95, 0x24e8 }, 16, 0x000a6be0, 1},
+ {{0xd445, 0x94c0, 0x76d0, 0x840d, 0xde93, 0x66e8, 0xd05b, 0x3600, 0xa100, 0x4097, 0xefea, 0x3600, 0xa100, 0x5310, 0xef6e, 0x3a80 }, 16, 0x000a6c00, 1},
+ {{0xa000, 0x36cd, 0x810c, 0x5197, 0x5616, 0x3880, 0xa100, 0x7475, 0x5296, 0x5310, 0x38c0, 0xa000, 0x5594, 0x2f0f, 0x800a, 0x94c0 }, 16, 0x000a6c20, 1},
+ {{0xf603, 0xf141, 0x94c0, 0xf243, 0xff45, 0x94c0, 0xf544, 0xf304, 0x98c0, 0x0124, 0x3540, 0x8009, 0xf847, 0x94c0, 0xf448, 0xfb49 }, 16, 0x000a6c40, 1},
+ {{0x94c0, 0xfa4a, 0xf94b, 0x3640, 0xa000, 0xfd4c, 0xfd4d, 0x3660, 0xa000, 0xfb4e, 0xf84f, 0x3660, 0xa000, 0xf950, 0xfe51, 0x98c0 }, 16, 0x000a6c60, 1},
+ {{0xcc4e, 0x3264, 0x27d0, 0x800a, 0x3660, 0xa000, 0xfa52, 0xff53, 0x3660, 0xa000, 0xffd3, 0xccb2, 0x94c0, 0xcc46, 0xf8c7, 0x36c0 }, 16, 0x000a6c80, 1},
+ {{0xa000, 0x4097, 0xf8cf, 0x3a80, 0xa000, 0xefef, 0x0626, 0x3534, 0x8009, 0x3aa0, 0xa000, 0x3d1b, 0x8001, 0xef3c, 0xfaca, 0x3840 }, 16, 0x000a6ca0, 1},
+ {{0xa100, 0x65e9, 0x5697, 0x5010, 0x3e80, 0xac0e, 0xd0d6, 0x30cb, 0x810c, 0xd15e, 0x5210, 0x5112, 0x3a46, 0xa003, 0x90c0, 0xf9d0 }, 16, 0x000a6cc0, 1},
+ {{0x64e4, 0x6ab8, 0x3e61, 0xb20f, 0xccbc, 0xd51b, 0xd49b, 0x7ee6, 0x7ee6, 0xccbc, 0x3a81, 0xb399, 0x5591, 0x6e0a, 0x6e46, 0x5591 }, 16, 0x000a6ce0, 1},
+ {{0x3820, 0xa840, 0x6c55, 0x5294, 0xff55, 0x3a20, 0xa000, 0xef3c, 0x3284, 0x20b0, 0x800a, 0x98c0, 0x6466, 0x7752, 0xf054, 0xf556 }, 16, 0x000a6d00, 1},
+ {{0x94c0, 0xcc40, 0xf5d6, 0x7455, 0x98c0, 0xecfc, 0x3284, 0x20b0, 0x800a, 0xfc57, 0x96c0, 0x7456, 0xfcd7, 0xc150, 0x90c0, 0x3a20 }, 16, 0x000a6d20, 1},
+ {{0xa000, 0xec39, 0x3284, 0x20b0, 0x800a, 0xfc57, 0x94c0, 0xc150, 0xfcd7, 0x3640, 0xa000, 0xfaca, 0xffd5, 0x94c0, 0xf8c7, 0xf0d4 }, 16, 0x000a6d40, 1},
+ {{0x3620, 0xa000, 0xec39, 0xf9cb, 0x3660, 0xa000, 0xfed1, 0xf8cf, 0x3680, 0xa000, 0xecea, 0x4c17, 0x3680, 0xa100, 0x4097, 0xec6a }, 16, 0x000a6d60, 1},
+ {{0x3600, 0xa100, 0x5210, 0x5196, 0x3a00, 0xa104, 0x34c8, 0x810c, 0x5691, 0x5394, 0x3800, 0xa900, 0x7470, 0x5210, 0x5512, 0x3840 }, 16, 0x000a6d80, 1},
+ {{0xa000, 0xf143, 0x2c0f, 0x8008, 0x94c0, 0xf644, 0xff45, 0x94c0, 0xf204, 0xf503, 0x98c0, 0xc45e, 0x3264, 0x27d0, 0x800a, 0x98c0 }, 16, 0x000a6da0, 1},
+ {{0xf341, 0x0124, 0x3540, 0x8009, 0x3820, 0xa000, 0x7750, 0xc456, 0xf8cf, 0x3640, 0xa000, 0xfdcc, 0xfdcd, 0x3620, 0xa000, 0xfbce }, 16, 0x000a6dc0, 1},
+ {{0xe8ef, 0x3680, 0xa000, 0x4694, 0xecef, 0x3600, 0xa100, 0xe870, 0x5110, 0x1695, 0x5390, 0x3680, 0xa100, 0x5515, 0x5293, 0x94c0 }, 16, 0x000a6de0, 1},
+ {{0xf4c8, 0xec64, 0x96c0, 0x7454, 0xf644, 0xf104, 0x94c0, 0xf503, 0xf341, 0x94c0, 0xfc45, 0xf243, 0x3264, 0x27d0, 0x800a, 0x98c0 }, 16, 0x000a6e00, 1},
+ {{0x0124, 0x3540, 0x8009, 0xc84e, 0x96c0, 0x76d0, 0xfbc9, 0xfaca, 0x3620, 0xa000, 0xfad2, 0xc846, 0x1616, 0xef54, 0x0590, 0xeeef }, 16, 0x000a6e20, 1},
+ {{0x1112, 0xf4c8, 0x3454, 0x1397, 0x5293, 0x3680, 0xa000, 0x5592, 0xee64, 0x94c0, 0xf104, 0xf544, 0x94c0, 0xfe45, 0xf243, 0x94c0 }, 16, 0x000a6e40, 1},
+ {{0xf603, 0xf341, 0x3264, 0x27d0, 0x800a, 0x0124, 0x3540, 0x8009, 0x98c0, 0x3421, 0x3554, 0x8009, 0xc394, 0x2a0f, 0x0097, 0xfaca }, 16, 0x000a6e60, 1},
+ {{0x94c0, 0xc944, 0xf4bd, 0x9ac0, 0x6a34, 0x0124, 0x3540, 0x8009, 0xea56, 0x96c0, 0xd619, 0xe942, 0x5792, 0x3757, 0x5251, 0x6569 }, 16, 0x000a6e80, 1},
+ {{0x94c1, 0xd092, 0x6d10, 0x92c3, 0x74f1, 0x94c3, 0x3302, 0x800e, 0xd71a, 0x2d1f, 0xdf14, 0x2768, 0xd544, 0x94c0, 0x7752, 0x840d }, 16, 0x000a6ea0, 1},
+ {{0xdf17, 0x6768, 0xd15f, 0x4292, 0x27ea, 0x9fa0, 0xe7ea, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0 }, 16, 0x000a6ec0, 1},
+ {{0x96c0, 0x7750, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x98c0, 0xce40, 0x3722, 0x359c, 0x8009, 0x98c0, 0x3622, 0x3590, 0x8009 }, 16, 0x000a6ee0, 1},
+ {{0xc494, 0x96c0, 0xeefe, 0x270f, 0x8028, 0x3680, 0xa000, 0xef1e, 0xe7ef, 0x36c0, 0xa000, 0x5297, 0xee1e, 0x94c0, 0xf241, 0xf942 }, 16, 0x000a6f00, 1},
+ {{0x1e96, 0x3721, 0x3554, 0x8009, 0x2b80, 0x33c4, 0x20c0, 0x800a, 0x96c0, 0x6d10, 0xcf47, 0xf9c2, 0xc184, 0x96c0, 0xef50, 0x290a }, 16, 0x000a6f20, 1},
+ {{0x8002, 0x0897, 0xca4f, 0x3284, 0x2120, 0x800a, 0x0211, 0x5012, 0x94c0, 0xca47, 0xe8ef, 0x94c0, 0xe86e, 0xecef, 0x0010, 0xea54 }, 16, 0x000a6f40, 1},
+ {{0x1512, 0xf9c2, 0x94c0, 0xec66, 0xedef, 0x0514, 0xebea, 0x3620, 0xa000, 0x5211, 0xed68, 0x3620, 0xa000, 0x4215, 0x5410, 0x3800 }, 16, 0x000a6f60, 1},
+ {{0xa140, 0x6cc8, 0xebef, 0xeb62, 0x3820, 0xa100, 0x78e1, 0xeb64, 0x5313, 0x3680, 0xa000, 0xedea, 0xedea, 0x3640, 0xa100, 0xecea }, 16, 0x000a6f80, 1},
+ {{0x4313, 0x3680, 0xa100, 0xeaea, 0xed66, 0x94c0, 0xec6a, 0xed6e, 0x1515, 0x3322, 0x35a8, 0x8009, 0x96c0, 0xdb95, 0xf143, 0x5114 }, 16, 0x000a6fa0, 1},
+ {{0x3840, 0xa104, 0xda91, 0x5115, 0xe8ea, 0x3c80, 0xb900, 0xd991, 0x3bed, 0x9fff, 0xecea, 0xea72, 0x3ea0, 0xa000, 0x37e9, 0x9fff }, 16, 0x000a6fc0, 1},
+ {{0x5712, 0x3feb, 0x9fff, 0xebea, 0x3880, 0xa804, 0xd817, 0xe864, 0xec70, 0x3a00, 0xa800, 0x31ea, 0x9fff, 0xc156, 0x5610, 0x3aa0 }, 16, 0x000a6fe0, 1},
+ {{0xa100, 0x3dfc, 0x9fff, 0x5214, 0xe8ea, 0x3c80, 0xa804, 0x35fa, 0x9fff, 0xde19, 0xeb68, 0xe86c, 0x3860, 0xa004, 0xdd1a, 0x5013 }, 16, 0x000a7000, 1},
+ {{0x54d1, 0x3ae0, 0xa800, 0x31fe, 0x9fff, 0x5710, 0x50d2, 0x3c60, 0xa900, 0x3fff, 0x9fff, 0xdf1d, 0xeb19, 0xf948, 0x3880, 0xa000 }, 16, 0x000a7020, 1},
+ {{0xdf9b, 0xf444, 0x90bb, 0x3660, 0xa000, 0xf045, 0xf446, 0x32e4, 0x39e4, 0x8001, 0x3420, 0xa000, 0xf247, 0x3a20, 0xa000, 0xf9c8 }, 16, 0x000a7040, 1},
+ {{0x3b20, 0x35ab, 0x8009, 0x90c0, 0x3a80, 0xa000, 0xe91b, 0x32e4, 0x3a68, 0x8001, 0x36c0, 0xa000, 0x90b9, 0xf948, 0x3840, 0xa004 }, 16, 0x000a7060, 1},
+ {{0x6d90, 0xf4c6, 0xf1c3, 0x3c00, 0xa402, 0x7679, 0x2e0d, 0x8004, 0xda94, 0xf2c1, 0x3e00, 0xa800, 0xde1d, 0x76d2, 0xe8ed, 0x3bc8 }, 16, 0x000a7080, 1},
+ {{0x3820, 0xbfff, 0x0495, 0xe862, 0x3660, 0xa000, 0x4316, 0xf9c8, 0x3a20, 0xa000, 0x4310, 0x3cc8, 0x3820, 0xbfff, 0x3420, 0xa000 }, 16, 0x000a70a0, 1},
+ {{0x5493, 0x3400, 0xa004, 0xde02, 0x3400, 0xa004, 0xd220, 0x840b, 0x5194, 0xdc85, 0x64e9, 0x81fb, 0x98c0, 0xce44, 0x32e4, 0x3a68 }, 16, 0x000a70c0, 1},
+ {{0x8001, 0x3680, 0xa000, 0x90b9, 0xfd49, 0x3800, 0xa004, 0x6f10, 0xfdc9, 0xce4c, 0x3660, 0xa000, 0xf4c6, 0xf0c5, 0x3800, 0xa804 }, 16, 0x000a70e0, 1},
+ {{0xd890, 0x449d, 0xf4c4, 0x3660, 0xa000, 0x4495, 0xf2c7, 0x94c0, 0xed54, 0xe8ef, 0x96c0, 0x449d, 0x27eb, 0x9fd8, 0x069d, 0xef61 }, 16, 0x000a7100, 1},
+ {{0x079d, 0xe7eb, 0x3640, 0xa000, 0xeaed, 0x4295, 0x94c0, 0xea7c, 0xed44, 0x3620, 0xa000, 0x4192, 0xe862, 0x3640, 0xa000, 0x6e10 }, 16, 0x000a7120, 1},
+ {{0xc481, 0x449d, 0x449d, 0x449d, 0x4495, 0x3660, 0xa000, 0x969f, 0x9498, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71 }, 16, 0x000a7140, 1},
+ {{0x3e00, 0xa004, 0x02fc, 0x9ff4, 0x6e10, 0x75d1, 0x7456, 0xc594, 0x3e00, 0xa108, 0x6566, 0x74d7, 0x3121, 0x3554, 0x8009, 0xe8ee }, 16, 0x000a7160, 1},
+ {{0x9ec0, 0x311a, 0x8003, 0x6f90, 0x0cf2, 0xbfff, 0x6881, 0xc68b, 0x9ac0, 0x7d42, 0x3c20, 0x3590, 0x8009, 0xce41, 0x96c7, 0xc942 }, 16, 0x000a7180, 1},
+ {{0x02fc, 0x9ff4, 0x9cc1, 0x6566, 0x2e0b, 0x8006, 0x6c90, 0x2e0b, 0x8006, 0x94c7, 0xe91c, 0xd81a, 0x94c7, 0x5213, 0xd010, 0x96c7 }, 16, 0x000a71a0, 1},
+ {{0xc58e, 0x3101, 0x801e, 0x2c86, 0x0084, 0x2ca2, 0x8009, 0x98c0, 0x7471, 0x3119, 0x8010, 0x5991, 0x2c7c, 0x64e9, 0x98c7, 0x6c88 }, 16, 0x000a71c0, 1},
+ {{0x6f10, 0x2908, 0x8014, 0x2d7d, 0xede8, 0x26e4, 0xed62, 0x34f5, 0x4513, 0x94c7, 0x6e18, 0x4616, 0x3e48, 0x4390, 0x98c0, 0x391c }, 16, 0x000a71e0, 1},
+ {{0x9f00, 0x5313, 0xe844, 0x96c0, 0x3718, 0x801f, 0xeb46, 0xdc1c, 0x4011, 0x3640, 0xa000, 0x5616, 0xeee8, 0x3600, 0xa800, 0x7750 }, 16, 0x000a7200, 1},
+ {{0x4615, 0xf185, 0x4190, 0x131b, 0xe876, 0x371c, 0x800f, 0x94c0, 0x4410, 0x9f70, 0x3600, 0xa800, 0x77d1, 0x979b, 0x90c0, 0x90c0 }, 16, 0x000a7220, 1},
+ {{0x96c0, 0x7750, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0xe748, 0x32c4, 0x20c0, 0x800a, 0xf941, 0x9cc0, 0x7456, 0x6d10, 0x3321 }, 16, 0x000a7240, 1},
+ {{0x3554, 0x8009, 0xc794, 0x9ac0, 0x699f, 0x3d1d, 0x8003, 0x5e90, 0xc681, 0x9ac0, 0x7ec2, 0xcd43, 0x3a20, 0x3590, 0x8009, 0xc845 }, 16, 0x000a7260, 1},
+ {{0xed4f, 0x94c0, 0x95bd, 0xe81a, 0x26e9, 0x5c90, 0x2518, 0x80fe, 0x94c0, 0xed61, 0xca40, 0x98c0, 0x95bd, 0x38c8, 0x3820, 0xbfff }, 16, 0x000a7280, 1},
+ {{0x94c0, 0xd2a1, 0xeafe, 0x94c6, 0x802c, 0x6d90, 0x92c2, 0x939d, 0x1790, 0x3d20, 0x359c, 0x8009, 0x90c0, 0xea1d, 0x1392, 0x3ac8 }, 16, 0x000a72a0, 1},
+ {{0x3820, 0xbfff, 0xdf83, 0xd3a0, 0x840b, 0x5692, 0xdf03, 0x6769, 0x81fb, 0x98c0, 0xcd40, 0x3f20, 0x35ab, 0x8009, 0xcc4e, 0x98c0 }, 16, 0x000a72c0, 1},
+ {{0xed1f, 0x32e4, 0x3a68, 0x8001, 0x90bd, 0x94c0, 0xf9c1, 0xcc46, 0x90c0, 0x9ac0, 0x2908, 0x804a, 0x90c0, 0x2900, 0x805e, 0x96c0 }, 16, 0x000a72e0, 1},
+ {{0x5210, 0x280b, 0x8020, 0x96c0, 0xefeb, 0x2c0c, 0x8040, 0x0213, 0xef39, 0x96c0, 0x4217, 0x2c09, 0x8004, 0x5694, 0x5791, 0x3f20 }, 16, 0x000a7300, 1},
+ {{0x8000, 0xdf90, 0x3f8d, 0x8000, 0x66e9, 0x800f, 0x6468, 0x90c0, 0x96c3, 0x30e8, 0x3fff, 0xbfff, 0x98c0, 0xcb4f, 0x3264, 0x2400 }, 16, 0x000a7320, 1},
+ {{0x800a, 0x96c0, 0x7c6e, 0xfc42, 0xc84e, 0x94c0, 0xcb47, 0xc846, 0x90c0, 0x1110, 0xeb44, 0x3264, 0x2400, 0x800a, 0x2c31, 0x4013 }, 16, 0x000a7340, 1},
+ {{0x2464, 0xfcc2, 0x7570, 0x96c0, 0x35f9, 0x9fff, 0xec74, 0x5394, 0x37ef, 0x9fff, 0xdc9f, 0x4194, 0x5696, 0x3d1d, 0x8010, 0x66e9 }, 16, 0x000a7360, 1},
+ {{0x840d, 0x0017, 0x3164, 0x338c, 0x800a, 0x969d, 0x3452, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0 }, 16, 0x000a7380, 1},
+ {{0x96c0, 0x7651, 0xc386, 0xc297, 0x2c7c, 0x0024, 0x3540, 0x8009, 0x2669, 0x6c13, 0x94c1, 0xd094, 0x6d90, 0x94c3, 0x3303, 0x801e }, 16, 0x000a73a0, 1},
+ {{0x65e8, 0x90c0, 0x92c3, 0xc39f, 0x6ebd, 0x2c41, 0x3084, 0x2100, 0x800a, 0x6c90, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a73c0, 1},
+ {{0x98c0, 0x3121, 0x3554, 0x8009, 0xc394, 0x6893, 0x94c0, 0xc841, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a73e0, 1},
+ {{0x96c0, 0x6c90, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x98c0, 0xc2b8, 0x3721, 0x35b0, 0x8009, 0x96c0, 0x6b92, 0xe748, 0xc94e }, 16, 0x000a7400, 1},
+ {{0x32e4, 0x3c8a, 0x8001, 0x94c0, 0xf241, 0xc847, 0x9cc0, 0x6e90, 0x6f90, 0x6c90, 0x6c10, 0xc847, 0xc946, 0x94c0, 0x6f10, 0x9746 }, 16, 0x000a7420, 1},
+ {{0x96c0, 0xc010, 0x280d, 0x8010, 0x94c0, 0xeced, 0x959d, 0x94c0, 0xed42, 0xec68, 0x0715, 0xc014, 0x96c0, 0x5319, 0x2d0d, 0x8002 }, 16, 0x000a7440, 1},
+ {{0x96c0, 0x4315, 0x2d08, 0x8004, 0x0310, 0xeae8, 0x1111, 0xea62, 0x0112, 0xe944, 0x96c0, 0x5709, 0x280c, 0x8002, 0x96c0, 0x4714 }, 16, 0x000a7460, 1},
+ {{0x2c0e, 0x8002, 0x96c0, 0x5111, 0x2e0b, 0x8002, 0x96c0, 0x4116, 0x2b09, 0x800c, 0x92d0, 0x461b, 0x4619, 0xe768, 0x94c0, 0x9e21 }, 16, 0x000a7480, 1},
+ {{0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x7751, 0x9620, 0x9720, 0x96c0, 0x7f62, 0x9e20, 0x9f20 }, 16, 0x000a74a0, 1},
+ {{0x96c0, 0xe750, 0x2809, 0x801e, 0x98c0, 0x7f4f, 0xf643, 0x290d, 0x800c, 0x151d, 0xf642, 0x1019, 0xf6c2, 0x98c0, 0x2b03, 0x800c }, 16, 0x000a74c0, 1},
+ {{0x6b41, 0x9345, 0x76d6, 0x141d, 0xf542, 0x94d0, 0xf6c2, 0x5519, 0x6b55, 0x76d6, 0x96c0, 0x7f6f, 0xf542, 0xc110, 0x7676, 0x69b4 }, 16, 0x000a74e0, 1},
+ {{0x25e8, 0x65e1, 0x92c2, 0x6e90, 0x94c7, 0xd4c3, 0xc5ff, 0x1505, 0xa001, 0x90c0, 0x96c6, 0xd445, 0xc581, 0xf6c3, 0x98c6, 0x6abe }, 16, 0x000a7500, 1},
+ {{0xd445, 0x280f, 0x8008, 0x26e8, 0x26e1, 0xc010, 0x94c6, 0xc117, 0x6d10, 0x94c7, 0xd4c5, 0xc2ff, 0x1505, 0xa001, 0x90c0, 0x96c6 }, 16, 0x000a7520, 1},
+ {{0xd442, 0xc581, 0xf2cb, 0x96c6, 0x6569, 0xd445, 0xc695, 0x90c0, 0x98c1, 0xd392, 0xc595, 0xc595, 0x6d10, 0x96c7, 0xc38f, 0x3f02 }, 16, 0x000a7540, 1},
+ {{0x801e, 0x98c0, 0x2f0b, 0x8016, 0x6e7d, 0xc017, 0x98c0, 0x2b0e, 0x800c, 0x6fba, 0x561b, 0x96c0, 0x6f7d, 0xeaee, 0x9345, 0x98c0 }, 16, 0x000a7560, 1},
+ {{0xd617, 0x551a, 0x2b03, 0x801c, 0x2661, 0x7ecf, 0x7e48, 0x6665, 0x7e48, 0x765c, 0xd91c, 0x6a8a, 0x7eef, 0x051e, 0x551a, 0x94d0 }, 16, 0x000a7580, 1},
+ {{0x7ecf, 0x571b, 0x6a8b, 0x7eef, 0x96c0, 0x4516, 0x2f0a, 0x800a, 0x1412, 0xc84f, 0x3a41, 0xeeea, 0x3774, 0x2e10, 0x4412, 0x94c0 }, 16, 0x000a75a0, 1},
+ {{0xd72f, 0xc684, 0x96c0, 0x75d6, 0x2718, 0x814a, 0x2768, 0x4412, 0x94c6, 0xc110, 0x6d10, 0x32e4, 0x3d86, 0x8001, 0x94c7, 0x64e0 }, 16, 0x000a75c0, 1},
+ {{0xc2ff, 0x2768, 0x35d6, 0xc847, 0x92c2, 0x6d10, 0x94c7, 0xc010, 0xc2ff, 0x98c0, 0xc117, 0x32e4, 0x3d86, 0x8001, 0x64e0, 0x9ac0 }, 16, 0x000a75e0, 1},
+ {{0x7451, 0xc017, 0x3284, 0x20b0, 0x800a, 0x6461, 0x3750, 0xc847, 0x90c0, 0xc110, 0x3451, 0x3284, 0x20b0, 0x800a, 0x6461, 0x98c0 }, 16, 0x000a7600, 1},
+ {{0x2e0b, 0x800a, 0x6c02, 0xc847, 0x1513, 0xeaee, 0x32f6, 0xe9eb, 0x94c0, 0xe962, 0x8075, 0x1311, 0xe9ea, 0x31f0, 0xe962, 0x94c0 }, 16, 0x000a7620, 1},
+ {{0x93b9, 0x8067, 0x25e9, 0xedeb, 0x94c0, 0xed68, 0x8431, 0x1215, 0xc781, 0x3961, 0xeb66, 0x36f2, 0x4215, 0x66e8, 0x80ab, 0x9799 }, 16, 0x000a7640, 1},
+ {{0x5413, 0x4415, 0x0426, 0x3690, 0x8009, 0x3a41, 0x3064, 0x3706, 0x800a, 0x0422, 0x3690, 0x8009, 0xeb68, 0x96c0, 0x5313, 0x2b09 }, 16, 0x000a7660, 1},
+ {{0x8002, 0x3284, 0x20f0, 0x800a, 0x98c0, 0x3700, 0x8008, 0x5111, 0xcb4e, 0x94c0, 0xcb46, 0xc847, 0x98c0, 0xeaee, 0x3064, 0x3706 }, 16, 0x000a7680, 1},
+ {{0x800a, 0x4013, 0xe9ea, 0xe962, 0x90b9, 0xd021, 0x96c0, 0x8451, 0x157c, 0x9fd3, 0x66e9, 0x94c0, 0xf6cd, 0x8025, 0x96c0, 0x3d18 }, 16, 0x000a76a0, 1},
+ {{0x8010, 0xedeb, 0x2469, 0xed68, 0x94c0, 0x5515, 0x8413, 0xd6a2, 0x90c0, 0x92c2, 0xc682, 0x92c2, 0x4615, 0x2f90, 0xeceb, 0x94c0 }, 16, 0x000a76c0, 1},
+ {{0xec68, 0xeb64, 0x5214, 0x7961, 0x34f2, 0x4214, 0x64e8, 0x8019, 0x9799, 0x1413, 0x3064, 0x3706, 0x800a, 0x4414, 0xeb68, 0x2b09 }, 16, 0x000a76e0, 1},
+ {{0x8004, 0x5711, 0x4713, 0x2c10, 0x6c90, 0xc010, 0xc017, 0x9745, 0x9ac0, 0x2a0d, 0x800c, 0x90c0, 0x280f, 0x8028, 0x280c, 0x8026 }, 16, 0x000a7700, 1},
+ {{0x92d0, 0x560c, 0x460f, 0x94c0, 0xf6c3, 0xea62, 0x4615, 0x94c0, 0xe770, 0x90ba, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721 }, 16, 0x000a7720, 1},
+ {{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x7750, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x94c0 }, 16, 0x000a7740, 1},
+ {{0xe750, 0xc3b8, 0x98c0, 0x3721, 0x35b0, 0x8009, 0xeee9, 0x2b93, 0x33c4, 0x20c0, 0x800a, 0x96c0, 0xf5ce, 0x147c, 0x9fcf, 0x94c0 }, 16, 0x000a7760, 1},
+ {{0xf3cc, 0xc281, 0x1f90, 0xf208, 0x96c0, 0xf543, 0x047c, 0x9ffb, 0x94c0, 0xf341, 0xf195, 0x3264, 0x34b0, 0x800a, 0xc847, 0x9ac0 }, 16, 0x000a7780, 1},
+ {{0x6469, 0xe9ee, 0x3300, 0x2000, 0x8008, 0x94c0, 0x5791, 0x8043, 0xdd9f, 0x4391, 0x5597, 0x3b09, 0x8004, 0x64e9, 0x90c0, 0x94c3 }, 16, 0x000a77a0, 1},
+ {{0x0917, 0xa00c, 0x92c3, 0x4791, 0x1797, 0x5291, 0x3f3c, 0x8000, 0x6669, 0x90c0, 0x94c6, 0x8038, 0xf4cf, 0x92c2, 0xde1a, 0xf4cf }, 16, 0x000a77c0, 1},
+ {{0x98c0, 0xda04, 0x3064, 0x380c, 0x800a, 0xde02, 0x1491, 0x30f8, 0x3fff, 0xbff7, 0x9ac0, 0xdc04, 0x32f8, 0x3fff, 0xbff3, 0xf5cf }, 16, 0x000a77e0, 1},
+ {{0x96c0, 0xdd04, 0xda05, 0x4091, 0x0291, 0xde02, 0x96c0, 0xd323, 0x4491, 0xc0a8, 0x94c0, 0xcf4a, 0x8019, 0x96c0, 0xd442, 0x2300 }, 16, 0x000a7800, 1},
+ {{0x808c, 0x680e, 0xcc40, 0x90c0, 0x5714, 0xf708, 0x98c0, 0x3200, 0x2002, 0x8008, 0xf188, 0x96c0, 0xdd04, 0xef44, 0xe770, 0x9ac0 }, 16, 0x000a7820, 1},
+ {{0x3440, 0x8001, 0x5397, 0x3645, 0x8001, 0x3040, 0x8001, 0xd910, 0xd545, 0xdd1b, 0x4297, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621 }, 16, 0x000a7840, 1},
+ {{0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x3321, 0x35b0, 0x8009, 0xc4b8, 0x6980, 0x94c0, 0xc843 }, 16, 0x000a7860, 1},
+ {{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6c90, 0x9620, 0x9720, 0x94c0, 0x9f20, 0xc39c, 0x98c0 }, 16, 0x000a7880, 1},
+ {{0x3721, 0x3704, 0x8009, 0xe748, 0x96c0, 0x6b93, 0xf341, 0xc94e, 0x32e4, 0x3c8a, 0x8001, 0xc847, 0x94c0, 0xc946, 0xca47, 0x94c0 }, 16, 0x000a78a0, 1},
+ {{0xc485, 0xc3fb, 0x96c0, 0x5219, 0x2a0d, 0x8002, 0x98c0, 0x2d08, 0x8008, 0x6564, 0x4415, 0x0212, 0xc081, 0x96c0, 0x4310, 0x280a }, 16, 0x000a78c0, 1},
+ {{0x8002, 0x0012, 0xedea, 0x10d9, 0xed66, 0x96c0, 0x4015, 0x2a0f, 0x8008, 0x13d1, 0x32c4, 0x20c0, 0x800a, 0x4317, 0x94c0, 0xef44 }, 16, 0x000a78e0, 1},
+ {{0xe768, 0x4897, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x98c0, 0x3621, 0x3704, 0x8009, 0xc79c }, 16, 0x000a7900, 1},
+ {{0x96c0, 0x6b03, 0x9e20, 0x9f20, 0x96c0, 0xcb46, 0x2709, 0x8028, 0x94c0, 0xe7e9, 0xc4a8, 0x9ac0, 0x2b0a, 0x8018, 0x90c0, 0x2500 }, 16, 0x000a7920, 1},
+ {{0x808c, 0x1e92, 0x31f8, 0x3fbf, 0xbfbf, 0x3378, 0x3fff, 0xbfff, 0x96c0, 0x5896, 0x2e0c, 0x8024, 0x1f94, 0xc84a, 0xd642, 0x3754 }, 16, 0x000a7940, 1},
+ {{0xcc44, 0x6b01, 0x96c0, 0xc846, 0x2c0e, 0x8292, 0x90c0, 0xe848, 0x3420, 0xa000, 0x5390, 0x3800, 0xaa04, 0x371d, 0x9000, 0xdc83 }, 16, 0x000a7960, 1},
+ {{0x3600, 0xa004, 0x66e9, 0x4190, 0x995a, 0x94c3, 0x0901, 0xa040, 0x94c3, 0x4190, 0xe96a, 0x3423, 0xa000, 0x5411, 0x3403, 0xa004 }, 16, 0x000a7980, 1},
+ {{0x7a41, 0x3423, 0xa000, 0x4411, 0x3820, 0xa000, 0x5090, 0x2809, 0x8070, 0x3600, 0xa804, 0x310a, 0x8020, 0x3400, 0xa004, 0x6569 }, 16, 0x000a79a0, 1},
+ {{0x9d5a, 0x3623, 0xa000, 0x0910, 0xa040, 0x3623, 0xa000, 0x4090, 0xed66, 0x3423, 0xa000, 0x5715, 0x3403, 0xa004, 0x7bc1, 0x3423 }, 16, 0x000a79c0, 1},
+ {{0xa000, 0x4715, 0x5790, 0xdd87, 0x4390, 0x1416, 0x5513, 0x96c0, 0x3614, 0x81ff, 0x5611, 0x801f, 0x7375, 0x9b5a, 0x94c3, 0x0983 }, 16, 0x000a79e0, 1},
+ {{0xa000, 0x94c3, 0x4390, 0xeb68, 0x92c3, 0x5013, 0x92c3, 0x7841, 0x92c3, 0x4013, 0x94c0, 0xcba4, 0xe9ec, 0xc183, 0xe93b, 0x1091 }, 16, 0x000a7a00, 1},
+ {{0xe9ea, 0x96c0, 0x3138, 0x8000, 0xe970, 0x2469, 0x1011, 0xc94e, 0x94c0, 0x7841, 0x8023, 0x94c0, 0xfa43, 0xf844, 0x3284, 0x2100 }, 16, 0x000a7a20, 1},
+ {{0x800a, 0xfc45, 0x94c0, 0xc946, 0xfac3, 0x94c0, 0xf8c4, 0xfcc5, 0x4011, 0x96c0, 0xebea, 0x2f09, 0x84aa, 0x11d1, 0xeb6c, 0x1313 }, 16, 0x000a7a40, 1},
+ {{0xfb46, 0x98c0, 0x79c1, 0xefea, 0x2400, 0x80cc, 0x3473, 0x0313, 0x0bc6, 0x2100, 0x8009, 0x96c0, 0x7071, 0xef70, 0xedea, 0x96c0 }, 16, 0x000a7a60, 1},
+ {{0x5317, 0x2718, 0x81dc, 0x98c0, 0x2b0b, 0x8090, 0x65e9, 0xed74, 0x96c0, 0x53d3, 0x290b, 0x806a, 0x94c7, 0xf342, 0xee6c, 0x92c3 }, 16, 0x000a7a80, 1},
+ {{0x5516, 0x92c3, 0xd59d, 0x92c3, 0xf342, 0xf0c2, 0x6c7c, 0x4413, 0x1715, 0x5217, 0x67e9, 0x841d, 0x6569, 0x94c0, 0x9e5a, 0x9b5a }, 16, 0x000a7aa0, 1},
+ {{0x92c3, 0x6e10, 0x94c3, 0xee6a, 0xeb66, 0x92c3, 0x4416, 0x92c3, 0x4413, 0x1415, 0xfa43, 0x96c0, 0x7a61, 0xf844, 0xfc45, 0x2c90 }, 16, 0x000a7ac0, 1},
+ {{0x3474, 0x0415, 0xf947, 0x3284, 0x2120, 0x800a, 0xfd48, 0x94c0, 0xfac3, 0xfdc8, 0xf9c7, 0x0015, 0xebea, 0x3600, 0xa100, 0xeb6e }, 16, 0x000a7ae0, 1},
+ {{0xe9ea, 0x3600, 0xa100, 0x5513, 0xe964, 0x3880, 0xa000, 0x7ae1, 0xeeea, 0xefea, 0x0513, 0xee66, 0x3680, 0xa000, 0x54d1, 0x5716 }, 16, 0x000a7b00, 1},
+ {{0x3a00, 0xa100, 0x3919, 0x80ff, 0x52d1, 0xeaea, 0x3880, 0xa100, 0x69a7, 0xef72, 0xea6a, 0x3820, 0xa100, 0x7173, 0xedea, 0xfa49 }, 16, 0x000a7b20, 1},
+ {{0x3607, 0xa100, 0x7e6c, 0xed76, 0x92c3, 0x7a43, 0x92c3, 0x4415, 0x3680, 0xa100, 0x56d7, 0x5712, 0x3d1d, 0x80ff, 0x2b3b, 0xc55f }, 16, 0x000a7b40, 1},
+ {{0x3176, 0xcb4e, 0x90c0, 0x92c3, 0x5113, 0x94c3, 0x3302, 0x8002, 0x92c3, 0x4213, 0x36a0, 0xa000, 0x5915, 0x5013, 0xc15b, 0x3dc1 }, 16, 0x000a7b60, 1},
+ {{0x3284, 0x20f0, 0x800a, 0x74f3, 0x96c0, 0x7650, 0xf8c4, 0xc557, 0x98c0, 0xcb46, 0x31f8, 0x3fff, 0xb7ff, 0x3600, 0xa100, 0x5390 }, 16, 0x000a7b80, 1},
+ {{0x5015, 0x9cc0, 0x375f, 0x8000, 0x6464, 0xdc83, 0xfdc8, 0xf9c7, 0x98c0, 0x67e9, 0x6c7c, 0xfac3, 0xfcc5, 0x90c0, 0x92c2, 0xc4fc }, 16, 0x000a7ba0, 1},
+ {{0x4413, 0x4190, 0x1413, 0xebea, 0x2668, 0xeb68, 0x90c0, 0x94c2, 0x0911, 0xa800, 0x92c2, 0x4190, 0x5490, 0x0914, 0xa001, 0x4490 }, 16, 0x000a7bc0, 1},
+ {{0x5115, 0x64e9, 0x90c0, 0x96c3, 0x31f8, 0x3fff, 0xbffe, 0x94c7, 0x8426, 0xdc84, 0x92c3, 0x4190, 0x1313, 0x50d1, 0x3705, 0x8005 }, 16, 0x000a7be0, 1},
+ {{0x7075, 0x90c0, 0x96c3, 0x30f8, 0x3fff, 0xbffe, 0x92c3, 0xdc04, 0x92c3, 0x4090, 0xcba0, 0x90c0, 0xec3b, 0x5794, 0x3f09, 0x8004 }, 16, 0x000a7c00, 1},
+ {{0x64e9, 0x90c0, 0x92c3, 0x5190, 0x94c3, 0x0911, 0xa001, 0x92c3, 0x4190, 0x5017, 0x3861, 0x3284, 0x2120, 0x800a, 0x6c90, 0x3820 }, 16, 0x000a7c20, 1},
+ {{0xa000, 0x6d10, 0xfac3, 0xfac9, 0x0017, 0xfbc6, 0xea68, 0x4213, 0x4212, 0x3480, 0xa000, 0x4212, 0x4216, 0x27e9, 0x9fd8, 0xe7e9 }, 16, 0x000a7c40, 1},
+ {{0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x98c0, 0x3421, 0x3704, 0x8009, 0xc19c, 0x6a11, 0x94c0, 0xc844 }, 16, 0x000a7c60, 1},
+ {{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6c90, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x98c0 }, 16, 0x000a7c80, 1},
+ {{0xc5a4, 0x3721, 0x3758, 0x8009, 0x96c0, 0x6b81, 0xe748, 0xc94e, 0x98c0, 0xce40, 0x32e4, 0x3c8a, 0x8001, 0x94c0, 0xf541, 0xc847 }, 16, 0x000a7ca0, 1},
+ {{0x33c4, 0x20c0, 0x800a, 0x94c0, 0xcf47, 0xce48, 0x2469, 0xc946, 0x2f0b, 0x8020, 0x94c6, 0x4893, 0xc2a8, 0x94c6, 0x8019, 0x5190 }, 16, 0x000a7cc0, 1},
+ {{0x1190, 0xd021, 0x90c0, 0x9ac1, 0x2200, 0x8140, 0x90c0, 0x2200, 0x80b4, 0x98c0, 0xd541, 0x6f90, 0xeaeb, 0xedeb, 0x94c0, 0xea64 }, 16, 0x000a7ce0, 1},
+ {{0xed7e, 0x0292, 0xeceb, 0x1119, 0xec7a, 0x0117, 0xeeeb, 0x1611, 0xe944, 0x0615, 0xe8e9, 0x11d1, 0xe862, 0x0114, 0xee7c, 0x1410 }, 16, 0x000a7d00, 1},
+ {{0xedeb, 0x0416, 0xe942, 0x1619, 0xed76, 0x0615, 0xe8eb, 0x1319, 0xedeb, 0x94c0, 0xe874, 0xeeeb, 0x0310, 0xed70, 0x0715, 0xee6e }, 16, 0x000a7d20, 1},
+ {{0x0716, 0xeceb, 0x1519, 0xec72, 0x0514, 0xeeeb, 0x1511, 0xedeb, 0x94c0, 0xee68, 0xe768, 0x0516, 0xed6a, 0x94c0, 0x9e21, 0x9f21 }, 16, 0x000a7d40, 1},
+ {{0x0715, 0xeb66, 0x4713, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x3e00, 0xa00c, 0x74d6, 0x7557, 0xc6a4, 0x3421, 0x3758, 0x8009 }, 16, 0x000a7d60, 1},
+ {{0x3a80, 0xa100, 0x6a02, 0x64e6, 0xe8ee, 0xcf48, 0x98c0, 0xcd44, 0x36d8, 0x33ff, 0xbfef, 0xc8a0, 0x2d0c, 0x8020, 0x1a94, 0xeeec }, 16, 0x000a7d80, 1},
+ {{0x94c0, 0xee64, 0xe9ec, 0x1f96, 0x5e92, 0x94c0, 0xe97a, 0xeaec, 0x94c0, 0xef48, 0xea6c, 0x96c0, 0x5397, 0x2f0b, 0x8042, 0x3880 }, 16, 0x000a7da0, 1},
+ {{0xa100, 0xdf03, 0xe9eb, 0xefec, 0x3600, 0xa100, 0x4697, 0xe938, 0x1713, 0x53d1, 0x3a00, 0xa100, 0x67e6, 0x371c, 0x800f, 0xef6e }, 16, 0x000a7dc0, 1},
+ {{0x3677, 0x998f, 0x90c0, 0x94c2, 0x0916, 0xa010, 0x92c2, 0x4697, 0x5315, 0x71f1, 0x90c0, 0x92c3, 0x5597, 0x94c3, 0x0925, 0xa000 }, 16, 0x000a7de0, 1},
+ {{0x92c3, 0x4597, 0x3600, 0xa100, 0x5312, 0x5111, 0x30f3, 0x1697, 0xeaec, 0x96c0, 0x841f, 0x0916, 0xa002, 0x0697, 0xea72, 0x5712 }, 16, 0x000a7e00, 1},
+ {{0x3f19, 0x8fff, 0x3a80, 0xa000, 0x4117, 0x3164, 0x3e56, 0x800a, 0xeaec, 0xea6e, 0x5212, 0x3961, 0xd520, 0x94c7, 0x4212, 0x6d90 }, 16, 0x000a7e20, 1},
+ {{0x98c3, 0x4312, 0x32f8, 0x3fff, 0xbffd, 0x92c3, 0x5697, 0x92c3, 0xdd06, 0x92c3, 0x4297, 0x3600, 0xa100, 0xeb5e, 0xefec, 0x3600 }, 16, 0x000a7e40, 1},
+ {{0xa100, 0xeaeb, 0xef7e, 0x1613, 0xea62, 0x3600, 0xa100, 0x5512, 0x5317, 0x3880, 0xa000, 0x6c9a, 0x5597, 0xeaec, 0x3880, 0xa100 }, 16, 0x000a7e60, 1},
+ {{0x71f1, 0xea72, 0xedec, 0x96c0, 0x8027, 0x0905, 0xb000, 0x3600, 0xa100, 0x4597, 0xed70, 0x3480, 0xa000, 0x5112, 0x3319, 0x8fff }, 16, 0x000a7e80, 1},
+ {{0x3a80, 0xa000, 0x4115, 0x3164, 0x3ee0, 0x800a, 0x3480, 0xa000, 0xecec, 0x3480, 0xa000, 0xec70, 0x3480, 0xa000, 0x5514, 0x3ae1 }, 16, 0x000a7ea0, 1},
+ {{0xd6a0, 0x3607, 0xa100, 0x6c90, 0x4514, 0x3883, 0xa000, 0x4114, 0x23e0, 0x8fff, 0x92c3, 0x5297, 0x92c3, 0xdd82, 0x92c3, 0x4397 }, 16, 0x000a7ec0, 1},
+ {{0x3680, 0xa000, 0xecec, 0x5213, 0x3680, 0xa000, 0xec68, 0x5712, 0x3880, 0xa100, 0x6f2b, 0x5314, 0xecec, 0x3880, 0xa000, 0x71f6 }, 16, 0x000a7ee0, 1},
+ {{0x5697, 0xec72, 0x96c0, 0x8029, 0x0916, 0xa020, 0x3600, 0xa100, 0x4697, 0xeeec, 0x3680, 0xa100, 0x5514, 0xee6a, 0x3b1e, 0x8fff }, 16, 0x000a7f00, 1},
+ {{0x3a80, 0xa000, 0x4616, 0x3164, 0x3f62, 0x800a, 0x3480, 0xa000, 0xebec, 0x3480, 0xa000, 0xeb6a, 0x3480, 0xa000, 0x5313, 0x39e1 }, 16, 0x000a7f20, 1},
+ {{0xd5a0, 0x3607, 0xa100, 0x6c90, 0x4313, 0x3a83, 0xa000, 0x4113, 0x32f8, 0x3fff, 0xbfdf, 0x92c3, 0x5397, 0x92c3, 0xdd03, 0x92c3 }, 16, 0x000a7f40, 1},
+ {{0x4297, 0x3680, 0xa000, 0xe9ec, 0x5312, 0x3600, 0xa100, 0x5613, 0xe97c, 0x3600, 0xa100, 0x6d8e, 0x5511, 0x72f3, 0x90c0, 0x92c3 }, 16, 0x000a7f60, 1},
+ {{0x5397, 0x94c3, 0x0903, 0xa800, 0x92c3, 0x4397, 0x1397, 0x51d1, 0x9ac0, 0x371e, 0x9000, 0x7ce4, 0x370d, 0x8010, 0x6769, 0x8427 }, 16, 0x000a7f80, 1},
+ {{0x26e9, 0xeaec, 0x94c0, 0xea78, 0x8421, 0x5112, 0x3751, 0x78e1, 0x676c, 0x96c0, 0x8425, 0x0903, 0xa400, 0x0112, 0x3064, 0x3fd6 }, 16, 0x000a7fa0, 1},
+ {{0x800a, 0x4397, 0x9ac0, 0x331a, 0x8fff, 0xeaec, 0x0903, 0xa400, 0xea78, 0x4212, 0x4397, 0x1296, 0xee44, 0x96c0, 0x3509, 0x8002 }, 16, 0x000a7fc0, 1},
+ {{0x5796, 0x96c0, 0x64e9, 0x3f1a, 0x8004, 0x848b, 0x96c0, 0x6569, 0x3f1d, 0x8008, 0x8481, 0x26e9, 0xee44, 0x94c0, 0x5296, 0x847b }, 16, 0x000a7fe0, 1},
+ {{0x96c0, 0x351d, 0x8002, 0x5397, 0x96c0, 0x66e9, 0x371f, 0x8002, 0x8465, 0x98c0, 0x67e9, 0x375a, 0x8000, 0xebec, 0x94c0, 0xeb76 }, 16, 0x000a8000, 1},
+ {{0x8459, 0x2569, 0x5e13, 0xce4a, 0x94c0, 0x7d41, 0x804e, 0x3578, 0x9e00, 0x371a, 0x8800, 0x96c0, 0x6569, 0x379a, 0x8000, 0x842f }, 16, 0x000a8020, 1},
+ {{0x98c0, 0x6569, 0x371f, 0x8400, 0xd41c, 0x8423, 0x67e9, 0x90c0, 0x92c3, 0xec74, 0x92c3, 0x5114, 0x92c3, 0x68b1, 0x92c3, 0x7cef }, 16, 0x000a8040, 1},
+ {{0x98c0, 0xd059, 0x3084, 0x2076, 0x800a, 0x7470, 0x2c10, 0x3184, 0x2076, 0x800a, 0x6c10, 0x3ac0, 0xb800, 0x77d2, 0x7751, 0xcf40 }, 16, 0x000a8060, 1},
+ {{0xeee8, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x3321, 0x3758, 0x8009, 0xc4a4, 0x6980, 0x94c0, 0xc843 }, 16, 0x000a8080, 1},
+ {{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x2468, 0x74d0, 0x842e, 0x92c3, 0xc0ff, 0x96c0, 0x64e9, 0xd211 }, 16, 0x000a80a0, 1},
+ {{0xc283, 0x96c6, 0x7a61, 0x6c10, 0x8021, 0xd011, 0x3105, 0x801e, 0x2d89, 0x7ec3, 0x7473, 0x6c7c, 0xd49c, 0x64e5, 0x3318, 0x8007 }, 16, 0x000a80c0, 1},
+ {{0xdc1d, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x7651, 0x94c0, 0x6c7d, 0x9f70, 0x7454, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a80e0, 1},
+ {{0x7071, 0x94c0, 0xd0d8, 0x9f70, 0x7471, 0x90c0, 0x90c0, 0x90c0, 0x76d0, 0x94c0, 0x6d7c, 0x9f70, 0x7455, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a8100, 1},
+ {{0x7071, 0x94c0, 0xd059, 0x9f70, 0x7470, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x6d10, 0x6c10, 0xc48f, 0xc3ff, 0x0222, 0x37c4, 0x8009 }, 16, 0x000a8120, 1},
+ {{0x0422, 0x37d0, 0x8009, 0x98c0, 0x0322, 0x37cc, 0x8009, 0x9f70, 0x0022, 0x37c8, 0x8009, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a8140, 1},
+ {{0x3a00, 0xa008, 0x7751, 0x7750, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x94c0, 0xc281, 0xe748, 0x3c40, 0xa000, 0x6e7c, 0xf641 }, 16, 0x000a8160, 1},
+ {{0x3284, 0x20b0, 0x800a, 0x7456, 0x35d0, 0x2f90, 0x2e90, 0x3656, 0x3f60, 0x2a30, 0x8008, 0x3640, 0xa000, 0x7de3, 0xf6c1, 0x3600 }, 16, 0x000a8180, 1},
+ {{0xb000, 0x79ee, 0x7456, 0x96c0, 0x3701, 0x800b, 0x6f7c, 0x2d7c, 0xd71f, 0x6cbb, 0xd619, 0xd61f, 0x7a61, 0x7e41, 0xce44, 0x90c0 }, 16, 0x000a81a0, 1},
+ {{0xee1f, 0x1416, 0xce41, 0x69b6, 0x65e6, 0xd599, 0x65e4, 0x9ac0, 0x377d, 0x9fff, 0x90c0, 0x379b, 0x8000, 0x25e9, 0x6935, 0x94c7 }, 16, 0x000a81c0, 1},
+ {{0x6566, 0x7e4f, 0x92c3, 0xd544, 0x3542, 0x8000, 0x7d6f, 0x75f2, 0x6b2e, 0x6766, 0xd719, 0x6764, 0x3d7c, 0x9fff, 0x96c0, 0x3d9c }, 16, 0x000a81e0, 1},
+ {{0x8000, 0x6b28, 0x2669, 0x6766, 0x92c3, 0x7d4f, 0x92c3, 0xd742, 0x3d46, 0x8000, 0x3284, 0x20b0, 0x800a, 0x7f6f, 0x3a20, 0xa000 }, 16, 0x000a8200, 1},
+ {{0x7650, 0x6c10, 0xf6c1, 0xf391, 0x3e63, 0xce49, 0x7a6e, 0x6c7c, 0x3600, 0xa004, 0xd71c, 0x6664, 0x3800, 0xa200, 0x3900, 0x800f }, 16, 0x000a8220, 1},
+ {{0x7576, 0x2f33, 0x682a, 0x6768, 0x94c6, 0xd741, 0xd41e, 0x94c6, 0x8024, 0xd419, 0x92c2, 0xd41f, 0x6768, 0x96c6, 0xd747, 0xd41e }, 16, 0x000a8240, 1},
+ {{0x8018, 0x92c2, 0xd41f, 0x6768, 0x94c1, 0x6764, 0xd41e, 0x92c3, 0xd416, 0x2461, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621 }, 16, 0x000a8260, 1},
+ {{0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x1099, 0xe748 }, 16, 0x000a8280, 1},
+ {{0x98c0, 0xefe8, 0x32a4, 0x2970, 0x800a, 0x94c0, 0xc18d, 0xeee9, 0x96c0, 0x77d0, 0xe9ee, 0xc18d, 0x3fc8, 0x5099, 0x27e5, 0xeee9 }, 16, 0x000a82a0, 1},
+ {{0x3fc8, 0x32a4, 0x2970, 0x800a, 0x77df, 0x98c0, 0x7c48, 0xd99f, 0xe8ef, 0xe9ee, 0x98c0, 0x6465, 0x6975, 0x2600, 0x807f, 0x3c48 }, 16, 0x000a82c0, 1},
+ {{0x4298, 0x7458, 0xd998, 0x6875, 0xf041, 0x1099, 0xc18d, 0x32a4, 0x2970, 0x800a, 0x94c0, 0xeee9, 0xefe8, 0x96c0, 0x77d0, 0xe9ee }, 16, 0x000a82e0, 1},
+ {{0xc18d, 0x3fc8, 0x5099, 0x27e5, 0xeee9, 0x3fc8, 0x32a4, 0x2970, 0x800a, 0x77df, 0x9ac0, 0x7c48, 0xda1f, 0x7b61, 0xe8ef, 0xe9ee }, 16, 0x000a8300, 1},
+ {{0x2465, 0x2ab4, 0x676a, 0x7c48, 0x7458, 0xdb98, 0x69f7, 0x94c0, 0x6ccd, 0x81bc, 0x4198, 0x94c0, 0xf0c1, 0xe768, 0x94c0, 0x9e21 }, 16, 0x000a8320, 1},
+ {{0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f70, 0x4090, 0x90c0, 0x90c0, 0x3a00, 0xa008, 0x7556, 0x7457, 0x5090, 0x5151, 0x98c0, 0x6374 }, 16, 0x000a8340, 1},
+ {{0x9342, 0x2b03, 0x8020, 0x3880, 0xa100, 0x6f74, 0xe8ee, 0xe9ef, 0x4698, 0x3480, 0xa000, 0xeee8, 0xe844, 0xebe8, 0x109b, 0x5151 }, 16, 0x000a8360, 1},
+ {{0x92d0, 0x6274, 0x6e74, 0x4498, 0x96c0, 0x9346, 0x2b03, 0x800a, 0xe942, 0x1151, 0x5090, 0x63f4, 0x6ff4, 0x4798, 0x1151, 0x5090 }, 16, 0x000a8380, 1},
+ {{0x6374, 0x6f74, 0x4698, 0x1151, 0x5090, 0x62f4, 0x6ef4, 0x4598, 0x1090, 0x5159, 0x92d0, 0x6274, 0x6e74, 0x4498, 0x96c0, 0x9346 }, 16, 0x000a83a0, 1},
+ {{0x2b03, 0x800a, 0xeae8, 0x109a, 0x5151, 0x92d0, 0x6374, 0x6f74, 0x4698, 0x96c0, 0x9346, 0x2b03, 0x800e, 0x94c0, 0xe942, 0xeae8 }, 16, 0x000a83c0, 1},
+ {{0x109a, 0x5151, 0x92d0, 0x6274, 0x6e74, 0x4498, 0x96c0, 0x9346, 0x2b03, 0x800e, 0x94c0, 0xe942, 0xebe8, 0x109b, 0x5151, 0x92d0 }, 16, 0x000a83e0, 1},
+ {{0x61f4, 0x6df4, 0x4398, 0x96c0, 0x9348, 0x2b03, 0x800e, 0x94c0, 0xe942, 0xede8, 0x109d, 0x5151, 0x92d0, 0x62f4, 0x6ef4, 0x4598 }, 16, 0x000a8400, 1},
+ {{0x96c0, 0x9348, 0x2b03, 0x8010, 0x96c0, 0xe942, 0xefe8, 0x90c0, 0x109f, 0x5151, 0x92d0, 0x6374, 0x6f74, 0x4698, 0x96c0, 0x934a }, 16, 0x000a8420, 1},
+ {{0x2b03, 0x800e, 0x94c0, 0xe942, 0xede8, 0x109d, 0x5151, 0x92d0, 0x61f4, 0x6df4, 0x4398, 0x96c0, 0x934c, 0x2b03, 0x800e, 0x94c0 }, 16, 0x000a8440, 1},
+ {{0xe942, 0xece8, 0x109c, 0x5151, 0x92d0, 0x6274, 0x6e74, 0x4498, 0x96c0, 0x934e, 0x2b03, 0x8010, 0x96c0, 0xe942, 0xefe8, 0x90c0 }, 16, 0x000a8460, 1},
+ {{0x109f, 0x5151, 0x92d0, 0x6274, 0x6e74, 0x4498, 0x96c0, 0x934e, 0x2b03, 0x800e, 0x94c0, 0xe942, 0xebe8, 0x109b, 0x5151, 0x92d0 }, 16, 0x000a8480, 1},
+ {{0x6374, 0x6f74, 0x4698, 0x96c0, 0x9350, 0x2b03, 0x800e, 0x94c0, 0xe942, 0xece8, 0x109c, 0x5151, 0x92d0, 0x6274, 0x6e74, 0x4498 }, 16, 0x000a84a0, 1},
+ {{0x96c0, 0x9352, 0x2b03, 0x8010, 0x96c0, 0xe942, 0xede8, 0x90c0, 0x109d, 0x5151, 0x92d0, 0x62f4, 0x6ef4, 0x4598, 0x96c0, 0x9356 }, 16, 0x000a84c0, 1},
+ {{0x2b03, 0x800e, 0x94c0, 0xe942, 0xece8, 0x109c, 0x5151, 0x92d0, 0x62f4, 0x6ef4, 0x4598, 0x96c0, 0x9358, 0x2b03, 0x800e, 0x94c0 }, 16, 0x000a84e0, 1},
+ {{0xe942, 0xeee8, 0x109e, 0x5151, 0x92d0, 0x6374, 0x6f74, 0x4698, 0x96c0, 0x935e, 0x2b03, 0x8010, 0x96c0, 0xe942, 0xede8, 0x90c0 }, 16, 0x000a8500, 1},
+ {{0x109d, 0x5151, 0x92d0, 0x6374, 0x6f74, 0x4698, 0x96c0, 0x9362, 0x2b03, 0x800e, 0x94c0, 0xe942, 0xeee8, 0x109e, 0x5151, 0x92d0 }, 16, 0x000a8520, 1},
+ {{0x6274, 0x6e74, 0x4498, 0x3800, 0xa100, 0x7752, 0x5096, 0x5151, 0x3860, 0xa000, 0x63f4, 0xefe9, 0xeee8, 0x94c0, 0x6ff4, 0x9f70 }, 16, 0x000a8540, 1},
+ {{0x3600, 0xa900, 0x77d0, 0x4796, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0xc56b, 0x1005, 0xa004, 0x90c0, 0x3c20, 0xa000, 0x6c10, 0x3a20 }, 16, 0x000a8560, 1},
+ {{0x37d4, 0x8009, 0x5298, 0x96c0, 0x9354, 0x2b03, 0x803e, 0x559a, 0x3c00, 0xa060, 0x3a41, 0x8005, 0x90c0, 0x3644, 0x8005, 0x3a20 }, 16, 0x000a8580, 1},
+ {{0xa040, 0x3841, 0x8005, 0x5298, 0x559a, 0x3800, 0xa080, 0xd911, 0x3a41, 0x8005, 0x3c00, 0xa060, 0x3644, 0x8005, 0xd544, 0x3841 }, 16, 0x000a85a0, 1},
+ {{0x8005, 0x6561, 0x3a30, 0xa000, 0x74d2, 0xd911, 0x5698, 0x559a, 0x3e00, 0xa060, 0x3ac1, 0x8005, 0xd544, 0x36c4, 0x8005, 0x6c51 }, 16, 0x000a85c0, 1},
+ {{0x3800, 0xa040, 0x38c1, 0x8005, 0x6561, 0x36d2, 0xd911, 0x2c41, 0xd544, 0x6561, 0x6c52, 0x6465, 0xc563, 0x90c0, 0x90c0, 0x9f71 }, 16, 0x000a85e0, 1},
+ {{0x3600, 0xa00c, 0x75d7, 0x7456, 0x3420, 0xa000, 0xc56a, 0x1005, 0xa004, 0x90c0, 0x96c0, 0x9347, 0x2b03, 0x800a, 0xc781, 0x5198 }, 16, 0x000a8600, 1},
+ {{0x5298, 0x6cd8, 0x92d0, 0xd49f, 0x64e5, 0x4199, 0x96c0, 0x9243, 0x2a03, 0x8012, 0x3660, 0xa000, 0xc682, 0xc184, 0xc185, 0x5698 }, 16, 0x000a8620, 1},
+ {{0x5098, 0x2ec2, 0x5298, 0x6c49, 0x3750, 0x36d0, 0x7550, 0x3800, 0xb800, 0xd71e, 0xd699, 0xd519, 0x6f22, 0x6e9a, 0x6e89, 0x92d0 }, 16, 0x000a8640, 1},
+ {{0xd69f, 0x66e5, 0x4599, 0x5698, 0x94c0, 0x5098, 0x9742, 0x2f42, 0x5298, 0x2d4a, 0x5398, 0x6e5d, 0x3400, 0xa800, 0xd61e, 0x6665 }, 16, 0x000a8660, 1},
+ {{0x4499, 0x5498, 0x5098, 0x2d40, 0x5398, 0x2c5d, 0x5698, 0x6ec2, 0x3400, 0xa800, 0xd69e, 0x66e5, 0x4599, 0x5298, 0x5098, 0x36d0 }, 16, 0x000a8680, 1},
+ {{0x5098, 0x96c8, 0x6d49, 0x76d0, 0x5098, 0x94c0, 0x6d49, 0x9743, 0x6d52, 0x3752, 0x3452, 0x7652, 0x3800, 0xb000, 0xd71f, 0xd419 }, 16, 0x000a86a0, 1},
+ {{0xd619, 0x6d2a, 0x6f12, 0x6e16, 0xd61f, 0x6665, 0x4499, 0x5098, 0x5698, 0x35d6, 0x5698, 0x96c8, 0x6c53, 0x75d6, 0x5698, 0x94c0 }, 16, 0x000a86c0, 1},
+ {{0x6c53, 0x9744, 0x6c42, 0x3750, 0x3550, 0x7650, 0x3800, 0xb800, 0xd71e, 0xd519, 0x7e66, 0x6c22, 0x6f32, 0x6e16, 0x3400, 0xa800 }, 16, 0x000a86e0, 1},
+ {{0xd61e, 0x6665, 0x4499, 0x5498, 0x5698, 0x36d6, 0x5698, 0x96c8, 0x6e55, 0x76d6, 0x5698, 0x94c0, 0x6e55, 0x9744, 0x2e56, 0xc683 }, 16, 0x000a8700, 1},
+ {{0x36d4, 0x35d4, 0x7454, 0x3800, 0xaa00, 0xd69e, 0x7de3, 0xd419, 0x6eb5, 0x6d8d, 0x6c13, 0x3400, 0xa800, 0xd41e, 0x6465, 0x4099 }, 16, 0x000a8720, 1},
+ {{0x5098, 0x5498, 0x36d4, 0x5498, 0x96c8, 0x6c41, 0x76d4, 0x5498, 0x94c0, 0x6c41, 0x9745, 0x6c40, 0x36d0, 0x3650, 0x75d0, 0x3800 }, 16, 0x000a8740, 1},
+ {{0xaa00, 0xd69e, 0xd61e, 0xd599, 0x6d21, 0x6c28, 0x6db3, 0x3400, 0xa800, 0xd59e, 0x65e5, 0x4399, 0x5098, 0x5598, 0x35d5, 0x5598 }, 16, 0x000a8760, 1},
+ {{0x96c8, 0x6c53, 0x75d5, 0x5598, 0x94c0, 0x6c53, 0x9746, 0x6c41, 0xd41e, 0x6465, 0x4099, 0x5498, 0x5398, 0x3553, 0x5398, 0x96c8 }, 16, 0x000a8780, 1},
+ {{0x6e48, 0x7553, 0x5398, 0x94c0, 0x6e48, 0x9748, 0x2e4c, 0xc287, 0x35d4, 0x36d4, 0x7454, 0x3800, 0xb000, 0xd59f, 0xd699, 0x7c67 }, 16, 0x000a87a0, 1},
+ {{0x6d8c, 0x6ead, 0x6c41, 0x3400, 0xa800, 0xd41e, 0x6465, 0x4099, 0x5498, 0x5398, 0x36d3, 0x5398, 0x96c8, 0x6e55, 0x76d3, 0x5398 }, 16, 0x000a87c0, 1},
+ {{0x94c0, 0x6e55, 0x9749, 0x6e4c, 0x7454, 0x3550, 0x35d0, 0xd41a, 0x94c0, 0xd51f, 0xd59e, 0x6d08, 0x6ebd, 0x6c01, 0x3400, 0xa800 }, 16, 0x000a87e0, 1},
+ {{0xd41e, 0x6465, 0x4099, 0x5498, 0x5298, 0x3452, 0x5298, 0x96c8, 0x6e40, 0x7452, 0x5298, 0x94c0, 0x6e40, 0x974c, 0x6e48, 0x35d4 }, 16, 0x000a8800, 1},
+ {{0x3554, 0x7454, 0x3800, 0xb800, 0xd59e, 0xd519, 0xd419, 0x6d8c, 0x6d9d, 0x6d93, 0xd59e, 0x65e5, 0x4399, 0x5498, 0x5098, 0x36d0 }, 16, 0x000a8820, 1},
+ {{0x5098, 0x96c8, 0x6e55, 0x76d0, 0x5098, 0x94c0, 0x6e55, 0x974e, 0x2e40, 0xc389, 0x3454, 0x3554, 0x76d4, 0x96c0, 0xd41f, 0xd519 }, 16, 0x000a8840, 1},
+ {{0x7ee9, 0x6e00, 0x6e48, 0x6ed5, 0xd69e, 0x66e5, 0x4599, 0x5498, 0x5098, 0x34d0, 0x5098, 0x96c8, 0x6e44, 0x74d0, 0x5098, 0x6e44 }, 16, 0x000a8860, 1},
+ {{0x6e40, 0x3554, 0x3454, 0x74d4, 0x3800, 0xa800, 0xd519, 0xd41b, 0x7cea, 0x6e88, 0x6f41, 0x6dc6, 0x3400, 0xa800, 0xd599, 0x65e5 }, 16, 0x000a8880, 1},
+ {{0x4391, 0x3420, 0xa000, 0xc562, 0x90c0, 0x90c0, 0x9f70, 0x3600, 0xb800, 0x7750, 0x77d3, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a88a0, 1},
+ {{0x3c00, 0xa108, 0x75d6, 0x7457, 0x5191, 0x2908, 0x8004, 0x96c0, 0x4190, 0x2304, 0x807f, 0x3c00, 0xa100, 0x2b03, 0x805a, 0x90c0 }, 16, 0x000a88c0, 1},
+ {{0x280f, 0x8400, 0x3680, 0xa100, 0x5190, 0xebef, 0x3880, 0xa000, 0xeaee, 0x280c, 0x8008, 0x9ac0, 0x280f, 0x8408, 0x90c0, 0x280d }, 16, 0x000a88e0, 1},
+ {{0x840c, 0x3680, 0xa000, 0x4197, 0xe84c, 0x3c00, 0xa100, 0x290a, 0x8008, 0x90c0, 0x2909, 0x800c, 0x9ac0, 0x290e, 0x87f8, 0x90c0 }, 16, 0x000a8900, 1},
+ {{0x290b, 0x87fc, 0x9ac0, 0x2ae2, 0x9ffe, 0x90c0, 0x2b02, 0x8002, 0x1496, 0x5292, 0x6f48, 0x76c6, 0x45bc, 0x11b6, 0x52ba, 0x6eb8 }, 16, 0x000a8920, 1},
+ {{0x7545, 0x42bd, 0x3680, 0xa000, 0x5791, 0x5593, 0x6f9b, 0x7447, 0x40b8, 0x3680, 0xa000, 0x57b9, 0x54b3, 0x92d0, 0x6fd7, 0x74c7 }, 16, 0x000a8940, 1},
+ {{0x41bf, 0x3a40, 0xa200, 0x2e00, 0x83fc, 0x77d0, 0xeaef, 0x38c0, 0xa000, 0xef44, 0x2809, 0x83fc, 0x1599, 0xea3e, 0x3640, 0xa000 }, 16, 0x000a8960, 1},
+ {{0x4592, 0xefeb, 0x3640, 0xa000, 0x5691, 0xeeea, 0x9f70, 0x3600, 0xa100, 0x7753, 0x4697, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a8980, 1},
+ {{0x3e80, 0xa004, 0x74d7, 0x6f90, 0x6c90, 0xfcc3, 0x2808, 0x8004, 0x3c00, 0xa001, 0x2304, 0x807f, 0x7456, 0x2b03, 0x8070, 0x3800 }, 16, 0x000a89a0, 1},
+ {{0xa100, 0x5294, 0x2c0e, 0x8004, 0x3800, 0xa100, 0x4290, 0x290d, 0x8004, 0x3680, 0xa100, 0x4790, 0xeaef, 0x3680, 0xa100, 0x5396 }, 16, 0x000a89c0, 1},
+ {{0xe9ee, 0x96c0, 0x4391, 0x290e, 0x8008, 0x9ac0, 0x280d, 0x8008, 0x90c0, 0x2c0f, 0x8008, 0x9ac0, 0x2c0b, 0x87fc, 0x90c0, 0x2c0a }, 16, 0x000a89e0, 1},
+ {{0x800c, 0x3680, 0xa000, 0x4195, 0xe84c, 0x96c0, 0xe94c, 0x2c0c, 0x87f8, 0x9cc0, 0x2ae2, 0x9ffe, 0x90c0, 0x2b02, 0x8002, 0x90c0 }, 16, 0x000a8a00, 1},
+ {{0x1397, 0x5194, 0x6ed9, 0x75c5, 0x43bd, 0x16b4, 0x51bf, 0x6c06, 0x76c0, 0x45b9, 0x1493, 0x5092, 0x6e20, 0x7444, 0x40b8, 0x13ba }, 16, 0x000a8a20, 1},
+ {{0x52b3, 0x92d0, 0x6e5d, 0x7444, 0x40be, 0x3e60, 0xa000, 0x6d10, 0x2e09, 0x83fc, 0x6f10, 0x280a, 0x83fc, 0x3a20, 0xa800, 0x77d1 }, 16, 0x000a8a40, 1},
+ {{0x5599, 0x2d0d, 0x83fc, 0x3640, 0xa000, 0x459a, 0xefea, 0x3640, 0xa000, 0x4292, 0xeee9, 0x5091, 0x94c0, 0x409d, 0x9f70, 0x3600 }, 16, 0x000a8a60, 1},
+ {{0xa800, 0x7750, 0x4695, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x3c00, 0xa10c, 0x74d7, 0x7456, 0x5791, 0x290b, 0x8400, 0x96c0 }, 16, 0x000a8a80, 1},
+ {{0x4790, 0x2304, 0x807f, 0x3c00, 0xa100, 0x2b03, 0x805a, 0x90c0, 0x2808, 0x8004, 0x3680, 0xa100, 0x5593, 0xeaef, 0x3880, 0xa000 }, 16, 0x000a8aa0, 1},
+ {{0xe9ee, 0x280b, 0x8008, 0x3c00, 0xa100, 0x280f, 0x87f8, 0x90c0, 0x280c, 0x87fc, 0x3880, 0xa000, 0x4590, 0x290c, 0x8008, 0x96c0 }, 16, 0x000a8ac0, 1},
+ {{0xe84c, 0x290d, 0x800c, 0x9ac0, 0x290e, 0x8408, 0x90c0, 0x290a, 0x840c, 0x9cc0, 0x2ae2, 0x9ffe, 0x90c0, 0x2b02, 0x8002, 0x90c0 }, 16, 0x000a8ae0, 1},
+ {{0x1096, 0x5695, 0x6e22, 0x3480, 0xa000, 0x44b4, 0x1394, 0x5492, 0x6ecc, 0x45b7, 0x13bc, 0x51ba, 0x6e99, 0x45bb, 0x94d0, 0x52be }, 16, 0x000a8b00, 1},
+ {{0x50bd, 0x6dd2, 0x43b8, 0x3c20, 0xac00, 0x7750, 0x2a00, 0x83fc, 0x77d1, 0xedeb, 0x38c0, 0xa000, 0xeb44, 0x280e, 0x83fc, 0x3640 }, 16, 0x000a8b20, 1},
+ {{0xa000, 0xed3a, 0xefea, 0x5195, 0x419e, 0x3480, 0xa000, 0x5493, 0x94c0, 0x4496, 0x9f70, 0x3420, 0xa000, 0xeee9, 0x90c0, 0x90c0 }, 16, 0x000a8b40, 1},
+ {{0x3550, 0x3451, 0x03fc, 0x9ff6, 0x9ac0, 0xda9b, 0x6275, 0x3181, 0x2000, 0x8000, 0x34f9, 0x6e75, 0x6ea5, 0xd895, 0x61f4, 0x94c0 }, 16, 0x000a8b60, 1},
+ {{0x6df4, 0x9f70, 0x6c4c, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x2809, 0x850c, 0x6e10, 0xcca0, 0x96c0, 0x5891, 0x290a }, 16, 0x000a8b80, 1},
+ {{0x8084, 0x98c0, 0x3b20, 0x383a, 0x8009, 0x9347, 0x96c0, 0x4198, 0x2b03, 0x8034, 0x98c0, 0xea88, 0x30e8, 0x3fff, 0xbfff, 0x985a }, 16, 0x000a8ba0, 1},
+ {{0x92c3, 0xcca0, 0x90c0, 0x92c3, 0xe83c, 0x4891, 0x1298, 0x534b, 0x20f5, 0xea88, 0x94c0, 0x6cf5, 0x985a, 0xd641, 0x92c3, 0xe83c }, 16, 0x000a8bc0, 1},
+ {{0x2c7d, 0x1298, 0x534b, 0x20f5, 0xea88, 0x94d0, 0x6cf5, 0x985a, 0xd641, 0x92c3, 0xe83c, 0x94c0, 0x6c7d, 0x9f70, 0x7454, 0x90c0 }, 16, 0x000a8be0, 1},
+ {{0x98c0, 0x2808, 0x850c, 0x6d10, 0x9748, 0x280c, 0x8064, 0x4c90, 0x92c8, 0x429c, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a8c00, 1},
+ {{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x94c0, 0xe750, 0xc596, 0x9cc0, 0x3f60, 0x2ab8, 0x8008, 0xc782, 0x90c0, 0x90c0 }, 16, 0x000a8c20, 1},
+ {{0x96c0, 0x6f10, 0xc485, 0xf941, 0x96c0, 0xce44, 0xf542, 0x90c0, 0x3284, 0x2110, 0x800a, 0x2c90, 0x3457, 0xf843, 0x3284, 0x20f0 }, 16, 0x000a8c40, 1},
+ {{0x800a, 0xc195, 0x96c0, 0x7be1, 0xcc40, 0xf8c3, 0x111f, 0xce4b, 0x39e1, 0xecfc, 0x96c0, 0x65ea, 0xec18, 0xce43, 0x5214, 0x6a38 }, 16, 0x000a8c60, 1},
+ {{0x94c0, 0x7e6f, 0x81d0, 0xd744, 0x98c0, 0x7446, 0x7bc6, 0xf5c2, 0xf9c1, 0x3ae1, 0xef6a, 0x26ea, 0x4019, 0x81a7, 0xe770, 0x94c0 }, 16, 0x000a8c80, 1},
+ {{0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x3880, 0xa100, 0xe8e8, 0x280a, 0x8590, 0x94c0, 0x9620, 0x9720 }, 16, 0x000a8ca0, 1},
+ {{0x3480, 0xa000, 0x56d2, 0x98c0, 0x3d1d, 0x8001, 0x9e20, 0x9f20, 0x96c0, 0x66e9, 0x270e, 0x8130, 0x96c0, 0xe7ee, 0x2518, 0x9bd6 }, 16, 0x000a8cc0, 1},
+ {{0x32c4, 0x20c0, 0x800a, 0x3660, 0xa000, 0xf845, 0xfa46, 0x3620, 0xa000, 0xfac6, 0xcf84, 0x3640, 0xa000, 0xff47, 0xf8c5, 0x36a0 }, 16, 0x000a8ce0, 1},
+ {{0xa000, 0x2a0e, 0x9e38, 0x3a80, 0xa000, 0x5cd6, 0x3e20, 0x3c48, 0x8009, 0x90c0, 0xec8f, 0x96c0, 0xecfe, 0x2518, 0x9b98, 0x98c0 }, 16, 0x000a8d00, 1},
+ {{0x6e90, 0xec1e, 0x2502, 0x9600, 0x3640, 0xa000, 0x5f94, 0xeeee, 0x3a20, 0xa000, 0xee3d, 0x31c1, 0x2000, 0x800c, 0x94c0, 0xedee }, 16, 0x000a8d20, 1},
+ {{0x9f61, 0x96c0, 0xffc7, 0x2304, 0x8080, 0x9ac0, 0x2b03, 0x8026, 0x90c0, 0x2000, 0x8080, 0x98c0, 0xef1e, 0x0142, 0x2e78, 0x8009 }, 16, 0x000a8d40, 1},
+ {{0x94c0, 0xff47, 0xc684, 0x98c0, 0x2b02, 0x8002, 0x90c0, 0x90c0, 0x9ac0, 0x7ad0, 0x0b46, 0x2e78, 0x8009, 0xca45, 0x3b50, 0xcc46 }, 16, 0x000a8d60, 1},
+ {{0xeb1a, 0x5493, 0x44bd, 0x0946, 0x2e78, 0x8009, 0x90c0, 0x92d0, 0xe91c, 0x5491, 0x44bf, 0x96c0, 0x9b40, 0x2b03, 0x802a, 0x3c60 }, 16, 0x000a8d80, 1},
+ {{0xa000, 0x280b, 0x91cc, 0x90c0, 0x280a, 0x91c8, 0x94c0, 0xc08c, 0xc288, 0x9cc0, 0x2b02, 0x8002, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a8da0, 1},
+ {{0x9ac0, 0x7950, 0xc942, 0x0c46, 0x2e78, 0x8009, 0x3850, 0xc840, 0xec19, 0x5794, 0x47ba, 0x0946, 0x2e78, 0x8009, 0x90c0, 0x92d0 }, 16, 0x000a8dc0, 1},
+ {{0xe918, 0x5391, 0x43bb, 0x3820, 0xa000, 0xe8ee, 0x2d00, 0x9e00, 0x3640, 0xa000, 0xe9ee, 0xfe49, 0x98c0, 0xe83d, 0x3284, 0x28c0 }, 16, 0x000a8de0, 1},
+ {{0x800a, 0xf848, 0x98c0, 0xfe41, 0x3920, 0x3840, 0x8009, 0x3284, 0x29a0, 0x800a, 0x38e0, 0x3a00, 0x800b, 0x3a40, 0xa000, 0x3ae8 }, 16, 0x000a8e00, 1},
+ {{0x3c28, 0xbfff, 0xf8c5, 0x3a40, 0xa000, 0x33a1, 0x2000, 0x8000, 0xfec9, 0x347b, 0x1192, 0x3ce8, 0x3c28, 0xbfff, 0x33bb, 0x8000 }, 16, 0x000a8e20, 1},
+ {{0x7063, 0x800d, 0x5294, 0x35be, 0x8000, 0x7066, 0x85f9, 0x9ac0, 0x2304, 0x8080, 0x6f10, 0x2b03, 0x8032, 0x98c0, 0x31c1, 0x3000 }, 16, 0x000a8e40, 1},
+ {{0x800c, 0xffc7, 0x98c0, 0x0142, 0x2e78, 0x8009, 0xc784, 0x96c0, 0xe9ee, 0x2500, 0x8080, 0x98c0, 0x2b02, 0x8002, 0x90c0, 0x90c0 }, 16, 0x000a8e60, 1},
+ {{0x9ac0, 0x7b50, 0x0b46, 0x2e78, 0x8009, 0xcd46, 0x3bd0, 0xc847, 0xeb1d, 0x5493, 0x44b9, 0x0c46, 0x2e78, 0x8009, 0x90c0, 0x92d0 }, 16, 0x000a8e80, 1},
+ {{0xec18, 0x5494, 0x44bf, 0x96c0, 0x9b45, 0x2b03, 0x802a, 0x3c60, 0xa000, 0x2808, 0x91cc, 0x90c0, 0x280c, 0x91c8, 0x94c0, 0xc38c }, 16, 0x000a8ea0, 1},
+ {{0xc688, 0x9cc0, 0x2b02, 0x8002, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x9ac0, 0x7b50, 0xcf46, 0x0d46, 0x2e78, 0x8009, 0x39d0, 0xc943 }, 16, 0x000a8ec0, 1},
+ {{0xed1f, 0x5495, 0x44bc, 0x0f46, 0x2e78, 0x8009, 0x90c0, 0x92d0, 0xef19, 0x5197, 0x41b8, 0x3820, 0xa000, 0xe8ee, 0x2a00, 0x8e00 }, 16, 0x000a8ee0, 1},
+ {{0x98c0, 0xe9ee, 0x3284, 0x28c0, 0x800a, 0xe83a, 0x98c0, 0x33e2, 0x3e08, 0x800b, 0xfe41, 0x90c0, 0x3860, 0xa000, 0xe8eb, 0x2b0f }, 16, 0x000a8f00, 1},
+ {{0x8408, 0x3284, 0x29a0, 0x800a, 0xe9ef, 0x3a20, 0xa000, 0xf8c5, 0x3900, 0x2618, 0x800c, 0x3264, 0x2bd0, 0x800b, 0x3a20, 0xa000 }, 16, 0x000a8f20, 1},
+ {{0xf841, 0x38e0, 0x3a00, 0x800b, 0x3820, 0xa000, 0xfec9, 0x2702, 0x9dfc, 0x9ac0, 0x2304, 0x8080, 0x90c0, 0x2b03, 0x802e, 0x3a20 }, 16, 0x000a8f40, 1},
+ {{0xa000, 0xeaee, 0x3900, 0x2618, 0x800c, 0x3820, 0xa000, 0xea3f, 0x2b02, 0x8002, 0x98c0, 0x3b00, 0x261c, 0x800c, 0xfa4a, 0xf8c8 }, 16, 0x000a8f60, 1},
+ {{0x52b9, 0x92d0, 0x42b8, 0x57bb, 0x47ba, 0x98c0, 0x3502, 0x2a18, 0x800c, 0xfaca, 0xf9c8, 0x3480, 0xa000, 0x5095, 0x0092, 0x3284 }, 16, 0x000a8f80, 1},
+ {{0x2290, 0x800a, 0x0846, 0x2e74, 0x8009, 0x3820, 0xa000, 0xfec9, 0x2b00, 0x9a00, 0x3820, 0xa000, 0x0f46, 0x2e74, 0x8009, 0x3420 }, 16, 0x000a8fa0, 1},
+ {{0xa000, 0xe9ee, 0x3840, 0xa000, 0xe93b, 0x2f08, 0x8204, 0x3284, 0x2290, 0x800a, 0xf94b, 0x0946, 0x2e74, 0x8009, 0x32a4, 0x20e0 }, 16, 0x000a8fc0, 1},
+ {{0x800b, 0x3840, 0x3508, 0x8009, 0x0a46, 0x2e74, 0x8009, 0x3840, 0x2eb0, 0x8009, 0x32a4, 0x20e0, 0x800b, 0x2a09, 0x8204, 0x0846 }, 16, 0x000a8fe0, 1},
+ {{0x2e74, 0x8009, 0x3284, 0x2600, 0x800a, 0x2809, 0x8810, 0x0d46, 0x2e74, 0x8009, 0x90c0, 0x2d08, 0x8204, 0x3284, 0x2600, 0x800a }, 16, 0x000a9000, 1},
+ {{0x2809, 0x8664, 0x3820, 0xa000, 0xffcb, 0x2c00, 0x8510, 0x96c0, 0xc581, 0x2402, 0x8520, 0x3660, 0xa000, 0xe9ef, 0xfec9, 0x36c0 }, 16, 0x000a9020, 1},
+ {{0xa000, 0xef3c, 0xe93c, 0x3680, 0xa000, 0x5217, 0x54d1, 0x3a60, 0xa000, 0xd692, 0x6d10, 0xf8c5, 0xfac6, 0x98c0, 0x66e1, 0xf94c }, 16, 0x000a9040, 1},
+ {{0x2b00, 0x9e04, 0x3a40, 0xa000, 0x72f4, 0xedee, 0x2600, 0x83e8, 0x96c0, 0x8467, 0x2a00, 0x808c, 0x96c0, 0xed3b, 0x2b03, 0x802e }, 16, 0x000a9060, 1},
+ {{0x94c0, 0x4695, 0x9356, 0x3a40, 0xa000, 0x0b46, 0x2e74, 0x8009, 0xedea, 0x96c0, 0xed3a, 0x2560, 0x9fff, 0x3820, 0xa000, 0xeae8 }, 16, 0x000a9080, 1},
+ {{0x2b0b, 0x89a4, 0x4693, 0x3942, 0x1415, 0xcb42, 0x449a, 0x0846, 0x2e74, 0x8009, 0x90c0, 0x280f, 0x89d4, 0xef1b, 0x4517, 0x0f46 }, 16, 0x000a90a0, 1},
+ {{0x2e74, 0x8009, 0x90c0, 0x94d0, 0x2f0f, 0x8944, 0xef1b, 0x4517, 0x31a4, 0x22e4, 0x800a, 0x9ac0, 0x2a00, 0x808c, 0x7265, 0x2900 }, 16, 0x000a90c0, 1},
+ {{0x80d2, 0x3620, 0xa000, 0xedea, 0x8487, 0x3620, 0xa000, 0xecea, 0xed3a, 0x94c0, 0xec39, 0xc696, 0x3c60, 0xa000, 0x2809, 0x818c }, 16, 0x000a90e0, 1},
+ {{0x90c0, 0x280b, 0x80dc, 0x3860, 0xa000, 0xeae8, 0x2808, 0x823c, 0x3620, 0xa000, 0xff4d, 0xcd4f, 0x96c0, 0xfc4e, 0x90c0, 0x90c0 }, 16, 0x000a9100, 1},
+ {{0x96c0, 0x6c10, 0xcc47, 0xf851, 0x94c0, 0xfb4f, 0xf950, 0x1114, 0xfcce, 0x419a, 0x14d4, 0xfa52, 0x3284, 0x2b60, 0x800a, 0xf401 }, 16, 0x000a9120, 1},
+ {{0x96c0, 0x7b61, 0xf8d1, 0xf9d0, 0x96c0, 0x676a, 0xfbcf, 0xfad2, 0x4098, 0x94c0, 0x4099, 0x81ce, 0x409b, 0x3660, 0xa000, 0xf8c5 }, 16, 0x000a9140, 1},
+ {{0xfac6, 0x3420, 0xa000, 0xffcd, 0x9ac0, 0x6e10, 0x0b46, 0x2e74, 0x8009, 0x9356, 0x9ac0, 0x2b03, 0x801c, 0x90c0, 0x2101, 0x85d1 }, 16, 0x000a9160, 1},
+ {{0x9ac0, 0x2b09, 0x89a4, 0x90c0, 0x2d00, 0x8194, 0x92c0, 0x4491, 0x9ac0, 0x7a44, 0x0a46, 0x2e74, 0x8009, 0xcc44, 0x90c0, 0x2a0b }, 16, 0x000a9180, 1},
+ {{0x89a4, 0x1293, 0xe9eb, 0xe93d, 0xe91c, 0x5091, 0x62f4, 0x92d0, 0x6ef4, 0x6ec9, 0x4593, 0x9ac0, 0x6c10, 0x0b46, 0x2e74, 0x8009 }, 16, 0x000a91a0, 1},
+ {{0x9356, 0x3820, 0xa000, 0xe9e8, 0x2b03, 0x8010, 0x2b0b, 0x89a0, 0x4093, 0x1099, 0x0a46, 0x2e74, 0x8009, 0x6274, 0x96c0, 0x6e74 }, 16, 0x000a91c0, 1},
+ {{0x2a0a, 0x89a0, 0x92d0, 0x5292, 0x6ec8, 0x4592, 0x3a40, 0xa000, 0x2402, 0x84b4, 0x6f10, 0xebea, 0x3820, 0xa000, 0xe9ea, 0x2c00 }, 16, 0x000a91e0, 1},
+ {{0x80d2, 0x3660, 0xa000, 0xeb3c, 0xe8ea, 0x96c0, 0xe83c, 0x2402, 0x808c, 0x94c0, 0xc796, 0xfb53, 0x3660, 0xa000, 0xe93c, 0xff4d }, 16, 0x000a9200, 1},
+ {{0xf954, 0x98c0, 0x0c46, 0x2e74, 0x8009, 0xca46, 0x14d0, 0x5093, 0x96c0, 0xf401, 0x2c09, 0x8810, 0x94c0, 0xe91a, 0xfb55, 0x3284 }, 16, 0x000a9220, 1},
+ {{0x2b60, 0x800a, 0x1191, 0xf856, 0x9ac0, 0x7650, 0x7be1, 0x7b44, 0xfdd4, 0xfbd5, 0x27ea, 0xf8d6, 0x5015, 0x94c0, 0x6c7c, 0x81c8 }, 16, 0x000a9240, 1},
+ {{0x449b, 0x3a40, 0xa000, 0x6e90, 0xfac6, 0x2800, 0x845c, 0x3820, 0xa000, 0xf8c5, 0x2102, 0x80d0, 0x3620, 0xa000, 0xedea, 0xc396 }, 16, 0x000a9260, 1},
+ {{0x3640, 0xa000, 0xed38, 0xeaea, 0x3620, 0xa000, 0xece8, 0xebed, 0x94c0, 0xf357, 0xf558, 0x3640, 0xa000, 0xf9d3, 0xea39, 0xfd59 }, 16, 0x000a9280, 1},
+ {{0x3c20, 0xa000, 0x6c90, 0x0846, 0x2e74, 0x8009, 0xf9d8, 0x3620, 0xa000, 0x5c94, 0xfb5a, 0x96c0, 0xfa5b, 0x2808, 0x8810, 0x3620 }, 16, 0x000a92a0, 1},
+ {{0xa000, 0xe819, 0xf95c, 0x1890, 0xfc5d, 0x90c0, 0x3a20, 0xa000, 0xe83c, 0x3284, 0x2110, 0x800a, 0xc848, 0x96c0, 0x74d0, 0xfadb }, 16, 0x000a92c0, 1},
+ {{0xfbda, 0x90c0, 0x14d2, 0x5093, 0x3284, 0x2b60, 0x800a, 0xf401, 0x3a20, 0xa000, 0x0946, 0x2e74, 0x8009, 0xf8d8, 0x94c0, 0xf9dc }, 16, 0x000a92e0, 1},
+ {{0xfcdd, 0x3840, 0xa100, 0xc686, 0x290c, 0x88ec, 0x3680, 0xa000, 0xec18, 0xf601, 0x3680, 0xa000, 0x4094, 0xc84e, 0x1099, 0x5194 }, 16, 0x000a9300, 1},
+ {{0x3284, 0x2160, 0x800a, 0xf95c, 0x3c40, 0xa000, 0x7550, 0x0946, 0x2e74, 0x8009, 0xc846, 0x94c0, 0xfcdd, 0xc08f, 0x3840, 0xa100 }, 16, 0x000a9320, 1},
+ {{0xf001, 0x290c, 0x88ec, 0x3680, 0xa000, 0xec18, 0x539c, 0x3a80, 0xa000, 0x5094, 0x3680, 0x2000, 0x8000, 0x96c0, 0xd5c0, 0x6e7d }, 16, 0x000a9340, 1},
+ {{0xfc5d, 0x98c0, 0xf343, 0x3284, 0x2160, 0x800a, 0xf1c3, 0x35d0, 0x3780, 0x2000, 0x8000, 0x6f7d, 0x7677, 0x6836, 0x6466, 0x3c6f }, 16, 0x000a9360, 1},
+ {{0x3284, 0x2110, 0x800a, 0x6c90, 0x96c0, 0xd43f, 0xfbda, 0xfadb, 0x8040, 0x94c0, 0xf9dc, 0xfcdd, 0x3c41, 0x3860, 0x2d20, 0x8008 }, 16, 0x000a9380, 1},
+ {{0xc450, 0x90c0, 0x3480, 0xa000, 0xec18, 0x3480, 0xa000, 0x5314, 0x9ac0, 0x34e4, 0x8003, 0x90c0, 0x36e6, 0x8003, 0x30e4, 0x8003 }, 16, 0x000a93a0, 1},
+ {{0xd814, 0x98c0, 0xd446, 0x3084, 0x3410, 0x800a, 0x30cf, 0x950c, 0x96c0, 0x3610, 0x80ef, 0x7c64, 0x96c0, 0x3105, 0x801d, 0x8039 }, 16, 0x000a93c0, 1},
+ {{0x3ec1, 0x3860, 0x2d20, 0x8008, 0xc155, 0x90c0, 0x3480, 0xa000, 0xe918, 0x3480, 0xa000, 0x5511, 0x9ac0, 0x34e4, 0x8005, 0x90c0 }, 16, 0x000a93e0, 1},
+ {{0x36e6, 0x8005, 0x30e4, 0x8005, 0xda14, 0xd646, 0x38cf, 0x950c, 0x96c0, 0x67e6, 0xf0d7, 0xf3d8, 0x3861, 0x39c4, 0x479b, 0x96c0 }, 16, 0x000a9400, 1},
+ {{0x646a, 0xf358, 0xf057, 0x2dff, 0x9e7b, 0x3a40, 0xa000, 0x6f10, 0xfac6, 0x2a00, 0x8090, 0x3620, 0xa000, 0xf8c5, 0xfdd9, 0x3620 }, 16, 0x000a9420, 1},
+ {{0xa000, 0xecea, 0xc796, 0x3640, 0xa000, 0xec3a, 0xe8e8, 0x96c0, 0x51d4, 0x2a00, 0x807e, 0x3a40, 0xa000, 0x331c, 0x8002, 0xebed }, 16, 0x000a9440, 1},
+ {{0xe9ea, 0x2669, 0xe93a, 0x2518, 0x8226, 0x3284, 0x2c00, 0x800a, 0xfc5e, 0x3c20, 0xa000, 0x6c90, 0x0b46, 0x2e74, 0x8009, 0xf8c5 }, 16, 0x000a9460, 1},
+ {{0x90c0, 0x3880, 0xa000, 0x5990, 0x2b0a, 0x8810, 0x5b92, 0x90c0, 0x98c0, 0xeb39, 0x3284, 0x2110, 0x800a, 0xcb48, 0x3640, 0xa000 }, 16, 0x000a9480, 1},
+ {{0x74d0, 0xf8c5, 0x3284, 0x2b90, 0x800a, 0x3420, 0xa000, 0xe8e8, 0x3c40, 0xa000, 0x6c90, 0xfac6, 0x0b46, 0x2e74, 0x8009, 0x2900 }, 16, 0x000a94a0, 1},
+ {{0x858c, 0x3820, 0xa000, 0xeaea, 0x2b0b, 0x8814, 0x1b93, 0xea39, 0x5a92, 0x90c0, 0x98c0, 0xeb3a, 0x3284, 0x2110, 0x800a, 0xcb48 }, 16, 0x000a94c0, 1},
+ {{0x3640, 0xa000, 0x74d0, 0xf8c5, 0x3284, 0x2b90, 0x800a, 0x3420, 0xa000, 0xe8e8, 0x3c20, 0xa000, 0x6e10, 0x6f90, 0xfac6, 0x2a00 }, 16, 0x000a94e0, 1},
+ {{0x807e, 0x3620, 0xa000, 0xf8c5, 0xfdd9, 0x3620, 0xa000, 0xe9ea, 0xc388, 0x94c0, 0xe93a, 0xf460, 0x3640, 0xa100, 0xf35f, 0xece8 }, 16, 0x000a9500, 1},
+ {{0x3600, 0xa100, 0xc696, 0xe9ed, 0x98c0, 0x3b40, 0x2e80, 0x8009, 0xfe61, 0x3c40, 0xa000, 0xff62, 0x280a, 0x8008, 0x90c0, 0x90c0 }, 16, 0x000a9520, 1},
+ {{0x3e20, 0xa000, 0xd7b3, 0x6c90, 0x0e46, 0x2e74, 0x8009, 0x5f92, 0x94c0, 0xf8df, 0x8051, 0x3860, 0xa100, 0xf963, 0x2e0b, 0x8810 }, 16, 0x000a9540, 1},
+ {{0x3680, 0xa000, 0xeb18, 0xfb64, 0x3680, 0xa000, 0x5893, 0xfa65, 0xeee9, 0x98c0, 0xe83f, 0x3284, 0x2110, 0x800a, 0x3640, 0xa000 }, 16, 0x000a9560, 1},
+ {{0xc848, 0xefec, 0x3620, 0xa000, 0xf8c5, 0xe9ee, 0x36c0, 0xa000, 0xecef, 0xf9e3, 0x3084, 0x35a2, 0x800a, 0x94c0, 0xfbe4, 0xfae5 }, 16, 0x000a9580, 1},
+ {{0x6c10, 0x3860, 0xa000, 0x74d0, 0xe8e8, 0xf963, 0x94c0, 0xfb64, 0xfa65, 0x3284, 0x2b90, 0x800a, 0x3640, 0xa000, 0xeee9, 0xefec }, 16, 0x000a95a0, 1},
+ {{0x94c0, 0xfbe4, 0xfcde, 0x3680, 0xa000, 0xecef, 0xc289, 0x115b, 0x53d4, 0x3c00, 0xa100, 0x6274, 0x371b, 0x800f, 0x559c, 0xf201 }, 16, 0x000a95c0, 1},
+ {{0x3c20, 0xa000, 0x6e74, 0x7de2, 0x74d5, 0xfb64, 0xefec, 0xd613, 0x98c0, 0xf444, 0x32c4, 0x33c0, 0x800a, 0xf0c4, 0x3840, 0xa000 }, 16, 0x000a95e0, 1},
+ {{0x7c46, 0xf9e3, 0xe9ee, 0x5111, 0x3480, 0xa000, 0x5599, 0x3640, 0xa000, 0xd445, 0xf963, 0x2461, 0x3284, 0x2110, 0x800a, 0x6466 }, 16, 0x000a9600, 1},
+ {{0x3284, 0x2100, 0x800a, 0x2160, 0x9fff, 0x98c0, 0x7b61, 0x7bc1, 0xe9ee, 0xf4e0, 0x9cc0, 0x676a, 0x7a42, 0x0e46, 0x2e74, 0x8009 }, 16, 0x000a9620, 1},
+ {{0xc844, 0x94c0, 0xfae5, 0xf2df, 0x3a80, 0xa100, 0x2e0e, 0x8944, 0x7944, 0xecef, 0x3680, 0xa000, 0xee18, 0xfbe4, 0x3620, 0xa000 }, 16, 0x000a9640, 1},
+ {{0xf9e3, 0xea44, 0x3620, 0xa000, 0xf8c5, 0xf25f, 0x2cff, 0x9ed5, 0x3600, 0xa100, 0xf460, 0x4016, 0x3620, 0xa000, 0xfac6, 0xfee1 }, 16, 0x000a9660, 1},
+ {{0x3084, 0x36d4, 0x800a, 0x94c0, 0xffe2, 0xfdd9, 0x109b, 0x5111, 0x3284, 0x2110, 0x800a, 0x96c0, 0x6466, 0xf966, 0xfb67, 0x3284 }, 16, 0x000a9680, 1},
+ {{0x2100, 0x800a, 0x2160, 0x9fff, 0x9cc0, 0x7be1, 0x7b42, 0x0846, 0x2e74, 0x8009, 0xca46, 0x96c0, 0x67ea, 0xf9e6, 0xfbe7, 0x280c }, 16, 0x000a96a0, 1},
+ {{0x8944, 0x94c0, 0xec1a, 0x81ca, 0x4014, 0x3660, 0xa000, 0xf8c5, 0xfac6, 0xfdd9, 0x9ac0, 0x6f10, 0x6f90, 0x9356, 0x2b03, 0x8010 }, 16, 0x000a96c0, 1},
+ {{0x2a00, 0x8134, 0x9ac0, 0x7bc2, 0x0b46, 0x2e74, 0x8009, 0xc947, 0x3b44, 0xc846, 0x2b0c, 0x8944, 0xe91c, 0x1111, 0xec3a, 0x2a74 }, 16, 0x000a96e0, 1},
+ {{0xec18, 0x3e6f, 0x5094, 0xd894, 0x92d0, 0x62f4, 0x6ef4, 0x459d, 0x3820, 0xa000, 0xebea, 0x2a00, 0x80ec, 0x3c60, 0xa000, 0x280c }, 16, 0x000a9700, 1},
+ {{0x823c, 0x90c0, 0x280d, 0x818c, 0xeb3a, 0x14d3, 0xfb68, 0x6669, 0x94c0, 0xfbd3, 0x8425, 0x98c0, 0x9356, 0x2b03, 0x800a, 0x90c0 }, 16, 0x000a9720, 1},
+ {{0x1093, 0x5495, 0x6c7d, 0x92d0, 0x449c, 0x569b, 0x469d, 0x3184, 0x3782, 0x800a, 0x96c0, 0x9356, 0x2b03, 0x801c, 0x3840, 0xa000 }, 16, 0x000a9740, 1},
+ {{0xfdd3, 0x280c, 0x823c, 0x3820, 0xa000, 0x280b, 0x818c, 0x90c0, 0x1495, 0x5093, 0x6c7d, 0x449b, 0x94d0, 0x5094, 0x549d, 0x6c7d }, 16, 0x000a9760, 1},
+ {{0x449c, 0x9ac0, 0x2900, 0x82fc, 0x90c0, 0x2d00, 0x80ea, 0x3820, 0xa000, 0xebea, 0x2c00, 0x83ac, 0x36a0, 0xa000, 0xe9ea, 0xeb3d }, 16, 0x000a9780, 1},
+ {{0x3620, 0xa100, 0xeaea, 0xe939, 0x94c0, 0xfb69, 0xea3c, 0x94c0, 0xc796, 0xf8d3, 0x3a20, 0xa000, 0xf96a, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000a97a0, 1},
+ {{0x3640, 0xa000, 0x5098, 0xf96b, 0x3284, 0x20b0, 0x800a, 0x94c0, 0xf86c, 0xca4e, 0x96c0, 0x7be1, 0xca46, 0xfce9, 0x3620, 0xa000 }, 16, 0x000a97c0, 1},
+ {{0xf9eb, 0xf8ec, 0x1492, 0x52d4, 0x2569, 0x6c7d, 0x90c0, 0x98c1, 0x7774, 0xedea, 0x90c0, 0x74f4, 0x3647, 0xa000, 0x4692, 0x9d59 }, 16, 0x000a97e0, 1},
+ {{0x3681, 0xa100, 0x4191, 0x5491, 0x94c7, 0xea44, 0x6c7d, 0x3880, 0xa000, 0xd05c, 0x67ea, 0xe944, 0x94c0, 0x76f0, 0x81a8, 0x4595 }, 16, 0x000a9800, 1},
+ {{0x3a40, 0xa000, 0x0b46, 0x2e74, 0x8009, 0xfec9, 0x3a40, 0xa000, 0x33e2, 0x3e08, 0x800b, 0xf8c5, 0x3820, 0xa000, 0xe9ee, 0x2102 }, 16, 0x000a9820, 1},
+ {{0x9e0c, 0x2b0b, 0x89a4, 0x3640, 0xa000, 0x5493, 0xe939, 0x4499, 0x0b46, 0x2e74, 0x8009, 0x90c0, 0x2b0b, 0x89a0, 0x1393, 0x3ba0 }, 16, 0x000a9840, 1},
+ {{0x3074, 0x8009, 0x4391, 0x1293, 0x03a6, 0x3070, 0x8009, 0x9ac0, 0x370b, 0x8020, 0x90c0, 0x350a, 0x8001, 0x65e9, 0x8407, 0x6569 }, 16, 0x000a9860, 1},
+ {{0x8415, 0x3ba0, 0x3074, 0x8009, 0x37f8, 0x3fff, 0xbbff, 0x5593, 0xdf85, 0x4793, 0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x2b0b, 0x81c0 }, 16, 0x000a9880, 1},
+ {{0x96c0, 0x5213, 0x2b09, 0x8100, 0x98c0, 0x355b, 0x8000, 0xcb82, 0x5911, 0x65e9, 0x96c0, 0xe961, 0x2718, 0x8106, 0xe98b, 0x96c0 }, 16, 0x000a98a0, 1},
+ {{0xe9fe, 0x2518, 0x80fc, 0x98c0, 0x3b20, 0x3c5c, 0x8009, 0xe8ef, 0x90c0, 0xe91b, 0x1b91, 0x0946, 0x2e74, 0x8009, 0x90c0, 0x96c0 }, 16, 0x000a98c0, 1},
+ {{0x9b61, 0x2909, 0x8944, 0x2f0b, 0x8004, 0x3800, 0xa100, 0xcb4e, 0x2b09, 0x83fc, 0x3a80, 0xa000, 0x5791, 0x3284, 0x2350, 0x800a }, 16, 0x000a98e0, 1},
+ {{0x0793, 0xc15f, 0x96c0, 0x6c90, 0xcb46, 0xc157, 0x33e2, 0x3e08, 0x800b, 0x1393, 0x4193, 0x3480, 0xa000, 0x4399, 0x3480, 0xa000 }, 16, 0x000a9900, 1},
+ {{0x4191, 0x3820, 0xa000, 0xe8eb, 0x2b00, 0x8404, 0x0946, 0x2e74, 0x8009, 0xef3b, 0x9ac0, 0x2f0b, 0x83fc, 0x90c0, 0x2909, 0x8944 }, 16, 0x000a9920, 1},
+ {{0x1493, 0xcb4e, 0x3284, 0x2350, 0x800a, 0x4497, 0x2c10, 0x1697, 0xcb46, 0x9ac0, 0x2900, 0x840c, 0x90c0, 0x2402, 0x8808, 0x069b }, 16, 0x000a9940, 1},
+ {{0x4097, 0x3ac0, 0xa000, 0xebeb, 0x0946, 0x2e74, 0x8009, 0x3680, 0xa000, 0xeb39, 0xefeb, 0x36c0, 0xa000, 0x5293, 0xef3c, 0x3840 }, 16, 0x000a9960, 1},
+ {{0xa000, 0x4093, 0x2909, 0x8944, 0x0297, 0x38e0, 0x3a00, 0x800b, 0x3284, 0x2350, 0x800a, 0x94c0, 0xcb4e, 0xc35f, 0x96c0, 0x6c10 }, 16, 0x000a9980, 1},
+ {{0xcb46, 0xc357, 0x96c0, 0x5497, 0x2900, 0x8408, 0x3620, 0xa100, 0xf8c5, 0x4493, 0x0097, 0xeb39, 0x4093, 0x3c40, 0xa000, 0x6f90 }, 16, 0x000a99a0, 1},
+ {{0xf842, 0x3900, 0x2618, 0x800c, 0x3264, 0x2b60, 0x800b, 0x98c0, 0xf741, 0x38e0, 0x3a00, 0x800b, 0x9ac0, 0x2304, 0x8080, 0x90c0 }, 16, 0x000a99c0, 1},
+ {{0x2b03, 0x8036, 0x3a40, 0xa000, 0x3b00, 0x2618, 0x800c, 0xf8c5, 0x3660, 0xa000, 0xfac6, 0xfec9, 0x3a40, 0xa000, 0x3502, 0x2a18 }, 16, 0x000a99e0, 1},
+ {{0x800c, 0xffcd, 0x96c0, 0xffca, 0x2b02, 0x8002, 0xf9c8, 0x559b, 0x92d0, 0x45b9, 0x559b, 0x45bf, 0x3600, 0xa100, 0xfaca, 0x5695 }, 16, 0x000a9a00, 1},
+ {{0x94c0, 0xf9cc, 0xc081, 0x3840, 0xa000, 0x4692, 0x280d, 0x839c, 0x3680, 0xa000, 0x5717, 0x51d1, 0x3c60, 0xa000, 0x280a, 0x83f4 }, 16, 0x000a9a20, 1},
+ {{0xd417, 0x280b, 0x82ec, 0x3840, 0xa000, 0x6461, 0x2809, 0x844c, 0x30f0, 0x6c90, 0x8015, 0x96c0, 0x9356, 0x2b03, 0x8008, 0x4199 }, 16, 0x000a9a40, 1},
+ {{0x92d0, 0x419b, 0x419d, 0x419a, 0x3e00, 0xa006, 0x6c10, 0x2d00, 0x80c8, 0x6f10, 0x2502, 0x9e04, 0x9ac0, 0x2702, 0x9e36, 0x90c0 }, 16, 0x000a9a60, 1},
+ {{0x2a00, 0x80d6, 0x36e0, 0xa000, 0xecea, 0xefee, 0x3880, 0xa000, 0xec3d, 0x2800, 0x80ce, 0x3660, 0xa000, 0xef3d, 0xebea, 0x38a0 }, 16, 0x000a9a80, 1},
+ {{0xa000, 0xedea, 0x2d00, 0x8144, 0x3600, 0xa100, 0xeb3a, 0xed38, 0x3820, 0xa000, 0xeaea, 0x2800, 0x80c6, 0x3640, 0xa000, 0xea3d }, 16, 0x000a9aa0, 1},
+ {{0xecea, 0x3820, 0xa000, 0xe9ee, 0x2d00, 0x80cc, 0x3660, 0xa100, 0xe93f, 0xe9ea, 0x96c0, 0xec38, 0x2702, 0x80e4, 0x3680, 0xa000 }, 16, 0x000a9ac0, 1},
+ {{0xe93d, 0xfc6f, 0x3820, 0xa000, 0xfc6e, 0x2402, 0x80b0, 0x13d1, 0xc4ef, 0x3840, 0xa000, 0xde03, 0xecea, 0xedef, 0x3660, 0xa000 }, 16, 0x000a9ae0, 1},
+ {{0xec3f, 0xed3c, 0x3660, 0xa000, 0xf970, 0xfd6d, 0x3860, 0xa100, 0xc396, 0x280b, 0x82ec, 0x3640, 0xa000, 0x4411, 0xffd3, 0x3ce0 }, 16, 0x000a9b00, 1},
+ {{0xa100, 0x280d, 0x8344, 0x90c0, 0x280c, 0x83f4, 0x3840, 0xa100, 0xfe61, 0x2809, 0x839c, 0xff71, 0x3600, 0xa100, 0xffed, 0xce40 }, 16, 0x000a9b20, 1},
+ {{0x3680, 0xa000, 0x5093, 0xf972, 0x11d7, 0x0f46, 0x2e74, 0x8009, 0x3640, 0xa000, 0xf101, 0xf373, 0x96c0, 0xfb74, 0x2f0f, 0x8868 }, 16, 0x000a9b40, 1},
+ {{0x94c0, 0xef1e, 0xfa75, 0x1197, 0xfc76, 0x3640, 0xa000, 0xfd77, 0xf678, 0x3660, 0xa000, 0xf079, 0xfd7a, 0x3660, 0xa000, 0xff7b }, 16, 0x000a9b60, 1},
+ {{0xfc7c, 0x3284, 0x2b60, 0x800a, 0x3660, 0xa000, 0xf97d, 0xfb7e, 0xfbf4, 0x3284, 0x2110, 0x800a, 0x5113, 0x3a40, 0xa000, 0x31e8 }, 16, 0x000a9b80, 1},
+ {{0x3fff, 0xbfff, 0xfbfe, 0x3860, 0xa000, 0x7651, 0xf9fd, 0xfcfc, 0x96c0, 0x6c7d, 0xffee, 0xf9f2, 0x3800, 0xa100, 0x74d4, 0x4493 }, 16, 0x000a9ba0, 1},
+ {{0xfaf5, 0x3680, 0xa000, 0x5591, 0xfbf4, 0x96c0, 0x6d7d, 0xc688, 0xc18f, 0x3480, 0xa000, 0x4591, 0x3680, 0xa100, 0x5494, 0x5093 }, 16, 0x000a9bc0, 1},
+ {{0x6c7d, 0x3480, 0xa000, 0x4494, 0x3600, 0xa100, 0x50d7, 0x5393, 0x12d1, 0xd610, 0x327b, 0xdf1a, 0x8055, 0x0611, 0x0902, 0xa018 }, 16, 0x000a9be0, 1},
+ {{0x0211, 0xf101, 0x3a00, 0xa100, 0x0f46, 0x2e74, 0x8009, 0x5193, 0x90c0, 0x2f0f, 0x88ec, 0x98c0, 0xef1e, 0x3284, 0x2160, 0x800a }, 16, 0x000a9c00, 1},
+ {{0x5097, 0x96c0, 0x74d0, 0xffef, 0xfaf5, 0x90c0, 0x13d7, 0x5092, 0x3284, 0x2b60, 0x800a, 0xf301, 0x94c0, 0xfaf5, 0xfbf4, 0x3a20 }, 16, 0x000a9c20, 1},
+ {{0xa000, 0xfbfe, 0x3084, 0x3c52, 0x800a, 0x4092, 0xc6f7, 0xdf02, 0x4611, 0x3880, 0xa000, 0x6f10, 0x5792, 0x5493, 0x27e9, 0x5113 }, 16, 0x000a9c40, 1},
+ {{0x92c2, 0x6d10, 0x94c7, 0x559a, 0x5092, 0x96c7, 0x66e0, 0xd190, 0xfa75, 0x94c3, 0x3702, 0x801e, 0x796e, 0x6e7c, 0xd68e, 0xda95 }, 16, 0x000a9c60, 1},
+ {{0x2076, 0x3284, 0x2110, 0x800a, 0x6c76, 0x9ac0, 0x7650, 0xf9f2, 0x0f46, 0x2e74, 0x8009, 0x3c40, 0xa000, 0xd616, 0xfffb, 0x30e8 }, 16, 0x000a9c80, 1},
+ {{0x3fff, 0xbfff, 0x2661, 0x17d1, 0xc586, 0x9cc0, 0x2f0f, 0x899c, 0x6666, 0x3f1a, 0x8008, 0xf501, 0x2569, 0x6c7d, 0x92c2, 0x6e10 }, 16, 0x000a9ca0, 1},
+ {{0x4497, 0x3a00, 0xa100, 0x0f46, 0x2e74, 0x8009, 0x509f, 0x3420, 0xa000, 0xff7b, 0x2f0f, 0x899c, 0x3284, 0x2160, 0x800a, 0x5197 }, 16, 0x000a9cc0, 1},
+ {{0x3e20, 0xa000, 0x7550, 0x6c90, 0x0a46, 0x2e74, 0x8009, 0xefee, 0x3880, 0xa000, 0xeeee, 0x2002, 0x8058, 0x36a0, 0xa000, 0x2a0a }, 16, 0x000a9ce0, 1},
+ {{0x8868, 0x3a20, 0xa000, 0xef1a, 0x3680, 0x2000, 0x8000, 0x3640, 0xa100, 0x6e7d, 0xea38, 0x3480, 0xa000, 0xea1e, 0x3480, 0xa000 }, 16, 0x000a9d00, 1},
+ {{0x5392, 0x4397, 0x0f46, 0x2e74, 0x8009, 0x90c0, 0x2f0f, 0x8868, 0x3480, 0xa000, 0xee1f, 0x38a0, 0xa000, 0x5a96, 0x2f0f, 0x8134 }, 16, 0x000a9d20, 1},
+ {{0x5f97, 0x90c0, 0x3a80, 0xa000, 0xea3f, 0x3284, 0x2110, 0x800a, 0xc258, 0x3820, 0xa000, 0x74d0, 0xfff0, 0xfdfa, 0x90c0, 0x3600 }, 16, 0x000a9d40, 1},
+ {{0xa100, 0x53d7, 0x5095, 0x3284, 0x2b60, 0x800a, 0xf301, 0xfbf4, 0x3284, 0x2110, 0x800a, 0x5113, 0x98c0, 0x0f46, 0x2e74, 0x8009 }, 16, 0x000a9d60, 1},
+ {{0xc48f, 0xf401, 0x2f0f, 0x899c, 0x5597, 0xd6c0, 0x98c0, 0xf543, 0x3284, 0x2160, 0x800a, 0xf1c3, 0x37d0, 0x3380, 0x2000, 0x8000 }, 16, 0x000a9d80, 1},
+ {{0x6f7d, 0x7477, 0x6822, 0x6466, 0x3c6f, 0x3284, 0x2110, 0x800a, 0x6c90, 0x98c0, 0xd43f, 0x3f60, 0x2d20, 0x8008, 0x94c7, 0x8037 }, 16, 0x000a9da0, 1},
+ {{0x7c41, 0xc250, 0x90c0, 0x3480, 0xa000, 0xea1f, 0x3480, 0xa000, 0x5612, 0x9ac0, 0x34e4, 0x8006, 0x90c0, 0x36e5, 0x8006, 0x30e4 }, 16, 0x000a9dc0, 1},
+ {{0x8006, 0xda14, 0x98c0, 0xd645, 0x3084, 0x3e32, 0x800a, 0x38cf, 0x950c, 0x96c0, 0x3610, 0x80ef, 0x7c64, 0x96c0, 0x3102, 0x801d }, 16, 0x000a9de0, 1},
+ {{0x8039, 0x3d41, 0x3f60, 0x2d20, 0x8008, 0xc252, 0x90c0, 0x3480, 0xa000, 0xea1f, 0x3480, 0xa000, 0x5312, 0x9ac0, 0x34e0, 0x8003 }, 16, 0x000a9e00, 1},
+ {{0x90c0, 0x36e6, 0x8003, 0x30e0, 0x8003, 0xd810, 0xd446, 0x30cf, 0x950c, 0x96c0, 0x67e6, 0x2160, 0x9fff, 0x3284, 0x20f0, 0x800a }, 16, 0x000a9e20, 1},
+ {{0x7457, 0x94c0, 0xfcf6, 0xfff1, 0x98c0, 0x34e8, 0x3fff, 0xbfff, 0xc18f, 0x0014, 0xf101, 0x1097, 0x0f46, 0x2e74, 0x8009, 0x7c41 }, 16, 0x000a9e40, 1},
+ {{0x96c0, 0x6461, 0x2f0f, 0x89a0, 0x2c7d, 0x1097, 0x32c4, 0x33c0, 0x800a, 0x74d4, 0x3284, 0x20f0, 0x800a, 0x2160, 0x9fff, 0xfdf7 }, 16, 0x000a9e60, 1},
+ {{0x3284, 0x2110, 0x800a, 0x5115, 0xfcf6, 0x3284, 0x2120, 0x800a, 0x5114, 0x3a60, 0xa000, 0x0a46, 0x2e74, 0x8009, 0xf6f8, 0x36c0 }, 16, 0x000a9e80, 1},
+ {{0xa000, 0xcf46, 0xfdfa, 0x3860, 0xa100, 0xf9fd, 0x2a08, 0x88c0, 0x36c0, 0xa000, 0xe81f, 0xfbfe, 0x36c0, 0xa000, 0x4010, 0xfcfc }, 16, 0x000a9ea0, 1},
+ {{0x3a20, 0xa000, 0x0e46, 0x2e74, 0x8009, 0xfaf5, 0x98c0, 0x38a0, 0x3074, 0x8009, 0xfbf4, 0x3860, 0xa100, 0xf3f3, 0x2e08, 0x88c0 }, 16, 0x000a9ec0, 1},
+ {{0x3680, 0xa000, 0xe81f, 0xfcf6, 0x3680, 0xa000, 0x5210, 0xfdf7, 0x3860, 0xa000, 0x683c, 0xf0f9, 0xfffb, 0x3c6f, 0xf9f2, 0x3600 }, 16, 0x000a9ee0, 1},
+ {{0xa100, 0xd890, 0x4095, 0x3820, 0xa000, 0x0e46, 0x2e74, 0x8009, 0x90c0, 0x36a0, 0xa000, 0x2e08, 0x8868, 0x3480, 0xa000, 0xe81e }, 16, 0x000a9f00, 1},
+ {{0x3680, 0xa000, 0x5090, 0xfee8, 0x6174, 0x6d74, 0x3480, 0xa000, 0x429d, 0x56d6, 0x6769, 0x90c0, 0x3682, 0xa100, 0x5491, 0x5093 }, 16, 0x000a9f20, 1},
+ {{0x92c2, 0x6c7d, 0x3482, 0xa000, 0x4494, 0x3482, 0xa000, 0x5593, 0x3482, 0xa000, 0x4591, 0x1290, 0x04a6, 0x3070, 0x8009, 0x9ac0 }, 16, 0x000a9f40, 1},
+ {{0x350a, 0x8400, 0x90c0, 0x394f, 0x8000, 0x6569, 0x8491, 0x3c40, 0xa000, 0x67e9, 0x0a46, 0x2e74, 0x8009, 0xeeef, 0x3680, 0xa000 }, 16, 0x000a9f60, 1},
+ {{0xeeef, 0x844f, 0x3ca0, 0xa000, 0x2a0a, 0x8944, 0x90c0, 0x2002, 0x8114, 0x3420, 0xa000, 0xee1a, 0x3840, 0xa100, 0x5016, 0x2a0a }, 16, 0x000a9f80, 1},
+ {{0x8090, 0x34a0, 0xa000, 0xee1a, 0x34a0, 0xa000, 0xea38, 0x3480, 0xa000, 0xea1f, 0x3480, 0xa000, 0x5112, 0x6a31, 0x3e6f, 0x3084 }, 16, 0x000a9fa0, 1},
+ {{0x3ffc, 0x800a, 0x3480, 0xa000, 0x4416, 0x3a20, 0xa000, 0x0e46, 0x2e74, 0x8009, 0xeeef, 0x2202, 0x8090, 0x36a0, 0xa000, 0x2e0e }, 16, 0x000a9fc0, 1},
+ {{0x89d4, 0x3420, 0xa000, 0xee1e, 0x34a0, 0xa000, 0xee3a, 0x3480, 0xa000, 0xee1f, 0x3480, 0xa000, 0x5216, 0x4216, 0x3c80, 0xa10d }, 16, 0x000a9fe0, 1},
+ {{0x79e1, 0x7844, 0x7b42, 0xec44, 0xeb44, 0x3600, 0xa104, 0x65ea, 0xe944, 0x2dff, 0x9b27, 0x3640, 0xa000, 0x50d1, 0xf8c5, 0x3a20 }, 16, 0x000aa000, 1},
+ {{0xa000, 0x311f, 0x8010, 0xfac6, 0xfee1, 0x98c0, 0x67e9, 0x6f90, 0xfff1, 0xc696, 0x38a0, 0xa000, 0xebea, 0x2718, 0x8104, 0x3c40 }, 16, 0x000aa020, 1},
+ {{0xa000, 0x2502, 0x8094, 0x90c0, 0x280d, 0x84cc, 0x3860, 0xa000, 0xffd3, 0x280c, 0x823c, 0x36e0, 0xa000, 0xeb3d, 0xeae8, 0x3840 }, 16, 0x000aa040, 1},
+ {{0xa100, 0xfd7f, 0x2809, 0x8058, 0x9ac0, 0x07fa, 0x9f00, 0x90c0, 0x0cf8, 0x9efc, 0x9ac0, 0x03fa, 0x9ef8, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000aa060, 1},
+ {{0x9ac0, 0x1df8, 0x9f00, 0x90c0, 0x18f8, 0x9efc, 0xfcff, 0x109d, 0x5498, 0x2c7d, 0x2460, 0x131c, 0x0df8, 0x9f00, 0x98c0, 0xd40b }, 16, 0x000aa080, 1},
+ {{0xfc7f, 0x08f8, 0x9efc, 0x9ac0, 0x6461, 0x0c46, 0x2e74, 0x8009, 0xc847, 0x3074, 0x5092, 0x96c0, 0x8053, 0x1df8, 0x9ef8, 0x9ac0 }, 16, 0x000aa0a0, 1},
+ {{0x2c0c, 0x8810, 0x90c0, 0x01fa, 0x9ef4, 0x15d5, 0xec18, 0x1194, 0xf501, 0x3284, 0x2b60, 0x800a, 0x0af8, 0x9ef0, 0xf8d4, 0x3284 }, 16, 0x000aa0c0, 1},
+ {{0x2110, 0x800a, 0x5110, 0x9ac0, 0x1af8, 0x9ef0, 0x90c0, 0x11fa, 0x9ef4, 0x34e8, 0x3fff, 0xbfff, 0x6c7d, 0x0492, 0x30a4, 0x2118 }, 16, 0x000aa0e0, 1},
+ {{0x800a, 0x3480, 0xa000, 0x4491, 0x0d26, 0x3c68, 0x8009, 0x90c0, 0xed41, 0x0d22, 0x3c68, 0x8009, 0x3a00, 0xa100, 0x7b61, 0x7bc4 }, 16, 0x000aa100, 1},
+ {{0xea44, 0xe944, 0x676a, 0x815b, 0x3640, 0xa000, 0xf9f2, 0xf8c5, 0x3420, 0xa000, 0xfac6, 0x90c0, 0x3640, 0xa100, 0x56d1, 0xecea }, 16, 0x000aa120, 1},
+ {{0x9ac0, 0x3d1f, 0x8010, 0xc696, 0x2102, 0x8098, 0x3ca0, 0xa000, 0x67e9, 0x6f90, 0xebea, 0x2702, 0x8094, 0x3c20, 0xa000, 0x280c }, 16, 0x000aa140, 1},
+ {{0x80b0, 0x90c0, 0x2718, 0x80e0, 0x38a0, 0xa000, 0xeb3f, 0x0cf8, 0x9eec, 0x38a0, 0xa000, 0xec39, 0x03fa, 0x9ee8, 0x3420, 0xa000 }, 16, 0x000aa160, 1},
+ {{0xfbea, 0x3640, 0xa000, 0xf8d3, 0xfb6a, 0x04fa, 0x9ee4, 0x1098, 0x3284, 0x20b0, 0x800a, 0xf853, 0x3820, 0xa000, 0xfbea, 0x14fa }, 16, 0x000aa180, 1},
+ {{0x9ee4, 0x98c0, 0x0d46, 0x2e74, 0x8009, 0xc847, 0x3680, 0xa100, 0x5314, 0x549b, 0x9ac0, 0x7dc3, 0x6c7d, 0xc581, 0x2d0d, 0x8810 }, 16, 0x000aa1a0, 1},
+ {{0x2cb3, 0xed18, 0x30f4, 0x5195, 0x96c0, 0x8055, 0x1af8, 0x9eec, 0x3820, 0xa000, 0xfb6a, 0x1cf8, 0x9ee8, 0x52d2, 0x14d4, 0xd692 }, 16, 0x000aa1c0, 1},
+ {{0x94c0, 0xf543, 0xf401, 0x3284, 0x2b60, 0x800a, 0xf0c3, 0xfdd4, 0x3284, 0x2110, 0x800a, 0x5115, 0x34e8, 0x3fff, 0xbfff, 0x2c7d }, 16, 0x000aa1e0, 1},
+ {{0x3284, 0x20b0, 0x800a, 0x7454, 0x3a40, 0xa000, 0x1af8, 0x9eec, 0x74f8, 0xfbea, 0x3ce3, 0x14fa, 0x9ee4, 0x4112, 0x3b61, 0x3bc4 }, 16, 0x000aa200, 1},
+ {{0x1af8, 0x9eec, 0x676a, 0x94c0, 0xea42, 0x815c, 0x0af8, 0x9eec, 0x3640, 0xa000, 0xf9f2, 0xfac6, 0x90c0, 0x14d1, 0x0946, 0x2e74 }, 16, 0x000aa220, 1},
+ {{0x8009, 0x3ca0, 0xa000, 0x3918, 0x8004, 0xebea, 0x2102, 0x808e, 0x2469, 0x5097, 0x96c0, 0x8439, 0x2909, 0x89a4, 0x36a0, 0xa000 }, 16, 0x000aa240, 1},
+ {{0xeb39, 0x5191, 0x3a80, 0xa000, 0x52d3, 0x3284, 0x2b60, 0x800a, 0xf201, 0xfbf4, 0x3284, 0x2110, 0x800a, 0x5113, 0x3a40, 0xa000 }, 16, 0x000aa260, 1},
+ {{0x34e8, 0x3fff, 0xbfff, 0xfac6, 0x6c7d, 0x4497, 0x96c0, 0xfbe8, 0x2502, 0x80dc, 0x38a0, 0xa000, 0xebea, 0x2f00, 0x80da, 0x3640 }, 16, 0x000aa280, 1},
+ {{0xa100, 0x53d3, 0xeb3d, 0x3640, 0xa100, 0x79c1, 0xe9ea, 0x3880, 0xa000, 0x76fb, 0x4313, 0xe93f, 0x3480, 0xa000, 0x5213, 0x7175 }, 16, 0x000aa2a0, 1},
+ {{0x92c3, 0x6e10, 0x94c7, 0xfbe9, 0x4413, 0x90c0, 0x50d3, 0x7841, 0x3478, 0x4013, 0x3480, 0xa000, 0x5111, 0x70f0, 0x92c3, 0x6c10 }, 16, 0x000aa2c0, 1},
+ {{0x92c3, 0x4013, 0x96c0, 0xf9cc, 0x2160, 0x9fff, 0x90c0, 0x10d1, 0x3284, 0x20f0, 0x800a, 0x7841, 0x3820, 0xa000, 0xfac6, 0x2b00 }, 16, 0x000aa2e0, 1},
+ {{0x804e, 0xf9cc, 0x3420, 0xa000, 0xe8ea, 0x0011, 0xe83b, 0x0b46, 0x2e74, 0x8009, 0x3284, 0x2c20, 0x800a, 0x2b09, 0x8970, 0x3c20 }, 16, 0x000aa300, 1},
+ {{0xa000, 0x6f90, 0x38a0, 0x3074, 0x8009, 0xf8c5, 0x3620, 0xa000, 0xfac6, 0xc696, 0x5490, 0x390c, 0x8400, 0x6669, 0x92c0, 0x8451 }, 16, 0x000aa320, 1},
+ {{0x98c0, 0x0b46, 0x2e74, 0x8009, 0xcf47, 0x2100, 0x8147, 0x2b0b, 0x8970, 0x98c0, 0xeb1f, 0x3284, 0x2110, 0x800a, 0x5013, 0x3b61 }, 16, 0x000aa340, 1},
+ {{0x3bc2, 0x0c46, 0x2e74, 0x8009, 0x676a, 0x2c0c, 0x89d4, 0xec1f, 0x5214, 0x68b2, 0x94c0, 0x7cef, 0x81cc, 0x4114, 0x3660, 0xa000 }, 16, 0x000aa360, 1},
+ {{0xf8c5, 0xfac6, 0x38a0, 0x3074, 0x8009, 0x90c0, 0x1290, 0x04a6, 0x3070, 0x8009, 0x9ac0, 0x3908, 0x8020, 0x90c0, 0x350a, 0x8001 }, 16, 0x000aa380, 1},
+ {{0x6469, 0x2718, 0x80f8, 0x3ca0, 0xa000, 0x6e10, 0x2b00, 0x8080, 0x6569, 0xe9ea, 0x96c0, 0xc696, 0x2518, 0x80e6, 0x3880, 0xa000 }, 16, 0x000aa3a0, 1},
+ {{0xe93b, 0x04f8, 0x9ee0, 0x38c0, 0xa000, 0x57d1, 0x280f, 0x80b0, 0x14df, 0xc381, 0x9ac0, 0xd594, 0xc48f, 0x3120, 0x2400, 0x8003 }, 16, 0x000aa3c0, 1},
+ {{0x94c0, 0xf343, 0xf401, 0x32c4, 0x33c0, 0x800a, 0xf0c3, 0x3284, 0x20f0, 0x800a, 0x2160, 0x9fff, 0x98c0, 0x7570, 0x67e0, 0x2160 }, 16, 0x000aa3e0, 1},
+ {{0x9fff, 0xda12, 0x3480, 0x8007, 0x3284, 0x20f0, 0x800a, 0x7c6b, 0x3b61, 0x27e0, 0x0b46, 0x2e74, 0x8009, 0x15f8, 0x9ee0, 0x98c0 }, 16, 0x000aa400, 1},
+ {{0x7ac2, 0xc945, 0x2b0b, 0x89d4, 0x05f8, 0x9ee0, 0xeb19, 0x5413, 0x7270, 0x90c0, 0x94c6, 0x676a, 0x4013, 0x8197, 0x3c20, 0xa000 }, 16, 0x000aa420, 1},
+ {{0x6e90, 0x38a0, 0x3074, 0x8009, 0xfec9, 0x96c0, 0xf9c8, 0x2302, 0x9df8, 0x1390, 0xfaca, 0x3820, 0xa000, 0xefee, 0x0913, 0xa400 }, 16, 0x000aa440, 1},
+ {{0x96c0, 0x4390, 0x2600, 0x80fe, 0x3640, 0xa000, 0x4591, 0xef3b, 0x4592, 0x04a6, 0x3070, 0x8009, 0x390b, 0x8040, 0x65e9, 0x94c7 }, 16, 0x000aa460, 1},
+ {{0x8414, 0x6c10, 0x92c3, 0x4097, 0x33a4, 0x3240, 0x800a, 0x7c48, 0x4097, 0x3b61, 0xef44, 0x676a, 0x81db, 0x3a20, 0xa000, 0x0b46 }, 16, 0x000aa480, 1},
+ {{0x2e74, 0x8009, 0xf8c8, 0x3284, 0x2350, 0x800a, 0x3620, 0xa000, 0x2b09, 0x89d4, 0x3820, 0xa000, 0xfac6, 0x2b00, 0x8090, 0x3660 }, 16, 0x000aa4a0, 1},
+ {{0xa000, 0xf8c5, 0xfec9, 0x38a0, 0xa000, 0xe9ea, 0x2000, 0x8040, 0x38c0, 0xa000, 0xe93b, 0x280f, 0x89c0, 0x38c0, 0xa000, 0x52d1 }, 16, 0x000aa4c0, 1},
+ {{0x280b, 0x89c4, 0x3c20, 0xa000, 0x280c, 0x85d0, 0x90c0, 0x351a, 0x8001, 0x9ac0, 0x2a02, 0x8002, 0x6569, 0x2be2, 0x9ffe, 0x94c0 }, 16, 0x000aa4e0, 1},
+ {{0xf9c8, 0x8481, 0x96c0, 0xfaca, 0x2304, 0x8040, 0x96c0, 0x5391, 0x2b03, 0x8012, 0x4392, 0x3620, 0xa000, 0x280a, 0x85d4, 0x52b4 }, 16, 0x000aa500, 1},
+ {{0x42bf, 0x92d0, 0x51b2, 0x64e4, 0x41bb, 0x96c0, 0xf9cb, 0x2102, 0x99fc, 0x3640, 0xa000, 0x9b40, 0xebee, 0x96c0, 0x5091, 0x2b03 }, 16, 0x000aa520, 1},
+ {{0x8038, 0x3820, 0xa000, 0xeb39, 0x2a02, 0x8002, 0x3840, 0xa000, 0x4093, 0x2808, 0x8dc0, 0x3c60, 0xa000, 0x2809, 0x8dc4, 0x90c0 }, 16, 0x000aa540, 1},
+ {{0x280a, 0x89d4, 0x3c20, 0xa000, 0x280c, 0x89d0, 0x90c0, 0x2be2, 0x9ffe, 0x56b4, 0x46b8, 0x92d0, 0x54b2, 0x6664, 0x44b9, 0x3284 }, 16, 0x000aa560, 1},
+ {{0x2a90, 0x800a, 0x94c0, 0xf9c8, 0xe8ee, 0x9ac0, 0x2304, 0x8100, 0x6d90, 0x2b03, 0x8026, 0x98c0, 0x37a1, 0x2000, 0x800c, 0xc684 }, 16, 0x000aa580, 1},
+ {{0x96c0, 0xffc7, 0x2b02, 0x8002, 0x96c0, 0x0742, 0x2e7c, 0x8009, 0x9ac0, 0x79c8, 0x0c46, 0x2e7c, 0x8009, 0xcd43, 0x3b48, 0x15be }, 16, 0x000aa5a0, 1},
+ {{0xca46, 0xec1d, 0x4594, 0x17bf, 0x0846, 0x2e7c, 0x8009, 0x90d0, 0xe81a, 0x4790, 0x98c0, 0x3be8, 0x3c0c, 0xbfff, 0xc0b2, 0x35e9 }, 16, 0x000aa5c0, 1},
+ {{0x3fff, 0xbfff, 0x1493, 0x3be8, 0x3c0c, 0xbfff, 0xde84, 0x0995, 0xa000, 0x32e4, 0x3a68, 0x8001, 0x4593, 0x98c0, 0x3ee8, 0x3c28 }, 16, 0x000aa5e0, 1},
+ {{0xbfff, 0xc1fd, 0x98c0, 0x3be8, 0x3c28, 0xbfff, 0xc5f7, 0x1096, 0x3ee8, 0x3c28, 0xbfff, 0x98c0, 0xdc80, 0xc0fb, 0x23e0, 0x9f0f }, 16, 0x000aa600, 1},
+ {{0x0196, 0x3ee8, 0x3c28, 0xbfff, 0x1293, 0x3be8, 0x3c28, 0xbfff, 0x3840, 0xa000, 0xde82, 0xfec9, 0xc683, 0x96c0, 0xc4fe, 0x0905 }, 16, 0x000aa620, 1},
+ {{0xa008, 0x0596, 0x3ee8, 0x3c28, 0xbfff, 0x3660, 0xa000, 0xfac6, 0xf8c5, 0x1596, 0x3ee8, 0x3c28, 0xbfff, 0xdc05, 0x0900, 0xa004 }, 16, 0x000aa640, 1},
+ {{0x4096, 0x5593, 0xdd85, 0x0903, 0xa080, 0x4396, 0x3480, 0xa000, 0x4616, 0x5396, 0xde03, 0x0904, 0xa001, 0x4493, 0x9f7d, 0x3480 }, 16, 0x000aa660, 1},
+ {{0xa000, 0x57d6, 0xd3a4, 0x9f7c, 0x2718, 0x8226, 0x3a40, 0xa000, 0x2e00, 0x9e00, 0x6f10, 0xebee, 0x9ac0, 0x2304, 0x8080, 0x90c0 }, 16, 0x000aa680, 1},
+ {{0x2b03, 0x8038, 0x98c0, 0xeb3e, 0x30c1, 0x2000, 0x800c, 0x96c0, 0xedeb, 0x2b0f, 0x8004, 0x98c0, 0x0042, 0x2e78, 0x8009, 0xeeef }, 16, 0x000aa6a0, 1},
+ {{0x96c0, 0xc484, 0x2500, 0x8080, 0x96c0, 0x2b02, 0x8002, 0x90c0, 0x9ac0, 0x7b50, 0x0946, 0x2e78, 0x8009, 0xcc46, 0x3a50, 0xca44 }, 16, 0x000aa6c0, 1},
+ {{0xe91c, 0x5391, 0x3701, 0x8080, 0x7ce8, 0x41bd, 0x0846, 0x2e78, 0x8009, 0x90c0, 0xe81a, 0x5790, 0x94d0, 0x3f00, 0x8080, 0x7c68 }, 16, 0x000aa6e0, 1},
+ {{0x40be, 0x96c0, 0x9b45, 0x2b03, 0x8020, 0x3c60, 0xa000, 0x280e, 0x89cc, 0x90c0, 0x2808, 0x89c8, 0x94c0, 0xc08c, 0xc188, 0x2b02 }, 16, 0x000aa700, 1},
+ {{0x8002, 0x9ac0, 0x78d0, 0x0a46, 0x2e78, 0x8009, 0xcd41, 0x3850, 0xc940, 0xea1d, 0x5292, 0x3503, 0x8080, 0x7de8, 0x43b8, 0x0c46 }, 16, 0x000aa720, 1},
+ {{0x2e78, 0x8009, 0x90c0, 0xec19, 0x5394, 0x94d0, 0x3707, 0x8080, 0x7fe8, 0x47be, 0x3820, 0xa000, 0xe9ee, 0x2e00, 0x9e24, 0x38a0 }, 16, 0x000aa740, 1},
+ {{0xa000, 0xe9ee, 0x2302, 0x8200, 0x96c0, 0xe93e, 0x2600, 0x8080, 0x3640, 0xa100, 0x53d1, 0xe93b, 0x3a40, 0xa000, 0x65e9, 0xfe49 }, 16, 0x000aa760, 1},
+ {{0x0bf8, 0x9edc, 0x01fa, 0x9ed8, 0x9ac1, 0x2e00, 0x9838, 0x90c0, 0x2e00, 0x9a38, 0x90c0, 0x3820, 0xa000, 0xee1a, 0x90c0, 0x90c0 }, 16, 0x000aa780, 1},
+ {{0x9ac0, 0x1bf8, 0x9ed8, 0x90c0, 0x1df8, 0x9edc, 0x5297, 0x101b, 0x5395, 0x2c53, 0x111b, 0x3284, 0x20f0, 0x800a, 0x9ac0, 0x0bf8 }, 16, 0x000aa7a0, 1},
+ {{0x9ed8, 0x6fd8, 0x2160, 0x9fff, 0x3284, 0x2110, 0x800a, 0x2180, 0x8000, 0x3284, 0x20f0, 0x800a, 0x98c0, 0x77d0, 0x7457, 0x2160 }, 16, 0x000aa7c0, 1},
+ {{0x9fff, 0x3284, 0x2110, 0x800a, 0x2180, 0x8000, 0x3b61, 0x071e, 0x1df8, 0x9edc, 0x276a, 0x001e, 0xef48, 0x94c0, 0xed48, 0x81a6 }, 16, 0x000aa7e0, 1},
+ {{0x0df8, 0x9edc, 0x3820, 0xa000, 0xfec9, 0x2e00, 0x8200, 0x3820, 0xa000, 0xf8c5, 0x2700, 0x8080, 0x3420, 0xa000, 0xebee, 0x3840 }, 16, 0x000aa800, 1},
+ {{0xa000, 0xeb3e, 0x280f, 0x89cc, 0x3c40, 0xa000, 0x0bf8, 0x9ed4, 0x90c0, 0x280e, 0x89c8, 0x1697, 0x3284, 0x20f0, 0x800a, 0x96c0 }, 16, 0x000aa820, 1},
+ {{0x5096, 0x2160, 0x9fff, 0x3284, 0x2110, 0x800a, 0x2180, 0x8000, 0x3284, 0x20f0, 0x800a, 0x98c0, 0x7750, 0x7456, 0x2160, 0x9fff }, 16, 0x000aa840, 1},
+ {{0x3284, 0x2110, 0x800a, 0x2180, 0x8000, 0x98c0, 0x18f8, 0x9ed4, 0x7be1, 0xee48, 0x27ea, 0xef48, 0x4618, 0x94c0, 0x4018, 0x81bc }, 16, 0x000aa860, 1},
+ {{0x08f8, 0x9ed4, 0x3660, 0xa000, 0xfac6, 0xfec9, 0x9f7d, 0x3680, 0xa000, 0x56d2, 0xc2fe, 0x0906, 0xa002, 0x767e, 0xdd04, 0x3480 }, 16, 0x000aa880, 1},
+ {{0xa000, 0x4212, 0x9f7c, 0x6c90, 0x3480, 0xa000, 0x4116, 0x27ee, 0x9ed0, 0xe7ee, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721 }, 16, 0x000aa8a0, 1},
+ {{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x3284, 0x2cb0, 0x800a, 0x3880, 0x2ca4, 0x8009, 0x98c0, 0x3980 }, 16, 0x000aa8c0, 1},
+ {{0x3236, 0x8009, 0xc4fe, 0x2c00, 0x808a, 0x10d1, 0x3800, 0x2064, 0x8008, 0x96c0, 0x3119, 0x8001, 0xde00, 0x24e9, 0x3a00, 0x2064 }, 16, 0x000aa8e0, 1},
+ {{0x8008, 0x802b, 0x0411, 0x3de8, 0x2404, 0xbfff, 0x98c0, 0xe93c, 0x3be8, 0x2404, 0xbfff, 0x5c91, 0x90c0, 0xec41, 0x4c91, 0x51d0 }, 16, 0x000aa900, 1},
+ {{0x78c1, 0x4112, 0x5195, 0x0911, 0xa001, 0x4193, 0x9f71, 0x90c0, 0x33c4, 0x20c0, 0x800a, 0x2c10, 0x1a90, 0x39a0, 0x306c, 0x8009 }, 16, 0x000aa920, 1},
+ {{0x90c0, 0x1292, 0x54d1, 0x351d, 0x8020, 0x66e9, 0x8415, 0xd221, 0x800b, 0xd223, 0x8007, 0x6669, 0x840b, 0x94c0, 0xc081, 0x9f71 }, 16, 0x000aa940, 1},
+ {{0xc081, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x3551, 0x24ea, 0xc481, 0x7961, 0xd612, 0x92c2, 0x6661, 0x94c6 }, 16, 0x000aa960, 1},
+ {{0x9f70, 0x6c40, 0x92c2, 0xd419, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6f10, 0x9620, 0x9720, 0x96c0, 0x6c90, 0x9e20, 0x9f20 }, 16, 0x000aa980, 1},
+ {{0x96c0, 0xe748, 0x2320, 0x83cc, 0x98c0, 0xf341, 0x0621, 0x3c6c, 0x8009, 0x98c0, 0x06c0, 0x210a, 0x8009, 0xefe8, 0x98c0, 0xc94e }, 16, 0x000aa9a0, 1},
+ {{0x33e4, 0x3c8a, 0x8001, 0x96c0, 0xc946, 0x2f08, 0x84b4, 0x96c0, 0xcdac, 0x280a, 0x8002, 0x96c0, 0x5211, 0x290e, 0x802e, 0x0210 }, 16, 0x000aa9c0, 1},
+ {{0xe9ee, 0x1716, 0xcbaa, 0x071a, 0xe93d, 0x1511, 0xecee, 0x051a, 0xc9a8, 0x94c0, 0xec3b, 0xedee, 0x1614, 0xed39, 0x3640, 0xa000 }, 16, 0x000aa9e0, 1},
+ {{0x461a, 0xcfa6, 0x1415, 0xebee, 0x041a, 0xc9a4, 0x3620, 0xa000, 0xeb3f, 0xecee, 0x1113, 0xcba2, 0x011a, 0xec39, 0x1114, 0xedee }, 16, 0x000aaa00, 1},
+ {{0x011a, 0xc9a0, 0x94c0, 0xed3b, 0xecee, 0x1015, 0xec39, 0x001a, 0xedee, 0x1114, 0xed7e, 0x011a, 0xebee, 0x1315, 0xeb7c, 0x031a }, 16, 0x000aaa20, 1},
+ {{0xe9ee, 0x1413, 0xe97a, 0x94c0, 0x441a, 0x9756, 0x5311, 0x0312, 0xebee, 0x96c0, 0xeb78, 0x2f09, 0x84cc, 0x92d0, 0x5613, 0x4619 }, 16, 0x000aaa40, 1},
+ {{0x98c0, 0x6f10, 0x6c10, 0xe9ee, 0xecee, 0x96c0, 0xe976, 0x2a0b, 0x802e, 0x1511, 0xec74, 0x051b, 0xe9ee, 0x1714, 0xe972, 0x071b }, 16, 0x000aaa60, 1},
+ {{0xedee, 0x1511, 0xed70, 0x051b, 0xecee, 0x1415, 0xec6e, 0x0413, 0xedee, 0x96c0, 0x5114, 0x2b09, 0x8002, 0x0111, 0xed6c, 0x1515 }, 16, 0x000aaa80, 1},
+ {{0xedee, 0x96c0, 0xed6a, 0x290c, 0x8002, 0x3600, 0xa100, 0x451c, 0xe9ee, 0x3600, 0xa100, 0x5415, 0xe966, 0x0414, 0xedee, 0x3600 }, 16, 0x000aaaa0, 1},
+ {{0xa100, 0xec4c, 0x5511, 0x051c, 0xed64, 0x3600, 0xa100, 0x52d5, 0xeeee, 0x3600, 0xa100, 0x421c, 0xee62, 0x3680, 0xa000, 0x53d6 }, 16, 0x000aaac0, 1},
+ {{0xee68, 0x96c0, 0x4314, 0x2c0d, 0x809a, 0x1316, 0xeced, 0x96c0, 0x4315, 0x2704, 0x8100, 0xec7a, 0x94c0, 0xed78, 0x969c, 0x0615 }, 16, 0x000aaae0, 1},
+ {{0x3c20, 0x3c74, 0x8009, 0x3542, 0x2074, 0x8009, 0x3d40, 0x2274, 0x8009, 0x3e20, 0x3e74, 0x8009, 0x90c0, 0x3610, 0xa100, 0x401e }, 16, 0x000aab00, 1},
+ {{0x401d, 0x001d, 0x401c, 0x9ac0, 0x2a0c, 0x80d2, 0x6d90, 0x2e00, 0x9828, 0x96c0, 0xe86a, 0x2c0d, 0x982c, 0x0d94, 0xc0b2, 0x96c0 }, 16, 0x000aab20, 1},
+ {{0xed3e, 0x2d0e, 0x8200, 0x96c0, 0x4e95, 0x2a0c, 0x9efe, 0x15d1, 0x39a0, 0x31e0, 0x800a, 0x3b1a, 0x8001, 0x6569, 0x90c0, 0x98c1 }, 16, 0x000aab40, 1},
+ {{0x2200, 0x807f, 0x90c0, 0xc5bf, 0x94c1, 0x4210, 0x4510, 0x92c3, 0x5a13, 0x90c0, 0x92c3, 0xeafc, 0x98c7, 0x32e4, 0x3a5c, 0x8001 }, 16, 0x000aab60, 1},
+ {{0x4a13, 0x4314, 0x32e4, 0x3a62, 0x8001, 0x94c0, 0xc183, 0xc0b2, 0x9756, 0x9ac0, 0x2f0a, 0x8516, 0x90c0, 0x2f0f, 0x8542, 0x2660 }, 16, 0x000aab80, 1},
+ {{0x9fff, 0x94c8, 0x461a, 0x461f, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0d, 0x82c0, 0x101d, 0x3284, 0x23a0, 0x800b, 0x5115, 0xe768 }, 16, 0x000aaba0, 1},
+ {{0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x1251, 0xf486, 0x266a, 0x3a61, 0xeae8, 0x94c0, 0x535a, 0x8427 }, 16, 0x000aabc0, 1},
+ {{0x94c0, 0x7453, 0x9f44, 0x04fc, 0x9ff6, 0x2103, 0x8010, 0x96d0, 0x6448, 0x7553, 0x535a, 0x3453, 0x4058, 0x2448, 0x7553, 0x4050 }, 16, 0x000aabe0, 1},
+ {{0x9f70, 0x4251, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x280a, 0x8598, 0x94c0, 0x9620, 0x9720, 0x15d2, 0x3322, 0x3e74 }, 16, 0x000aac00, 1},
+ {{0x8009, 0x98c0, 0x3615, 0x80ff, 0x9e20, 0x9f20, 0x94c6, 0xefea, 0x6d90, 0x94c6, 0xef62, 0x4312, 0x1317, 0x52d2, 0x9ac0, 0x6f5d }, 16, 0x000aac20, 1},
+ {{0x3542, 0x2074, 0x8009, 0xe758, 0x98c0, 0xcb46, 0x3742, 0x2274, 0x8009, 0x96c0, 0xf499, 0x2a0e, 0x801c, 0x98c0, 0xebf9, 0x3222 }, 16, 0x000aac40, 1},
+ {{0x3c74, 0x8009, 0x1016, 0xebfc, 0x3680, 0xa100, 0xeb1b, 0xef1b, 0x3680, 0xa100, 0xed1b, 0x4013, 0x3820, 0xa100, 0xeb1a, 0x2e08 }, 16, 0x000aac60, 1},
+ {{0x8002, 0x3680, 0xa000, 0x5010, 0x4413, 0x3680, 0xa100, 0x4117, 0x4015, 0x11d2, 0xe9ea, 0x9ac0, 0x78c1, 0x3ca0, 0x3074, 0x8009 }, 16, 0x000aac80, 1},
+ {{0xe968, 0x37f9, 0x2e10, 0x0112, 0xedea, 0x96c0, 0x3617, 0x807f, 0xed66, 0x2718, 0x83aa, 0x0412, 0x3b40, 0x2074, 0x8009, 0x17d1 }, 16, 0x000aaca0, 1},
+ {{0x3860, 0x2ccc, 0x8009, 0x96c0, 0xfa45, 0x0907, 0xa005, 0x3640, 0xa000, 0x4711, 0xf846, 0x1194, 0x52d5, 0x9ac0, 0x2100, 0x8080 }, 16, 0x000aacc0, 1},
+ {{0x90c0, 0x331d, 0x9000, 0x26e9, 0xf142, 0x90c0, 0x98c1, 0x0902, 0xa004, 0x90c0, 0xc5fb, 0x94c1, 0x4215, 0xde82, 0x92c2, 0x4515 }, 16, 0x000aace0, 1},
+ {{0x5917, 0x90c0, 0xe9fc, 0x98c0, 0xe91b, 0x3264, 0x2010, 0x800b, 0xf941, 0x1917, 0x3d40, 0x2274, 0x8009, 0x2400, 0x8080, 0x94c0 }, 16, 0x000aad00, 1},
+ {{0xe9fc, 0xf442, 0x98c0, 0xe91d, 0x3860, 0x36a4, 0x8009, 0x3264, 0x2010, 0x800b, 0xf941, 0x1917, 0x3b20, 0x3c74, 0x8009, 0x2400 }, 16, 0x000aad20, 1},
+ {{0x8080, 0x94c0, 0xe9fc, 0xf442, 0x98c0, 0xe91b, 0x3860, 0x31b8, 0x8009, 0x3264, 0x2010, 0x800b, 0xf941, 0x3620, 0xa000, 0xf8c6 }, 16, 0x000aad40, 1},
+ {{0x5817, 0x3b20, 0x3e74, 0x8009, 0x3620, 0xa000, 0xe9e8, 0xe8fc, 0x96c0, 0xe970, 0x2100, 0x8080, 0x96c0, 0xe81b, 0x290c, 0x8008 }, 16, 0x000aad60, 1},
+ {{0x1314, 0xf102, 0x32a4, 0x2bd0, 0x800a, 0xf301, 0x1817, 0x3b40, 0x2074, 0x8009, 0x1014, 0xe9ec, 0x96c0, 0xe8fc, 0x2700, 0x8080 }, 16, 0x000aad80, 1},
+ {{0x94c0, 0xe964, 0xf702, 0x32a4, 0x2bd0, 0x800a, 0x94c0, 0xe81b, 0xf001, 0x1817, 0x3940, 0x2274, 0x8009, 0x96c0, 0x5414, 0x2c0b }, 16, 0x000aada0, 1},
+ {{0x8002, 0x96c0, 0xe8fc, 0x2500, 0x8080, 0x94c0, 0xe819, 0xf502, 0x32a4, 0x2bd0, 0x800a, 0x94c0, 0xe9eb, 0xf401, 0x1817, 0x3920 }, 16, 0x000aadc0, 1},
+ {{0x3c74, 0x8009, 0x1114, 0xeb42, 0x96c0, 0xe8fc, 0x2200, 0x8080, 0x94c0, 0xe819, 0xf202, 0x32a4, 0x2bd0, 0x800a, 0x94c0, 0xe9eb }, 16, 0x000aade0, 1},
+ {{0xf101, 0x2c90, 0x1617, 0xfac5, 0x2769, 0x3960, 0x2ae8, 0x8008, 0x94c7, 0xedea, 0x6e10, 0x96c6, 0xed64, 0x2400, 0x8080, 0x96c0 }, 16, 0x000aae00, 1},
+ {{0x4417, 0x2b03, 0x8054, 0x96c0, 0x94bd, 0x2304, 0x80ff, 0x2669, 0x3422, 0x3e74, 0x8009, 0x98c7, 0x3b40, 0x2074, 0x8009, 0x6f10 }, 16, 0x000aae20, 1},
+ {{0x98c6, 0x3ca0, 0x2004, 0x800c, 0xc681, 0x96c0, 0x969d, 0x2b02, 0x8002, 0x1317, 0x38a0, 0x2000, 0x800c, 0x2e59, 0x5259, 0x3414 }, 16, 0x000aae40, 1},
+ {{0x8100, 0x94c2, 0x3c13, 0x8100, 0x2fd9, 0x78c1, 0x7fc1, 0xcd47, 0x90c0, 0x3600, 0xa100, 0x6f59, 0xec1d, 0x3a00, 0xa100, 0x3416 }, 16, 0x000aae60, 1},
+ {{0x8100, 0xed1b, 0x5054, 0x2332, 0x1755, 0x3422, 0x3e74, 0x8009, 0x96c6, 0x62ab, 0x3c13, 0x8100, 0x2c59, 0x38c1, 0x45b8, 0x94d0 }, 16, 0x000aae80, 1},
+ {{0x7c41, 0x46bc, 0x1259, 0xcd40, 0x90c0, 0x98c0, 0x39e8, 0x3c0c, 0xbfff, 0xc0b2, 0x3a80, 0xa000, 0xec1d, 0x36e9, 0x3fff, 0xbfff }, 16, 0x000aaea0, 1},
+ {{0x3600, 0xa100, 0xed1b, 0x5554, 0x2229, 0x5155, 0x62b8, 0x4590, 0x4494, 0x5491, 0xdf04, 0x0996, 0xa000, 0x32e4, 0x3a68, 0x8001 }, 16, 0x000aaec0, 1},
+ {{0x4691, 0x9ac0, 0x6f90, 0x3ce8, 0x3c28, 0xbfff, 0xc0fd, 0x98c0, 0x39e8, 0x3c28, 0xbfff, 0xc1f7, 0x1594, 0x3de8, 0x3c28, 0xbfff }, 16, 0x000aaee0, 1},
+ {{0x9ac0, 0xdc05, 0x3be8, 0x3c28, 0xbfff, 0xc2fb, 0x0091, 0x39e8, 0x3c28, 0xbfff, 0x96c0, 0x5395, 0x26e0, 0x9f0f, 0x3c20, 0xa000 }, 16, 0x000aaf00, 1},
+ {{0xdc83, 0x3ce8, 0x3c28, 0xbfff, 0xf8c6, 0x0191, 0xc481, 0x1393, 0x3be8, 0x3c28, 0xbfff, 0x3a20, 0xa000, 0x280d, 0x9e12, 0xdd03 }, 16, 0x000aaf20, 1},
+ {{0xc3fe, 0x9ac0, 0x0902, 0xa004, 0x90c0, 0x2304, 0x80ff, 0x0291, 0x36ea, 0x3c28, 0xbfff, 0x1593, 0x3960, 0x2ae8, 0x8008, 0x98c0 }, 16, 0x000aaf40, 1},
+ {{0x2b03, 0x805c, 0xdf05, 0xfac5, 0x9ac0, 0x0906, 0xa080, 0x90c0, 0x2b02, 0x8002, 0x0694, 0x3820, 0x3c74, 0x8009, 0x0415, 0x3ca0 }, 16, 0x000aaf60, 1},
+ {{0x3000, 0x800c, 0x1293, 0x3da0, 0x3004, 0x800c, 0x98c0, 0xdd82, 0x3b40, 0x2274, 0x8009, 0x0903, 0xa001, 0x3480, 0xa000, 0x4396 }, 16, 0x000aaf80, 1},
+ {{0x1417, 0x5259, 0x6dd7, 0x3413, 0x8100, 0x94c2, 0x3c14, 0x8100, 0x2cd7, 0x7bc1, 0x7cc1, 0xcf41, 0x90c0, 0x2dd7, 0xe81f, 0x98c0 }, 16, 0x000aafa0, 1},
+ {{0x3413, 0x8100, 0xef1b, 0x5350, 0x9ac6, 0x5357, 0x90c0, 0x60bd, 0x3c14, 0x8100, 0x21bd, 0x2d57, 0x3bc1, 0x3820, 0x3c74, 0x8009 }, 16, 0x000aafc0, 1},
+ {{0x94d0, 0x7d41, 0x43bc, 0x01bd, 0xcf42, 0x5259, 0x9ac0, 0x6e90, 0xe81f, 0x39e8, 0x3c28, 0xbfff, 0x1350, 0xef1b, 0x21bd, 0x5457 }, 16, 0x000aafe0, 1},
+ {{0x6028, 0x0094, 0x3ce8, 0x3c28, 0xbfff, 0x4395, 0x0522, 0x3c70, 0x8009, 0x5491, 0x399a, 0x8000, 0x6569, 0x8415, 0x7ac1, 0x0522 }, 16, 0x000ab000, 1},
+ {{0x3c70, 0x8009, 0x5494, 0x3998, 0x8000, 0x6469, 0x81f1, 0x98c0, 0x3de8, 0x3c28, 0xbfff, 0xc0fd, 0x98c0, 0x39e8, 0x3c28, 0xbfff }, 16, 0x000ab020, 1},
+ {{0xc6fe, 0x1295, 0x38e8, 0x3c28, 0xbfff, 0xdc02, 0x0900, 0xa002, 0x4091, 0x5291, 0xdf02, 0x0906, 0xa001, 0x4690, 0x3640, 0xa000 }, 16, 0x000ab040, 1},
+ {{0xe8ea, 0xe9e8, 0x96c0, 0xe868, 0x2c00, 0x809c, 0x11d0, 0xe97c, 0x96c0, 0x331a, 0x8004, 0xebe9, 0x2569, 0x12d1, 0xeb3c, 0x94c0 }, 16, 0x000ab060, 1},
+ {{0x7941, 0x809f, 0x377a, 0x2e10, 0x0211, 0xc7fb, 0x3640, 0xa000, 0x5313, 0xede8, 0x96c0, 0x71f6, 0xc6fd, 0xed72, 0x94c0, 0xeced }, 16, 0x000ab080, 1},
+ {{0x8081, 0x96c0, 0x4411, 0x2602, 0x9828, 0x96c0, 0x52d0, 0x2d09, 0x9824, 0x96c0, 0xdf82, 0xebe9, 0xec68, 0x3820, 0xa000, 0x76ff }, 16, 0x000ab0a0, 1},
+ {{0x4710, 0xeb3e, 0x3c80, 0xa000, 0x2909, 0x8200, 0x90c0, 0x3b1c, 0x8002, 0x6669, 0x3480, 0xa000, 0x9c52, 0xea66, 0x3482, 0xa000 }, 16, 0x000ab0c0, 1},
+ {{0xec66, 0x3482, 0xa000, 0x51d4, 0x94c2, 0x0901, 0xa001, 0x3482, 0xa000, 0x4114, 0x57d0, 0xdf07, 0x4610, 0x54d2, 0x391f, 0x80ff }, 16, 0x000ab0e0, 1},
+ {{0x75d7, 0x7dc8, 0xdd9f, 0x4312, 0x03c0, 0x210a, 0x8009, 0x53d5, 0xd883, 0x4115, 0x4994, 0x3420, 0xa000, 0x4993, 0x3420, 0xa000 }, 16, 0x000ab100, 1},
+ {{0xe8e8, 0xe872, 0x3640, 0xa000, 0x57d0, 0xe8e8, 0x27e9, 0xe87a, 0x94c0, 0x5990, 0x842d, 0x280b, 0x9a2c, 0x1611, 0xe944, 0x94c0 }, 16, 0x000ab120, 1},
+ {{0xeb89, 0xf944, 0x3480, 0xa000, 0x4610, 0x3623, 0xa000, 0x280b, 0x9812, 0x98c7, 0x31a4, 0x318a, 0x800a, 0xfb44, 0x3420, 0xa000 }, 16, 0x000ab140, 1},
+ {{0xe8e8, 0xe876, 0x96c0, 0x5990, 0x280b, 0x9c28, 0x90c0, 0x1211, 0xe944, 0x94c0, 0xeb89, 0xf944, 0x3480, 0xa000, 0x4210, 0x3623 }, 16, 0x000ab160, 1},
+ {{0xa000, 0x2809, 0x9a12, 0x92c3, 0xf944, 0x3620, 0xa000, 0xece8, 0xf5c4, 0x0590, 0xec68, 0x3680, 0xa000, 0x5610, 0x5514, 0x3880 }, 16, 0x000ab180, 1},
+ {{0xa000, 0x7f4f, 0xec66, 0xe842, 0x1414, 0xe778, 0x6b15, 0x6768, 0x94c3, 0x3d46, 0x8000, 0x7f6f, 0x7f48, 0x6765, 0x7f48, 0x775e }, 16, 0x000ab1a0, 1},
+ {{0x4654, 0x3480, 0xa000, 0x4658, 0x5016, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f70, 0x3480, 0xa000, 0x4010, 0x90c0 }, 16, 0x000ab1c0, 1},
+ {{0x32e4, 0x3a68, 0x8001, 0xc0b2, 0x3ba0, 0x306c, 0x8009, 0x90c0, 0x52d3, 0xd121, 0x90c0, 0x94c6, 0x8016, 0xc082, 0x92c2, 0x4013 }, 16, 0x000ab1e0, 1},
+ {{0xd123, 0x90c0, 0x92c2, 0xc284, 0x92c2, 0x4213, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ab200, 1},
+ {{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x3880, 0x2ca4, 0x8009, 0x9f71, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ab220, 1},
+ {{0x2400, 0x808d, 0x0347, 0x2eac, 0x8009, 0x3684, 0x8003, 0x94c0, 0x7a41, 0x9f70, 0x3474, 0x0440, 0x2eac, 0x8009, 0x90c0, 0x90c0 }, 16, 0x000ab240, 1},
+ {{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x32c4, 0x20d0 }, 16, 0x000ab260, 1},
+ {{0x800a, 0xe748, 0x33c4, 0x2050, 0x800a, 0x0dc6, 0x38d0, 0x8008, 0x3e20, 0x336c, 0x8009, 0x2d0b, 0x8026, 0x17d3, 0x0a86, 0x22d8 }, 16, 0x000ab280, 1},
+ {{0x8009, 0x3f19, 0x80ff, 0x7cc2, 0xc841, 0x90c0, 0xe81e, 0x5790, 0x4792, 0x0fc6, 0x38d0, 0x8008, 0x0d86, 0x22d8, 0x8009, 0x2f0b }, 16, 0x000ab2a0, 1},
+ {{0x8026, 0x10d3, 0xed44, 0x30cf, 0x8208, 0xc847, 0x90c0, 0xe8fe, 0xe81e, 0x5290, 0x4295, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0d }, 16, 0x000ab2c0, 1},
+ {{0x804e, 0x52d5, 0x3519, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7461, 0x0986, 0x22d8, 0x8009, 0x90c0, 0xe948, 0x4011, 0x0ac6, 0x38d0 }, 16, 0x000ab2e0, 1},
+ {{0x8008, 0x90c0, 0x2a0f, 0x804e, 0x56d7, 0x3cc9, 0x8208, 0x3244, 0x3d90, 0x800a, 0x7461, 0x0986, 0x22d8, 0x8009, 0x3820, 0x336c }, 16, 0x000ab300, 1},
+ {{0x8009, 0xe94a, 0x4011, 0x0dc6, 0x38d0, 0x8008, 0x0c86, 0x22d0, 0x8009, 0x2d0e, 0x8024, 0x51d6, 0x3318, 0x80ff, 0x7c42, 0xcd40 }, 16, 0x000ab320, 1},
+ {{0x90c0, 0xed18, 0x5495, 0x4494, 0x0ec6, 0x38d0, 0x8008, 0x0a86, 0x22d0, 0x8009, 0x2e09, 0x8024, 0x13d1, 0xea44, 0x36c8, 0x8208 }, 16, 0x000ab340, 1},
+ {{0xcc40, 0x90c0, 0xecfe, 0xec18, 0x5694, 0x4692, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0c, 0x804c, 0x52d4, 0x351f, 0x80ff, 0x3244 }, 16, 0x000ab360, 1},
+ {{0x3d90, 0x800a, 0x7467, 0x0d86, 0x22d0, 0x8009, 0x90c0, 0xed48, 0x4015, 0x0ac6, 0x38d0, 0x8008, 0x90c0, 0x2a0d, 0x804c, 0x53d5 }, 16, 0x000ab380, 1},
+ {{0x36ce, 0x8208, 0x3244, 0x3d90, 0x800a, 0x7466, 0x0886, 0x22d0, 0x8009, 0x90c0, 0xe84a, 0x4010, 0x0cc6, 0x38d0, 0x8008, 0x90c0 }, 16, 0x000ab3a0, 1},
+ {{0x2c0d, 0x8100, 0x56d5, 0x3d1c, 0x8002, 0x2669, 0x06c7, 0x2a40, 0x8009, 0x8429, 0x96c0, 0x6769, 0x2d0b, 0x8042, 0x94c0, 0x5013 }, 16, 0x000ab3c0, 1},
+ {{0x841f, 0x32a4, 0x34f0, 0x800b, 0x01a4, 0x33be, 0x8009, 0x30a4, 0x3402, 0x800a, 0x0080, 0x2ca0, 0x8009, 0x6e90, 0x0580, 0x2ca0 }, 16, 0x000ab3e0, 1},
+ {{0x8009, 0x2c00, 0x80d8, 0x3920, 0x336c, 0x8009, 0x98c0, 0xed3c, 0x0b86, 0x22dc, 0x8009, 0x50d5, 0x311c, 0x80ff, 0x7e42, 0xca44 }, 16, 0x000ab400, 1},
+ {{0x90c0, 0xea19, 0x5692, 0x4693, 0x0dc6, 0x38d0, 0x8008, 0x0886, 0x22dc, 0x8009, 0x2d0c, 0x8028, 0x15d4, 0xe844, 0x3ac8, 0x8208 }, 16, 0x000ab420, 1},
+ {{0xca40, 0x90c0, 0xeafe, 0xea19, 0x5592, 0x4590, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c0e, 0x8050, 0x50d6, 0x3119, 0x80ff, 0x3244 }, 16, 0x000ab440, 1},
+ {{0x3d90, 0x800a, 0x7461, 0x0e86, 0x22dc, 0x8009, 0x90c0, 0xee48, 0x4016, 0x0ec6, 0x38d0, 0x8008, 0x90c0, 0x2e0b, 0x8050, 0x54d3 }, 16, 0x000ab460, 1},
+ {{0x38c9, 0x8208, 0x3244, 0x3d90, 0x800a, 0x7461, 0x0986, 0x22dc, 0x8009, 0x3820, 0x336c, 0x8009, 0xe94a, 0x4011, 0x0dc6, 0x38d0 }, 16, 0x000ab480, 1},
+ {{0x8008, 0x0e86, 0x22d4, 0x8009, 0x2d0b, 0x802a, 0x54d3, 0x391d, 0x80ff, 0x7ec2, 0xcc45, 0x90c0, 0xec18, 0x5494, 0x4496, 0x0bc6 }, 16, 0x000ab4a0, 1},
+ {{0x38d0, 0x8008, 0x0e86, 0x22d4, 0x8009, 0x2b09, 0x802a, 0x13d1, 0xee44, 0x36ca, 0x8208, 0xca42, 0x90c0, 0xeafe, 0xea18, 0x5792 }, 16, 0x000ab4c0, 1},
+ {{0x4796, 0x0ac6, 0x38d0, 0x8008, 0x90c0, 0x2a0d, 0x8052, 0x55d5, 0x3b1e, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7466, 0x0f86, 0x22d4 }, 16, 0x000ab4e0, 1},
+ {{0x8009, 0x90c0, 0xef48, 0x4017, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c0c, 0x8052, 0x51d4, 0x32c9, 0x8208, 0x3244, 0x3d90, 0x800a }, 16, 0x000ab500, 1},
+ {{0x7461, 0x0f86, 0x22d4, 0x8009, 0x3860, 0x3d54, 0x8009, 0x98c0, 0xef4a, 0x3224, 0x3010, 0x800b, 0x4017, 0x3224, 0x3010, 0x800b }, 16, 0x000ab520, 1},
+ {{0x3860, 0x3f18, 0x8009, 0x3224, 0x3010, 0x800b, 0x3860, 0x3b90, 0x8009, 0x3224, 0x3010, 0x800b, 0x3880, 0x20dc, 0x8009, 0x0fc6 }, 16, 0x000ab540, 1},
+ {{0x38d0, 0x8008, 0x3860, 0x3d54, 0x8009, 0x2f09, 0x8344, 0x290e, 0x825c, 0x3244, 0x2fe0, 0x800b, 0xfe41, 0x0ac6, 0x38d0, 0x8008 }, 16, 0x000ab560, 1},
+ {{0x3860, 0x3f18, 0x8009, 0x2a09, 0x8344, 0x290c, 0x825c, 0x3244, 0x2fe0, 0x800b, 0xfc41, 0x0bc6, 0x38d0, 0x8008, 0x3860, 0x3b90 }, 16, 0x000ab580, 1},
+ {{0x8009, 0x2b09, 0x8344, 0x290f, 0x825c, 0x3244, 0x2fe0, 0x800b, 0xff41, 0x0dc6, 0x38d0, 0x8008, 0x3880, 0x20dc, 0x8009, 0x2d09 }, 16, 0x000ab5a0, 1},
+ {{0x8300, 0x290f, 0x8200, 0x3244, 0x2fe0, 0x800b, 0xff41, 0x98c0, 0x09c6, 0x38d0, 0x8008, 0xc182, 0x98c0, 0xf142, 0x3860, 0x22f4 }, 16, 0x000ab5c0, 1},
+ {{0x8009, 0x2909, 0x8400, 0x290e, 0x8060, 0x3244, 0x35b0, 0x800b, 0xfe41, 0x2d90, 0x09c6, 0x38d0, 0x8008, 0x98c0, 0xf342, 0x3860 }, 16, 0x000ab5e0, 1},
+ {{0x27e0, 0x8009, 0x2909, 0x8420, 0x290c, 0x8050, 0x3244, 0x35b0, 0x800b, 0xfc41, 0x98c0, 0x0cc6, 0x38d0, 0x8008, 0xc481, 0x98c0 }, 16, 0x000ab600, 1},
+ {{0xf442, 0x3860, 0x2ccc, 0x8009, 0x2c09, 0x8440, 0x290e, 0x8040, 0x3244, 0x35b0, 0x800b, 0xfe41, 0x98c0, 0x0cc6, 0x38d0, 0x8008 }, 16, 0x000ab620, 1},
+ {{0xc381, 0x98c0, 0xf342, 0x3860, 0x36a4, 0x8009, 0x2c09, 0x8440, 0x290c, 0x8040, 0x3244, 0x35b0, 0x800b, 0xfc41, 0x98c0, 0x0ac6 }, 16, 0x000ab640, 1},
+ {{0x38d0, 0x8008, 0xc281, 0x98c0, 0xf242, 0x3860, 0x31b8, 0x8009, 0x2a09, 0x8440, 0x290b, 0x8040, 0x3244, 0x35b0, 0x800b, 0xfb41 }, 16, 0x000ab660, 1},
+ {{0x98c0, 0xc381, 0x3960, 0x27e0, 0x8009, 0x32a4, 0x26c0, 0x800b, 0x98c0, 0xf341, 0x3840, 0x3508, 0x8009, 0x98c0, 0xc182, 0x3960 }, 16, 0x000ab680, 1},
+ {{0x22f4, 0x8009, 0x32a4, 0x26c0, 0x800b, 0x98c0, 0xf141, 0x3840, 0x2eb0, 0x8009, 0x3284, 0x3c60, 0x800b, 0x3820, 0x2ff0, 0x800c }, 16, 0x000ab6a0, 1},
+ {{0x2c90, 0x2d10, 0x2f90, 0x0fc6, 0x38d0, 0x8008, 0x3651, 0x3c40, 0x3b62, 0x8009, 0x9ac0, 0x2f0b, 0x80b6, 0x90c0, 0x2500, 0x8140 }, 16, 0x000ab6c0, 1},
+ {{0x96c0, 0x5013, 0x2704, 0x8050, 0x98c0, 0x6c7c, 0x7452, 0x2b02, 0x8002, 0x34d4, 0x3e40, 0x3b68, 0x8009, 0x2d7d, 0x34d2, 0x3840 }, 16, 0x000ab6e0, 1},
+ {{0x3b64, 0x8009, 0x96c0, 0x4514, 0x2300, 0x8050, 0x0740, 0x3b60, 0x8009, 0x94c8, 0x4878, 0x487e, 0x9ac0, 0x7550, 0x3860, 0x2072 }, 16, 0x000ab700, 1},
+ {{0x8009, 0x9f43, 0x98c0, 0x7452, 0x74d2, 0x2b02, 0x8002, 0x0510, 0x3d60, 0x2078, 0x8009, 0x3860, 0x2074, 0x8009, 0x0260, 0x2070 }, 16, 0x000ab720, 1},
+ {{0x8009, 0x94c8, 0x4878, 0x487d, 0x9ac0, 0x7550, 0x3d40, 0x3dea, 0x8009, 0x9f43, 0x98c0, 0x7452, 0x74d2, 0x2b02, 0x8002, 0x0515 }, 16, 0x000ab740, 1},
+ {{0x3e40, 0x3df0, 0x8009, 0x3f40, 0x3dec, 0x8009, 0x0240, 0x3de8, 0x8009, 0x94c8, 0x487f, 0x487e, 0xe768, 0x94c0, 0x9e21, 0x9f21 }, 16, 0x000ab760, 1},
+ {{0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x5210, 0x280b, 0x8002, 0x51d3, 0x64e9, 0x94c0, 0xf585 }, 16, 0x000ab780, 1},
+ {{0x803d, 0x96c0, 0x70f2, 0x2b0d, 0x8002, 0x94c7, 0x66ea, 0x6d10, 0x8427, 0x96c0, 0x9b45, 0x2b03, 0x8008, 0x3941, 0x1411, 0xcc42 }, 16, 0x000ab7a0, 1},
+ {{0x90c0, 0xecfc, 0xec1d, 0x1514, 0x4414, 0x4519, 0x92d0, 0x53d3, 0x71f2, 0x92c3, 0x6d10, 0x4210, 0x9f71, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ab7c0, 1},
+ {{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x270e, 0x8020, 0x32c4, 0x29f0, 0x800a, 0x98c0, 0xe7ee, 0x07a4, 0x33be, 0x8009 }, 16, 0x000ab7e0, 1},
+ {{0x0ec6, 0x38d0, 0x8008, 0x90c0, 0x2e0b, 0x804e, 0x55d3, 0x3b1c, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7464, 0x0e86, 0x22d8, 0x8009 }, 16, 0x000ab800, 1},
+ {{0x90c0, 0xee48, 0x4016, 0x09c6, 0x38d0, 0x8008, 0x90c0, 0x290b, 0x804e, 0x56d3, 0x3ccc, 0x8208, 0x3244, 0x3d90, 0x800a, 0x7464 }, 16, 0x000ab820, 1},
+ {{0x0a86, 0x22d8, 0x8009, 0x90c0, 0xea4a, 0x4012, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0c, 0x804c, 0x50d4, 0x3119, 0x80ff, 0x3244 }, 16, 0x000ab840, 1},
+ {{0x3d90, 0x800a, 0x7461, 0x0986, 0x22d0, 0x8009, 0x90c0, 0xe948, 0x4011, 0x09c6, 0x38d0, 0x8008, 0x90c0, 0x290b, 0x804c, 0x52d3 }, 16, 0x000ab860, 1},
+ {{0x34c9, 0x8208, 0x3244, 0x3d90, 0x800a, 0x7461, 0x0c86, 0x22d0, 0x8009, 0x90c0, 0xec4a, 0x4014, 0x0fc6, 0x38d0, 0x8008, 0x90c0 }, 16, 0x000ab880, 1},
+ {{0x2f0a, 0x8050, 0x53d2, 0x371b, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7463, 0x0e86, 0x22dc, 0x8009, 0x90c0, 0xee48, 0x4016, 0x0dc6 }, 16, 0x000ab8a0, 1},
+ {{0x38d0, 0x8008, 0x90c0, 0x2d0c, 0x8050, 0x50d4, 0x30cc, 0x8208, 0x3244, 0x3d90, 0x800a, 0x7464, 0x0f86, 0x22dc, 0x8009, 0x90c0 }, 16, 0x000ab8c0, 1},
+ {{0xef4a, 0x4017, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c0d, 0x8052, 0x52d5, 0x351a, 0x80ff, 0x3244, 0x3d90, 0x800a, 0x7462, 0x0d86 }, 16, 0x000ab8e0, 1},
+ {{0x22d4, 0x8009, 0x90c0, 0xed48, 0x4015, 0x0ec6, 0x38d0, 0x8008, 0x90c0, 0x2e0c, 0x8052, 0x56d4, 0x3cca, 0x8208, 0x3244, 0x3d90 }, 16, 0x000ab900, 1},
+ {{0x800a, 0x7462, 0x0b86, 0x22d4, 0x8009, 0x3920, 0x336c, 0x8009, 0xeb4a, 0x4013, 0x0484, 0x2ca0, 0x8009, 0x266a, 0x3a61, 0x0c86 }, 16, 0x000ab920, 1},
+ {{0x22d0, 0x8009, 0x8429, 0x0480, 0x2ca0, 0x8009, 0x0426, 0x336c, 0x8009, 0x4494, 0x0986, 0x22d0, 0x8009, 0x0026, 0x336c, 0x8009 }, 16, 0x000ab940, 1},
+ {{0x98c0, 0xe944, 0x30a4, 0x39b4, 0x800a, 0x4091, 0x0ac6, 0x38d0, 0x8008, 0x90c0, 0x2a0e, 0x8024, 0x16d6, 0x0a86, 0x22d0, 0x8009 }, 16, 0x000ab960, 1},
+ {{0x3d1e, 0x80ff, 0x7f42, 0xcb46, 0x90c0, 0xeb19, 0x5293, 0x4292, 0x0ac6, 0x38d0, 0x8008, 0x0f86, 0x22d0, 0x8009, 0x2a0d, 0x8024 }, 16, 0x000ab980, 1},
+ {{0x15d5, 0xef44, 0x3aca, 0x8208, 0xce42, 0x90c0, 0xeefe, 0xee19, 0x5596, 0x4597, 0x98c0, 0x3c20, 0x218a, 0x8009, 0xc381, 0x98c0 }, 16, 0x000ab9a0, 1},
+ {{0x0b86, 0x22d8, 0x8009, 0xc081, 0x1414, 0x02a4, 0x33be, 0x8009, 0x9ac0, 0xd221, 0x5993, 0x3880, 0x2be0, 0x8009, 0x94c0, 0xeb48 }, 16, 0x000ab9c0, 1},
+ {{0x804d, 0x1513, 0xedeb, 0x94c0, 0xed64, 0xeb42, 0x1495, 0x5113, 0x94c0, 0xf206, 0xf307, 0x94c0, 0xf105, 0xf442, 0x32e4, 0x208e }, 16, 0x000ab9e0, 1},
+ {{0x800a, 0x94c0, 0xf501, 0xc7a0, 0x98c0, 0xc6a0, 0x3980, 0x2be0, 0x8009, 0x3224, 0x3990, 0x800a, 0x98c0, 0xf601, 0x3820, 0x2178 }, 16, 0x000aba00, 1},
+ {{0x8009, 0x31a4, 0x3a62, 0x800a, 0x98c0, 0x0f86, 0x22d8, 0x8009, 0xf007, 0x03a4, 0x33be, 0x8009, 0x1997, 0xef48, 0x1017, 0xebef }, 16, 0x000aba20, 1},
+ {{0x94c0, 0xeb64, 0xef42, 0x1293, 0x5417, 0x94c0, 0xf306, 0xf242, 0x94c0, 0xf405, 0xf001, 0x32e4, 0x208e, 0x800a, 0x3880, 0x26a0 }, 16, 0x000aba40, 1},
+ {{0x8009, 0x98c0, 0x3c00, 0x3816, 0x8009, 0xc481, 0x0b86, 0x22d0, 0x8009, 0x1014, 0x02a4, 0x33be, 0x8009, 0x9ac0, 0xd021, 0x5993 }, 16, 0x000aba60, 1},
+ {{0x3880, 0x2a60, 0x8009, 0x94c0, 0xeb48, 0x8045, 0x1013, 0xedeb, 0x94c0, 0xed64, 0xeb42, 0x1313, 0x5195, 0x94c0, 0xf407, 0xf206 }, 16, 0x000aba80, 1},
+ {{0x94c0, 0xf305, 0xf142, 0x32e4, 0x208e, 0x800a, 0xf001, 0x98c0, 0xf701, 0x3980, 0x2a60, 0x8009, 0x3224, 0x3990, 0x800a, 0x3800 }, 16, 0x000abaa0, 1},
+ {{0x3804, 0x8009, 0x31a4, 0x3b08, 0x800a, 0x98c0, 0x0a86, 0x22d0, 0x8009, 0xc181, 0x98c0, 0xf107, 0x05a4, 0x33be, 0x8009, 0x1992 }, 16, 0x000abac0, 1},
+ {{0xea48, 0x1012, 0xebea, 0x94c0, 0xea42, 0xeb64, 0x1193, 0x5312, 0x94c0, 0xf506, 0xf142, 0x94c0, 0xf305, 0xf001, 0x32e4, 0x208e }, 16, 0x000abae0, 1},
+ {{0x800a, 0x3880, 0x23a0, 0x8009, 0x3900, 0x34a6, 0x8009, 0x0e86, 0x22dc, 0x8009, 0x1411, 0x06a4, 0x33be, 0x8009, 0x96c0, 0xd221 }, 16, 0x000abb00, 1},
+ {{0xc481, 0x5996, 0x94c0, 0xee48, 0x804d, 0x1516, 0xedee, 0x94c0, 0xed64, 0xee42, 0x1016, 0x5395, 0x94c0, 0xf407, 0xf606, 0x94c0 }, 16, 0x000abb20, 1},
+ {{0xf005, 0xf342, 0x32e4, 0x208e, 0x800a, 0x98c0, 0xf501, 0x3880, 0x2520, 0x8009, 0x98c0, 0xf701, 0x3980, 0x2520, 0x8009, 0x3224 }, 16, 0x000abb40, 1},
+ {{0x3990, 0x800a, 0x3800, 0x3494, 0x8009, 0x31a4, 0x3bae, 0x800a, 0x98c0, 0x0f86, 0x22dc, 0x8009, 0xc381, 0x98c0, 0xf307, 0x00a4 }, 16, 0x000abb60, 1},
+ {{0x33be, 0x8009, 0x1997, 0xef48, 0x1317, 0xebef, 0x94c0, 0xef42, 0xeb64, 0x1593, 0x5217, 0x94c0, 0xf006, 0xf542, 0x94c0, 0xf205 }, 16, 0x000abb80, 1},
+ {{0xf301, 0x32e4, 0x208e, 0x800a, 0x3880, 0x22e0, 0x8009, 0x98c0, 0x3e00, 0x3212, 0x8009, 0xc481, 0x0b86, 0x22d4, 0x8009, 0x1316 }, 16, 0x000abba0, 1},
+ {{0x3880, 0x28e0, 0x8009, 0x9ac0, 0xd1a1, 0x03a4, 0x33be, 0x8009, 0x5993, 0x94c0, 0xeb48, 0x8045, 0x1113, 0xedeb, 0x94c0, 0xed64 }, 16, 0x000abbc0, 1},
+ {{0xeb42, 0x1213, 0x5595, 0x94c0, 0xf407, 0xf306, 0x94c0, 0xf205, 0xf542, 0x32e4, 0x208e, 0x800a, 0xf101, 0x98c0, 0xf701, 0x3980 }, 16, 0x000abbe0, 1},
+ {{0x28e0, 0x8009, 0x3224, 0x3990, 0x800a, 0x3800, 0x3200, 0x8009, 0x31a4, 0x3c54, 0x800a, 0x98c0, 0x0e86, 0x22d4, 0x8009, 0xc481 }, 16, 0x000abc00, 1},
+ {{0x98c0, 0xf407, 0x05a4, 0x33be, 0x8009, 0x1996, 0xee48, 0x1116, 0xefee, 0x94c0, 0xee42, 0xef64, 0x1497, 0x5216, 0x94c0, 0xf506 }, 16, 0x000abc20, 1},
+ {{0xf442, 0x94c0, 0xf205, 0xf101, 0x32e4, 0x208e, 0x800a, 0x3880, 0x25e0, 0x8009, 0x09c6, 0x38d0, 0x8008, 0x3840, 0x3508, 0x8009 }, 16, 0x000abc40, 1},
+ {{0x290f, 0x8100, 0x13d7, 0x3980, 0x23a0, 0x8009, 0x371b, 0x8002, 0x65e9, 0x844d, 0x32a4, 0x30b0, 0x800b, 0xf741, 0x98c0, 0xf741 }, 16, 0x000abc60, 1},
+ {{0x3980, 0x23a0, 0x8009, 0x3244, 0x2d10, 0x800b, 0x3860, 0x3d54, 0x8009, 0x98c0, 0xf741, 0x3980, 0x22e0, 0x8009, 0x3244, 0x2d10 }, 16, 0x000abc80, 1},
+ {{0x800b, 0x3860, 0x3f18, 0x8009, 0x98c0, 0xf741, 0x3980, 0x25e0, 0x8009, 0x3244, 0x2d10, 0x800b, 0x3860, 0x3b90, 0x8009, 0x98c0 }, 16, 0x000abca0, 1},
+ {{0xf701, 0x3980, 0x23a0, 0x8009, 0x32a4, 0x3790, 0x800a, 0x3840, 0x3b60, 0x8009, 0x98c0, 0xf701, 0x3980, 0x22e0, 0x8009, 0x32a4 }, 16, 0x000abcc0, 1},
+ {{0x3790, 0x800a, 0x3860, 0x2070, 0x8009, 0x98c0, 0xf701, 0x3980, 0x25e0, 0x8009, 0x32a4, 0x3790, 0x800a, 0x3840, 0x3de8, 0x8009 }, 16, 0x000abce0, 1},
+ {{0x27ea, 0x3657, 0x3880, 0x2460, 0x8009, 0x94c0, 0x7a61, 0x841d, 0x9f44, 0x1018, 0x3f80, 0x2760, 0x8009, 0x2103, 0x800a, 0x94c8 }, 16, 0x000abd00, 1},
+ {{0x401f, 0x5018, 0x4017, 0x27ea, 0x3757, 0x3c80, 0x2820, 0x8009, 0x8479, 0x3d80, 0x2760, 0x8009, 0x3a80, 0x25e0, 0x8009, 0x3f80 }, 16, 0x000abd20, 1},
+ {{0x22e0, 0x8009, 0x3e80, 0x23a0, 0x8009, 0x3b80, 0x26a0, 0x8009, 0x98c0, 0x05a6, 0x33b8, 0x8009, 0xfc44, 0x96c0, 0x7ac1, 0xfd43 }, 16, 0x000abd40, 1},
+ {{0xfa42, 0x94c0, 0xff41, 0xe9ee, 0x94c0, 0xe8eb, 0xfc45, 0x94c0, 0xfd46, 0xfa47, 0x3224, 0x3120, 0x800c, 0x98c0, 0xfb48, 0x05a2 }, 16, 0x000abd60, 1},
+ {{0x33b8, 0x8009, 0x96c0, 0x7b61, 0xfcc5, 0xfdc6, 0x96c0, 0x676a, 0xfac7, 0xfbc8, 0x94c0, 0xee42, 0xef42, 0x94c0, 0xeb42, 0xea42 }, 16, 0x000abd80, 1},
+ {{0x81b0, 0x94c0, 0xed42, 0xec42, 0x0ac6, 0x38d0, 0x8008, 0x3980, 0x2760, 0x8009, 0x2a0d, 0x8100, 0x16d5, 0x3840, 0x2eb0, 0x8009 }, 16, 0x000abda0, 1},
+ {{0x3d1e, 0x8002, 0x6769, 0x8479, 0x32a4, 0x30b0, 0x800b, 0xf741, 0x98c0, 0x3181, 0x2760, 0x8009, 0xf742, 0x94c0, 0xf141, 0xc941 }, 16, 0x000abdc0, 1},
+ {{0x3264, 0x2010, 0x800b, 0x3860, 0x22f4, 0x8009, 0x98c0, 0x3581, 0x2820, 0x8009, 0xf742, 0x94c0, 0xf541, 0xc945, 0x3264, 0x2010 }, 16, 0x000abde0, 1},
+ {{0x800b, 0x3860, 0x27e0, 0x8009, 0x98c0, 0x3521, 0x2ff0, 0x800c, 0xf741, 0x98c0, 0xf542, 0x3980, 0x2460, 0x8009, 0x3284, 0x3d40 }, 16, 0x000abe00, 1},
+ {{0x800b, 0x3880, 0x2760, 0x8009, 0x98c0, 0xf741, 0x3980, 0x2760, 0x8009, 0x3244, 0x2d10, 0x800b, 0x3880, 0x20dc, 0x8009, 0x3800 }, 16, 0x000abe20, 1},
+ {{0x3d3e, 0x8009, 0x3980, 0x2820, 0x8009, 0x1010, 0x3800, 0x3d2c, 0x8009, 0x98c0, 0xd021, 0x04a4, 0x33be, 0x8009, 0x8011, 0x3224 }, 16, 0x000abe40, 1},
+ {{0x3a38, 0x800a, 0xf701, 0x31a4, 0x3e8e, 0x800a, 0x266a, 0x3a61, 0x3d80, 0x2820, 0x8009, 0x8419, 0x9f44, 0x1c1d, 0x3b80, 0x29a0 }, 16, 0x000abe60, 1},
+ {{0x8009, 0x2103, 0x800a, 0x94c8, 0x4c1b, 0x5c1d, 0x4c13, 0x3f00, 0x3b86, 0x8009, 0x3980, 0x2760, 0x8009, 0x1217, 0x3800, 0x3b74 }, 16, 0x000abe80, 1},
+ {{0x8009, 0x98c0, 0xd121, 0x03a4, 0x33be, 0x8009, 0x8011, 0x3224, 0x3a38, 0x800a, 0xf701, 0x31a4, 0x3ede, 0x800a, 0x25ea, 0x39e1 }, 16, 0x000abea0, 1},
+ {{0x3a80, 0x2760, 0x8009, 0x8419, 0x9f43, 0x161a, 0x3d80, 0x2b20, 0x8009, 0x2103, 0x800a, 0x94c8, 0x461d, 0x561a, 0x4615, 0x33c4 }, 16, 0x000abec0, 1},
+ {{0x3120, 0x800a, 0x27ef, 0x9fe0, 0xe7ef, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000abee0, 1},
+ {{0x3264, 0x2470, 0x800a, 0x94c0, 0x9e20, 0x9f20, 0x32a4, 0x3230, 0x800a, 0x08a2, 0x3330, 0x8009, 0x2c10, 0x3fa0, 0x3354, 0x8009 }, 16, 0x000abf00, 1},
+ {{0x3264, 0x3c70, 0x800a, 0x4897, 0x94c0, 0xef4c, 0xc081, 0x3264, 0x3c70, 0x800a, 0x4897, 0x94c0, 0xef44, 0xc082, 0x3264, 0x3c70 }, 16, 0x000abf20, 1},
+ {{0x800a, 0x4897, 0x9ac0, 0x6c10, 0xef44, 0x3284, 0x2090, 0x800a, 0x4897, 0x96c0, 0xc081, 0x2f0e, 0x8020, 0x3284, 0x2090, 0x800a }, 16, 0x000abf40, 1},
+ {{0x4896, 0x94c0, 0xee44, 0xc082, 0x3284, 0x2090, 0x800a, 0x4896, 0x9ac0, 0x6c10, 0xee44, 0x3244, 0x2150, 0x800c, 0x4896, 0x94c0 }, 16, 0x000abf60, 1},
+ {{0xcba4, 0xedee, 0xc081, 0x98c0, 0xed3b, 0x3244, 0x2150, 0x800c, 0x4895, 0x94c0, 0xc9a0, 0xecee, 0xc082, 0x98c0, 0xec39, 0x3244 }, 16, 0x000abf80, 1},
+ {{0x2150, 0x800c, 0x4894, 0x94c0, 0xecee, 0xc083, 0x98c0, 0xec7c, 0x3244, 0x2150, 0x800c, 0x4894, 0x2c10, 0xedee, 0x98c0, 0xed78 }, 16, 0x000abfa0, 1},
+ {{0x3264, 0x33e0, 0x800a, 0x4895, 0x94c0, 0xedee, 0xc081, 0x98c0, 0xed74, 0x3264, 0x33e0, 0x800a, 0x4895, 0x94c0, 0xebee, 0xc082 }, 16, 0x000abfc0, 1},
+ {{0x98c0, 0xeb70, 0x3264, 0x33e0, 0x800a, 0x4893, 0xebee, 0x98c0, 0xeb6c, 0x32e4, 0x2060, 0x800a, 0x4893, 0x96c0, 0xc083, 0x2e0f }, 16, 0x000abfe0, 1},
+ {{0x8020, 0x3264, 0x3870, 0x800a, 0x4897, 0x2c10, 0xeaef, 0x98c0, 0xea64, 0x3264, 0x3870, 0x800a, 0x4892, 0x94c0, 0xeaef, 0xc081 }, 16, 0x000ac000, 1},
+ {{0x98c0, 0xea70, 0x3264, 0x3870, 0x800a, 0x4892, 0x94c0, 0xe9ef, 0xc082, 0x98c0, 0xe96c, 0x3264, 0x3870, 0x800a, 0x4891, 0xef68 }, 16, 0x000ac020, 1},
+ {{0x4897, 0x94c0, 0x9e21, 0x9f21, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x3384, 0x2130, 0x800a, 0x0bc6, 0x2100, 0x8009, 0x0284, 0x2ca2 }, 16, 0x000ac040, 1},
+ {{0x8009, 0x9ac0, 0x20e0, 0x99ff, 0x90c0, 0x2b09, 0x8064, 0x98c0, 0xdd00, 0x3880, 0x2ca4, 0x8009, 0x32a4, 0x2990, 0x800a, 0x0280 }, 16, 0x000ac060, 1},
+ {{0x2ca2, 0x8009, 0x33a4, 0x3f00, 0x800a, 0x3224, 0x3000, 0x800c, 0x38a0, 0x3070, 0x8009, 0x0284, 0x2ca2, 0x8009, 0x0902, 0xa060 }, 16, 0x000ac080, 1},
+ {{0x74f2, 0x96c0, 0x33fa, 0x9fe0, 0x9f70, 0x0280, 0x2ca2, 0x8009, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ac0a0, 1},
+ {{0x98c0, 0x38a0, 0x3330, 0x8009, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x3ec0, 0xa00c, 0x74d7, 0x7456, 0xeaef, 0x0dc6, 0x2100, 0x8009 }, 16, 0x000ac0c0, 1},
+ {{0x3a00, 0xa100, 0x0fc6, 0x38d0, 0x8008, 0xe9ee, 0x90c0, 0x3680, 0xa000, 0x2f08, 0x8160, 0x3480, 0xa000, 0x5210, 0x3480, 0xa000 }, 16, 0x000ac0e0, 1},
+ {{0x4215, 0x0cc6, 0x38d0, 0x8008, 0x0fc6, 0x2100, 0x8009, 0x2c0c, 0x8162, 0x1514, 0xef42, 0x4517, 0x0ec6, 0x38d0, 0x8008, 0x0ac6 }, 16, 0x000ac100, 1},
+ {{0x2100, 0x8009, 0x2e0d, 0x8164, 0x1715, 0xea44, 0x4712, 0x09c6, 0x38d0, 0x8008, 0x0cc6, 0x2100, 0x8009, 0x290b, 0x8166, 0x1113 }, 16, 0x000ac120, 1},
+ {{0xec46, 0x4114, 0x0dc6, 0x38d0, 0x8008, 0x0ec6, 0x2100, 0x8009, 0x2d08, 0x8170, 0x1110, 0xee48, 0x4116, 0x0dc6, 0x38d0, 0x8008 }, 16, 0x000ac140, 1},
+ {{0x0bc6, 0x2100, 0x8009, 0x2d0a, 0x8172, 0x1712, 0xeb4a, 0x4713, 0x0ec6, 0x38d0, 0x8008, 0x0fc6, 0x2100, 0x8009, 0x2e0d, 0x8174 }, 16, 0x000ac160, 1},
+ {{0x11d5, 0xef4c, 0x4117, 0x0fc6, 0x38d0, 0x8008, 0x08c6, 0x2100, 0x8009, 0x2f0e, 0x8168, 0x1716, 0xe850, 0x4710, 0x0dc6, 0x38d0 }, 16, 0x000ac180, 1},
+ {{0x8008, 0x0fc6, 0x2100, 0x8009, 0x2d09, 0x816a, 0x1011, 0xef52, 0x4017, 0x08c6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x280c }, 16, 0x000ac1a0, 1},
+ {{0x816c, 0x1714, 0xe954, 0x4711, 0x09c6, 0x38d0, 0x8008, 0x0fc6, 0x2100, 0x8009, 0x2909, 0x816e, 0x1211, 0xef56, 0x4217, 0x0dc6 }, 16, 0x000ac1c0, 1},
+ {{0x38d0, 0x8008, 0x0cc6, 0x2100, 0x8009, 0x2d09, 0x8174, 0x12d1, 0xec58, 0x4214, 0x0bc6, 0x38d0, 0x8008, 0x0ec6, 0x2100, 0x8009 }, 16, 0x000ac1e0, 1},
+ {{0x2b0d, 0x81e6, 0x96c0, 0x5115, 0x2e0b, 0x8028, 0x4113, 0x0dc6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x2d0a, 0x81e8, 0x96c0 }, 16, 0x000ac200, 1},
+ {{0x5212, 0x2909, 0x802a, 0x4211, 0x0ec6, 0x38d0, 0x8008, 0x08c6, 0x2100, 0x8009, 0x2e0c, 0x81ea, 0x96c0, 0x5614, 0x2809, 0x802c }, 16, 0x000ac220, 1},
+ {{0x4611, 0x08c6, 0x38d0, 0x8008, 0x0fc6, 0x2100, 0x8009, 0x280e, 0x81ec, 0x96c0, 0x5116, 0x2f0c, 0x802e, 0x4114, 0x0bc6, 0x38d0 }, 16, 0x000ac240, 1},
+ {{0x8008, 0x0ec6, 0x2100, 0x8009, 0x2b0b, 0x81ee, 0x96c0, 0x5213, 0x2e09, 0x8030, 0x4211, 0x09c6, 0x38d0, 0x8008, 0x0bc6, 0x2100 }, 16, 0x000ac260, 1},
+ {{0x8009, 0x290e, 0x81f0, 0x96c0, 0x5116, 0x2b0f, 0x8032, 0x4117, 0x0fc6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x2f0d, 0x81f2 }, 16, 0x000ac280, 1},
+ {{0x96c0, 0x5015, 0x2909, 0x8034, 0x4011, 0x0ac6, 0x38d0, 0x8008, 0x0dc6, 0x2100, 0x8009, 0x2a0b, 0x81f4, 0x96c0, 0x5413, 0x2d0f }, 16, 0x000ac2a0, 1},
+ {{0x8036, 0x4417, 0x0cc6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x2c0b, 0x8126, 0x96c0, 0x5313, 0x290a, 0x8038, 0x4312, 0x08c6 }, 16, 0x000ac2c0, 1},
+ {{0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x280b, 0x813e, 0x96c0, 0x50d3, 0x290a, 0x803a, 0x4012, 0x0ec6, 0x38d0, 0x8008, 0x0dc6 }, 16, 0x000ac2e0, 1},
+ {{0x2100, 0x8009, 0x2e0f, 0x81fc, 0x96c0, 0x5617, 0x2d0d, 0x803c, 0x4615, 0x0ac6, 0x38d0, 0x8008, 0x0ec6, 0x2100, 0x8009, 0x2a0a }, 16, 0x000ac300, 1},
+ {{0x81d6, 0x96c0, 0x5212, 0x2e0b, 0x8044, 0x4213, 0x0dc6, 0x38d0, 0x8008, 0x0ec6, 0x2100, 0x8009, 0x2d0c, 0x8132, 0x96c0, 0x5714 }, 16, 0x000ac320, 1},
+ {{0x2e0b, 0x8046, 0x4713, 0x09c6, 0x38d0, 0x8008, 0x0cc6, 0x2100, 0x8009, 0x2909, 0x8134, 0x96c0, 0x5211, 0x2c0d, 0x8048, 0x4215 }, 16, 0x000ac340, 1},
+ {{0x08c6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x280d, 0x8138, 0x96c0, 0x53d5, 0x290f, 0x804a, 0x4317, 0x09c6, 0x38d0, 0x8008 }, 16, 0x000ac360, 1},
+ {{0x0ac6, 0x2100, 0x8009, 0x290c, 0x8130, 0x96c0, 0x56d4, 0x2a0d, 0x804c, 0x4615, 0x0fc6, 0x38d0, 0x8008, 0x0dc6, 0x2100, 0x8009 }, 16, 0x000ac380, 1},
+ {{0x2f0c, 0x8136, 0x96c0, 0x5214, 0x2d0e, 0x804e, 0x4216, 0x0ac6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x2a0f, 0x815c, 0x96c0 }, 16, 0x000ac3a0, 1},
+ {{0x5617, 0x2908, 0x8050, 0x4610, 0x08c6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x280c, 0x81fe, 0x96c0, 0x5414, 0x2909, 0x8052 }, 16, 0x000ac3c0, 1},
+ {{0x4411, 0x09c6, 0x38d0, 0x8008, 0x0ec6, 0x2100, 0x8009, 0x290d, 0x81a2, 0x96c0, 0x5615, 0x2e0c, 0x8064, 0x4614, 0x09c6, 0x2100 }, 16, 0x000ac3e0, 1},
+ {{0x8009, 0x0bc6, 0x38d0, 0x8008, 0x2908, 0x8066, 0x2b0e, 0x81a4, 0x1216, 0xc7fd, 0x4210, 0x08c6, 0x38d0, 0x8008, 0x0bc6, 0x2100 }, 16, 0x000ac400, 1},
+ {{0x8009, 0x280d, 0x81a6, 0x96c0, 0x5215, 0x2b0f, 0x8068, 0x4217, 0x0ec6, 0x38d0, 0x8008, 0x0dc6, 0x2100, 0x8009, 0x2e0c, 0x81a8 }, 16, 0x000ac420, 1},
+ {{0x96c0, 0x5414, 0x2d0f, 0x806a, 0x4417, 0x0cc6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x2c0e, 0x81aa, 0x96c0, 0x5016, 0x290d }, 16, 0x000ac440, 1},
+ {{0x806c, 0x4015, 0x0dc6, 0x38d0, 0x8008, 0x08c6, 0x2100, 0x8009, 0x2d0c, 0x81ac, 0x96c0, 0x5614, 0x280f, 0x806e, 0x4617, 0x0ac6 }, 16, 0x000ac460, 1},
+ {{0x38d0, 0x8008, 0x0bc6, 0x2100, 0x8009, 0x2a0e, 0x81ae, 0x96c0, 0x5616, 0x2b0c, 0x8070, 0x4614, 0x0ec6, 0x38d0, 0x8008, 0x09c6 }, 16, 0x000ac480, 1},
+ {{0x2100, 0x8009, 0x2e0b, 0x81b0, 0x96c0, 0x5413, 0x2908, 0x8072, 0x4410, 0x0ec6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x2e0d }, 16, 0x000ac4a0, 1},
+ {{0x81b2, 0x96c0, 0x5115, 0x290a, 0x8074, 0x4112, 0x0ec6, 0x38d0, 0x8008, 0x0cc6, 0x2100, 0x8009, 0x2e08, 0x81b4, 0x96c0, 0x5510 }, 16, 0x000ac4c0, 1},
+ {{0x2c0d, 0x8076, 0x4515, 0x09c6, 0x38d0, 0x8008, 0x08c6, 0x2100, 0x8009, 0x290c, 0x81b6, 0x96c0, 0x5114, 0x280b, 0x8078, 0x4113 }, 16, 0x000ac4e0, 1},
+ {{0x0fc6, 0x38d0, 0x8008, 0x08c6, 0x2100, 0x8009, 0x2f09, 0x81b8, 0x96c0, 0x5311, 0x280b, 0x807a, 0x4313, 0x09c6, 0x38d0, 0x8008 }, 16, 0x000ac500, 1},
+ {{0x0ec6, 0x2100, 0x8009, 0x290b, 0x81ba, 0x96c0, 0x5013, 0x2e0c, 0x807e, 0x4014, 0x0fc6, 0x38d0, 0x8008, 0x0ec6, 0x2100, 0x8009 }, 16, 0x000ac520, 1},
+ {{0x2f0a, 0x81bc, 0x96c0, 0x5412, 0x2e0b, 0x8080, 0x4413, 0x0dc6, 0x38d0, 0x8008, 0x0fc6, 0x2100, 0x8009, 0x2d09, 0x81be, 0x96c0 }, 16, 0x000ac540, 1},
+ {{0x5511, 0x2f0f, 0x8082, 0x4517, 0x08c6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x280d, 0x81c2, 0x96c0, 0x5215, 0x290a, 0x8086 }, 16, 0x000ac560, 1},
+ {{0x4212, 0x09c6, 0x38d0, 0x8008, 0x0dc6, 0x2100, 0x8009, 0x290f, 0x81c4, 0x96c0, 0x5517, 0x2d0a, 0x8088, 0x4512, 0x0bc6, 0x38d0 }, 16, 0x000ac580, 1},
+ {{0x8008, 0x0dc6, 0x2100, 0x8009, 0x2b0e, 0x81c6, 0x96c0, 0x5516, 0x2d0f, 0x808a, 0x4517, 0x0fc6, 0x38d0, 0x8008, 0x0bc6, 0x2100 }, 16, 0x000ac5a0, 1},
+ {{0x8009, 0x2f0d, 0x8124, 0x96c0, 0x5315, 0x2b0f, 0x808c, 0x4317, 0x0fc6, 0x38d0, 0x8008, 0x0dc6, 0x2100, 0x8009, 0x2f08, 0x81c8 }, 16, 0x000ac5c0, 1},
+ {{0x96c0, 0x51d0, 0x2d0b, 0x808e, 0x4113, 0x0ac6, 0x38d0, 0x8008, 0x0bc6, 0x2100, 0x8009, 0x2a0e, 0x81d2, 0x96c0, 0x56d6, 0x2b09 }, 16, 0x000ac5e0, 1},
+ {{0x8090, 0x4611, 0x0bc6, 0x38d0, 0x8008, 0x0fc6, 0x2100, 0x8009, 0x2b0b, 0x81ca, 0x96c0, 0x5113, 0x2f0e, 0x8092, 0x4116, 0x09c6 }, 16, 0x000ac600, 1},
+ {{0x38d0, 0x8008, 0x0bc6, 0x2100, 0x8009, 0x290f, 0x81cc, 0x96c0, 0x5417, 0x2b0c, 0x807c, 0x4414, 0x0fc6, 0x38d0, 0x8008, 0x90c0 }, 16, 0x000ac620, 1},
+ {{0x2f0a, 0x81c0, 0x5612, 0xdf86, 0x4712, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0d, 0x8102, 0x55d5, 0x3b18, 0x8001, 0x6469, 0x90c0 }, 16, 0x000ac640, 1},
+ {{0x94c3, 0x2d0d, 0x80be, 0x92c3, 0x5415, 0x94c3, 0x0904, 0xa002, 0x92c3, 0x4415, 0x0dc6, 0x38d0, 0x8008, 0x08c6, 0x2100, 0x8009 }, 16, 0x000ac660, 1},
+ {{0x2d0f, 0x81c0, 0x96c0, 0x5617, 0x280e, 0x8084, 0x4616, 0x0fc6, 0x38d0, 0x8008, 0x0bc6, 0x2100, 0x8009, 0x2f09, 0x81c0, 0x1711 }, 16, 0x000ac680, 1},
+ {{0x05a4, 0x33c0, 0x8009, 0x98c0, 0xd2a8, 0x07c0, 0x2106, 0x8009, 0x2b0e, 0x8084, 0x94c6, 0x5216, 0xc4fe, 0x94c1, 0xc481, 0xde02 }, 16, 0x000ac6a0, 1},
+ {{0x92c3, 0xde1a, 0x4416, 0x08c6, 0x38d0, 0x8008, 0x0ac6, 0x2100, 0x8009, 0x280d, 0x810c, 0x96c0, 0x55d5, 0x2a0e, 0x80a8, 0x4516 }, 16, 0x000ac6c0, 1},
+ {{0x0ac6, 0x38d0, 0x8008, 0x0dc6, 0x2100, 0x8009, 0x2a0f, 0x810e, 0x96c0, 0x50d7, 0x2d0e, 0x80aa, 0x4016, 0x0ec6, 0x38d0, 0x8008 }, 16, 0x000ac6e0, 1},
+ {{0x08c6, 0x2100, 0x8009, 0x2e0c, 0x812a, 0x96c0, 0x5514, 0x280d, 0x80ac, 0x4515, 0x0fc6, 0x38d0, 0x8008, 0x08c6, 0x2100, 0x8009 }, 16, 0x000ac700, 1},
+ {{0x2f0a, 0x8110, 0x96c0, 0x5012, 0x280f, 0x80ae, 0x4017, 0x0ac6, 0x38d0, 0x8008, 0x0cc6, 0x2100, 0x8009, 0x2a0d, 0x81f6, 0x96c0 }, 16, 0x000ac720, 1},
+ {{0x5115, 0x2c0f, 0x80ba, 0x4117, 0x0ec6, 0x38d0, 0x8008, 0x0cc6, 0x2100, 0x8009, 0x2e0a, 0x812c, 0x96c0, 0x55d2, 0x2c08, 0x80bc }, 16, 0x000ac740, 1},
+ {{0x4510, 0x08c6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x280c, 0x813a, 0x96c0, 0x5414, 0x2908, 0x80be, 0x4410, 0x09c6, 0x38d0 }, 16, 0x000ac760, 1},
+ {{0x8008, 0x08c6, 0x2100, 0x8009, 0x290e, 0x813c, 0x96c0, 0x5116, 0x280f, 0x80c0, 0x4117, 0x09c6, 0x38d0, 0x8008, 0x0dc6, 0x2100 }, 16, 0x000ac780, 1},
+ {{0x8009, 0x290c, 0x812e, 0x96c0, 0x5414, 0x2d09, 0x80c2, 0x4411, 0x0dc6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x2d0f, 0x8128 }, 16, 0x000ac7a0, 1},
+ {{0x96c0, 0x5417, 0x290a, 0x80c4, 0x4412, 0x09c6, 0x38d0, 0x8008, 0x0ec6, 0x2100, 0x8009, 0x290a, 0x81d4, 0x96c0, 0x5512, 0x2e0e }, 16, 0x000ac7c0, 1},
+ {{0x80c6, 0x4516, 0x0fc6, 0x38d0, 0x8008, 0x0cc6, 0x2100, 0x8009, 0x2f0d, 0x81d6, 0x96c0, 0x5415, 0x2c0c, 0x80c8, 0x4414, 0x0fc6 }, 16, 0x000ac7e0, 1},
+ {{0x38d0, 0x8008, 0x0dc6, 0x2100, 0x8009, 0x2f08, 0x81d8, 0x96c0, 0x5310, 0x2d0e, 0x80ca, 0x4316, 0x0ec6, 0x38d0, 0x8008, 0x0ac6 }, 16, 0x000ac800, 1},
+ {{0x2100, 0x8009, 0x2e0d, 0x81dc, 0x96c0, 0x52cd, 0x2a0f, 0x80cc, 0x16d5, 0xda92, 0xdf1d, 0x4697, 0x08c6, 0x38d0, 0x8008, 0x0cc6 }, 16, 0x000ac820, 1},
+ {{0x2100, 0x8009, 0x280d, 0x810a, 0x96c0, 0x5715, 0x2c0c, 0x80d0, 0x3600, 0xa800, 0x77d1, 0x4714, 0x0ac6, 0x38d0, 0x8008, 0x0ec6 }, 16, 0x000ac840, 1},
+ {{0x2100, 0x8009, 0x2a0d, 0x8100, 0x96c0, 0x55d5, 0x2e0c, 0x80d4, 0x4514, 0x0cc6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x2c0c }, 16, 0x000ac860, 1},
+ {{0x8102, 0x96c0, 0x56d4, 0x290a, 0x80d6, 0x3600, 0xa800, 0x7750, 0x4612, 0x0cc6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x2c08 }, 16, 0x000ac880, 1},
+ {{0x8102, 0x96c0, 0x54d0, 0x280c, 0x803e, 0x04c0, 0x2104, 0x8009, 0x96c0, 0x5114, 0x290e, 0x80dc, 0x4116, 0x09c6, 0x38d0, 0x8008 }, 16, 0x000ac8a0, 1},
+ {{0x0fc6, 0x2100, 0x8009, 0x2908, 0x8142, 0x96c0, 0x5110, 0x2f0c, 0x80de, 0x4114, 0x0fc6, 0x38d0, 0x8008, 0x0dc6, 0x2100, 0x8009 }, 16, 0x000ac8c0, 1},
+ {{0x2f09, 0x8144, 0x96c0, 0x5011, 0x2d0e, 0x80f2, 0x4016, 0x09c6, 0x38d0, 0x8008, 0x08c6, 0x2100, 0x8009, 0x290c, 0x8146, 0x96c0 }, 16, 0x000ac8e0, 1},
+ {{0x5114, 0x2809, 0x80f0, 0x4111, 0x0fc6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x2f0d, 0x8148, 0x96c0, 0x5315, 0x2908, 0x80e0 }, 16, 0x000ac900, 1},
+ {{0x4310, 0x0cc6, 0x38d0, 0x8008, 0x09c6, 0x2100, 0x8009, 0x2c0c, 0x814a, 0x96c0, 0x5414, 0x290e, 0x80e2, 0x4416, 0x0ec6, 0x38d0 }, 16, 0x000ac920, 1},
+ {{0x8008, 0x0dc6, 0x2100, 0x8009, 0x2e0a, 0x814c, 0x96c0, 0x5312, 0x2d09, 0x80e4, 0x4311, 0x09c6, 0x38d0, 0x8008, 0x0ec6, 0x2100 }, 16, 0x000ac940, 1},
+ {{0x8009, 0x2908, 0x814e, 0x96c0, 0x5210, 0x2e0e, 0x80e6, 0x4216, 0x0ec6, 0x38d0, 0x8008, 0x08c6, 0x2100, 0x8009, 0x2e0e, 0x8150 }, 16, 0x000ac960, 1},
+ {{0x96c0, 0x5316, 0x2808, 0x80e8, 0x4310, 0x09c6, 0x38d0, 0x8008, 0x0ec6, 0x2100, 0x8009, 0x290d, 0x8152, 0x96c0, 0x5115, 0x2e0c }, 16, 0x000ac980, 1},
+ {{0x80ea, 0x4114, 0x09c6, 0x38d0, 0x8008, 0x0dc6, 0x2100, 0x8009, 0x290f, 0x8154, 0x96c0, 0x5217, 0x2d0d, 0x80ec, 0x3640, 0xa000 }, 16, 0x000ac9a0, 1},
+ {{0x4215, 0xefea, 0x0dc6, 0x38d0, 0x8008, 0x0ec6, 0x2100, 0x8009, 0x2d0d, 0x8156, 0x96c0, 0x5015, 0x2e08, 0x80ee, 0x9f70, 0x3640 }, 16, 0x000ac9c0, 1},
+ {{0xa000, 0x4010, 0xeee9, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x32c4, 0x20c0 }, 16, 0x000ac9e0, 1},
+ {{0x800a, 0xe748, 0x3e40, 0xa000, 0x6f10, 0x6e90, 0x0cc6, 0x38d0, 0x8008, 0xc9a4, 0x9ac0, 0x280d, 0x8080, 0x90c0, 0x2202, 0x8050 }, 16, 0x000aca00, 1},
+ {{0x96c0, 0xeeed, 0x2c0f, 0x8102, 0x17d7, 0x04c4, 0x2104, 0x8009, 0x9ac0, 0x2f0c, 0x80be, 0xde17, 0x2b00, 0x804c, 0x3c20, 0xa000 }, 16, 0x000aca20, 1},
+ {{0x391c, 0x8001, 0xcda0, 0x2002, 0x8048, 0x3820, 0xa000, 0x6669, 0xc9a8, 0xee39, 0x3a80, 0xa000, 0xefed, 0x03c4, 0x2106, 0x8009 }, 16, 0x000aca40, 1},
+ {{0x1014, 0xeaed, 0x38a0, 0xa100, 0xdd90, 0xeced, 0xef3a, 0x3a80, 0xa100, 0x3719, 0x8002, 0xe9ed, 0xebed, 0x3880, 0xa000, 0xec39 }, 16, 0x000aca60, 1},
+ {{0x2202, 0x805c, 0x90c0, 0x3620, 0xa100, 0xea3d, 0xeb3b, 0x36a0, 0xa000, 0xe938, 0xebed, 0x3680, 0xa000, 0xeded, 0xe9ed, 0x36c0 }, 16, 0x000aca80, 1},
+ {{0xa000, 0xeeed, 0x5895, 0x3a47, 0xa000, 0x90c0, 0xed3a, 0xc681, 0x64e9, 0x36c0, 0xa000, 0xc058, 0x5890, 0x36c0, 0xa100, 0x5897 }, 16, 0x000acaa0, 1},
+ {{0x5a94, 0x3620, 0xa000, 0x5c96, 0x5e92, 0x3600, 0xa100, 0xeb70, 0x5a93, 0x96c7, 0x6769, 0xc581, 0xe968, 0x3680, 0xa100, 0xed64 }, 16, 0x000acac0, 1},
+ {{0xee6c, 0x3680, 0xa100, 0xc84d, 0x5891, 0x3680, 0xa100, 0xce4a, 0xc259, 0x3680, 0xa000, 0xca4c, 0x5a93, 0x3680, 0xa100, 0x5e95 }, 16, 0x000acae0, 1},
+ {{0xc84e, 0x3680, 0xa100, 0xc45b, 0x5b96, 0x8064, 0x3640, 0xa000, 0x5991, 0x5a95, 0xc7fd, 0x3840, 0xa000, 0xdf80, 0x2a0f, 0x8500 }, 16, 0x000acb00, 1},
+ {{0x4714, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c0d, 0x8102, 0x57d5, 0x3f1e, 0x8001, 0x6769, 0x90c0, 0x94c3, 0x2d0c, 0x80be, 0x92c3 }, 16, 0x000acb20, 1},
+ {{0x5514, 0x94c3, 0x0905, 0xa002, 0x92c3, 0x4514, 0x0dc6, 0x38d0, 0x8008, 0x0cc6, 0x2100, 0x8009, 0x2d0d, 0x81c0, 0x96c0, 0x5315 }, 16, 0x000acb40, 1},
+ {{0x2c0c, 0x8084, 0x0314, 0x30c4, 0x2baa, 0x800a, 0x4317, 0x26e9, 0xc0fe, 0x94c0, 0xdc07, 0x8039, 0x4017, 0x0cc6, 0x38d0, 0x8008 }, 16, 0x000acb60, 1},
+ {{0x90c0, 0x2c0c, 0x81c0, 0x5514, 0x3b18, 0x8002, 0x6469, 0x90c0, 0x94c3, 0x2d00, 0x80be, 0x90c0, 0x92c3, 0xec3d, 0x92c3, 0x54d4 }, 16, 0x000acb80, 1},
+ {{0x94c3, 0x0904, 0xa001, 0x92c3, 0x4414, 0x3a00, 0xa100, 0x0cc6, 0x38d0, 0x8008, 0xe84e, 0x9ac0, 0x2f00, 0x80c0, 0x90c0, 0x2302 }, 16, 0x000acba0, 1},
+ {{0x82a6, 0x3c40, 0xa000, 0x2c0d, 0x8102, 0x90c0, 0x280c, 0x82aa, 0x3800, 0xa100, 0x50d5, 0x2d0d, 0x80be, 0x98c0, 0x00c0, 0x2104 }, 16, 0x000acbc0, 1},
+ {{0x8009, 0xc2fe, 0x3680, 0xa100, 0x5015, 0xed3f, 0x98c0, 0x00c0, 0x2106, 0x8009, 0xe8ec, 0x3a00, 0xa100, 0x34a2, 0x3c9c, 0x8009 }, 16, 0x000acbe0, 1},
+ {{0x57d5, 0x3860, 0xa100, 0xe83b, 0x2a0a, 0x84b4, 0x38c0, 0xa100, 0x471c, 0x2a09, 0x805e, 0x3880, 0xa000, 0x56d5, 0x2302, 0x82a8 }, 16, 0x000acc00, 1},
+ {{0x3840, 0xa000, 0xdd06, 0xe0e9, 0xc3f7, 0x3680, 0xa100, 0x4215, 0xc25f, 0x3a00, 0xa100, 0x0dc6, 0x38d0, 0x8008, 0xedec, 0x36a0 }, 16, 0x000acc20, 1},
+ {{0xa100, 0xed3b, 0xeaec, 0x3c80, 0xa000, 0x2d09, 0x8102, 0x90c0, 0x2302, 0x8150, 0x3880, 0xa000, 0x57d1, 0x2f00, 0x81dc, 0x38a0 }, 16, 0x000acc40, 1},
+ {{0xa100, 0xdd87, 0x4714, 0xea3b, 0x3880, 0xa000, 0x4311, 0x2402, 0x8268, 0x3a20, 0xa000, 0x0bc6, 0x38d0, 0x8008, 0xc25a, 0x36c0 }, 16, 0x000acc60, 1},
+ {{0xa100, 0xeaec, 0xeee8, 0x38e0, 0xa100, 0xea3c, 0x2b0b, 0x810e, 0x3680, 0xa000, 0x51d3, 0xc558, 0x3680, 0xa100, 0x4110, 0xc051 }, 16, 0x000acc80, 1},
+ {{0x3a00, 0xa100, 0x0dc6, 0x38d0, 0x8008, 0xc453, 0x38c0, 0xa100, 0xedec, 0x2808, 0x800a, 0x38c0, 0xa100, 0xed3f, 0x2c0c, 0x800a }, 16, 0x000acca0, 1},
+ {{0x3820, 0xa000, 0xedec, 0x2d0f, 0x810c, 0x3640, 0xa000, 0x54d7, 0xefe8, 0x3680, 0xa000, 0xee62, 0xef68, 0x3680, 0xa000, 0x4416 }, 16, 0x000accc0, 1},
+ {{0xed68, 0x94c0, 0xcf4f, 0xcd49, 0x98c0, 0x0dc6, 0x38d0, 0x8008, 0xefec, 0x94c0, 0xef68, 0xee58, 0x3800, 0xa100, 0xe2ef, 0x2d0e }, 16, 0x000acce0, 1},
+ {{0x810a, 0x3680, 0xa000, 0x5516, 0xefec, 0x0514, 0xef64, 0x3a20, 0xa000, 0x0ec6, 0x38d0, 0x8008, 0xe3ef, 0x3600, 0xa100, 0xedee }, 16, 0x000acd00, 1},
+ {{0xefec, 0x3840, 0xa000, 0xed62, 0x2e0f, 0x8110, 0x1517, 0xfd41, 0x3600, 0xa100, 0x4510, 0xef6c, 0x3a00, 0xa100, 0x08c6, 0x38d0 }, 16, 0x000acd20, 1},
+ {{0x8008, 0xe9ec, 0x3680, 0xa000, 0xe96a, 0xe958, 0x3880, 0xa100, 0xc846, 0x280e, 0x8126, 0x3680, 0xa100, 0x5316, 0xc654, 0x3640 }, 16, 0x000acd40, 1},
+ {{0xa000, 0x65e4, 0xe1e9, 0x3600, 0xa100, 0x4310, 0xc152, 0x3600, 0xa100, 0xe846, 0x4316, 0x3680, 0xa100, 0xc84e, 0xc845, 0x38c0 }, 16, 0x000acd60, 1},
+ {{0xa100, 0xee46, 0x2909, 0x800a, 0x3600, 0xa100, 0x4310, 0xc65c, 0x3a40, 0xa100, 0x0dc6, 0x38d0, 0x8008, 0xebe9, 0x3680, 0xa000 }, 16, 0x000acd80, 1},
+ {{0xeb68, 0xe846, 0x3880, 0xa100, 0xc84d, 0x2d0e, 0x8128, 0x3680, 0xa100, 0x5616, 0xc846, 0x3680, 0xa100, 0x4617, 0xc654, 0x0dc6 }, 16, 0x000acda0, 1},
+ {{0x38d0, 0x8008, 0x90c0, 0x3800, 0xa100, 0xcd41, 0x2d0f, 0x812a, 0x3680, 0xa000, 0x5617, 0xc750, 0x90c0, 0x3480, 0xa000, 0x4617 }, 16, 0x000acdc0, 1},
+ {{0x3820, 0xa000, 0x0fc6, 0x38d0, 0x8008, 0x90c0, 0x36a0, 0xa000, 0x2f0f, 0x812e, 0x3680, 0xa000, 0x5617, 0xc752, 0x3680, 0xa100 }, 16, 0x000acde0, 1},
+ {{0x4615, 0x4612, 0x3480, 0xa000, 0x4617, 0x0fc6, 0x38d0, 0x8008, 0x90c0, 0x3800, 0xa100, 0xcf47, 0x2f0a, 0x8130, 0x3680, 0xa100 }, 16, 0x000ace00, 1},
+ {{0x53d2, 0xc257, 0x3480, 0xa000, 0x4311, 0x3680, 0xa100, 0x4314, 0xe94a, 0x3680, 0xa100, 0x4310, 0xec4a, 0x3a20, 0xa100, 0x0dc6 }, 16, 0x000ace20, 1},
+ {{0x38d0, 0x8008, 0xe84a, 0x90c0, 0x36a0, 0xa000, 0x2d0d, 0x8132, 0x3480, 0xa000, 0x5415, 0x3480, 0xa000, 0x4413, 0x4415, 0x4417 }, 16, 0x000ace40, 1},
+ {{0x3820, 0xa000, 0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x3620, 0xa000, 0x2b0d, 0x815e, 0x5115, 0x3480, 0xa000, 0x4111, 0x3680, 0xa100 }, 16, 0x000ace60, 1},
+ {{0x4114, 0xe970, 0x3680, 0xa100, 0x4110, 0xec70, 0x3a00, 0xa100, 0x0fc6, 0x38d0, 0x8008, 0xe870, 0x90c0, 0x3680, 0xa000, 0x2f0b }, 16, 0x000ace80, 1},
+ {{0x8134, 0x3480, 0xa000, 0x5313, 0x3480, 0xa000, 0x4311, 0x3680, 0xa100, 0x4314, 0xe9e0, 0x3480, 0xa000, 0x4310, 0x0dc6, 0x38d0 }, 16, 0x000acea0, 1},
+ {{0x8008, 0x90c0, 0x2d0d, 0x813e, 0x50d5, 0x3600, 0xa100, 0x4010, 0xc845, 0x3480, 0xa000, 0x4016, 0x4010, 0x3820, 0xa000, 0x0fc6 }, 16, 0x000acec0, 1},
+ {{0x38d0, 0x8008, 0x90c0, 0x36a0, 0xa000, 0x2f0d, 0x81a2, 0x3480, 0xa000, 0x5115, 0x3880, 0xa000, 0x4112, 0x2202, 0x805c, 0x3820 }, 16, 0x000acee0, 1},
+ {{0xa000, 0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x3620, 0xa000, 0x2b0d, 0x81c8, 0x57d5, 0x3480, 0xa000, 0x4711, 0x3a60, 0xa100, 0x08c6 }, 16, 0x000acf00, 1},
+ {{0x38d0, 0x8008, 0xe93a, 0x90c0, 0x3620, 0xa000, 0x280f, 0x81ca, 0x1017, 0xefe2, 0x3480, 0xa000, 0x4011, 0x3a20, 0xa100, 0x0cc6 }, 16, 0x000acf20, 1},
+ {{0x38d0, 0x8008, 0xe9e1, 0x3820, 0xa000, 0x08c6, 0x2100, 0x8009, 0x36a0, 0xa000, 0x2c0d, 0x81d2, 0x38c0, 0xa100, 0x51d5, 0x2808 }, 16, 0x000acf40, 1},
+ {{0x8090, 0x3480, 0xa000, 0x4110, 0x3820, 0xa000, 0x08c6, 0x38d0, 0x8008, 0x90c0, 0x38c0, 0xa100, 0xc051, 0x280c, 0x81d4, 0x3680 }, 16, 0x000acf60, 1},
+ {{0xa100, 0x5214, 0xc453, 0x3680, 0xa100, 0x4211, 0xc152, 0x3820, 0xa000, 0x0ec6, 0x38d0, 0x8008, 0x90c0, 0x36a0, 0xa000, 0x2e0f }, 16, 0x000acf80, 1},
+ {{0x81d6, 0x3480, 0xa000, 0x5017, 0x3480, 0xa000, 0x4011, 0x3680, 0xa000, 0x4014, 0xea58, 0x3480, 0xa000, 0x4010, 0x3820, 0xa000 }, 16, 0x000acfa0, 1},
+ {{0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x36a0, 0xa000, 0x2d0b, 0x81d8, 0x3480, 0xa000, 0x5013, 0x4017, 0x98c0, 0x0dc6, 0x38d0, 0x8008 }, 16, 0x000acfc0, 1},
+ {{0xefe3, 0x90c0, 0x3800, 0xa100, 0xfdc1, 0x2d0e, 0x81dc, 0x3480, 0xa000, 0x50ce, 0x3600, 0xa100, 0xd990, 0x50d6, 0xdc1b, 0x4097 }, 16, 0x000acfe0, 1},
+ {{0x3820, 0xa000, 0x0fc6, 0x38d0, 0x8008, 0x90c0, 0x36a0, 0xa000, 0x2f0d, 0x81e6, 0x3480, 0xa000, 0x5115, 0x4116, 0x3a20, 0xa000 }, 16, 0x000ad000, 1},
+ {{0x0bc6, 0x38d0, 0x8008, 0xee44, 0x90c0, 0x3840, 0xa100, 0xeb58, 0x2b0f, 0x81e8, 0x3680, 0xa100, 0x5517, 0xe9eb, 0x3600, 0xa100 }, 16, 0x000ad020, 1},
+ {{0x4515, 0xe962, 0x08c6, 0x38d0, 0x8008, 0x90c0, 0x2808, 0x81ea, 0x5210, 0x420e, 0x08c6, 0x38d0, 0x8008, 0x90c0, 0x2808, 0x81ec }, 16, 0x000ad040, 1},
+ {{0x1410, 0xe8e9, 0x0416, 0xe862, 0x0ec6, 0x38d0, 0x8008, 0x90c0, 0x2e0e, 0x81ee, 0x1016, 0xeeea, 0x0011, 0xee62, 0x0013, 0xe944 }, 16, 0x000ad060, 1},
+ {{0x0012, 0xeb44, 0x3a20, 0xa000, 0x0cc6, 0x38d0, 0x8008, 0xea44, 0x90c0, 0x36a0, 0xa000, 0x2c0c, 0x81f0, 0x3480, 0xa000, 0x5114 }, 16, 0x000ad080, 1},
+ {{0x3600, 0xa100, 0x4110, 0xc840, 0x3880, 0xa000, 0x4111, 0x2102, 0x829c, 0x4116, 0x3a40, 0xa000, 0x0ec6, 0x38d0, 0x8008, 0xec39 }, 16, 0x000ad0a0, 1},
+ {{0x90c0, 0x2e0e, 0x81f2, 0x5616, 0x4609, 0x460b, 0x460a, 0x0ec6, 0x38d0, 0x8008, 0x90c0, 0x2e0e, 0x81f4, 0x5216, 0x4211, 0x4213 }, 16, 0x000ad0c0, 1},
+ {{0x4212, 0x09c6, 0x38d0, 0x8008, 0x90c0, 0x2909, 0x81f6, 0x5611, 0x4614, 0x0cc6, 0x38d0, 0x8008, 0x32c4, 0x3b60, 0x800a, 0x2c09 }, 16, 0x000ad0e0, 1},
+ {{0x8200, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ad100, 1},
+ {{0x94c0, 0x9620, 0x9720, 0x32c4, 0x20c0, 0x800a, 0x94c0, 0x9e20, 0x9f20, 0x96c0, 0x5890, 0x280d, 0x804c, 0x96c0, 0x5f95, 0x2d0b }, 16, 0x000ad120, 1},
+ {{0x8034, 0x1e93, 0xe844, 0x32a4, 0x2050, 0x800b, 0x1090, 0xc84e, 0x98c0, 0xc846, 0x3b00, 0x2068, 0x8008, 0x9ac0, 0x31fc, 0x9fff }, 16, 0x000ad140, 1},
+ {{0xcda8, 0x2702, 0x816a, 0x0090, 0x3a00, 0x206c, 0x8008, 0x0413, 0x3b00, 0x206a, 0x8008, 0x96c0, 0x5290, 0x280c, 0x805e, 0x98c0 }, 16, 0x000ad160, 1},
+ {{0x34cd, 0x8410, 0xe9ec, 0xc8a6, 0x0513, 0x3b00, 0x206e, 0x8008, 0x1017, 0x3f00, 0x2072, 0x8008, 0x0012, 0xe93d, 0x1614, 0xedec }, 16, 0x000ad180, 1},
+ {{0x0613, 0x3b00, 0x2074, 0x8008, 0x1311, 0xed38, 0x0317, 0x3800, 0x207c, 0x8008, 0x96c0, 0x5115, 0x2c0a, 0x825a, 0x0113, 0xefea }, 16, 0x000ad1a0, 1},
+ {{0x1212, 0xef62, 0x0210, 0x3b00, 0x2078, 0x8008, 0x1017, 0x3800, 0x2076, 0x8008, 0x0013, 0xea42, 0x1512, 0x3f00, 0x2088, 0x8008 }, 16, 0x000ad1c0, 1},
+ {{0x96c0, 0x4510, 0x2800, 0x81f8, 0x3600, 0xa100, 0x5511, 0xebea, 0x96c0, 0x4517, 0x2f00, 0x816c, 0x3a00, 0xa100, 0x3900, 0x208a }, 16, 0x000ad1e0, 1},
+ {{0x8008, 0xeb38, 0x3680, 0xa000, 0x5013, 0xebea, 0x96c0, 0x4011, 0x2900, 0x80e0, 0x98c0, 0xeb3f, 0x3800, 0x208c, 0x8008, 0x1613 }, 16, 0x000ad200, 1},
+ {{0xefea, 0x0610, 0xef39, 0x1517, 0x3202, 0x208e, 0x8008, 0x98c0, 0x3b00, 0x2080, 0x8008, 0xe9ea, 0x3880, 0xa000, 0x4512, 0x2800 }, 16, 0x000ad220, 1},
+ {{0x81f6, 0x1615, 0x3f00, 0x2082, 0x8008, 0x0613, 0xe938, 0x1011, 0xedea, 0x96c0, 0x4017, 0x2b00, 0x80de, 0x3a40, 0xa000, 0x3800 }, 16, 0x000ad240, 1},
+ {{0x2084, 0x8008, 0xed3f, 0x1515, 0xefea, 0x0510, 0xef3b, 0x1517, 0x3d00, 0x2086, 0x8008, 0x96c0, 0xe8ea, 0x2b00, 0x81d0, 0x0515 }, 16, 0x000ad260, 1},
+ {{0x3f00, 0x2090, 0x8008, 0x1314, 0xe83b, 0x0317, 0x3900, 0x2092, 0x8008, 0x96c0, 0xecea, 0x2b00, 0x8144, 0x1410, 0x3d00, 0x2094 }, 16, 0x000ad280, 1},
+ {{0x8008, 0x96c0, 0x4411, 0x2900, 0x80b8, 0x94c0, 0xec3b, 0xee42, 0x1314, 0x3c00, 0x2096, 0x8008, 0x0315, 0xea39, 0x5712, 0x4714 }, 16, 0x000ad2a0, 1},
+ {{0x10d6, 0x06c5, 0x231c, 0x8009, 0x2769, 0x09c6, 0x38d0, 0x8008, 0x802b, 0x96c0, 0x6d90, 0x290f, 0x8200, 0x55d7, 0x96c0, 0x7065 }, 16, 0x000ad2c0, 1},
+ {{0x3b7e, 0x9c7f, 0x843b, 0x4617, 0x03c1, 0x231e, 0x8009, 0x30c4, 0x331e, 0x800a, 0x03c1, 0x231c, 0x8009, 0x2d90, 0x05c5, 0x231d }, 16, 0x000ad2e0, 1},
+ {{0x8009, 0x26e9, 0x0cc6, 0x38d0, 0x8008, 0x8015, 0x2c0a, 0x8200, 0x51d2, 0x337f, 0x9fff, 0x4712, 0x03c1, 0x231d, 0x8009, 0x94c0 }, 16, 0x000ad300, 1},
+ {{0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x33c4, 0x20c0, 0x800a, 0x1c90, 0x0bc6, 0x38d0, 0x8008, 0x90c0 }, 16, 0x000ad320, 1},
+ {{0x9ac0, 0x2b0a, 0x8024, 0x90c0, 0x2c0d, 0x8028, 0x96c0, 0x54d2, 0x2d0b, 0x808c, 0x9ac0, 0x2b0a, 0x8118, 0x6669, 0x2b08, 0x808c }, 16, 0x000ad340, 1},
+ {{0x92c2, 0x6e90, 0x92c3, 0xc581, 0x4515, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0c, 0x8028, 0x54d4, 0x6669, 0x92c2, 0x6d10, 0x92c3 }, 16, 0x000ad360, 1},
+ {{0xc281, 0x4213, 0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x2b0d, 0x802a, 0x55d5, 0x66e9, 0x92c2, 0x6d10, 0x92c3, 0xc281, 0x4210, 0x0dc6 }, 16, 0x000ad380, 1},
+ {{0x38d0, 0x8008, 0x90c0, 0x2d0d, 0x802c, 0x54d5, 0x6669, 0x92c2, 0x6d90, 0x94c7, 0x9f70, 0xc381, 0x4312, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ad3a0, 1},
+ {{0x36d1, 0xc281, 0x98c0, 0x74d2, 0x7750, 0x9620, 0x9720, 0x98c0, 0x6d7c, 0x6e7c, 0x9e20, 0x9f20, 0x3284, 0x20b0, 0x800a, 0x3455 }, 16, 0x000ad3c0, 1},
+ {{0xce45, 0x35d0, 0x7456, 0x7de3, 0x79ee, 0x2f90, 0x3284, 0x20b0, 0x800a, 0x6f7c, 0x98c0, 0x7c63, 0x6e10, 0xce4d, 0xc181, 0x386e }, 16, 0x000ad3e0, 1},
+ {{0xd69f, 0x2c7c, 0x7575, 0x94c0, 0xd71c, 0xce44, 0x2aaa, 0xd7c4, 0x66e6, 0x2d7c, 0x3284, 0x20b0, 0x800a, 0x3455, 0xcf45, 0x3e00 }, 16, 0x000ad400, 1},
+ {{0xa00d, 0x7450, 0x6e10, 0x6e90, 0x3381, 0x2000, 0x8000, 0x3e00, 0xa004, 0x7c63, 0x757b, 0xcf4d, 0x3c60, 0x32dc, 0x8008, 0x3600 }, 16, 0x000ad420, 1},
+ {{0xa004, 0x7863, 0xce4c, 0x3600, 0xa80c, 0x74d0, 0x786b, 0x3600, 0xb80c, 0x6c7c, 0x6d7c, 0x3800, 0xba40, 0x6d95, 0xd69c, 0xd7c4 }, 16, 0x000ad440, 1},
+ {{0x3c00, 0xa002, 0x7475, 0x74d5, 0xd69b, 0x3f1b, 0x8001, 0x3800, 0xa009, 0x7ae1, 0x65e9, 0x75f1, 0x3a07, 0xa402, 0x7be1, 0x7ec1 }, 16, 0x000ad460, 1},
+ {{0x90c0, 0xd813, 0x3e07, 0xa008, 0x90c0, 0xcf45, 0xc181, 0x371d, 0x8001, 0x75c7, 0x92c2, 0x6c90, 0xef1c, 0x3420, 0xa000, 0x5217 }, 16, 0x000ad480, 1},
+ {{0x3400, 0xa840, 0x6bbc, 0x7fef, 0x3600, 0xa044, 0x3400, 0x8007, 0x3400, 0xa004, 0x6466, 0x3400, 0xa004, 0xd41b, 0x3400, 0xa004 }, 16, 0x000ad4a0, 1},
+ {{0x7072, 0x3601, 0xa0cc, 0x6c92, 0x6e12, 0x3a61, 0xb299, 0xc48f, 0x6b28, 0x6b38, 0xc48f, 0x3600, 0xb004, 0x6766, 0x6e34, 0x3402 }, 16, 0x000ad4c0, 1},
+ {{0xa004, 0x6764, 0x3400, 0xa004, 0xd742, 0x3400, 0xa004, 0x7f70, 0x3400, 0xa844, 0x6cca, 0x3400, 0xa804, 0x7771, 0x3400, 0xa840 }, 16, 0x000ad4e0, 1},
+ {{0x6ba6, 0x7fef, 0x3c00, 0xa006, 0x34e6, 0x8000, 0x90c0, 0x36e7, 0x8000, 0x3600, 0xa004, 0x30e6, 0x8000, 0x3400, 0xa800, 0xdb96 }, 16, 0x000ad500, 1},
+ {{0x3400, 0xa800, 0xd7c7, 0x67e1, 0x67e6, 0xd79b, 0x73f2, 0x3601, 0xa00c, 0x6fab, 0x6eab, 0x3601, 0xb808, 0x7477, 0x7475, 0x3601 }, 16, 0x000ad520, 1},
+ {{0xb88c, 0x6ab1, 0x6ab1, 0x3400, 0xa004, 0x66e6, 0x3606, 0xa004, 0x66e4, 0x66e9, 0x3a07, 0xa008, 0x78c1, 0xd6c2, 0x79e1, 0xf28d }, 16, 0x000ad540, 1},
+ {{0x3c00, 0xa008, 0x6e08, 0x7ef0, 0x75c3, 0x331a, 0x8001, 0x3600, 0xb008, 0x6569, 0xd4c5, 0x3601, 0xb000, 0x76c1, 0x77f1, 0x3801 }, 16, 0x000ad560, 1},
+ {{0xa004, 0xd5c5, 0x3e57, 0x9a82, 0x3607, 0xa080, 0x67e6, 0x6ccc, 0x3a07, 0xa001, 0x90c0, 0x77f6, 0x3f41, 0x8000, 0x3607, 0xa004 }, 16, 0x000ad580, 1},
+ {{0x7cef, 0x6668, 0x3600, 0xa040, 0x6827, 0x803b, 0x24e8, 0x6466, 0x801b, 0xd4c3, 0x64e8, 0x94c7, 0x844a, 0x64e4, 0x92c3, 0xd411 }, 16, 0x000ad5a0, 1},
+ {{0x98c0, 0xd419, 0x31c4, 0x3600, 0x800a, 0x3600, 0xa004, 0x7271, 0xd419, 0x98c7, 0x30c4, 0x3600, 0x800a, 0x7c6f, 0xd41b, 0x3600 }, 16, 0x000ad5c0, 1},
+ {{0xb080, 0x77f6, 0x6cac, 0x3600, 0xa040, 0x6827, 0x64e8, 0x6466, 0xd41c, 0xd41b, 0x3601, 0xb000, 0xd419, 0xd41b, 0x92c2, 0x7c6f }, 16, 0x000ad5e0, 1},
+ {{0x96c0, 0x6461, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ad600, 1},
+ {{0x96c0, 0x6c90, 0x9620, 0x9720, 0x0190, 0xc94e, 0x14d1, 0xe84a, 0x9ac0, 0x399f, 0x8000, 0x90c0, 0x3978, 0x9fff, 0x67e9, 0x92c2 }, 16, 0x000ad620, 1},
+ {{0x6f90, 0x98c7, 0x3224, 0x24f0, 0x800a, 0xc781, 0x0710, 0xc84f, 0x94c0, 0xc847, 0xc946, 0x90c0, 0x94c0, 0xece8, 0xe942, 0x94c0 }, 16, 0x000ad640, 1},
+ {{0xec66, 0xc94e, 0x4094, 0x1511, 0x3244, 0x3d90, 0x800a, 0x7465, 0x96c0, 0x6e10, 0xc847, 0xc946, 0x90c0, 0x94c0, 0xebe8, 0xe942 }, 16, 0x000ad660, 1},
+ {{0x94c0, 0xeb62, 0xe842, 0x0013, 0xc94e, 0x4490, 0x14d1, 0xe84a, 0x9ac0, 0x399f, 0x8000, 0x90c0, 0x3978, 0x9fff, 0x27e9, 0xc84f }, 16, 0x000ad680, 1},
+ {{0x92c2, 0x6d10, 0x98c7, 0x3224, 0x24f0, 0x800a, 0xc281, 0x4210, 0x94c0, 0xc847, 0xc946, 0x90c0, 0x94c0, 0xeae8, 0xe942, 0xea66 }, 16, 0x000ad6a0, 1},
+ {{0x4092, 0x1211, 0x3244, 0x3d90, 0x800a, 0x7462, 0xc847, 0x94c0, 0x9621, 0x9721, 0x94c0, 0xe862, 0x9f70, 0x4010, 0x90c0, 0x90c0 }, 16, 0x000ad6c0, 1},
+ {{0x96c0, 0xd028, 0x77d0, 0x9720, 0x94c0, 0x9f20, 0x807f, 0x9ac0, 0x2040, 0x8e20, 0x90c0, 0x3417, 0x8030, 0x805b, 0x9ac0, 0x2020 }, 16, 0x000ad6e0, 1},
+ {{0x99d0, 0x90c0, 0x3417, 0x8020, 0x803b, 0x96c0, 0xd3b8, 0x2020, 0x8bc0, 0x801f, 0x96c0, 0xd3b0, 0x2000, 0x9c20, 0x844b, 0x3324 }, 16, 0x000ad700, 1},
+ {{0x24f0, 0x800a, 0x30c4, 0x377a, 0x800a, 0x00c2, 0x22bc, 0x8009, 0x3324, 0x24f0, 0x800a, 0x30c4, 0x377a, 0x800a, 0x00c2, 0x22bc }, 16, 0x000ad720, 1},
+ {{0x8009, 0x3324, 0x24f0, 0x800a, 0x30c4, 0x377a, 0x800a, 0x00c2, 0x22bc, 0x8009, 0x3324, 0x24f0, 0x800a, 0x30c4, 0x377a, 0x800a }, 16, 0x000ad740, 1},
+ {{0x00c2, 0x22bc, 0x8009, 0x3224, 0x24f0, 0x800a, 0x96c0, 0xc788, 0x2000, 0x8d48, 0x00c2, 0x22bc, 0x8009, 0x3fc1, 0x0cc6, 0x38d0 }, 16, 0x000ad760, 1},
+ {{0x8008, 0x38c0, 0x210c, 0x8009, 0x2c09, 0x80b8, 0x32c4, 0x3620, 0x800a, 0x07c0, 0x22cc, 0x8009, 0x0dc6, 0x38d0, 0x8008, 0x38c0 }, 16, 0x000ad780, 1},
+ {{0x21e4, 0x8009, 0x32c4, 0x3620, 0x800a, 0x2d09, 0x80c0, 0x3224, 0x24f0, 0x800a, 0x2000, 0x8064, 0x00c2, 0x22c4, 0x8009, 0x3224 }, 16, 0x000ad7a0, 1},
+ {{0x24f0, 0x800a, 0x2000, 0x83e8, 0x98c0, 0x01c6, 0x22c4, 0x8009, 0x9f21, 0x9ac0, 0x6c51, 0x02c6, 0x22bc, 0x8009, 0x9721, 0x7170 }, 16, 0x000ad7c0, 1},
+ {{0x90c0, 0x98c7, 0x9f70, 0x30e8, 0x3fff, 0xbfff, 0x96c3, 0x00c2, 0x22bc, 0x8009, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ad7e0, 1},
+ {{0x96c0, 0x5011, 0x280b, 0x800a, 0x96c0, 0x6468, 0x9620, 0x9720, 0x94c0, 0x9e20, 0xc3fe, 0x96c7, 0xc94e, 0x280c, 0x800a, 0x94c7 }, 16, 0x000ad800, 1},
+ {{0xc84f, 0x5514, 0x96c7, 0xeeeb, 0x0905, 0xa001, 0x94c7, 0x8423, 0x4514, 0x5413, 0xdd84, 0x0313, 0x3224, 0x24f0, 0x800a, 0x5011 }, 16, 0x000ad820, 1},
+ {{0x94c0, 0xebee, 0xc946, 0x94c0, 0xeb66, 0xc847, 0x4093, 0x94c0, 0xe942, 0xc84f, 0x1611, 0x3244, 0x3d90, 0x800a, 0x3466, 0xc94e }, 16, 0x000ad840, 1},
+ {{0x94c0, 0xc847, 0xc946, 0x90c0, 0x94c0, 0xe848, 0xe942, 0x0010, 0xc0fe, 0x1511, 0xc84f, 0x66e8, 0x90c0, 0x94c3, 0x280c, 0x800e }, 16, 0x000ad860, 1},
+ {{0x92c3, 0x5214, 0x96c7, 0x8432, 0x0902, 0xa001, 0x92c3, 0x4214, 0x280c, 0x800e, 0x1614, 0xeeec, 0x94c0, 0xdc06, 0xc94e, 0x0014 }, 16, 0x000ad880, 1},
+ {{0x3224, 0x24f0, 0x800a, 0x5011, 0x94c0, 0xecee, 0xc946, 0x94c0, 0xec66, 0xc847, 0x4094, 0x94c0, 0xe942, 0xc84f, 0x1011, 0x3244 }, 16, 0x000ad8a0, 1},
+ {{0x3d90, 0x800a, 0x7460, 0x94c0, 0xc847, 0x9e21, 0x94c0, 0x9621, 0x9721, 0x94c0, 0xe84c, 0x9f70, 0x4010, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ad8c0, 1},
+ {{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x0bc6, 0x38d0, 0x8008, 0x270a, 0x8030, 0x98c0, 0x38c0, 0x210c, 0x8009, 0xe7ea }, 16, 0x000ad8e0, 1},
+ {{0x32c4, 0x3800, 0x800a, 0x2b09, 0x80b8, 0x0ac6, 0x38d0, 0x8008, 0x38c0, 0x21e4, 0x8009, 0x32c4, 0x3800, 0x800a, 0x2a09, 0x80c0 }, 16, 0x000ad900, 1},
+ {{0x2f90, 0x38c0, 0x2116, 0x8009, 0x00c4, 0x22cc, 0x8009, 0x98c0, 0x280d, 0x800c, 0x646a, 0x5310, 0x98c0, 0x371a, 0x8001, 0x5115 }, 16, 0x000ad920, 1},
+ {{0xed62, 0x9ac0, 0x331e, 0x8001, 0xf241, 0x2718, 0x8168, 0x94c0, 0xece8, 0xefed, 0x94c0, 0xeeed, 0xec62, 0x94c0, 0xe866, 0xef68 }, 16, 0x000ad940, 1},
+ {{0x9ec0, 0xee64, 0x3ac0, 0x2124, 0x8009, 0x90c0, 0x90c0, 0x90c0, 0x1254, 0x00c6, 0x210c, 0x8009, 0x94c0, 0xf242, 0xf843, 0x94c0 }, 16, 0x000ad960, 1},
+ {{0xfd44, 0xfc45, 0x3224, 0x2590, 0x800a, 0xfa46, 0x9ac0, 0x74d0, 0xf8c3, 0x02c6, 0x210c, 0x8009, 0x94c0, 0xfdc4, 0xf147, 0x5090 }, 16, 0x000ad980, 1},
+ {{0xd540, 0x02c2, 0x210c, 0x8009, 0x3620, 0xa000, 0x5355, 0x5097, 0x3224, 0x2590, 0x800a, 0x3420, 0xa000, 0xf348, 0x3820, 0xa004 }, 16, 0x000ad9a0, 1},
+ {{0xda10, 0xf1c7, 0xf3c8, 0x3a40, 0xb084, 0xd891, 0x602c, 0x5197, 0x5296, 0x3c00, 0xa004, 0xd541, 0x31e8, 0x9fff, 0xf3c1, 0xf2c2 }, 16, 0x000ad9c0, 1},
+ {{0x3a40, 0xa080, 0x65e9, 0x6018, 0xfac6, 0x4297, 0x94c0, 0xf8c3, 0xfdc4, 0x8056, 0x005a, 0xfcc5, 0x01c4, 0x22c2, 0x8009, 0x03c4 }, 16, 0x000ad9e0, 1},
+ {{0x22ca, 0x8009, 0x9ac0, 0xd813, 0xd991, 0x09c3, 0x22c8, 0x8009, 0x98c0, 0xda99, 0x09c3, 0x22c0, 0x8009, 0x9ac0, 0x2461, 0x9541 }, 16, 0x000ada00, 1},
+ {{0xd919, 0x21e1, 0x83af, 0x2220, 0x21b9, 0x09c3, 0x22bc, 0x8009, 0x2e55, 0x6ddd, 0x2c4c, 0x04c2, 0x22c8, 0x8009, 0x2274, 0x03c2 }, 16, 0x000ada20, 1},
+ {{0x22c0, 0x8009, 0x6e74, 0x4490, 0x2769, 0x01c4, 0x22ca, 0x8009, 0x94c0, 0xd991, 0x804d, 0x05c4, 0x22c2, 0x8009, 0x98c0, 0xd915 }, 16, 0x000ada40, 1},
+ {{0x08c3, 0x22c0, 0x8009, 0x0dc3, 0x22c8, 0x8009, 0x9cc0, 0xda1d, 0x2161, 0x9541, 0xda98, 0x20e1, 0x83af, 0x21b9, 0x2032, 0x09c3 }, 16, 0x000ada60, 1},
+ {{0x22bc, 0x8009, 0x2e4c, 0x6dc1, 0x2c4c, 0x03c2, 0x22c0, 0x8009, 0x21f4, 0x04c2, 0x22c8, 0x8009, 0x6df4, 0x4396, 0x3bc1, 0x00c4 }, 16, 0x000ada80, 1},
+ {{0x22cc, 0x8009, 0x7077, 0x2dff, 0x9ecb, 0x246a, 0x2f10, 0x3ac0, 0x21ec, 0x8009, 0x8497, 0x96c0, 0xe8ea, 0x2a0d, 0x800c, 0x98c0 }, 16, 0x000adaa0, 1},
+ {{0x3bc0, 0x21fc, 0x8009, 0xe864, 0x94c0, 0xeeed, 0xefed, 0x94c0, 0xfb49, 0xef64, 0x94c0, 0xee68, 0xf84a, 0x3dc0, 0x21ec, 0x8009 }, 16, 0x000adac0, 1},
+ {{0x00c6, 0x21e4, 0x8009, 0x1755, 0x3324, 0x2590, 0x800a, 0x9ac0, 0x75d0, 0xfaca, 0x04c6, 0x21e4, 0x8009, 0x98c0, 0x3bc0, 0x21f8 }, 16, 0x000adae0, 1},
+ {{0x8009, 0xf34b, 0x5192, 0xd641, 0x04c2, 0x21e4, 0x8009, 0x1153, 0x5096, 0x3224, 0x2590, 0x800a, 0xf14c, 0x3b41, 0x1497, 0x1596 }, 16, 0x000adb00, 1},
+ {{0xd910, 0x96c0, 0xd645, 0xf1cc, 0xf3cb, 0x98c0, 0x6238, 0xd993, 0x4496, 0xf9c9, 0x39ec, 0x9fff, 0x220f, 0x00c4, 0x22cc, 0x8009 }, 16, 0x000adb20, 1},
+ {{0x3076, 0x4459, 0x94c0, 0xf949, 0x8197, 0x27ea, 0x9fd0, 0xe7ea, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0 }, 16, 0x000adb40, 1},
+ {{0x3c00, 0xa006, 0x74d7, 0x280d, 0x8002, 0x7456, 0x57d1, 0x96c0, 0x4715, 0x290a, 0x8002, 0x13d1, 0xed44, 0x3a80, 0xa100, 0x3718 }, 16, 0x000adb60, 1},
+ {{0x8800, 0xe8ee, 0xe9ef, 0x96c0, 0x6469, 0xeeed, 0x9748, 0xee62, 0x96c3, 0x50d0, 0x26e0, 0x9cff, 0x98c1, 0xdf07, 0x4710, 0x311c }, 16, 0x000adb80, 1},
+ {{0x8300, 0x9cc7, 0x280b, 0x800c, 0x90c0, 0x4610, 0x90c0, 0xde1e, 0x98c7, 0x290c, 0x8008, 0x90c0, 0x4410, 0x16da, 0x07c4, 0x2318 }, 16, 0x000adba0, 1},
+ {{0x8009, 0x96c0, 0xd897, 0x2a0f, 0x8026, 0x3424, 0x8006, 0x4415, 0x10d2, 0xed42, 0x4016, 0x17cf, 0x05c4, 0x2318, 0x8009, 0xda95 }, 16, 0x000adbc0, 1},
+ {{0x34a7, 0x8007, 0x471d, 0x12d7, 0x01c4, 0x2318, 0x8009, 0xdb91, 0x34e0, 0x8002, 0x4015, 0x92d0, 0x56dc, 0x461b, 0x9748, 0x94c0 }, 16, 0x000adbe0, 1},
+ {{0xe85c, 0xe958, 0x92d0, 0x50d9, 0x4018, 0x9f70, 0x3a60, 0xb800, 0x77d1, 0x7750, 0xefe9, 0xeee8, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000adc00, 1},
+ {{0x98c0, 0x05a4, 0x33c0, 0x8009, 0xc3bc, 0x96c0, 0x7ee3, 0x9620, 0x9720, 0x9ac0, 0x7ae1, 0x05c0, 0x2318, 0x8009, 0xc94e, 0x3ec1 }, 16, 0x000adc20, 1},
+ {{0x34c2, 0x230c, 0x8009, 0x2c90, 0xcb45, 0x94c0, 0x9e20, 0x9f20, 0x3640, 0xa000, 0xe748, 0xeb1c, 0x1513, 0xf341, 0x32e4, 0x3c8a }, 16, 0x000adc40, 1},
+ {{0x8001, 0x98c0, 0xeee8, 0x05c0, 0x231a, 0x8009, 0x96c0, 0xc946, 0x2e08, 0x8002, 0x9748, 0x3800, 0xa100, 0x54d1, 0x290b, 0x8002 }, 16, 0x000adc60, 1},
+ {{0x96c0, 0x4410, 0x2e0a, 0x800c, 0x15d1, 0xe844, 0x9ac0, 0x3b1b, 0x8800, 0xebe8, 0x280d, 0x8002, 0x98c0, 0x65e9, 0xeb62, 0x290f }, 16, 0x000adc80, 1},
+ {{0x8008, 0x90c0, 0x96c3, 0x51d6, 0x23e0, 0x9cff, 0x96c3, 0xdd84, 0x331c, 0x8300, 0x94c3, 0xde1b, 0x4316, 0x4416, 0x3a00, 0xa100 }, 16, 0x000adca0, 1},
+ {{0x05c4, 0x2318, 0x8009, 0x51db, 0x3840, 0xa000, 0xd915, 0x2b0c, 0x8026, 0x3442, 0x8001, 0x4210, 0x3480, 0xa000, 0x55d3, 0x4513 }, 16, 0x000adcc0, 1},
+ {{0x12cc, 0x00c4, 0x2318, 0x8009, 0xd810, 0x3401, 0x8002, 0x411d, 0x12d4, 0x04c4, 0x2318, 0x8009, 0xda14, 0x3482, 0x8002, 0x4215 }, 16, 0x000adce0, 1},
+ {{0x92d0, 0x52df, 0x421a, 0x9748, 0x94c0, 0xee5c, 0xe958, 0x92d0, 0x56d9, 0x461e, 0x96c0, 0x55d0, 0x2d0c, 0x802c, 0x051c, 0xc781 }, 16, 0x000add00, 1},
+ {{0x071c, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x4714, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000add20, 1},
+ {{0x9ac0, 0x2260, 0x8488, 0x76f8, 0x2400, 0x8555, 0x3c55, 0x8000, 0x34f5, 0x35f5, 0x3000, 0x2000, 0x9000, 0x96c0, 0x64e6, 0x3743 }, 16, 0x000add40, 1},
+ {{0x8000, 0x9ac0, 0x3631, 0x9fff, 0x90c0, 0x379b, 0x8000, 0x90c0, 0x96c2, 0x3581, 0x2000, 0x8000, 0x92c2, 0x76fd, 0x94c6, 0x65e9 }, 16, 0x000add60, 1},
+ {{0x6c85, 0x3623, 0x8002, 0x7dee, 0x3665, 0x8003, 0x3aca, 0x944f, 0x9ac0, 0x3641, 0x8004, 0x90c0, 0x3444, 0x8004, 0xd994, 0xd5c1 }, 16, 0x000add80, 1},
+ {{0x36cd, 0x94cd, 0x3c55, 0x8000, 0x9ac0, 0x3444, 0x8005, 0x90c0, 0x3641, 0x8005, 0x3044, 0x8005, 0xda14, 0xd641, 0x6661, 0xd444 }, 16, 0x000adda0, 1},
+ {{0x7c6e, 0x94c7, 0x9f70, 0x6464, 0x7470, 0x90c0, 0x90c0, 0x90c0, 0x3a00, 0xa10c, 0x7456, 0x74d7, 0x50d0, 0xe9ef, 0x3c80, 0xa000 }, 16, 0x000addc0, 1},
+ {{0x311a, 0x8800, 0xe8ee, 0x311e, 0x8080, 0x9ac0, 0x23e0, 0x9b7f, 0x6569, 0x280f, 0x803a, 0x94c0, 0xdd80, 0x8485, 0x9cc0, 0x6769 }, 16, 0x000adde0, 1},
+ {{0x319e, 0x8000, 0xc781, 0x280a, 0x8036, 0x804b, 0x07c1, 0x231e, 0x8009, 0x1412, 0x57d0, 0x96c0, 0x6669, 0x3f98, 0x8000, 0x8013 }, 16, 0x000ade00, 1},
+ {{0x6469, 0x98c6, 0x2418, 0x80fe, 0x90c0, 0x7a61, 0x92c2, 0x4412, 0x94c0, 0xc481, 0xcfb0, 0x98c0, 0x04c1, 0x231c, 0x8009, 0xeeea }, 16, 0x000ade20, 1},
+ {{0x11d0, 0xee3f, 0x3378, 0x9c7f, 0x4010, 0x11d6, 0x30c4, 0x3f20, 0x800a, 0x4112, 0x98c0, 0x280b, 0x8036, 0x6769, 0xc9b0, 0xeaeb }, 16, 0x000ade40, 1},
+ {{0x94c7, 0xea39, 0xc781, 0x84ba, 0x96c3, 0x07c1, 0x231d, 0x8009, 0x10d2, 0x30c4, 0x3f20, 0x800a, 0x4013, 0x98c0, 0x77fb, 0x4310 }, 16, 0x000ade60, 1},
+ {{0x26e0, 0x9eff, 0x98c0, 0x3f1b, 0x8100, 0x5117, 0xe9ef, 0x3551, 0x38e1, 0xe962, 0x656d, 0x8473, 0x9ac0, 0x3413, 0x8100, 0xecef }, 16, 0x000ade80, 1},
+ {{0x22e0, 0x9dff, 0x94c0, 0x9e57, 0x9d57, 0x94c0, 0xcab0, 0xebef, 0x94c2, 0xee6c, 0xed6e, 0x94c6, 0xec6c, 0x5016, 0x94c6, 0xeb3a }, 16, 0x000adea0, 1},
+ {{0x4015, 0x11d0, 0xedef, 0x94c0, 0xdf01, 0xed6e, 0x0610, 0x0906, 0xa200, 0x347e, 0x4610, 0x1411, 0xdd00, 0x36d4, 0x7a61, 0x66ed }, 16, 0x000adec0, 1},
+ {{0x8421, 0x0210, 0x0902, 0xa100, 0x4210, 0x1215, 0xcdb2, 0x4214, 0x56d3, 0x4617, 0xef3d, 0x12d7, 0x30c4, 0x3f0a, 0x800a, 0x4211 }, 16, 0x000adee0, 1},
+ {{0x0411, 0x31c4, 0x3f0a, 0x800a, 0x4117, 0x56d0, 0x3d9d, 0x8000, 0x66e9, 0x90c0, 0x92c3, 0xc481, 0x96c3, 0x04c1, 0x231d, 0x8009 }, 16, 0x000adf00, 1},
+ {{0x98c0, 0x6c90, 0x52d0, 0x280f, 0x802c, 0x9ac0, 0x351c, 0x8200, 0x5017, 0x2809, 0x8030, 0x6669, 0x804b, 0x33c4, 0x3d40, 0x800a }, 16, 0x000adf20, 1},
+ {{0x96c0, 0xecef, 0x2f0d, 0x8004, 0x4015, 0x11d0, 0x0fc3, 0x231a, 0x8009, 0x9ac0, 0x3318, 0x8040, 0x5217, 0x3319, 0x8030, 0x2469 }, 16, 0x000adf40, 1},
+ {{0x7ce3, 0xc941, 0x94c1, 0xca90, 0xcaa0, 0xe9fc, 0xec3a, 0xe91c, 0x5151, 0x6360, 0x643f, 0xd998, 0x2f5d, 0x30c4, 0x3f88, 0x800a }, 16, 0x000adf60, 1},
+ {{0x4617, 0x4111, 0xe964, 0x4111, 0x98c0, 0x6d90, 0x55d0, 0x280e, 0x802e, 0x9ac0, 0x3b1e, 0x8100, 0x5016, 0x280c, 0x8032, 0x6769 }, 16, 0x000adf80, 1},
+ {{0x804b, 0x33c4, 0x3d40, 0x800a, 0x96c0, 0xebee, 0x2e0c, 0x8004, 0x4014, 0x17d0, 0x0bc3, 0x231a, 0x8009, 0x9ac0, 0x3f18, 0x8040 }, 16, 0x000adfa0, 1},
+ {{0x5516, 0x3f1a, 0x800c, 0x2469, 0x7442, 0xcc40, 0x94c1, 0xc990, 0xc9a0, 0xecfc, 0xeb39, 0xec1b, 0x5654, 0x6e5e, 0x642c, 0xdb98 }, 16, 0x000adfc0, 1},
+ {{0x2ddb, 0x30c4, 0x3ff0, 0x800a, 0x4316, 0x4314, 0xec64, 0x4314, 0x3820, 0xa800, 0x7750, 0x50d0, 0xefe9, 0x3820, 0xa000, 0x311a }, 16, 0x000adfe0, 1},
+ {{0x8400, 0xeee8, 0x6569, 0x90c0, 0x96c7, 0xe844, 0x2809, 0x8030, 0x98c7, 0x280c, 0x802c, 0x90c0, 0x5011, 0x9ac7, 0x2c0b, 0x8002 }, 16, 0x000ae000, 1},
+ {{0x90c0, 0x3e10, 0x8192, 0x92c3, 0x7c69, 0x92c3, 0x4011, 0x15d0, 0x5714, 0x3b1d, 0x8007, 0xd79d, 0x4714, 0x17d0, 0x5513, 0x3800 }, 16, 0x000ae020, 1},
+ {{0xa200, 0x3f1c, 0x8070, 0x77d1, 0x7e64, 0xd69c, 0x451b, 0x5414, 0x94c0, 0x6e55, 0x9f70, 0x3474, 0x4413, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ae040, 1},
+ {{0x98c0, 0x38c0, 0x22d0, 0x8009, 0x9f71, 0x96c0, 0xf485, 0x10fc, 0x9ff4, 0x666a, 0x2718, 0x8018, 0x2803, 0x800a, 0x9844, 0x90c0 }, 16, 0x000ae060, 1},
+ {{0x5159, 0x92d0, 0x6174, 0x2565, 0x5159, 0x4258, 0x9f71, 0x96c0, 0xf48a, 0x10fc, 0x9ff6, 0x266a, 0x12fc, 0x9fee, 0x2718, 0x802c }, 16, 0x000ae080, 1},
+ {{0x9822, 0x96c0, 0xfbc6, 0x187a, 0x9fe2, 0x96c0, 0x9844, 0x2803, 0x800c, 0x5161, 0x5363, 0x2274, 0x22f5, 0x5161, 0x94d0, 0x6e55 }, 16, 0x000ae0a0, 1},
+ {{0x5363, 0x6665, 0x4458, 0x9823, 0x9f71, 0x1005, 0xa004, 0x3860, 0x3fc0, 0x8004, 0x2341, 0x8000, 0x3c00, 0xa008, 0x74d0, 0x6cd3 }, 16, 0x000ae0c0, 1},
+ {{0x6466, 0x2481, 0x8000, 0x3c00, 0xa805, 0x32c8, 0x87c0, 0x64e1, 0x38cc, 0x8800, 0x1890, 0x0d50, 0xa000, 0x92c2, 0x6c00, 0x3620 }, 16, 0x000ae0e0, 1},
+ {{0xa000, 0x0d50, 0xa000, 0x3606, 0xa04c, 0x6c00, 0x6e93, 0x3600, 0xa08c, 0x66e9, 0x6e13, 0x92c2, 0x7861, 0x3600, 0xa004, 0x6669 }, 16, 0x000ae100, 1},
+ {{0x7550, 0x3606, 0xa004, 0x7861, 0x7d76, 0x3e00, 0xa603, 0x30cc, 0x8580, 0x7550, 0x30cc, 0x8580, 0xc852, 0x3800, 0xa009, 0x7e49 }, 16, 0x000ae120, 1},
+ {{0x7e49, 0x7d76, 0x3620, 0xa100, 0x5f40, 0xc852, 0x3600, 0xa804, 0x6317, 0x5b40, 0x3600, 0xb000, 0x64e8, 0x610c, 0x3607, 0xa00c }, 16, 0x000ae140, 1},
+ {{0x6764, 0x64e8, 0x3607, 0xb000, 0x6564, 0x74ce, 0x344a, 0xf5c1, 0x4952, 0x9f70, 0xc565, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ae160, 1},
+ {{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x3a20, 0xa000, 0x0cc6, 0x38d0, 0x8008, 0xe748, 0x2700, 0x8040, 0x3840, 0xa000 }, 16, 0x000ae180, 1},
+ {{0xf741, 0x2c09, 0x8248, 0x32e4, 0x3c84, 0x8001, 0x38c0, 0x2320, 0x8009, 0x0ac6, 0x38d0, 0x8008, 0x3fe8, 0x3c10, 0xbfff, 0x2a0b }, 16, 0x000ae1a0, 1},
+ {{0x8264, 0x14db, 0x3de8, 0x3c14, 0xbfff, 0x9ac0, 0xdb94, 0x51d3, 0x34f9, 0x3fff, 0xbf00, 0x98c0, 0xdc9f, 0x3ae8, 0x3c14, 0xbfff }, 16, 0x000ae1c0, 1},
+ {{0x0197, 0x3ec0, 0x2336, 0x8009, 0x1195, 0x0bc6, 0x38d0, 0x8008, 0x98c0, 0xde01, 0x38c8, 0x380c, 0xbfff, 0x9ac0, 0x2b0b, 0x8268 }, 16, 0x000ae1e0, 1},
+ {{0x90c0, 0x2e0d, 0x8002, 0x13d3, 0x3bc8, 0x380c, 0xbfff, 0x98c0, 0xdd9c, 0x3f00, 0x2048, 0x8008, 0x4392, 0x16d6, 0x5090, 0x96c0 }, 16, 0x000ae200, 1},
+ {{0x31e8, 0x9fff, 0x51d5, 0x96c0, 0xdc86, 0x26e0, 0x8fef, 0xdc98, 0x4193, 0x10d7, 0x0ac6, 0x38d0, 0x8008, 0x315f, 0x8000, 0x96c0 }, 16, 0x000ae220, 1},
+ {{0x67e9, 0x2a0a, 0x825e, 0x94c0, 0x54d2, 0x800b, 0xdf04, 0x4612, 0x9ac0, 0x6f10, 0x08c6, 0x38d0, 0x8008, 0x9351, 0x3bc8, 0x3810 }, 16, 0x000ae240, 1},
+ {{0xbfff, 0x9ac0, 0x280a, 0x825e, 0x90c0, 0x2b03, 0x803a, 0x12d2, 0x3dc8, 0x3808, 0xbfff, 0x0293, 0x3fc8, 0x3808, 0xbfff, 0x15d6 }, 16, 0x000ae260, 1},
+ {{0x0ac6, 0x38d0, 0x8008, 0x9ac0, 0xd985, 0x5795, 0x38c0, 0x2376, 0x8009, 0x96c0, 0xdf83, 0x2a0c, 0x8262, 0x4714, 0x5297, 0x6560 }, 16, 0x000ae280, 1},
+ {{0x94d0, 0xd50e, 0x7b41, 0x351d, 0x8001, 0x9580, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0 }, 16, 0x000ae2a0, 1},
+ {{0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x52d3, 0x351a, 0x8001, 0x6569, 0x90c0, 0x96c3, 0x33e4, 0x3a8c, 0x8001, 0x9f71, 0x90c0, 0x90c0 }, 16, 0x000ae2c0, 1},
+ {{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x3ec0, 0x2336, 0x8009, 0x3bc8, 0x3808, 0xbfff, 0x96c0, 0x55d6, 0x2e0f, 0x8004 }, 16, 0x000ae2e0, 1},
+ {{0x9ac0, 0xd885, 0x5693, 0x38c8, 0x3808, 0xbfff, 0x98c0, 0xdf01, 0x03c5, 0x2376, 0x8009, 0x4617, 0x50d6, 0x311f, 0x8001, 0x67e9 }, 16, 0x000ae300, 1},
+ {{0x2718, 0x80fe, 0x1590, 0x3cc8, 0x3808, 0xbfff, 0x3b18, 0x8001, 0xdc13, 0x6460, 0x6469, 0x2518, 0x80e8, 0x1794, 0xe8ee, 0x96c0 }, 16, 0x000ae320, 1},
+ {{0x3f1d, 0x8001, 0xe862, 0x26e9, 0x56d0, 0x96c0, 0x3d1d, 0x8001, 0x8055, 0x26e9, 0x07c6, 0x2364, 0x8009, 0x8029, 0x98c0, 0x67e9 }, 16, 0x000ae340, 1},
+ {{0xc947, 0x2f0d, 0x800e, 0x94c0, 0x55dd, 0x801d, 0x52d1, 0xde82, 0x4511, 0x14d5, 0x0ac6, 0x2364, 0x8009, 0x90c0, 0x55d2, 0xde1d }, 16, 0x000ae360, 1},
+ {{0x4412, 0x2f08, 0x8008, 0x50d0, 0x3118, 0x8001, 0x6469, 0x90c0, 0x98c3, 0x6c90, 0x32e4, 0x22c0, 0x800a, 0x92c3, 0xc082, 0x98c0 }, 16, 0x000ae380, 1},
+ {{0x39c8, 0x3808, 0xbfff, 0xe8ee, 0xe862, 0x1291, 0x57d0, 0x9ac0, 0x351e, 0x8001, 0x90c0, 0x3f1c, 0x8002, 0x6769, 0x844f, 0x2669 }, 16, 0x000ae3a0, 1},
+ {{0x05c6, 0x236c, 0x8009, 0x8029, 0x98c0, 0x66e9, 0xc945, 0x2f08, 0x8014, 0x94c0, 0x53d8, 0x801d, 0x54d1, 0xdd84, 0x4311, 0x10d0 }, 16, 0x000ae3c0, 1},
+ {{0x0cc6, 0x236c, 0x8009, 0x90c0, 0x54d4, 0xdc1c, 0x4014, 0x2f0b, 0x800a, 0x51d3, 0x331e, 0x8001, 0x6769, 0x90c0, 0x98c3, 0x6c90 }, 16, 0x000ae3e0, 1},
+ {{0x32e4, 0x22c0, 0x800a, 0x92c3, 0xc083, 0x3ac8, 0x3808, 0xbfff, 0x90c0, 0x5492, 0x391f, 0x8001, 0x07c1, 0x2376, 0x8009, 0x13d6 }, 16, 0x000ae400, 1},
+ {{0x30ca, 0x3808, 0xbfff, 0x371f, 0x8002, 0x27e9, 0x3bc0, 0x2377, 0x8009, 0x2718, 0x8108, 0x3680, 0xa000, 0x5490, 0x97bb, 0x391e }, 16, 0x000ae420, 1},
+ {{0x8002, 0x276e, 0x3cc8, 0x3808, 0xbfff, 0xdf17, 0x6769, 0x2518, 0x80ec, 0x1794, 0xedee, 0x96c0, 0x3f18, 0x8002, 0xed62, 0x2469 }, 16, 0x000ae440, 1},
+ {{0x50d5, 0x96c0, 0x3118, 0x8004, 0x8055, 0x2469, 0x00c6, 0x2368, 0x8009, 0x8029, 0x98c0, 0x6469, 0xcb40, 0x2f09, 0x801a, 0x94c0 }, 16, 0x000ae460, 1},
+ {{0x55d9, 0x801d, 0x53d3, 0xde83, 0x4513, 0x12d1, 0x0ac6, 0x2368, 0x8009, 0x90c0, 0x54d2, 0xdd1c, 0x4212, 0x2f0d, 0x8008, 0x56d5 }, 16, 0x000ae480, 1},
+ {{0x3d1f, 0x8002, 0x67e9, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc181, 0xc082, 0x3dc8, 0x3808, 0xbfff, 0x90c0, 0x1295 }, 16, 0x000ae4a0, 1},
+ {{0xedee, 0x96c0, 0x351a, 0x8002, 0xed62, 0x2569, 0x51d5, 0x96c0, 0x331d, 0x8008, 0x8455, 0x26e9, 0x00c6, 0x2360, 0x8009, 0x8029 }, 16, 0x000ae4c0, 1},
+ {{0x98c0, 0x6469, 0xcd40, 0x2f0a, 0x8020, 0x94c0, 0x57da, 0x801d, 0x53d5, 0xdf83, 0x4715, 0x17d2, 0x08c6, 0x2360, 0x8009, 0x90c0 }, 16, 0x000ae4e0, 1},
+ {{0x56d0, 0xdf9e, 0x4710, 0x2f08, 0x800a, 0x57d0, 0x3f1f, 0x8002, 0x67e9, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc181 }, 16, 0x000ae500, 1},
+ {{0xc083, 0x31ca, 0x3808, 0xbfff, 0x3bc0, 0x2377, 0x8009, 0x3480, 0xa000, 0x5791, 0x3ecc, 0x8041, 0x949b, 0x11d6, 0x36ca, 0x3808 }, 16, 0x000ae520, 1},
+ {{0xbfff, 0x3318, 0x8004, 0x2469, 0x38c0, 0x2378, 0x8009, 0x84d7, 0x3680, 0xa000, 0x5196, 0x93b8, 0x331c, 0x8004, 0x98c0, 0xde22 }, 16, 0x000ae540, 1},
+ {{0x3bc8, 0x3808, 0xbfff, 0xde13, 0x6669, 0x80bb, 0x1693, 0xedee, 0x96c0, 0x3d1f, 0x8004, 0xed62, 0x27e9, 0x50d5, 0x96c0, 0x311f }, 16, 0x000ae560, 1},
+ {{0x8010, 0x8031, 0x27e9, 0x2e10, 0x0ac6, 0x38d0, 0x8008, 0x801f, 0x2a0c, 0x810a, 0x5114, 0x78e1, 0x4114, 0x0bc6, 0x38d0, 0x8008 }, 16, 0x000ae580, 1},
+ {{0x90c0, 0x2b08, 0x810a, 0x5010, 0x6c7c, 0x4410, 0x3bc8, 0x3808, 0xbfff, 0x2f0d, 0x8008, 0x1693, 0x52d5, 0x9ac0, 0x3d1c, 0x8004 }, 16, 0x000ae5a0, 1},
+ {{0x90c0, 0x351e, 0x8004, 0x6669, 0x8015, 0x6769, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc182, 0xc082, 0x38c8, 0x3808 }, 16, 0x000ae5c0, 1},
+ {{0xbfff, 0x2f0d, 0x800a, 0x1290, 0x55d5, 0x9ac0, 0x351e, 0x8004, 0x90c0, 0x3b1c, 0x8004, 0x6769, 0x8415, 0x6669, 0x90c0, 0x96c3 }, 16, 0x000ae5e0, 1},
+ {{0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc182, 0xc083, 0x32ca, 0x3808, 0xbfff, 0x38c0, 0x2378, 0x8009, 0x3480, 0xa000, 0x5292, 0x34cc }, 16, 0x000ae600, 1},
+ {{0x8042, 0x9498, 0x14d6, 0x33ca, 0x3808, 0xbfff, 0x391f, 0x8008, 0x27e9, 0x3bc0, 0x2379, 0x8009, 0x2718, 0x80da, 0x3680, 0xa000 }, 16, 0x000ae620, 1},
+ {{0x5693, 0x93bb, 0x3d19, 0x8008, 0x98c0, 0xdca3, 0x3dc8, 0x3808, 0xbfff, 0xdc93, 0x64e9, 0x80bd, 0x1195, 0xe9ee, 0x96c0, 0x331d }, 16, 0x000ae640, 1},
+ {{0x8008, 0xe962, 0x26e9, 0x56d1, 0x96c0, 0x3d18, 0x8020, 0x8035, 0x2469, 0x0cc6, 0x38d0, 0x8008, 0x96c0, 0x8025, 0x2400, 0x8078 }, 16, 0x000ae660, 1},
+ {{0x2c0b, 0x810a, 0x5513, 0x7ac1, 0x4513, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c08, 0x810a, 0x5010, 0x6c7d, 0x4410, 0x3dc8, 0x3808 }, 16, 0x000ae680, 1},
+ {{0xbfff, 0x2f0c, 0x8008, 0x5595, 0x3b1b, 0x8008, 0x25e9, 0x53d4, 0x96c0, 0x3718, 0x8008, 0x801b, 0x6469, 0x90c0, 0x96c3, 0x32e4 }, 16, 0x000ae6a0, 1},
+ {{0x22c0, 0x800a, 0x94c3, 0xc183, 0xc082, 0x3ac8, 0x3808, 0xbfff, 0x2f0c, 0x800a, 0x1292, 0x54d4, 0x9ac0, 0x3518, 0x8008, 0x90c0 }, 16, 0x000ae6c0, 1},
+ {{0x391e, 0x8008, 0x6469, 0x8415, 0x6769, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc183, 0xc083, 0x34ca, 0x3808, 0xbfff }, 16, 0x000ae6e0, 1},
+ {{0x3bc0, 0x2379, 0x8009, 0x3480, 0xa000, 0x5594, 0x3aca, 0x8043, 0x929b, 0x12d6, 0x37ca, 0x3808, 0xbfff, 0x351c, 0x8010, 0x2669 }, 16, 0x000ae700, 1},
+ {{0x3dc0, 0x237a, 0x8009, 0x2718, 0x80dc, 0x3680, 0xa000, 0x5797, 0x96bd, 0x3f1c, 0x8010, 0x98c0, 0xde24, 0x39c8, 0x3808, 0xbfff }, 16, 0x000ae720, 1},
+ {{0xde16, 0x6669, 0x80bf, 0x1491, 0xedee, 0x96c0, 0x391a, 0x8010, 0xed62, 0x2569, 0x55d5, 0x96c0, 0x3b1c, 0x8040, 0x8037, 0x2669 }, 16, 0x000ae740, 1},
+ {{0x0cc6, 0x38d0, 0x8008, 0x8027, 0x2c0c, 0x8100, 0x57d4, 0x3f1e, 0x8100, 0x6769, 0x90c0, 0x9ac1, 0x20e0, 0x9eff, 0x90c0, 0x0907 }, 16, 0x000ae760, 1},
+ {{0xa100, 0x94c1, 0xdc07, 0x4714, 0x92c3, 0x4014, 0x39c8, 0x3808, 0xbfff, 0x2f0a, 0x8008, 0x5291, 0x351e, 0x8010, 0x2769, 0x56d2 }, 16, 0x000ae780, 1},
+ {{0x96c0, 0x3d1a, 0x8010, 0x801b, 0x6569, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc184, 0xc082, 0x3dc8, 0x3808, 0xbfff }, 16, 0x000ae7a0, 1},
+ {{0x2f0a, 0x800a, 0x1295, 0x57d2, 0x9ac0, 0x3518, 0x8010, 0x90c0, 0x3f1e, 0x8010, 0x6469, 0x8415, 0x6769, 0x90c0, 0x96c3, 0x32e4 }, 16, 0x000ae7c0, 1},
+ {{0x22c0, 0x800a, 0x94c3, 0xc184, 0xc083, 0x35ca, 0x3808, 0xbfff, 0x3dc0, 0x237a, 0x8009, 0x3480, 0xa000, 0x5395, 0x36cb, 0x8044 }, 16, 0x000ae7e0, 1},
+ {{0x939d, 0x15d6, 0x30ca, 0x3808, 0xbfff, 0x96c0, 0x3b19, 0x8020, 0xecee, 0x9ac0, 0x64e9, 0x39c0, 0x237b, 0x8009, 0xec62, 0x94c0 }, 16, 0x000ae800, 1},
+ {{0x51d4, 0x84a1, 0x3680, 0xa000, 0x5790, 0x94b9, 0x3f1a, 0x8020, 0x98c0, 0xdd25, 0x38c8, 0x3808, 0xbfff, 0xdd14, 0x6569, 0x2518 }, 16, 0x000ae820, 1},
+ {{0x80f2, 0x96c0, 0x5690, 0x2f08, 0x8008, 0x96c0, 0x3d1b, 0x8020, 0x50d0, 0x96c0, 0x65e9, 0x311b, 0x8020, 0x8015, 0x65e9, 0x90c0 }, 16, 0x000ae840, 1},
+ {{0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc185, 0xc082, 0x3bc8, 0x3808, 0xbfff, 0x2f0a, 0x800a, 0x1693, 0x51d2, 0x9ac0, 0x3d1b }, 16, 0x000ae860, 1},
+ {{0x8020, 0x90c0, 0x3318, 0x8020, 0x65e9, 0x8415, 0x6469, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc185, 0xc083, 0x31ca }, 16, 0x000ae880, 1},
+ {{0x3808, 0xbfff, 0x39c0, 0x237b, 0x8009, 0x3480, 0xa000, 0x5491, 0x38cb, 0x8045, 0x98c0, 0x9399, 0x31e4, 0x2930, 0x800a, 0x331d }, 16, 0x000ae8a0, 1},
+ {{0x8080, 0x26e9, 0x09c6, 0x38d0, 0x8008, 0x8067, 0x290c, 0x8100, 0x14d4, 0x3cc8, 0x380c, 0xbfff, 0x391c, 0x8100, 0x6669, 0x8027 }, 16, 0x000ae8c0, 1},
+ {{0x5394, 0x3719, 0x8020, 0x64e9, 0x90c0, 0x96c2, 0x3ac8, 0x380c, 0xbfff, 0x90c0, 0x92c2, 0x5192, 0x96c6, 0x8038, 0x0901, 0xa020 }, 16, 0x000ae8e0, 1},
+ {{0x92c2, 0x4192, 0x2669, 0x3cc8, 0x380c, 0xbfff, 0x8425, 0x5194, 0x331f, 0x8020, 0x67e9, 0x90c0, 0x98c3, 0x3bc8, 0x380c, 0xbfff }, 16, 0x000ae900, 1},
+ {{0xc7df, 0x90c0, 0x92c3, 0x5093, 0x92c3, 0xdf80, 0x92c3, 0x4793, 0x15d6, 0x36ca, 0x3808, 0xbfff, 0x3b1e, 0x8040, 0x2769, 0x3bc0 }, 16, 0x000ae920, 1},
+ {{0x237c, 0x8009, 0x84bf, 0x3680, 0xa000, 0x5296, 0x94bb, 0x351d, 0x8040, 0x98c0, 0xdea6, 0x39c8, 0x3808, 0xbfff, 0xde94, 0x66e9 }, 16, 0x000ae940, 1},
+ {{0x80a3, 0x1491, 0xe8ee, 0x96c0, 0x391a, 0x8040, 0xe862, 0x2569, 0x56d0, 0x96c0, 0x3d1e, 0x8100, 0x8019, 0x6769, 0x90c0, 0x96c3 }, 16, 0x000ae960, 1},
+ {{0x3204, 0x33b0, 0x800b, 0x92c3, 0xc081, 0x3ac8, 0x3808, 0xbfff, 0x2f08, 0x8008, 0x5292, 0x96c0, 0x351e, 0x8040, 0x52d0, 0x96c0 }, 16, 0x000ae980, 1},
+ {{0x6769, 0x3518, 0x8040, 0x8015, 0x6469, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc186, 0xc082, 0x3bc8, 0x3808, 0xbfff }, 16, 0x000ae9a0, 1},
+ {{0x2f09, 0x800a, 0x1493, 0x51d1, 0x9ac0, 0x391e, 0x8040, 0x90c0, 0x3318, 0x8040, 0x6769, 0x8415, 0x6469, 0x90c0, 0x96c3, 0x32e4 }, 16, 0x000ae9c0, 1},
+ {{0x22c0, 0x800a, 0x94c3, 0xc186, 0xc083, 0x32ca, 0x3808, 0xbfff, 0x3bc0, 0x237c, 0x8009, 0x3480, 0xa000, 0x5292, 0x34ca, 0x8046 }, 16, 0x000ae9e0, 1},
+ {{0x929b, 0x17d6, 0x3ac8, 0x3808, 0xbfff, 0x3f1d, 0x8080, 0x66e9, 0x2718, 0x8116, 0x1392, 0xeaee, 0x96c0, 0x371c, 0x8080, 0xea62 }, 16, 0x000aea00, 1},
+ {{0x2669, 0x54d2, 0x96c0, 0x391e, 0x8200, 0x8067, 0x2769, 0x6c10, 0x805b, 0x33e4, 0x39e4, 0x8001, 0x98c0, 0x3be8, 0x2004, 0xbfff }, 16, 0x000aea20, 1},
+ {{0xc081, 0x90c0, 0x5293, 0x0912, 0xa080, 0x3204, 0x34a0, 0x800b, 0x4293, 0x98c0, 0x39e8, 0x2004, 0xbfff, 0xee74, 0x37f9, 0x3fff }, 16, 0x000aea40, 1},
+ {{0xbf7f, 0x5291, 0xdf82, 0x4791, 0x11d6, 0x04c7, 0x2320, 0x8009, 0x6669, 0x2718, 0x85da, 0x64e9, 0x92c2, 0x6c10, 0x96c2, 0x33e4 }, 16, 0x000aea60, 1},
+ {{0x39ea, 0x8001, 0x31e4, 0x304c, 0x800a, 0x33ca, 0x3808, 0xbfff, 0x38c0, 0x237d, 0x8009, 0x3a80, 0xa000, 0x5293, 0x3cc8, 0x3808 }, 16, 0x000aea80, 1},
+ {{0xbfff, 0x96c0, 0x351a, 0x8080, 0x94b8, 0xdd27, 0xdd14, 0x6569, 0x8077, 0x96c0, 0x5094, 0x2f0d, 0x8008, 0x96c0, 0x311a, 0x8080 }, 16, 0x000aeaa0, 1},
+ {{0x57d5, 0x96c0, 0x6569, 0x3f1a, 0x8080, 0x8015, 0x6569, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc187, 0xc082, 0x3cc8 }, 16, 0x000aeac0, 1},
+ {{0x3808, 0xbfff, 0x2f09, 0x800a, 0x1694, 0x53d1, 0x9ac0, 0x3d1f, 0x8080, 0x90c0, 0x371d, 0x8080, 0x67e9, 0x8415, 0x66e9, 0x90c0 }, 16, 0x000aeae0, 1},
+ {{0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc187, 0xc083, 0x34ca, 0x3808, 0xbfff, 0x38c0, 0x237d, 0x8009, 0x3480, 0xa000, 0x5194 }, 16, 0x000aeb00, 1},
+ {{0x32c9, 0x8047, 0x9198, 0x15d6, 0x37ca, 0x3808, 0xbfff, 0x3b19, 0x8100, 0x24e9, 0x3ac0, 0x237e, 0x8009, 0x8491, 0x3680, 0xa000 }, 16, 0x000aeb20, 1},
+ {{0x5197, 0x95ba, 0x331e, 0x8100, 0x98c0, 0xdf28, 0x3bc8, 0x3808, 0xbfff, 0xdf15, 0x6769, 0x8075, 0x96c0, 0x5693, 0x2f09, 0x8008 }, 16, 0x000aeb40, 1},
+ {{0x96c0, 0x3d19, 0x8100, 0x55d1, 0x96c0, 0x64e9, 0x3b1d, 0x8100, 0x8015, 0x66e9, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3 }, 16, 0x000aeb60, 1},
+ {{0xc188, 0xc082, 0x3ac8, 0x3808, 0xbfff, 0x2f0d, 0x800a, 0x5692, 0x3d1e, 0x8100, 0x2769, 0x56d5, 0x96c0, 0x3d1e, 0x8100, 0x841b }, 16, 0x000aeb80, 1},
+ {{0x6769, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc188, 0xc083, 0x35ca, 0x3808, 0xbfff, 0x3ac0, 0x237e, 0x8009, 0x3480 }, 16, 0x000aeba0, 1},
+ {{0xa000, 0x5695, 0x3ccc, 0x8048, 0x949a, 0x10d6, 0x30ca, 0x3808, 0xbfff, 0x3119, 0x8200, 0x24e9, 0x3cc0, 0x237f, 0x8009, 0x8495 }, 16, 0x000aebc0, 1},
+ {{0x3680, 0xa000, 0x5190, 0x95bc, 0x331c, 0x8200, 0x98c0, 0xde29, 0x39c8, 0x3808, 0xbfff, 0xde15, 0x6669, 0x8079, 0x96c0, 0x5291 }, 16, 0x000aebe0, 1},
+ {{0x2f0c, 0x8008, 0x351d, 0x8200, 0x26e9, 0x55d4, 0x96c0, 0x3b1a, 0x8200, 0x801b, 0x6569, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a }, 16, 0x000aec00, 1},
+ {{0x94c3, 0xc189, 0xc082, 0x3bc8, 0x3808, 0xbfff, 0x90c0, 0x96c0, 0x5193, 0x2f0b, 0x800a, 0x96c0, 0x331a, 0x8200, 0x51d3, 0x96c0 }, 16, 0x000aec20, 1},
+ {{0x6569, 0x331c, 0x8200, 0x8415, 0x6669, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc189, 0xc083, 0x31ca, 0x3808, 0xbfff }, 16, 0x000aec40, 1},
+ {{0x3cc0, 0x237f, 0x8009, 0x3480, 0xa000, 0x5691, 0x3ccd, 0x8049, 0x959c, 0x11d6, 0x36ca, 0x3808, 0xbfff, 0x3318, 0x8400, 0x2469 }, 16, 0x000aec60, 1},
+ {{0x39c0, 0x2380, 0x8009, 0x8495, 0x3680, 0xa000, 0x5396, 0x92b9, 0x371c, 0x8400, 0x98c0, 0xde2a, 0x38c8, 0x3808, 0xbfff, 0xde12 }, 16, 0x000aec80, 1},
+ {{0x6669, 0x8079, 0x96c0, 0x5690, 0x2f0d, 0x8008, 0x3d1d, 0x8400, 0x26e9, 0x55d5, 0x96c0, 0x3b19, 0x8400, 0x801b, 0x64e9, 0x90c0 }, 16, 0x000aeca0, 1},
+ {{0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc18a, 0xc082, 0x39c8, 0x3808, 0xbfff, 0x90c0, 0x96c0, 0x5791, 0x2f09, 0x800a, 0x96c0 }, 16, 0x000aecc0, 1},
+ {{0x3f18, 0x8400, 0x55d1, 0x96c0, 0x6469, 0x3b1b, 0x8400, 0x8415, 0x65e9, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc18a }, 16, 0x000aece0, 1},
+ {{0xc083, 0x32ca, 0x3808, 0xbfff, 0x39c0, 0x2380, 0x8009, 0x3480, 0xa000, 0x5192, 0x32c9, 0x804a, 0x9199, 0x17d6, 0x32ca, 0x3808 }, 16, 0x000aed00, 1},
+ {{0xbfff, 0x3f19, 0x8800, 0x24e9, 0x3cc0, 0x2381, 0x8009, 0x8493, 0x3680, 0xa000, 0x5692, 0x90bc, 0x3d1e, 0x8800, 0x98c0, 0xdf2b }, 16, 0x000aed20, 1},
+ {{0x3dc8, 0x3808, 0xbfff, 0xdf10, 0x6769, 0x8077, 0x96c0, 0x5495, 0x2f0b, 0x8008, 0x96c0, 0x391a, 0x8800, 0x50d3, 0x96c0, 0x6569 }, 16, 0x000aed40, 1},
+ {{0x311d, 0x8800, 0x8015, 0x66e9, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc18b, 0xc082, 0x39c8, 0x3808, 0xbfff, 0x2f0b }, 16, 0x000aed60, 1},
+ {{0x800a, 0x1091, 0x56d3, 0x9ac0, 0x311a, 0x8800, 0x90c0, 0x3d1f, 0x8800, 0x6569, 0x8415, 0x67e9, 0x90c0, 0x96c3, 0x32e4, 0x22c0 }, 16, 0x000aed80, 1},
+ {{0x800a, 0x94c3, 0xc18b, 0xc083, 0x36ca, 0x3808, 0xbfff, 0x3cc0, 0x2381, 0x8009, 0x3480, 0xa000, 0x5696, 0x3ccd, 0x804b, 0x959c }, 16, 0x000aeda0, 1},
+ {{0x17d6, 0x31ca, 0x3808, 0xbfff, 0x3f1d, 0x9000, 0x26e9, 0x3cc0, 0x2382, 0x8009, 0x8493, 0x3680, 0xa000, 0x5191, 0x95bc, 0x331b }, 16, 0x000aedc0, 1},
+ {{0x9000, 0x98c0, 0xddac, 0x3bc8, 0x3808, 0xbfff, 0xdd95, 0x65e9, 0x8077, 0x96c0, 0x5693, 0x2f0a, 0x8008, 0x96c0, 0x3d1d, 0x9000 }, 16, 0x000aede0, 1},
+ {{0x54d2, 0x96c0, 0x66e9, 0x391d, 0x9000, 0x8015, 0x66e9, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc18c, 0xc082, 0x3bc8 }, 16, 0x000aee00, 1},
+ {{0x3808, 0xbfff, 0x2f08, 0x800a, 0x1493, 0x55d0, 0x9ac0, 0x391b, 0x9000, 0x90c0, 0x3b1d, 0x9000, 0x65e9, 0x8415, 0x66e9, 0x90c0 }, 16, 0x000aee20, 1},
+ {{0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc18c, 0xc083, 0x30ca, 0x3808, 0xbfff, 0x3cc0, 0x2382, 0x8009, 0x3480, 0xa000, 0x5690 }, 16, 0x000aee40, 1},
+ {{0x3ccb, 0x804c, 0x939c, 0x17d6, 0x35ca, 0x3808, 0xbfff, 0x3f3f, 0x8000, 0x27e9, 0x3cc0, 0x2383, 0x8009, 0x8493, 0x3680, 0xa000 }, 16, 0x000aee60, 1},
+ {{0x5195, 0x97bc, 0x333d, 0x8000, 0x98c0, 0xdead, 0x3dc8, 0x3808, 0xbfff, 0xde97, 0x66e9, 0x8077, 0x96c0, 0x5395, 0x2f0c, 0x8008 }, 16, 0x000aee80, 1},
+ {{0x96c0, 0x373d, 0x8000, 0x50d4, 0x96c0, 0x66e9, 0x313a, 0x8000, 0x8015, 0x6569, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3 }, 16, 0x000aeea0, 1},
+ {{0xc18d, 0xc082, 0x3cc8, 0x3808, 0xbfff, 0x2f0d, 0x800a, 0x1094, 0x52d5, 0x9ac0, 0x3139, 0x8000, 0x90c0, 0x353b, 0x8000, 0x64e9 }, 16, 0x000aeec0, 1},
+ {{0x8415, 0x65e9, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc18d, 0xc083, 0x37ca, 0x3808, 0xbfff, 0x3cc0, 0x2383, 0x8009 }, 16, 0x000aeee0, 1},
+ {{0x3480, 0xa000, 0x5297, 0x34cb, 0x804d, 0x939c, 0x13d6, 0x34ca, 0x3808, 0xbfff, 0x375b, 0x8000, 0x25e9, 0x3dc0, 0x2384, 0x8009 }, 16, 0x000aef00, 1},
+ {{0x8493, 0x3a80, 0xa000, 0x5694, 0x39c8, 0x3808, 0xbfff, 0x96c0, 0x3d59, 0x8000, 0x96bd, 0xdcae, 0xdc96, 0x64e9, 0x8077, 0x96c0 }, 16, 0x000aef20, 1},
+ {{0x5091, 0x2f0b, 0x8008, 0x96c0, 0x315c, 0x8000, 0x52d3, 0x96c0, 0x6669, 0x355c, 0x8000, 0x8015, 0x6669, 0x90c0, 0x96c3, 0x32e4 }, 16, 0x000aef40, 1},
+ {{0x22c0, 0x800a, 0x94c3, 0xc18e, 0xc082, 0x39c8, 0x3808, 0xbfff, 0x2f08, 0x800a, 0x5791, 0x96c0, 0x3f5a, 0x8000, 0x57d0, 0x96c0 }, 16, 0x000aef60, 1},
+ {{0x6569, 0x3f5f, 0x8000, 0x8415, 0x67e9, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc18e, 0xc083, 0x33ca, 0x3808, 0xbfff }, 16, 0x000aef80, 1},
+ {{0x3dc0, 0x2384, 0x8009, 0x3480, 0xa000, 0x5693, 0x3ccd, 0x804e, 0x959d, 0x14d6, 0x39c8, 0x3808, 0xbfff, 0x399d, 0x8000, 0x26e9 }, 16, 0x000aefa0, 1},
+ {{0x3ec0, 0x2385, 0x8009, 0x8487, 0x94c0, 0x5591, 0x97be, 0x3b98, 0x8000, 0x98c0, 0xdc2f, 0x3dc8, 0x3808, 0xbfff, 0xdc17, 0x6469 }, 16, 0x000aefc0, 1},
+ {{0x806d, 0x96c0, 0x5195, 0x2f0a, 0x8008, 0x96c0, 0x339a, 0x8000, 0x57d2, 0x96c0, 0x6569, 0x3f9d, 0x8000, 0x8015, 0x66e9, 0x90c0 }, 16, 0x000aefe0, 1},
+ {{0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc18f, 0xc082, 0x98c0, 0x38c8, 0x3808, 0xbfff, 0xef4a, 0x52d7, 0x5490, 0x399d, 0x8000 }, 16, 0x000af000, 1},
+ {{0x96c0, 0x66e9, 0x359d, 0x8000, 0x8415, 0x66e9, 0x90c0, 0x96c3, 0x32e4, 0x22c0, 0x800a, 0x94c3, 0xc18f, 0xc083, 0x3cc8, 0x3808 }, 16, 0x000af020, 1},
+ {{0xbfff, 0x90c0, 0x5094, 0x30cc, 0x804f, 0x949e, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000af040, 1},
+ {{0x3e00, 0xa10c, 0x7556, 0x75d7, 0x09c6, 0x38d0, 0x8008, 0xcf49, 0x3c80, 0xa000, 0x6e90, 0x3fc0, 0x2334, 0x8009, 0xce48, 0x3680 }, 16, 0x000af060, 1},
+ {{0xa000, 0x290d, 0x825c, 0x3680, 0xa000, 0x53d5, 0x50d7, 0x96c0, 0x71e0, 0x371c, 0x8001, 0x2518, 0x857e, 0x98c0, 0x6669, 0x371b }, 16, 0x000af080, 1},
+ {{0x8002, 0x4317, 0x8431, 0x65e9, 0x90c0, 0x98c2, 0xc0fe, 0x04c7, 0x2372, 0x8009, 0x9ac2, 0xdc04, 0xc6fc, 0x03c7, 0x2374, 0x8009 }, 16, 0x000af0a0, 1},
+ {{0x98c2, 0xdf03, 0x00c0, 0x2372, 0x8009, 0x807c, 0x96c2, 0x06c0, 0x2374, 0x8009, 0x3680, 0xa000, 0xed42, 0xc4fe, 0x3680, 0xa000 }, 16, 0x000af0c0, 1},
+ {{0x52d5, 0xc7fc, 0x98c0, 0x2f0c, 0x800a, 0xde02, 0xc2fc, 0x3480, 0xa000, 0x4415, 0x0ec6, 0x38d0, 0x8008, 0x03c7, 0x2374, 0x8009 }, 16, 0x000af0e0, 1},
+ {{0x06c7, 0x2372, 0x8009, 0x9ac0, 0x0906, 0xa001, 0x90c0, 0x2e09, 0x8266, 0x0903, 0xa003, 0x06c0, 0x2372, 0x8009, 0x03c0, 0x2374 }, 16, 0x000af100, 1},
+ {{0x8009, 0x54d1, 0xdf84, 0x4711, 0x08c6, 0x38d0, 0x8008, 0x90c0, 0x280a, 0x8266, 0x50d2, 0x0900, 0xa001, 0x4012, 0x54d4, 0xdd04 }, 16, 0x000af120, 1},
+ {{0x0902, 0xa001, 0x4214, 0x57d7, 0x9ac0, 0x3f18, 0x8004, 0x90c0, 0x3f1a, 0x8008, 0x6469, 0x8431, 0x6569, 0x90c0, 0x98c2, 0xc7fd }, 16, 0x000af140, 1},
+ {{0x01c7, 0x2372, 0x8009, 0x9ac2, 0xdf81, 0xc3f3, 0x06c7, 0x2374, 0x8009, 0x98c2, 0xdd86, 0x07c0, 0x2372, 0x8009, 0x807c, 0x96c2 }, 16, 0x000af160, 1},
+ {{0x03c0, 0x2374, 0x8009, 0x98c0, 0x0ec6, 0x38d0, 0x8008, 0xc0fd, 0x96c0, 0xc3f3, 0x2f09, 0x800a, 0x96c0, 0xc7f3, 0x2e0e, 0x825e }, 16, 0x000af180, 1},
+ {{0x54d6, 0xdc04, 0x4016, 0x0ac6, 0x38d0, 0x8008, 0x01c7, 0x2374, 0x8009, 0x04c7, 0x2372, 0x8009, 0x9ac0, 0x0904, 0xa002, 0x90c0 }, 16, 0x000af1a0, 1},
+ {{0x2a0e, 0x8266, 0x0901, 0xa00c, 0x04c0, 0x2372, 0x8009, 0x01c0, 0x2374, 0x8009, 0x50d6, 0xdd80, 0x4316, 0x0ac6, 0x38d0, 0x8008 }, 16, 0x000af1c0, 1},
+ {{0x90c0, 0x2a0b, 0x8266, 0x52d3, 0x0902, 0xa004, 0x4213, 0x52d1, 0xdf82, 0x0907, 0xa004, 0x4711, 0x13d7, 0x08c6, 0x38d0, 0x8008 }, 16, 0x000af1e0, 1},
+ {{0x9ac0, 0x371a, 0x8010, 0xc6fb, 0x2f0b, 0x800a, 0x98c0, 0x6569, 0xc2cf, 0x2809, 0x825e, 0x94c0, 0xc0cf, 0x8065, 0x57d1, 0xdf07 }, 16, 0x000af200, 1},
+ {{0x4611, 0x08c6, 0x38d0, 0x8008, 0x04c7, 0x2372, 0x8009, 0x03c7, 0x2374, 0x8009, 0x9ac0, 0x0904, 0xa004, 0x90c0, 0x2808, 0x8266 }, 16, 0x000af220, 1},
+ {{0x0903, 0xa030, 0x03c0, 0x2374, 0x8009, 0x04c0, 0x2372, 0x8009, 0x54d0, 0xdd04, 0x4210, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c0e }, 16, 0x000af240, 1},
+ {{0x8266, 0x51d6, 0x0901, 0xa010, 0x4116, 0x51d3, 0xdc01, 0x0900, 0xa010, 0x0013, 0x31e4, 0x32a0, 0x800a, 0x98c0, 0xc4fb, 0x03c7 }, 16, 0x000af260, 1},
+ {{0x2372, 0x8009, 0x9ac0, 0xde03, 0xc0cf, 0x01c7, 0x2374, 0x8009, 0x98c0, 0xdc01, 0x04c0, 0x2372, 0x8009, 0x00c0, 0x2374, 0x8009 }, 16, 0x000af280, 1},
+ {{0x10d7, 0x0ac6, 0x38d0, 0x8008, 0x9ac0, 0x311b, 0x8020, 0xc6f7, 0x20e0, 0x9f3f, 0x9ac0, 0x2f0d, 0x800a, 0x65e9, 0x2a0a, 0x825e }, 16, 0x000af2a0, 1},
+ {{0x96c0, 0x8067, 0x27e0, 0x9f3f, 0x52d2, 0xdf02, 0x4612, 0x0bc6, 0x38d0, 0x8008, 0x06c7, 0x2374, 0x8009, 0x03c7, 0x2372, 0x8009 }, 16, 0x000af2c0, 1},
+ {{0x9ac0, 0x0903, 0xa008, 0x90c0, 0x2b08, 0x8266, 0x0906, 0xa0c0, 0x03c0, 0x2372, 0x8009, 0x06c0, 0x2374, 0x8009, 0x54d0, 0xdc04 }, 16, 0x000af2e0, 1},
+ {{0x4010, 0x09c6, 0x38d0, 0x8008, 0x90c0, 0x290e, 0x8266, 0x51d6, 0x0901, 0xa040, 0x4116, 0x52d5, 0xdf82, 0x0907, 0xa040, 0x0715 }, 16, 0x000af300, 1},
+ {{0x31e4, 0x334e, 0x800a, 0x98c0, 0x02c7, 0x2372, 0x8009, 0xc0f7, 0x96c0, 0xdc02, 0x22e0, 0x9f3f, 0x04c7, 0x2374, 0x8009, 0x98c0 }, 16, 0x000af320, 1},
+ {{0xdd04, 0x00c0, 0x2372, 0x8009, 0x02c0, 0x2374, 0x8009, 0x12d7, 0x09c6, 0x38d0, 0x8008, 0x9ac0, 0x3518, 0x8040, 0xc1ef, 0x2f0e }, 16, 0x000af340, 1},
+ {{0x800a, 0x9ac0, 0x20e0, 0x9cff, 0x6469, 0x290c, 0x825e, 0x96c0, 0x8067, 0x23e0, 0x9cff, 0x57d4, 0xdc87, 0x4114, 0x0cc6, 0x38d0 }, 16, 0x000af360, 1},
+ {{0x8008, 0x07c7, 0x2374, 0x8009, 0x06c7, 0x2372, 0x8009, 0x9ac0, 0x0906, 0xa010, 0x90c0, 0x2c0d, 0x8266, 0x0907, 0xa300, 0x06c0 }, 16, 0x000af380, 1},
+ {{0x2372, 0x8009, 0x07c0, 0x2374, 0x8009, 0x51d5, 0xdc01, 0x4015, 0x09c6, 0x38d0, 0x8008, 0x90c0, 0x290d, 0x8266, 0x50d5, 0x0900 }, 16, 0x000af3a0, 1},
+ {{0xa100, 0x4015, 0x51d6, 0xdd81, 0x0903, 0xa100, 0x0316, 0x31e4, 0x33fc, 0x800a, 0x98c0, 0xc0ef, 0x01c7, 0x2372, 0x8009, 0x96c0 }, 16, 0x000af3c0, 1},
+ {{0xdc01, 0x24e0, 0x9cff, 0x06c7, 0x2374, 0x8009, 0x98c0, 0xde06, 0x00c0, 0x2372, 0x8009, 0x04c0, 0x2374, 0x8009, 0x17d7, 0x0ac6 }, 16, 0x000af3e0, 1},
+ {{0x38d0, 0x8008, 0x9ac0, 0x3f18, 0x8080, 0xc7df, 0x2f0d, 0x800a, 0x9ac0, 0x20e0, 0x93ff, 0x6469, 0x2a0b, 0x825e, 0x96c0, 0x8073 }, 16, 0x000af400, 1},
+ {{0x24e0, 0x93ff, 0x13d3, 0xc581, 0x0903, 0xa020, 0x4313, 0x09c6, 0x38d0, 0x8008, 0x01c7, 0x2374, 0x8009, 0x9ac0, 0x0901, 0xac00 }, 16, 0x000af420, 1},
+ {{0x90c0, 0x290a, 0x8266, 0x01c0, 0x2374, 0x8009, 0x51d2, 0xdc01, 0x4012, 0x16d5, 0x0cc6, 0x38d0, 0x8008, 0xde06, 0x96c0, 0x4415 }, 16, 0x000af440, 1},
+ {{0x2c08, 0x8100, 0x16d0, 0xed66, 0x96c0, 0x3d1e, 0x8100, 0x52d5, 0x6769, 0x90c0, 0x98c1, 0x0902, 0xa020, 0x90c0, 0xc6df, 0x94c1 }, 16, 0x000af460, 1},
+ {{0x4215, 0xdf02, 0x98c6, 0x31e4, 0x34b2, 0x800a, 0x4615, 0x00c7, 0x2372, 0x8009, 0x96c0, 0xdf80, 0x22e0, 0x93ff, 0x04c7, 0x2374 }, 16, 0x000af480, 1},
+ {{0x8009, 0x98c0, 0xdd04, 0x07c0, 0x2372, 0x8009, 0x02c0, 0x2374, 0x8009, 0x11d7, 0x0cc6, 0x38d0, 0x8008, 0x9ac0, 0x26e0, 0x9fbf }, 16, 0x000af4a0, 1},
+ {{0x90c0, 0x331a, 0x8100, 0x9ac0, 0x23c0, 0x8fff, 0x6569, 0x2c0c, 0x825e, 0x96c0, 0x806d, 0x2f08, 0x800a, 0x96c0, 0x51d4, 0x20c0 }, 16, 0x000af4c0, 1},
+ {{0x8fff, 0xdf01, 0x4614, 0x09c6, 0x38d0, 0x8008, 0x06c7, 0x2372, 0x8009, 0x02c7, 0x2374, 0x8009, 0x9ac0, 0x0906, 0xa040, 0x90c0 }, 16, 0x000af4e0, 1},
+ {{0x290c, 0x8266, 0x0922, 0xb000, 0x02c0, 0x2374, 0x8009, 0x06c0, 0x2372, 0x8009, 0x56d4, 0xdd86, 0x4314, 0x0ac6, 0x38d0, 0x8008 }, 16, 0x000af500, 1},
+ {{0x90c0, 0x2a09, 0x8266, 0x51d1, 0x0901, 0xa100, 0x4111, 0x53d0, 0xdc03, 0x0900, 0xa100, 0x0010, 0x31e4, 0x356a, 0x800a, 0x9ac0 }, 16, 0x000af520, 1},
+ {{0x24e0, 0x9fbf, 0x90c0, 0x27c0, 0x8fff, 0x00c7, 0x2372, 0x8009, 0x98c0, 0xde00, 0x03c7, 0x2374, 0x8009, 0x98c0, 0xdf83, 0x04c0 }, 16, 0x000af540, 1},
+ {{0x2372, 0x8009, 0x07c0, 0x2374, 0x8009, 0x16d7, 0x0dc6, 0x38d0, 0x8008, 0x9ac0, 0x21e0, 0x9f7f, 0x90c0, 0x3d1e, 0x8200, 0x9ac0 }, 16, 0x000af560, 1},
+ {{0x2f0c, 0x800a, 0x6769, 0x2d0e, 0x825e, 0x94c0, 0x57d6, 0x8067, 0xdc87, 0x4116, 0x0ec6, 0x38d0, 0x8008, 0x01c7, 0x2374, 0x8009 }, 16, 0x000af580, 1},
+ {{0x06c7, 0x2372, 0x8009, 0x9ac0, 0x09c1, 0xa000, 0x90c0, 0x2e0a, 0x8266, 0x0906, 0xa080, 0x01c0, 0x2374, 0x8009, 0x06c0, 0x2372 }, 16, 0x000af5a0, 1},
+ {{0x8009, 0x56d2, 0x3d39, 0x9fff, 0x4112, 0x09c6, 0x38d0, 0x8008, 0x90c0, 0x290e, 0x8266, 0x57d6, 0x0907, 0xa100, 0x4716, 0x51d4 }, 16, 0x000af5c0, 1},
+ {{0x333f, 0x9fff, 0x0907, 0xa100, 0x0714, 0x31e4, 0x3614, 0x800a, 0x22e0, 0x9f7f, 0x06c7, 0x2372, 0x8009, 0x98c0, 0xdd06, 0x07c7 }, 16, 0x000af5e0, 1},
+ {{0x2374, 0x8009, 0x3f3b, 0x9fff, 0x02c0, 0x2372, 0x8009, 0x03c0, 0x2374, 0x8009, 0x0cc6, 0x38d0, 0x8008, 0x06c7, 0x2372, 0x8009 }, 16, 0x000af600, 1},
+ {{0x96c0, 0xd806, 0x2c09, 0x825e, 0x16d1, 0x3c00, 0x2048, 0x8008, 0xdc06, 0x4011, 0x54d7, 0x9ac0, 0x24e0, 0x8fef, 0x90c0, 0x3918 }, 16, 0x000af620, 1},
+ {{0x8080, 0x6469, 0x90c0, 0x96c3, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x94c3, 0x2d0e, 0x825e, 0x92c3, 0x52d6, 0x94c3, 0x0902, 0xa020 }, 16, 0x000af640, 1},
+ {{0x92c3, 0x4216, 0x11d4, 0x0bc6, 0x38d0, 0x8008, 0x335b, 0x8000, 0x96c0, 0x65e9, 0x2b0b, 0x825e, 0x94c0, 0x50d3, 0x800b, 0xde00 }, 16, 0x000af660, 1},
+ {{0x4413, 0x98c0, 0x0dc6, 0x38d0, 0x8008, 0xef42, 0x96c0, 0x52d7, 0x2f0b, 0x8002, 0x9ac0, 0x2d08, 0x825e, 0x90c0, 0x2f0c, 0x8004 }, 16, 0x000af680, 1},
+ {{0x11d0, 0xe842, 0x96c0, 0x70e2, 0x2f09, 0x8006, 0x90c0, 0x92c3, 0x4117, 0x14d3, 0x53d0, 0x31e4, 0xe842, 0x90c0, 0x94c3, 0x4313 }, 16, 0x000af6a0, 1},
+ {{0xc581, 0x14d4, 0x53d0, 0x71e4, 0x90c0, 0x92c3, 0x4410, 0x17d1, 0x0cc6, 0x38d0, 0x8008, 0x04c7, 0x2370, 0x8009, 0x2c0a, 0x8264 }, 16, 0x000af6c0, 1},
+ {{0x11d2, 0x52d2, 0x30e7, 0x3452, 0xdf84, 0x94c0, 0xdc04, 0x8089, 0x3067, 0xdb84, 0x94c0, 0xdf82, 0x8025, 0x4712, 0x10d1, 0x0ec6 }, 16, 0x000af6e0, 1},
+ {{0x38d0, 0x8008, 0x01c7, 0x2370, 0x8009, 0x96c0, 0xdc80, 0x2e0c, 0x8264, 0x54d4, 0xdc9c, 0x4114, 0x12d1, 0x0ec6, 0x38d0, 0x8008 }, 16, 0x000af700, 1},
+ {{0x00c7, 0x2370, 0x8009, 0x96c0, 0xda00, 0x2e08, 0x8264, 0x9ac0, 0xdd04, 0x56d0, 0x3de8, 0x3c10, 0xbfff, 0x9ac0, 0xdf04, 0x6561 }, 16, 0x000af720, 1},
+ {{0x3ae8, 0x3c10, 0xbfff, 0x6761, 0x7362, 0x90c0, 0x92c3, 0x56d0, 0x92c3, 0x4611, 0x5695, 0x3dfb, 0x9fff, 0x4395, 0x1092, 0x0dc6 }, 16, 0x000af740, 1},
+ {{0x38d0, 0x8008, 0x90c0, 0x2d0d, 0x8264, 0x54d5, 0xd994, 0xdd98, 0x4392, 0x0cc6, 0x38d0, 0x8008, 0x2f0e, 0x8008, 0x96c0, 0x50d6 }, 16, 0x000af760, 1},
+ {{0x2c0d, 0x8266, 0x16d5, 0x53d5, 0x3360, 0x34d3, 0x07c7, 0x2374, 0x8009, 0x96c0, 0xdc07, 0xdc87, 0x8089, 0x30e0, 0xd907, 0x94c0 }, 16, 0x000af780, 1},
+ {{0xdd03, 0x8025, 0x4215, 0x10d6, 0x0dc6, 0x38d0, 0x8008, 0x04c7, 0x2374, 0x8009, 0x96c0, 0xde00, 0x2d0d, 0x8266, 0x56d5, 0xde1e }, 16, 0x000af7a0, 1},
+ {{0x4415, 0x10d6, 0x0cc6, 0x38d0, 0x8008, 0x01c7, 0x2374, 0x8009, 0x96c0, 0xd881, 0x2c0d, 0x8266, 0x9ac0, 0xdc01, 0x52d5, 0x3ae8 }, 16, 0x000af7c0, 1},
+ {{0x3c10, 0xbfff, 0x9ac0, 0xdd01, 0x6461, 0x38e8, 0x3c10, 0xbfff, 0x6561, 0x7160, 0x90c0, 0x92c3, 0x51d5, 0x92c3, 0x4116, 0x5192 }, 16, 0x000af7e0, 1},
+ {{0x33ec, 0x9fff, 0x4492, 0x1790, 0x0ac6, 0x38d0, 0x8008, 0x90c0, 0x2a09, 0x8266, 0x52d1, 0xdd1f, 0x4290, 0x0ec6, 0x38d0, 0x8008 }, 16, 0x000af800, 1},
+ {{0x2f0a, 0x800a, 0x96c0, 0x54d2, 0x2e0c, 0x8268, 0x11d4, 0x3de8, 0x3c14, 0xbfff, 0x30e4, 0x32f9, 0x3fff, 0xbf00, 0x8027, 0x0112 }, 16, 0x000af820, 1},
+ {{0x3ce8, 0x3c14, 0xbfff, 0x5195, 0xdd01, 0x4295, 0x1294, 0x08c6, 0x38d0, 0x8008, 0x90c0, 0x2808, 0x8268, 0x57d0, 0xdb17, 0xdf1a }, 16, 0x000af840, 1},
+ {{0x4694, 0x0ec6, 0x38d0, 0x8008, 0x9ac0, 0x2f08, 0x800c, 0x90c0, 0x2f0a, 0x800e, 0x96c0, 0x50d0, 0x2e0d, 0x826a, 0x11d5, 0xed42 }, 16, 0x000af860, 1},
+ {{0x9ac0, 0x2f0c, 0x8010, 0x70e0, 0x2d0e, 0x8002, 0x3c80, 0xa100, 0x2f0f, 0x8012, 0x90c0, 0x2f0c, 0x8014, 0x3807, 0xa100, 0x4110 }, 16, 0x000af880, 1},
+ {{0x2d0b, 0x8006, 0x16d5, 0x51d2, 0x3c00, 0xa100, 0x2d08, 0x8004, 0x7361, 0x2d0d, 0x8008, 0x3c80, 0xa100, 0x2f0e, 0x8016, 0x90c0 }, 16, 0x000af8a0, 1},
+ {{0x2d0a, 0x800a, 0x3807, 0xa100, 0x4612, 0x2d09, 0x800c, 0x17d4, 0x56d6, 0x3c80, 0xa000, 0x2f08, 0x801c, 0x7367, 0x2f09, 0x801e }, 16, 0x000af8c0, 1},
+ {{0x2d0a, 0x8014, 0x98c3, 0x4614, 0x3000, 0x2000, 0x8008, 0x3607, 0xa100, 0x56d6, 0x52d7, 0x9ac7, 0x2f0e, 0x8020, 0x90c0, 0x3d1f }, 16, 0x000af8e0, 1},
+ {{0x8ffe, 0x98c7, 0x2f0c, 0x8022, 0x90c0, 0x6dc3, 0x96c3, 0x03c2, 0x2364, 0x8009, 0x96c0, 0x56d0, 0x2d08, 0x8012, 0x7362, 0x90c0 }, 16, 0x000af900, 1},
+ {{0x3483, 0xa000, 0x4617, 0x3680, 0xa100, 0x54d4, 0x51d3, 0x3800, 0xa100, 0x70e4, 0x2f0f, 0x8024, 0x33ca, 0x3810, 0xbfff, 0x3483 }, 16, 0x000af920, 1},
+ {{0xa000, 0x4114, 0x3680, 0xa100, 0x53d6, 0x51d5, 0x3800, 0xa100, 0x70e3, 0x2f0c, 0x801a, 0x90c0, 0x3a83, 0xa000, 0x4116, 0x3400 }, 16, 0x000af940, 1},
+ {{0x2000, 0x8008, 0x3887, 0xa100, 0x57d5, 0x2f0d, 0x8018, 0x3a07, 0xa100, 0x90c0, 0x56d5, 0x3f19, 0x8ffe, 0x3807, 0xa100, 0x6dc4 }, 16, 0x000af960, 1},
+ {{0x2f0e, 0x8026, 0x96c3, 0x03c2, 0x236c, 0x8009, 0x3880, 0xa100, 0x50d2, 0x2d0a, 0x800e, 0x7066, 0x90c0, 0x3483, 0xa000, 0x4015 }, 16, 0x000af980, 1},
+ {{0x3680, 0xa100, 0x54d4, 0x52d1, 0x3800, 0xa100, 0x7164, 0x2d09, 0x8016, 0x90c0, 0x3483, 0xa000, 0x4214, 0x3680, 0xa100, 0x54d0 }, 16, 0x000af9a0, 1},
+ {{0x52d2, 0x7164, 0x90c0, 0x3a83, 0xa000, 0x4210, 0x3100, 0x2000, 0x8008, 0x3887, 0xa100, 0x54d2, 0x2d08, 0x8010, 0x96c7, 0x56d1 }, 16, 0x000af9c0, 1},
+ {{0x391a, 0x8ffe, 0x94c7, 0xed58, 0x6dd8, 0x96c3, 0x03c2, 0x2368, 0x8009, 0x3480, 0xa000, 0x54d0, 0x7266, 0x90c0, 0x98c7, 0x39c8 }, 16, 0x000af9e0, 1},
+ {{0x3810, 0xbfff, 0x4411, 0x13d0, 0x56d6, 0x71e6, 0x90c0, 0x92c3, 0x4316, 0x14d4, 0x53d2, 0x71e4, 0x90c0, 0x98c3, 0x4314, 0x3400 }, 16, 0x000afa00, 1},
+ {{0x2000, 0x8008, 0x3607, 0xa100, 0x53d2, 0x50d7, 0x94c3, 0x371f, 0x8ffe, 0x98c7, 0x3cc8, 0x3810, 0xbfff, 0x6d57, 0x96c3, 0x02c2 }, 16, 0x000afa20, 1},
+ {{0x2360, 0x8009, 0x3480, 0xa000, 0x51d1, 0x70e0, 0x90c0, 0x3483, 0xa000, 0x4117, 0x3680, 0xa000, 0x53d6, 0x54d5, 0x7263, 0x90c0 }, 16, 0x000afa40, 1},
+ {{0x3483, 0xa000, 0x4416, 0x3680, 0xa000, 0x5193, 0x53d7, 0x33fc, 0x9fff, 0x71e4, 0x800d, 0x5094, 0x31ef, 0x9fff, 0xdd9f, 0x4391 }, 16, 0x000afa60, 1},
+ {{0x26e9, 0x15d3, 0x3ec8, 0x380c, 0xbfff, 0x94c0, 0x53d7, 0x801b, 0x9ac0, 0xde83, 0x5796, 0x3cc8, 0x380c, 0xbfff, 0x3feb, 0x9fff }, 16, 0x000afa80, 1},
+ {{0xde9b, 0x4594, 0x3a80, 0xb900, 0x77d3, 0x7752, 0xcf41, 0xce40, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000afaa0, 1},
+ {{0x24e8, 0x75d0, 0x96c7, 0x7453, 0x64e4, 0x8017, 0x32e4, 0x3ac0, 0x800a, 0x74f1, 0x31e4, 0x3afe, 0x800a, 0x64e9, 0x8021, 0x65e9 }, 16, 0x000afac0, 1},
+ {{0x801d, 0x98c0, 0xd4af, 0x36ca, 0x83c1, 0x78e1, 0x94c6, 0x8013, 0x6c10, 0x3472, 0x30e4, 0x3afe, 0x800a, 0xd419, 0x7453, 0x94c0 }, 16, 0x000afae0, 1},
+ {{0x7470, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x6c90, 0x5310, 0x280c, 0x800a, 0x9ac0, 0x65e9, 0x7def }, 16, 0x000afb00, 1},
+ {{0xe84c, 0x2401, 0x8080, 0x94c6, 0xeae8, 0x6e10, 0x2ea4, 0x120a, 0xe94c, 0x96c0, 0x7d6f, 0x5051, 0x9345, 0x96c0, 0x7163, 0x2b03 }, 16, 0x000afb20, 1},
+ {{0x8016, 0x92c2, 0x6ec4, 0x3175, 0x9f80, 0x94c0, 0x4549, 0x90c0, 0x2d24, 0x100a, 0x550c, 0x3c6f, 0x4508, 0x3063, 0x5551, 0x92d2 }, 16, 0x000afb40, 1},
+ {{0x6d44, 0x3b72, 0x9f80, 0x4249, 0x94c0, 0x5114, 0x9f70, 0x4110, 0x2c10, 0x1219, 0xe842, 0x3d6f, 0x1519, 0x5350, 0x9ac0, 0x7eef }, 16, 0x000afb60, 1},
+ {{0x7dc2, 0x5111, 0x24e1, 0x9f80, 0x3e20, 0xa000, 0x7165, 0x75db, 0x7cef, 0xe842, 0x2521, 0x9000, 0x3a06, 0xa002, 0x90c0, 0x5050 }, 16, 0x000afb80, 1},
+ {{0x6e90, 0x6d53, 0x3a46, 0xa004, 0x6d0d, 0x27c1, 0x9000, 0x7161, 0x3600, 0xa804, 0x35ea, 0x9fff, 0x3a06, 0xa008, 0x90c0, 0x7d67 }, 16, 0x000afba0, 1},
+ {{0x2401, 0x8080, 0x3400, 0xa040, 0x6ec8, 0x3bed, 0x9fff, 0x3175, 0x9f00, 0x3400, 0xa040, 0x60e6, 0x33e9, 0x9fff, 0x64ea, 0x3400 }, 16, 0x000afbc0, 1},
+ {{0xa800, 0xd2d5, 0x3400, 0xa040, 0x6dbb, 0x37eb, 0x9fff, 0x65e8, 0x3600, 0xa800, 0xd2df, 0x9f70, 0x4550, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000afbe0, 1},
+ {{0x96c0, 0x5211, 0x290c, 0x8002, 0x3d6f, 0x1514, 0xe842, 0x9ac0, 0x3ac9, 0x904f, 0x5350, 0x280d, 0x8002, 0x9ac0, 0x24e1, 0x9f40 }, 16, 0x000afc00, 1},
+ {{0x7161, 0x2021, 0x9c00, 0x5255, 0x96c6, 0x6c32, 0x2401, 0x80c0, 0x9ac0, 0x3774, 0x9f80, 0x90c0, 0x31e8, 0x9fff, 0x6d80, 0x37eb }, 16, 0x000afc20, 1},
+ {{0x9fff, 0x65ea, 0x94c0, 0xd250, 0x8015, 0x6dc0, 0x37eb, 0x9fff, 0x65e8, 0xd258, 0x92c3, 0x6664, 0x96c0, 0x5211, 0x2c0d, 0x8002 }, 16, 0x000afc40, 1},
+ {{0x0515, 0x4214, 0x9f70, 0x4450, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x5250, 0x280b, 0x8004, 0x96c0, 0x6c5c, 0xeceb, 0xe942 }, 16, 0x000afc60, 1},
+ {{0xec62, 0x1314, 0x4254, 0x4313, 0x1159, 0x5553, 0x21e2, 0x5251, 0x613d, 0x35ea, 0x9fff, 0x94c0, 0x6111, 0x9f70, 0xd81a, 0x90c0 }, 16, 0x000afc80, 1},
+ {{0x3e00, 0xa004, 0x2601, 0x8001, 0xd911, 0x6c90, 0x7656, 0xcc57, 0x3880, 0xa100, 0x6f2a, 0xce48, 0xcf4b, 0x96c0, 0xfbc3, 0x0cf6 }, 16, 0x000afca0, 1},
+ {{0xbfff, 0x96c0, 0xc7a0, 0x2718, 0x814c, 0x98c0, 0x6c10, 0xeb54, 0x2f00, 0x8062, 0x96c0, 0x4713, 0x2900, 0x8064, 0x96c0, 0xeb50 }, 16, 0x000afcc0, 1},
+ {{0x2a00, 0x8054, 0x96c0, 0x4013, 0x2b0d, 0x8042, 0x3680, 0xa000, 0xe9ed, 0x4015, 0x3600, 0xa100, 0xeced, 0xe962, 0x3680, 0xa000 }, 16, 0x000afce0, 1},
+ {{0x4011, 0xebed, 0x94c0, 0xec64, 0xeb3f, 0x3600, 0xa100, 0x4014, 0xe9ed, 0x96c0, 0x4013, 0x2800, 0x8056, 0x3600, 0xa100, 0xeced }, 16, 0x000afd00, 1},
+ {{0xe939, 0x96c0, 0xec3a, 0x2e00, 0x8058, 0x3680, 0xa000, 0x4011, 0xe9ed, 0x96c0, 0x4014, 0x2a00, 0x805a, 0x94c0, 0xe938, 0xebed }, 16, 0x000afd20, 1},
+ {{0x96c0, 0x4011, 0x2900, 0x805c, 0x94c0, 0xeb3e, 0xefed, 0x96c0, 0x4013, 0x2e00, 0x805e, 0x94c0, 0xef3a, 0xe8ed, 0x96c0, 0x4017 }, 16, 0x000afd40, 1},
+ {{0x2f00, 0x8044, 0x94c0, 0xe839, 0xebed, 0x96c0, 0x4010, 0x2900, 0x8046, 0x94c0, 0xeb3e, 0xeced, 0x96c0, 0x4013, 0x2b00, 0x8048 }, 16, 0x000afd60, 1},
+ {{0x94c0, 0xec3f, 0xeaed, 0x96c0, 0x4014, 0x2f00, 0x804a, 0x94c0, 0xea39, 0xeeed, 0x96c0, 0x4012, 0x2a00, 0x804c, 0x94c0, 0xee3b }, 16, 0x000afd80, 1},
+ {{0xeced, 0x96c0, 0x4016, 0x2800, 0x804e, 0x94c0, 0xec3f, 0xe9ed, 0x96c0, 0x4014, 0x2f00, 0x8050, 0x94c0, 0xe93a, 0xebed, 0x0011 }, 16, 0x000afda0, 1},
+ {{0xcabc, 0x94c0, 0xeb38, 0xeced, 0x0013, 0xcebe, 0x94c0, 0xec3f, 0xe9ed, 0x96c0, 0x4014, 0x2c00, 0x8040, 0x94c0, 0xe93a, 0xe8ed }, 16, 0x000afdc0, 1},
+ {{0x0011, 0xc9b6, 0x94c0, 0xebed, 0xe83e, 0x0010, 0xceb8, 0x94c0, 0xeaed, 0xeb3c, 0x0013, 0xccba, 0x94c0, 0xefed, 0xea39, 0x0012 }, 16, 0x000afde0, 1},
+ {{0xef3e, 0x0017, 0xed3c, 0x0015, 0x3104, 0x2078, 0x800b, 0x9ac0, 0xd910, 0x6c10, 0xfbc3, 0x2461, 0x9fff, 0x9ac0, 0x2561, 0x9fff }, 16, 0x000afe00, 1},
+ {{0x90c0, 0x2900, 0x804e, 0x2b0e, 0x8062, 0x1356, 0xecee, 0x9ac0, 0x6dbd, 0xec39, 0x38c0, 0x28d0, 0x8009, 0x96c0, 0xdb1b, 0xde03 }, 16, 0x000afe20, 1},
+ {{0x5254, 0x96c0, 0xdb16, 0x39ec, 0x9fff, 0x3f6f, 0x6e95, 0x0cf6, 0xbfff, 0xd2d3, 0x3bed, 0x9fff, 0x6fa1, 0x3fef, 0x9fff, 0x27ea }, 16, 0x000afe40, 1},
+ {{0xc79e, 0x8023, 0x70e7, 0x801f, 0x78c1, 0xc941, 0x90c0, 0xe9fc, 0xe918, 0x5351, 0x7dc3, 0x75db, 0x603d, 0x6c21, 0x31e8, 0x9fff }, 16, 0x000afe60, 1},
+ {{0x646a, 0x85e3, 0x9ec0, 0x6767, 0x7cc1, 0x6c10, 0x33c1, 0x2692, 0x8009, 0xc8be, 0x98c0, 0x2700, 0x8040, 0xda1e, 0xcd41, 0x9cc0 }, 16, 0x000afe80, 1},
+ {{0x6997, 0xd897, 0x39c0, 0x296e, 0x8009, 0xeaee, 0x98c0, 0xcf43, 0x30c2, 0x298e, 0x8009, 0x98c0, 0x31c2, 0x29ce, 0x8009, 0xea38 }, 16, 0x000afea0, 1},
+ {{0x98c0, 0xed1f, 0x33c2, 0x29ee, 0x8009, 0x1655, 0x32c2, 0x29ae, 0x8009, 0x3c20, 0xa000, 0x7656, 0x75d6, 0x5552, 0x2402, 0x804c }, 16, 0x000afec0, 1},
+ {{0x9ac0, 0x7e62, 0x2541, 0x8800, 0x7de2, 0xe8ee, 0x3c20, 0xa000, 0xda1c, 0xd99b, 0xe83c, 0x2602, 0x8040, 0x90c0, 0x3e00, 0xa100 }, 16, 0x000afee0, 1},
+ {{0x7e41, 0x2e0d, 0x8004, 0x7dc1, 0x2701, 0x81ff, 0x94c0, 0xc754, 0xcf43, 0x3aa0, 0xa000, 0x5655, 0x3dc0, 0x23d0, 0x8009, 0x3640 }, 16, 0x000aff00, 1},
+ {{0xa100, 0xe91f, 0xef18, 0x3620, 0xa100, 0x5f11, 0x5917, 0x90c0, 0x3660, 0xa000, 0xef1a, 0xccba, 0x3600, 0xa100, 0xe9fc, 0xeffc }, 16, 0x000aff20, 1},
+ {{0x3660, 0xa100, 0xe919, 0xef1b, 0x3600, 0xa100, 0x5451, 0x5357, 0x3ce0, 0xa800, 0x3b74, 0x9f00, 0x7dc3, 0x5117, 0xeaed, 0x3ee0 }, 16, 0x000aff40, 1},
+ {{0xa102, 0x39ec, 0x9fff, 0x75db, 0x64e9, 0xea3e, 0xe8ed, 0x3c20, 0xa000, 0x6c7c, 0x2f00, 0x8060, 0x7453, 0x5156, 0x38e0, 0xa000 }, 16, 0x000aff60, 1},
+ {{0x6464, 0xe9ed, 0xe83c, 0x96c0, 0xd053, 0x7275, 0xe93f, 0x2132, 0xd255, 0x3e66, 0x0452, 0x4250, 0x1050, 0x1450, 0xdf84, 0x3600 }, 16, 0x000aff80, 1},
+ {{0xa800, 0x6ec2, 0x6d47, 0x3600, 0xa100, 0xda9a, 0x4552, 0x7ec1, 0xca45, 0x90c0, 0xea1d, 0x5052, 0x6467, 0x31e8, 0x9fff, 0x7c42 }, 16, 0x000affa0, 1},
+ {{0x3c00, 0xa040, 0x6e44, 0x7458, 0x32e4, 0x3b10, 0x800a, 0x3600, 0xa100, 0x4054, 0x4450, 0x32e4, 0x3b70, 0x800a, 0x3620, 0xa000 }, 16, 0x000affc0, 1},
+ {{0xe9ea, 0xe8eb, 0x32e4, 0x3c00, 0x800a, 0x3620, 0xa000, 0xe9ea, 0xe8eb, 0x9ac0, 0x2be2, 0x9ffe, 0x6c90, 0x2b0f, 0x8022, 0x9ac0 }, 16, 0x000affe0, 1},
+ {{0x33e9, 0x9fff, 0x9342, 0x2b0c, 0x8012, 0x96c0, 0x527f, 0x2b08, 0x8020, 0x98c0, 0x6e5c, 0x537c, 0x2b03, 0x801e, 0x98c0, 0x608c }, 16, 0x000b0000, 1},
+ {{0x5278, 0x2b0d, 0x8010, 0x98c0, 0x6edc, 0x33e9, 0x9fff, 0x577d, 0x209b, 0x137f, 0x507c, 0x9ad0, 0x61e1, 0x33e9, 0x9fff, 0x5278 }, 16, 0x000b0020, 1},
+ {{0x577d, 0x2093, 0x6edc, 0x33e9, 0x9fff, 0x3820, 0xa000, 0x609b, 0xe9eb, 0xe8e8, 0x32e4, 0x3c70, 0x800a, 0x3480, 0xa000, 0x4155 }, 16, 0x000b0040, 1},
+ {{0x3a80, 0xa100, 0x76d0, 0xd81e, 0x5155, 0xed62, 0xdb95, 0x3600, 0xa100, 0x6ec7, 0x4755, 0x4556, 0x3880, 0xa800, 0x7754, 0xcc5f }, 16, 0x000b0060, 1},
+ {{0xcf43, 0x3680, 0xa000, 0xce40, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0xdb11, 0xcc56, 0x2501, 0x8001, 0x98c0, 0x6d1a, 0xda1d }, 16, 0x000b0080, 1},
+ {{0xcd57, 0xc788, 0x96c0, 0xc8b8, 0x0cf2, 0xbfff, 0x2618, 0x810a, 0x94c0, 0x9e20, 0x9f20, 0x96c0, 0x6c10, 0xfec5, 0xccba, 0x94c0 }, 16, 0x000b00a0, 1},
+ {{0xcaaa, 0xcbac, 0x3820, 0xa000, 0xc9ae, 0x2e0f, 0x8046, 0x96c0, 0x4717, 0x2f0e, 0x8022, 0x3640, 0xa000, 0x4016, 0xcaa0, 0xee46 }, 16, 0x000b00c0, 1},
+ {{0x3680, 0xa000, 0xecee, 0x4016, 0x3600, 0xa100, 0xedee, 0xec62, 0x3680, 0xa000, 0x4014, 0xefee, 0x94c0, 0xed64, 0xef38, 0x3600 }, 16, 0x000b00e0, 1},
+ {{0xa100, 0x4015, 0xedee, 0x0017, 0xe8ee, 0x3680, 0xa000, 0xed3c, 0xe83a, 0x3680, 0xa000, 0x4015, 0xefee, 0x0010, 0xef3b, 0x94c0 }, 16, 0x000b0100, 1},
+ {{0xc8b0, 0xecee, 0x0017, 0xcdb2, 0x3640, 0xa000, 0xeaee, 0xec39, 0x0014, 0xcbb4, 0x94c0, 0xea38, 0xefee, 0x0012, 0xef3d, 0x0017 }, 16, 0x000b0120, 1},
+ {{0xecee, 0x94c0, 0xec3b, 0xeaee, 0x0014, 0xebee, 0x94c0, 0xea7a, 0xeb7c, 0x0012, 0xecee, 0x0013, 0xc8a2, 0x3600, 0xa100, 0xec7e }, 16, 0x000b0140, 1},
+ {{0xebee, 0x0014, 0xcda4, 0x3640, 0xa100, 0xefee, 0xeb3a, 0x3600, 0xa100, 0xcca6, 0x4013, 0x94c0, 0xef38, 0xebee, 0x0017, 0xeb3d }, 16, 0x000b0160, 1},
+ {{0x0013, 0xeaee, 0x94c0, 0xea3c, 0xe8ee, 0x0012, 0xedee, 0x94c0, 0xe874, 0xebee, 0x0010, 0xed76, 0x0015, 0xeaee, 0x94c0, 0xeb78 }, 16, 0x000b0180, 1},
+ {{0xefee, 0x0013, 0xea6e, 0x0012, 0xef70, 0x0017, 0xee72, 0x0016, 0x3104, 0x2408, 0x800b, 0x98c0, 0xda90, 0x6c10, 0xfbc5, 0xcda4 }, 16, 0x000b01a0, 1},
+ {{0x9ac0, 0x2161, 0x9fff, 0x90c0, 0x2201, 0x91a0, 0x3c40, 0xa000, 0x2b0e, 0x806a, 0x90c0, 0x2161, 0x9fff, 0x1756, 0xecee, 0x3c20 }, 16, 0x000b01c0, 1},
+ {{0xa004, 0x6dbb, 0xec3d, 0x34c1, 0x29fe, 0x8009, 0x3a40, 0xb800, 0xdb9b, 0xdc83, 0x5354, 0xc286, 0x3e20, 0xa006, 0xda97, 0x33e9 }, 16, 0x000b01e0, 1},
+ {{0x9fff, 0x603d, 0xcda2, 0xe8ee, 0x3e40, 0xb20d, 0x7eef, 0x6364, 0x31e8, 0x9fff, 0xedee, 0xcab6, 0x3a20, 0xa001, 0x0cf5, 0xbfff }, 16, 0x000b0200, 1},
+ {{0x66e7, 0xed62, 0x3e00, 0xb80c, 0xd353, 0xdb9d, 0x30c2, 0x2a1a, 0x8009, 0x5655, 0x3e40, 0xb8cc, 0x6d82, 0x6a0b, 0x34c2, 0x2a12 }, 16, 0x000b0220, 1},
+ {{0x8009, 0x5656, 0x3ac0, 0xa804, 0x37eb, 0x9fff, 0xca44, 0xe83d, 0x3a00, 0xa004, 0x65e8, 0x35c2, 0x2a0a, 0x8009, 0x31c2, 0x2a22 }, 16, 0x000b0240, 1},
+ {{0x8009, 0x98c6, 0x2541, 0x9800, 0x90c0, 0xc482, 0x3c00, 0xa100, 0x2101, 0x81ff, 0x7e41, 0x2e0f, 0x8004, 0x3640, 0xa000, 0xc654 }, 16, 0x000b0260, 1},
+ {{0xe9ef, 0x3660, 0xa100, 0xe93a, 0x5757, 0x36c0, 0xa000, 0xee1a, 0xefef, 0x3a80, 0xa000, 0x5716, 0x3ac0, 0x23d0, 0x8009, 0x3640 }, 16, 0x000b0280, 1},
+ {{0xa100, 0xc657, 0xebef, 0x3680, 0xa000, 0xeb72, 0xef78, 0x3480, 0xa000, 0xeefc, 0x36e0, 0xa100, 0xe81e, 0xec1e, 0x36e0, 0xa100 }, 16, 0x000b02a0, 1},
+ {{0x5810, 0xee1d, 0x36c0, 0xa100, 0x5414, 0x5c16, 0x3600, 0xa100, 0x6669, 0xe8fc, 0x36a0, 0xa100, 0xe819, 0xecfc, 0x3a00, 0xa100 }, 16, 0x000b02c0, 1},
+ {{0x31c2, 0x2a28, 0x8009, 0x5250, 0x7d43, 0x3640, 0xa100, 0x755a, 0xec19, 0x3480, 0xa000, 0x5454, 0x96c0, 0x3d74, 0x9f00, 0x7752 }, 16, 0x000b02e0, 1},
+ {{0x96c0, 0x39ec, 0x9fff, 0x6764, 0x2c7c, 0xd352, 0x3275, 0x612e, 0x0250, 0xd255, 0x3e66, 0x0455, 0x5250, 0x3800, 0xb000, 0xdc84 }, 16, 0x000b0300, 1},
+ {{0x6ecb, 0x5050, 0x0557, 0xdb19, 0x7f41, 0xc256, 0x90c0, 0x3480, 0xa000, 0xea1a, 0x3480, 0xa000, 0x5152, 0x64e7, 0x33e9, 0x9fff }, 16, 0x000b0320, 1},
+ {{0x7cc2, 0x3c00, 0xa800, 0x6f42, 0x74d9, 0x32e4, 0x3b10, 0x800a, 0x3680, 0xa000, 0x4653, 0x4154, 0x3640, 0xa100, 0xccbc, 0xe9ef }, 16, 0x000b0340, 1},
+ {{0xe9ef, 0x3a80, 0xa000, 0xe93c, 0x32e4, 0x3b70, 0x800a, 0x3420, 0xa000, 0xe8e9, 0x32e4, 0x3c00, 0x800a, 0x3640, 0xa000, 0xe9ef }, 16, 0x000b0360, 1},
+ {{0xe8e9, 0x9ac0, 0x2be2, 0x9ffe, 0x6d10, 0x2b09, 0x8054, 0x9ac0, 0x35ea, 0x9fff, 0x9342, 0x2b0c, 0x8044, 0x96c0, 0x5679, 0x2b0f }, 16, 0x000b0380, 1},
+ {{0x8052, 0x98c0, 0x6dde, 0x557c, 0x2b03, 0x801e, 0x98c0, 0x610d, 0x567f, 0x2b08, 0x8042, 0x98c0, 0x6e5e, 0x35ea, 0x9fff, 0x5678 }, 16, 0x000b03a0, 1},
+ {{0x2116, 0x1179, 0x557c, 0x9ad0, 0x6260, 0x35ea, 0x9fff, 0x537f, 0x5678, 0x2115, 0x6261, 0x35ea, 0x9fff, 0x3860, 0xa000, 0x6116 }, 16, 0x000b03c0, 1},
+ {{0xe9e9, 0xe8eb, 0x32e4, 0x3c70, 0x800a, 0x3480, 0xa000, 0x4257, 0x3a80, 0xa100, 0x75d0, 0x7457, 0x5157, 0xef62, 0xd913, 0x3600 }, 16, 0x000b03e0, 1},
+ {{0xa100, 0x6fd8, 0x4257, 0x4756, 0x94c0, 0x9e21, 0x9f21, 0x9f70, 0x94c0, 0xcd5f, 0xcc5e, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b0400, 1},
+ {{0x98c0, 0x7650, 0x6c10, 0xe748, 0xcc56, 0x9ac0, 0x02fc, 0x9fee, 0x90c0, 0x2601, 0x8001, 0x3880, 0xa000, 0x6eaa, 0xcd57, 0xcf4b }, 16, 0x000b0420, 1},
+ {{0x3880, 0xa000, 0xce49, 0x0cf5, 0xbfff, 0x96c0, 0xf9c6, 0x2718, 0x817e, 0x96c0, 0xc7a0, 0x2102, 0x8054, 0x90c0, 0x96c0, 0xe954 }, 16, 0x000b0440, 1},
+ {{0x2c00, 0x8062, 0x96c0, 0x4711, 0x2f00, 0x8064, 0x96c0, 0xe950, 0x2002, 0x8048, 0x96c0, 0x4011, 0x290d, 0x8042, 0x0015, 0xe9ed }, 16, 0x000b0460, 1},
+ {{0x94c0, 0xeeed, 0xe962, 0x0011, 0xe8ed, 0x94c0, 0xee64, 0xe83c, 0x0016, 0xebed, 0x96c0, 0x4010, 0x2202, 0x8056, 0x3680, 0xa000 }, 16, 0x000b0480, 1},
+ {{0xebed, 0xeb3f, 0x3640, 0xa100, 0x4013, 0xeb39, 0x3600, 0xa100, 0xe8ed, 0x4013, 0x3820, 0xa000, 0xe83a, 0x2c00, 0x805a, 0x3640 }, 16, 0x000b04a0, 1},
+ {{0xa000, 0x4010, 0xcbb8, 0x96c0, 0xe8ed, 0x2b00, 0x805e, 0x3680, 0xa000, 0xeced, 0xe83c, 0x38a0, 0xa000, 0xec3b, 0x2e00, 0x805c }, 16, 0x000b04c0, 1},
+ {{0x96c0, 0xeced, 0x2f00, 0x8046, 0x3680, 0xa000, 0xebed, 0xec3b, 0x9ac0, 0x2602, 0x804c, 0x90c0, 0x2900, 0x8044, 0x3680, 0xa000 }, 16, 0x000b04e0, 1},
+ {{0xeb3e, 0xebed, 0x9ac0, 0x2702, 0x804e, 0x90c0, 0x2102, 0x804a, 0x94c0, 0xeb3f, 0xeeed, 0x94c0, 0xefed, 0xee39, 0x3620, 0xa000 }, 16, 0x000b0500, 1},
+ {{0xef39, 0xe9ed, 0x3660, 0xa000, 0xcab6, 0xe938, 0x3680, 0xa000, 0xe9ed, 0x4010, 0x38a0, 0xa000, 0xe93f, 0x2a00, 0x8058, 0x3600 }, 16, 0x000b0520, 1},
+ {{0xa100, 0xe8ed, 0xe8ed, 0x3880, 0xa000, 0xeded, 0x2702, 0x8050, 0x36c0, 0xa000, 0x4014, 0xccbe, 0x36e0, 0xa000, 0xe83e, 0xe83a }, 16, 0x000b0540, 1},
+ {{0x3680, 0xa100, 0xed3a, 0xeeed, 0x3680, 0xa000, 0xeaed, 0xcaba, 0x36e0, 0xa100, 0xea3c, 0xee3f, 0x3880, 0xa000, 0x4015, 0x2502 }, 16, 0x000b0560, 1},
+ {{0x8040, 0x36c0, 0xa000, 0x4013, 0xcbbc, 0x3680, 0xa100, 0xefed, 0xeced, 0x36e0, 0xa100, 0xef3b, 0xec3d, 0x0014, 0xed3a, 0x0016 }, 16, 0x000b0580, 1},
+ {{0x4013, 0x0011, 0x4017, 0x3680, 0xa100, 0x4010, 0x4011, 0x3680, 0xa100, 0x4016, 0x4017, 0x3680, 0xa100, 0x4012, 0x4014, 0x3004 }, 16, 0x000b05a0, 1},
+ {{0x292a, 0x800b, 0x0010, 0x4015, 0x3c20, 0xa000, 0x38cf, 0x9382, 0x6d90, 0xcd41, 0xcd83, 0x9ac0, 0x7fc1, 0xfbc6, 0x3ec0, 0x292e }, 16, 0x000b05c0, 1},
+ {{0x8009, 0x3a20, 0xa000, 0xed8d, 0x3cc0, 0x290e, 0x8009, 0x96c0, 0xedfe, 0x2b0a, 0x8014, 0x96c0, 0x5152, 0x2518, 0x8108, 0x2f90 }, 16, 0x000b05e0, 1},
+ {{0x3544, 0x2e90, 0x35c2, 0x23c0, 0x8009, 0x3d41, 0x3ec0, 0x2712, 0x8009, 0x3a20, 0xa000, 0xed1d, 0x3cc0, 0x2792, 0x8009, 0x1d95 }, 16, 0x000b0600, 1},
+ {{0x35c2, 0x2892, 0x8009, 0x38ce, 0x9382, 0x94c0, 0x7f41, 0x9d61, 0xcd44, 0x90c0, 0xedfc, 0xee1d, 0xed1c, 0x1c16, 0x5215, 0x6569 }, 16, 0x000b0620, 1},
+ {{0xecfc, 0x3420, 0xa000, 0xec1d, 0x5554, 0x7ec3, 0x76dd, 0x98c0, 0x6f1b, 0x6f90, 0x2618, 0x80ea, 0x2d5b, 0x06fe, 0x9ff8, 0x3004 }, 16, 0x000b0640, 1},
+ {{0x2738, 0x800b, 0x02fe, 0x9ff8, 0x9cc0, 0x6f90, 0x6d90, 0xcd42, 0x3ec0, 0x2852, 0x8009, 0x3cc0, 0x2812, 0x8009, 0x98c0, 0x35c2 }, 16, 0x000b0660, 1},
+ {{0x294e, 0x8009, 0xee1d, 0x90c0, 0xed1c, 0x1c16, 0x5215, 0x6569, 0xecfc, 0x3420, 0xa000, 0xec1d, 0x5554, 0x7ec3, 0x76dd, 0x96c0 }, 16, 0x000b0680, 1},
+ {{0x6f9b, 0x6c4d, 0x849a, 0x07fe, 0x9ff8, 0x3004, 0x2738, 0x800b, 0x00fe, 0x9ff8, 0x98c0, 0xcd46, 0x3ec0, 0x292e, 0x8009, 0x3cc0 }, 16, 0x000b06a0, 1},
+ {{0x290e, 0x8009, 0x98c0, 0x35c2, 0x29de, 0x8009, 0xee1d, 0x90c0, 0xed1c, 0x1c16, 0x5215, 0x6569, 0xecfc, 0x3420, 0xa000, 0xec1d }, 16, 0x000b06c0, 1},
+ {{0x5054, 0x7c43, 0x7458, 0x96c0, 0x6d81, 0x6e90, 0x8452, 0x2c41, 0x03fe, 0x9ff8, 0x3004, 0x2738, 0x800b, 0x00fe, 0x9ff8, 0x98c0 }, 16, 0x000b06e0, 1},
+ {{0xcd47, 0x35c2, 0x29de, 0x8009, 0x90c0, 0xee1d, 0xed1c, 0x1c16, 0x5215, 0x6569, 0xecfc, 0x3420, 0xa000, 0xec1d, 0x5554, 0x7ec3 }, 16, 0x000b0700, 1},
+ {{0x76dd, 0x6d2d, 0x98c6, 0x02fe, 0x9ff8, 0x90c0, 0x6d10, 0x92c2, 0x6fc9, 0x94c2, 0x07fe, 0x9ff8, 0x3e40, 0xa000, 0x7e62, 0x6c10 }, 16, 0x000b0720, 1},
+ {{0x3dc0, 0x296e, 0x8009, 0xc9ba, 0x3e41, 0x3ec0, 0x29ae, 0x8009, 0x98c0, 0xcc44, 0x39c0, 0x298e, 0x8009, 0x3c80, 0xa000, 0x2a0d }, 16, 0x000b0740, 1},
+ {{0x804e, 0x90c0, 0x05fc, 0x9ff8, 0x3800, 0xa100, 0x6225, 0x5255, 0xed1c, 0x3800, 0xa004, 0x6f48, 0xee1c, 0x5d15, 0x96c0, 0xec19 }, 16, 0x000b0760, 1},
+ {{0x2621, 0x9fff, 0x3c00, 0xa800, 0x6d3e, 0x5914, 0x30c2, 0x29ce, 0x8009, 0x98c0, 0x36c2, 0x29ee, 0x8009, 0xedfc, 0x3c20, 0xa000 }, 16, 0x000b0780, 1},
+ {{0x35ea, 0x9fff, 0xe8ed, 0x2f00, 0x804c, 0x3840, 0xa000, 0x656a, 0xed1e, 0xe9fc, 0x3800, 0xa004, 0xd356, 0xe83f, 0x5255, 0x3a40 }, 16, 0x000b07a0, 1},
+ {{0xa000, 0x7d43, 0xe918, 0x27c1, 0x8000, 0x3c00, 0xa402, 0x755a, 0x280c, 0x800e, 0x6c3f, 0x5451, 0x3a00, 0xa804, 0x31e8, 0x9fff }, 16, 0x000b07c0, 1},
+ {{0x5354, 0x5516, 0x3e20, 0xa004, 0x6468, 0x3774, 0x9f00, 0x75d2, 0x2441, 0x8800, 0x3e00, 0xa108, 0x65e4, 0xd35f, 0x66e9, 0x39ec }, 16, 0x000b07e0, 1},
+ {{0x9fff, 0x5655, 0x9cc0, 0x6c7c, 0x2001, 0x81ff, 0xd1d2, 0x2201, 0x8040, 0x3c00, 0xa800, 0x7274, 0x60b9, 0x3fc0, 0x23d0, 0x8009 }, 16, 0x000b0800, 1},
+ {{0x3a20, 0xa800, 0xd254, 0x4150, 0x2d0d, 0x8004, 0x98c0, 0x7e66, 0x4454, 0x2602, 0x8060, 0x98c0, 0x2702, 0x8040, 0xdc04, 0x5755 }, 16, 0x000b0820, 1},
+ {{0x3880, 0xa000, 0x6d52, 0x5350, 0xe8ed, 0x98c0, 0xd81a, 0x6dcf, 0xeeed, 0x5250, 0x3820, 0xa000, 0x7c41, 0xe9ed, 0xee3f, 0x3640 }, 16, 0x000b0840, 1},
+ {{0xa100, 0xcc40, 0xe839, 0x3620, 0xa000, 0xe93e, 0x4356, 0xec1f, 0x5154, 0x64e7, 0x33e9, 0x9fff, 0x7cc2, 0x2fca, 0x34d9, 0x32e4 }, 16, 0x000b0860, 1},
+ {{0x3b10, 0x800a, 0x3600, 0xa100, 0x4152, 0x4750, 0x32e4, 0x3b70, 0x800a, 0x94c0, 0xe9ee, 0xe8eb, 0x98c0, 0xcd4e, 0x32e4, 0x3c00 }, 16, 0x000b0880, 1},
+ {{0x800a, 0x94c0, 0xe9ee, 0xe8eb, 0x9ac0, 0x2be2, 0x9ffe, 0x6f90, 0x2b0f, 0x8022, 0x9ac0, 0x3fef, 0x9fff, 0x9342, 0x2b0c, 0x8012 }, 16, 0x000b08a0, 1},
+ {{0x137f, 0x547c, 0x9ac0, 0x2b09, 0x8020, 0x6061, 0x2b03, 0x8022, 0x98c0, 0x2b0a, 0x8010, 0x6380, 0x5379, 0x9ac0, 0x6261, 0x3fef }, 16, 0x000b08c0, 1},
+ {{0x9fff, 0xcd46, 0x567a, 0x2396, 0x127f, 0x537c, 0x9ad0, 0x6edc, 0x3fef, 0x9fff, 0x5079, 0x567a, 0x238d, 0x6e50, 0x3fef, 0x9fff }, 16, 0x000b08e0, 1},
+ {{0x3820, 0xa000, 0x6396, 0xe9eb, 0xe8e8, 0x32e4, 0x3c70, 0x800a, 0x4755, 0x3a00, 0xb000, 0x76d0, 0xd81e, 0x5655, 0xed62, 0xda95 }, 16, 0x000b0900, 1},
+ {{0x2dda, 0x4555, 0x3480, 0xa000, 0x4355, 0x94c0, 0xe768, 0xcd5f, 0x3600, 0xa100, 0xcc5e, 0xcf43, 0x3680, 0xa000, 0xce41, 0x9f71 }, 16, 0x000b0920, 1},
+ {{0x3e00, 0xa005, 0x2201, 0x8001, 0x7757, 0xdb91, 0x7656, 0xc150, 0x3a80, 0xa100, 0x6f0b, 0x6c10, 0xce49, 0xcf4b, 0x96c0, 0xffc3 }, 16, 0x000b0940, 1},
+ {{0x0cf6, 0xbfff, 0x96c0, 0xc488, 0x2718, 0x813e, 0x3660, 0xa000, 0xcfb8, 0xceba, 0x3660, 0xa000, 0xcaa2, 0xc8a6, 0x96c0, 0xccaa }, 16, 0x000b0960, 1},
+ {{0x2f0e, 0x8046, 0x96c0, 0x4416, 0x2e0b, 0x8022, 0x0013, 0xcfae, 0x94c0, 0xeb46, 0xceb2, 0x94c0, 0xeaeb, 0xe8eb, 0x3640, 0xa000 }, 16, 0x000b0980, 1},
+ {{0xea64, 0xe83f, 0x0012, 0x4010, 0x94c0, 0xeaeb, 0xe8eb, 0x3640, 0xa000, 0xea3c, 0xe83e, 0x3640, 0xa000, 0x4012, 0xccac, 0x94c0 }, 16, 0x000b09a0, 1},
+ {{0xeaeb, 0xc9b0, 0x0010, 0xea3f, 0x94c0, 0xefeb, 0xcdb4, 0x94c0, 0xe8eb, 0xeceb, 0x94c0, 0xef3e, 0xe839, 0x3620, 0xa000, 0xec3c }, 16, 0x000b09c0, 1},
+ {{0xeeeb, 0x3620, 0xa100, 0xcba4, 0xedeb, 0x0014, 0xee3d, 0x3600, 0xa100, 0x4010, 0xed62, 0x94c0, 0xeceb, 0xe8eb, 0x3640, 0xa000 }, 16, 0x000b09e0, 1},
+ {{0xedeb, 0xc9a0, 0x3660, 0xa000, 0xec38, 0xe83a, 0x3620, 0xa000, 0xed3b, 0x4012, 0x3680, 0xa100, 0x4015, 0xeeeb, 0x3680, 0xa100 }, 16, 0x000b0a00, 1},
+ {{0xefeb, 0xedeb, 0x3680, 0xa100, 0xeaeb, 0xeceb, 0x3600, 0xa100, 0xeaeb, 0xebeb, 0x3600, 0xa100, 0xe9eb, 0xe8eb, 0x3600, 0xa100 }, 16, 0x000b0a20, 1},
+ {{0x4013, 0xed6e, 0x3680, 0xa100, 0xee78, 0xec76, 0x3680, 0xa000, 0xef70, 0xe974, 0x3600, 0xa100, 0xea7a, 0xeb7c, 0x36c0, 0xa100 }, 16, 0x000b0a40, 1},
+ {{0xe87e, 0xea39, 0x0017, 0xeb72, 0x3600, 0xa100, 0x4012, 0x4013, 0x3600, 0xa100, 0x4016, 0x4010, 0x3680, 0xa000, 0x4012, 0x4010 }, 16, 0x000b0a60, 1},
+ {{0x0015, 0x4014, 0x3600, 0xa100, 0x4011, 0x4014, 0x3680, 0xa100, 0x4016, 0x4015, 0x3004, 0x2c82, 0x800b, 0x3680, 0xa000, 0x4017 }, 16, 0x000b0a80, 1},
+ {{0x4013, 0x3c80, 0xa000, 0x6c10, 0x3dc0, 0x2a1a, 0x8009, 0xe9fc, 0x98c0, 0x3ec0, 0x2a12, 0x8009, 0xfbc3, 0x3a40, 0xa000, 0x3cc0 }, 16, 0x000b0aa0, 1},
+ {{0x2a0a, 0x8009, 0xed19, 0x3660, 0xa000, 0xee19, 0x5c15, 0x3a80, 0xa000, 0xe91c, 0x32c2, 0x2a22, 0x8009, 0x3a80, 0xa000, 0x5d11 }, 16, 0x000b0ac0, 1},
+ {{0x31c2, 0x2a28, 0x8009, 0x3880, 0xa000, 0xecfc, 0x2b0a, 0x8046, 0x96c0, 0xedfc, 0x2a08, 0x8002, 0x38a0, 0xa000, 0xec1a, 0x2809 }, 16, 0x000b0ae0, 1},
+ {{0x8020, 0x36c0, 0xa000, 0x5154, 0xed19, 0x3cc3, 0x1455, 0x5351, 0x9cc0, 0x74d9, 0x3774, 0x9f00, 0x5616, 0x2341, 0x9800, 0x9ec0 }, 16, 0x000b0b00, 1},
+ {{0x39ec, 0x9fff, 0x6769, 0x2201, 0x81ff, 0x7751, 0x5752, 0x9cc0, 0x6764, 0x6c7c, 0x3cc0, 0x23d0, 0x8009, 0xceb6, 0x3c80, 0xa000 }, 16, 0x000b0b20, 1},
+ {{0xd351, 0x290f, 0x8006, 0x7273, 0xc948, 0x3a80, 0xa000, 0xd253, 0x62bf, 0xe8ef, 0x5057, 0x3e66, 0x0451, 0x4550, 0x3880, 0xa000 }, 16, 0x000b0b40, 1},
+ {{0xdd04, 0x5150, 0xe864, 0x3a80, 0xa100, 0xdb1a, 0x6ed1, 0xefef, 0x5450, 0x96c0, 0x7f41, 0xedef, 0xe9ef, 0x1650, 0xc656, 0x3680 }, 16, 0x000b0b60, 1},
+ {{0xa000, 0xef72, 0xed78, 0x3680, 0xa000, 0xee1c, 0x4555, 0x3680, 0xa000, 0x5256, 0xe93e, 0x6567, 0x35ea, 0x9fff, 0x7d42, 0x2f56 }, 16, 0x000b0b80, 1},
+ {{0x355a, 0x32e4, 0x3b10, 0x800a, 0x3600, 0xa100, 0x4252, 0x4657, 0x3600, 0xa100, 0xcabc, 0xedef, 0xe9ed, 0x3a80, 0xa000, 0xed3a }, 16, 0x000b0ba0, 1},
+ {{0x32e4, 0x3b70, 0x800a, 0x3420, 0xa000, 0xe8ed, 0x32e4, 0x3c00, 0x800a, 0x3640, 0xa000, 0xe9ed, 0xe8ed, 0x9ac0, 0x2be2, 0x9ffe }, 16, 0x000b0bc0, 1},
+ {{0x6c90, 0x2b0a, 0x8054, 0x9ac0, 0x33e9, 0x9fff, 0x9342, 0x2b0e, 0x8044, 0x96c0, 0x537a, 0x2b0c, 0x8052, 0x98c0, 0x62e1, 0x537e }, 16, 0x000b0be0, 1},
+ {{0x2b03, 0x801e, 0x98c0, 0x2b09, 0x8042, 0x608d, 0x527c, 0x98c0, 0x6f5c, 0x33e9, 0x9fff, 0x5479, 0x2096, 0x147a, 0x577e, 0x9ad0 }, 16, 0x000b0c00, 1},
+ {{0x33e9, 0x9fff, 0x6ed4, 0x567c, 0x5479, 0x209b, 0x6f5e, 0x33e9, 0x9fff, 0x3860, 0xa000, 0x6096, 0xe9ed, 0xe8ef, 0x32e4, 0x3c70 }, 16, 0x000b0c20, 1},
+ {{0x800a, 0x4157, 0x3a00, 0xa100, 0xdb90, 0x5657, 0x2121, 0x9fff, 0x98c0, 0x6d86, 0x5057, 0x24c1, 0x8000, 0x3a00, 0xa100, 0x37eb }, 16, 0x000b0c40, 1},
+ {{0x9fff, 0x6d43, 0xc940, 0x3600, 0xa100, 0x65ea, 0x4250, 0x94c0, 0xd351, 0xe944, 0x2c16, 0x4751, 0x31e8, 0x9fff, 0x6468, 0xd35c }, 16, 0x000b0c60, 1},
+ {{0xd81e, 0x3a80, 0xb900, 0x77d6, 0x7754, 0xcf43, 0xce41, 0x9f71, 0x98c0, 0x75d1, 0x74d0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20 }, 16, 0x000b0c80, 1},
+ {{0x94c0, 0xe750, 0xc086, 0x98c0, 0xffcd, 0x3ec0, 0x2392, 0x8009, 0x90c0, 0x2f09, 0x8072, 0x0311, 0xece9, 0x94c0, 0xec62, 0xc94e }, 16, 0x000b0ca0, 1},
+ {{0x3204, 0x3090, 0x800b, 0x4114, 0x3750, 0x101e, 0xc946, 0x90c0, 0x96c0, 0x5111, 0x290c, 0x8002, 0x3204, 0x3090, 0x800b, 0xfc43 }, 16, 0x000b0cc0, 1},
+ {{0x96c0, 0x7650, 0xc28b, 0xfcc3, 0xf244, 0x3456, 0x111c, 0x5e56, 0x3204, 0x30a0, 0x800b, 0x98c0, 0x74d6, 0x7754, 0xf101, 0xfc43 }, 16, 0x000b0ce0, 1},
+ {{0x9ac0, 0x7656, 0x7750, 0x74d7, 0xfcc3, 0xee44, 0x7454, 0x121c, 0x3204, 0x30a0, 0x800b, 0x94c0, 0xf201, 0xfc43, 0x96c0, 0x7650 }, 16, 0x000b0d00, 1},
+ {{0xf1c4, 0xfcc3, 0x78e1, 0x24ea, 0xf144, 0x81c1, 0x94c0, 0x7454, 0x9756, 0x9ac0, 0x2f0e, 0x809e, 0x90c0, 0x2f0c, 0x809a, 0x92d0 }, 16, 0x000b0d20, 1},
+ {{0x5f0c, 0x4f0e, 0x9cc0, 0x6ec2, 0x2321, 0x9fff, 0x6f02, 0x21c1, 0x8000, 0x98c0, 0x6062, 0x6d5e, 0xfacb, 0xf9cc, 0x3c70, 0x3d70 }, 16, 0x000b0d40, 1},
+ {{0xe770, 0x9cc0, 0xdb90, 0xda10, 0xdb12, 0xd912, 0x9e21, 0x9f21, 0x2e8f, 0x6f0e, 0x9ac0, 0x3bed, 0x9fff, 0x90c0, 0x3dee, 0x9fff }, 16, 0x000b0d60, 1},
+ {{0x66ea, 0xd253, 0x6661, 0x6e84, 0x3bed, 0x9fff, 0x66e8, 0x276a, 0xd259, 0x0452, 0xd153, 0x6561, 0x6f18, 0x3dee, 0x9fff, 0x96c0 }, 16, 0x000b0d80, 1},
+ {{0x6768, 0x9621, 0x9721, 0x94c0, 0xd159, 0x9f70, 0x4251, 0x90c0, 0x98c0, 0xd910, 0xdb91, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20 }, 16, 0x000b0da0, 1},
+ {{0x94c0, 0xe750, 0xc086, 0x98c0, 0xfecd, 0x3fc0, 0x2392, 0x8009, 0x90c0, 0x98c0, 0x6d4b, 0x6fab, 0x2e0d, 0x80a2, 0x96c0, 0xd89f }, 16, 0x000b0dc0, 1},
+ {{0xe9ed, 0x4255, 0x94c0, 0xe962, 0xcd4e, 0x3204, 0x3090, 0x800b, 0x4751, 0x3750, 0x101f, 0xcd46, 0x90c0, 0x96c0, 0x5115, 0x2d0a }, 16, 0x000b0de0, 1},
+ {{0x8002, 0x3204, 0x3090, 0x800b, 0xfa43, 0x96c0, 0x76d0, 0xc28b, 0xfac3, 0xf244, 0x3456, 0x131a, 0x5e57, 0x3204, 0x30a0, 0x800b }, 16, 0x000b0e00, 1},
+ {{0x98c0, 0x74d6, 0x7755, 0xf301, 0xfa43, 0x9ac0, 0x76d6, 0x7750, 0x74d7, 0xfac3, 0xef44, 0x7455, 0x141a, 0x3204, 0x30a0, 0x800b }, 16, 0x000b0e20, 1},
+ {{0x94c0, 0xf401, 0xfa43, 0x96c0, 0x76d0, 0xf3c4, 0xfac3, 0x79e1, 0x25ea, 0xf344, 0x81c1, 0x94c0, 0x7455, 0x9756, 0x9ac0, 0x2e0b }, 16, 0x000b0e40, 1},
+ {{0x80ce, 0x90c0, 0x2e0f, 0x80ca, 0x92d0, 0x5e0f, 0x4e0b, 0x98c0, 0x7f44, 0x7c44, 0xfacb, 0xf9cc, 0x2765, 0x2465, 0xe770, 0x94c0 }, 16, 0x000b0e60, 1},
+ {{0x9e21, 0x9f21, 0x4652, 0x94c0, 0x9621, 0x9721, 0x9f70, 0x4051, 0x94c0, 0x6c10, 0x974c, 0x96c0, 0x9620, 0x2b02, 0x8002, 0x96c0 }, 16, 0x000b0e80, 1},
+ {{0xe748, 0x280b, 0x8070, 0x2809, 0x8072, 0x94c8, 0x403b, 0x4039, 0x98c0, 0xc84e, 0x32e4, 0x3ca0, 0x800a, 0x94c0, 0xf841, 0xc181 }, 16, 0x000b0ea0, 1},
+ {{0x96c0, 0x6c10, 0xc846, 0xc181, 0x3204, 0x2090, 0x800b, 0xf841, 0xe768, 0x9621, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b0ec0, 1},
+ {{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0xe758, 0x94c0, 0xf0cd, 0xf7ce, 0x7440, 0x246a, 0x7750, 0x8473, 0x92c0, 0xf045 }, 16, 0x000b0ee0, 1},
+ {{0x96c0, 0x5118, 0x27ed, 0x9ff2, 0x96c0, 0x5018, 0x27eb, 0x9ff0, 0x94c0, 0xf743, 0xfd42, 0x98c0, 0xefe8, 0x3204, 0x2c90, 0x800b }, 16, 0x000b0f00, 1},
+ {{0x94c0, 0xfb41, 0xeee9, 0x32e4, 0x3ca0, 0x800a, 0x96c0, 0x6c90, 0xf741, 0xf088, 0x98c0, 0x76d0, 0x6c90, 0xf741, 0xf087, 0x3204 }, 16, 0x000b0f20, 1},
+ {{0x2090, 0x800b, 0xf546, 0x9ac0, 0xd910, 0x7b61, 0xf5c6, 0x2401, 0x80ff, 0x9ac0, 0x7d46, 0xda95, 0x676a, 0xe9ee, 0xe8ef, 0x755a }, 16, 0x000b0f40, 1},
+ {{0x6dc9, 0x94c0, 0xde03, 0x819e, 0x4459, 0xf0c5, 0xe778, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0 }, 16, 0x000b0f60, 1},
+ {{0x94c0, 0x6d10, 0x974c, 0x96c0, 0x9620, 0x2b02, 0x8002, 0x96c0, 0xe748, 0x280c, 0x80a0, 0x280b, 0x80a2, 0x94c8, 0x423c, 0x423b }, 16, 0x000b0f80, 1},
+ {{0x96c0, 0x6c90, 0xc581, 0xf842, 0x3204, 0x2420, 0x800b, 0x96c0, 0x6c10, 0xf501, 0xc84e, 0x96c0, 0x6c10, 0xc846, 0xc181, 0x3204 }, 16, 0x000b0fa0, 1},
+ {{0x2940, 0x800b, 0xf841, 0xe768, 0x9621, 0x9f71, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x270c, 0x8020 }, 16, 0x000b0fc0, 1},
+ {{0xe7ec, 0x94c0, 0xf19e, 0xf6d0, 0x24ea, 0x77d1, 0x8483, 0xf145, 0x1018, 0xc186, 0x98c0, 0x311d, 0x803f, 0xefe8, 0xeee9, 0x32e4 }, 16, 0x000b0fe0, 1},
+ {{0x3ac0, 0x800a, 0xf546, 0x98c0, 0x6e10, 0x7550, 0xf5c6, 0xf642, 0x9ac0, 0x351c, 0x8003, 0x7455, 0xf401, 0xf19d, 0x3204, 0x2420 }, 16, 0x000b1000, 1},
+ {{0x800b, 0xf447, 0xf4c7, 0x3650, 0x2c90, 0x3454, 0xf641, 0x3204, 0x2940, 0x800b, 0xf448, 0x98c0, 0x74d0, 0xf4c8, 0x27ea, 0x9ff2 }, 16, 0x000b1020, 1},
+ {{0x98c0, 0x27ed, 0x9ff0, 0x7454, 0xf643, 0x3204, 0x2db0, 0x800b, 0x94c0, 0xfa42, 0xfd41, 0x96c0, 0x7be1, 0xe9ee, 0xf588, 0x27ea }, 16, 0x000b1040, 1},
+ {{0x0519, 0xe8ef, 0x94c0, 0xf387, 0x818c, 0x4319, 0xf1c5, 0x96c0, 0xda11, 0x27eb, 0x9fe0, 0x2d54, 0xe7eb, 0x96c0, 0xd81a, 0x9e21 }, 16, 0x000b1060, 1},
+ {{0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x6831, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b1080, 1},
+ {{0xf385, 0x94c0, 0x69b9, 0x9f70, 0x6c53, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b10a0, 1},
+ {{0x3e00, 0xa008, 0x7656, 0x7457, 0x3ac8, 0x3c18, 0xbfff, 0xe8ee, 0x94c0, 0xce40, 0xe9ef, 0x1192, 0xce48, 0x9ac0, 0x331b, 0x8003 }, 16, 0x000b10c0, 1},
+ {{0x6460, 0x2100, 0x9770, 0x65e9, 0x844f, 0x33e4, 0x3c4e, 0x8001, 0x96c0, 0xc5fe, 0x2300, 0x9770, 0x96c0, 0xde80, 0x2100, 0x87d0 }, 16, 0x000b10e0, 1},
+ {{0x9ac0, 0x36a7, 0x8003, 0x90c0, 0x34a3, 0x8003, 0xdb13, 0xd747, 0xcc46, 0x90c0, 0xee3c, 0xce48, 0x7c48, 0x6461, 0x2468, 0x32e4 }, 16, 0x000b1100, 1},
+ {{0x3c48, 0x8001, 0x9ac1, 0x3c10, 0x83e8, 0x90c0, 0x3100, 0x83e8, 0x3104, 0x314a, 0x800b, 0x96c0, 0xce48, 0x2100, 0x9800, 0x32e4 }, 16, 0x000b1120, 1},
+ {{0x3c4e, 0x8001, 0x6460, 0x36d0, 0x6c10, 0x96c0, 0x7ed8, 0x3118, 0x87ff, 0x3b2b, 0x9f00, 0xc56e, 0x9f7d, 0x3de8, 0x3c00, 0xbfff }, 16, 0x000b1140, 1},
+ {{0x32f9, 0x3800, 0x80ff, 0x1595, 0x3ce8, 0x3c00, 0xbfff, 0xdd05, 0xdd9a, 0xdd98, 0x4394, 0xc566, 0x90c0, 0x90c0, 0x9f70, 0x3a00 }, 16, 0x000b1160, 1},
+ {{0xa800, 0x77d0, 0x7754, 0xefe9, 0xeee8, 0x90c0, 0x90c0, 0x90c0, 0x9ac0, 0xd422, 0x7750, 0x77d1, 0x9620, 0x9720, 0x94c0, 0x9e20 }, 16, 0x000b1180, 1},
+ {{0x80be, 0x92c2, 0xc0ff, 0x32e4, 0x394e, 0x8001, 0x7456, 0x34d7, 0x2760, 0x3dc0, 0x2a30, 0x8009, 0x24e0, 0xc946, 0x64e9, 0x94c0 }, 16, 0x000b11a0, 1},
+ {{0xe9fe, 0x809c, 0x92c2, 0xc0ff, 0x9ac0, 0x6f90, 0xe91d, 0x3601, 0x2000, 0x8008, 0x30fe, 0x1d91, 0x34e1, 0x3fff, 0x80ff, 0x98c0 }, 16, 0x000b11c0, 1},
+ {{0x3ce8, 0x3c1c, 0xbfff, 0xc941, 0x94c6, 0x9d61, 0xc0ff, 0x98c0, 0x147c, 0x9fe7, 0x7cc5, 0x806d, 0x9ac0, 0xd221, 0x78e1, 0x38e8 }, 16, 0x000b11e0, 1},
+ {{0x3c18, 0xbfff, 0x0991, 0xa000, 0x94c2, 0x0911, 0xb000, 0x0190, 0x3104, 0x3258, 0x800b, 0x96c0, 0xdc84, 0x147c, 0x9fe7, 0x96c0 }, 16, 0x000b1200, 1},
+ {{0xd221, 0x09d1, 0xa000, 0x90c0, 0x94c2, 0x0911, 0xb000, 0x0194, 0x3104, 0x3258, 0x800b, 0x98c0, 0x3d00, 0x3556, 0x8008, 0xe949 }, 16, 0x000b1220, 1},
+ {{0x94c0, 0xc948, 0xc18a, 0x32e4, 0x3c4e, 0x8001, 0x94c0, 0x6460, 0x979d, 0x0002, 0x3550, 0x8008, 0x6c10, 0x9e21, 0x94c0, 0x9621 }, 16, 0x000b1240, 1},
+ {{0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x9ac0, 0xd421, 0xda10, 0x3bc8, 0x3c08, 0xbfff, 0x8443, 0x4493 }, 16, 0x000b1260, 1},
+ {{0x1493, 0x3bc8, 0x3c08, 0xbfff, 0x39fc, 0x9fff, 0x7064, 0x800d, 0x5293, 0x35fb, 0x9fff, 0x7063, 0x85f9, 0x32e4, 0x39e4, 0x8001 }, 16, 0x000b1280, 1},
+ {{0xc08b, 0x32e4, 0x3a5c, 0x8001, 0x98c0, 0x3900, 0x32c0, 0x800b, 0xc09c, 0x32e4, 0x3a62, 0x8001, 0x94c0, 0xc181, 0xc09c, 0x9f71 }, 16, 0x000b12a0, 1},
+ {{0x98c0, 0x3aa8, 0x3c20, 0xbfff, 0xc09c, 0x0dc6, 0x2a3c, 0x8009, 0x1992, 0x3800, 0x20f0, 0x8008, 0x94c0, 0x9620, 0x9f20, 0xebe9 }, 16, 0x000b12c0, 1},
+ {{0xeb3d, 0x0b90, 0x32e4, 0x3a68, 0x8001, 0x09c2, 0x2a3c, 0x8009, 0x0b06, 0x354c, 0x8008, 0x3c00, 0x2036, 0x8008, 0xeb41, 0x0b02 }, 16, 0x000b12e0, 1},
+ {{0x354c, 0x8008, 0x0007, 0x354e, 0x8008, 0x4014, 0x0506, 0x3550, 0x8008, 0x26e9, 0xcc45, 0x8021, 0xec61, 0x98c0, 0xecf1, 0x0c02 }, 16, 0x000b1300, 1},
+ {{0x3550, 0x8008, 0x90c0, 0x98c2, 0x3f00, 0x3556, 0x8008, 0xc381, 0x90c0, 0x92c2, 0x939f, 0x01c5, 0x38b8, 0x8008, 0x3761, 0x0024 }, 16, 0x000b1320, 1},
+ {{0x3364, 0x8009, 0x2769, 0x3cc8, 0x3c10, 0xbfff, 0x801b, 0xd422, 0x8407, 0xd428, 0x8445, 0x98c0, 0xc581, 0x3004, 0x3398, 0x800b }, 16, 0x000b1340, 1},
+ {{0x05c1, 0x38d5, 0x8008, 0x1294, 0x3681, 0x2000, 0x8000, 0x377e, 0x0006, 0x354c, 0x8008, 0x9ac0, 0x311c, 0x803f, 0x90c0, 0x34cd }, 16, 0x000b1360, 1},
+ {{0x8410, 0x347d, 0xd220, 0x8413, 0x7360, 0x90c0, 0x92c3, 0xc281, 0x96c3, 0x02c1, 0x38d5, 0x8008, 0x96c0, 0x6d10, 0x9621, 0x9f21 }, 16, 0x000b1380, 1},
+ {{0x9f70, 0x0220, 0x3364, 0x8009, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x77d0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x32e4 }, 16, 0x000b13a0, 1},
+ {{0x38ac, 0x8001, 0xe750, 0x32e4, 0x3a7a, 0x8001, 0xc09e, 0x32e4, 0x3a62, 0x8001, 0x94c0, 0xc183, 0xc09e, 0x33e4, 0x3b3a, 0x8001 }, 16, 0x000b13c0, 1},
+ {{0x27e0, 0x0307, 0x39c0, 0x8008, 0x25e9, 0x36d7, 0x3c00, 0x2026, 0x8008, 0x3ae1, 0x3e00, 0x38a8, 0x8008, 0x96c6, 0x7ec1, 0xc086 }, 16, 0x000b13e0, 1},
+ {{0x8093, 0x14d4, 0xc845, 0x73fc, 0x94c0, 0xe81e, 0x8082, 0x56d0, 0xd720, 0x8479, 0x9ac0, 0x2000, 0x83e8, 0x90c0, 0x3656, 0x8000 }, 16, 0x000b1400, 1},
+ {{0x806b, 0x33e4, 0x39f6, 0x8001, 0x9ac0, 0x6760, 0x3a00, 0x2114, 0x8008, 0xc082, 0x27eb, 0x9ff0, 0x14d2, 0xfb41, 0x7e48, 0x9ac0 }, 16, 0x000b1420, 1},
+ {{0x3681, 0x8006, 0x90c0, 0x3484, 0x8006, 0xda14, 0xd641, 0x2661, 0x6d10, 0x9ac0, 0x027c, 0x9ffb, 0x90c0, 0x3901, 0x800e, 0x32e4 }, 16, 0x000b1440, 1},
+ {{0x3b76, 0x8001, 0x64e0, 0x2760, 0x11fc, 0x9ff0, 0x98c0, 0xd4c6, 0x3f00, 0x21f2, 0x8008, 0x78e1, 0x2f90, 0x3479, 0x32e4, 0x3b58 }, 16, 0x000b1460, 1},
+ {{0x8001, 0x4717, 0x3104, 0x348c, 0x800b, 0xc081, 0xe770, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0 }, 16, 0x000b1480, 1},
+ {{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x270c, 0x8028, 0xe7ec, 0x270c, 0x8000, 0xc9a8, 0x7450, 0xf014, 0x3aa8, 0x3c20 }, 16, 0x000b14a0, 1},
+ {{0xbfff, 0xfa48, 0xfbc8, 0x90c0, 0x5193, 0xf149, 0x9f7d, 0xc781, 0x07c0, 0x2a40, 0x8009, 0x0ac6, 0x38d0, 0x8008, 0x90c0, 0xea46 }, 16, 0x000b14c0, 1},
+ {{0xfa48, 0xfbc8, 0x90c0, 0x5b13, 0xfb10, 0xf690, 0x3d18, 0x8008, 0xf048, 0xf0c8, 0x6469, 0x3704, 0x3540, 0x800b, 0x3bc8, 0x2428 }, 16, 0x000b14e0, 1},
+ {{0xbfff, 0xfb48, 0xfec8, 0x90c0, 0x5196, 0xf142, 0xf3c2, 0x3719, 0x8080, 0xf148, 0xf5c8, 0xf542, 0x18fc, 0x9ffa, 0xf807, 0x34c9 }, 16, 0x000b1500, 1},
+ {{0x2428, 0xbfff, 0xf448, 0xfcc8, 0x90c0, 0x5394, 0xf342, 0x24e0, 0x9f7f, 0xf0c2, 0xde00, 0xf442, 0xf5c2, 0xfac8, 0x90c0, 0x4592 }, 16, 0x000b1520, 1},
+ {{0x3ce8, 0x3c2c, 0xbfff, 0xfc48, 0xffc8, 0x90c0, 0x5597, 0xf542, 0xf0c2, 0x3119, 0x8f00, 0xf148, 0xf5c8, 0x3ace, 0x8608, 0xf648 }, 16, 0x000b1540, 1},
+ {{0xf4c8, 0xf442, 0x1afc, 0x9ffa, 0xfa09, 0x35c9, 0x2418, 0xbfff, 0xf548, 0xffc8, 0x90c0, 0x5597, 0xf542, 0xf4c2, 0x3909, 0x8030 }, 16, 0x000b1560, 1},
+ {{0xf148, 0xf3c8, 0x36ce, 0x8410, 0xf642, 0xf2c2, 0xf248, 0x1ffc, 0x9fe2, 0xff08, 0x30c9, 0x2418, 0xbfff, 0xf048, 0xfec8, 0x90c0 }, 16, 0x000b1580, 1},
+ {{0x5396, 0xf342, 0xf2c2, 0x350a, 0x8f00, 0xf248, 0xf4c8, 0x38cc, 0x8218, 0xf442, 0xf3c2, 0xf348, 0x1dfc, 0x9fe2, 0xfd06, 0x33e9 }, 16, 0x000b15a0, 1},
+ {{0x3c2c, 0xbfff, 0xf348, 0xfcc8, 0x90c0, 0x5194, 0xf142, 0x22e0, 0x90ff, 0xf4c2, 0xdd04, 0xf242, 0xf2c2, 0xfdc8, 0x90c0, 0x4295 }, 16, 0x000b15c0, 1},
+ {{0x30c9, 0x2418, 0xbfff, 0xf048, 0xfdc8, 0x90c0, 0x5095, 0xf042, 0x32f9, 0x3fff, 0xbfcf, 0xf4c2, 0xdd04, 0xf242, 0xf1c2, 0xf9c8 }, 16, 0x000b15e0, 1},
+ {{0x90c0, 0x4191, 0x33c9, 0x2418, 0xbfff, 0xf348, 0xfac8, 0x90c0, 0x5392, 0xf342, 0x31f9, 0x3fff, 0xb0ff, 0xf6c2, 0xdc86, 0xf141 }, 16, 0x000b1600, 1},
+ {{0xf5c1, 0xffc8, 0x90c0, 0x4597, 0x32e9, 0x3c0c, 0xbfff, 0xf248, 0xfdc8, 0x90c0, 0x5395, 0xf342, 0xf1c2, 0x3389, 0x8000, 0xf148 }, 16, 0x000b1620, 1},
+ {{0xf0c8, 0x30cd, 0x805f, 0xf542, 0xf1c2, 0xf148, 0x11fc, 0x9fe2, 0xf10a, 0x36e9, 0x3c0c, 0xbfff, 0xf648, 0xfcc8, 0x90c0, 0x5494 }, 16, 0x000b1640, 1},
+ {{0xf442, 0x31e9, 0x3fff, 0xbfff, 0xf2c2, 0xdc82, 0xf142, 0xf0c2, 0xfdc8, 0x90c0, 0x4095, 0x13fc, 0x9fd8, 0x73e3, 0x3504, 0x36a2 }, 16, 0x000b1660, 1},
+ {{0x800b, 0x32a9, 0x3c4c, 0xbfff, 0xf248, 0xfac8, 0x90c0, 0x5292, 0xf242, 0xf4c2, 0x0914, 0xa800, 0xf442, 0xf3c2, 0xfdc8, 0x90c0 }, 16, 0x000b1680, 1},
+ {{0x4395, 0x31e9, 0x3c00, 0xbfff, 0xf148, 0xf8c8, 0x90c0, 0x5790, 0xf747, 0xc090, 0x3304, 0x31b0, 0x800a, 0xc08b, 0x33e4, 0x39ea }, 16, 0x000b16a0, 1},
+ {{0x8001, 0xc08a, 0x33e4, 0x39ea, 0x8001, 0xc087, 0x33e4, 0x39ea, 0x8001, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b16c0, 1},
+ {{0x90c0, 0x90c0, 0x9f79, 0x2000, 0x83e8, 0x33e4, 0x39f6, 0x8001, 0xc08b, 0x33e4, 0x39e4, 0x8001, 0xc08a, 0x33e4, 0x39e4, 0x8001 }, 16, 0x000b16e0, 1},
+ {{0x2000, 0x83e8, 0x33e4, 0x39f6, 0x8001, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0xec44, 0xfc48, 0xfcc8, 0x90c0, 0x5614, 0xf605, 0xf285 }, 16, 0x000b1700, 1},
+ {{0xd128, 0x3704, 0x3736, 0x800b, 0xc09a, 0x3304, 0x31b0, 0x800a, 0x3104, 0x373e, 0x800b, 0xc0ae, 0x3304, 0x31b0, 0x800a, 0x35e9 }, 16, 0x000b1720, 1},
+ {{0x3c2c, 0xbfff, 0xf548, 0x1efc, 0x9fee, 0xfe05, 0x10fc, 0x9ff6, 0x7c48, 0xf042, 0xfec8, 0x90c0, 0x5296, 0xf241, 0xf7c2, 0xf4c1 }, 16, 0x000b1740, 1},
+ {{0xdf9c, 0xf741, 0xf4c1, 0xfec8, 0x90c0, 0x4496, 0x3bc8, 0x2418, 0xbfff, 0xfb48, 0x1afc, 0x9ff0, 0xfa05, 0x15fc, 0x9ff6, 0xdb95 }, 16, 0x000b1760, 1},
+ {{0xf742, 0xfdc8, 0x90c0, 0x5695, 0xf641, 0xf5c2, 0xf2c1, 0xde9a, 0xf541, 0xf5c1, 0xffc8, 0x90c0, 0x4597, 0x3cc8, 0x2418, 0xbfff }, 16, 0x000b1780, 1},
+ {{0xfc48, 0x1cfc, 0x9ff4, 0xfc05, 0x10fc, 0x9ff6, 0x7c58, 0xf042, 0xfbc8, 0x90c0, 0x5293, 0xf241, 0xf6c2, 0xf0c1, 0xdf18, 0xf642 }, 16, 0x000b17a0, 1},
+ {{0xf7c2, 0xfec8, 0x90c0, 0x4796, 0x38e8, 0x3c0c, 0xbfff, 0xf848, 0x1dfc, 0x9fec, 0xfd05, 0x11fc, 0x9ff6, 0x7cdf, 0xf142, 0xfec8 }, 16, 0x000b17c0, 1},
+ {{0x90c0, 0x5296, 0xf241, 0xf5c2, 0xf6c1, 0xde9e, 0xf542, 0xf4c2, 0xf8c8, 0x90c0, 0x4490, 0x16fc, 0x9fd8, 0xd321, 0x3504, 0x3826 }, 16, 0x000b17e0, 1},
+ {{0x800b, 0x33a9, 0x3c4c, 0xbfff, 0xf348, 0xfdc8, 0x90c0, 0x5495, 0xf442, 0x32f9, 0x3fff, 0xb7ff, 0xf0c2, 0xdd00, 0xf242, 0xf5c2 }, 16, 0x000b1800, 1},
+ {{0xfec8, 0x90c0, 0x4596, 0x0ac6, 0x38d0, 0x8008, 0x90c0, 0xea46, 0xfa48, 0xf9c8, 0x90c0, 0x5411, 0xf405, 0xf685, 0x3d1e, 0x8008 }, 16, 0x000b1820, 1},
+ {{0xf648, 0xf2c8, 0x6569, 0x3704, 0x3874, 0x800b, 0x33c9, 0x2428, 0xbfff, 0xf348, 0x1ffc, 0x9ff2, 0xff05, 0xfcc8, 0x90c0, 0x5094 }, 16, 0x000b1840, 1},
+ {{0xf042, 0x17fc, 0x9ff6, 0xf0c2, 0xdf98, 0xf742, 0xf5c2, 0xffc8, 0x90c0, 0x4597, 0x9f7c, 0x33a9, 0x3c20, 0xbfff, 0xf348, 0xfcc8 }, 16, 0x000b1860, 1},
+ {{0x90c0, 0x5194, 0xf146, 0xc9a8, 0x270b, 0x8000, 0x27eb, 0x9fd8, 0xe7eb, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71 }, 16, 0x000b1880, 1},
+ {{0x98c0, 0x3a00, 0x2032, 0x8008, 0xe748, 0x3b00, 0x2034, 0x8008, 0x1dd2, 0x3c00, 0x203e, 0x8008, 0x96c0, 0x50d3, 0x2980, 0x8001 }, 16, 0x000b18a0, 1},
+ {{0x11d4, 0x3800, 0x203e, 0x8008, 0x9ac0, 0x78c1, 0xe9f8, 0x3a00, 0x2032, 0x8008, 0x0110, 0xe9ad, 0x94c6, 0xcbff, 0x6d10, 0x8048 }, 16, 0x000b18c0, 1},
+ {{0x94c6, 0x4b12, 0xf204, 0x9ac0, 0x2c80, 0x8002, 0x90c0, 0x2b80, 0x8005, 0x90c0, 0x94c0, 0xecf8, 0xebf8, 0xecad, 0x8413, 0x3304 }, 16, 0x000b18e0, 1},
+ {{0x33b0, 0x800b, 0x98c0, 0xf004, 0x3104, 0x3926, 0x800b, 0x96c0, 0x6c10, 0xebad, 0xc588, 0x840f, 0x3304, 0x34a0, 0x800b, 0x3104 }, 16, 0x000b1900, 1},
+ {{0x3926, 0x800b, 0xf504, 0x2d10, 0x3b00, 0x2034, 0x8008, 0x3c00, 0x2032, 0x8008, 0x15fc, 0x9ff8, 0x0513, 0xe768, 0x9f70, 0x4214 }, 16, 0x000b1920, 1},
+ {{0x96c0, 0x6e90, 0x9620, 0x9720, 0x94c0, 0x9e20, 0xcb8b, 0x94c0, 0xce40, 0xe748, 0x3dc0, 0x2a88, 0x8009, 0xee8b, 0x96c0, 0xeefe }, 16, 0x000b1940, 1},
+ {{0x2518, 0x80f8, 0x94c0, 0xee1d, 0xc488, 0x5e96, 0x90c0, 0x94c0, 0xf293, 0x9e61, 0x35db, 0x8000, 0x65e9, 0x98c7, 0x2618, 0x80da }, 16, 0x000b1960, 1},
+ {{0x90c0, 0x6f90, 0x92c3, 0xf704, 0x98c0, 0xc581, 0x3104, 0x3a54, 0x800b, 0xf691, 0x6769, 0x2418, 0x80be, 0x92c2, 0xc581, 0xd321 }, 16, 0x000b1980, 1},
+ {{0x90c0, 0x98c6, 0x2418, 0x80b2, 0x90c0, 0xc081, 0x92c2, 0xf004, 0xd322, 0x90c0, 0x94c6, 0x80a0, 0xc782, 0x92c2, 0xf704, 0xd323 }, 16, 0x000b19a0, 1},
+ {{0x8094, 0x92c2, 0xc588, 0xd324, 0x808c, 0x92c2, 0xc588, 0xd325, 0x8084, 0x92c2, 0xc588, 0xd326, 0x90c0, 0x94c6, 0x807a, 0xc783 }, 16, 0x000b19c0, 1},
+ {{0x92c2, 0xf704, 0xd327, 0x846f, 0x98c0, 0xc588, 0x3104, 0x3a54, 0x800b, 0xf292, 0x6569, 0x805e, 0x92c2, 0xc581, 0xd121, 0x90c0 }, 16, 0x000b19e0, 1},
+ {{0x94c6, 0x8054, 0xc084, 0x92c2, 0xf004, 0xd122, 0x90c0, 0x94c6, 0x8046, 0xc685, 0x92c2, 0xf604, 0xd123, 0x803a, 0x92c2, 0xc590 }, 16, 0x000b1a00, 1},
+ {{0xd124, 0x8032, 0x92c2, 0xc590, 0xd125, 0x90c0, 0x94c6, 0x8028, 0xc086, 0x92c2, 0xf004, 0xd126, 0x90c0, 0x94c6, 0x801a, 0xc787 }, 16, 0x000b1a20, 1},
+ {{0x92c2, 0xf704, 0xd127, 0x840f, 0x98c0, 0xc590, 0x3104, 0x3a54, 0x800b, 0xf404, 0x94c0, 0xcd41, 0xc990, 0x90c0, 0xed89, 0x96c0 }, 16, 0x000b1a40, 1},
+ {{0xedfe, 0x2518, 0x81be, 0x39c0, 0x2a44, 0x8009, 0x3cc0, 0x2abc, 0x8009, 0xed19, 0x1d95, 0x39c0, 0x2abc, 0x8009, 0x90c0, 0x94c0 }, 16, 0x000b1a60, 1},
+ {{0xf094, 0x9d61, 0x311b, 0x8001, 0x65e9, 0x98c7, 0x2618, 0x8192, 0x90c0, 0x6e10, 0x92c3, 0xf403, 0x3004, 0x3c1c, 0x800b, 0x0905 }, 16, 0x000b1a80, 1},
+ {{0xa002, 0xf794, 0x3f1e, 0x8002, 0x6769, 0x98c7, 0x2618, 0x8172, 0x90c0, 0x6e10, 0x92c3, 0xf403, 0x3004, 0x3c1c, 0x800b, 0x0905 }, 16, 0x000b1aa0, 1},
+ {{0xa002, 0xf294, 0x351e, 0x8004, 0x6769, 0x98c7, 0x2618, 0x8152, 0x90c0, 0x6d10, 0x92c3, 0xf203, 0x3004, 0x3c1c, 0x800b, 0x0905 }, 16, 0x000b1ac0, 1},
+ {{0xa002, 0xf394, 0x371a, 0x8008, 0x6569, 0x98c7, 0x2618, 0x8132, 0x90c0, 0x6e10, 0x92c3, 0xf403, 0x3004, 0x3c1c, 0x800b, 0x0905 }, 16, 0x000b1ae0, 1},
+ {{0xa002, 0x94c0, 0xc385, 0xf691, 0x6fb9, 0x7fc1, 0xcd47, 0x90c0, 0xed19, 0x5315, 0x65e9, 0x90c0, 0x96c6, 0x6769, 0x0905, 0xa002 }, 16, 0x000b1b00, 1},
+ {{0x2418, 0x80fc, 0x94c2, 0x0905, 0xa002, 0xd321, 0x90c0, 0x98c6, 0x2418, 0x80ee, 0x90c0, 0xc481, 0x92c2, 0xf403, 0xd322, 0x90c0 }, 16, 0x000b1b20, 1},
+ {{0x98c6, 0x2418, 0x80dc, 0x90c0, 0xc282, 0x92c2, 0xf203, 0xd323, 0x2418, 0x80cc, 0x94c2, 0x0905, 0xa008, 0xd324, 0x2418, 0x80c0 }, 16, 0x000b1b40, 1},
+ {{0x94c2, 0x0905, 0xa008, 0xd325, 0x2418, 0x80b4, 0x94c2, 0x0905, 0xa008, 0xd326, 0x90c0, 0x94c6, 0x80a6, 0xc483, 0x92c2, 0xf403 }, 16, 0x000b1b60, 1},
+ {{0xd327, 0x849b, 0x3004, 0x3c1c, 0x800b, 0x0905, 0xa008, 0xc685, 0x2da6, 0xf692, 0x7dc1, 0xc843, 0x90c0, 0xe81c, 0x5710, 0x67e9 }, 16, 0x000b1b80, 1},
+ {{0x90c0, 0x96c6, 0x6769, 0x0905, 0xa002, 0x8072, 0x94c2, 0x0905, 0xa002, 0xd321, 0x90c0, 0x94c6, 0x8066, 0xc484, 0x92c2, 0xf403 }, 16, 0x000b1ba0, 1},
+ {{0xd322, 0x90c0, 0x94c6, 0x8058, 0xc785, 0x92c2, 0xf703, 0xd323, 0x804c, 0x94c2, 0x0905, 0xa010, 0xd324, 0x8042, 0x94c2, 0x0905 }, 16, 0x000b1bc0, 1},
+ {{0xa010, 0xd325, 0x90c0, 0x94c6, 0x8036, 0xc386, 0x92c2, 0xf303, 0xd326, 0x90c0, 0x94c6, 0x8028, 0xc287, 0x92c2, 0xf203, 0xd327 }, 16, 0x000b1be0, 1},
+ {{0x841d, 0x3004, 0x3c1c, 0x800b, 0x0905, 0xa010, 0x98c0, 0xc488, 0x3004, 0x3c1c, 0x800b, 0xf403, 0xc689, 0xf603, 0x64e9, 0x92c2 }, 16, 0x000b1c00, 1},
+ {{0x6e90, 0x77f5, 0x67e9, 0x8425, 0x24e9, 0x06c6, 0x2ab8, 0x8009, 0x94c0, 0xf583, 0x801b, 0x94c0, 0xc789, 0xfd84, 0x6b1b, 0xcc46 }, 16, 0x000b1c20, 1},
+ {{0x90c0, 0xed1c, 0x94fd, 0x391f, 0x80ff, 0x3477, 0xe768, 0x9e21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b1c40, 1},
+ {{0x3e00, 0xa004, 0x6e10, 0x6e10, 0x36ca, 0x3c14, 0xbfff, 0x9744, 0x2e90, 0x2c10, 0x2d10, 0x0ac6, 0x38d0, 0x8008, 0x3480, 0xa000 }, 16, 0x000b1c60, 1},
+ {{0x5196, 0x9ac0, 0x3399, 0x8000, 0xe0ea, 0x2a0b, 0x8062, 0x96c0, 0x64e9, 0x9620, 0x9720, 0x96c0, 0x56d3, 0x2b0a, 0x8018, 0x98c6 }, 16, 0x000b1c80, 1},
+ {{0x3d99, 0x8000, 0x57d2, 0x6f10, 0x9ac7, 0x64e9, 0xc681, 0x3f9f, 0x8000, 0xeb62, 0x94c0, 0x9e20, 0x9f20, 0x3606, 0xa004, 0x6c10 }, 16, 0x000b1ca0, 1},
+ {{0x51d3, 0x3e27, 0xa002, 0x90c0, 0xea62, 0xc081, 0x339d, 0x8000, 0x67e9, 0x3820, 0xa000, 0x57d2, 0x270d, 0x8058, 0x3a06, 0xb000 }, 16, 0x000b1cc0, 1},
+ {{0x6d90, 0x3f99, 0x8000, 0xe7ed, 0x3a07, 0xa002, 0xc381, 0x27ef, 0x9fe8, 0x66e9, 0x3a46, 0xb004, 0x6e90, 0x3f5f, 0x8000, 0x4497 }, 16, 0x000b1ce0, 1},
+ {{0x3a27, 0xa000, 0xc581, 0x2f0a, 0x8004, 0x64e9, 0x3820, 0xa000, 0x4492, 0x27e8, 0x9ff0, 0x98c1, 0x67e9, 0x67e9, 0xc181, 0x6c90 }, 16, 0x000b1d00, 1},
+ {{0x3820, 0xa000, 0x4490, 0x280e, 0x8004, 0x3820, 0xa000, 0x4496, 0x27e9, 0x9fd8, 0x94c6, 0xf151, 0x6c90, 0x92c3, 0xc181, 0x92c8 }, 16, 0x000b1d20, 1},
+ {{0x4299, 0x94c0, 0x6f90, 0x9746, 0x27ea, 0x9fc0, 0x92c8, 0x479a, 0x3c00, 0xa004, 0x6469, 0xeae0, 0x3cc0, 0x2abe, 0x8009, 0x3c00 }, 16, 0x000b1d40, 1},
+ {{0xa100, 0x2a08, 0x8068, 0x90c0, 0x27eb, 0x9fea, 0x3800, 0xa100, 0x57d0, 0x280a, 0x8002, 0x3c20, 0xa000, 0x2a0a, 0x8002, 0x90c0 }, 16, 0x000b1d60, 1},
+ {{0x3f1a, 0x8700, 0x02c0, 0x2abc, 0x8009, 0x3880, 0xa000, 0x57d2, 0x2c0d, 0x8002, 0x3c80, 0xa000, 0x2a0e, 0x8002, 0x90c0, 0x3f1a }, 16, 0x000b1d80, 1},
+ {{0x8700, 0x96c0, 0x4214, 0x2d09, 0x8002, 0x3840, 0xa100, 0x57d2, 0x2e0f, 0x8012, 0x3ca0, 0xa000, 0x2f08, 0x8002, 0x90c0, 0x3f1a }, 16, 0x000b1da0, 1},
+ {{0x8700, 0x0215, 0x3fc0, 0x2ac4, 0x8009, 0x3a80, 0xa000, 0x52d6, 0x34c2, 0x2ac6, 0x8009, 0x3ca0, 0xa000, 0x280d, 0x8002, 0x90c0 }, 16, 0x000b1dc0, 1},
+ {{0x351a, 0x8700, 0x3840, 0xa000, 0x4211, 0x2c0b, 0x8002, 0x38c0, 0xa100, 0x57d7, 0x2d09, 0x8002, 0x3f1a, 0x8700, 0x0217, 0x3ec0 }, 16, 0x000b1de0, 1},
+ {{0x2aca, 0x8009, 0x3480, 0xa000, 0x57d0, 0x3f1f, 0x8700, 0x3480, 0xa000, 0x4714, 0x38c0, 0xa100, 0x52d5, 0x2b0c, 0x8002, 0x351f }, 16, 0x000b1e00, 1},
+ {{0x8700, 0x4713, 0x3480, 0xa000, 0x57d1, 0x3f1a, 0x8700, 0x4216, 0x96c0, 0x57d0, 0x27ee, 0x9ff2, 0x9ac0, 0x2e0f, 0x8002, 0x90c0 }, 16, 0x000b1e20, 1},
+ {{0x3f1a, 0x80ff, 0x98c6, 0xf20c, 0x3800, 0x20e0, 0x8008, 0x3a06, 0xa100, 0x3202, 0x20e0, 0x8008, 0x52d2, 0x98c7, 0x351a, 0x80ff }, 16, 0x000b1e40, 1},
+ {{0x90c0, 0xe866, 0x3480, 0xa000, 0x4213, 0x96c0, 0x52d2, 0x27ea, 0x9fee, 0x351f, 0x80ff, 0x3480, 0xa000, 0x4714, 0x3880, 0xa100 }, 16, 0x000b1e60, 1},
+ {{0x52d6, 0x27ee, 0x9ff6, 0x351a, 0x80ff, 0x4212, 0x3480, 0xa000, 0x52d7, 0x351f, 0x80ff, 0xf708, 0x3480, 0xa000, 0x52d0, 0x351f }, 16, 0x000b1e80, 1},
+ {{0x80ff, 0x4716, 0x3480, 0xa000, 0x52d5, 0x351f, 0x80ff, 0x4717, 0x3480, 0xa000, 0x52d1, 0x351a, 0x80ff, 0x3480, 0xa000, 0x4216 }, 16, 0x000b1ea0, 1},
+ {{0x3a86, 0xa002, 0x90c0, 0x52d0, 0x57d2, 0x6469, 0x3c00, 0xa002, 0x357f, 0x9ff0, 0x90c0, 0x351b, 0x8007, 0x7fe4, 0x3c00, 0xa002 }, 16, 0x000b1ec0, 1},
+ {{0x2418, 0x80e4, 0x90c0, 0x3f04, 0x8001, 0x3400, 0xa004, 0x7e63, 0x3600, 0xb000, 0x6769, 0x7773, 0x90c0, 0x98c6, 0xd321, 0x3501 }, 16, 0x000b1ee0, 1},
+ {{0x2000, 0x8010, 0x8433, 0xd3af, 0x8083, 0xd3bf, 0x807f, 0x3417, 0x803f, 0x8079, 0x3417, 0x807f, 0x8073, 0x3417, 0x80ff, 0x806d }, 16, 0x000b1f00, 1},
+ {{0x3417, 0x81ff, 0x8067, 0x3417, 0x83ff, 0x8061, 0x3004, 0x3f8a, 0x800b, 0x0905, 0xa040, 0xd322, 0x8431, 0xd3a7, 0x804f, 0xd3af }, 16, 0x000b1f20, 1},
+ {{0x804b, 0xd3bf, 0x8047, 0x3417, 0x803f, 0x8041, 0x3417, 0x807f, 0x803b, 0x3417, 0x80ff, 0x8035, 0x3417, 0x81ff, 0x802f, 0x3004 }, 16, 0x000b1f40, 1},
+ {{0x3f8a, 0x800b, 0x0905, 0xa040, 0xd326, 0x8417, 0xd3bf, 0x801d, 0x3417, 0x803f, 0x8017, 0x3004, 0x3f8a, 0x800b, 0x0905, 0xa040 }, 16, 0x000b1f60, 1},
+ {{0x6769, 0x90c0, 0x94c3, 0x0905, 0xa008, 0xd321, 0x8409, 0x3417, 0x83ff, 0x8011, 0xd322, 0x2718, 0x8126, 0x3417, 0x81ff, 0x2718 }, 16, 0x000b1f80, 1},
+ {{0x811e, 0x38e8, 0x3c00, 0xbfff, 0x90c0, 0x5790, 0x3f0f, 0x8300, 0x67e9, 0x2518, 0x810a, 0x3024, 0x20bc, 0x800b, 0x0915, 0xa020 }, 16, 0x000b1fa0, 1},
+ {{0x3600, 0xb000, 0x6769, 0x7773, 0x809b, 0xd321, 0x843f, 0xd3af, 0x2518, 0x80ec, 0xd3bf, 0x2518, 0x80e6, 0x3417, 0x803f, 0x2518 }, 16, 0x000b1fc0, 1},
+ {{0x80de, 0x3417, 0x807f, 0x2518, 0x80d6, 0x3417, 0x80ff, 0x2518, 0x80ce, 0x3417, 0x81ff, 0x2518, 0x80c6, 0x3417, 0x83ff, 0x80bf }, 16, 0x000b1fe0, 1},
+ {{0x3024, 0x20bc, 0x800b, 0x2500, 0x8040, 0xd322, 0x8431, 0xd3a7, 0x80ad, 0xd3af, 0x80a9, 0xd3bf, 0x80a5, 0x3417, 0x803f, 0x809f }, 16, 0x000b2000, 1},
+ {{0x3417, 0x807f, 0x8099, 0x3417, 0x80ff, 0x8093, 0x3417, 0x81ff, 0x808d, 0x3024, 0x20bc, 0x800b, 0x2500, 0x8040, 0xd326, 0x8417 }, 16, 0x000b2020, 1},
+ {{0xd3bf, 0x807b, 0x3417, 0x803f, 0x8075, 0x3024, 0x20bc, 0x800b, 0x2500, 0x8040, 0x6769, 0x8067, 0x98c0, 0xc588, 0x3124, 0x20bc }, 16, 0x000b2040, 1},
+ {{0x800b, 0x3400, 0xa800, 0x7773, 0xd321, 0x841f, 0x3417, 0x80ff, 0x804d, 0x3417, 0x81ff, 0x8047, 0x3417, 0x83ff, 0x8041, 0x3024 }, 16, 0x000b2060, 1},
+ {{0x20bc, 0x800b, 0x2500, 0x8040, 0xd322, 0x841f, 0x3417, 0x807f, 0x802d, 0x3417, 0x80ff, 0x8027, 0x3417, 0x81ff, 0x8021, 0x3024 }, 16, 0x000b2080, 1},
+ {{0x20bc, 0x800b, 0x2500, 0x8040, 0xd326, 0x8012, 0x96c2, 0x3501, 0x2000, 0x8010, 0x6769, 0x90c0, 0x92c3, 0xc588, 0x65e9, 0x3420 }, 16, 0x000b20a0, 1},
+ {{0xa000, 0x9a59, 0x96c2, 0x3a00, 0x20e2, 0x8008, 0x90c0, 0x98c1, 0xea6c, 0x3800, 0x20e2, 0x8008, 0x56d2, 0x3a26, 0xa008, 0x57d0 }, 16, 0x000b20c0, 1},
+ {{0x3d79, 0x9ff0, 0x65e9, 0x3800, 0xa00c, 0x7ce4, 0x3d1e, 0x8007, 0x3c00, 0xaa00, 0x3307, 0x8001, 0x7776, 0x2418, 0x8102, 0x7fe3 }, 16, 0x000b20e0, 1},
+ {{0xd321, 0x844f, 0x3400, 0xa004, 0xd0af, 0x809f, 0x3400, 0xa004, 0xd0bf, 0x8097, 0x3600, 0xa004, 0x3411, 0x803f, 0x808d, 0x3600 }, 16, 0x000b2100, 1},
+ {{0xa004, 0x3411, 0x807f, 0x8083, 0x3600, 0xa004, 0x3411, 0x80ff, 0x8079, 0x3600, 0xa004, 0x3411, 0x81ff, 0x806f, 0x3600, 0xa004 }, 16, 0x000b2120, 1},
+ {{0x3411, 0x83ff, 0x8065, 0x3024, 0x21a8, 0x800b, 0x0905, 0xa080, 0xd322, 0x844d, 0x3400, 0xa004, 0xd0a7, 0x804f, 0x3400, 0xa004 }, 16, 0x000b2140, 1},
+ {{0xd0af, 0x8047, 0x3400, 0xa004, 0xd0bf, 0x803f, 0x3600, 0xa004, 0x3411, 0x803f, 0x8035, 0x3600, 0xa004, 0x3411, 0x807f, 0x802b }, 16, 0x000b2160, 1},
+ {{0x3600, 0xa004, 0x3411, 0x80ff, 0x8021, 0x3600, 0xa004, 0x3411, 0x81ff, 0x8017, 0x3024, 0x21a8, 0x800b, 0x0905, 0xa080, 0x6769 }, 16, 0x000b2180, 1},
+ {{0x90c0, 0x94c3, 0x0905, 0xa010, 0xd321, 0x840d, 0x3600, 0xa004, 0x3411, 0x83ff, 0x8015, 0xd322, 0x2718, 0x813a, 0x3600, 0xa004 }, 16, 0x000b21a0, 1},
+ {{0x3411, 0x81ff, 0x2718, 0x812e, 0x38e8, 0x3c00, 0xbfff, 0x90c0, 0x3420, 0xa000, 0x5190, 0x3600, 0xa804, 0x330a, 0x8300, 0x3400 }, 16, 0x000b21c0, 1},
+ {{0xa004, 0x6569, 0x2518, 0x810e, 0x3024, 0x22f2, 0x800b, 0x0915, 0xa020, 0x3400, 0xa800, 0x7776, 0xd321, 0x8457, 0x3400, 0xa004 }, 16, 0x000b21e0, 1},
+ {{0xd0af, 0x2518, 0x80f0, 0x3400, 0xa004, 0xd0bf, 0x2518, 0x80e6, 0x3600, 0xa004, 0x3411, 0x803f, 0x2518, 0x80da, 0x3600, 0xa004 }, 16, 0x000b2200, 1},
+ {{0x3411, 0x807f, 0x2518, 0x80ce, 0x3600, 0xa004, 0x3411, 0x80ff, 0x80c3, 0x3600, 0xa004, 0x3411, 0x81ff, 0x80b9, 0x3600, 0xa004 }, 16, 0x000b2220, 1},
+ {{0x3411, 0x83ff, 0x80af, 0x3024, 0x22f2, 0x800b, 0x0905, 0xa080, 0xd322, 0x844d, 0x3400, 0xa004, 0xd0a7, 0x8099, 0x3400, 0xa004 }, 16, 0x000b2240, 1},
+ {{0xd0af, 0x8091, 0x3400, 0xa004, 0xd0bf, 0x8089, 0x3600, 0xa004, 0x3411, 0x803f, 0x807f, 0x3600, 0xa004, 0x3411, 0x807f, 0x8075 }, 16, 0x000b2260, 1},
+ {{0x3600, 0xa004, 0x3411, 0x80ff, 0x806b, 0x3600, 0xa004, 0x3411, 0x81ff, 0x8061, 0x3024, 0x22f2, 0x800b, 0x0905, 0xa080, 0xd326 }, 16, 0x000b2280, 1},
+ {{0x841f, 0x3400, 0xa004, 0xd0bf, 0x804b, 0x3600, 0xa004, 0x3411, 0x803f, 0x8041, 0x3024, 0x22f2, 0x800b, 0x0905, 0xa080, 0xd325 }, 16, 0x000b22a0, 1},
+ {{0x8429, 0x3400, 0xa004, 0xd0bf, 0x802b, 0x3600, 0xa004, 0x3411, 0x803f, 0x8021, 0x3600, 0xa004, 0x3411, 0x807f, 0x8017, 0x3024 }, 16, 0x000b22c0, 1},
+ {{0x22f2, 0x800b, 0x0905, 0xa080, 0x6769, 0x90c0, 0x94c3, 0x0905, 0xa010, 0x3600, 0xa100, 0x65e9, 0xe96c, 0x90c0, 0x96c3, 0x33c1 }, 16, 0x000b22e0, 1},
+ {{0x2bdc, 0x8009, 0x8456, 0x96c3, 0x03c2, 0x2ab8, 0x8009, 0x3480, 0xa000, 0x53d1, 0x371b, 0x8007, 0x96c0, 0x65e9, 0x3d1b, 0x8007 }, 16, 0x000b2300, 1},
+ {{0x802f, 0x65e9, 0x802b, 0x64e9, 0x90c0, 0x96c3, 0x33c1, 0x2b82, 0x8009, 0x8428, 0x96c3, 0x03c2, 0x2ab8, 0x8009, 0x33c1, 0x2b28 }, 16, 0x000b2320, 1},
+ {{0x8009, 0x3024, 0x235a, 0x800b, 0x03c2, 0x2ab8, 0x8009, 0x33c1, 0x2ace, 0x8009, 0x03c2, 0x2ab8, 0x8009, 0x98c0, 0x6d90, 0xeae0 }, 16, 0x000b2340, 1},
+ {{0x27e8, 0x9fc0, 0x3820, 0xa000, 0xc28c, 0x2a0a, 0x8010, 0x94c0, 0xf552, 0xf053, 0x3a20, 0xa000, 0xf554, 0xcd51, 0x90c0, 0x90c0 }, 16, 0x000b2360, 1},
+ {{0x3e80, 0xa000, 0xcc56, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x3e20, 0xa008, 0x7453, 0x74d3, 0x09c6, 0x38d0, 0x8008, 0xc181 }, 16, 0x000b2380, 1},
+ {{0x96c0, 0xd493, 0x52d2, 0xe0e8, 0x3ca0, 0xa002, 0x290a, 0x8002, 0x90c0, 0x34cd, 0x8208, 0x38c0, 0xa100, 0x55d2, 0x2a0f, 0x80ae }, 16, 0x000b23a0, 1},
+ {{0x94c0, 0xdc85, 0xcc5d, 0x64e1, 0x96c0, 0x64e9, 0x3519, 0x80ff, 0x3800, 0xa004, 0x7451, 0x2518, 0x816a, 0x3880, 0xa000, 0x65e9 }, 16, 0x000b23c0, 1},
+ {{0xf502, 0x55d7, 0x3620, 0xa000, 0xf301, 0xf455, 0x9ac1, 0x2502, 0x80a0, 0x90c0, 0x2502, 0x809e, 0xf504, 0x34a0, 0xa000, 0xed1a }, 16, 0x000b23e0, 1},
+ {{0x3aa0, 0xa000, 0x56d5, 0x3204, 0x3940, 0x800b, 0x3420, 0xa000, 0xf603, 0x3e40, 0xb000, 0x7550, 0x74f5, 0xe8e0, 0x08c6, 0x38d0 }, 16, 0x000b2400, 1},
+ {{0x8008, 0x3860, 0xa800, 0x7451, 0x5710, 0xf603, 0x3aa0, 0xa200, 0x280e, 0x80b0, 0xdd1f, 0xcc5d, 0x3640, 0xa000, 0x4210, 0xf301 }, 16, 0x000b2420, 1},
+ {{0x36a0, 0xa000, 0x56d6, 0xf502, 0x3204, 0x3940, 0x800b, 0x3420, 0xa000, 0xf604, 0x3a00, 0xb808, 0x75d1, 0x7470, 0xe8e0, 0xf5d2 }, 16, 0x000b2440, 1},
+ {{0x3840, 0xa004, 0x6469, 0x5710, 0xf4d5, 0x3400, 0xa800, 0xdc1f, 0x3600, 0xa004, 0x74f0, 0x4010, 0x3600, 0xa800, 0xde99, 0x805a }, 16, 0x000b2460, 1},
+ {{0xf552, 0x3400, 0xa004, 0xd029, 0x800f, 0x3400, 0xa004, 0xd02a, 0x94c7, 0x8409, 0x6d10, 0xc281, 0x6569, 0x840f, 0x3400, 0xa004 }, 16, 0x000b2480, 1},
+ {{0xd02b, 0x94c7, 0x8409, 0x6c90, 0xc181, 0x64e9, 0x8411, 0x3400, 0xa004, 0xd02c, 0x3607, 0xa004, 0x6c10, 0x840f, 0x3420, 0xa000 }, 16, 0x000b24a0, 1},
+ {{0xc081, 0x3600, 0xa004, 0x6469, 0xcd5a, 0x8009, 0x6569, 0x92c3, 0x7a41, 0x3400, 0xa804, 0x7475, 0x3400, 0xa004, 0x6469, 0x805d }, 16, 0x000b24c0, 1},
+ {{0x3400, 0xa004, 0xd029, 0x8011, 0x3400, 0xa004, 0xd02a, 0x3607, 0xa004, 0x6c90, 0x840f, 0x3420, 0xa000, 0xc181, 0x3400, 0xa004 }, 16, 0x000b24e0, 1},
+ {{0x64e9, 0x840f, 0x3400, 0xa004, 0xd02b, 0x94c7, 0x8409, 0x6e90, 0xc581, 0x66e9, 0x8411, 0x3400, 0xa004, 0xd02c, 0x3607, 0xa004 }, 16, 0x000b2500, 1},
+ {{0x6c10, 0x840f, 0x3420, 0xa000, 0xc081, 0x3600, 0xa004, 0x6469, 0xcd5a, 0x8009, 0x6569, 0x92c3, 0x7a41, 0x3a00, 0xa004, 0x7961 }, 16, 0x000b2520, 1},
+ {{0x79c1, 0xea42, 0xe842, 0x3400, 0xa004, 0x656a, 0x2dff, 0x9e45, 0x3a60, 0xa000, 0x03c4, 0x2abc, 0x8009, 0xf5d4, 0x3a00, 0xa005 }, 16, 0x000b2540, 1},
+ {{0x3413, 0x8500, 0x66e0, 0xf5d2, 0x3dc0, 0x2ac0, 0x8009, 0x3cc0, 0x2abe, 0x8009, 0x39c0, 0x2ac2, 0x8009, 0x8012, 0x3bc0, 0x2ac8 }, 16, 0x000b2560, 1},
+ {{0x8009, 0x3600, 0xa004, 0x3413, 0x8700, 0x8407, 0x0905, 0xa100, 0x5314, 0x3413, 0x8500, 0x8009, 0x3413, 0x8700, 0x8407, 0x0905 }, 16, 0x000b2580, 1},
+ {{0xa200, 0x5115, 0x3411, 0x8500, 0x8009, 0x3411, 0x8700, 0x8407, 0x0905, 0xa400, 0x5211, 0x3412, 0x8500, 0x8009, 0x3412, 0x8700 }, 16, 0x000b25a0, 1},
+ {{0x8407, 0x0905, 0xa800, 0x3400, 0xa004, 0x77d3, 0x3400, 0xa804, 0xdf9b, 0x3400, 0xa004, 0xdf99, 0x3400, 0xa004, 0xdf9a, 0x3400 }, 16, 0x000b25c0, 1},
+ {{0xa004, 0x67e9, 0x804f, 0x3400, 0xa004, 0x65e9, 0x8011, 0x3400, 0xa804, 0x73e3, 0x843e, 0x94c3, 0x0915, 0xa001, 0x65e9, 0x8011 }, 16, 0x000b25e0, 1},
+ {{0x3400, 0xa004, 0x73e3, 0x842c, 0x94c3, 0x0915, 0xa001, 0x64e9, 0x8011, 0x3400, 0xa004, 0x73e1, 0x841a, 0x94c3, 0x0915, 0xa001 }, 16, 0x000b2600, 1},
+ {{0x6569, 0x8011, 0x3400, 0xa004, 0x73e2, 0x90c0, 0x94c3, 0x0915, 0xa001, 0x3ac0, 0x2ac4, 0x8009, 0x90c0, 0x3420, 0xa000, 0x5312 }, 16, 0x000b2620, 1},
+ {{0x3600, 0xa004, 0x3413, 0x8500, 0x800d, 0x3600, 0xa004, 0x3413, 0x8700, 0x8407, 0x0905, 0xb000, 0x38c0, 0x2ac6, 0x8009, 0x90c0 }, 16, 0x000b2640, 1},
+ {{0x5110, 0x3411, 0x8500, 0x8009, 0x3411, 0x8700, 0x8407, 0x0925, 0xa000, 0x5313, 0x3413, 0x8500, 0x8009, 0x3413, 0x8700, 0x8407 }, 16, 0x000b2660, 1},
+ {{0x0945, 0xa000, 0x38c0, 0x2aca, 0x8009, 0x90c0, 0x5210, 0x3412, 0x8500, 0x8009, 0x3412, 0x8700, 0x8407, 0x0985, 0xa000, 0x3400 }, 16, 0x000b2680, 1},
+ {{0xa004, 0x7751, 0x3400, 0xa804, 0xdf1b, 0x3400, 0xa004, 0xdf1b, 0x3400, 0xa004, 0xdf1a, 0x3a40, 0xa004, 0x6769, 0x06c0, 0x2acc }, 16, 0x000b26a0, 1},
+ {{0x8009, 0x804f, 0x3400, 0xa004, 0x65e9, 0x8011, 0x3400, 0xa804, 0x7363, 0x843e, 0x94c3, 0x0915, 0xa002, 0x64e9, 0x8011, 0x3400 }, 16, 0x000b26c0, 1},
+ {{0xa004, 0x7361, 0x842c, 0x94c3, 0x0915, 0xa002, 0x65e9, 0x8011, 0x3400, 0xa004, 0x7363, 0x841a, 0x94c3, 0x0915, 0xa002, 0x6569 }, 16, 0x000b26e0, 1},
+ {{0x8011, 0x3400, 0xa004, 0x7362, 0x90c0, 0x94c3, 0x0915, 0xa002, 0x98c0, 0x6c90, 0xc290, 0x27e8, 0x9fd8, 0x94c0, 0xf241, 0xf552 }, 16, 0x000b2700, 1},
+ {{0x3620, 0xa000, 0xf554, 0xf455, 0x32e4, 0x3c8a, 0x8001, 0x3420, 0xa000, 0xf456, 0x3a20, 0xa000, 0xf5d4, 0x3cc0, 0x2abe, 0x8009 }, 16, 0x000b2720, 1},
+ {{0x3c00, 0xa004, 0x66e0, 0xf5d2, 0x3dc0, 0x2ac0, 0x8009, 0x3c80, 0xa101, 0x27eb, 0x9fea, 0x66e9, 0x27ec, 0x9fec, 0x80a4, 0x3a20 }, 16, 0x000b2740, 1},
+ {{0xa000, 0xf4d6, 0x39c0, 0x2ac2, 0x8009, 0xf28c, 0xd121, 0x90c0, 0x94c6, 0x8020, 0xc382, 0x92c2, 0xf30c, 0x98c0, 0xd521, 0x01c4 }, 16, 0x000b2760, 1},
+ {{0x2abc, 0x8009, 0x840d, 0x64e9, 0x90c0, 0x94c3, 0x0915, 0xa040, 0x3480, 0xa000, 0x5113, 0xd0a1, 0x90c0, 0x94c6, 0x801c, 0xc282 }, 16, 0x000b2780, 1},
+ {{0x3482, 0xa000, 0x4213, 0x1314, 0xd4a1, 0x840d, 0x65e9, 0x90c0, 0x94c3, 0x0915, 0xa080, 0x3480, 0xa000, 0x5314, 0xd1a1, 0x90c0 }, 16, 0x000b27a0, 1},
+ {{0x94c6, 0x801c, 0xc182, 0x3482, 0xa000, 0x4114, 0x1115, 0xd5a1, 0x840d, 0x64e9, 0x90c0, 0x94c3, 0x0915, 0xa100, 0x27ea, 0x9fee }, 16, 0x000b27c0, 1},
+ {{0x5112, 0xd0a1, 0x90c0, 0x94c6, 0x801a, 0xc282, 0x92c2, 0x4212, 0x1311, 0xd4a1, 0x840d, 0x65e9, 0x90c0, 0x94c3, 0x0915, 0xa200 }, 16, 0x000b27e0, 1},
+ {{0x3c00, 0xa800, 0x75d4, 0x3dc0, 0x2abc, 0x8009, 0xc284, 0x96c0, 0x75c3, 0x27e9, 0x9fe8, 0x3640, 0xa000, 0x511d, 0x5311, 0x3ec0 }, 16, 0x000b2800, 1},
+ {{0xa402, 0x3411, 0x8100, 0xc843, 0x3701, 0x8001, 0xc581, 0x3840, 0xa804, 0xd691, 0xf6ca, 0x8483, 0x3640, 0xa000, 0xc181, 0xf2ca }, 16, 0x000b2820, 1},
+ {{0x3a00, 0xa800, 0xd493, 0xe8fe, 0x27ea, 0x9fd8, 0x3800, 0xa004, 0xdf01, 0x64e0, 0xe81a, 0x3600, 0xa00c, 0xdd19, 0x6760, 0x3640 }, 16, 0x000b2840, 1},
+ {{0xa004, 0x7361, 0xf24a, 0x3647, 0xa000, 0x6c90, 0x5290, 0x3606, 0xb008, 0xc181, 0x75d2, 0x3800, 0xb009, 0x64e9, 0xdd85, 0x66e0 }, 16, 0x000b2860, 1},
+ {{0x3400, 0xa004, 0x65e0, 0x3e07, 0xb40a, 0x90c0, 0x71e5, 0x90c0, 0xde9a, 0x0915, 0xa004, 0x3647, 0xa000, 0x6c90, 0x4590, 0x92c2 }, 16, 0x000b2880, 1},
+ {{0xc181, 0x64e9, 0x3024, 0x2a54, 0x800b, 0x94c3, 0x0915, 0xa004, 0x3411, 0x8200, 0x2518, 0x8142, 0x3411, 0x8300, 0x2518, 0x813a }, 16, 0x000b28a0, 1},
+ {{0x3411, 0x8400, 0x2518, 0x8132, 0x3411, 0x8500, 0x80c9, 0x3411, 0x8700, 0x80c3, 0x3a40, 0xa200, 0x3411, 0x8600, 0x74d4, 0x5011 }, 16, 0x000b28c0, 1},
+ {{0x3800, 0xa040, 0x6c53, 0x2718, 0x8174, 0x33a4, 0x35b0, 0x800b, 0x3e00, 0xa207, 0x27e8, 0x9fd8, 0x77d0, 0x7c65, 0x76d0, 0xc181 }, 16, 0x000b28e0, 1},
+ {{0x3c20, 0xa904, 0x3f1b, 0x801f, 0x7c65, 0xca40, 0xc781, 0x3a00, 0xb808, 0xd493, 0x3b1d, 0x801f, 0xcc40, 0x3600, 0xa804, 0xd795 }, 16, 0x000b2900, 1},
+ {{0xeafe, 0x94c0, 0xea18, 0xecfe, 0x3620, 0xa000, 0x5692, 0xec18, 0x3400, 0xa804, 0x7456, 0x3600, 0xa004, 0xdc01, 0x64e0, 0x3400 }, 16, 0x000b2920, 1},
+ {{0xa004, 0x6460, 0x3600, 0xb004, 0x7061, 0xdc9e, 0x94c7, 0x4192, 0x6c90, 0x3646, 0xa000, 0xc181, 0x5294, 0x3600, 0xb000, 0x64e9 }, 16, 0x000b2940, 1},
+ {{0x74d2, 0x3600, 0xa808, 0xdc87, 0x67e0, 0x96c7, 0x64e0, 0x0915, 0xa004, 0x3600, 0xb808, 0x70e7, 0xdf9a, 0x3647, 0xa000, 0x6c90 }, 16, 0x000b2960, 1},
+ {{0x4794, 0x92c2, 0xc181, 0x64e9, 0x3024, 0x2a54, 0x800b, 0x94c3, 0x0915, 0xa004, 0x3820, 0xa000, 0x5611, 0x27ec, 0x9fd8, 0x3800 }, 16, 0x000b2980, 1},
+ {{0xa80c, 0x75d6, 0x7f65, 0xc181, 0x3880, 0xa804, 0x3718, 0x801f, 0xc846, 0x3400, 0xa800, 0xd490, 0xe8fe, 0xe81c, 0x3420, 0xa000 }, 16, 0x000b29a0, 1},
+ {{0x5090, 0x3400, 0xa804, 0x74d0, 0x3600, 0xa004, 0xdc81, 0x64e0, 0x3400, 0xa004, 0x64e0, 0x3600, 0xb004, 0x70e1, 0xdc98, 0x94c7 }, 16, 0x000b29c0, 1},
+ {{0x4190, 0x6c90, 0x92c2, 0xc181, 0x64e9, 0x3024, 0x2a54, 0x800b, 0x94c3, 0x0915, 0xa004, 0x3820, 0xa000, 0x5711, 0x27ea, 0x9fd8 }, 16, 0x000b29e0, 1},
+ {{0x3800, 0xa80c, 0x7557, 0x7fe5, 0xc181, 0x3880, 0xa804, 0x351f, 0x801f, 0xcc47, 0x3400, 0xa800, 0xd497, 0xecfe, 0xec1a, 0x3420 }, 16, 0x000b2a00, 1},
+ {{0xa000, 0x5594, 0x3400, 0xa804, 0x74d5, 0x3600, 0xa004, 0xdc81, 0x64e0, 0x3400, 0xa004, 0x64e0, 0x3600, 0xb004, 0x70e1, 0xdc9d }, 16, 0x000b2a20, 1},
+ {{0x94c7, 0x4194, 0x6c90, 0x92c2, 0xc181, 0x64e9, 0x90c0, 0x94c3, 0x0915, 0xa004, 0x3961, 0xe942, 0x656a, 0x2dff, 0x9dbd, 0x98c0 }, 16, 0x000b2a40, 1},
+ {{0x6c90, 0xc290, 0x27e8, 0x9fd8, 0x32e4, 0x3c8a, 0x8001, 0x94c0, 0xf241, 0xf552, 0x94c0, 0xf1d1, 0xf5d2, 0x9ac0, 0x64e9, 0xf4d5 }, 16, 0x000b2a60, 1},
+ {{0x3bc0, 0x2ac8, 0x8009, 0x94c0, 0xf288, 0x80af, 0xd121, 0x90c0, 0x94c6, 0x8022, 0xc182, 0x92c2, 0xf108, 0x98c0, 0xd521, 0x3ac0 }, 16, 0x000b2a80, 1},
+ {{0x2ac4, 0x8009, 0x840f, 0x5312, 0x65e9, 0x90c0, 0x94c3, 0x0915, 0xa400, 0x5316, 0xd1a1, 0x90c0, 0x94c6, 0x8026, 0xc282, 0x92c2 }, 16, 0x000b2aa0, 1},
+ {{0x4216, 0x98c0, 0xd5a1, 0x34c2, 0x2ac6, 0x8009, 0x8413, 0x3480, 0xa000, 0x5314, 0x65e9, 0x90c0, 0x94c3, 0x0915, 0xa800, 0x5217 }, 16, 0x000b2ac0, 1},
+ {{0xd121, 0x90c0, 0x94c6, 0x801a, 0xc182, 0x92c2, 0x4117, 0x1213, 0xd521, 0x840d, 0x6569, 0x90c0, 0x94c3, 0x0915, 0xb000, 0x3680 }, 16, 0x000b2ae0, 1},
+ {{0xa000, 0x27ee, 0x9ff6, 0x3480, 0xa000, 0x5116, 0xd0a1, 0x90c0, 0x94c6, 0x8024, 0xc282, 0x3482, 0xa000, 0x4216, 0x98c0, 0xd4a1 }, 16, 0x000b2b00, 1},
+ {{0x3ec0, 0x2aca, 0x8009, 0x840f, 0x5316, 0x65e9, 0x90c0, 0x94c3, 0x0935, 0xa000, 0x9ac0, 0x74d7, 0x3dc0, 0x2ac4, 0x8009, 0xc284 }, 16, 0x000b2b20, 1},
+ {{0x96c0, 0x74c1, 0x27e8, 0x9ff0, 0x3600, 0xa004, 0x7551, 0x90c0, 0x3640, 0xa000, 0x531d, 0xc581, 0x9ac0, 0x27e9, 0x9fd8, 0x90c0 }, 16, 0x000b2b40, 1},
+ {{0x3413, 0x8100, 0x3620, 0xa000, 0xf6ca, 0x8481, 0x3640, 0xa000, 0x5310, 0xf3ca, 0x3c00, 0xa004, 0xd693, 0x3701, 0x8001, 0xcc43 }, 16, 0x000b2b60, 1},
+ {{0xc381, 0x3800, 0xa80c, 0xdf05, 0x66e0, 0xd591, 0x3800, 0xa80c, 0xdd9d, 0x6760, 0xecfe, 0x3820, 0xa804, 0x7365, 0xec19, 0xf34a }, 16, 0x000b2b80, 1},
+ {{0x3647, 0xa004, 0x6c90, 0x5594, 0x3626, 0xb000, 0xc181, 0x74d5, 0x3800, 0xa004, 0x64e9, 0xdc83, 0x65e0, 0x64e0, 0x3e07, 0xa400 }, 16, 0x000b2ba0, 1},
+ {{0x90c0, 0x70e3, 0x90c0, 0xdd9d, 0x0915, 0xa008, 0x94c7, 0x4394, 0x6d90, 0x92c2, 0xc381, 0x65e9, 0x3024, 0x2d64, 0x800b, 0x94c3 }, 16, 0x000b2bc0, 1},
+ {{0x0915, 0xa008, 0x3413, 0x8200, 0x2518, 0x812a, 0x3413, 0x8300, 0x2518, 0x8122, 0x3413, 0x8400, 0x2518, 0x811a, 0x3413, 0x8500 }, 16, 0x000b2be0, 1},
+ {{0x80bf, 0x3413, 0x8700, 0x80b9, 0x3a40, 0xa000, 0x3413, 0x8600, 0x74d7, 0x5110, 0x3800, 0xa840, 0x6c58, 0x2718, 0x8150, 0x33a4 }, 16, 0x000b2c00, 1},
+ {{0x35b0, 0x800b, 0x3e00, 0xa206, 0x27ee, 0x9fd8, 0x75d1, 0x7ce5, 0x77d0, 0xc181, 0x3e80, 0xa406, 0x3718, 0x801f, 0xc941, 0x3f1c }, 16, 0x000b2c20, 1},
+ {{0x801f, 0xc381, 0x3800, 0xb800, 0xd490, 0xd594, 0x7c65, 0x94c0, 0xe9fe, 0xcb40, 0xe91e, 0x3620, 0xa000, 0x5791, 0xebfe, 0x3600 }, 16, 0x000b2c40, 1},
+ {{0xa804, 0x7657, 0xeb1e, 0x3600, 0xa004, 0xde01, 0x64e0, 0x3400, 0xa004, 0x6660, 0x3600, 0xb004, 0x7261, 0xdc9f, 0x94c7, 0x4191 }, 16, 0x000b2c60, 1},
+ {{0x6c90, 0x3646, 0xa000, 0xc181, 0x5093, 0x3600, 0xb000, 0x64e9, 0x74d0, 0x25e0, 0xdc83, 0x96c7, 0x64e0, 0x0915, 0xa008, 0x3600 }, 16, 0x000b2c80, 1},
+ {{0xb000, 0x70e3, 0xdd98, 0x94c7, 0x4393, 0x6d90, 0x92c2, 0xc381, 0x65e9, 0x3024, 0x2d64, 0x800b, 0x94c3, 0x0915, 0xa008, 0x96c0 }, 16, 0x000b2ca0, 1},
+ {{0x5310, 0x27e9, 0x9fd8, 0x3820, 0xa000, 0x74d3, 0x7de5, 0xc481, 0x96c0, 0x3319, 0x801f, 0xcf43, 0x3400, 0xa004, 0xd611, 0xeffe }, 16, 0x000b2cc0, 1},
+ {{0xef19, 0x5397, 0x74d3, 0x3600, 0xa808, 0xdc84, 0x6660, 0x64e0, 0x3600, 0xa808, 0x70e4, 0xde1b, 0x3647, 0xa000, 0x6c90, 0x4497 }, 16, 0x000b2ce0, 1},
+ {{0x92c2, 0xc181, 0x64e9, 0x3024, 0x2d64, 0x800b, 0x94c3, 0x0915, 0xa008, 0x3820, 0xa000, 0x5610, 0x27eb, 0x9fd8, 0x3800, 0xa808 }, 16, 0x000b2d00, 1},
+ {{0x75d6, 0x7f65, 0xc181, 0x3880, 0xa000, 0x371b, 0x801f, 0xcf46, 0xd493, 0xeffe, 0xef1b, 0x3420, 0xa000, 0x5397, 0x3400, 0xa800 }, 16, 0x000b2d20, 1},
+ {{0x75d3, 0x24e0, 0xdd81, 0x65e0, 0x3600, 0xb000, 0x71e1, 0xdc9b, 0x94c7, 0x4197, 0x6d90, 0x92c2, 0xc381, 0x65e9, 0x90c0, 0x94c3 }, 16, 0x000b2d40, 1},
+ {{0x0915, 0xa008, 0x3961, 0xe842, 0x656a, 0x2dff, 0x9de7, 0x94c0, 0xd722, 0xf0d3, 0x840d, 0xd624, 0x90c0, 0x94c2, 0x0995, 0xa000 }, 16, 0x000b2d60, 1},
+ {{0x9cc0, 0x3b1f, 0x8018, 0x6c90, 0x3b1a, 0x80c0, 0x934c, 0x9ac0, 0x3b0c, 0x8010, 0x67e9, 0x3b0e, 0x8020, 0x9cc0, 0x6660, 0x2b03 }, 16, 0x000b2d80, 1},
+ {{0x8036, 0x6760, 0x27ee, 0x9fc0, 0x96c7, 0x6569, 0x20c0, 0x8001, 0x90c0, 0x96c7, 0x6669, 0x09c0, 0xa002, 0x92c3, 0x7470, 0x96c7 }, 16, 0x000b2da0, 1},
+ {{0x6769, 0x09c0, 0xa004, 0x92c3, 0x7470, 0x94c3, 0x09c0, 0xa008, 0x1416, 0x33e0, 0x3f00, 0x8003, 0x9ec0, 0x392e, 0x9fcc, 0x6669 }, 16, 0x000b2dc0, 1},
+ {{0x391f, 0x8004, 0xdd84, 0xee42, 0x96c0, 0x391a, 0x8003, 0x8055, 0x98c0, 0x65e9, 0x391c, 0x8020, 0x7cc9, 0x92c3, 0x7470, 0x96c7 }, 16, 0x000b2de0, 1},
+ {{0x6769, 0x09a0, 0xa010, 0x92c3, 0x7470, 0x96c7, 0x67e9, 0x09a0, 0xa100, 0x92c3, 0x7470, 0x96c7, 0x6669, 0x09a0, 0xa020, 0x92c3 }, 16, 0x000b2e00, 1},
+ {{0x7470, 0x96c7, 0x6569, 0x09a0, 0xa040, 0x92c3, 0x7470, 0x94c3, 0x09a0, 0xa080, 0x96c0, 0xdc19, 0x2003, 0x8010, 0x92d0, 0x78c1 }, 16, 0x000b2e20, 1},
+ {{0x90c0, 0x90c0, 0x98c0, 0x27eb, 0x9fc2, 0x7470, 0xf1a0, 0x3cc8, 0x161b, 0x3900, 0x20c0, 0x8008, 0x3d1f, 0x80ff, 0x98c0, 0xdf99 }, 16, 0x000b2e40, 1},
+ {{0x3a00, 0x20c2, 0x8008, 0x0711, 0x3302, 0x20ca, 0x8008, 0x90c0, 0x141b, 0x3900, 0x20c4, 0x8008, 0x3e48, 0x111b, 0x3d00, 0x20c6 }, 16, 0x000b2e60, 1},
+ {{0x8008, 0x331b, 0x80ff, 0x98c0, 0xdd9c, 0x3102, 0x20c8, 0x8008, 0x0312, 0x3a00, 0x20cc, 0x8008, 0x521b, 0x3d48, 0x571b, 0x3f1e }, 16, 0x000b2e80, 1},
+ {{0x80ff, 0xdf1a, 0x4611, 0x96c0, 0x571b, 0x27e9, 0x9fa8, 0x3fc8, 0x561b, 0x3d19, 0x80ff, 0xdc9f, 0x4115, 0x511b, 0x3cc8, 0x571b }, 16, 0x000b2ea0, 1},
+ {{0x3f1b, 0x80ff, 0xdd99, 0x3480, 0xa000, 0x4311, 0x511b, 0x3cc8, 0x5713, 0x96c0, 0x3f1a, 0x80ff, 0xe7e9, 0x96c0, 0xdd19, 0x9e21 }, 16, 0x000b2ec0, 1},
+ {{0x9f21, 0x3480, 0xa000, 0x4213, 0x94c0, 0x9621, 0x9721, 0x9f70, 0x4592, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20 }, 16, 0x000b2ee0, 1},
+ {{0x96c0, 0x5d98, 0x2a03, 0x806c, 0x1998, 0x1005, 0xa03f, 0x5a98, 0x5c98, 0x3420, 0xa000, 0x5318, 0x3600, 0xa004, 0x7de2, 0xeeec }, 16, 0x000b2f00, 1},
+ {{0x3420, 0xa000, 0x9a43, 0x545a, 0x555a, 0x565a, 0x575a, 0x3420, 0xa000, 0x5052, 0x1059, 0x535c, 0x3600, 0xa004, 0x63a0, 0x5159 }, 16, 0x000b2f20, 1},
+ {{0x3800, 0xa00c, 0x6324, 0x638d, 0x525c, 0x3800, 0xa00c, 0x6301, 0x638a, 0x5259, 0x3420, 0xa000, 0x555c, 0x3a00, 0xa21d, 0x62a8 }, 16, 0x000b2f40, 1},
+ {{0x630e, 0x63c1, 0x5359, 0x3420, 0xa000, 0x545c, 0x3a00, 0xa23f, 0x622c, 0x6285, 0x6340, 0x63d7, 0x3400, 0xa844, 0x63e3, 0x3c20 }, 16, 0x000b2f60, 1},
+ {{0xa20d, 0x6209, 0x6282, 0x6b6b, 0x5059, 0x972d, 0x3400, 0xa844, 0x6f5e, 0x3c20, 0xa21d, 0x63a0, 0x6206, 0x62c3, 0x5159, 0x962d }, 16, 0x000b2f80, 1},
+ {{0x3a00, 0xa23f, 0x6324, 0x638d, 0x6242, 0x62df, 0x3400, 0xa844, 0x62e2, 0x3c30, 0xa01d, 0x6301, 0x638a, 0x625b, 0x5259, 0x952d }, 16, 0x000b2fa0, 1},
+ {{0x3400, 0xa844, 0x6e54, 0x3c20, 0xa21d, 0x62a8, 0x630e, 0x63c1, 0x5359, 0x942d, 0xecee, 0x08f1, 0x9ff6, 0x96c0, 0x902c, 0x09f1 }, 16, 0x000b2fc0, 1},
+ {{0x9ff4, 0x96c0, 0x912c, 0x08f5, 0x9ffc, 0x96c0, 0x902c, 0x09f5, 0x9ffe, 0x993c, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721 }, 16, 0x000b2fe0, 1},
+ {{0x94c0, 0x9f70, 0xf3c1, 0xc563, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x6c90, 0x9248, 0x2a03, 0x803a, 0x96c0, 0x6f10, 0x9620 }, 16, 0x000b3000, 1},
+ {{0x9720, 0x94c0, 0x4110, 0x9f20, 0x9ac0, 0x280a, 0x801c, 0x90c0, 0x280c, 0x8004, 0x3718, 0x2000, 0x8000, 0x9ac0, 0x2808, 0x8038 }, 16, 0x000b3020, 1},
+ {{0x90c0, 0x2b02, 0x801c, 0x2a02, 0x800e, 0x9742, 0x96c0, 0x4638, 0x2902, 0x8002, 0x96c0, 0xe9ea, 0x2a0b, 0x8004, 0x94c8, 0x46a9 }, 16, 0x000b3040, 1},
+ {{0x46ab, 0x9743, 0x9ac0, 0x2902, 0x8002, 0x90c0, 0x2c0f, 0x8004, 0xedec, 0x94d8, 0x46ad, 0x46af, 0x96c0, 0x47b4, 0x2a0a, 0x8038 }, 16, 0x000b3060, 1},
+ {{0x90c0, 0x2d10, 0x01c6, 0x2eac, 0x8009, 0x24e8, 0x3361, 0x3ed8, 0x8648, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff }, 16, 0x000b3080, 1},
+ {{0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x9ac0, 0x6c10, 0x9f21, 0x01c2, 0x2ea8, 0x8009, 0x94c0 }, 16, 0x000b30a0, 1},
+ {{0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x9ac0, 0x280e }, 16, 0x000b30c0, 1},
+ {{0x802c, 0x90c0, 0x270b, 0x8198, 0x3800, 0xa100, 0xe7eb, 0x2e09, 0x8004, 0x36e0, 0xa100, 0xece9, 0x5011, 0x3c00, 0xa900, 0x75d0 }, 16, 0x000b30e0, 1},
+ {{0xec62, 0x06c6, 0x2eb0, 0x8009, 0x3800, 0xa100, 0x74d6, 0x5214, 0xf87f, 0x3c40, 0xa000, 0x01fa, 0x9f00, 0xda12, 0x00f8, 0x9efc }, 16, 0x000b3100, 1},
+ {{0x3dd8, 0x04f8, 0x9ef8, 0x65e1, 0x65e8, 0x92c2, 0x6d10, 0x94c7, 0x6768, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3 }, 16, 0x000b3120, 1},
+ {{0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3a00, 0xa004, 0x7551, 0x3cc0, 0x2e54 }, 16, 0x000b3140, 1},
+ {{0x8009, 0x3800, 0xa004, 0x6561, 0x27eb, 0x9f30, 0x3600, 0xa004, 0x6569, 0x509c, 0x2418, 0x8874, 0x3822, 0xa000, 0x3700, 0x2000 }, 16, 0x000b3160, 1},
+ {{0x8100, 0x9746, 0x90c0, 0x94c8, 0x409b, 0x509c, 0x2c10, 0x0093, 0x3300, 0x2005, 0x8a00, 0x3100, 0x2000, 0x8200, 0x35c3, 0x7841 }, 16, 0x000b3180, 1},
+ {{0x71f1, 0x81fb, 0x98c0, 0x3cc0, 0x2e8c, 0x8009, 0x9744, 0x27ea, 0x9f4c, 0x519c, 0x94c8, 0x419a, 0x519c, 0x3c58, 0x0192, 0x3200 }, 16, 0x000b31a0, 1},
+ {{0x2000, 0x8100, 0x3c00, 0xa008, 0x6461, 0x6c9d, 0x3361, 0x3218, 0x80b1, 0x3c40, 0xa000, 0x6468, 0x6d10, 0x74d0, 0x02f8, 0x9ef4 }, 16, 0x000b31c0, 1},
+ {{0x3846, 0xa000, 0x6c10, 0x01f8, 0x9ef0, 0x32e4, 0x3d62, 0x8001, 0x92c3, 0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86 }, 16, 0x000b31e0, 1},
+ {{0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3a20, 0xa001, 0x11f8, 0x9ef0, 0x7651, 0xc598, 0x3c20, 0xa006, 0x64e8, 0x27eb, 0x9f44, 0x6661 }, 16, 0x000b3200, 1},
+ {{0xf167, 0x3800, 0xa804, 0xd641, 0xe9eb, 0xeceb, 0x98c1, 0x66e8, 0x66e8, 0xc0ff, 0x6c10, 0x94c6, 0xf565, 0x6d10, 0x94c7, 0xec70 }, 16, 0x000b3220, 1},
+ {{0xc2ff, 0x94c0, 0xe968, 0xf3e5, 0x96c0, 0x65e0, 0xf1e7, 0xf266, 0x3820, 0xa000, 0x64e0, 0xf068, 0x5594, 0x3620, 0xa000, 0x5391 }, 16, 0x000b3240, 1},
+ {{0xf0e8, 0x3840, 0xa000, 0xf2e6, 0x04f8, 0x9eec, 0x3c40, 0xa000, 0x0bf8, 0x9ee8, 0x90c0, 0x03f8, 0x9ee4, 0x32e4, 0x3d8c, 0x8001 }, 16, 0x000b3260, 1},
+ {{0x3840, 0xa000, 0x5f93, 0x05f8, 0x9ee0, 0x3300, 0x2000, 0x8200, 0x3620, 0xa000, 0x11f8, 0x9ef0, 0x3400, 0xa800, 0xd5c1, 0x65e8 }, 16, 0x000b3280, 1},
+ {{0x98c6, 0x32e4, 0x3d74, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x77d1, 0x67e1, 0x96c0, 0x67e8, 0xf763, 0xf761, 0x94c6, 0xf1e1, 0x6c10 }, 16, 0x000b32a0, 1},
+ {{0x9ac7, 0xf3e3, 0x90c0, 0x67e8, 0xc0ff, 0x64e0, 0x96c6, 0x65e0, 0x6d10, 0xf064, 0x92c3, 0xc2ff, 0x94c0, 0xf262, 0xf2e4, 0x32e4 }, 16, 0x000b32c0, 1},
+ {{0x3d62, 0x8001, 0xf0e2, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x7751, 0x6761, 0x96c0 }, 16, 0x000b32e0, 1},
+ {{0x6768, 0xf65f, 0xf65d, 0x94c6, 0xf1dd, 0x6c10, 0x9ac7, 0xf3df, 0x90c0, 0x6768, 0xc0ff, 0x64e0, 0x96c6, 0x65e0, 0x6d10, 0xf060 }, 16, 0x000b3300, 1},
+ {{0x92c3, 0xc2ff, 0x94c0, 0xf25e, 0xf2e0, 0x32e4, 0x3d62, 0x8001, 0xf0de, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001 }, 16, 0x000b3320, 1},
+ {{0x6d10, 0x92c3, 0xc2ff, 0x3600, 0xa104, 0x77d1, 0xcf4e, 0x3640, 0xa004, 0x67e1, 0xf659, 0x3840, 0xa004, 0x67e8, 0xf75b, 0xf1d9 }, 16, 0x000b3340, 1},
+ {{0x96c6, 0x64e0, 0x6c10, 0xf3db, 0x3e47, 0xa002, 0x90c0, 0x07f8, 0x9edc, 0x6768, 0xc0ff, 0x65e0, 0x94c6, 0xf05c, 0x6d10, 0x92c3 }, 16, 0x000b3360, 1},
+ {{0xc2ff, 0x94c0, 0xf25a, 0xf2dc, 0x32e4, 0x3d62, 0x8001, 0xf0da, 0x3550, 0xc598, 0x26e8, 0xf557, 0x94c6, 0xf3d7, 0x6c10, 0x94c7 }, 16, 0x000b3380, 1},
+ {{0x65e0, 0xc0ff, 0x9ac0, 0x7452, 0xf058, 0x32e4, 0x3d86, 0x8001, 0xf2d8, 0x3c60, 0xa000, 0x17f8, 0x9edc, 0x64e1, 0x13f8, 0x9ee4 }, 16, 0x000b33a0, 1},
+ {{0x3820, 0xb004, 0x67e8, 0x6cd9, 0xf755, 0x94c6, 0xf3d5, 0x6d10, 0x96c7, 0x64e8, 0xc2ff, 0x65e0, 0x94c6, 0xf256, 0x6c10, 0x32e4 }, 16, 0x000b33c0, 1},
+ {{0x3d62, 0x8001, 0x94c7, 0xf2d6, 0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3c60 }, 16, 0x000b33e0, 1},
+ {{0xa000, 0x17f8, 0x9edc, 0x7551, 0x15f8, 0x9ee0, 0x3820, 0xa004, 0x67e8, 0x6561, 0xf753, 0x3600, 0xa800, 0x6cc9, 0xf3d3, 0x98c1 }, 16, 0x000b3400, 1},
+ {{0x64e8, 0x64e8, 0xc0ff, 0x6c10, 0x96c6, 0x65e0, 0x6c10, 0xf054, 0x32e4, 0x3d62, 0x8001, 0x94c7, 0xf2d4, 0xc0ff, 0xc598, 0x26e8 }, 16, 0x000b3420, 1},
+ {{0xf551, 0x94c6, 0xf3d1, 0x6d10, 0x94c7, 0x65e0, 0xc2ff, 0x98c0, 0xf252, 0x32e4, 0x3d86, 0x8001, 0xf2d2, 0x3c40, 0xa001, 0x1bf8 }, 16, 0x000b3440, 1},
+ {{0x9ee8, 0x75d1, 0x17f8, 0x9edc, 0x3a20, 0xb004, 0x67e8, 0x75d7, 0x03f8, 0x9ed8, 0x94c6, 0xeb44, 0x6d10, 0x94c7, 0x5193, 0xc2ff }, 16, 0x000b3460, 1},
+ {{0x24e8, 0x0bf8, 0x9ee8, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0x3550, 0xc598, 0x26e8, 0xf54f, 0x94c6, 0xf3cf }, 16, 0x000b3480, 1},
+ {{0x6c10, 0x94c7, 0x65e0, 0xc0ff, 0x9ac0, 0x7452, 0xf050, 0x32e4, 0x3d86, 0x8001, 0xf2d0, 0x3c40, 0xa000, 0x1bf8, 0x9ee8, 0x64e1 }, 16, 0x000b34a0, 1},
+ {{0x17f8, 0x9edc, 0x3640, 0xa004, 0x67e8, 0xf74d, 0x94c0, 0xefeb, 0xf3cd, 0x96c7, 0x65e0, 0xc2ff, 0xef68, 0x3420, 0xa000, 0x5697 }, 16, 0x000b34c0, 1},
+ {{0x3400, 0xa800, 0x6cc6, 0x96c6, 0x64e8, 0x6d10, 0xf14b, 0x94c6, 0xf24e, 0x6c10, 0x94c7, 0xf1cb, 0xc0ff, 0x96c0, 0x64e0, 0xf04c }, 16, 0x000b34e0, 1},
+ {{0xf2ce, 0x32e4, 0x3d62, 0x8001, 0xf0cc, 0xc598, 0x26e8, 0xf549, 0x94c6, 0xf3c9, 0x6d10, 0x94c7, 0x65e0, 0xc2ff, 0x98c0, 0xf24a }, 16, 0x000b3500, 1},
+ {{0x32e4, 0x3d86, 0x8001, 0xf2ca, 0x3c40, 0xa001, 0x1bf8, 0x9ee8, 0x76d1, 0x17f8, 0x9edc, 0x3820, 0xa00c, 0x67e8, 0x66e1, 0xf747 }, 16, 0x000b3520, 1},
+ {{0xeb70, 0x94c7, 0x5293, 0xc0ff, 0x3400, 0xa800, 0x6dc9, 0x96c6, 0x65e8, 0x6c10, 0xf345, 0x94c6, 0xf048, 0x6d10, 0x94c7, 0xf1c5 }, 16, 0x000b3540, 1},
+ {{0xc2ff, 0x96c0, 0x64e0, 0xf246, 0xf3c7, 0x32e4, 0x3d62, 0x8001, 0x96c0, 0x65e0, 0xf2c8, 0xf0c6, 0xc598, 0x26e8, 0x75d5, 0x98c6 }, 16, 0x000b3560, 1},
+ {{0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3a40, 0xa000, 0x6768, 0x64e1, 0x75d6, 0xf7f4, 0x3400, 0xa800, 0x6cc7, 0x98c1 }, 16, 0x000b3580, 1},
+ {{0x64e8, 0x64e8, 0xc2ff, 0x6d10, 0x94c6, 0xf143, 0x6c10, 0x94c7, 0xf1c3, 0xc0ff, 0x9ac0, 0x64e0, 0xf044, 0x32e4, 0x3d62, 0x8001 }, 16, 0x000b35a0, 1},
+ {{0xf0c4, 0xc598, 0x26e8, 0xf541, 0x94c6, 0xf3c1, 0x6d10, 0x94c7, 0x65e0, 0xc2ff, 0x98c0, 0xf242, 0x32e4, 0x3d86, 0x8001, 0xf2c2 }, 16, 0x000b35c0, 1},
+ {{0x3e60, 0xa000, 0x64e1, 0x13f8, 0x9ed8, 0x67e8, 0x11f8, 0x9ef0, 0x3600, 0xb000, 0x75d7, 0x6fd9, 0x3607, 0xb000, 0xc2ff, 0x6ca7 }, 16, 0x000b35e0, 1},
+ {{0x94c6, 0x64e8, 0x6d10, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86 }, 16, 0x000b3600, 1},
+ {{0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3c60, 0xa000, 0x14f8, 0x9eec, 0x7551, 0x12f8, 0x9ef4, 0x3600, 0xb000, 0x6561, 0x74d2, 0x3400 }, 16, 0x000b3620, 1},
+ {{0xa800, 0x6d88, 0x65e8, 0x92c2, 0x6d10, 0x3607, 0xa008, 0xc2ff, 0x6568, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff }, 16, 0x000b3640, 1},
+ {{0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3751, 0x3141, 0x3477, 0x8171, 0x6761, 0x2769, 0x75d6 }, 16, 0x000b3660, 1},
+ {{0x2418, 0x8368, 0x3822, 0xa000, 0x3700, 0x2000, 0x8100, 0x6768, 0x92c3, 0x65e4, 0x65e8, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6d10 }, 16, 0x000b3680, 1},
+ {{0x94c7, 0x6c10, 0xc2ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x37d1, 0x2768, 0x3200 }, 16, 0x000b36a0, 1},
+ {{0x2000, 0x8080, 0x27e1, 0x3161, 0x3218, 0x80b1, 0x6fcb, 0x3600, 0xa004, 0x3fe9, 0x9f00, 0x3403, 0xa004, 0x64e4, 0x3880, 0xb004 }, 16, 0x000b36c0, 1},
+ {{0x64e8, 0x75d1, 0xcf41, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6d10, 0x94c7, 0x6c10, 0xc2ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4 }, 16, 0x000b36e0, 1},
+ {{0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x37d1, 0x3101, 0x2000, 0x8200, 0x67e1, 0x3400, 0xa004, 0x6e3f, 0x3a20, 0xb004, 0x6668 }, 16, 0x000b3700, 1},
+ {{0x75d4, 0x04f8, 0x9ed4, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6d10, 0x94c7, 0x6c10, 0xc2ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4 }, 16, 0x000b3720, 1},
+ {{0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x24e1, 0xc598, 0x24e8, 0x75d5, 0x92c2, 0x6c10, 0x94c7, 0x66e8, 0xc0ff, 0x98c6, 0x32e4 }, 16, 0x000b3740, 1},
+ {{0x3d8c, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3e40, 0xa000, 0x77d0, 0x14f8, 0x9ed4, 0x7751, 0x27ea, 0x9f5c, 0x3c00, 0xb204, 0x6668 }, 16, 0x000b3760, 1},
+ {{0x75d4, 0x74d4, 0xe9ea, 0xecea, 0x3646, 0xa000, 0x6d10, 0x5792, 0x3a07, 0xa002, 0x90c0, 0xec68, 0xc2ff, 0x6668, 0x94c0, 0xe964 }, 16, 0x000b3780, 1},
+ {{0xea6c, 0x3660, 0xa000, 0x5394, 0x5592, 0x3860, 0xa000, 0x5291, 0x07f8, 0x9ed0, 0x3847, 0xa000, 0xc0ff, 0x02f8, 0x9ecc, 0x3846 }, 16, 0x000b37a0, 1},
+ {{0xa000, 0x6c10, 0x03f8, 0x9ec8, 0x32e4, 0x3d62, 0x8001, 0x3620, 0xa000, 0x05f8, 0x9ec4, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4 }, 16, 0x000b37c0, 1},
+ {{0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3840, 0xa004, 0x7751, 0x17f8, 0x9ed0, 0x3600, 0xb004, 0x6761, 0x74d7, 0x3a20, 0xb004 }, 16, 0x000b37e0, 1},
+ {{0x6768, 0x75d6, 0x06f8, 0x9ec0, 0x92c2, 0x6d10, 0x3607, 0xa008, 0xc2ff, 0x67e8, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3 }, 16, 0x000b3800, 1},
+ {{0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3c60, 0xa000, 0x16f8, 0x9ec0, 0x64e1 }, 16, 0x000b3820, 1},
+ {{0x12f8, 0x9ecc, 0x3800, 0xb204, 0x6768, 0x6cd8, 0x75d6, 0x92c2, 0x6d10, 0x94c7, 0x64e8, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001 }, 16, 0x000b3840, 1},
+ {{0x6c10, 0x92c3, 0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3c60, 0xa000, 0x16f8 }, 16, 0x000b3860, 1},
+ {{0x9ec0, 0x64e1, 0x13f8, 0x9ec8, 0x3800, 0xb204, 0x6768, 0x6cd9, 0x75d6, 0x92c2, 0x6d10, 0x94c7, 0x64e8, 0xc2ff, 0x98c6, 0x32e4 }, 16, 0x000b3880, 1},
+ {{0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3c60 }, 16, 0x000b38a0, 1},
+ {{0xa000, 0x16f8, 0x9ec0, 0x64e1, 0x15f8, 0x9ec4, 0x3800, 0xb204, 0x6768, 0x6cc5, 0x75d6, 0x92c2, 0x6d10, 0x94c7, 0x64e8, 0xc2ff }, 16, 0x000b38c0, 1},
+ {{0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0x3550, 0xc598, 0x26e8, 0xf573, 0x94c6, 0xf3f3, 0x6c10, 0x94c7, 0x65e0 }, 16, 0x000b38e0, 1},
+ {{0xc0ff, 0x9ac0, 0x7452, 0xf074, 0x32e4, 0x3d86, 0x8001, 0xf2f4, 0x3a20, 0xa000, 0x16f8, 0x9ec0, 0x64e1, 0xf2ed, 0x3800, 0xa204 }, 16, 0x000b3900, 1},
+ {{0x6768, 0x6cd8, 0x75d6, 0x92c2, 0x6d10, 0x94c7, 0x64e8, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc598 }, 16, 0x000b3920, 1},
+ {{0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3c40, 0xa000, 0x7457, 0x77d1, 0x6760, 0x14f8, 0x9ed4 }, 16, 0x000b3940, 1},
+ {{0x34d6, 0x27e1, 0x3600, 0x2000, 0x8200, 0x6fdf, 0x3400, 0xa040, 0x6d97, 0x65e8, 0x98c6, 0x32e4, 0x3d74, 0x8001, 0x6d10, 0x92c3 }, 16, 0x000b3960, 1},
+ {{0xc2ff, 0x3c00, 0xa100, 0x64e1, 0xcf49, 0x3300, 0x2000, 0x8100, 0x3600, 0xa004, 0x64e8, 0x6ed9, 0x3607, 0xa004, 0x64e4, 0x74d5 }, 16, 0x000b3980, 1},
+ {{0x3400, 0xa004, 0x7cf8, 0x3601, 0xb800, 0xd591, 0xd599, 0x65e1, 0x65e8, 0x92c2, 0x6d10, 0x94c7, 0x66e8, 0xc2ff, 0x98c6, 0x32e4 }, 16, 0x000b39a0, 1},
+ {{0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3400, 0xa004 }, 16, 0x000b39c0, 1},
+ {{0x77d1, 0x3400, 0xa004, 0x67e1, 0x3a40, 0xa000, 0x07c6, 0x2ea8, 0x8009, 0x5116, 0x3c00, 0xac00, 0x34e2, 0x8001, 0xc581, 0x36e6 }, 16, 0x000b39e0, 1},
+ {{0x8001, 0x3600, 0xa800, 0x30e2, 0x8001, 0x98c0, 0xd812, 0x07c6, 0x2ea0, 0x8009, 0x9ac0, 0xd446, 0xf774, 0x07c6, 0x2ea4, 0x8009 }, 16, 0x000b3a00, 1},
+ {{0x96c0, 0x6461, 0xf072, 0xf773, 0x32e4, 0x3c5a, 0x8001, 0x3160, 0x3ed8, 0x8648, 0x2468, 0x37d0, 0x3600, 0x3fb6, 0x8192, 0x90c0 }, 16, 0x000b3a20, 1},
+ {{0x96c3, 0x3260, 0x3ed8, 0x8648, 0x92c3, 0xd7c2, 0x33f6, 0x3620, 0x3f6c, 0x8324, 0x840b, 0x73f6, 0x94c7, 0x843b, 0x6fbf, 0x3620 }, 16, 0x000b3a40, 1},
+ {{0x3f6c, 0x8324, 0x33f6, 0x3240, 0x3f22, 0x84b6, 0x840f, 0x73f2, 0x94c7, 0x8422, 0x6f9f, 0x92c3, 0xc5ff, 0x3240, 0x3f22, 0x84b6 }, 16, 0x000b3a60, 1},
+ {{0x73f2, 0x90c0, 0x98c2, 0x3260, 0x3ed8, 0x8648, 0xc5ff, 0x92c2, 0x6fab, 0x3e20, 0xa000, 0x07f8, 0x9ebc, 0x67e8, 0x75d7, 0x74d7 }, 16, 0x000b3a80, 1},
+ {{0xcf45, 0x92c2, 0x6d10, 0x94c7, 0x67e8, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc398, 0x65e8, 0x98c6 }, 16, 0x000b3aa0, 1},
+ {{0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3751, 0xf3f4, 0x25e8, 0x6761, 0x94c6, 0x74d6, 0x6d10, 0x94c7, 0x6768, 0xc2ff }, 16, 0x000b3ac0, 1},
+ {{0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff }, 16, 0x000b3ae0, 1},
+ {{0x3a00, 0xa004, 0x75d1, 0x74d6, 0x27ec, 0x9f34, 0x3600, 0xa004, 0x65e1, 0x5294, 0x3400, 0xa800, 0x6d9d, 0x65e8, 0x92c2, 0x6d10 }, 16, 0x000b3b00, 1},
+ {{0x94c7, 0x6768, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001 }, 16, 0x000b3b20, 1},
+ {{0x6d10, 0x92c3, 0xc2ff, 0x3551, 0x34d7, 0x3600, 0x2000, 0x8100, 0x6561, 0x6dca, 0x65e8, 0x92c2, 0x6d10, 0x94c7, 0x67e8, 0xc2ff }, 16, 0x000b3b40, 1},
+ {{0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc698, 0x2768, 0x75d6, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3 }, 16, 0x000b3b60, 1},
+ {{0xc2ff, 0x3c20, 0xa004, 0x76d1, 0xcf4d, 0x03c6, 0x2ea0, 0x8009, 0x3860, 0xa004, 0x66e1, 0xf371, 0xf2f2, 0x3c00, 0xac06, 0x34a6 }, 16, 0x000b3b80, 1},
+ {{0x8005, 0xc781, 0x36a3, 0x8005, 0x3600, 0xa804, 0x30a6, 0x8005, 0x3a00, 0xa804, 0xdb16, 0x3200, 0x3fb6, 0x8192, 0x3a40, 0xa804 }, 16, 0x000b3ba0, 1},
+ {{0xd743, 0x01c6, 0x2ea4, 0x8009, 0x32e4, 0x3c5a, 0x8001, 0x3c40, 0xa040, 0x6c3c, 0xf170, 0x3160, 0x3ed8, 0x8648, 0x2468, 0x76d0 }, 16, 0x000b3bc0, 1},
+ {{0x90c0, 0x3823, 0xa000, 0x3560, 0x3ed8, 0x8648, 0x3403, 0xa800, 0xd6c5, 0x32f2, 0x3220, 0x3f6c, 0x8324, 0x840b, 0x72f2, 0x94c7 }, 16, 0x000b3be0, 1},
+ {{0x8445, 0x6ea9, 0x3820, 0xa000, 0x3220, 0x3f6c, 0x8324, 0x3a00, 0xa800, 0x72f2, 0x3240, 0x3f22, 0x84b6, 0x8411, 0x72f2, 0x3607 }, 16, 0x000b3c00, 1},
+ {{0xa040, 0x6e89, 0x8424, 0x92c3, 0xc7ff, 0x3240, 0x3f22, 0x84b6, 0x72f2, 0x90c0, 0x98c2, 0x3260, 0x3ed8, 0x8648, 0xc7ff, 0x92c2 }, 16, 0x000b3c20, 1},
+ {{0x6ea9, 0x3c40, 0xa000, 0x66e8, 0x75d5, 0x74d5, 0xf67c, 0xcf45, 0x92c2, 0x6d10, 0x94c7, 0x66e8, 0xc2ff, 0x98c6, 0x32e4, 0x3d62 }, 16, 0x000b3c40, 1},
+ {{0x8001, 0x6c10, 0x92c3, 0xc0ff, 0x2768, 0x75d6, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3600, 0xa004, 0x75d1 }, 16, 0x000b3c60, 1},
+ {{0xf3f1, 0x3600, 0xa008, 0x65e8, 0x65e1, 0x3a46, 0xa400, 0x6d10, 0x03f8, 0x9eb8, 0x74d3, 0x3607, 0xa008, 0xc2ff, 0x65e8, 0x98c6 }, 16, 0x000b3c80, 1},
+ {{0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0x2768, 0x75d6, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3c40 }, 16, 0x000b3ca0, 1},
+ {{0xa001, 0x27ea, 0x9f40, 0x74d1, 0x13f8, 0x9eb8, 0x3800, 0xb004, 0x64e1, 0x74d3, 0x5292, 0x3400, 0xa800, 0x6db8, 0x65e8, 0x92c2 }, 16, 0x000b3cc0, 1},
+ {{0x6d10, 0x3607, 0xa008, 0xc2ff, 0x65e8, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0x2768, 0x75d6, 0x98c6, 0x32e4 }, 16, 0x000b3ce0, 1},
+ {{0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x9ac0, 0x7751, 0x3200, 0x2000, 0x8100, 0xcf4d, 0x2761, 0x74d5, 0x6dca, 0x65e8, 0x92c2 }, 16, 0x000b3d00, 1},
+ {{0x6d10, 0x94c7, 0x66e8, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86 }, 16, 0x000b3d20, 1},
+ {{0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3840, 0xa004, 0x7551, 0xf6fc, 0xc598, 0x3a00, 0xa40c, 0x6561, 0x6768, 0x75d5, 0x74d6, 0x3c00 }, 16, 0x000b3d40, 1},
+ {{0xac00, 0x34e2, 0x8002, 0x90c0, 0x36e6, 0x8002, 0x3807, 0xb000, 0xc0ff, 0x30e2, 0x8002, 0x3400, 0xa004, 0xd912, 0x3400, 0xa004 }, 16, 0x000b3d60, 1},
+ {{0xd546, 0x3a46, 0xa000, 0x90c0, 0xf27e, 0x6c10, 0x66e8, 0x98c6, 0x32e4, 0x3d8c, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3a00, 0xa00c }, 16, 0x000b3d80, 1},
+ {{0x7650, 0x76d1, 0x14f8, 0x9ef8, 0x3e00, 0xa200, 0x6668, 0x75d4, 0x77d5, 0x3101, 0x2000, 0x8200, 0x3e06, 0xb000, 0x90c0, 0x32e4 }, 16, 0x000b3da0, 1},
+ {{0x3d62, 0x8001, 0x6d10, 0x7754, 0x94c7, 0x6c10, 0xc2ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3 }, 16, 0x000b3dc0, 1},
+ {{0xc2ff, 0x3800, 0xa008, 0x7651, 0x76d7, 0x7456, 0x3600, 0xa008, 0x6661, 0x66e0, 0x3c00, 0xa600, 0x6668, 0x75d4, 0x74d5, 0x77d5 }, 16, 0x000b3de0, 1},
+ {{0xcf44, 0x98c6, 0x32e4, 0x3d74, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3e00, 0xa003, 0x11fa, 0x9f00, 0x7656, 0x76d7, 0x7751, 0xca89 }, 16, 0x000b3e00, 1},
+ {{0x3c60, 0xa004, 0x66e0, 0x10f8, 0x9efc, 0x6761, 0xf2fe, 0x38c0, 0xa000, 0xe942, 0x17f8, 0x9ebc, 0x3680, 0xa000, 0x5d11, 0xcf4c }, 16, 0x000b3e20, 1},
+ {{0x98c0, 0xc598, 0x3bc0, 0x2e2c, 0x8009, 0xed61, 0xed8a, 0x96c0, 0xedfe, 0x2518, 0x8c24, 0x9cc0, 0x6668, 0x75d4, 0xed1b, 0x3900 }, 16, 0x000b3e40, 1},
+ {{0x2000, 0x8100, 0x3600, 0xa100, 0x5d95, 0xcb42, 0x96c0, 0xc0ff, 0x27ef, 0x9f1c, 0x94c0, 0xe93b, 0x9d61, 0x3c00, 0xa004, 0x6561 }, 16, 0x000b3e60, 1},
+ {{0xc94c, 0x3500, 0x2000, 0x8100, 0x3e00, 0xa208, 0x77c4, 0x6568, 0x75d2, 0x3119, 0x2000, 0xbe00, 0x98c0, 0xd6c6, 0xf77a, 0x01fa }, 16, 0x000b3e80, 1},
+ {{0x9f00, 0x94c6, 0x449f, 0x6d10, 0x94c7, 0x4797, 0xc2ff, 0xef4c, 0x0597, 0xedef, 0x98c0, 0xed68, 0x32e4, 0x3d62, 0x8001, 0xcd4f }, 16, 0x000b3ea0, 1},
+ {{0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x98c0, 0xcd47, 0x3700, 0x2000, 0x8100, 0x98c0, 0x6e9f }, 16, 0x000b3ec0, 1},
+ {{0xef64, 0x11fa, 0x9f00, 0x3044, 0x2a72, 0x800b, 0x0597, 0x4195, 0x3c00, 0xa004, 0x6561, 0x3500, 0x2000, 0x8100, 0xc0ff, 0x3c00 }, 16, 0x000b3ee0, 1},
+ {{0xaa08, 0xd6c2, 0x6568, 0x75d2, 0x27ed, 0x9f1c, 0x37c5, 0x26e4, 0x3400, 0x2000, 0x8100, 0x96c7, 0xd646, 0xc2ff, 0xf77a, 0x94c6 }, 16, 0x000b3f00, 1},
+ {{0x459d, 0x6d10, 0x0795, 0x3119, 0x2000, 0xbe00, 0x96c0, 0xed4c, 0x01fa, 0x9f00, 0x0495, 0xeaed, 0x94c0, 0xea68, 0xcd4f, 0x98c0 }, 16, 0x000b3f20, 1},
+ {{0xefea, 0x33e4, 0x3d62, 0x8001, 0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x98c0, 0xcd47, 0x3700 }, 16, 0x000b3f40, 1},
+ {{0x2000, 0x8100, 0x98c0, 0x6d1f, 0xeaef, 0x11fa, 0x9f00, 0x0192, 0xed64, 0x0295, 0x3144, 0x2a72, 0x800b, 0x3e06, 0xb400, 0x90c0 }, 16, 0x000b3f60, 1},
+ {{0x01fa, 0x9f00, 0x7454, 0x6d10, 0x74d5, 0x32e4, 0x3d74, 0x8001, 0x92c3, 0xc2ff, 0x9ac0, 0x77d6, 0x27ec, 0x9f1c, 0x6e10, 0xf17a }, 16, 0x000b3f80, 1},
+ {{0x3820, 0xa000, 0x67e4, 0x449c, 0xf2fe, 0x3e00, 0xb004, 0x6568, 0x75d2, 0x4794, 0x3500, 0x2000, 0x8100, 0x96c0, 0xd6c6, 0xec4c }, 16, 0x000b3fa0, 1},
+ {{0xc0ff, 0x98c6, 0x3119, 0x2000, 0xbe00, 0x6d10, 0x94c7, 0xefec, 0xc2ff, 0x98c0, 0xcc4f, 0x32e4, 0x3d62, 0x8001, 0x0594, 0xef68 }, 16, 0x000b3fc0, 1},
+ {{0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x98c0, 0xcc47, 0x3500, 0x2000, 0x8100, 0x2d3a, 0x0197 }, 16, 0x000b3fe0, 1},
+ {{0x11fa, 0x9f00, 0x98c0, 0xec64, 0x3044, 0x2a72, 0x800b, 0x4294, 0x3c00, 0xa004, 0x6561, 0x3500, 0x2000, 0x8100, 0xc0ff, 0x3c00 }, 16, 0x000b4000, 1},
+ {{0xa404, 0x6568, 0x27ed, 0x9f1c, 0x75d2, 0xf57a, 0x98c6, 0x3119, 0x2000, 0xbe00, 0x6d10, 0x98c0, 0xcd4f, 0x32e4, 0x3d62, 0x8001 }, 16, 0x000b4020, 1},
+ {{0x98c7, 0x01fa, 0x9f00, 0x90c0, 0xc2ff, 0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x98c0, 0xcd47 }, 16, 0x000b4040, 1},
+ {{0x3400, 0x2000, 0x8100, 0x3700, 0x2000, 0x8100, 0x2f9f, 0x019d, 0x11fa, 0x9f00, 0x0495, 0xd646, 0xed4c, 0x0495, 0xebed, 0x94c0 }, 16, 0x000b4060, 1},
+ {{0xed64, 0xeb68, 0x3044, 0x2a72, 0x800b, 0x0193, 0x4795, 0x3c00, 0xa004, 0x6561, 0x3700, 0x2000, 0x8100, 0xc0ff, 0x3c00, 0xa204 }, 16, 0x000b4080, 1},
+ {{0x6568, 0x6e1f, 0x75d2, 0x27e9, 0x9f1c, 0x98c6, 0x3119, 0x2000, 0xbe00, 0x6d10, 0x94c7, 0xf47a, 0xc2ff, 0x98c0, 0xcf44, 0x32e4 }, 16, 0x000b40a0, 1},
+ {{0x3d62, 0x8001, 0x9ac0, 0x01fa, 0x9f00, 0x90c0, 0x09f8, 0x9eb4, 0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3 }, 16, 0x000b40c0, 1},
+ {{0xc2ff, 0x9ac0, 0x19f8, 0x9eb4, 0x6f5f, 0x11fa, 0x9f00, 0xcf4c, 0x4199, 0x4691, 0xe94c, 0x0691, 0xefe9, 0x94c0, 0xef68, 0xe964 }, 16, 0x000b40e0, 1},
+ {{0x3044, 0x2a72, 0x800b, 0x0197, 0x4491, 0x3c00, 0xb004, 0x67e8, 0x75d7, 0x74d6, 0x01fa, 0x9f00, 0x92c2, 0x6d10, 0x94c7, 0x6768 }, 16, 0x000b4100, 1},
+ {{0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10 }, 16, 0x000b4120, 1},
+ {{0x92c3, 0xc2ff, 0x3c40, 0xa004, 0x7451, 0xf2fe, 0x3400, 0x2000, 0x8100, 0x3e00, 0xa803, 0x27ea, 0x9f1c, 0x6568, 0x6461, 0x75d2 }, 16, 0x000b4140, 1},
+ {{0xc0ff, 0x3e00, 0xb800, 0xd640, 0x77d0, 0x3119, 0x2000, 0xbe00, 0xefea, 0x94c6, 0xf47a, 0x6d10, 0x32e4, 0x3d62, 0x8001, 0x92c3 }, 16, 0x000b4160, 1},
+ {{0xc2ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3e00, 0xa008, 0x6768, 0x7457, 0x3400 }, 16, 0x000b4180, 1},
+ {{0x2000, 0x8100, 0xeaef, 0x3a00, 0xa010, 0x77d1, 0x74d6, 0x6f00, 0xc598, 0x96c6, 0x75d5, 0x6c10, 0x479a, 0x9ac7, 0x4692, 0x90c0 }, 16, 0x000b41a0, 1},
+ {{0x66e8, 0xc0ff, 0x7754, 0x94c6, 0xea4c, 0x6d10, 0x32e4, 0x3d8c, 0x8001, 0x94c7, 0xefea, 0xc2ff, 0x3620, 0xa000, 0x17f8, 0x9ebc }, 16, 0x000b41c0, 1},
+ {{0x3600, 0xb004, 0x67e8, 0x75d7, 0x98c6, 0x32e4, 0x3d74, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x98c0, 0x7656, 0x64e1, 0xeaef, 0xedef }, 16, 0x000b41e0, 1},
+ {{0x9ac0, 0xd641, 0x3600, 0x2000, 0x8100, 0xed68, 0x2f06, 0x0492, 0x11fa, 0x9f00, 0x0795, 0xea64, 0x0692, 0x3144, 0x2a72, 0x800b }, 16, 0x000b4200, 1},
+ {{0x3a00, 0xb004, 0x67e8, 0x74d7, 0x6f90, 0xc498, 0x90c0, 0x98c7, 0x2618, 0x81a2, 0x90c0, 0xc2ff, 0x92c3, 0xf274, 0x24e9, 0x3200 }, 16, 0x000b4220, 1},
+ {{0x2000, 0x8100, 0x2518, 0x8186, 0x7161, 0x2518, 0x8180, 0x7171, 0x8447, 0x3c00, 0xb000, 0xd4a6, 0x75d7, 0x3000, 0x2000, 0x8001 }, 16, 0x000b4240, 1},
+ {{0x8437, 0x3e00, 0xa002, 0x6c90, 0x04f8, 0x9eb0, 0x67e8, 0x01fa, 0x9f00, 0x94c6, 0xc781, 0x6d10, 0x32e4, 0x3d74, 0x8001, 0x92c3 }, 16, 0x000b4260, 1},
+ {{0xc2ff, 0x3a40, 0xa000, 0x11fa, 0x9f00, 0x64e1, 0xf2fe, 0x96c0, 0xc598, 0x14f8, 0x9eb0, 0x3200, 0x2000, 0x8100, 0x30f2, 0x7551 }, 16, 0x000b4280, 1},
+ {{0x94c6, 0x840f, 0x6e10, 0x3d62, 0x7a41, 0x656a, 0x81fb, 0x3a00, 0xa009, 0x666a, 0x74c1, 0x6e90, 0x75d5, 0x3800, 0xa004, 0x78c1 }, 16, 0x000b42a0, 1},
+ {{0x2718, 0x80c4, 0x9ac0, 0x01fa, 0x9f00, 0x64e8, 0x04f8, 0x9eb0, 0x3846, 0xa000, 0x6c10, 0x01f8, 0x9eac, 0x3a47, 0xa000, 0xc0ff }, 16, 0x000b42c0, 1},
+ {{0x05f8, 0x9ea8, 0x66e8, 0x98c6, 0x32e4, 0x3d8c, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3860, 0xa000, 0xf2fe, 0x11f8, 0x9eac, 0x3c20 }, 16, 0x000b42e0, 1},
+ {{0xa000, 0x15f8, 0x9ea8, 0x90c0, 0x01f8, 0x9ea4, 0x3640, 0xa000, 0xcf40, 0xf27e, 0x3800, 0xb004, 0x64e9, 0x75d1, 0xcf48, 0x98c6 }, 16, 0x000b4300, 1},
+ {{0x2418, 0x89ca, 0x90c0, 0x6d10, 0x92c2, 0xf274, 0x3c40, 0xa001, 0x11f8, 0x9ea4, 0x64e8, 0x01f8, 0x9eac, 0x3a46, 0xa000, 0x6d10 }, 16, 0x000b4320, 1},
+ {{0x05f8, 0x9ea8, 0x64e0, 0x32e4, 0x3d74, 0x8001, 0x92c3, 0xc2ff, 0x3c60, 0xa000, 0x15f8, 0x9ea8, 0x64e1, 0x11f8, 0x9eac, 0x3a00 }, 16, 0x000b4340, 1},
+ {{0xa084, 0x7ac1, 0x60e0, 0x12f8, 0x9eb0, 0x3600, 0xa808, 0x7175, 0x74c1, 0x81a3, 0x3820, 0xa000, 0xf2fe, 0x11fa, 0x9f00, 0x3e00 }, 16, 0x000b4360, 1},
+ {{0xa200, 0x67e9, 0x6c90, 0x75d1, 0x3000, 0x2000, 0x8001, 0x8031, 0x3a40, 0xa001, 0x01fa, 0x9f00, 0x64e8, 0xf27e, 0x98c6, 0x32e4 }, 16, 0x000b4380, 1},
+ {{0x3d74, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x98c0, 0xf174, 0x3044, 0x23d0, 0x800b, 0x3820, 0xa000, 0xf2fe, 0x11fa, 0x9f00, 0x3a20 }, 16, 0x000b43a0, 1},
+ {{0xa000, 0xf174, 0x3144, 0x23d0, 0x800b, 0x3420, 0xa000, 0xf774, 0x98c0, 0x74d6, 0xf3f4, 0x01fa, 0x9f00, 0x3640, 0xa000, 0x65e8 }, 16, 0x000b43c0, 1},
+ {{0xf27e, 0x92c2, 0x6d10, 0x94c7, 0x6768, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc598, 0x26e8, 0x75d5 }, 16, 0x000b43e0, 1},
+ {{0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3a60, 0xa000, 0x7651, 0xf2fe, 0x17f8, 0x9ebc, 0x3e00, 0xa208, 0x6661 }, 16, 0x000b4400, 1},
+ {{0x6568, 0x75d2, 0x3700, 0x2000, 0x8100, 0x3e40, 0xb000, 0x7e41, 0xd7c7, 0x3600, 0x2000, 0x8200, 0xf27e, 0x96c7, 0x6f1f, 0xc2ff }, 16, 0x000b4420, 1},
+ {{0xcf44, 0x96c6, 0x6768, 0x6d10, 0x74d6, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6 }, 16, 0x000b4440, 1},
+ {{0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3a20, 0xa001, 0x17f8, 0x9ebc, 0x7451, 0xcf4c, 0x3a00, 0xa20c, 0x6461, 0x67e8 }, 16, 0x000b4460, 1},
+ {{0x75d7, 0xcf44, 0x3840, 0xa044, 0x6d83, 0x00f8, 0x9ea0, 0x3a47, 0xa020, 0xc2ff, 0x03f8, 0x9e9c, 0x6ccc, 0x94c6, 0x64e8, 0x6d10 }, 16, 0x000b4480, 1},
+ {{0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3 }, 16, 0x000b44a0, 1},
+ {{0xc2ff, 0x3c20, 0xa000, 0x76d1, 0x74d7, 0xf2fe, 0x27e9, 0x9f1c, 0x3c00, 0xb004, 0x6568, 0x75d2, 0xf57a, 0x09f8, 0x9e98, 0x92c2 }, 16, 0x000b44c0, 1},
+ {{0x6d10, 0x94c7, 0x67e8, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86 }, 16, 0x000b44e0, 1},
+ {{0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3840, 0xa000, 0x76d1, 0x17f8, 0x9ebc, 0x3800, 0xa204, 0x67e8, 0x66e1, 0x75d7, 0x2c9a, 0x05f8 }, 16, 0x000b4500, 1},
+ {{0x9e94, 0x98c1, 0x64e8, 0x64e8, 0xc2ff, 0x6d10, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0x3420, 0xa000, 0xc598 }, 16, 0x000b4520, 1},
+ {{0x3600, 0xb004, 0x66e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3c40, 0xa000, 0x19f8, 0x9e98, 0x64e1 }, 16, 0x000b4540, 1},
+ {{0x17f8, 0x9ebc, 0x3e20, 0xa801, 0x13f8, 0x9e9c, 0x67e8, 0x7cc1, 0x75d7, 0xcf4c, 0x3600, 0xa800, 0x6cac, 0x4199, 0x98c1, 0x64e8 }, 16, 0x000b4560, 1},
+ {{0x64e8, 0xc2ff, 0x6d10, 0x98c6, 0x09f8, 0x9e98, 0x90c0, 0x6c10, 0x32e4, 0x3d62, 0x8001, 0x92c3, 0xc0ff, 0x3420, 0xa000, 0xc598 }, 16, 0x000b4580, 1},
+ {{0x3600, 0xb004, 0x66e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3c20, 0xa000, 0x10f8, 0x9ea0, 0x90c0 }, 16, 0x000b45a0, 1},
+ {{0x15f8, 0x9e94, 0x3c00, 0xa020, 0x6d5a, 0x19f8, 0x9e98, 0x6fc3, 0xcf4c, 0x11fa, 0x9f00, 0x34d1, 0x2e57, 0x2564, 0x6f97, 0x3d41 }, 16, 0x000b45c0, 1},
+ {{0x4191, 0xe94c, 0x0491, 0xebe9, 0x94c0, 0xe964, 0xeb68, 0x3044, 0x2a72, 0x800b, 0x0293, 0x4791, 0x3a00, 0xb004, 0x67e8, 0x74d7 }, 16, 0x000b45e0, 1},
+ {{0x6f90, 0xc498, 0x90c0, 0x98c7, 0x2618, 0x81a8, 0x90c0, 0xc2ff, 0x92c3, 0xf274, 0x24e9, 0x3300, 0x2000, 0x8100, 0x2518, 0x818c }, 16, 0x000b4600, 1},
+ {{0x71e1, 0x2518, 0x8186, 0x71f1, 0x8447, 0x3c00, 0xb000, 0xd4a6, 0x75d7, 0x3000, 0x2000, 0x8001, 0x8437, 0x3e00, 0xa002, 0x6c90 }, 16, 0x000b4620, 1},
+ {{0x04f8, 0x9e90, 0x67e8, 0x01fa, 0x9f00, 0x94c6, 0xc781, 0x6d10, 0x32e4, 0x3d74, 0x8001, 0x92c3, 0xc2ff, 0x3a40, 0xa000, 0x11fa }, 16, 0x000b4640, 1},
+ {{0x9f00, 0x64e1, 0xf2fe, 0x96c0, 0xc598, 0x14f8, 0x9e90, 0x3451, 0x3300, 0x2000, 0x8100, 0x70f3, 0x96c6, 0x8411, 0x6e10, 0x90c0 }, 16, 0x000b4660, 1},
+ {{0x3c62, 0x7a41, 0x646a, 0x81fb, 0x3a00, 0xa009, 0x666a, 0x7641, 0x6c10, 0x75d5, 0x3800, 0xa004, 0x7a41, 0x2718, 0x80c8, 0x9ac0 }, 16, 0x000b4680, 1},
+ {{0x01fa, 0x9f00, 0x64e8, 0x04f8, 0x9e90, 0x3846, 0xa000, 0x6c10, 0x04f8, 0x9e8c, 0x3a47, 0xa000, 0xc0ff, 0x00f8, 0x9e88, 0x66e8 }, 16, 0x000b46a0, 1},
+ {{0x98c6, 0x32e4, 0x3d8c, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3860, 0xa000, 0xf2fe, 0x14f8, 0x9e8c, 0x3c20, 0xa000, 0x10f8, 0x9e88 }, 16, 0x000b46c0, 1},
+ {{0x90c0, 0x01f8, 0x9e84, 0x3840, 0xa000, 0xcf40, 0xf27e, 0x90c0, 0x3600, 0xa004, 0x6669, 0xcf48, 0x98c6, 0x2418, 0x8600, 0x90c0 }, 16, 0x000b46e0, 1},
+ {{0x6d90, 0x3606, 0xb000, 0xf374, 0x75d4, 0x3c40, 0xa001, 0x11f8, 0x9e84, 0x6668, 0x04f8, 0x9e8c, 0x3a46, 0xa000, 0x6d10, 0x00f8 }, 16, 0x000b4700, 1},
+ {{0x9e88, 0x64e0, 0x32e4, 0x3d74, 0x8001, 0x92c3, 0xc2ff, 0x3c60, 0xa000, 0x10f8, 0x9e88, 0x64e1, 0x14f8, 0x9e8c, 0x3a00, 0xb004 }, 16, 0x000b4720, 1},
+ {{0x7841, 0x6cc4, 0x13f8, 0x9e90, 0x3600, 0xa808, 0x71f0, 0x7641, 0x81a1, 0x3820, 0xa000, 0xf2fe, 0x11fa, 0x9f00, 0x3e00, 0xa200 }, 16, 0x000b4740, 1},
+ {{0x67e9, 0x6c90, 0x75d4, 0x3000, 0x2000, 0x8001, 0x8031, 0x3a40, 0xa001, 0x01fa, 0x9f00, 0x6668, 0xf27e, 0x98c6, 0x32e4, 0x3d74 }, 16, 0x000b4760, 1},
+ {{0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x98c0, 0xf174, 0x3044, 0x27ae, 0x800b, 0x3820, 0xa000, 0xf2fe, 0x11fa, 0x9f00, 0x3a20, 0xa000 }, 16, 0x000b4780, 1},
+ {{0xf474, 0x3144, 0x27ae, 0x800b, 0x3420, 0xa000, 0xf774, 0x98c0, 0x74d6, 0xf3f4, 0x01fa, 0x9f00, 0x3640, 0xa000, 0x65e8, 0xf27e }, 16, 0x000b47a0, 1},
+ {{0x92c2, 0x6d10, 0x94c7, 0x6768, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6 }, 16, 0x000b47c0, 1},
+ {{0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3a60, 0xa000, 0x7651, 0xf2fe, 0x17f8, 0x9ebc, 0x3e00, 0xa208, 0x6661, 0x6568 }, 16, 0x000b47e0, 1},
+ {{0x75d2, 0x3700, 0x2000, 0x8100, 0x3e40, 0xb000, 0x7e41, 0xd7c7, 0x3600, 0x2000, 0x8200, 0xf27e, 0x96c7, 0x6f1f, 0xc2ff, 0xcf44 }, 16, 0x000b4800, 1},
+ {{0x96c6, 0x6768, 0x6d10, 0x74d6, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4 }, 16, 0x000b4820, 1},
+ {{0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3a20, 0xa001, 0x17f8, 0x9ebc, 0x76d1, 0xcf4c, 0x3a00, 0xa20c, 0x66e1, 0x67e8, 0x75d7 }, 16, 0x000b4840, 1},
+ {{0xcf44, 0x3840, 0xa044, 0x6e5b, 0x05f8, 0x9e80, 0x3a47, 0xa400, 0xc2ff, 0x04f8, 0x9e7c, 0x6cd4, 0x94c6, 0x64e8, 0x6d10, 0x98c6 }, 16, 0x000b4860, 1},
+ {{0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc598, 0x26e8, 0x75d5, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff }, 16, 0x000b4880, 1},
+ {{0x3c20, 0xa000, 0x7451, 0x74d7, 0xf2fe, 0x27ea, 0x9f1c, 0x3c00, 0xb004, 0x6568, 0x75d2, 0xf07a, 0x0af8, 0x9e78, 0x92c2, 0x6d10 }, 16, 0x000b48a0, 1},
+ {{0x94c7, 0x67e8, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001 }, 16, 0x000b48c0, 1},
+ {{0x6d10, 0x92c3, 0xc2ff, 0x3840, 0xa000, 0x76d1, 0x17f8, 0x9ebc, 0x3800, 0xa204, 0x67e8, 0x66e1, 0x75d7, 0x2cda, 0x05f8, 0x9e74 }, 16, 0x000b48e0, 1},
+ {{0x98c1, 0x64e8, 0x64e8, 0xc2ff, 0x6d10, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0x3420, 0xa000, 0xc198, 0x3600 }, 16, 0x000b4900, 1},
+ {{0xb004, 0x64e8, 0x75d1, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3c60, 0xa000, 0x17f8, 0x9ebc, 0x64e1, 0x14f8 }, 16, 0x000b4920, 1},
+ {{0x9e7c, 0x3e00, 0xa204, 0x67e8, 0x7cc1, 0x75d7, 0xcf4c, 0x1af8, 0x9e78, 0x3600, 0xa804, 0x6d34, 0x64e1, 0x98c1, 0x64e4, 0x64e4 }, 16, 0x000b4940, 1},
+ {{0xc2ff, 0x6d10, 0x3800, 0xb004, 0x6568, 0x74d2, 0x419a, 0x98c6, 0x0af8, 0x9e78, 0x90c0, 0x6c10, 0x32e4, 0x3d62, 0x8001, 0x92c3 }, 16, 0x000b4960, 1},
+ {{0xc0ff, 0x3420, 0xa000, 0xc198, 0x3600, 0xb004, 0x64e8, 0x75d1, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3c40 }, 16, 0x000b4980, 1},
+ {{0xa000, 0x1af8, 0x9e78, 0x90c0, 0x15f8, 0x9e80, 0x3a00, 0xa040, 0x6c1b, 0xcf4c, 0x15f8, 0x9e74, 0x2d9a, 0x2f40, 0x2e20, 0x0192 }, 16, 0x000b49a0, 1},
+ {{0x11fa, 0x9f00, 0x3dc1, 0xea4c, 0x0692, 0xebea, 0x94c0, 0xeb68, 0xea64, 0x3044, 0x2a72, 0x800b, 0x0393, 0x4492, 0x98c0, 0x6e90 }, 16, 0x000b49c0, 1},
+ {{0x6f90, 0xc4dc, 0xc098, 0x3a40, 0xa001, 0x27eb, 0x9f1c, 0x7654, 0xf77a, 0x3c00, 0xa804, 0x6c7c, 0x459b, 0x3fc0, 0x2d38, 0x8009 }, 16, 0x000b49e0, 1},
+ {{0x3c00, 0xa800, 0x7654, 0x4593, 0x3300, 0x2000, 0x8100, 0x96c0, 0x6c7d, 0xeb4c, 0xedee, 0x98c0, 0x3902, 0x8024, 0xe9eb, 0x4393 }, 16, 0x000b4a00, 1},
+ {{0x96c0, 0x7d42, 0xeb64, 0xed64, 0x94c0, 0xca42, 0xe968, 0x0791, 0x4793, 0xea1f, 0x1392, 0x3044, 0x2a72, 0x800b, 0x4395, 0x3e40 }, 16, 0x000b4a20, 1},
+ {{0xa004, 0x27ed, 0x9f1c, 0x6c90, 0x6f90, 0x67e4, 0xf77a, 0x3a20, 0xa000, 0x479d, 0x3000, 0x2000, 0x8100, 0x0195, 0x3398, 0x2f5c }, 16, 0x000b4a40, 1},
+ {{0xbf02, 0xed4c, 0x0095, 0xe9ed, 0x94c0, 0xe968, 0xed64, 0x0391, 0x4795, 0x3880, 0xa000, 0x5411, 0x27ec, 0x9f2c, 0x9ac0, 0xd22f }, 16, 0x000b4a60, 1},
+ {{0x5394, 0x3000, 0x2000, 0x8001, 0x96c0, 0x7dc1, 0x2518, 0x8248, 0x25e1, 0x6c90, 0x65e8, 0x98c6, 0x32e4, 0x3d74, 0x8001, 0x6d10 }, 16, 0x000b4a80, 1},
+ {{0x92c3, 0xc2ff, 0x3751, 0xf3fa, 0x25e8, 0x6761, 0x94c6, 0x74d6, 0x6d10, 0x94c7, 0x6768, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001 }, 16, 0x000b4aa0, 1},
+ {{0x6c10, 0x92c3, 0xc0ff, 0xc798, 0x27e8, 0x75d7, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x98c0, 0x75d1, 0x74d6 }, 16, 0x000b4ac0, 1},
+ {{0x27ec, 0x9f2c, 0x94c0, 0xeaec, 0xf37a, 0xea70, 0x1392, 0x0af8, 0x9e70, 0x65e8, 0x92c2, 0x6d10, 0x94c7, 0x6768, 0xc2ff, 0x98c6 }, 16, 0x000b4ae0, 1},
+ {{0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0x27e8, 0x75d7, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x9cc0 }, 16, 0x000b4b00, 1},
+ {{0x76d1, 0x1af8, 0x9e70, 0x74d6, 0x27ec, 0x9f2c, 0xe9ec, 0x0592, 0xe96c, 0x1391, 0x09f8, 0x9e6c, 0x65e8, 0x92c2, 0x6d10, 0x94c7 }, 16, 0x000b4b20, 1},
+ {{0x6768, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0x27e8, 0x75d7, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10 }, 16, 0x000b4b40, 1},
+ {{0x92c3, 0xc2ff, 0x9cc0, 0x7651, 0x19f8, 0x9e6c, 0x74d6, 0x27ec, 0x9f2c, 0xedec, 0x0491, 0xed68, 0x1395, 0x0df8, 0x9e68, 0x65e8 }, 16, 0x000b4b60, 1},
+ {{0x92c2, 0x6d10, 0x94c7, 0x6768, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0x27e8, 0x75d7, 0x98c6, 0x32e4 }, 16, 0x000b4b80, 1},
+ {{0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x9cc0, 0x76d1, 0x1df8, 0x9e68, 0x74d6, 0x27ec, 0x9f2c, 0xefec, 0x0595, 0xef64, 0x5397 }, 16, 0x000b4ba0, 1},
+ {{0x65e8, 0x92c2, 0x6d10, 0x94c7, 0x6768, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0x27e8, 0x75d7, 0x98c6 }, 16, 0x000b4bc0, 1},
+ {{0x32e4, 0x3d86, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x98c0, 0x7651, 0x74d6, 0x27ec, 0x9f2c, 0x4497, 0x5394, 0x65e8, 0x92c2, 0x6d10 }, 16, 0x000b4be0, 1},
+ {{0x94c7, 0x6768, 0xc2ff, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6c10, 0x92c3, 0xc0ff, 0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001 }, 16, 0x000b4c00, 1},
+ {{0x6d10, 0x92c3, 0xc2ff, 0x96c0, 0xc786, 0x27ec, 0x9f2c, 0x96c0, 0x4194, 0x27eb, 0x9f18, 0x1393, 0x3101, 0x2000, 0x8020, 0x25e8 }, 16, 0x000b4c20, 1},
+ {{0xcb4e, 0x98c6, 0x32e4, 0x3d62, 0x8001, 0x6d10, 0x94c7, 0x6c10, 0xc2ff, 0xc398, 0x65e8, 0x98c6, 0x32e4, 0x3d86, 0x8001, 0x6d10 }, 16, 0x000b4c40, 1},
+ {{0x92c3, 0xc2ff, 0x3be1, 0xcb46, 0x67ea, 0x94c0, 0x419b, 0x81cd, 0x9ac0, 0x1af8, 0x9e70, 0x90c0, 0x19f8, 0x9e6c, 0x96c0, 0xcba8 }, 16, 0x000b4c60, 1},
+ {{0x1df8, 0x9e68, 0x3660, 0xa000, 0xcda4, 0xcaa0, 0x94c0, 0xf8ff, 0xecee, 0x3680, 0xa100, 0xeeee, 0xefee, 0x1292, 0xf0fa, 0x3c47 }, 16, 0x000b4c80, 1},
+ {{0x3d47, 0x1791, 0x5395, 0x3a00, 0xa100, 0x7dc7, 0x7fc7, 0x5697, 0xee3b, 0x38e0, 0xa000, 0x7f47, 0xec3d, 0xef3a, 0x0090, 0xee7c }, 16, 0x000b4ca0, 1},
+ {{0x3680, 0xa000, 0x4296, 0x4794, 0x3680, 0xa000, 0x4397, 0x4696, 0x96c0, 0x6c10, 0x27ec, 0x9e68, 0xe7ec, 0x94c0, 0x9e21, 0x9f21 }, 16, 0x000b4cc0, 1},
+ {{0x94c0, 0x9621, 0x9721, 0x9f71, 0x3044, 0x23d0, 0x800b, 0x3820, 0xa000, 0xf2fe, 0x11fa, 0x9f00, 0x3044, 0x27ae, 0x800b, 0x3820 }, 16, 0x000b4ce0, 1},
+ {{0xa000, 0xf2fe, 0x11fa, 0x9f00, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x96c0, 0x5510 }, 16, 0x000b4d00, 1},
+ {{0x270a, 0x8030, 0x26e9, 0xe7ea, 0x98c6, 0x2518, 0x829c, 0x90c0, 0x6c10, 0x98c0, 0xf6d3, 0x3ac0, 0x2e80, 0x8009, 0x9ac0, 0x3616 }, 16, 0x000b4d20, 1},
+ {{0x8040, 0xc788, 0x280c, 0x8004, 0x9ac0, 0x280e, 0x802c, 0x90c0, 0x2718, 0x812a, 0x3680, 0xa100, 0xedea, 0xebea, 0x3680, 0xa100 }, 16, 0x000b4d40, 1},
+ {{0xe8ea, 0xed64, 0x3680, 0xa100, 0xeb68, 0xe86c, 0x9ac0, 0x280f, 0x801c, 0x90c0, 0x280b, 0x8036, 0x3820, 0xa000, 0xfd41, 0x280d }, 16, 0x000b4d60, 1},
+ {{0x8038, 0x3660, 0xa000, 0xfb42, 0xf843, 0x1315, 0x5213, 0xd1a1, 0x84a1, 0x9ac0, 0xd129, 0x38c0, 0x2e80, 0x8009, 0x5096, 0x3620 }, 16, 0x000b4d80, 1},
+ {{0xa000, 0xfbc1, 0x8051, 0x3620, 0xa000, 0xffc2, 0x4610, 0x3600, 0xa100, 0xfac3, 0x4f93, 0x3680, 0xa000, 0x4c97, 0xf944, 0x0992 }, 16, 0x000b4da0, 1},
+ {{0x38c0, 0x2e70, 0x8009, 0x94c0, 0xfc45, 0xfb46, 0x3284, 0x38cc, 0x800b, 0x98c0, 0xfd47, 0x09c2, 0x2e70, 0x8009, 0x94c0, 0xf9c4 }, 16, 0x000b4dc0, 1},
+ {{0xfcc5, 0x3044, 0x2e30, 0x800b, 0x94c0, 0xfbc6, 0xfdc7, 0x98c0, 0x676a, 0x76d6, 0xeae9, 0xe8e9, 0x96c0, 0x7ae1, 0x5158, 0x8439 }, 16, 0x000b4de0, 1},
+ {{0x98c0, 0x61f4, 0x9b45, 0x2b03, 0x8014, 0x6df4, 0x96c0, 0x7dc8, 0x2103, 0x801c, 0x25e5, 0x5158, 0x22f4, 0x7dc8, 0x94d0, 0x6ef4 }, 16, 0x000b4e00, 1},
+ {{0x75db, 0x35d5, 0x435a, 0x7dc8, 0x65e5, 0x7dc8, 0x75db, 0x4352, 0x90c0, 0x9ac0, 0x2f0f, 0x8038, 0x7be1, 0x2d0d, 0x8038, 0x9ac0 }, 16, 0x000b4e20, 1},
+ {{0x2b0b, 0x8038, 0x67ea, 0x2e0e, 0x8038, 0x96c0, 0x8141, 0x2c0c, 0x8038, 0x3a20, 0xa000, 0xf8c3, 0x31c1, 0x2c38, 0x8009, 0x90c0 }, 16, 0x000b4e40, 1},
+ {{0x3a80, 0xa000, 0x4190, 0x3044, 0x2fc2, 0x800b, 0x01c2, 0x2e70, 0x8009, 0x9ac0, 0x676a, 0xede9, 0x3bc0, 0x2c38, 0x8009, 0x840f }, 16, 0x000b4e60, 1},
+ {{0x9f46, 0x90c0, 0x90c0, 0x92d0, 0x505d, 0x409b, 0x98c0, 0x3bc0, 0x2e80, 0x8009, 0xf944, 0x96c0, 0xc788, 0x280f, 0x8004, 0x3600 }, 16, 0x000b4e80, 1},
+ {{0xa100, 0xeceb, 0xedeb, 0x3880, 0xa000, 0xed68, 0x2f0e, 0x8018, 0x96c0, 0xec64, 0x2e0a, 0x801a, 0x96c0, 0xf848, 0x2a0d, 0x8002 }, 16, 0x000b4ea0, 1},
+ {{0x3640, 0xa000, 0xfc49, 0xfd4a, 0x1315, 0x3bc0, 0x2e80, 0x8009, 0x1312, 0xd1a1, 0x94c0, 0xfcca, 0x8435, 0x96c0, 0xd1a9, 0xfa4b }, 16, 0x000b4ec0, 1},
+ {{0xfd4c, 0x90c0, 0x94c7, 0xfbc9, 0x4613, 0x96c3, 0x38c0, 0x2e70, 0x8009, 0x98c3, 0x4e93, 0x3284, 0x3a18, 0x800b, 0x92c3, 0x4f94 }, 16, 0x000b4ee0, 1},
+ {{0x94c0, 0xfacb, 0xfdcc, 0x90c0, 0x9ac0, 0x2e0e, 0x8038, 0x7be1, 0x2d0d, 0x8038, 0x9ac0, 0x2a0a, 0x8038, 0x67ea, 0x2f0f, 0x8038 }, 16, 0x000b4f00, 1},
+ {{0x81a9, 0x96c0, 0x676a, 0xf9c4, 0xf8c8, 0x8417, 0x9f46, 0x98c0, 0x3bc0, 0x2c38, 0x8009, 0xede9, 0x90c0, 0x92d0, 0x559b, 0x455d }, 16, 0x000b4f20, 1},
+ {{0x98c0, 0x2808, 0x802c, 0x7556, 0x9248, 0x9ac0, 0x2a03, 0x801c, 0x90c0, 0x2b03, 0x804c, 0x9ac0, 0x280a, 0x800a, 0x90c0, 0x2b02 }, 16, 0x000b4f40, 1},
+ {{0x801c, 0x2a0d, 0x8002, 0x143d, 0x5112, 0xd221, 0x8447, 0x1090, 0xd0a9, 0x8441, 0x96c0, 0x676a, 0xeee9, 0xece9, 0x94c6, 0x8437 }, 16, 0x000b4f60, 1},
+ {{0x7961, 0x96c0, 0x7941, 0x515c, 0x9b42, 0x6274, 0x6e74, 0x96c0, 0x7e48, 0x2103, 0x801c, 0x2665, 0x515c, 0x22f4, 0x7e48, 0x94d0 }, 16, 0x000b4f80, 1},
+ {{0x6ef4, 0x765c, 0x3655, 0x445e, 0x7e48, 0x6665, 0x7e48, 0x765c, 0x4456, 0x9ad0, 0x2a0a, 0x8038, 0x90c0, 0x2808, 0x8038, 0x90c0 }, 16, 0x000b4fa0, 1},
+ {{0x90c0, 0x6c10, 0x27ec, 0x9fd0, 0xe7ec, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b4fc0, 1},
+ {{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x96c0, 0xcba6, 0x270d, 0x8040, 0x3640, 0xa000, 0xe7ed, 0xc9ae, 0x96c0, 0xcaa2 }, 16, 0x000b4fe0, 1},
+ {{0x280d, 0x8004, 0x3800, 0xa100, 0xccaa, 0x2d0e, 0x8018, 0x3840, 0xa100, 0x5311, 0x2e0f, 0x801a, 0x36e0, 0xa000, 0xecef, 0xefef }, 16, 0x000b5000, 1},
+ {{0x36c0, 0xa100, 0xec3b, 0xedef, 0x3660, 0xa100, 0xebef, 0xebef, 0x3660, 0xa100, 0xeb39, 0xeaef, 0x3620, 0xa000, 0xeeef, 0xef3a }, 16, 0x000b5020, 1},
+ {{0x36a0, 0xa100, 0xe8ef, 0xed3c, 0x94c0, 0xe944, 0xf341, 0x94c0, 0xc781, 0xc688, 0x94c0, 0xeaed, 0xeced, 0x3680, 0xa100, 0xe862 }, 16, 0x000b5040, 1},
+ {{0xea64, 0x36a0, 0xa100, 0xe939, 0xeb66, 0x98c0, 0xee7e, 0x3110, 0x2000, 0x8000, 0x94c0, 0xf842, 0xfd43, 0xfb44, 0x5319, 0x1519 }, 16, 0x000b5060, 1},
+ {{0xd1af, 0x3620, 0xa000, 0x5319, 0x8470, 0x5219, 0x94c0, 0xf8d7, 0xfdc4, 0x90c0, 0x3420, 0xa000, 0x5598, 0x3400, 0xa004, 0x7ee3 }, 16, 0x000b5080, 1},
+ {{0x3420, 0xa000, 0x4594, 0x3420, 0xa000, 0x5198, 0x3400, 0xa004, 0x7ce3, 0x3420, 0xa000, 0x4195, 0x3420, 0xa000, 0x5498, 0x3400 }, 16, 0x000b50a0, 1},
+ {{0xa004, 0x7e63, 0x34a0, 0xa000, 0x4495, 0x3420, 0xa000, 0x5698, 0x3400, 0xa004, 0x7f63, 0x34a0, 0xa000, 0x4694, 0x3420, 0xa000 }, 16, 0x000b50c0, 1},
+ {{0x5098, 0x3600, 0xa004, 0x7c63, 0xf857, 0x3420, 0xa000, 0x4097, 0x4196, 0x3600, 0xa100, 0x6e10, 0x4513, 0x36a0, 0xa000, 0x4312 }, 16, 0x000b50e0, 1},
+ {{0x9742, 0x3880, 0xa000, 0x4210, 0x2b02, 0x8002, 0x38c0, 0xa000, 0x4317, 0x2e0b, 0x8004, 0x3420, 0xa000, 0xedee, 0x94c8, 0x44bd }, 16, 0x000b5100, 1},
+ {{0x44bb, 0x94c0, 0xe8ea, 0xf945, 0x94c0, 0xfa46, 0xfc47, 0x3660, 0xa000, 0xfe48, 0xff49, 0x3660, 0xa000, 0xf84a, 0xfa4b, 0x3660 }, 16, 0x000b5120, 1},
+ {{0xa000, 0xfb4c, 0xf94d, 0x3224, 0x30d0, 0x800b, 0x3660, 0xa000, 0xfc4e, 0xfd4f, 0x3a40, 0xa000, 0x7577, 0x6e90, 0xf3c1, 0xfdcf }, 16, 0x000b5140, 1},
+ {{0x3860, 0xa000, 0xdd03, 0xf8ca, 0xf9cd, 0x3860, 0xa000, 0x6569, 0xfec8, 0xffc9, 0x94c0, 0xfac6, 0xfcc7, 0x3640, 0xa000, 0xf9c5 }, 16, 0x000b5160, 1},
+ {{0xfacb, 0x3660, 0xa000, 0xfbcc, 0xfcce, 0x8048, 0x98c0, 0x3110, 0x2000, 0x8000, 0xc081, 0x3640, 0xa000, 0xf8c3, 0xede9, 0x96c0 }, 16, 0x000b5180, 1},
+ {{0x9348, 0x2b03, 0x801c, 0x96c0, 0xed18, 0x280b, 0x8034, 0x96c0, 0xf8c2, 0x2d0d, 0x8034, 0x4015, 0x4510, 0x5513, 0x7065, 0x90c0 }, 16, 0x000b51a0, 1},
+ {{0x96c2, 0x4010, 0x2003, 0x808c, 0x94d0, 0x2b0b, 0x8038, 0x90c0, 0x90c0, 0x3c40, 0xa100, 0x7b61, 0x7fc1, 0xfdc4, 0x2d0d, 0x8038 }, 16, 0x000b51c0, 1},
+ {{0x3ca0, 0xa000, 0x2c0c, 0x8038, 0x676a, 0x2f0f, 0x8038, 0x9ac0, 0x2d0d, 0x8038, 0x90c0, 0x2e0e, 0x8038, 0x96c0, 0xfd44, 0x2c0c }, 16, 0x000b51e0, 1},
+ {{0x8038, 0x3ce0, 0xa100, 0x2909, 0x8038, 0x90c0, 0x2b0b, 0x8038, 0x3ce0, 0xa100, 0x2a0a, 0x8038, 0x90c0, 0x2808, 0x8038, 0x9ac0 }, 16, 0x000b5200, 1},
+ {{0x2a0a, 0x8038, 0x90c0, 0x2cff, 0x9e5f, 0x3ce0, 0xa100, 0x2f0f, 0x8038, 0x90c0, 0x2e0e, 0x8038, 0x27ec, 0x9fc0, 0xe7ec, 0x94c0 }, 16, 0x000b5220, 1},
+ {{0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x3144, 0x31d2, 0x800b, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b5240, 1},
+ {{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b5260, 1},
+ {{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b5280, 1},
+ {{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b52a0, 1},
+ {{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0xc941, 0xc840, 0x94c0, 0xc848 }, 16, 0x000b52c0, 1},
+ {{0xc949, 0x9ac0, 0x3604, 0x8001, 0x90c0, 0x3405, 0x8001, 0x96c0, 0x7e78, 0x3005, 0x8001, 0x3ee8, 0x6331, 0x2fd5, 0x7f47, 0x6c5f }, 16, 0x000b52e0, 1},
+ {{0xc840, 0x90c0, 0x94c0, 0x9621, 0x9721, 0x94c0, 0xc848, 0x9f71, 0x9ac0, 0x3318, 0x807f, 0xc598, 0x32cc, 0x80c7, 0x9cc0, 0x3e70 }, 16, 0x000b5300, 1},
+ {{0x8000, 0x74f4, 0x75d5, 0x9620, 0x9720, 0x9cc0, 0x7c48, 0x64e8, 0x3200, 0x200c, 0x9800, 0xc84e, 0x6461, 0x94c7, 0x6fb2, 0xc0ff }, 16, 0x000b5320, 1},
+ {{0x94c6, 0x66e8, 0x6c10, 0x98c6, 0x32e4, 0x3d8c, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3451, 0x3100, 0x2003, 0x8600, 0x3244, 0x32d0 }, 16, 0x000b5340, 1},
+ {{0x800b, 0x6461, 0x9ac0, 0x6464, 0x3418, 0x200f, 0xa200, 0xc846, 0x7270, 0x98c7, 0x280a, 0x8048, 0x90c0, 0x6e10, 0x92c3, 0x6c7d }, 16, 0x000b5360, 1},
+ {{0x96c0, 0x6dd7, 0x9621, 0x9721, 0x9f70, 0x4392, 0x90c0, 0x90c0, 0x9ac0, 0x2809, 0x8048, 0x90c0, 0x331d, 0x8f00, 0x3ee8, 0x3200 }, 16, 0x000b5380, 1},
+ {{0x2001, 0x8300, 0x9ac0, 0x3644, 0x8005, 0x90c0, 0x3442, 0x8005, 0x98c0, 0xd812, 0x3300, 0x200c, 0x9800, 0xd444, 0x6461, 0x94c0 }, 16, 0x000b53a0, 1},
+ {{0x6c33, 0x9f70, 0x4091, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0xf4c3, 0xd623, 0x92c3, 0x7cd8, 0x96c3, 0xcc44, 0x280b, 0x8048 }, 16, 0x000b53c0, 1},
+ {{0x90c0, 0x92c3, 0xecfe, 0x94c7, 0x9f70, 0xec1b, 0x92c3, 0x4194, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b53e0, 1},
+ {{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x6469, 0x7750, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20 }, 16, 0x000b5400, 1},
+ {{0x2418, 0x817a, 0x98c6, 0xe758, 0x3000, 0x2000, 0x8100, 0x98c0, 0x38c0, 0x3608, 0x8009, 0x9744, 0x27ef, 0x9fe8, 0x5798, 0x94c8 }, 16, 0x000b5420, 1},
+ {{0x479f, 0x5798, 0x32e4, 0x3c48, 0x8001, 0x0797, 0x30d8, 0x2cce, 0xbdcc, 0x2468, 0x34d0, 0xc498, 0x94c6, 0x75d4, 0x6c10, 0x94c7 }, 16, 0x000b5440, 1},
+ {{0x6668, 0xc0ff, 0x98c6, 0x32e4, 0x3d8c, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x2768, 0x75d6, 0x98c6, 0x32e4, 0x3d74, 0x8001, 0x6d10 }, 16, 0x000b5460, 1},
+ {{0x92c3, 0xc2ff, 0x3551, 0x3140, 0x3477, 0x8171, 0x6561, 0x6569, 0x2418, 0x8102, 0x96c2, 0x3000, 0x2000, 0x8100, 0x2568, 0x3452 }, 16, 0x000b5480, 1},
+ {{0x3244, 0x32d0, 0x800b, 0x92c3, 0x6464, 0x2568, 0x3100, 0x2000, 0x8080, 0x98c0, 0xd441, 0x3160, 0x3218, 0x80b1, 0x31ee, 0x9f00 }, 16, 0x000b54a0, 1},
+ {{0x98c7, 0x3244, 0x32d0, 0x800b, 0x6764, 0x7456, 0x2f92, 0x3244, 0x32d0, 0x800b, 0x34d7, 0x7457, 0x96c0, 0x7550, 0x27ef, 0x9ff8 }, 16, 0x000b54c0, 1},
+ {{0x3244, 0x32d0, 0x800b, 0x5197, 0x3650, 0x3452, 0xe8ef, 0xe864, 0x1590, 0x3244, 0x32d0, 0x800b, 0x6cd5, 0x34d0, 0x3452, 0xeeef }, 16, 0x000b54e0, 1},
+ {{0xee68, 0x1396, 0x3244, 0x32d0, 0x800b, 0x6cd9, 0x36d0, 0x3452, 0xef6c, 0x1397, 0x3244, 0x32d0, 0x800b, 0x6ccd, 0x9cc0, 0x7650 }, 16, 0x000b5500, 1},
+ {{0x7452, 0xf1c6, 0x3244, 0x32d0, 0x800b, 0x6cc4, 0x35d0, 0x3457, 0x3100, 0x2000, 0x8200, 0x3244, 0x32d0, 0x800b, 0x6d59, 0x2468 }, 16, 0x000b5520, 1},
+ {{0x2fab, 0x34d0, 0xc498, 0x94c6, 0x75d4, 0x6c10, 0x94c7, 0x6668, 0xc0ff, 0x98c6, 0x32e4, 0x3d8c, 0x8001, 0x6d10, 0x92c3, 0xc2ff }, 16, 0x000b5540, 1},
+ {{0x27e8, 0x75d7, 0x98c6, 0x32e4, 0x3d74, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x2768, 0x24e1, 0x3000, 0x2000, 0x8100, 0x94c7, 0x6cd1 }, 16, 0x000b5560, 1},
+ {{0x6764, 0x7f78, 0x94c1, 0xd41e, 0xd416, 0x3244, 0x32d0, 0x800b, 0x6461, 0x3500, 0x2000, 0x8100, 0x6c01, 0xe778, 0x94c0, 0x9e21 }, 16, 0x000b5580, 1},
+ {{0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x96c0, 0x57d1 }, 16, 0x000b55a0, 1},
+ {{0x270d, 0x8020, 0xe7ed, 0x94c0, 0xf841, 0xf0cf, 0x96c0, 0xfbc1, 0x2908, 0x8002, 0x94c0, 0xc250, 0xf042, 0x3800, 0xa100, 0x4793 }, 16, 0x000b55c0, 1},
+ {{0x2b0c, 0x8004, 0x3840, 0xa000, 0x5110, 0x2c0e, 0x8002, 0x38c0, 0xa000, 0x4114, 0x2a0d, 0x8002, 0x5710, 0x0716, 0xc84f, 0xee46 }, 16, 0x000b55e0, 1},
+ {{0x499e, 0x96c0, 0x4096, 0x2e0c, 0x804c, 0x1415, 0xed42, 0x9ac0, 0x2e0a, 0x8050, 0x7e51, 0x2e0b, 0x8008, 0x4494, 0x3480, 0xa000 }, 16, 0x000b5600, 1},
+ {{0x5114, 0x3319, 0x8010, 0x24e9, 0x5115, 0x94c0, 0x7cc9, 0x80b1, 0x4192, 0x00c6, 0x3638, 0x8009, 0x06c6, 0x3628, 0x8009, 0x3244 }, 16, 0x000b5620, 1},
+ {{0x32d0, 0x800b, 0x6c22, 0x96c0, 0x6dc2, 0x2e0f, 0x8034, 0x0397, 0x3400, 0x2000, 0x8100, 0x1592, 0x01c6, 0x3634, 0x8009, 0x02c6 }, 16, 0x000b5640, 1},
+ {{0x3630, 0x8009, 0x2c38, 0x3244, 0x32d0, 0x800b, 0x6cb5, 0x1294, 0xc9b0, 0x96c0, 0x6c3d, 0xebef, 0xc847, 0x94c0, 0xeb39, 0xc298 }, 16, 0x000b5660, 1},
+ {{0x35d2, 0x0093, 0xc481, 0x1197, 0x06c6, 0x363c, 0x8009, 0x70f6, 0x8435, 0x64e8, 0x92c2, 0x6c10, 0x94c7, 0x6568, 0xc0ff, 0x98c6 }, 16, 0x000b5680, 1},
+ {{0x32e4, 0x3d8c, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x2768, 0x75d6, 0x98c6, 0x32e4, 0x3d74, 0x8001, 0x6d10, 0x92c3, 0xc2ff, 0x3651 }, 16, 0x000b56a0, 1},
+ {{0xc847, 0x6661, 0x3000, 0x2010, 0xa000, 0x96c0, 0x6c7d, 0x2e0c, 0x8008, 0x0494, 0x3144, 0x3706, 0x800b, 0x9ac0, 0x280d, 0x8006 }, 16, 0x000b56c0, 1},
+ {{0x90c0, 0x2e0a, 0x8004, 0x96c0, 0x5115, 0x2d0f, 0x8002, 0x98c0, 0x7cd1, 0xed64, 0x2e0c, 0x8034, 0x4192, 0x5017, 0x7c51, 0x4093 }, 16, 0x000b56e0, 1},
+ {{0x5515, 0x7ed1, 0x4594, 0x98c0, 0x6e10, 0xe84a, 0x2e0d, 0x800c, 0x96c0, 0x5510, 0x2809, 0x8002, 0x3c00, 0xa100, 0x2e0a, 0x8010 }, 16, 0x000b5700, 1},
+ {{0x7ece, 0x280b, 0x8004, 0x96c0, 0x4595, 0x2e0b, 0x8014, 0x3800, 0xa100, 0x5711, 0x280a, 0x8006, 0x9ac0, 0x2e0c, 0x8018, 0x7fce }, 16, 0x000b5720, 1},
+ {{0x2809, 0x8008, 0x3800, 0xa100, 0x4792, 0x2e08, 0x801c, 0x3880, 0xa000, 0x5013, 0x280f, 0x800a, 0x3c80, 0xa100, 0x2e09, 0x8020 }, 16, 0x000b5740, 1},
+ {{0x7c51, 0x280c, 0x800c, 0x3800, 0xa100, 0x4093, 0x2e0e, 0x8024, 0x3880, 0xa100, 0x5012, 0x280f, 0x8010, 0x3c80, 0xa100, 0x2e0d }, 16, 0x000b5760, 1},
+ {{0x8028, 0x7c51, 0x280b, 0x8012, 0x3800, 0xa100, 0x4094, 0x2e0a, 0x802c, 0x1511, 0xe84e, 0x3860, 0xa000, 0x7ece, 0xfa45, 0xf943 }, 16, 0x000b5780, 1},
+ {{0x3680, 0xa000, 0x4590, 0xf9c1, 0x96c0, 0x5717, 0x2e0f, 0x8030, 0x3640, 0xa000, 0x7fce, 0xfd44, 0x3680, 0xa000, 0x4791, 0x9742 }, 16, 0x000b57a0, 1},
+ {{0x36c0, 0xa100, 0x5714, 0xecea, 0x3ac0, 0xa000, 0x7fd1, 0xfac2, 0x2e09, 0x8048, 0x3680, 0xa000, 0x4796, 0xc081, 0x3880, 0xa000 }, 16, 0x000b57c0, 1},
+ {{0x5117, 0x2b02, 0x8002, 0x7cce, 0x3480, 0xa000, 0x4195, 0x38c0, 0xa100, 0x5213, 0x290d, 0x8040, 0x7d4e, 0x3480, 0xa000, 0x4294 }, 16, 0x000b57e0, 1},
+ {{0x96c0, 0x5210, 0x2908, 0x8048, 0x96c0, 0x7d51, 0x2909, 0x804c, 0x4297, 0x3480, 0xa000, 0x5312, 0x7dd1, 0x3480, 0xa000, 0x4391 }, 16, 0x000b5800, 1},
+ {{0x3480, 0xa000, 0x4095, 0x94c8, 0x44b8, 0x44b9, 0x3680, 0xa000, 0x2e0d, 0x8004, 0x3a80, 0xa000, 0x5195, 0x3510, 0x2029, 0xae00 }, 16, 0x000b5820, 1},
+ {{0x72f1, 0x800b, 0x64ea, 0x94c6, 0xd2d9, 0x6e90, 0x3880, 0xa100, 0x4595, 0x2e0f, 0x8008, 0x3a80, 0xa000, 0x5597, 0x3100, 0x2000 }, 16, 0x000b5840, 1},
+ {{0x8100, 0x70f5, 0x800d, 0x3100, 0x2014, 0xa800, 0x72f1, 0xd0dd, 0x3a80, 0xa000, 0x4197, 0x3700, 0x2005, 0x8a00, 0x5495, 0x2668 }, 16, 0x000b5860, 1},
+ {{0x7454, 0x94c7, 0x840b, 0x6e10, 0x7077, 0xd257, 0x0495, 0x3000, 0x2005, 0x8a00, 0x5492, 0x2668, 0x76d4, 0x94c7, 0x840b, 0x6e10 }, 16, 0x000b5880, 1},
+ {{0x72f0, 0xd250, 0x0492, 0x3310, 0x2029, 0xae00, 0x3480, 0xa000, 0x5496, 0x71f4, 0x800b, 0x666a, 0x94c6, 0xd1dc, 0x6d90, 0x3a80 }, 16, 0x000b58a0, 1},
+ {{0xa000, 0x4396, 0x3500, 0x2000, 0x8100, 0x5097, 0x72f0, 0x800d, 0x3500, 0x2014, 0xa800, 0x7075, 0xd2d8, 0x3620, 0xa000, 0xfdc4 }, 16, 0x000b58c0, 1},
+ {{0x4597, 0x3000, 0x2005, 0x8a00, 0x3480, 0xa000, 0x5595, 0x26e8, 0x7755, 0x94c7, 0x840b, 0x6e90, 0x7370, 0xd2d0, 0x36c0, 0xa100 }, 16, 0x000b58e0, 1},
+ {{0x4595, 0xeaec, 0x3a80, 0xa000, 0x5392, 0x3400, 0x2005, 0x8a00, 0x25e8, 0x76d3, 0x94c7, 0x840b, 0x6d90, 0x72f4, 0xd1d4, 0x3a80 }, 16, 0x000b5900, 1},
+ {{0xa000, 0x4392, 0x3210, 0x2029, 0xae00, 0x5593, 0x7175, 0x800b, 0x66ea, 0x94c6, 0xd15d, 0x6d10, 0x0293, 0x3400, 0x2000, 0x8100 }, 16, 0x000b5920, 1},
+ {{0x5794, 0x7277, 0x800d, 0x3400, 0x2004, 0x8800, 0x73f4, 0xd25f, 0x0494, 0x3700, 0x2005, 0x8a00, 0x3480, 0xa000, 0x5390, 0x25e8 }, 16, 0x000b5940, 1},
+ {{0x7653, 0x94c7, 0x840b, 0x6d90, 0x7277, 0xd1d7, 0x3600, 0xa100, 0xfbc3, 0x4390, 0x3700, 0x2005, 0x8a00, 0x5693, 0x2768, 0x7456 }, 16, 0x000b5960, 1},
+ {{0x94c7, 0x840b, 0x6f10, 0x7077, 0xd357, 0x96c0, 0x4693, 0x2e08, 0x8034, 0x1490, 0xf846, 0x2668, 0x3754, 0x3500, 0x201e, 0xbc00 }, 16, 0x000b5980, 1},
+ {{0x94c7, 0x840b, 0x6e10, 0x7375, 0xd255, 0x0490, 0x3210, 0x2029, 0xae00, 0x3480, 0xa000, 0x5591, 0x7175, 0x800b, 0x66ea, 0x94c6 }, 16, 0x000b59a0, 1},
+ {{0xd15d, 0x6d10, 0x3600, 0xa100, 0xf9c1, 0x4291, 0x3640, 0xa000, 0x5095, 0xff47, 0x98c0, 0xca4e, 0x3244, 0x3410, 0x800b, 0x1191 }, 16, 0x000b59c0, 1},
+ {{0xc05f, 0x94c0, 0xf9c1, 0xca46, 0x2e0c, 0x8054, 0x0094, 0xfc48, 0x3244, 0x3410, 0x800b, 0x1191, 0x5092, 0x94c0, 0xfcc8, 0xf9c1 }, 16, 0x000b59e0, 1},
+ {{0xc057, 0xec44, 0x0094, 0xfc48, 0x3244, 0x3410, 0x800b, 0x3680, 0xa000, 0x5090, 0x5191, 0x94c0, 0xfcc8, 0xf9c1, 0xfbc3, 0xec48 }, 16, 0x000b5a00, 1},
+ {{0x0094, 0xfc48, 0x3244, 0x3410, 0x800b, 0x1093, 0x5191, 0x94c0, 0xfcc8, 0xf9c1, 0x3420, 0xa000, 0xfdc4, 0xec44, 0x0094, 0xfc48 }, 16, 0x000b5a20, 1},
+ {{0x3244, 0x3410, 0x800b, 0x3680, 0xa000, 0x5095, 0x5191, 0x94c0, 0xfcc8, 0xf9c1, 0x3420, 0xa000, 0xfac5, 0xec44, 0x0094, 0xfc48 }, 16, 0x000b5a40, 1},
+ {{0x3244, 0x3410, 0x800b, 0x3680, 0xa000, 0x5092, 0x5191, 0x3820, 0xa000, 0x6c90, 0xfcc8, 0xffc7, 0x3700, 0x2000, 0x8100, 0xec44 }, 16, 0x000b5a60, 1},
+ {{0x0094, 0x3000, 0x2000, 0x8001, 0xec48, 0x0794, 0xedec, 0x3680, 0xa000, 0x5397, 0xfc48, 0x25e8, 0xed78, 0x94c6, 0xcd4e, 0x6d10 }, 16, 0x000b5a80, 1},
+ {{0x32e4, 0x3d74, 0x8001, 0x92c3, 0xc2ff, 0x9ac0, 0x64e1, 0xcd46, 0x3600, 0x2000, 0x8100, 0x9ac0, 0x6c86, 0xfcc8, 0x3000, 0x2000 }, 16, 0x000b5aa0, 1},
+ {{0x8001, 0x2c90, 0x4195, 0x1397, 0xebec, 0x25e8, 0xeb64, 0x94c6, 0xcb4f, 0x6d10, 0x32e4, 0x3d74, 0x8001, 0x92c3, 0xc2ff, 0x9cc0 }, 16, 0x000b5ac0, 1},
+ {{0x64e1, 0x6d90, 0x6c10, 0xcb47, 0x2102, 0x8408, 0x9ac0, 0x6f86, 0x2e0d, 0x84a8, 0x6d10, 0xfcc8, 0x0793, 0xeaed, 0x3680, 0xa000 }, 16, 0x000b5ae0, 1},
+ {{0xe8ed, 0x4395, 0x3680, 0xa000, 0xeeed, 0xea68, 0x36a0, 0xa100, 0xe839, 0xee64, 0x3620, 0xa000, 0x4892, 0xed50, 0x3680, 0xa000 }, 16, 0x000b5b00, 1},
+ {{0x4a96, 0xebed, 0x96c0, 0x4395, 0x2c0c, 0x8024, 0x96c0, 0x4394, 0x2702, 0x841c, 0x94c0, 0xefed, 0xeb6c, 0x0393, 0xef68, 0x98c0 }, 16, 0x000b5b20, 1},
+ {{0x10c0, 0x362c, 0x8009, 0xf9c1, 0x009f, 0x03c6, 0x362c, 0x8009, 0x2704, 0x8080, 0x0397, 0x3710, 0x2000, 0x8000, 0x3820, 0xa000 }, 16, 0x000b5b40, 1},
+ {{0xed3f, 0x2b02, 0x8002, 0x96c0, 0x4795, 0x290a, 0x80b4, 0x3688, 0xa000, 0x42b8, 0x42ba, 0x98c0, 0x2e0a, 0x84bc, 0x6c10, 0xf8c6 }, 16, 0x000b5b60, 1},
+ {{0x029a, 0x31e0, 0x2148, 0x80fa, 0x96c0, 0x429a, 0x2c00, 0x8080, 0x96c0, 0x419a, 0x2e0b, 0x8078, 0x0092, 0x5590, 0x0593, 0xea4c }, 16, 0x000b5b80, 1},
+ {{0x96c0, 0xf2d0, 0x2400, 0x8040, 0x2568, 0x049a, 0xeb3c, 0x0092, 0xf19f, 0x94c0, 0x4113, 0x8427, 0xd523, 0x90c0, 0x98c3, 0xf6d0 }, 16, 0x000b5ba0, 1},
+ {{0x3ac0, 0x361c, 0x8009, 0x92c3, 0x7f42, 0x92c3, 0xcd46, 0x90c0, 0x92c3, 0xed1a, 0x92c3, 0x4995, 0x96c0, 0x6c10, 0x27eb, 0x9fe0 }, 16, 0x000b5bc0, 1},
+ {{0xe7eb, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0xe748, 0xfbc9 }, 16, 0x000b5be0, 1},
+ {{0x90c0, 0x2b0c, 0x8408, 0x5e94, 0xc56f, 0x1005, 0xa004, 0x90c0, 0x98c0, 0x2c0f, 0x800c, 0x64ea, 0x5596, 0x98c0, 0x2f0b, 0x8004 }, 16, 0x000b5c00, 1},
+ {{0x7455, 0x5297, 0x3ee7, 0x149b, 0x06c6, 0x3648, 0x8009, 0x38e1, 0x138b, 0xd741, 0x1358, 0x03c2, 0x362c, 0x8009, 0x9ac0, 0x69f1 }, 16, 0x000b5c20, 1},
+ {{0x06c2, 0x3648, 0x8009, 0xe9eb, 0x846e, 0x98c0, 0x1cc0, 0x362c, 0x8009, 0xe96c, 0x9ac0, 0x74d3, 0x36cb, 0x9647, 0x439e, 0x9b41 }, 16, 0x000b5c40, 1},
+ {{0x9ac0, 0x6f44, 0xd543, 0x5d91, 0x2b03, 0x8022, 0x2e02, 0x6d29, 0xed8e, 0x9e5c, 0x9ac7, 0x2103, 0x803c, 0x90c0, 0x2d00, 0x8400 }, 16, 0x000b5c60, 1},
+ {{0x90c0, 0x94c7, 0x5558, 0xee3d, 0x2af2, 0x5196, 0x9cc0, 0x6f55, 0x7451, 0x7ce7, 0x3acb, 0x9647, 0x459e, 0x2e02, 0x1a91, 0xd543 }, 16, 0x000b5c80, 1},
+ {{0x6d18, 0xea8e, 0x92d0, 0x9e5c, 0x94c3, 0x2d00, 0x8400, 0x90c0, 0x90c0, 0x92c3, 0xee3d, 0x2d90, 0x0e94, 0x14c0, 0x362c, 0x8009 }, 16, 0x000b5ca0, 1},
+ {{0x3e67, 0x049b, 0x00c6, 0x362c, 0x8009, 0x98c0, 0x6665, 0x4093, 0x2000, 0x8051, 0x36d4, 0x0297, 0xc1a8, 0x3ac0, 0x3144, 0x8009 }, 16, 0x000b5cc0, 1},
+ {{0x7751, 0x7f43, 0xcb46, 0x90c0, 0xeb1a, 0x5693, 0x727e, 0x9ac6, 0x805d, 0x90c0, 0x78e1, 0x3303, 0x8001, 0x7551, 0x7d43, 0x94c0 }, 16, 0x000b5ce0, 1},
+ {{0xd91e, 0xcd42, 0x3dee, 0x9fff, 0xed1a, 0x1095, 0xed44, 0x707c, 0x94c6, 0x803b, 0x7451, 0x96c0, 0xda18, 0x31e8, 0x9fff, 0x3066 }, 16, 0x000b5d00, 1},
+ {{0x2ca8, 0x1695, 0xd91d, 0x94c0, 0x6c28, 0x8015, 0x33a4, 0x3590, 0x800b, 0x3c49, 0x3144, 0x3d3c, 0x800b, 0x6c10, 0x646a, 0x98c6 }, 16, 0x000b5d20, 1},
+ {{0x3044, 0x3d58, 0x800b, 0xd740, 0xf642, 0x31f0, 0x6cd3, 0x94c0, 0x74c1, 0x8593, 0x6e90, 0xf542, 0xc567, 0x90c0, 0x90c0, 0xf0c2 }, 16, 0x000b5d40, 1},
+ {{0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x36d0, 0x01c6, 0x3640, 0x8009, 0x2d7c, 0x3cf8, 0x00c6, 0x3644 }, 16, 0x000b5d60, 1},
+ {{0x8009, 0x3655, 0x3dc0, 0x33d4, 0x8009, 0x6c7d, 0x38ca, 0x9218, 0x2e98, 0x31e0, 0x3fff, 0x80ff, 0x96c0, 0x7ac1, 0xdc84, 0xcc45 }, 16, 0x000b5d80, 1},
+ {{0xcb45, 0xecfe, 0x94c0, 0xebfe, 0xec1d, 0x1394, 0xeb1d, 0x1593, 0x3244, 0x32d0, 0x800b, 0x6c0d, 0x94c0, 0xd5c0, 0x9f70, 0x7453 }, 16, 0x000b5da0, 1},
+ {{0x9cc0, 0x7751, 0x6f90, 0x6d10, 0x6c90, 0x9620, 0x9720, 0x96c0, 0x6e90, 0x9e20, 0x9f20, 0xffc7, 0x90c0, 0x2f0b, 0x8014, 0x1493 }, 16, 0x000b5dc0, 1},
+ {{0xeaeb, 0x3270, 0xea70, 0x94c0, 0x5312, 0x8043, 0x9ac0, 0x2b0a, 0x8058, 0x90c0, 0x371b, 0x8001, 0x65e9, 0x94c7, 0x802f, 0x6c20 }, 16, 0x000b5de0, 1},
+ {{0x3244, 0x32d0, 0x800b, 0x2464, 0x5192, 0x96c0, 0x7650, 0xe9ea, 0xc281, 0x94c0, 0xea58, 0xe968, 0x1191, 0xe8ea, 0xe87c, 0x1590 }, 16, 0x000b5e00, 1},
+ {{0x3044, 0x3e8e, 0x800b, 0x4592, 0x96c0, 0xe9eb, 0x2b0d, 0x8010, 0x1395, 0xe970, 0x31f0, 0x5411, 0x96c0, 0x391c, 0x8004, 0x8453 }, 16, 0x000b5e20, 1},
+ {{0x9ac0, 0x6669, 0x3410, 0x203c, 0x8800, 0xed44, 0x94c0, 0x6c7c, 0x803f, 0x2c0c, 0x1595, 0x3100, 0x2000, 0x8100, 0x3244, 0x32d0 }, 16, 0x000b5e40, 1},
+ {{0x800b, 0x6c85, 0x98c0, 0x2d08, 0x8048, 0x7650, 0xc284, 0x1190, 0xe854, 0x98c0, 0xe9e8, 0x3018, 0x2012, 0x9c00, 0x2c7c, 0xe970 }, 16, 0x000b5e60, 1},
+ {{0x1591, 0x3044, 0x3e8e, 0x800b, 0x4590, 0x2e10, 0xc781, 0x96c0, 0x6d90, 0xe8eb, 0xeeeb, 0x94c0, 0xe86c, 0xee70, 0x5010, 0x2469 }, 16, 0x000b5e80, 1},
+ {{0x5016, 0x96c0, 0x3118, 0x8008, 0x844d, 0x2469, 0x3ac0, 0x3624, 0x8009, 0x96c0, 0x8035, 0x2b0c, 0x8044, 0x1992, 0x5094, 0xec74 }, 16, 0x000b5ea0, 1},
+ {{0x290a, 0x80a0, 0x3420, 0xa000, 0x5092, 0x3400, 0xa004, 0x7070, 0x8421, 0x3600, 0xa040, 0x6db0, 0x5094, 0x6464, 0x3073, 0x3044 }, 16, 0x000b5ec0, 1},
+ {{0x3ef0, 0x800b, 0xd1d0, 0x2d90, 0x3144, 0x3ef0, 0x800b, 0x6d90, 0x3e00, 0xa002, 0x6c10, 0x2b02, 0x8002, 0x6c10, 0x2f09, 0x804c }, 16, 0x000b5ee0, 1},
+ {{0x9ac0, 0x2f0e, 0x8048, 0x90c0, 0x2b0c, 0x8030, 0x3660, 0xa000, 0x55be, 0x53b9, 0x3a60, 0xb808, 0xd445, 0xd443, 0x5596, 0x5391 }, 16, 0x000b5f00, 1},
+ {{0x3a20, 0xb808, 0xd445, 0xd443, 0x5494, 0xeaec, 0x3a00, 0xb800, 0x6e54, 0xd440, 0xea70, 0xeb70, 0x2e40, 0x5092, 0x2dcc, 0x5413 }, 16, 0x000b5f20, 1},
+ {{0x96c0, 0xd743, 0x391c, 0x8002, 0x7370, 0x843d, 0x98c0, 0x6669, 0x6c02, 0x2c0a, 0x803c, 0x96c0, 0x6464, 0xc84e, 0x8031, 0x3244 }, 16, 0x000b5f40, 1},
+ {{0x32d0, 0x800b, 0x5192, 0x98c0, 0xd5c0, 0xe9ea, 0x0902, 0xa002, 0x94c0, 0xea44, 0xe968, 0x1191, 0xebea, 0x94c0, 0xeb68, 0xc846 }, 16, 0x000b5f60, 1},
+ {{0x1593, 0xc783, 0x4592, 0x96c0, 0xd3a1, 0x2c0a, 0x8044, 0x90c0, 0x94c2, 0x2c09, 0x804c, 0x9e51, 0x90c0, 0x92c2, 0xee6c, 0x94c6 }, 16, 0x000b5f80, 1},
+ {{0x8018, 0x5796, 0x92c2, 0x4791, 0x1092, 0xea48, 0x7073, 0x90c0, 0x94c1, 0x4592, 0x4192, 0x2c0b, 0x8050, 0x98c0, 0xeeeb, 0x3600 }, 16, 0x000b5fa0, 1},
+ {{0x2000, 0x8100, 0xee64, 0x5096, 0x6c02, 0x4093, 0xeb68, 0x4393, 0x5510, 0x66e9, 0x90c0, 0x96c2, 0x3d00, 0x20a6, 0x8008, 0x8018 }, 16, 0x000b5fc0, 1},
+ {{0x92c2, 0x4215, 0xd2a2, 0x90c0, 0x96c2, 0x3c00, 0x20aa, 0x8008, 0x90c0, 0x92c2, 0x4214, 0x96c0, 0x7453, 0x9e21, 0x9f21, 0x94c0 }, 16, 0x000b5fe0, 1},
+ {{0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x9ac0, 0x280e }, 16, 0x000b6000, 1},
+ {{0x800c, 0x90c0, 0x270b, 0x8030, 0x3620, 0xa000, 0x5d96, 0xecee, 0x94c0, 0xec68, 0xe7eb, 0x3680, 0xa000, 0xed42, 0x5014, 0x3a80 }, 16, 0x000b6020, 1},
+ {{0xa000, 0x311a, 0x8100, 0x55d5, 0xf947, 0x98c0, 0x3b18, 0x8100, 0xffd3, 0xfc48, 0x96c0, 0x7160, 0xf846, 0xf945, 0x96c0, 0x8027 }, 16, 0x000b6040, 1},
+ {{0x2e0b, 0x8004, 0x98c0, 0x6d90, 0x4514, 0x2080, 0x8000, 0x5a93, 0x90c0, 0xea48, 0x4012, 0x1c93, 0xeb66, 0x90c0, 0xec4a, 0x4014 }, 16, 0x000b6060, 1},
+ {{0x4313, 0x94c0, 0xfcc8, 0xebee, 0xeb64, 0x1114, 0x5713, 0x64e9, 0x840d, 0x67e9, 0x8009, 0xd3a2, 0x2718, 0x8256, 0x3800, 0xa100 }, 16, 0x000b6080, 1},
+ {{0xf1d4, 0x2e0e, 0x809c, 0x3640, 0xa000, 0xe8e9, 0xfe41, 0x3244, 0x3bf0, 0x800b, 0x3420, 0xa000, 0xfe49, 0x3820, 0xa000, 0x77d0 }, 16, 0x000b60a0, 1},
+ {{0xf6d4, 0xfec9, 0x96c0, 0x676a, 0xfdc5, 0xf043, 0x3840, 0xa000, 0x847d, 0x2e09, 0x843c, 0x94c0, 0xece9, 0xeae9, 0x94c0, 0xebe9 }, 16, 0x000b60c0, 1},
+ {{0xec74, 0x94c0, 0xea78, 0xeb70, 0x1491, 0x535d, 0x266a, 0x25e6, 0x1194, 0x5092, 0x94c0, 0xd91b, 0x841d, 0x96c0, 0x7171, 0x2400 }, 16, 0x000b60e0, 1},
+ {{0x8040, 0x8439, 0x4294, 0x0292, 0x3064, 0x213a, 0x800b, 0x4491, 0x3244, 0x32d0, 0x800b, 0x1193, 0xc94a, 0x96c0, 0xda9b, 0x4092 }, 16, 0x000b6100, 1},
+ {{0xc942, 0x72f0, 0x90c0, 0x96c2, 0x4594, 0x2000, 0x8040, 0x94c1, 0xc581, 0x4592, 0x94c1, 0x4591, 0x4091, 0x3b61, 0x5591, 0x276a }, 16, 0x000b6120, 1},
+ {{0x7ae1, 0x94c0, 0x4591, 0x81a7, 0x3a20, 0xa000, 0x2e0c, 0x8428, 0x6c10, 0xc2a8, 0x96c0, 0x5694, 0x2100, 0x8051, 0x35f6, 0x3ac0 }, 16, 0x000b6140, 1},
+ {{0x2eb4, 0x8009, 0x7752, 0x7f43, 0xcb46, 0x90c0, 0xeb1a, 0x5413, 0x71f4, 0x9ac6, 0x8051, 0x90c0, 0x7961, 0x3500, 0x8001, 0x7752 }, 16, 0x000b6160, 1},
+ {{0x7f43, 0xcb46, 0x90c0, 0xeb1a, 0x1513, 0xeb44, 0x32f3, 0x2cb5, 0x5693, 0x802f, 0x32e4, 0x6c2d, 0x8015, 0x33a4, 0x3590, 0x800b }, 16, 0x000b6180, 1},
+ {{0x3a20, 0xa000, 0xfec9, 0x3164, 0x21ae, 0x800b, 0x6c10, 0x646a, 0x92c2, 0x7c49, 0x98c6, 0x3064, 0x21d0, 0x800b, 0xd740, 0xf642 }, 16, 0x000b61a0, 1},
+ {{0x74d2, 0x3071, 0x6d51, 0x94c0, 0x7542, 0x859f, 0x6e90, 0xf542, 0x3c20, 0xa000, 0x3ec9, 0x93d1, 0xebee, 0x2002, 0x8098, 0x96c0 }, 16, 0x000b61c0, 1},
+ {{0x7571, 0xf5c2, 0xf6c2, 0x3a20, 0xa000, 0x3cc8, 0x93d1, 0xeb38, 0xf544, 0x3840, 0xa000, 0x7670, 0x5993, 0xfcc8, 0xedee, 0x3680 }, 16, 0x000b61e0, 1},
+ {{0xa000, 0xe948, 0xed62, 0x3480, 0xa000, 0x5511, 0x7175, 0x90c0, 0x3482, 0xa000, 0x4111, 0x3420, 0xa000, 0x5b93, 0x90c0, 0x3480 }, 16, 0x000b6200, 1},
+ {{0xa000, 0xeb4a, 0x3480, 0xa000, 0x5513, 0x7275, 0x90c0, 0x3482, 0xa000, 0x4013, 0x5514, 0x3b1b, 0x8040, 0x25e9, 0x5315, 0x806b }, 16, 0x000b6220, 1},
+ {{0x98c0, 0x65e9, 0x3b18, 0x8080, 0x5a93, 0x845f, 0x2469, 0xea46, 0x94c0, 0x5112, 0x8033, 0x96c0, 0x7171, 0xc181, 0xc088, 0x844b }, 16, 0x000b6240, 1},
+ {{0x32e4, 0x3a8c, 0x8001, 0x94c0, 0xf24a, 0xfd4b, 0x94c0, 0xfdcb, 0xc381, 0x3620, 0xa000, 0xfec9, 0xf2ca, 0x0315, 0x3164, 0x22a8 }, 16, 0x000b6260, 1},
+ {{0x800b, 0x96c0, 0x7271, 0xc181, 0xc088, 0x841f, 0x32e4, 0x3a8c, 0x8001, 0x94c0, 0xf24a, 0xfd4b, 0x94c0, 0xfdcb, 0xc181, 0x3620 }, 16, 0x000b6280, 1},
+ {{0xa000, 0xfec9, 0xf2ca, 0x4115, 0x3880, 0xa000, 0xee68, 0x2d00, 0x809c, 0x3480, 0xa000, 0x479e, 0x3480, 0xa000, 0x4696, 0x3480 }, 16, 0x000b62a0, 1},
+ {{0xa000, 0xee3d, 0x3480, 0xa000, 0x5116, 0x64e9, 0x90c0, 0x96c2, 0x3b00, 0x20a4, 0x8008, 0x8018, 0x92c2, 0x4213, 0xd0a2, 0x90c0 }, 16, 0x000b62c0, 1},
+ {{0x96c2, 0x3d00, 0x20a8, 0x8008, 0x90c0, 0x92c2, 0x4215, 0x96c0, 0xfcc8, 0x2b02, 0x8002, 0x3c00, 0xa100, 0x2e0d, 0x803c, 0x90c0 }, 16, 0x000b62e0, 1},
+ {{0x2e0f, 0x807c, 0x1114, 0xebed, 0x3a40, 0xa100, 0x331f, 0x8007, 0x55bb, 0x5697, 0x67e9, 0x94c0, 0xfcc6, 0x849f, 0x2f10, 0x2f90 }, 16, 0x000b6300, 1},
+ {{0x6d90, 0x98c0, 0x2c0c, 0x804c, 0xd745, 0x5593, 0x98c0, 0xd745, 0x50bc, 0x2b02, 0x8002, 0x1094, 0xd7c0, 0x2c10, 0xd7c0, 0x17bd }, 16, 0x000b6320, 1},
+ {{0xd747, 0x2769, 0xd447, 0x94c0, 0xf8d3, 0x8425, 0x94c0, 0xfdc5, 0xf2d4, 0x7d41, 0x94c0, 0xe8ad, 0xe9ed, 0x8053, 0x32e4, 0x3c84 }, 16, 0x000b6340, 1},
+ {{0x8001, 0xf241, 0x3164, 0x23ac, 0x800b, 0x1795, 0xfcc6, 0xd447, 0x2c0a, 0x804c, 0x56ba, 0x1692, 0xd5c6, 0x98c0, 0xd5c6, 0x3244 }, 16, 0x000b6360, 1},
+ {{0x3d70, 0x800b, 0xd443, 0x94c0, 0xf3d4, 0xfec7, 0x65ea, 0x841f, 0x96c0, 0x9b43, 0x2b03, 0x8008, 0x515e, 0x62f4, 0x6ef4, 0x7645 }, 16, 0x000b6380, 1},
+ {{0x7e48, 0x6665, 0x92d0, 0x7e48, 0x765c, 0x445f, 0x2c10, 0x3164, 0x2464, 0x800b, 0x94c0, 0xfcc6, 0xf1c4, 0x3244, 0x3dc0, 0x800b }, 16, 0x000b63a0, 1},
+ {{0x94c0, 0xfc41, 0xf0c3, 0x3620, 0xa000, 0x2f0c, 0x8004, 0x3420, 0xa000, 0x5394, 0xc56e, 0x1105, 0xa004, 0x90c0, 0x90c0, 0x3840 }, 16, 0x000b63c0, 1},
+ {{0xa004, 0x7456, 0xf2d4, 0xec44, 0x3800, 0xa004, 0x656a, 0x2c0e, 0x8004, 0x3620, 0xa000, 0xfec7, 0x8467, 0x3244, 0x32d0, 0x800b }, 16, 0x000b63e0, 1},
+ {{0x3880, 0xa800, 0x7453, 0x5194, 0x575e, 0x3244, 0x32d0, 0x800b, 0x3800, 0xb000, 0x75d0, 0x7456, 0x5196, 0x3c00, 0xa004, 0x6f53 }, 16, 0x000b6400, 1},
+ {{0xcc4e, 0x3244, 0x3d70, 0x800b, 0x3400, 0xa800, 0x7456, 0x3800, 0xa008, 0x7750, 0x7961, 0xcc46, 0x3600, 0xa008, 0x62f7, 0x656a }, 16, 0x000b6420, 1},
+ {{0x6ef7, 0x75c5, 0x7dc8, 0x65e5, 0x7dc8, 0x94c0, 0x75db, 0x81b0, 0x435f, 0x3400, 0xa800, 0x7750, 0xc566, 0x90c0, 0x3640, 0xa100 }, 16, 0x000b6440, 1},
+ {{0x6c10, 0x4697, 0x27ed, 0x9fd0, 0xe7ed, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b6460, 1},
+ {{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x9ac0, 0x3303, 0x8001, 0x7551, 0x9620, 0x9720, 0x98c0, 0x77d2 }, 16, 0x000b6480, 1},
+ {{0x74d2, 0x9e20, 0x9f20, 0x94c0, 0xe758, 0xeee8, 0x94c0, 0xf6cd, 0xf5ce, 0x98c0, 0x71e6, 0x6e0a, 0xe8ee, 0xcf42, 0x96c0, 0x7454 }, 16, 0x000b64a0, 1},
+ {{0x2518, 0x8100, 0x96c0, 0x666a, 0xf443, 0xf545, 0x94c7, 0xf542, 0x7841, 0x7440, 0x98c0, 0xd442, 0x3264, 0x2490, 0x800b, 0x94c0 }, 16, 0x000b64c0, 1},
+ {{0xf044, 0xf041, 0x94c0, 0xf0c4, 0xf5c5, 0x96c0, 0x74d0, 0xf542, 0xf641, 0x3264, 0x2490, 0x800b, 0xe8ee, 0x94c0, 0xcf4a, 0xf0c4 }, 16, 0x000b64e0, 1},
+ {{0x3e00, 0xa001, 0x7372, 0x74d2, 0x7450, 0x75d0, 0xf5c5, 0xf4c3, 0x3a00, 0xa008, 0x7cc3, 0x7c43, 0xc845, 0x847b, 0x3880, 0xa000 }, 16, 0x000b6500, 1},
+ {{0x74d0, 0xca41, 0xc940, 0x96c0, 0x9b44, 0x2b03, 0x8026, 0x94c0, 0xea1e, 0xe91e, 0x9ac0, 0x2b02, 0x8002, 0x90c0, 0x2a0f, 0x8004 }, 16, 0x000b6520, 1},
+ {{0x96c0, 0xcd45, 0x2808, 0x8004, 0x290c, 0x8004, 0x71f7, 0x8425, 0x3361, 0x1092, 0x5491, 0x94c0, 0x6c7c, 0x800b, 0x7260, 0x8415 }, 16, 0x000b6540, 1},
+ {{0x3bc1, 0x1092, 0xea48, 0x0095, 0x3064, 0x257e, 0x800b, 0x1097, 0xef48, 0x38c1, 0x1091, 0xe948, 0x4095, 0x1094, 0xec48, 0x94d0 }, 16, 0x000b6560, 1},
+ {{0x40b8, 0xed48, 0x90c0, 0x90c0, 0xf4c3, 0x98c0, 0x7372, 0x7d43, 0xcf45, 0xcc45, 0x94c0, 0xc942, 0x8429, 0x96c0, 0x9b44, 0x2b03 }, 16, 0x000b6580, 1},
+ {{0x8018, 0x96c0, 0xee19, 0x2b02, 0x8002, 0x96c0, 0xef44, 0x2e0d, 0x8004, 0x57bc, 0x92d0, 0x47be, 0x52bf, 0x42bd, 0xe778, 0x94c0 }, 16, 0x000b65a0, 1},
+ {{0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b65c0, 1},
+ {{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6c10, 0x9620, 0x9720, 0x96c0, 0x76d0, 0x9e20, 0x9f20 }, 16, 0x000b65e0, 1},
+ {{0x96c0, 0xc481, 0x270e, 0x80a0, 0x96c0, 0xe7ee, 0x2304, 0x8080, 0x94c0, 0xeee9, 0xfbef, 0x96c0, 0x5196, 0x2b03, 0x801a, 0x2f44 }, 16, 0x000b6600, 1},
+ {{0xefe8, 0x4696, 0x519b, 0x24e6, 0x529b, 0x94c0, 0x7451, 0x74d2, 0x3655, 0x64e6, 0x94d0, 0x6c7c, 0x509b, 0x36d4, 0x6466, 0x2d7c }, 16, 0x000b6620, 1},
+ {{0x519b, 0x3551, 0x34d0, 0x3455, 0x6e10, 0x36d0, 0x6566, 0x6d7c, 0x3455, 0x0526, 0x20f8, 0x800c, 0x7750, 0x6e7c, 0x34d6, 0x7456 }, 16, 0x000b6640, 1},
+ {{0x2d7c, 0x6c7c, 0x0522, 0x20f8, 0x800c, 0x5317, 0x35d4, 0xd5a1, 0x94c0, 0xfaef, 0x845d, 0x90c0, 0x9ac0, 0x2a08, 0x8408, 0x6c10 }, 16, 0x000b6660, 1},
+ {{0x2304, 0x8080, 0x98c0, 0x76d0, 0x5298, 0x2b03, 0x8010, 0x2566, 0x5198, 0x7452, 0x3655, 0x64e6, 0x94d0, 0x6c7c, 0x5098, 0x36d4 }, 16, 0x000b6680, 1},
+ {{0x6466, 0x2d7c, 0x5198, 0x3550, 0x3455, 0x24e6, 0x7653, 0x7750, 0x6e7c, 0x3456, 0x0626, 0x20fc, 0x800c, 0x76d0, 0x6d7c, 0x3555 }, 16, 0x000b66a0, 1},
+ {{0x7455, 0x2e7c, 0x6c7c, 0x0622, 0x20fc, 0x800c, 0x35d4, 0x5717, 0xd7a2, 0x94c0, 0xf8ef, 0x845b, 0x9ac0, 0x2304, 0x8080, 0x6c10 }, 16, 0x000b66c0, 1},
+ {{0x2b03, 0x801c, 0x96c0, 0x76d0, 0x280d, 0x8810, 0x529d, 0x2566, 0x519d, 0x7452, 0x3655, 0x64e6, 0x94d0, 0x6c7c, 0x509d, 0x36d4 }, 16, 0x000b66e0, 1},
+ {{0x6466, 0x2d7c, 0x519d, 0x3550, 0x3455, 0x24e6, 0x7653, 0x7750, 0x6e7c, 0x3456, 0x0626, 0x2100, 0x800c, 0x76d0, 0x6d7c, 0x3555 }, 16, 0x000b6700, 1},
+ {{0x7455, 0x2e7c, 0x6c7c, 0x0622, 0x2100, 0x800c, 0x35d4, 0x5117, 0xd4a3, 0x94c0, 0xfcef, 0x845b, 0x9ac0, 0x2304, 0x8080, 0x6c10 }, 16, 0x000b6720, 1},
+ {{0x2b03, 0x801c, 0x96c0, 0x76d0, 0x2c0c, 0x8c18, 0x529c, 0x2566, 0x519c, 0x7452, 0x3655, 0x64e6, 0x94d0, 0x6c7c, 0x509c, 0x36d4 }, 16, 0x000b6740, 1},
+ {{0x6466, 0x2d7c, 0x519c, 0x3550, 0x3455, 0x24e6, 0x7653, 0x7750, 0x6e7c, 0x3456, 0x0626, 0x20f4, 0x800c, 0x76d0, 0x6d7c, 0x3555 }, 16, 0x000b6760, 1},
+ {{0x7455, 0x2e7c, 0x6c7c, 0x0622, 0x20f4, 0x800c, 0x96c0, 0xd114, 0x5317, 0xf8ef, 0x96c0, 0x6564, 0xe9ee, 0xf341, 0x3284, 0x29f0 }, 16, 0x000b6780, 1},
+ {{0x800b, 0xf203, 0x9ac0, 0x2f0c, 0x8028, 0x77d0, 0x2e0d, 0x8e0a, 0x1114, 0xc681, 0x3319, 0x8800, 0x64e9, 0x96c0, 0xfbf1, 0x2518 }, 16, 0x000b67a0, 1},
+ {{0x8112, 0x98c0, 0xfc67, 0x3284, 0x2570, 0x800a, 0x2b08, 0x8058, 0x3c66, 0xfce7, 0xf043, 0xc56d, 0x1005, 0xa004, 0x90c0, 0x3c80 }, 16, 0x000b67c0, 1},
+ {{0xa000, 0x2e09, 0x8b64, 0x6e10, 0x2704, 0x807f, 0x3420, 0xa000, 0xeae9, 0x96c0, 0x539a, 0x2200, 0x8081, 0x34d3, 0x539a, 0x96c8 }, 16, 0x000b67e0, 1},
+ {{0x6e44, 0x74d3, 0x539a, 0x6e44, 0x6e4c, 0x6665, 0xc565, 0x90c0, 0x96c0, 0x6d90, 0xedec, 0x9f42, 0xed6c, 0x1555, 0x3b00, 0x3cb4 }, 16, 0x000b6800, 1},
+ {{0x800c, 0x3c20, 0xa004, 0x63f6, 0x3900, 0x3cb8, 0x800c, 0xeae9, 0x3800, 0xa004, 0x6ff6, 0x2b02, 0x8002, 0x90c0, 0x96d0, 0x79c1 }, 16, 0x000b6820, 1},
+ {{0x569a, 0x43b9, 0x46bb, 0x9cc0, 0x6c90, 0x7750, 0x3301, 0x38ac, 0x800c, 0xf241, 0x98c0, 0xf342, 0x3800, 0x3cb4, 0x800c, 0x3264 }, 16, 0x000b6840, 1},
+ {{0x2490, 0x800b, 0xf466, 0x98c0, 0x7456, 0x6d90, 0x2704, 0x8081, 0x3840, 0xa000, 0xfce7, 0x290b, 0x82a6, 0x94c0, 0xf4e6, 0xeaeb }, 16, 0x000b6860, 1},
+ {{0x92c8, 0x9382, 0x3074, 0x3d00, 0x3cb8, 0x800c, 0x804b, 0x2e90, 0x2d10, 0x3800, 0x3cb4, 0x800c, 0x90c0, 0x1190, 0x5a95, 0x96c0 }, 16, 0x000b6880, 1},
+ {{0xd541, 0xc081, 0xe848, 0x96c0, 0x7ac1, 0xea1b, 0xed48, 0x96c0, 0x3415, 0x8081, 0x909a, 0x800b, 0x3400, 0xa004, 0x73f2, 0x8005 }, 16, 0x000b68a0, 1},
+ {{0xc381, 0x65e9, 0x81d7, 0x3164, 0x28d6, 0x800b, 0x2704, 0x8081, 0x90c0, 0x92c8, 0x9685, 0x96c0, 0xebec, 0x2c08, 0x800c, 0x1010 }, 16, 0x000b68c0, 1},
+ {{0xeb62, 0x96c0, 0x7077, 0xe8ef, 0xe9ee, 0x94c7, 0xfc67, 0x6c90, 0x98c6, 0x3264, 0x3370, 0x800b, 0xc181, 0x919b, 0x3264, 0x2f10 }, 16, 0x000b68e0, 1},
+ {{0x800b, 0x94c0, 0xe9ee, 0xe8ef, 0x2704, 0x8081, 0x9ac0, 0x2e0a, 0x8524, 0x90c0, 0x27eb, 0x9f70, 0x94c0, 0xe8ea, 0xfce7, 0x92d0 }, 16, 0x000b6900, 1},
+ {{0x90a0, 0x9083, 0x96c0, 0x5314, 0x2e0b, 0x8e0a, 0x9ac0, 0x3719, 0x8800, 0xedea, 0x27e9, 0x9f70, 0x94c0, 0x64e9, 0x91e3, 0x94c0 }, 16, 0x000b6920, 1},
+ {{0xf3c3, 0x8069, 0x9ac0, 0x2304, 0x8080, 0x64e9, 0x2b03, 0x8032, 0x90c0, 0x9ac2, 0x2000, 0x80ff, 0x90c0, 0x2200, 0x80ff, 0x92c2 }, 16, 0x000b6940, 1},
+ {{0x909d, 0x96c6, 0x73f3, 0x9299, 0xed41, 0x90c0, 0x94c3, 0x2300, 0x80ff, 0x92c3, 0x9399, 0x94c0, 0x91e3, 0xf6c3, 0x24e9, 0xe941 }, 16, 0x000b6960, 1},
+ {{0x90c0, 0x9ac2, 0x2500, 0x80ff, 0x90c0, 0x2400, 0x80ff, 0x92c2, 0x959d, 0x96c6, 0x73f6, 0x9499, 0xed41, 0x90d0, 0x94c3, 0x2500 }, 16, 0x000b6980, 1},
+ {{0x80ff, 0x92c3, 0x9599, 0x1014, 0xe9ee, 0x98c0, 0x3118, 0x8100, 0xe8ef, 0xca4e, 0x6469, 0x80a1, 0x3384, 0x30a0, 0x800b, 0x94c0 }, 16, 0x000b69a0, 1},
+ {{0xfce7, 0xca46, 0xc569, 0x1005, 0xa004, 0x90c0, 0x98c0, 0x6e10, 0x6f10, 0xc9a4, 0xebec, 0x96c0, 0xc8a2, 0x2e0d, 0x8523, 0x94c0 }, 16, 0x000b69c0, 1},
+ {{0xeb39, 0x92a5, 0x1513, 0xe9ec, 0x98c0, 0x6d29, 0xe938, 0x2304, 0x8080, 0x9ac0, 0x2b03, 0x801e, 0xd992, 0x2a0b, 0x8640, 0x25e1 }, 16, 0x000b69e0, 1},
+ {{0x1211, 0x509b, 0x65e6, 0xdb9b, 0x96c0, 0x7177, 0x90c0, 0x90c0, 0x3a20, 0xa000, 0xd3d0, 0xd1d8, 0x94a5, 0x509b, 0x3a01, 0xac06 }, 16, 0x000b6a00, 1},
+ {{0x6fb5, 0x6f4e, 0x6e57, 0x6fb5, 0x3400, 0xa800, 0xdb97, 0x67e1, 0x92d0, 0x67e6, 0xdb9f, 0x7177, 0x90c0, 0x9cc1, 0x6f42, 0x2a09 }, 16, 0x000b6a20, 1},
+ {{0x8420, 0x6e40, 0x2a09, 0x8420, 0x96c6, 0x6665, 0x77d0, 0x6765, 0x4499, 0x4691, 0xc561, 0x3640, 0xa000, 0xc9a4, 0xcea2, 0x98c0 }, 16, 0x000b6a40, 1},
+ {{0x3b20, 0x2252, 0x800c, 0xe8ec, 0x3640, 0xa000, 0xedec, 0xe83e, 0x1310, 0xed39, 0x10d3, 0x5715, 0x94c0, 0xf003, 0xf301, 0x96c0 }, 16, 0x000b6a60, 1},
+ {{0xf702, 0x27e9, 0x9f70, 0x3264, 0x3df0, 0x800b, 0x94c0, 0xe8ee, 0xca4e, 0x3384, 0x23b0, 0x800b, 0x3284, 0x25d0, 0x800b, 0x94c0 }, 16, 0x000b6a80, 1},
+ {{0xe9ee, 0xe8ef, 0x94c0, 0xfce7, 0xca46, 0x5396, 0x25e0, 0xefec, 0xef68, 0x91bf, 0x64e9, 0x803b, 0x96c0, 0xd5a1, 0xcda0, 0xebec }, 16, 0x000b6aa0, 1},
+ {{0x94c0, 0xec64, 0x8431, 0x9ac0, 0x2304, 0x8081, 0x90c0, 0x2b03, 0x801a, 0x96c0, 0xeb3d, 0x2e09, 0x819c, 0x94c0, 0x2e0d, 0x8004 }, 16, 0x000b6ac0, 1},
+ {{0x1354, 0x5459, 0x96d0, 0x632c, 0x5253, 0x5155, 0x6718, 0x465d, 0x96c0, 0xfff0, 0x2304, 0x8081, 0x96c0, 0xfdf0, 0x2b03, 0x801a }, 16, 0x000b6ae0, 1},
+ {{0x94c0, 0xee44, 0xef44, 0x9ac0, 0x2001, 0x8147, 0x90c0, 0x2b02, 0x8002, 0x155e, 0x5295, 0x7655, 0x6c7c, 0x36d4, 0x5497, 0x35d5 }, 16, 0x000b6b00, 1},
+ {{0x37d5, 0x7754, 0x96d0, 0x60f5, 0x63f7, 0x75d5, 0x2cf5, 0x6ff6, 0x01bd, 0x47bf, 0x2200, 0x8081, 0x96c0, 0x9f42, 0x27eb, 0x9f70 }, 16, 0x000b6b20, 1},
+ {{0x90c0, 0x90c0, 0x92d0, 0x93a3, 0x9382, 0x27ec, 0x9f60, 0xe7ec, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0 }, 16, 0x000b6b40, 1},
+ {{0x98c0, 0xe750, 0x0ac6, 0x38d0, 0x8008, 0xf0c7, 0x96c0, 0x6469, 0x2a0a, 0x81c0, 0x94c0, 0x5412, 0x840f, 0x395b, 0x8000, 0x65e9 }, 16, 0x000b6b60, 1},
+ {{0x844d, 0x0324, 0x20bc, 0x800c, 0xd1a1, 0x94c0, 0xf2c8, 0x8427, 0x9ac0, 0x2304, 0x8081, 0x90c0, 0x2b03, 0x8010, 0x92c0, 0x90c0 }, 16, 0x000b6b80, 1},
+ {{0x92d0, 0x5198, 0x1498, 0x4199, 0x4499, 0x3164, 0x2bcc, 0x800b, 0x94c0, 0xf942, 0xf841, 0x98c0, 0xf243, 0x3900, 0x2a20, 0x800c }, 16, 0x000b6ba0, 1},
+ {{0x3264, 0x25f0, 0x800b, 0x3820, 0x20bc, 0x800c, 0xe770, 0x9f71, 0x94c0, 0x9e20, 0x9f20, 0x94c0, 0xe750, 0xeee9, 0x94c0, 0xefe8 }, 16, 0x000b6bc0, 1},
+ {{0xf942, 0x98c0, 0xf841, 0x3900, 0x2a20, 0x800c, 0x3264, 0x3930, 0x800b, 0x3820, 0x20bc, 0x800c, 0x0ac6, 0x38d0, 0x8008, 0x90c0 }, 16, 0x000b6be0, 1},
+ {{0x2a09, 0x81c0, 0x5311, 0x375c, 0x8000, 0x2669, 0x0424, 0x20bc, 0x800c, 0x8047, 0x98c0, 0xd221, 0x3900, 0x2a20, 0x800c, 0x94c0 }, 16, 0x000b6c00, 1},
+ {{0xf3c9, 0x8425, 0x9ac0, 0x2304, 0x8081, 0x90c0, 0x2b03, 0x800e, 0x90c0, 0x92d0, 0x549f, 0x129f, 0x449e, 0x429e, 0x3164, 0x2c58 }, 16, 0x000b6c20, 1},
+ {{0x800b, 0x94c0, 0xfe42, 0xf343, 0x3264, 0x25f0, 0x800b, 0x98c0, 0xff41, 0x3820, 0x20bc, 0x800c, 0xe770, 0x94c0, 0x9e21, 0x9f21 }, 16, 0x000b6c40, 1},
+ {{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x3a00, 0xa004, 0x6e90, 0x6d90, 0xce57, 0xf7c3, 0x9ac0, 0x7be1 }, 16, 0x000b6c60, 1},
+ {{0xcd56, 0x3010, 0x2001, 0x8000, 0x3880, 0xa100, 0xd7a1, 0xe9ef, 0xe8ee, 0x94c0, 0xc681, 0x8455, 0x96c0, 0xf2c3, 0x290d, 0x8008 }, 16, 0x000b6c80, 1},
+ {{0x3962, 0x149d, 0xebe9, 0x9ac0, 0x76d4, 0x7961, 0x519b, 0x2b03, 0x8022, 0x98c0, 0x6d7c, 0x9b42, 0x290f, 0x8004, 0x3655, 0x529f }, 16, 0x000b6ca0, 1},
+ {{0x96c0, 0x6c7c, 0x2103, 0x8022, 0x3174, 0x149d, 0x519b, 0x9ac0, 0x76d4, 0xd052, 0xd1d6, 0x7b41, 0x529f, 0x92d0, 0x6d7c, 0x7655 }, 16, 0x000b6cc0, 1},
+ {{0x6c7c, 0x7174, 0xd1d6, 0x2e90, 0x0310, 0xf1c4, 0x96c0, 0x64ea, 0xc481, 0xece8, 0x96c0, 0xf0c6, 0x2718, 0x8150, 0x6c7c, 0xcb44 }, 16, 0x000b6ce0, 1},
+ {{0x90c0, 0x9cc0, 0xebfe, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x9cc0, 0x73f4, 0x75d4, 0xc2ff, 0x3010, 0x2001, 0x8000, 0x3c00 }, 16, 0x000b6d00, 1},
+ {{0xa001, 0x2b0d, 0x8004, 0x6c17, 0x2718, 0x810c, 0x3c00, 0xa004, 0x3906, 0x8001, 0xeae9, 0x2a03, 0x8024, 0x3640, 0xa000, 0xea1d }, 16, 0x000b6d20, 1},
+ {{0x9a40, 0x94c0, 0xeee9, 0xed68, 0x94c0, 0xed19, 0xee1b, 0xcc54, 0x3800, 0xa008, 0x66ea, 0x6d90, 0xefe8, 0x94c0, 0xf6c5, 0x842b }, 16, 0x000b6d40, 1},
+ {{0x96c0, 0x9b45, 0x2b03, 0x8008, 0x5417, 0x6e0c, 0x6666, 0x7276, 0x90c0, 0x94c3, 0x2003, 0x8012, 0x3610, 0xa004, 0x79c1, 0xef42 }, 16, 0x000b6d60, 1},
+ {{0x90c0, 0x90c0, 0x3800, 0xa800, 0x72e3, 0x5495, 0x5696, 0x94c0, 0x6c7c, 0x848b, 0x3640, 0xa000, 0x7374, 0x5792, 0x847d, 0x3400 }, 16, 0x000b6d80, 1},
+ {{0xa800, 0x7377, 0x96c0, 0xd056, 0xd153, 0x8075, 0x3400, 0xa004, 0x73e6, 0x8467, 0x3a00, 0xb919, 0x73f6, 0x74d6, 0x6d9f, 0xcf46 }, 16, 0x000b6da0, 1},
+ {{0x3600, 0xa004, 0x7cc2, 0x8459, 0x3c20, 0xa804, 0x3300, 0x8004, 0x9b43, 0x2b03, 0x801e, 0x3680, 0xa000, 0xc450, 0xeffe, 0xef19 }, 16, 0x000b6dc0, 1},
+ {{0x3480, 0xa000, 0xec19, 0x3660, 0xa100, 0x5497, 0x5294, 0x3880, 0xa804, 0x7164, 0xef44, 0xec44, 0x801b, 0x3400, 0xa804, 0x7272 }, 16, 0x000b6de0, 1},
+ {{0x90c0, 0x94c3, 0x2003, 0x8016, 0x98c0, 0x7456, 0x7553, 0x2003, 0x8010, 0x90d0, 0x90c0, 0x90c0, 0x3a10, 0xa008, 0x79c1, 0x7b41 }, 16, 0x000b6e00, 1},
+ {{0xee44, 0xed44, 0xea44, 0x90c0, 0xcc5c, 0x2568, 0x7ac1, 0x3800, 0xa808, 0xd05d, 0x7ac1, 0x84cb, 0x3600, 0xa800, 0x70f5, 0x421c }, 16, 0x000b6e20, 1},
+ {{0x2dff, 0x9ed1, 0x3a00, 0xb000, 0x6f10, 0x7575, 0x2a03, 0x801c, 0x2e7c, 0x7961, 0x9ac0, 0x9a46, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b6e40, 1},
+ {{0x9cc0, 0x280f, 0x8002, 0x656a, 0x6f90, 0x76d2, 0xebe8, 0x96c0, 0x7ae1, 0x5a13, 0x8473, 0x94c0, 0x5d17, 0x9b45, 0x96c0, 0xecea }, 16, 0x000b6e60, 1},
+ {{0x2b03, 0x8030, 0x94c0, 0xeeed, 0xecfe, 0x94c0, 0xeefe, 0xec19, 0x1394, 0xee19, 0x1696, 0xc848, 0x7373, 0x90c0, 0x94c2, 0x4d13 }, 16, 0x000b6e80, 1},
+ {{0x4a17, 0x94c0, 0xef42, 0xeb42, 0x2103, 0x8034, 0x1d13, 0x5817, 0x92c2, 0xc781, 0x94c0, 0xeced, 0xeee8, 0x94c0, 0xecfe, 0xeefe }, 16, 0x000b6ea0, 1},
+ {{0x94c0, 0xec19, 0xee19, 0x1694, 0x5196, 0x70f6, 0x90d0, 0x94c2, 0x4d17, 0x4813, 0x94c0, 0xef42, 0xeb42, 0xc840, 0x92c2, 0xc781 }, 16, 0x000b6ec0, 1},
+ {{0x3961, 0xd3a1, 0x90c0, 0x94c3, 0x2003, 0x800c, 0x90d0, 0x90c0, 0x90c0, 0x3400, 0xa800, 0x7455, 0x94c0, 0xce5f, 0xcd5e, 0x9f70 }, 16, 0x000b6ee0, 1},
+ {{0x3660, 0xa000, 0xefe9, 0xeee8, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6c90, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x9ac0 }, 16, 0x000b6f00, 1},
+ {{0x270d, 0x80f8, 0x90c0, 0x2400, 0x8081, 0x94c0, 0xe7ed, 0xefe8, 0x98c0, 0x3d00, 0x2f44, 0x800c, 0xf441, 0x96c0, 0xf97d, 0x290a }, 16, 0x000b6f20, 1},
+ {{0x8108, 0x32e4, 0x3c8a, 0x8001, 0x94c0, 0xe8ed, 0xca4e, 0x98c0, 0x6f10, 0x6d10, 0xf9fd, 0xca46, 0x96c0, 0x9362, 0x2b03, 0x802c }, 16, 0x000b6f40, 1},
+ {{0x96c0, 0xeeea, 0x290c, 0x8110, 0x109e, 0x549c, 0x9ac0, 0x6c7c, 0x3010, 0x2001, 0x8000, 0xc181, 0x98c0, 0x6c7c, 0x75d1, 0x290b }, 16, 0x000b6f60, 1},
+ {{0x810c, 0x579b, 0x33f4, 0x149c, 0x519e, 0x9ac0, 0x76d4, 0xd057, 0xd153, 0x79c1, 0x579b, 0x92d0, 0x6d7c, 0x7655, 0x6c7c, 0x9ec0 }, 16, 0x000b6f80, 1},
+ {{0x2a03, 0x8048, 0x6d90, 0x73f4, 0x74d3, 0x27ec, 0x9fa4, 0x94c0, 0xd151, 0xc4a4, 0xcb42, 0x98c0, 0xfb2e, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b6fa0, 1},
+ {{0x3a00, 0xa00c, 0x7453, 0x74d4, 0x9263, 0xc2ff, 0x98c0, 0x3010, 0x2001, 0x8000, 0xc181, 0x96c0, 0xc582, 0x290b, 0x8110, 0x96c0 }, 16, 0x000b6fc0, 1},
+ {{0xeeea, 0x290d, 0x810c, 0x98c0, 0x65ea, 0x6e10, 0x27e8, 0x9fa4, 0x8427, 0x3820, 0xa000, 0x9b40, 0x2b03, 0x800a, 0x5710, 0x6f87 }, 16, 0x000b6fe0, 1},
+ {{0x67e6, 0xd7a2, 0x90c0, 0x94c3, 0x2003, 0x8010, 0x94d0, 0x7a41, 0xe842, 0x90c0, 0x90c0, 0x3820, 0xa000, 0x71e4, 0x5496, 0x5495 }, 16, 0x000b7000, 1},
+ {{0x94c0, 0x6c7c, 0x8481, 0x3600, 0xa004, 0x7274, 0x5793, 0x8473, 0x3400, 0xa004, 0x7277, 0x3800, 0xa800, 0xd054, 0xd151, 0x806b }, 16, 0x000b7020, 1},
+ {{0x3600, 0xb800, 0x73e4, 0x6e25, 0x8459, 0x266a, 0x37d5, 0xc845, 0x94c0, 0x7fc2, 0x8451, 0x98c0, 0x7bc4, 0x9b44, 0x2b03, 0x801a }, 16, 0x000b7040, 1},
+ {{0x94c0, 0xc157, 0xe8fe, 0xe81a, 0x3680, 0xa000, 0xe91a, 0x90c0, 0x3600, 0xa100, 0x5490, 0x5791, 0x3880, 0xa000, 0x73e4, 0xe844 }, 16, 0x000b7060, 1},
+ {{0xe944, 0x8019, 0x7277, 0x90c0, 0x94c3, 0x2003, 0x8018, 0x3a00, 0xa800, 0x7454, 0x7551, 0x2003, 0x8012, 0x90d0, 0x90c0, 0x90c0 }, 16, 0x000b7080, 1},
+ {{0x98d0, 0x78c1, 0x7ac1, 0xed44, 0xee44, 0xeb44, 0x90c0, 0x3800, 0xb000, 0x6568, 0x7651, 0x79c1, 0x84cf, 0x3b41, 0x421c, 0x3616 }, 16, 0x000b70a0, 1},
+ {{0x8024, 0x2fff, 0x9eff, 0x9ac0, 0x75f6, 0x2a03, 0x801a, 0x6f90, 0xcf49, 0x2f7c, 0x79e1, 0x98c0, 0x9a47, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b70c0, 1},
+ {{0x9ec0, 0x27eb, 0x9fa6, 0x65ea, 0x6c10, 0x77d3, 0x27ec, 0x9fa4, 0x3840, 0xa000, 0x7be1, 0x5b14, 0x847d, 0x94c0, 0x5e13, 0x9b47 }, 16, 0x000b70e0, 1},
+ {{0x38a0, 0xa000, 0xeaeb, 0x2b03, 0x803a, 0x3600, 0xa100, 0xedee, 0xeafe, 0x3600, 0xa100, 0xedfe, 0xea1a, 0x3600, 0xa100, 0xed1a }, 16, 0x000b7100, 1},
+ {{0x5292, 0x5795, 0x73f2, 0x90c0, 0x3642, 0xa000, 0x4e14, 0x4b13, 0x94c0, 0xeb42, 0xec42, 0x2103, 0x8032, 0x1914, 0x5f13, 0x92c2 }, 16, 0x000b7120, 1},
+ {{0xc081, 0x94c0, 0xeee9, 0xedef, 0x94c0, 0xeefe, 0xedfe, 0x94c0, 0xee1a, 0xed1a, 0x1596, 0x5495, 0x7275, 0x90d0, 0x94c2, 0x4913 }, 16, 0x000b7140, 1},
+ {{0x4f14, 0x94c0, 0xeb42, 0xec42, 0x92c2, 0xc081, 0x39e1, 0xd021, 0x90c0, 0x94c3, 0x2003, 0x81da, 0x90d0, 0x90c0, 0x90c0, 0x94c0 }, 16, 0x000b7160, 1},
+ {{0xf9fd, 0xcf41, 0x90c0, 0x90c0, 0x36f6, 0x2e10, 0xef58, 0x26e9, 0x5017, 0x96c0, 0xfbae, 0x2518, 0x81a6, 0x9ac0, 0x27e8, 0x9f10 }, 16, 0x000b7180, 1},
+ {{0x66ea, 0x27ed, 0x9fa4, 0xebfe, 0xeb1a, 0x96c0, 0x5793, 0x290b, 0x8dbe, 0x9ac0, 0x34e2, 0x8000, 0x90c0, 0x36e6, 0x8000, 0x30e2 }, 16, 0x000b71a0, 1},
+ {{0x8000, 0xd992, 0x94c0, 0xd5c6, 0x8448, 0x36c8, 0x944f, 0x96c0, 0x9b45, 0x2b03, 0x8008, 0x3420, 0xa000, 0x581d, 0x90c0, 0x3420 }, 16, 0x000b71c0, 1},
+ {{0xa000, 0xece8, 0xecfe, 0xec1a, 0x5794, 0x7077, 0x92c3, 0x7a41, 0x98c3, 0x3e80, 0x32e0, 0x8008, 0x4798, 0x90c0, 0x3493, 0xa000 }, 16, 0x000b71e0, 1},
+ {{0xe81e, 0x3483, 0xa000, 0x92b8, 0x92c3, 0x421b, 0x98c0, 0x6f90, 0xc081, 0x2c00, 0x8863, 0x9ac0, 0x2a0d, 0x8d00, 0x6c7d, 0x2800 }, 16, 0x000b7200, 1},
+ {{0x8081, 0x96c0, 0x4415, 0x2a03, 0x801e, 0x94c0, 0xed3c, 0x9a48, 0x94c0, 0xeeed, 0xef64, 0x3800, 0xa100, 0xee38, 0x2908, 0x8626 }, 16, 0x000b7220, 1},
+ {{0x98c0, 0x6f10, 0x93a5, 0x27eb, 0x9ff4, 0x9ac0, 0x27ea, 0x9fee, 0x65e9, 0x2200, 0x80b4, 0x2518, 0x80d6, 0x9743, 0x90c0, 0x94c8 }, 16, 0x000b7240, 1},
+ {{0x421a, 0x461b, 0x98c0, 0x65e9, 0xc947, 0x27ec, 0x9ff4, 0x96c0, 0x8057, 0x27ea, 0x9fee, 0x96c0, 0x9b43, 0x2b03, 0x800e, 0x3420 }, 16, 0x000b7260, 1},
+ {{0xa000, 0xe918, 0x9ac0, 0x6c90, 0x2500, 0x80ff, 0x666a, 0x92b9, 0x3620, 0xa000, 0xfdae, 0x8429, 0x3b80, 0x32e0, 0x8008, 0x90c0 }, 16, 0x000b7280, 1},
+ {{0x3420, 0xa000, 0xeb1d, 0x96bb, 0x6daa, 0x65e6, 0x756b, 0x3612, 0x80fe, 0x94c7, 0xd2db, 0x6c90, 0x96d0, 0x74ed, 0x411c, 0xe918 }, 16, 0x000b72a0, 1},
+ {{0x411a, 0x90c0, 0x9ac0, 0x6c90, 0x6e90, 0x6d10, 0x5617, 0x90c0, 0x96c0, 0xcc41, 0x27ea, 0x9fee, 0x27e9, 0x9fa4, 0x98c0, 0xecfc }, 16, 0x000b72c0, 1},
+ {{0x3b80, 0x32e0, 0x8008, 0xea1c, 0x3820, 0xa000, 0x5712, 0x27ea, 0x9ff4, 0x3600, 0xa004, 0x73f6, 0xec1a, 0x94c7, 0x801f, 0x76d0 }, 16, 0x000b72e0, 1},
+ {{0x5c14, 0x90c0, 0xecfc, 0xec19, 0x5a14, 0x90c0, 0x98c0, 0xea1b, 0x3064, 0x331a, 0x800b, 0x92ba, 0x78c1, 0x74e9, 0xd4a1, 0xd2d0 }, 16, 0x000b7300, 1},
+ {{0x76ed, 0x66e9, 0x81ad, 0x3164, 0x332e, 0x800b, 0x92be, 0x94d0, 0x7bc1, 0x9286, 0x90c0, 0x90c0, 0x27ed, 0x9f08, 0xe7ed, 0x94c0 }, 16, 0x000b7320, 1},
+ {{0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x3064, 0x3186, 0x800b, 0x94c0, 0xf9fd, 0xcf41, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b7340, 1},
+ {{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6d10, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x2704 }, 16, 0x000b7360, 1},
+ {{0x8387, 0x3c00, 0xa100, 0x270e, 0x8b00, 0x90c0, 0x290f, 0x85a5, 0x3640, 0xa000, 0xe7ee, 0xeaef, 0x92c8, 0x9282, 0x3820, 0xa000 }, 16, 0x000b7380, 1},
+ {{0xeeef, 0x2b00, 0x849d, 0x9765, 0xee3b, 0xedee, 0x92c8, 0x429d, 0x9765, 0x27ec, 0x9e90, 0x92c8, 0x429c, 0x96c0, 0x5110, 0x280a }, 16, 0x000b73a0, 1},
+ {{0x8028, 0x3840, 0xa000, 0x5512, 0x2000, 0x8081, 0x3b1a, 0x8002, 0x6569, 0x841d, 0xd0a2, 0x90c0, 0x96c2, 0x3d20, 0x2252, 0x800c }, 16, 0x000b73c0, 1},
+ {{0x3623, 0xa000, 0x2000, 0x8081, 0x3422, 0xa000, 0x50d5, 0x3c40, 0xa104, 0x6461, 0x6e90, 0xeb3b, 0x2f0b, 0x87c3, 0x3ac0, 0xa004 }, 16, 0x000b73e0, 1},
+ {{0x646a, 0xefef, 0x290a, 0x8b64, 0x9ac0, 0x27ec, 0x955c, 0x90c0, 0x2718, 0x8504, 0x3c80, 0xa100, 0x290d, 0x8626, 0x90c0, 0x27ee }, 16, 0x000b7400, 1},
+ {{0x9558, 0x3482, 0x3118, 0x8008, 0x3c80, 0xa000, 0x27e9, 0x9964, 0x90c0, 0x27e9, 0x9960, 0x33e1, 0x3e08, 0x800b, 0x9ac0, 0x07fa }, 16, 0x000b7420, 1},
+ {{0x954c, 0x90c0, 0x0ef8, 0x9548, 0x9ac0, 0x0af8, 0x9544, 0x90c0, 0x03fa, 0x9540, 0x94c0, 0x6f90, 0x9742, 0x9ac0, 0x7457, 0x27ed }, 16, 0x000b7440, 1},
+ {{0x9fd4, 0x74d7, 0xc4ff, 0x3ac0, 0x3650, 0x8009, 0x27ee, 0x9fc0, 0x3610, 0x2000, 0x8000, 0x94d0, 0x469e, 0x441d, 0xc01a, 0x37d0 }, 16, 0x000b7460, 1},
+ {{0x1610, 0xca45, 0x96c0, 0x7b61, 0xce43, 0xc355, 0x276a, 0x3de0, 0x3a00, 0x800b, 0x96c0, 0xea1e, 0x2718, 0x81be, 0x3a40, 0xa000 }, 16, 0x000b7480, 1},
+ {{0x3ec0, 0x3650, 0x8009, 0xed1b, 0x96c0, 0xfe46, 0x01fa, 0x9520, 0x3c20, 0xa000, 0x00f8, 0x9550, 0x90c0, 0x0bf8, 0x9538, 0x9ac0 }, 16, 0x000b74a0, 1},
+ {{0x08f8, 0x953c, 0x90c0, 0x02fa, 0x9534, 0x9ac0, 0x04fa, 0x9530, 0x90c0, 0x05f8, 0x952c, 0x9ac0, 0x0cf8, 0x9528, 0x90c0, 0x06fa }, 16, 0x000b74c0, 1},
+ {{0x9524, 0x3c80, 0xa000, 0xe9ea, 0x05fa, 0x951c, 0x90c0, 0x90c0, 0x3600, 0xa100, 0x549d, 0x5299, 0x98c0, 0xf44a, 0x34e0, 0x3fff }, 16, 0x000b74e0, 1},
+ {{0x800f, 0x168d, 0xf1ca, 0x3800, 0xa100, 0x64e6, 0x5089, 0xf248, 0x96c0, 0x7271, 0xf649, 0xf047, 0x96c0, 0x8445, 0x27e8, 0x9fdc }, 16, 0x000b7500, 1},
+ {{0x5290, 0x6566, 0x7272, 0x94c0, 0xf6c8, 0x8437, 0x96c0, 0x6766, 0x27ec, 0x9fe4, 0x3276, 0x5194, 0x94c0, 0x64e6, 0x8425, 0x7271 }, 16, 0x000b7520, 1},
+ {{0x94c0, 0xf6ca, 0x841d, 0x3f48, 0xf0c8, 0x3c48, 0xf64a, 0x1090, 0xf048, 0x3c48, 0x5494, 0x3e48, 0x4090, 0x4494, 0x94c0, 0xf4c8 }, 16, 0x000b7540, 1},
+ {{0xf6c7, 0x94c0, 0xf2ca, 0xf1c9, 0x94c0, 0xf444, 0xf643, 0x94c0, 0xf242, 0xf141, 0x9ac0, 0x27ea, 0x9fb8, 0x90c0, 0x09f8, 0x9518 }, 16, 0x000b7560, 1},
+ {{0x3284, 0x2720, 0x800b, 0x9ac0, 0x01fa, 0x9514, 0x90c0, 0x0df8, 0x9510, 0x94c0, 0xf2d2, 0xf0d1, 0x029e, 0x19f8, 0x9518, 0x008e }, 16, 0x000b7580, 1},
+ {{0x18f8, 0x9520, 0x94c0, 0xc116, 0xf4d2, 0x0091, 0xf6d1, 0x0190, 0xf442, 0x3284, 0x28a0, 0x800b, 0x96c0, 0xf641, 0x27ea, 0x9fc8 }, 16, 0x000b75a0, 1},
+ {{0x9747, 0x9ac0, 0x27e8, 0x9fc8, 0x90c0, 0x1df8, 0x9510, 0x9ac0, 0x11fa, 0x9514, 0x90c0, 0x19f8, 0x9518, 0x90e0, 0x94c8, 0x9086 }, 16, 0x000b75c0, 1},
+ {{0x90e0, 0x98c0, 0x1cf8, 0x953c, 0x7bc1, 0x909e, 0x96c0, 0xfec6, 0x1af8, 0x9528, 0x1214, 0x1cf8, 0x9524, 0x98c0, 0x7961, 0xc11e }, 16, 0x000b75e0, 1},
+ {{0x2d0d, 0x8408, 0x3aa0, 0xa000, 0x7177, 0x4094, 0x2909, 0x8408, 0x2cff, 0x9ee1, 0x0192, 0xfe46, 0x3c40, 0xa000, 0x18f8, 0x953c }, 16, 0x000b7600, 1},
+ {{0x90c0, 0x10f8, 0x9550, 0x9ac0, 0x1bf8, 0x9538, 0x90c0, 0x12fa, 0x9534, 0x9ac0, 0x14fa, 0x9530, 0x90c0, 0x15f8, 0x952c, 0x96c0 }, 16, 0x000b7620, 1},
+ {{0xecea, 0x16fa, 0x9524, 0x9ac0, 0x11fa, 0x9520, 0x90c0, 0x15fa, 0x951c, 0x98c0, 0x27ea, 0x9e90, 0x6f10, 0xc7a5, 0x3c00, 0xa100 }, 16, 0x000b7640, 1},
+ {{0x27ee, 0x9f24, 0x90c0, 0x27eb, 0x9d68, 0x3a00, 0xa100, 0x3722, 0x2206, 0x800c, 0xe8ea, 0x3c20, 0xa000, 0x00f8, 0x9550, 0x90c0 }, 16, 0x000b7660, 1},
+ {{0x0bf8, 0x9538, 0x9ac0, 0x0ff8, 0x950c, 0x90c0, 0x02fa, 0x9534, 0x9ac0, 0x05f8, 0x952c, 0x90c0, 0x0cf8, 0x9528, 0x9ac0, 0x06fa }, 16, 0x000b7680, 1},
+ {{0x9524, 0x90c0, 0x01fa, 0x9520, 0x9ac0, 0x09f8, 0x9518, 0x90c0, 0x05fa, 0x951c, 0x3680, 0xa100, 0x505f, 0x5254, 0x9ac0, 0x27ea }, 16, 0x000b76a0, 1},
+ {{0x9fd0, 0x60b2, 0x08f8, 0x953c, 0x9ac0, 0x04fa, 0x9530, 0x7cc4, 0x03fa, 0x9508, 0x96c0, 0xf146, 0x07fa, 0x9504, 0x32e4, 0x20ca }, 16, 0x000b76c0, 1},
+ {{0x800a, 0x3640, 0xa000, 0xf0c6, 0xefe8, 0x9ac0, 0x18f8, 0x953c, 0x90c0, 0x27ed, 0x9fd2, 0x9ac0, 0x02fc, 0x9fd0, 0x90c0, 0x13fa }, 16, 0x000b76e0, 1},
+ {{0x9508, 0x3840, 0xa000, 0xd91a, 0x5410, 0x5155, 0x3c80, 0xa004, 0x7a61, 0xd999, 0xe8ef, 0x14fa, 0x9530, 0x3c80, 0xb00c, 0x666a }, 16, 0x000b7700, 1},
+ {{0x74d4, 0xc21b, 0x17fa, 0x9504, 0x3840, 0xa104, 0x78e1, 0x5790, 0x849f, 0x3a40, 0xa000, 0x3bc0, 0x3650, 0x8009, 0x9b41, 0x9ac0 }, 16, 0x000b7720, 1},
+ {{0x03fc, 0x9fd0, 0x90c0, 0x2b03, 0x8036, 0x96c0, 0xc51b, 0x27ea, 0x9fc0, 0x3c20, 0xa000, 0x7554, 0x27ef, 0x9fd4, 0x7455, 0x5192 }, 16, 0x000b7740, 1},
+ {{0x22f5, 0x6274, 0x2ef5, 0x6e74, 0x98c0, 0x6d15, 0x7657, 0x2103, 0x8048, 0x76d2, 0x3a00, 0xa808, 0x72f1, 0xd7c5, 0xc31b, 0x4596 }, 16, 0x000b7760, 1},
+ {{0x3453, 0x03fc, 0x9fd0, 0x3a16, 0xa002, 0x90c0, 0x63f4, 0x4592, 0x60f5, 0x3e06, 0xa002, 0x90c0, 0xea44, 0x90c0, 0x6cf5, 0x4617 }, 16, 0x000b7780, 1},
+ {{0x6ff4, 0x3820, 0xa800, 0x6ea7, 0xef42, 0x5192, 0x37d4, 0x7555, 0x3800, 0xa808, 0x7171, 0xd7c2, 0x4296, 0x34a0, 0xa000, 0x4790 }, 16, 0x000b77a0, 1},
+ {{0x94c2, 0x4292, 0x4617, 0x3a80, 0xa000, 0x7be1, 0x7b41, 0xe844, 0xee44, 0x67ea, 0x2dff, 0x9ee1, 0x3e00, 0xa002, 0x6c90, 0x1bf8 }, 16, 0x000b77c0, 1},
+ {{0x9538, 0x666a, 0x15fa, 0x951c, 0x3c20, 0xa000, 0x10f8, 0x9550, 0x6d10, 0x1ff8, 0x950c, 0x9ac0, 0x12fa, 0x9534, 0x90c0, 0x15f8 }, 16, 0x000b77e0, 1},
+ {{0x952c, 0x9ac0, 0x1cf8, 0x9528, 0x90c0, 0x16fa, 0x9524, 0x9ac0, 0x11fa, 0x9520, 0x90c0, 0x19f8, 0x9518, 0x84c4, 0x3a00, 0xa100 }, 16, 0x000b7800, 1},
+ {{0x33e0, 0x3e08, 0x800b, 0xe8eb, 0x38a0, 0xa100, 0xe81d, 0x27ef, 0x9fd4, 0x9cc0, 0x13fa, 0x954c, 0x90c0, 0x1af8, 0x9548, 0x90c0 }, 16, 0x000b7820, 1},
+ {{0x9ec0, 0x1df8, 0x9544, 0x90c0, 0x1ef8, 0x9540, 0x90c0, 0x90c0, 0x3aa0, 0xa000, 0x5e1f, 0x3c80, 0x32e0, 0x8008, 0xe9eb, 0x36c0 }, 16, 0x000b7840, 1},
+ {{0xa000, 0xeef3, 0xec1e, 0x94c0, 0x97bc, 0x844b, 0x3880, 0xa100, 0x78c1, 0x9798, 0xeefe, 0x3600, 0xa100, 0x5615, 0xee1a, 0x3cc0 }, 16, 0x000b7860, 1},
+ {{0xa100, 0x3d1c, 0x8040, 0x5096, 0x2808, 0x8081, 0x6669, 0x92c2, 0x7841, 0x3683, 0xa000, 0x5792, 0x5616, 0x92c3, 0xd79e, 0x92c3 }, 16, 0x000b7880, 1},
+ {{0x6c43, 0x3a80, 0xa000, 0x4096, 0x3064, 0x38c4, 0x800b, 0x919f, 0x94c0, 0x6f90, 0x9747, 0x3420, 0xa000, 0xe91b, 0x92d0, 0x9799 }, 16, 0x000b78a0, 1},
+ {{0x2909, 0x8081, 0x3941, 0x5010, 0x7861, 0x7072, 0x8185, 0x9ac0, 0x1cf8, 0x9528, 0x90c0, 0x16fa, 0x9524, 0x19f8, 0x9518, 0x3a80 }, 16, 0x000b78c0, 1},
+ {{0xa004, 0x7861, 0x7ac8, 0xe948, 0xeb41, 0x3880, 0xa004, 0x646a, 0xe948, 0xee48, 0x3680, 0xa000, 0xec42, 0xec48, 0x2cff, 0x9b59 }, 16, 0x000b78e0, 1},
+ {{0x3680, 0xa000, 0xea44, 0xef41, 0x1ef8, 0x9548, 0x9764, 0x27e9, 0x9e90, 0x5099, 0x94c8, 0x409e, 0x5099, 0x4096, 0x27ee, 0x9500 }, 16, 0x000b7900, 1},
+ {{0xe7ee, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x96c0, 0x6f10, 0x9620, 0x9720, 0x9ac0, 0x290c, 0x892c, 0x90c0 }, 16, 0x000b7920, 1},
+ {{0x2809, 0x8004, 0x94c0, 0x9e20, 0x9f20, 0x94c0, 0x5011, 0x92bc, 0x96c0, 0x7160, 0x270a, 0x8020, 0x96c0, 0xe7ea, 0x2518, 0x810e }, 16, 0x000b7940, 1},
+ {{0x3f80, 0x3304, 0x8008, 0x90c0, 0x94bf, 0x6c7d, 0x4411, 0x0185, 0x32e0, 0x8008, 0x7271, 0x8417, 0x3e80, 0x32e0, 0x8008, 0x90c0 }, 16, 0x000b7960, 1},
+ {{0xee41, 0x94c0, 0x7b41, 0x95a6, 0x7275, 0x81f9, 0x6769, 0x802d, 0x9ac0, 0x76d6, 0xce46, 0x3a80, 0x32e0, 0x8008, 0x3ae1, 0x3b80 }, 16, 0x000b7980, 1},
+ {{0x32e0, 0x8008, 0x94c0, 0xcd45, 0xea1e, 0x97ba, 0x2d17, 0xed1b, 0x90bd, 0x6d80, 0x7173, 0x92c2, 0x7b61, 0x9cc0, 0x7f41, 0x6e90 }, 16, 0x000b79a0, 1},
+ {{0x3b20, 0x2206, 0x800c, 0xfc44, 0x96c0, 0xcd46, 0x2200, 0x8081, 0x98c0, 0x3e80, 0x3118, 0x8008, 0xf943, 0xed1b, 0x5355, 0xf345 }, 16, 0x000b79c0, 1},
+ {{0x1610, 0xc481, 0x9ac0, 0xd721, 0xcd45, 0x3f20, 0x2258, 0x800c, 0x8461, 0x94c0, 0xef1d, 0xf246, 0xf547, 0x1756, 0xf6c5, 0x96c0 }, 16, 0x000b79e0, 1},
+ {{0x603f, 0xf448, 0xc84f, 0x9ac0, 0x3a01, 0x8004, 0x90c0, 0x3606, 0x8004, 0x3801, 0x8004, 0xd991, 0xd5c6, 0x7dc4, 0x98c0, 0xf342 }, 16, 0x000b7a00, 1},
+ {{0x3284, 0x2b30, 0x800b, 0xf0c2, 0x3284, 0x2b50, 0x800b, 0x3750, 0xf0c2, 0x96c0, 0x77d0, 0xc847, 0xf4c8, 0x98c0, 0x7a41, 0x4e57 }, 16, 0x000b7a20, 1},
+ {{0x2f0f, 0x8204, 0x5310, 0x71f4, 0x81b3, 0x94c0, 0xf2c6, 0xf5c7, 0x3ac4, 0xee42, 0x7961, 0x656a, 0x8189, 0x94c0, 0xf9c3, 0xfcc4 }, 16, 0x000b7a40, 1},
+ {{0x90c0, 0x5411, 0x949c, 0xc56d, 0x1005, 0xa004, 0x90c0, 0x90c0, 0x3a00, 0xa008, 0x6e10, 0x6e90, 0xffcf, 0xfdd0, 0x96c0, 0xcc54 }, 16, 0x000b7a60, 1},
+ {{0x2204, 0x8081, 0x9ac0, 0x2b03, 0x80dc, 0x90c0, 0x2a03, 0x8044, 0x96c0, 0xcd55, 0x2b02, 0x8002, 0x90c0, 0x3800, 0xa100, 0xfecf }, 16, 0x000b7a80, 1},
+ {{0x2f0d, 0x8004, 0x94c0, 0xfbd0, 0xed44, 0x3cc0, 0xa000, 0x2f0b, 0x8408, 0x90c0, 0x2321, 0x8aab, 0x3a40, 0xa000, 0x3122, 0x2660 }, 16, 0x000b7aa0, 1},
+ {{0x800c, 0xca83, 0x2a02, 0x8102, 0x3640, 0xa100, 0x5710, 0x56bd, 0x3e20, 0xa000, 0xd7a1, 0x7be1, 0x54be, 0x3920, 0x2258, 0x800c }, 16, 0x000b7ac0, 1},
+ {{0x3a00, 0xa100, 0x7be1, 0xcf45, 0x2718, 0x80f2, 0x94c0, 0xcc5c, 0x9b47, 0x3640, 0xa000, 0xcc44, 0xef1b, 0x96c0, 0x50b7, 0x2f0a }, 16, 0x000b7ae0, 1},
+ {{0x8004, 0x3a00, 0xa004, 0x7450, 0x7750, 0xe91c, 0x52b2, 0x98c0, 0x290c, 0x8002, 0x7652, 0x5371, 0x3600, 0xa004, 0x74d3, 0x5574 }, 16, 0x000b7b00, 1},
+ {{0x3e00, 0xa847, 0x63f4, 0x77d5, 0x74d3, 0x7452, 0x90c0, 0x90c0, 0x3e00, 0xb08d, 0x6177, 0x6074, 0x60f6, 0x77d3, 0x90c0, 0x90c0 }, 16, 0x000b7b20, 1},
+ {{0x3e00, 0xa002, 0x74d5, 0x7652, 0x7750, 0x6c75, 0x90c0, 0x90c0, 0x3e00, 0xa00d, 0x6ff7, 0x6d74, 0x6cf6, 0x2103, 0x8072, 0x90c0 }, 16, 0x000b7b40, 1},
+ {{0x3e00, 0xbe53, 0x6c8a, 0x7651, 0x6d57, 0x75d0, 0x50b7, 0x5371, 0x3e00, 0xa413, 0x7750, 0x77d3, 0x6e48, 0x6f59, 0x5574, 0x52b2 }, 16, 0x000b7b60, 1},
+ {{0x3a00, 0xa006, 0x63f7, 0x77d5, 0x7750, 0x7452, 0x3a00, 0xa006, 0x6177, 0x7752, 0x77d3, 0x74d5, 0x3a10, 0xa84c, 0x60f4, 0x6077 }, 16, 0x000b7b80, 1},
+ {{0x77d5, 0x74d3, 0x3a00, 0xa003, 0x7750, 0x7652, 0x6ff4, 0x6c75, 0x3600, 0xa00c, 0x6cf6, 0x6d77, 0x3820, 0xa000, 0x3300, 0x2000 }, 16, 0x000b7ba0, 1},
+ {{0xaaab, 0x3600, 0xb8c0, 0x6d0a, 0x6f57, 0x3600, 0xa0cc, 0x6e46, 0x6f52, 0x5f10, 0x90c0, 0xef61, 0x3420, 0xa000, 0xef8a, 0x94c0 }, 16, 0x000b7bc0, 1},
+ {{0xeffe, 0x8089, 0x3820, 0xb800, 0x74d3, 0x75d3, 0xef19, 0x5997, 0x90c0, 0x9961, 0x3c00, 0xa00c, 0x7e61, 0x7f61, 0x3064, 0x3c6e }, 16, 0x000b7be0, 1},
+ {{0x800b, 0x3600, 0xa00c, 0x6665, 0x6765, 0x3600, 0xa00c, 0x7f62, 0x7e62, 0x3600, 0xb804, 0x7556, 0x7454, 0x3600, 0xa004, 0x6565 }, 16, 0x000b7c00, 1},
+ {{0x6465, 0x3800, 0xaa08, 0x7552, 0x63f4, 0x74d3, 0x3600, 0xa008, 0x62f5, 0x6ff4, 0x3600, 0xb8c8, 0x6ef5, 0x6e57, 0x3c00, 0xa80c }, 16, 0x000b7c20, 1},
+ {{0x6f5a, 0x6665, 0x3064, 0x3c6e, 0x800b, 0x3400, 0xa004, 0x6765, 0x3c00, 0xa00c, 0x7e62, 0x7f62, 0x3064, 0x3c6e, 0x800b, 0x3600 }, 16, 0x000b7c40, 1},
+ {{0xa00c, 0x6665, 0x6765, 0x3600, 0xa00c, 0x6665, 0x6765, 0x3820, 0xa004, 0x7ac8, 0xcc5c, 0x44bb, 0x7a44, 0x92d0, 0xcc54, 0x90c0 }, 16, 0x000b7c60, 1},
+ {{0x3420, 0xa000, 0x46bd, 0xcd5d, 0xc565, 0x90c0, 0x90c0, 0x27ee, 0x9fe0, 0xe7ee, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721 }, 16, 0x000b7c80, 1},
+ {{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6d10, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x3382 }, 16, 0x000b7ca0, 1},
+ {{0x3304, 0x8008, 0x9ac0, 0x280f, 0x8004, 0x90c0, 0x270c, 0x8020, 0x3600, 0xa100, 0x5017, 0x94bb, 0x2c7d, 0xe7ec, 0x4417, 0x0085 }, 16, 0x000b7cc0, 1},
+ {{0x32e0, 0x8008, 0x7270, 0x8417, 0x3e80, 0x32e0, 0x8008, 0x90c0, 0xee41, 0x94c0, 0x7941, 0x97a6, 0x7277, 0x81f9, 0x6569, 0x802d }, 16, 0x000b7ce0, 1},
+ {{0x9ac0, 0x75d2, 0xce42, 0x3b80, 0x32e0, 0x8008, 0x39e1, 0x3a80, 0x32e0, 0x8008, 0x94c0, 0xcc43, 0xeb1e, 0x97bb, 0x2c17, 0xec1a }, 16, 0x000b7d00, 1},
+ {{0x91bc, 0x6c84, 0x7071, 0x92c2, 0x7961, 0x9cc0, 0x7d41, 0x6f10, 0x3c20, 0x2206, 0x800c, 0xf943, 0x96c0, 0xcd42, 0x2700, 0x8081 }, 16, 0x000b7d20, 1},
+ {{0x3e80, 0x3118, 0x8008, 0xed1c, 0x5455, 0xf444, 0x1110, 0xc581, 0x9ac0, 0xd4a1, 0xca46, 0x3d20, 0x2258, 0x800c, 0x8463, 0x94c0 }, 16, 0x000b7d40, 1},
+ {{0xed1a, 0xf745, 0xf646, 0x1256, 0xf3c4, 0x96c0, 0x61bd, 0xf547, 0xfd48, 0x9ac0, 0x3a61, 0x8005, 0xc84f, 0x3664, 0x8005, 0x3861 }, 16, 0x000b7d60, 1},
+ {{0x8005, 0xd811, 0xd444, 0x7c44, 0x98c0, 0xf042, 0x3284, 0x2b30, 0x800b, 0xf0c2, 0x3284, 0x2b50, 0x800b, 0x3750, 0xf0c2, 0x96c0 }, 16, 0x000b7d80, 1},
+ {{0x77d0, 0xfdc8, 0xc847, 0xf5c7, 0x98c0, 0x7ac1, 0x4e55, 0x2d0d, 0x8204, 0x5010, 0x7075, 0x81b1, 0x94c0, 0xf7c5, 0xf6c6, 0x3be1 }, 16, 0x000b7da0, 1},
+ {{0x3b44, 0xee42, 0x67ea, 0x8187, 0x96c0, 0xf9c3, 0x27eb, 0x9fe0, 0x1417, 0xe7eb, 0x94c0, 0x9e21, 0x9f21, 0x290a, 0x892c, 0x94c0 }, 16, 0x000b7dc0, 1},
+ {{0x9621, 0x9721, 0x9f70, 0x949a, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6e10, 0x2704, 0x8081, 0x280a, 0x829e, 0xebea, 0x92c8 }, 16, 0x000b7de0, 1},
+ {{0x9483, 0x94c0, 0xf087, 0x95a1, 0x246a, 0x7861, 0x94c0, 0xf486, 0x844d, 0x96c0, 0x6c95, 0xf385, 0x9b40, 0x96c0, 0xda91, 0x2b03 }, 16, 0x000b7e00, 1},
+ {{0x8020, 0x66e1, 0x66e6, 0xda9d, 0x72f3, 0x90c0, 0x92c3, 0xc381, 0x98c7, 0x2103, 0x8028, 0x90c0, 0x939a, 0x94c0, 0x92a1, 0xf185 }, 16, 0x000b7e20, 1},
+ {{0x2ea8, 0xea41, 0xd915, 0x6561, 0x6566, 0xd91a, 0x7171, 0x90d0, 0x92c3, 0xc281, 0x92c3, 0x929a, 0x9f71, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b7e40, 1},
+ {{0x98c0, 0x09c6, 0x38d0, 0x8008, 0xc381, 0x94c0, 0x9620, 0x9720, 0x96c0, 0xc683, 0x290c, 0x82c0, 0x98c0, 0x7456, 0x5714, 0x2100 }, 16, 0x000b7e60, 1},
+ {{0x8064, 0x96c0, 0x7657, 0x9e20, 0x9f20, 0x98c0, 0x6c7d, 0xeee8, 0x280f, 0x8002, 0x3840, 0xa000, 0x77d4, 0xc08a, 0xe748, 0x2f7c }, 16, 0x000b7e80, 1},
+ {{0x3020, 0x3333, 0x9573, 0x4716, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c08, 0x82c2, 0x3420, 0xa000, 0x5410, 0x3400, 0xa800, 0x76d4 }, 16, 0x000b7ea0, 1},
+ {{0x6d7d, 0x3400, 0xa004, 0x7655, 0x3a00, 0xa804, 0x6c7c, 0x32e4, 0x3c48, 0x8001, 0x3640, 0xa800, 0x74d4, 0x4417, 0x3e40, 0xa008 }, 16, 0x000b7ec0, 1},
+ {{0x77d0, 0x6c90, 0x0cc6, 0x38d0, 0x8008, 0xcaa2, 0x3c20, 0xa000, 0x6e90, 0x3b80, 0x3304, 0x8008, 0xc685, 0x9ac0, 0x2c0d, 0x82c4 }, 16, 0x000b7ee0, 1},
+ {{0x6c90, 0x2f0c, 0x8002, 0x94c0, 0x5415, 0x90bb, 0x3c20, 0xa000, 0x6c7d, 0x0085, 0x32e0, 0x8008, 0xc0a8, 0x3a40, 0xa000, 0x6c7c }, 16, 0x000b7f00, 1},
+ {{0xc8a4, 0x2482, 0x8000, 0x90c0, 0x041c, 0xc0fa, 0x3a40, 0xa000, 0x0ac6, 0x38d0, 0x8008, 0xcba5, 0x3a40, 0xa000, 0x3502, 0x378c }, 16, 0x000b7f20, 1},
+ {{0x800c, 0xc382, 0x9ac0, 0x2a0a, 0x82c6, 0x90c0, 0x2b00, 0x87c7, 0x3820, 0xa000, 0x5412, 0x2200, 0x8387, 0x3a40, 0xb80c, 0x6c7d }, 16, 0x000b7f40, 1},
+ {{0x7456, 0xf241, 0xcea0, 0x3600, 0xa904, 0x6c7c, 0xecf8, 0x3860, 0xa000, 0x4414, 0x2460, 0x9fff, 0x98c0, 0x08c6, 0x38d0, 0x8008 }, 16, 0x000b7f60, 1},
+ {{0xec45, 0x94c0, 0xeaec, 0xe9ec, 0x3820, 0xa000, 0xe8ed, 0x280d, 0x82c8, 0x1415, 0xe83b, 0x3800, 0xa004, 0x76d4, 0xea61, 0xe963 }, 16, 0x000b7f80, 1},
+ {{0x3400, 0xa804, 0x6d7d, 0x3400, 0xa800, 0x7655, 0x96c0, 0x6c7c, 0x2020, 0x8000, 0x949c, 0x98c0, 0x0dc6, 0x38d0, 0x8008, 0xec5d }, 16, 0x000b7fa0, 1},
+ {{0x90c0, 0x2d0b, 0x82ca, 0x3420, 0xa000, 0x5713, 0x3420, 0xa000, 0x979a, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0d, 0x82ce, 0x5415 }, 16, 0x000b7fc0, 1},
+ {{0x2c7c, 0xc090, 0x4411, 0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x2b0d, 0x82d0, 0x3420, 0xa000, 0x5215, 0x3420, 0xa000, 0x4214, 0x98c0 }, 16, 0x000b7fe0, 1},
+ {{0x0dc6, 0x38d0, 0x8008, 0xec44, 0x90c0, 0x2d0b, 0x82d2, 0x3420, 0xa000, 0x5513, 0x3400, 0xa804, 0x6d7c, 0x3420, 0xa000, 0x459c }, 16, 0x000b8000, 1},
+ {{0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x2b0d, 0x82d4, 0x3420, 0xa000, 0x5715, 0x3400, 0xa800, 0x7657, 0x2c7d, 0xc094, 0x3400, 0xa004 }, 16, 0x000b8020, 1},
+ {{0x77d4, 0x3400, 0xa804, 0x6f7c, 0x3420, 0xa000, 0x471c, 0x98c0, 0x0bc6, 0x38d0, 0x8008, 0xedec, 0x94c0, 0xed7c, 0xeaec, 0x3800 }, 16, 0x000b8040, 1},
+ {{0xa100, 0xea7b, 0x2b09, 0x82d6, 0x36a0, 0xa000, 0x5711, 0xebec, 0x3880, 0xa800, 0x7657, 0xeb7a, 0xefec, 0x38a0, 0xa000, 0x6c7d }, 16, 0x000b8060, 1},
+ {{0x7456, 0xef38, 0x3600, 0xa104, 0x77d4, 0xe8ec, 0x3640, 0xa904, 0x6f7c, 0xe83a, 0x3620, 0xa100, 0x4714, 0xeaec, 0x3a60, 0xa100 }, 16, 0x000b8080, 1},
+ {{0x09c6, 0x38d0, 0x8008, 0xea3e, 0x3480, 0xa000, 0xeeec, 0x38c0, 0xa100, 0xee78, 0x2909, 0x82d8, 0x36c0, 0xa000, 0x5211, 0xec3b }, 16, 0x000b80a0, 1},
+ {{0x351c, 0x800f, 0x6c7d, 0x949d, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0d, 0x82d8, 0x3420, 0xa000, 0x5215, 0x3600, 0xa804, 0x34c9 }, 16, 0x000b80c0, 1},
+ {{0x8104, 0x3400, 0xa800, 0x7571, 0x6e7d, 0x969a, 0x0ac6, 0x38d0, 0x8008, 0x90c0, 0x2a0d, 0x82da, 0x3420, 0xa000, 0x5215, 0x3420 }, 16, 0x000b80e0, 1},
+ {{0xa000, 0x4213, 0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x2b0a, 0x82dc, 0x5612, 0x3600, 0xa004, 0x3d19, 0x80ff, 0x34a0, 0xa000, 0x4117 }, 16, 0x000b8100, 1},
+ {{0x0ac6, 0x38d0, 0x8008, 0x90c0, 0x2a0d, 0x82dc, 0x3420, 0xa000, 0x5515, 0x3600, 0xa804, 0x3ac8, 0x8208, 0x34a0, 0xa000, 0x4010 }, 16, 0x000b8120, 1},
+ {{0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0b, 0x82de, 0x5613, 0x3cce, 0x8104, 0x3600, 0xa004, 0x7576, 0xc55e, 0x3400, 0xa804, 0x6e7d }, 16, 0x000b8140, 1},
+ {{0x3640, 0xa104, 0xd724, 0x4612, 0x90c0, 0x3422, 0xa000, 0xc584, 0x34a2, 0xa000, 0x4512, 0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x2b0a }, 16, 0x000b8160, 1},
+ {{0x82e6, 0x3420, 0xa000, 0x5012, 0x34a0, 0xa000, 0x401e, 0x3a40, 0xa000, 0x0dc6, 0x38d0, 0x8008, 0xeaee, 0xea68, 0x2d0d, 0x82e8 }, 16, 0x000b8180, 1},
+ {{0x5215, 0x3480, 0xa000, 0x4216, 0x3a00, 0xa100, 0x0bc6, 0x38d0, 0x8008, 0xee48, 0x90c0, 0x2b0d, 0x82e0, 0x3420, 0xa000, 0x5615 }, 16, 0x000b81a0, 1},
+ {{0x3660, 0xa000, 0x4612, 0xc683, 0x5911, 0x90c0, 0x3480, 0xa000, 0xec39, 0x34a0, 0xa000, 0x4c16, 0x3480, 0xa000, 0xee78, 0x34a0 }, 16, 0x000b81c0, 1},
+ {{0xa000, 0x969e, 0x3420, 0xa000, 0x939c, 0xec51, 0x939c, 0xec43, 0x94c0, 0xedec, 0x939c, 0x94c0, 0xeaec, 0xed62, 0x94c0, 0x939d }, 16, 0x000b81e0, 1},
+ {{0xea61, 0x94c0, 0x939a, 0xec53, 0x3a20, 0xa000, 0x4414, 0x32e4, 0x3c8a, 0x8001, 0x3480, 0xa000, 0x4515, 0x98c0, 0x6c90, 0xc556 }, 16, 0x000b8200, 1},
+ {{0x2c00, 0x8848, 0x2300, 0x8081, 0x3620, 0xa000, 0xe8ed, 0xf341, 0x32e4, 0x3c8a, 0x8001, 0xe83c, 0x98c0, 0x6c90, 0xc556, 0x2900 }, 16, 0x000b8220, 1},
+ {{0x8d68, 0x2300, 0x8102, 0x3620, 0xa000, 0xe8ed, 0xf341, 0x32e4, 0x3c8a, 0x8001, 0xe839, 0x98c0, 0x6c90, 0xc556, 0x2900, 0x8a4d }, 16, 0x000b8240, 1},
+ {{0x2500, 0x8204, 0x3620, 0xa000, 0xe8ed, 0xf541, 0x32e4, 0x3c8a, 0x8001, 0xe839, 0x98c0, 0x6c90, 0xc556, 0x2d00, 0x8849, 0x3a20 }, 16, 0x000b8260, 1},
+ {{0xa000, 0x3360, 0x3a54, 0x805f, 0x9763, 0x3a80, 0xa000, 0xed3d, 0x3880, 0x3296, 0x8008, 0x3480, 0xa000, 0x919d, 0x1158, 0x0102 }, 16, 0x000b8280, 1},
+ {{0x2a20, 0x800c, 0x1517, 0x3f20, 0x2206, 0x800c, 0x3c00, 0xa060, 0x3464, 0x8005, 0x90c0, 0x3663, 0x8005, 0x3600, 0xa040, 0x3064 }, 16, 0x000b82a0, 1},
+ {{0x8005, 0xd814, 0xd443, 0x6274, 0x2e74, 0x5158, 0x3554, 0x6274, 0x96d0, 0x6e74, 0x774a, 0x5158, 0x3554, 0x2274, 0x465f, 0x9ac0 }, 16, 0x000b82c0, 1},
+ {{0x6e74, 0x2600, 0x8081, 0x74ca, 0xc381, 0x34cc, 0x015f, 0x3820, 0x2104, 0x800c, 0x4157, 0x32e4, 0x3c48, 0x8001, 0x3457, 0x74d3 }, 16, 0x000b82e0, 1},
+ {{0x98c0, 0x3102, 0x8080, 0x7b61, 0x79c1, 0x3d68, 0x676a, 0x7d48, 0x6565, 0x7d48, 0x94c0, 0x755a, 0x81e2, 0x4258, 0x32e4, 0x3c48 }, 16, 0x000b8300, 1},
+ {{0x8001, 0x34d5, 0x3020, 0x3333, 0x9573, 0x98c0, 0x3300, 0x2000, 0x8001, 0xe8ee, 0x9ac0, 0xd5c0, 0x7c41, 0x3100, 0x2000, 0x8001 }, 16, 0x000b8320, 1},
+ {{0x9cc0, 0x6cd1, 0x2401, 0x8081, 0x65ea, 0x2501, 0x8081, 0x9ac7, 0x64ea, 0x79c1, 0x3f20, 0x2252, 0x800c, 0x9ac7, 0x75c3, 0x78c1 }, 16, 0x000b8340, 1},
+ {{0x3900, 0x2a20, 0x800c, 0x344b, 0x74c1, 0x2c7d, 0x34c9, 0x0023, 0x2250, 0x800c, 0x2d7d, 0x0423, 0x2250, 0x800c, 0x0157, 0x3264 }, 16, 0x000b8360, 1},
+ {{0x3cb0, 0x800b, 0x4557, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b8380, 1},
+ {{0x3064, 0x3e60, 0x800b, 0x3820, 0x20bc, 0x800c, 0x90c0, 0x90c0, 0x3e00, 0xa10c, 0x7456, 0x74d7, 0x3d20, 0x20ca, 0x800c, 0xe8ee }, 16, 0x000b83a0, 1},
+ {{0x9ac0, 0x2709, 0x8088, 0x90c0, 0x2400, 0x8081, 0x1015, 0xed53, 0x96c0, 0x6c7d, 0x96bd, 0xe7e9, 0x3c00, 0xa100, 0x6769, 0xe9ef }, 16, 0x000b83c0, 1},
+ {{0x3e00, 0x2cbe, 0x800c, 0x9ac0, 0x27e9, 0x9f78, 0x90c0, 0x2518, 0x80c6, 0x2704, 0x8080, 0x96c0, 0xebee, 0x2700, 0x8081, 0x95a3 }, 16, 0x000b83e0, 1},
+ {{0x94c8, 0x9581, 0x95a3, 0x96c0, 0x6f10, 0xeaed, 0x9a47, 0x96c0, 0xea6f, 0x2a03, 0x8018, 0x94c0, 0x9599, 0x5512, 0x98c0, 0xeaee }, 16, 0x000b8400, 1},
+ {{0x3001, 0x2d3f, 0x800c, 0x94c0, 0x6d10, 0x91ba, 0x64e9, 0x8031, 0x98c0, 0x66ea, 0x74d5, 0xc946, 0xc840, 0x94c0, 0x78e1, 0x8423 }, 16, 0x000b8420, 1},
+ {{0x9f41, 0xe918, 0x96c0, 0x93b9, 0x2909, 0x8081, 0x2103, 0x800e, 0x98c8, 0xdd1b, 0x93b9, 0x2909, 0x8081, 0xdd1b, 0x929a, 0x94d0 }, 16, 0x000b8440, 1},
+ {{0x7b41, 0xea41, 0x90c0, 0x90c0, 0x9cc0, 0x7ae1, 0x2e09, 0x8285, 0x6f10, 0x2b03, 0x8028, 0x94c0, 0x93b9, 0x9b47, 0x96c0, 0x72e3 }, 16, 0x000b8460, 1},
+ {{0x27e8, 0x9f78, 0x94c1, 0x79c1, 0x6d10, 0x94c1, 0x9399, 0x9299, 0x98c0, 0x6461, 0x7b41, 0x97b9, 0xcc46, 0x96c0, 0x3e17, 0x8081 }, 16, 0x000b8480, 1},
+ {{0x92a0, 0xd7c0, 0xce47, 0x90d0, 0xee1c, 0x929e, 0x2f10, 0xebed, 0xeb62, 0x95bb, 0x26e9, 0x6e90, 0x2518, 0x80fe, 0x266a, 0x34d4 }, 16, 0x000b84a0, 1},
+ {{0x3800, 0x2cbe, 0x800c, 0x8447, 0xd622, 0x801f, 0x96c0, 0x9b41, 0x2b03, 0x800c, 0x90c0, 0x90c0, 0x92d0, 0x97a0, 0x67e9, 0x92c3 }, 16, 0x000b84c0, 1},
+ {{0x7b41, 0x3184, 0x250c, 0x800b, 0x94c0, 0x78e2, 0x90a0, 0x96c0, 0x6469, 0x9f41, 0x90a0, 0x90c0, 0x90c0, 0x96cf, 0x6469, 0x7b41 }, 16, 0x000b84e0, 1},
+ {{0x90a0, 0x94c7, 0x6469, 0x7b41, 0x92c3, 0x7b41, 0x9ac0, 0x3614, 0x8080, 0xc844, 0x2700, 0x8081, 0x94c0, 0x6c97, 0x8057, 0x98c0 }, 16, 0x000b8500, 1},
+ {{0xd4a2, 0x3001, 0x2cbe, 0x800c, 0xcc40, 0x8020, 0xec18, 0x96c0, 0x9b41, 0x2b03, 0x800c, 0x90c0, 0x90c0, 0x92d0, 0x92a4, 0x6569 }, 16, 0x000b8520, 1},
+ {{0x92c3, 0x7ac1, 0x3184, 0x256e, 0x800b, 0x94c0, 0x78e2, 0x92a4, 0x96c0, 0x6569, 0x9f41, 0x92a4, 0x90c0, 0x90c0, 0x96cf, 0x6569 }, 16, 0x000b8540, 1},
+ {{0x7ac1, 0x92a4, 0x94c7, 0x6569, 0x7ac1, 0x92c3, 0x7ac1, 0x72f6, 0x8429, 0x9cc0, 0x6d90, 0x3614, 0x8080, 0xc844, 0x2700, 0x8081 }, 16, 0x000b8560, 1},
+ {{0x8017, 0x3201, 0x2cbe, 0x800c, 0x2d17, 0xc942, 0x9f42, 0xe918, 0x90c0, 0x92c8, 0x9381, 0x6e90, 0x9ac0, 0x6f5a, 0xed71, 0x3900 }, 16, 0x000b8580, 1},
+ {{0x2cbe, 0x800c, 0x5015, 0x3076, 0x6c10, 0x840d, 0x2704, 0x8081, 0x90c0, 0x92c8, 0x9081, 0x3c20, 0xac00, 0x77d1, 0x27ee, 0x9f78 }, 16, 0x000b85a0, 1},
+ {{0x7750, 0xefe9, 0xe7ee, 0x3620, 0xa000, 0xeee8, 0x9f71, 0x90c0, 0x3a00, 0xa00c, 0x7456, 0x74d7, 0x2704, 0x8081, 0x3880, 0xa100 }, 16, 0x000b85c0, 1},
+ {{0xe8ee, 0x290b, 0x819c, 0x36c0, 0xa000, 0xe9ef, 0xeeeb, 0x96c0, 0xe84b, 0x2600, 0x8081, 0x92d0, 0x92f8, 0x421e, 0x3840, 0xa000 }, 16, 0x000b85e0, 1},
+ {{0xeae8, 0x2b0e, 0x8102, 0x94c0, 0xefee, 0xea61, 0x94c0, 0x92a7, 0x93fa, 0x3a40, 0xa000, 0x280d, 0x8001, 0xd121, 0xeceb, 0x98c7 }, 16, 0x000b8600, 1},
+ {{0x2b03, 0x8026, 0x90c0, 0x7573, 0x94c1, 0x91fd, 0x94f8, 0x98c7, 0x2304, 0x8080, 0x90c0, 0x6e98, 0x96c1, 0x75d5, 0x4414, 0x4514 }, 16, 0x000b8620, 1},
+ {{0x92c2, 0x93f8, 0x94c0, 0x95a7, 0xec42, 0xd2a1, 0x92c3, 0x7673, 0x94d1, 0x97fd, 0x95f8, 0x94c1, 0x6fb7, 0x4514, 0x96c1, 0x75d7 }, 16, 0x000b8640, 1},
+ {{0x93f8, 0x4714, 0x9ac0, 0x2304, 0x8082, 0x90c0, 0x2b03, 0x8010, 0x2909, 0x831f, 0x91a9, 0xd0a1, 0x90c0, 0x92c2, 0x94f8, 0x94c6 }, 16, 0x000b8660, 1},
+ {{0x801e, 0x4416, 0x92c2, 0x93f8, 0x96c0, 0x76f3, 0x94fd, 0x5216, 0x6c95, 0x75f1, 0x71f2, 0x90c0, 0x92c2, 0x4116, 0x92d0, 0xee62 }, 16, 0x000b8680, 1},
+ {{0x90c0, 0x90c0, 0x96c0, 0x9b46, 0x2b03, 0x800e, 0x3420, 0xa000, 0xeceb, 0x94c0, 0x5014, 0x92fa, 0x7170, 0x90d0, 0x92c2, 0x4214 }, 16, 0x000b86a0, 1},
+ {{0xec42, 0x3820, 0xa000, 0xebeb, 0x2b03, 0x8020, 0x96c0, 0x551b, 0x2304, 0x8080, 0x26e4, 0x3980, 0x321a, 0x8008, 0x7ec1, 0xcf45 }, 16, 0x000b86c0, 1},
+ {{0x90c0, 0x131b, 0xef19, 0x25e4, 0x5017, 0x3610, 0xa100, 0x7dc1, 0x401b, 0xcf43, 0x90c0, 0x3640, 0xa800, 0x77d1, 0xeee8, 0xef19 }, 16, 0x000b86e0, 1},
+ {{0x3640, 0xa000, 0x5617, 0xefe9, 0x9f70, 0x3600, 0xa900, 0x7750, 0x4613, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b8700, 1},
+ {{0x3a00, 0xa00c, 0x75d7, 0x74d6, 0xe748, 0xe8ef, 0x10e0, 0xbffb, 0x9ac0, 0x27ef, 0x9fec, 0x90c0, 0x27ec, 0x9fe4, 0x1097, 0xf6c6 }, 16, 0x000b8720, 1},
+ {{0x3f6f, 0x3c6f, 0x1594, 0xf3c8, 0x9ac0, 0x7def, 0x27ed, 0x9ffc, 0x7eef, 0xefe8, 0x9ac0, 0x34c7, 0x8003, 0x90c0, 0x3402, 0x8005 }, 16, 0x000b8740, 1},
+ {{0x9ac0, 0x34c1, 0x8005, 0x90c0, 0x30c7, 0x8003, 0x3c00, 0xa002, 0x3002, 0x8005, 0xdb97, 0x3460, 0x8000, 0x3c00, 0xa002, 0x30c1 }, 16, 0x000b8760, 1},
+ {{0x8005, 0xd912, 0x3060, 0x8000, 0x3e00, 0xb00a, 0x36c4, 0x8003, 0xd891, 0x3602, 0x8005, 0xd810, 0x3e00, 0xa200, 0x3663, 0x8000 }, 16, 0x000b8780, 1},
+ {{0xd542, 0x36c6, 0x8005, 0xd7c4, 0x3a00, 0xa001, 0xd4c6, 0x6561, 0xd443, 0x67e1, 0x3a00, 0xa001, 0x6565, 0x64e1, 0x6461, 0x67e5 }, 16, 0x000b87a0, 1},
+ {{0x3a00, 0xa401, 0x6d4b, 0x64e5, 0x6465, 0x77d3, 0x3800, 0xb800, 0x6d31, 0x7751, 0xf242, 0x4295, 0x94c0, 0xf0c2, 0xf1c1, 0x009a }, 16, 0x000b87c0, 1},
+ {{0xe768, 0x9f70, 0x4192, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x9ac0, 0x64e9, 0x77d1, 0x6d10, 0x9620, 0x9720, 0x94c0, 0x9e20 }, 16, 0x000b87e0, 1},
+ {{0x9f20, 0x94c6, 0xe748, 0xc781, 0x98c0, 0x67e8, 0xf0ca, 0x27ef, 0x9fdc, 0x96c7, 0x6466, 0x67e6, 0x5197, 0x98c0, 0x7077, 0x75d1 }, 16, 0x000b8800, 1},
+ {{0xc590, 0xf4ca, 0x25e6, 0x2666, 0xeeea, 0x92c2, 0xf7ca, 0x92c2, 0x67e6, 0x71f7, 0xd3d1, 0x92c2, 0x67e6, 0xd097, 0x64e4, 0x6f05 }, 16, 0x000b8820, 1},
+ {{0x6e7c, 0xd79e, 0x9ac0, 0xd61e, 0x74f7, 0x32a4, 0x3590, 0x800b, 0x7474, 0x34f7, 0x1797, 0xf4ca, 0x35d7, 0x2668, 0xf042, 0x94c7 }, 16, 0x000b8840, 1},
+ {{0x65e6, 0x6464, 0x9ac7, 0xd59e, 0xf042, 0x32a4, 0x3590, 0x800b, 0x7473, 0x98c0, 0x27ef, 0x9ffc, 0x67e8, 0xeaee, 0x94c7, 0x4097 }, 16, 0x000b8860, 1},
+ {{0x6464, 0x92c3, 0x4097, 0x94c0, 0xf1c2, 0xf7c1, 0x019a, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x4792, 0x94c0, 0x9621, 0x9721, 0x9f71 }, 16, 0x000b8880, 1},
+ {{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x94c0, 0xe758, 0xefea, 0x96c0, 0xf1ce, 0x27ed, 0x9fcc, 0x64e6, 0x96c0, 0x3611 }, 16, 0x000b88a0, 1},
+ {{0x80ff, 0x5195, 0x94c0, 0x64e6, 0x801b, 0x3611, 0x80ff, 0x94c0, 0xf6ce, 0x8011, 0x7f47, 0xf64e, 0x5195, 0x7cc7, 0x4195, 0x96c0 }, 16, 0x000b88c0, 1},
+ {{0xf5ce, 0x27e8, 0x9fcc, 0x26e9, 0x5590, 0x8417, 0x66e9, 0x92c2, 0x6f10, 0x96c2, 0xf646, 0x27ec, 0x9fec, 0x94c6, 0x80b1, 0x4694 }, 16, 0x000b88e0, 1},
+ {{0x96c0, 0x6f90, 0xf0ce, 0xf1cd, 0x94c0, 0xf044, 0xf143, 0x96c0, 0xf0c4, 0x27ea, 0x9ff4, 0x1592, 0x04c6, 0x3664, 0x8009, 0x26e9 }, 16, 0x000b8900, 1},
+ {{0x6c7c, 0x806e, 0x98c6, 0x04c2, 0x3664, 0x8009, 0x6466, 0x9cc0, 0x6469, 0xd315, 0xc1fe, 0x3308, 0x2000, 0x8000, 0x96c0, 0xd055 }, 16, 0x000b8920, 1},
+ {{0x6764, 0x8054, 0x94c6, 0xdf01, 0x6466, 0xd110, 0x6564, 0xdd01, 0x6e7d, 0x94c0, 0xd696, 0xd416, 0x2972, 0x6030, 0x7652, 0x6c7c }, 16, 0x000b8940, 1},
+ {{0x7273, 0x94c2, 0x7c62, 0x7d62, 0x9ac6, 0x6e52, 0xc781, 0x3284, 0x2b60, 0x800b, 0xd81c, 0xd72f, 0x92c2, 0x7b70, 0x94c1, 0xc490 }, 16, 0x000b8960, 1},
+ {{0xd41e, 0x92c3, 0x6db6, 0x94c7, 0xd3a1, 0xd413, 0x92c2, 0x7c41, 0x96c0, 0x74d0, 0xf5ce, 0xf4cd, 0x96c0, 0x64e1, 0xf542, 0xf441 }, 16, 0x000b8980, 1},
+ {{0x3284, 0x27f0, 0x800b, 0x27ea, 0x9fe8, 0x94c0, 0xf3c6, 0xf6c5, 0x039f, 0xe778, 0x4697, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621 }, 16, 0x000b89a0, 1},
+ {{0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x32a4, 0x34c0, 0x800b, 0x3451, 0x74d0, 0x96c0, 0x30c8, 0x97c1 }, 16, 0x000b89c0, 1},
+ {{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x3800, 0xa004, 0x77d6, 0xcc57, 0xe750, 0x3480, 0xa000, 0xe8ef }, 16, 0x000b89e0, 1},
+ {{0xc56c, 0x1005, 0xa004, 0x90c0, 0x90c0, 0x3e00, 0xa002, 0x6d10, 0x6c10, 0x6f10, 0x7754, 0xf5c7, 0xc184, 0x9ac0, 0x6d7d, 0x3cc0 }, 16, 0x000b8a00, 1},
+ {{0x3668, 0x8009, 0xf244, 0x9ac0, 0x2700, 0x8081, 0x75d5, 0x290b, 0x8b64, 0x9ac0, 0x0afc, 0x9ff4, 0x79e1, 0x2b02, 0x8102, 0x7dc1 }, 16, 0x000b8a20, 1},
+ {{0xca43, 0x90c0, 0xea1c, 0x98c0, 0x5352, 0x90c0, 0x90c0, 0x90c0, 0x3e00, 0xa009, 0x6d10, 0x74d7, 0x76d0, 0x7655, 0xcd40, 0xf642 }, 16, 0x000b8a40, 1},
+ {{0x3800, 0xa004, 0x75d2, 0x0efc, 0x9ffc, 0xed18, 0x2d0f, 0x8004, 0x11bd, 0x3284, 0x29d0, 0x800b, 0x7451, 0x37d0, 0x11bf, 0x3284 }, 16, 0x000b8a60, 1},
+ {{0x29d0, 0x800b, 0x7451, 0x3c20, 0xa006, 0x65e9, 0x6cc3, 0x7a61, 0x79c1, 0xf2c2, 0x3620, 0xa000, 0x0afe, 0x9ffc, 0x3626, 0xb000 }, 16, 0x000b8a80, 1},
+ {{0xf0c4, 0x6d58, 0x3a26, 0xa000, 0x90c0, 0xf242, 0x08fe, 0x9ff4, 0x3806, 0xa044, 0x6e51, 0x0afc, 0x9ffc, 0x3626, 0xa000, 0xf444 }, 16, 0x000b8aa0, 1},
+ {{0x666a, 0x81ae, 0x3622, 0xa000, 0x0cfc, 0x9ff4, 0x3800, 0xaa00, 0x77d1, 0x6275, 0x7455, 0x3be1, 0x2e75, 0x7848, 0x27ea, 0x449b }, 16, 0x000b8ac0, 1},
+ {{0x8171, 0x3a00, 0xa200, 0x2700, 0x8930, 0x7656, 0xc94b, 0x96c0, 0xd7c3, 0xf6c4, 0xf0c4, 0x96c0, 0xca47, 0x0efe, 0x9ff4, 0x16c0 }, 16, 0x000b8ae0, 1},
+ {{0x3660, 0x8009, 0x069a, 0x08fe, 0x9ff4, 0x2465, 0x05c6, 0x3660, 0x8009, 0x4592, 0xc564, 0x90c0, 0x90c0, 0x3800, 0xa800, 0x7757 }, 16, 0x000b8b00, 1},
+ {{0xe770, 0xcc5f, 0x3620, 0xa000, 0xefe8, 0x9f71, 0x90c0, 0x90c0, 0x98c0, 0x3309, 0x2000, 0x8000, 0xe748, 0xd5c0, 0x98c0, 0xf342 }, 16, 0x000b8b20, 1},
+ {{0x3224, 0x2590, 0x800a, 0xf0c2, 0xe768, 0x9f71, 0x90c0, 0x90c0, 0x3124, 0x2590, 0x800a, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b8b40, 1},
+ {{0x1005, 0xa03b, 0x90c0, 0x2161, 0x8000, 0x98c0, 0xd110, 0xd210, 0x6466, 0xf5c1, 0x35d1, 0x6469, 0x98c0, 0x7941, 0x6664, 0x2b03 }, 16, 0x000b8b60, 1},
+ {{0x8022, 0x96c2, 0x3184, 0x2bb2, 0x800b, 0x98c0, 0x35fa, 0x9ffe, 0x7e61, 0x9346, 0x94c0, 0xd41a, 0x7a47, 0x3810, 0xa00d, 0x6039 }, 16, 0x000b8b80, 1},
+ {{0x60b1, 0x6970, 0x3400, 0xa844, 0x6058, 0x3400, 0xa840, 0x6cd0, 0x6031, 0x94c0, 0x9f70, 0xd41c, 0xc565, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b8ba0, 1},
+ {{0x94c0, 0x9620, 0x9720, 0x3c80, 0xa000, 0x280f, 0x8032, 0x90c0, 0x290c, 0x8d82, 0x94c0, 0x9e20, 0x9f20, 0x3880, 0xa000, 0x5317 }, 16, 0x000b8bc0, 1},
+ {{0x270f, 0x8050, 0x98c0, 0x65ea, 0xe7ef, 0x290e, 0x8d6e, 0x96c0, 0x841d, 0x27ed, 0x9fc4, 0x9f43, 0x27e8, 0x9fb0, 0x90c0, 0x94d0 }, 16, 0x000b8be0, 1},
+ {{0x94a6, 0x90a4, 0x94c0, 0x9480, 0x9085, 0x9ac0, 0x27eb, 0x9fd8, 0x65ea, 0x27ee, 0x9fb0, 0x8469, 0x96c0, 0x9a43, 0x2a03, 0x800a }, 16, 0x000b8c00, 1},
+ {{0x90c0, 0x9cc0, 0x65ea, 0x6c10, 0x7753, 0x95a6, 0x27e8, 0x9fb0, 0x8447, 0xd5a2, 0x801f, 0x96c0, 0x9b46, 0x2b03, 0x800c, 0x90c0 }, 16, 0x000b8c20, 1},
+ {{0x90c0, 0x92d0, 0x97a0, 0x72e7, 0x92c2, 0x7841, 0x3184, 0x2c76, 0x800b, 0x94c0, 0x7b62, 0x94a0, 0x96c0, 0x72e4, 0x9f46, 0x94a0 }, 16, 0x000b8c40, 1},
+ {{0x90c0, 0x90c0, 0x96ce, 0x72e4, 0x7841, 0x94a0, 0x94c6, 0x72e4, 0x7841, 0x92c2, 0x7841, 0x92d0, 0x9083, 0x90c0, 0x90c0, 0x9ac0 }, 16, 0x000b8c60, 1},
+ {{0x27ed, 0x9fec, 0x65ea, 0x27e8, 0x9fc4, 0x8473, 0x96c0, 0x9a43, 0x2a03, 0x8014, 0x9ac0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b8c80, 1},
+ {{0x9cc0, 0x65ea, 0x6c10, 0x74d3, 0x95a0, 0x27ea, 0x9fc4, 0x8447, 0xd5a2, 0x801f, 0x96c0, 0x9b41, 0x2b03, 0x800c, 0x90c0, 0x90c0 }, 16, 0x000b8ca0, 1},
+ {{0x92d0, 0x91a2, 0x72e1, 0x92c2, 0x7841, 0x3184, 0x2cf4, 0x800b, 0x94c0, 0x78e2, 0x96a2, 0x96c0, 0x72e6, 0x9f41, 0x96a2, 0x90c0 }, 16, 0x000b8cc0, 1},
+ {{0x90c0, 0x96ce, 0x72e6, 0x7841, 0x96a2, 0x94c6, 0x72e6, 0x7841, 0x92c2, 0x7841, 0x92d0, 0x9085, 0x90c0, 0x90c0, 0x9cc0, 0x65ea }, 16, 0x000b8ce0, 1},
+ {{0x27ef, 0x9fd8, 0x7753, 0x27e8, 0x9fec, 0x96c0, 0x7b61, 0x95a7, 0x8453, 0x98c0, 0xd2a1, 0x9b46, 0x2b03, 0x8020, 0x96c0, 0x94a0 }, 16, 0x000b8d00, 1},
+ {{0x27eb, 0x9fc4, 0x98c6, 0x27ea, 0x9fb0, 0x90c0, 0x6d10, 0x2103, 0x8020, 0x96c6, 0xd221, 0x929a, 0x90a7, 0x94d6, 0x94a0, 0x6f90 }, 16, 0x000b8d20, 1},
+ {{0x96c6, 0xd021, 0x979b, 0xea41, 0x94c6, 0xeb41, 0x6d10, 0x94c6, 0xd221, 0x929a, 0x92c2, 0x6e10, 0x92c2, 0x949b, 0x3600, 0xa004 }, 16, 0x000b8d40, 1},
+ {{0x6d90, 0x9754, 0x9ac0, 0x27ef, 0x9fec, 0x90c0, 0x27ee, 0x9fd8, 0x3668, 0xa000, 0x9386, 0x9387, 0x3e00, 0xa004, 0x6d10, 0x27e8 }, 16, 0x000b8d60, 1},
+ {{0x9fb0, 0x65ea, 0x27eb, 0x9fc4, 0x96c0, 0x79e1, 0x96a0, 0x8465, 0x98c0, 0x6769, 0x9b43, 0x2b03, 0x8030, 0x3807, 0xa004, 0x65e1 }, 16, 0x000b8d80, 1},
+ {{0x27ea, 0x9fd8, 0x3807, 0xa001, 0x9682, 0x95a3, 0x79c1, 0x9ac0, 0x27ee, 0x9fec, 0x66e9, 0x2103, 0x8034, 0x94c0, 0x90c0, 0x90c0 }, 16, 0x000b8da0, 1},
+ {{0x3807, 0xa001, 0x9586, 0x97a0, 0x7941, 0x94c0, 0x67e9, 0x95a3, 0x3413, 0xa004, 0x65e1, 0x3807, 0xa001, 0x9782, 0x66e9, 0x79c1 }, 16, 0x000b8dc0, 1},
+ {{0x90c0, 0x3403, 0xa004, 0x7941, 0x92c3, 0x959e, 0x3e00, 0xa004, 0x65e1, 0x6e90, 0x6c90, 0x6c10, 0x27ea, 0x9fd8, 0x3c00, 0xb004 }, 16, 0x000b8de0, 1},
+ {{0x65e9, 0x77d3, 0x6d10, 0x290c, 0x8940, 0x94c0, 0x2518, 0x8136, 0x94c0, 0x92ba, 0xea41, 0x6569, 0x8409, 0x7841, 0x73f0, 0x81f3 }, 16, 0x000b8e00, 1},
+ {{0x73e0, 0x98c6, 0x2518, 0x80b4, 0x90c0, 0x6f10, 0x3c00, 0xb000, 0x73f0, 0x6d93, 0x3102, 0x8001, 0xce40, 0x96c0, 0x849b, 0x27ef }, 16, 0x000b8e20, 1},
+ {{0x9fd8, 0x96c0, 0x9a43, 0x2a03, 0x800e, 0x94c0, 0xee1f, 0x90c0, 0x94c0, 0x90a6, 0xc481, 0x6469, 0x8075, 0x3c00, 0xb000, 0x73f2 }, 16, 0x000b8e40, 1},
+ {{0x6d9d, 0xca42, 0x27ed, 0x9fd8, 0x844d, 0x94c0, 0xd5a2, 0xed1a, 0x8021, 0x96c0, 0x9b43, 0x2b03, 0x800e, 0x90c0, 0x92c0, 0x90c0 }, 16, 0x000b8e60, 1},
+ {{0x92d0, 0x93a5, 0x71e0, 0x92c2, 0x7a41, 0x3184, 0x2eb4, 0x800b, 0x94c0, 0x79e2, 0x96a5, 0x96c0, 0x7360, 0x9f43, 0x96a5, 0x90c0 }, 16, 0x000b8e80, 1},
+ {{0x90c0, 0x96ce, 0x7360, 0x7a41, 0x96a5, 0x94c6, 0x7360, 0x7a41, 0x92c2, 0x7a41, 0x7271, 0x96c0, 0xd2d0, 0xd0d4, 0x8017, 0x70e4 }, 16, 0x000b8ea0, 1},
+ {{0x840d, 0x66e1, 0x72f0, 0x94c0, 0xd2d0, 0xd0d4, 0x92d0, 0x7941, 0x90c0, 0x90c0, 0x7755, 0x3e00, 0xa004, 0x65ea, 0x6c10, 0x6c90 }, 16, 0x000b8ec0, 1},
+ {{0x766e, 0x27ef, 0x9fd8, 0x96c6, 0x7a6a, 0x776e, 0x8437, 0x3e40, 0xa000, 0x7556, 0x3d07, 0x800a, 0x9b43, 0x2b03, 0x8010, 0x96a7 }, 16, 0x000b8ee0, 1},
+ {{0x7276, 0x800b, 0x7377, 0x8408, 0x92c3, 0xc581, 0x6e90, 0x92d0, 0xd2a1, 0x94c2, 0xd446, 0x78c1, 0x90c0, 0x7752, 0x96c0, 0x64e9 }, 16, 0x000b8f00, 1},
+ {{0x290b, 0x8940, 0x8013, 0x33e4, 0x3c48, 0x8001, 0x98c0, 0x909b, 0x3184, 0x2f42, 0x800b, 0x98c0, 0x969b, 0x3184, 0x2f42, 0x800b }, 16, 0x000b8f20, 1},
+ {{0x929c, 0x3e00, 0xb004, 0x6569, 0x77d2, 0x6e10, 0x6f10, 0x27ec, 0x9fec, 0x9cc0, 0x6d90, 0x2908, 0x8941, 0x6d10, 0x2518, 0x8134 }, 16, 0x000b8f40, 1},
+ {{0x94c0, 0x95bc, 0xec41, 0x66e9, 0x8409, 0x79c1, 0x73f3, 0x81f3, 0x73e3, 0x94c6, 0x80ab, 0x6e90, 0x9cc0, 0x73f3, 0x3705, 0x8001 }, 16, 0x000b8f60, 1},
+ {{0xca43, 0x27ed, 0x9fec, 0x3600, 0xa800, 0x6dbd, 0x8495, 0x96c0, 0x9a43, 0x2a03, 0x800a, 0xea1d, 0x94c0, 0x93a2, 0xc281, 0x65e9 }, 16, 0x000b8f80, 1},
+ {{0x8073, 0x3c00, 0xb000, 0x73f5, 0x6ca9, 0xcd45, 0x27ec, 0x9fec, 0x844b, 0x94c0, 0xd4a2, 0xec1d, 0x801f, 0x96c0, 0x9b41, 0x2b03 }, 16, 0x000b8fa0, 1},
+ {{0x800c, 0x90c0, 0x90c0, 0x92d0, 0x91a4, 0x70e3, 0x92c2, 0x7941, 0x3184, 0x2ffa, 0x800b, 0x94c0, 0x78e2, 0x90a4, 0x96c0, 0x7063 }, 16, 0x000b8fc0, 1},
+ {{0x9f41, 0x90a4, 0x90c0, 0x90c0, 0x96ce, 0x7063, 0x7941, 0x90a4, 0x94c6, 0x7063, 0x7941, 0x92c2, 0x7941, 0x7176, 0x96c0, 0xd253 }, 16, 0x000b8fe0, 1},
+ {{0xd352, 0x8017, 0x7362, 0x840d, 0x6661, 0x7273, 0x94c0, 0xd253, 0xd352, 0x92d0, 0x7ac1, 0x90c0, 0x90c0, 0x76d4, 0x3e00, 0xa004 }, 16, 0x000b9000, 1},
+ {{0x656a, 0x6c10, 0x6c90, 0x77ed, 0x27ea, 0x9fec, 0x96c6, 0x7bea, 0x76ed, 0x8437, 0x3e40, 0xa000, 0x7555, 0x3b03, 0x800a, 0x9b42 }, 16, 0x000b9020, 1},
+ {{0x2b03, 0x8010, 0x95a2, 0x73f5, 0x800b, 0x72f3, 0x8408, 0x92c3, 0xc681, 0x6f10, 0x92d0, 0xd321, 0x94c2, 0xd445, 0x78c1, 0x90c0 }, 16, 0x000b9040, 1},
+ {{0x76d2, 0x96c0, 0x64e9, 0x2908, 0x8941, 0x8013, 0x33e4, 0x3c48, 0x8001, 0x98c0, 0x9098, 0x3184, 0x3088, 0x800b, 0x98c0, 0x9598 }, 16, 0x000b9060, 1},
+ {{0x3184, 0x3088, 0x800b, 0x9298, 0x96c0, 0x6c10, 0x27e9, 0x9fb0, 0xe7e9, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71 }, 16, 0x000b9080, 1},
+ {{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x3880, 0xa000, 0xede9, 0x270b, 0x8048, 0x3600, 0xa100, 0xe7eb, 0xe8e8, 0xc56e }, 16, 0x000b90a0, 1},
+ {{0x1005, 0xa004, 0x90c0, 0x94c0, 0x6c10, 0x9742, 0x9ac0, 0x290e, 0x8d6a, 0x90c0, 0x27eb, 0x9fe8, 0x5516, 0x92c8, 0x9083, 0x3880 }, 16, 0x000b90c0, 1},
+ {{0xa000, 0xebee, 0x2900, 0x841e, 0x96c0, 0x9365, 0x2b03, 0x801a, 0x38c0, 0xa000, 0xeb39, 0x2d0d, 0x8108, 0x3660, 0xa000, 0xeaeb }, 16, 0x000b90e0, 1},
+ {{0xe8eb, 0x94d0, 0x5098, 0x579d, 0x6dc3, 0x439a, 0x94c0, 0x6e10, 0x9744, 0x27ed, 0x9fe0, 0x92c8, 0x9485, 0x98c0, 0x2d00, 0x8846 }, 16, 0x000b9100, 1},
+ {{0x6c10, 0x9742, 0xe8ee, 0x96c0, 0xe83d, 0x27ec, 0x9fe0, 0x27ea, 0x9fe1, 0x94d0, 0x909c, 0x909a, 0x94c0, 0xec42, 0xea42, 0x96c0 }, 16, 0x000b9120, 1},
+ {{0xebe8, 0x2704, 0x8080, 0x97a3, 0x96c0, 0x67e9, 0x2300, 0x8081, 0x94d0, 0xd25f, 0x97a3, 0x67e9, 0x98c0, 0xd25f, 0xc281, 0x27ed }, 16, 0x000b9140, 1},
+ {{0x9fe1, 0x2669, 0x047c, 0x9fe0, 0x94c6, 0x804c, 0x6c10, 0x92c2, 0xf045, 0x98c0, 0x6c10, 0x9b43, 0x2b03, 0x800c, 0xe9e8, 0x97a1 }, 16, 0x000b9160, 1},
+ {{0x67e9, 0x90c0, 0x94c2, 0x2303, 0x8018, 0x73f8, 0x90c0, 0x94c3, 0x2303, 0x800e, 0x92d0, 0x727f, 0xd057, 0x90c0, 0x2469, 0x7650 }, 16, 0x000b9180, 1},
+ {{0x8014, 0x94c6, 0x7941, 0xf245, 0x94c0, 0xd523, 0x9085, 0x85c5, 0xc284, 0xf245, 0x9ac0, 0x2f00, 0x830a, 0x6d10, 0x2d00, 0x838a }, 16, 0x000b91a0, 1},
+ {{0x3680, 0xa000, 0xecee, 0xeaee, 0x3600, 0xa100, 0xea3f, 0xec3d, 0x3600, 0xa100, 0xc45c, 0xca49, 0x94c0, 0xc088, 0xc790, 0x3800 }, 16, 0x000b91c0, 1},
+ {{0xa008, 0x6a01, 0x689b, 0x9743, 0x3600, 0xa100, 0xcb44, 0xcf41, 0x90c0, 0x92d0, 0x421b, 0x429f, 0x3840, 0xa100, 0xf2c5, 0x2d0f }, 16, 0x000b91e0, 1},
+ {{0x8b64, 0x3a00, 0xa100, 0x656a, 0xcb41, 0x27ec, 0x9fe0, 0x94c0, 0xc944, 0x847f, 0x9ac0, 0x2d00, 0x8204, 0x90c0, 0x2f00, 0x8081 }, 16, 0x000b9200, 1},
+ {{0x98c0, 0x6c10, 0x6c90, 0x94a4, 0x9b43, 0x98c0, 0x2b03, 0x800e, 0x7a6a, 0x4419, 0x3907, 0x8014, 0x3420, 0xa000, 0x96a0, 0x3400 }, 16, 0x000b9220, 1},
+ {{0xa800, 0x7276, 0x8011, 0x3400, 0xa004, 0x7377, 0x840e, 0x3423, 0xa000, 0xc281, 0x3400, 0xa004, 0x6d10, 0x3400, 0xa004, 0x6569 }, 16, 0x000b9240, 1},
+ {{0x92d3, 0x78c1, 0x36a7, 0xa100, 0x5797, 0xef44, 0x3403, 0xa800, 0xd447, 0x64ea, 0x8409, 0x33e4, 0x3c48, 0x8001, 0x3961, 0x009b }, 16, 0x000b9260, 1},
+ {{0xe83f, 0x3600, 0xa100, 0x656a, 0xef3d, 0x8197, 0x3c20, 0xa000, 0x280f, 0x8030, 0x6c10, 0x27ed, 0x9fe5, 0x96c0, 0x5217, 0x27e8 }, 16, 0x000b9280, 1},
+ {{0x9fe4, 0x7961, 0x3175, 0x5516, 0x96c0, 0x7ac1, 0x2518, 0x8602, 0x9742, 0x4016, 0x94d0, 0x9098, 0x909d, 0x94c0, 0xe842, 0xed42 }, 16, 0x000b92a0, 1},
+ {{0x9ac0, 0x6c90, 0x27e8, 0x9fd8, 0x6d10, 0xc7a5, 0x96c0, 0x6d90, 0xc482, 0xc584, 0x94c0, 0xc810, 0xf741, 0x94c0, 0xf044, 0xf542 }, 16, 0x000b92c0, 1},
+ {{0x3640, 0xa000, 0xf443, 0xe9eb, 0x3820, 0xa000, 0xfd4f, 0x27e8, 0x9fd8, 0x3660, 0xa000, 0xf850, 0xfc51, 0x3264, 0x2c70, 0x800b }, 16, 0x000b92e0, 1},
+ {{0x94c0, 0xfa52, 0xc35f, 0x96c0, 0x7470, 0xf294, 0xc357, 0x96c0, 0x6569, 0xcd42, 0xc484, 0x3a40, 0xa000, 0x2101, 0x9999, 0x6c7d }, 16, 0x000b9300, 1},
+ {{0xfcd1, 0x98c3, 0xcc42, 0x3b80, 0x32e0, 0x8008, 0x94c0, 0xedfe, 0xfad2, 0x3647, 0xa000, 0xeb1c, 0xed1b, 0x94c7, 0x5095, 0x95bb }, 16, 0x000b9320, 1},
+ {{0x9ec7, 0x27e8, 0x9fda, 0xd621, 0x90c0, 0x6174, 0x057c, 0x9fe4, 0x98c0, 0x6d74, 0x7a61, 0x5b18, 0x8475, 0x9ac0, 0x2b03, 0x8036 }, 16, 0x000b9340, 1},
+ {{0x7a61, 0x27e9, 0x9fe5, 0x94c0, 0xeceb, 0x9b44, 0xecfe, 0x3420, 0xa000, 0xec1b, 0x5494, 0x7272, 0x90c0, 0x96c2, 0x3d80, 0x32e0 }, 16, 0x000b9360, 1},
+ {{0x8008, 0x90c0, 0x9ac6, 0x2103, 0x8038, 0x90c0, 0xeb1d, 0x90c0, 0x94c6, 0x5b18, 0x93bb, 0x92c2, 0x9399, 0x94c0, 0xeceb, 0xe941 }, 16, 0x000b9380, 1},
+ {{0xecfe, 0x3420, 0xa000, 0xec1b, 0x5594, 0x72f2, 0x90c0, 0x96d2, 0x3d80, 0x32e0, 0x8008, 0x90c0, 0x92c2, 0xeb1d, 0x92c2, 0x92bb }, 16, 0x000b93a0, 1},
+ {{0x92c2, 0x9299, 0x3800, 0xa100, 0x6d10, 0xefef, 0xcdac, 0x3680, 0xa000, 0xef68, 0xc9aa, 0x3680, 0xa000, 0x5417, 0xe8ef, 0x98c0 }, 16, 0x000b93c0, 1},
+ {{0x391f, 0x8001, 0xebef, 0xe83d, 0x27e9, 0x14d0, 0xeb39, 0x3a00, 0xa008, 0x77f4, 0x75d4, 0x50d3, 0x8481, 0x9ac0, 0x75f0, 0x74d0 }, 16, 0x000b93e0, 1},
+ {{0x9344, 0x2b03, 0x801a, 0x9ac0, 0x2500, 0x80b4, 0x90c0, 0x27eb, 0x9fe4, 0x7455, 0x3a00, 0xb008, 0x7671, 0x75f3, 0x71f7, 0x95bb }, 16, 0x000b9400, 1},
+ {{0x3800, 0xa814, 0x6d2c, 0x74fc, 0x6e4c, 0x3a06, 0xa001, 0x90c0, 0x64e9, 0x6d10, 0x6c7d, 0x841d, 0x3400, 0xa804, 0x75fb, 0x3400 }, 16, 0x000b9420, 1},
+ {{0xa004, 0x71e5, 0x8020, 0x92c2, 0xc481, 0x2e10, 0x3184, 0x3464, 0x800b, 0x3400, 0xa004, 0x7175, 0x800b, 0x72f4, 0x8408, 0x92c3 }, 16, 0x000b9440, 1},
+ {{0xc481, 0x6e10, 0x6669, 0x90d0, 0x92c3, 0x929b, 0xeb41, 0x94c0, 0x6c10, 0x9742, 0x27e8, 0x9fe8, 0x92c8, 0x9080, 0x98c0, 0x6c10 }, 16, 0x000b9460, 1},
+ {{0x6c90, 0xe8ef, 0x9144, 0x9ac0, 0x2903, 0x8036, 0x90c0, 0x2b03, 0x8064, 0x9ac0, 0x2a03, 0x803e, 0x90c0, 0x27ed, 0x9fd0, 0x1317 }, 16, 0x000b9480, 1},
+ {{0xe864, 0x98c0, 0x27e9, 0x9fc8, 0x77d3, 0xc015, 0x96c0, 0x5590, 0x27ed, 0x9fc8, 0x96c0, 0xc011, 0x27eb, 0x9fe4, 0x94a3, 0x6669 }, 16, 0x000b94a0, 1},
+ {{0x8055, 0x3820, 0xa000, 0x65ea, 0xe9ea, 0xecec, 0x8449, 0x9a47, 0x96c0, 0x767c, 0x511c, 0x9343, 0x34e9, 0x5295, 0x7261, 0x92c3 }, 16, 0x000b94c0, 1},
+ {{0x6c10, 0x92c2, 0xc081, 0x6469, 0x90c0, 0x94c7, 0x501c, 0x5191, 0x96c7, 0x7468, 0xd541, 0xe944, 0x7260, 0x92c3, 0x6c90, 0x92d2 }, 16, 0x000b94e0, 1},
+ {{0xc181, 0x64e9, 0x90c0, 0x90c0, 0x94d7, 0xe944, 0x5091, 0x92c3, 0xd540, 0x4295, 0x92d0, 0xed44, 0x90c0, 0x90c0, 0x96c0, 0x9342 }, 16, 0x000b9500, 1},
+ {{0x27e9, 0x9fcc, 0x96c0, 0xf1ce, 0x2b03, 0x801c, 0x1499, 0xec3c, 0x3271, 0xc381, 0x9ac0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b9520, 1},
+ {{0x9ad6, 0x5499, 0x90c0, 0x79c1, 0xcc43, 0xd0d4, 0x7271, 0x90c0, 0x9cc0, 0xd0d4, 0x6c10, 0x6f90, 0x9344, 0x2b03, 0x8020, 0x98c6 }, 16, 0x000b9540, 1},
+ {{0x27e8, 0x9fc8, 0x90c0, 0xcc43, 0x96c0, 0xcc4a, 0xed3d, 0x90c0, 0x3167, 0x5390, 0x800b, 0x71f0, 0xd053, 0x92c2, 0xcd47, 0x94d0 }, 16, 0x000b9560, 1},
+ {{0x7bc1, 0xe844, 0x90c0, 0x90c0, 0x98c0, 0x2b00, 0x842e, 0x70f5, 0xe8ee, 0x98c7, 0x2300, 0x8094, 0x90c0, 0x6d10, 0x96c6, 0xe83b }, 16, 0x000b9580, 1},
+ {{0x27ea, 0x9fe4, 0x94c6, 0x4190, 0xec1a, 0x96c6, 0x7075, 0x92bc, 0xf341, 0x98c7, 0x027c, 0x9fe8, 0x90c0, 0x6e10, 0x9cc1, 0x6c90 }, 16, 0x000b95a0, 1},
+ {{0x27ea, 0x9fe4, 0x6c90, 0x27ea, 0x9fe9, 0x96c2, 0xed1a, 0x27e9, 0x9fe9, 0x94c1, 0x949a, 0x90bd, 0x98c0, 0xc75f, 0x32e4, 0x3c8a }, 16, 0x000b95c0, 1},
+ {{0x8001, 0x3646, 0xa000, 0x9099, 0xe8eb, 0x3a40, 0xa000, 0x6c90, 0xfcd1, 0x2200, 0x8080, 0x98c0, 0xf241, 0x32e4, 0x3c8a, 0x8001 }, 16, 0x000b95e0, 1},
+ {{0x3420, 0xa000, 0xe8ec, 0x3820, 0xa000, 0xfdcf, 0x2e0c, 0x8004, 0x96c0, 0xebec, 0x117c, 0x9fe8, 0x3640, 0xa000, 0xeb62, 0xf8d0 }, 16, 0x000b9600, 1},
+ {{0x96c0, 0x5d13, 0x27e9, 0x9fe9, 0x96c0, 0x90b9, 0x2f09, 0x8002, 0x3600, 0xa100, 0xed1c, 0xe9ee, 0x94c0, 0x919d, 0xec54, 0x5813 }, 16, 0x000b9620, 1},
+ {{0x90c0, 0xe81c, 0x9098, 0x1011, 0x5513, 0x7861, 0x7075, 0x90c0, 0x3a01, 0xa100, 0x90c0, 0xeeee, 0x7ac1, 0x6d90, 0x96c3, 0xc481 }, 16, 0x000b9640, 1},
+ {{0x2a00, 0x8432, 0x92c2, 0x4513, 0x3483, 0xa000, 0xee3a, 0x3887, 0xa000, 0x949e, 0x2a00, 0x8432, 0x92c3, 0x4313, 0x3480, 0xa000 }, 16, 0x000b9660, 1},
+ {{0xe93a, 0x3480, 0xa000, 0x95b9, 0xd2a1, 0x3660, 0xa000, 0x9955, 0x9850, 0x96c2, 0x3384, 0x2bc0, 0x800b, 0x96c0, 0xc757, 0x2800 }, 16, 0x000b9680, 1},
+ {{0x842a, 0xeaee, 0x3680, 0xa000, 0x5117, 0xea38, 0x96c0, 0x331f, 0x8200, 0x93ba, 0x27e9, 0x76d3, 0x8083, 0x9cc0, 0x65ea, 0x3c13 }, 16, 0x000b96a0, 1},
+ {{0x805a, 0xe9ef, 0x2100, 0x80af, 0x96c0, 0x7651, 0xe976, 0x842b, 0x3620, 0xa000, 0x5611, 0xc585, 0x3400, 0xa804, 0x682e, 0x3400 }, 16, 0x000b96c0, 1},
+ {{0xa004, 0x7c6c, 0x3600, 0xa800, 0x3100, 0x805a, 0x6c7d, 0x74d4, 0x6d7c, 0x96c0, 0xecee, 0x2900, 0x8429, 0x94c0, 0x959a, 0xef76 }, 16, 0x000b96e0, 1},
+ {{0x96c0, 0xec39, 0x2100, 0x80af, 0x96c0, 0x7651, 0x97bc, 0x5217, 0x98c0, 0x67ea, 0x76d7, 0x3c17, 0x805a, 0x3600, 0xa004, 0x68ab }, 16, 0x000b9700, 1},
+ {{0x841f, 0x3600, 0xa004, 0x7cec, 0xc585, 0x3600, 0xa800, 0x3300, 0x805a, 0x6c7d, 0x74d4, 0x6d7c, 0x959c, 0x3880, 0xa000, 0x5117 }, 16, 0x000b9720, 1},
+ {{0x2d00, 0x842a, 0x98c0, 0x331d, 0x8400, 0xebee, 0xc185, 0x26e9, 0xeb3d, 0x94c0, 0x95bb, 0x8055, 0x32a4, 0x34f0, 0x800b, 0x7455 }, 16, 0x000b9740, 1},
+ {{0x9cc0, 0x2f00, 0x8429, 0x66e0, 0x3e10, 0x8005, 0xe9ee, 0x3468, 0xc185, 0x2e01, 0xe93f, 0x76ec, 0xd6a2, 0x94c2, 0x3104, 0x8005 }, 16, 0x000b9760, 1},
+ {{0xd054, 0x909b, 0x98c0, 0x95b9, 0x32a4, 0x34f0, 0x800b, 0x7455, 0x3e10, 0x8005, 0x7468, 0x6e01, 0x766c, 0xd622, 0x94c2, 0x3101 }, 16, 0x000b9780, 1},
+ {{0x8005, 0xd051, 0x9099, 0x2c10, 0x3c00, 0x20a0, 0x8008, 0x0016, 0x3d20, 0x33b6, 0x8009, 0x15d4, 0x08c6, 0x38d0, 0x8008, 0x3ec7 }, 16, 0x000b97a0, 1},
+ {{0x3b20, 0x33b4, 0x8009, 0x9ac0, 0x2808, 0x82b0, 0x90c0, 0x2b02, 0x8002, 0x5110, 0xd0a1, 0x840d, 0x9770, 0x90c0, 0x94c8, 0x453b }, 16, 0x000b97c0, 1},
+ {{0x453d, 0x96c0, 0xefee, 0x2900, 0x842a, 0x90c0, 0xef39, 0x95bf, 0x66e9, 0x90c0, 0x98c2, 0x3d00, 0x20a0, 0x8008, 0xc9ff, 0x8046 }, 16, 0x000b97e0, 1},
+ {{0x92c2, 0x4915, 0x3480, 0xa000, 0x5017, 0x311c, 0x8004, 0x96c0, 0x6669, 0x311c, 0x8010, 0x90c0, 0x98c3, 0x3800, 0x20a0, 0x8008 }, 16, 0x000b9800, 1},
+ {{0xcfff, 0x8422, 0x92c3, 0x4f10, 0x2669, 0x3f00, 0x20a0, 0x8008, 0x90c0, 0x98c1, 0x2400, 0x80b4, 0x90c0, 0x4517, 0x92c3, 0x6cb5 }, 16, 0x000b9820, 1},
+ {{0x92c3, 0x4117, 0x2900, 0x8429, 0x90c0, 0xee39, 0x90be, 0x6469, 0x90c0, 0x98c2, 0x3900, 0x20a2, 0x8008, 0xcbff, 0x8050, 0x92c2 }, 16, 0x000b9840, 1},
+ {{0x4b11, 0x3480, 0xa000, 0x5417, 0x9ac0, 0x391d, 0x8008, 0x90c0, 0x391c, 0x8010, 0x66e9, 0x90c0, 0x98c3, 0x3f00, 0x20a2, 0x8008 }, 16, 0x000b9860, 1},
+ {{0xcaff, 0x842a, 0x92c3, 0x4a17, 0x2669, 0x3a00, 0x20a2, 0x8008, 0x90c0, 0x94c3, 0x2500, 0x80b4, 0x94c7, 0x8414, 0x6e81, 0x92c3 }, 16, 0x000b9880, 1},
+ {{0x4512, 0x0012, 0x3184, 0x38ac, 0x800b, 0x4516, 0xc566, 0x90c0, 0x90c0, 0x96c0, 0x6c10, 0x27e8, 0x9fb8, 0xe7e8, 0x94c0, 0x9e21 }, 16, 0x000b98a0, 1},
+ {{0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x96c0, 0x5d98, 0x2a03, 0x80b2, 0x1998, 0x1005, 0xa03f }, 16, 0x000b98c0, 1},
+ {{0x1a98, 0x1105, 0xa004, 0x5c98, 0x3420, 0xa000, 0x5318, 0x3800, 0xa101, 0x509a, 0xefec, 0x79e1, 0x3640, 0xa000, 0x529a, 0x9a43 }, 16, 0x000b98e0, 1},
+ {{0x549a, 0x569a, 0x3420, 0xa000, 0x5092, 0x3800, 0xa008, 0x6764, 0x6464, 0x5159, 0x139c, 0x7ce2, 0x559c, 0x579c, 0x3420, 0xa000 }, 16, 0x000b9900, 1},
+ {{0x519c, 0x3a00, 0xa00f, 0x6e68, 0x6ee9, 0x6f6a, 0x6feb, 0x3a00, 0xa42f, 0x6e60, 0x6ee1, 0x6f62, 0x6de8, 0x3a00, 0xa42f, 0x7e70 }, 16, 0x000b9920, 1},
+ {{0x7ef0, 0x6fe3, 0x6de0, 0x3a00, 0xa00f, 0x6211, 0x7f70, 0x7ff0, 0x7df0, 0x3a00, 0xa42f, 0x629d, 0x6315, 0x639f, 0x6191, 0x3800 }, 16, 0x000b9940, 1},
+ {{0xb8cc, 0x6ed5, 0x6fdf, 0xc543, 0x3600, 0xa844, 0x6fdb, 0xc341, 0x3820, 0xa844, 0x6d4f, 0x5159, 0xc147, 0x3800, 0xa841, 0x6fdc }, 16, 0x000b9960, 1},
+ {{0x7ce2, 0x7d43, 0x3a00, 0xa00f, 0x6e68, 0x6ee9, 0x6f6a, 0x6feb, 0x3a00, 0xa42f, 0x6e60, 0x6ee1, 0x6f62, 0x6de8, 0x3a00, 0xa42f }, 16, 0x000b9980, 1},
+ {{0x7e70, 0x7ef0, 0x6fe3, 0x6de0, 0x3a00, 0xa00f, 0x6211, 0x7f70, 0x7ff0, 0x7df0, 0x3a00, 0xa42f, 0x629d, 0x6315, 0x639f, 0x6191 }, 16, 0x000b99a0, 1},
+ {{0x3a00, 0xb8ce, 0x6ed5, 0x6fdf, 0xc543, 0x6565, 0x3830, 0xa844, 0x6fdb, 0xc341, 0x425d, 0x3820, 0xa844, 0x6d4f, 0x5159, 0xc147 }, 16, 0x000b99c0, 1},
+ {{0x3800, 0xa841, 0x6fdc, 0x7ce2, 0x7d43, 0x3420, 0xa000, 0xecef, 0x3400, 0xa004, 0x6565, 0x3420, 0xa000, 0x425d, 0x94c0, 0x4394 }, 16, 0x000b99e0, 1},
+ {{0xb561, 0x3640, 0xa000, 0xb762, 0xb163, 0x94c0, 0x9621, 0x9721, 0x94c0, 0x9f70, 0xf3c1, 0xc563, 0x94c0, 0x9620, 0x9720, 0x96c0 }, 16, 0x000b9a00, 1},
+ {{0x5d98, 0x2a03, 0x80b2, 0x1998, 0x1005, 0xa03f, 0x1a98, 0x1105, 0xa004, 0x5c98, 0x3420, 0xa000, 0x5318, 0x3800, 0xa101, 0x509a }, 16, 0x000b9a20, 1},
+ {{0xefec, 0x79e1, 0x3640, 0xa000, 0x529a, 0x9a43, 0x549a, 0x569a, 0x3420, 0xa000, 0x5092, 0x3800, 0xa008, 0x6764, 0x6464, 0x5199 }, 16, 0x000b9a40, 1},
+ {{0x139c, 0x7ce2, 0x559c, 0x579c, 0x3420, 0xa000, 0x519c, 0x3a00, 0xa00f, 0x6e68, 0x6ee9, 0x6f6a, 0x6feb, 0x3a00, 0xa42f, 0x6e60 }, 16, 0x000b9a60, 1},
+ {{0x6ee1, 0x6f62, 0x6de8, 0x3a00, 0xa42f, 0x7e70, 0x7ef0, 0x6fe3, 0x6de0, 0x3a00, 0xa00f, 0x6211, 0x7f70, 0x7ff0, 0x7df0, 0x3a00 }, 16, 0x000b9a80, 1},
+ {{0xa42f, 0x629d, 0x6315, 0x639f, 0x6191, 0x3800, 0xb8cc, 0x6ed5, 0x6fdf, 0xc543, 0x3600, 0xa844, 0x6fdb, 0xc341, 0x3820, 0xa840 }, 16, 0x000b9aa0, 1},
+ {{0x6fcf, 0x5199, 0xc147, 0x3820, 0xa000, 0x7fc4, 0x7ce2, 0xc247, 0x3a00, 0xa00f, 0x6e68, 0x6ee9, 0x6f6a, 0x6feb, 0x3a00, 0xa42f }, 16, 0x000b9ac0, 1},
+ {{0x6e60, 0x6ee1, 0x6f62, 0x6de8, 0x3a00, 0xa42f, 0x7e70, 0x7ef0, 0x6fe3, 0x6de0, 0x3a00, 0xa00f, 0x6211, 0x7f70, 0x7ff0, 0x7df0 }, 16, 0x000b9ae0, 1},
+ {{0x3a00, 0xa42f, 0x629d, 0x6315, 0x639f, 0x6191, 0x3a00, 0xb8ce, 0x6ed5, 0x6fdf, 0xc543, 0x7d46, 0x3810, 0xa845, 0x6fdb, 0xc341 }, 16, 0x000b9b00, 1},
+ {{0x6565, 0x3820, 0xa840, 0x6fcf, 0x5199, 0xc147, 0x3a60, 0xa000, 0x7fc4, 0x7ce2, 0xc247, 0x42dd, 0x3620, 0xa008, 0xecef, 0x7d46 }, 16, 0x000b9b20, 1},
+ {{0x3400, 0xa004, 0x6565, 0x3420, 0xa000, 0x42dd, 0x94c0, 0x4394, 0xb561, 0x3640, 0xa000, 0xb762, 0xb163, 0x94c0, 0x9621, 0x9721 }, 16, 0x000b9b40, 1},
+ {{0x94c0, 0x9f70, 0xf3c1, 0xc563, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x96c0, 0x5b98, 0x2a03, 0x805a, 0x1005 }, 16, 0x000b9b60, 1},
+ {{0xa03f, 0x96c0, 0x5998, 0x2b03, 0x806e, 0x5a98, 0x90c0, 0x1098, 0xedea, 0x3620, 0xa000, 0x5a98, 0xece8, 0x3420, 0xa000, 0x5318 }, 16, 0x000b9b80, 1},
+ {{0x3620, 0xa008, 0x5418, 0x7de2, 0x3820, 0xb009, 0x9a43, 0x76d4, 0x7e41, 0x3e00, 0xa00c, 0x7a48, 0x7ee2, 0x3703, 0x2008, 0x8000 }, 16, 0x000b9ba0, 1},
+ {{0xc050, 0x90c0, 0x36c0, 0xa000, 0xcc54, 0xe8ea, 0x92c0, 0x90c0, 0x3e40, 0xa000, 0x6e10, 0x6e90, 0x6f10, 0x6f90, 0x49d9, 0x9b45 }, 16, 0x000b9bc0, 1},
+ {{0x08d0, 0xeaed, 0x3a40, 0xa000, 0x6e10, 0x6e90, 0x5048, 0x505a, 0x3e40, 0xa4d0, 0x6393, 0x6312, 0x6291, 0x6210, 0x5348, 0x505a }, 16, 0x000b9be0, 1},
+ {{0x3e50, 0xa2e0, 0x6392, 0x6311, 0x6290, 0x6213, 0x5248, 0x505a, 0x3e40, 0xb070, 0x6391, 0x6310, 0x6293, 0x6212, 0x5148, 0x505a }, 16, 0x000b9c00, 1},
+ {{0x3e50, 0xa8b0, 0x6390, 0x6313, 0x6292, 0x6211, 0x5048, 0x505a, 0x364c, 0x36cd, 0x374e, 0x77cf, 0x0cdb, 0x5058, 0x0894, 0x3703 }, 16, 0x000b9c20, 1},
+ {{0x2000, 0x8000, 0x94c0, 0x9621, 0x9721, 0x94c0, 0x9f70, 0xf3c1, 0x98c0, 0x3cfa, 0x3fff, 0xbfff, 0xc563, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b9c40, 1},
+ {{0x3e00, 0xa10c, 0x74d7, 0x7456, 0x0dc6, 0x38d0, 0x8008, 0xe9ee, 0x3e00, 0xa100, 0x6f10, 0x6e10, 0x39e0, 0x3200, 0x800b, 0xeaef }, 16, 0x000b9c60, 1},
+ {{0x3c80, 0xa000, 0x2d08, 0x82b2, 0x6c10, 0x2500, 0x8100, 0x3a80, 0xa000, 0x5110, 0x3f20, 0x2f48, 0x800c, 0x0190, 0x3e20, 0x2f30 }, 16, 0x000b9c80, 1},
+ {{0x800c, 0x3c20, 0x2f60, 0x800c, 0x3a20, 0x2f18, 0x800c, 0x96c0, 0x499c, 0x290b, 0x8200, 0x0b9f, 0x33e1, 0x3000, 0x800b, 0x96c0 }, 16, 0x000b9ca0, 1},
+ {{0x439a, 0x2b0d, 0x8200, 0x0d9e, 0x3721, 0x2c88, 0x800c, 0x079e, 0x3221, 0x2878, 0x800c, 0x029f, 0x3321, 0x2670, 0x800c, 0x039a }, 16, 0x000b9cc0, 1},
+ {{0x3121, 0x2a80, 0x800c, 0x3800, 0xa800, 0x77d1, 0x419c, 0x4796, 0x0392, 0x4297, 0x0194, 0xee46, 0x94c0, 0xef46, 0xea46, 0x050e }, 16, 0x000b9ce0, 1},
+ {{0xec46, 0x050f, 0x450c, 0x050a, 0x4617, 0x3800, 0xa800, 0x7750, 0x4416, 0x4612, 0x3620, 0xa000, 0xeee9, 0x9f70, 0x3640, 0xa000 }, 16, 0x000b9d00, 1},
+ {{0x4414, 0xefea, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000b9d20, 1},
+ {{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x94c0, 0xe748, 0xeee8, 0x94c0, 0xfcca, 0xf3c9, 0x90c0, 0x5594, 0x3b18, 0x8001 }, 16, 0x000b9d40, 1},
+ {{0x6469, 0x94c0, 0xf6c9, 0x8449, 0x25ea, 0xede9, 0x840f, 0x9f43, 0x90c0, 0x90c0, 0x92d0, 0x541e, 0x441d, 0x0ec6, 0x38d0, 0x8008 }, 16, 0x000b9d60, 1},
+ {{0x90c0, 0x2e0f, 0x82b0, 0x5017, 0x6469, 0x8419, 0x25ea, 0x3b20, 0x33b4, 0x8009, 0x840f, 0x9f43, 0x90c0, 0x90c0, 0x92d0, 0x5519 }, 16, 0x000b9d80, 1},
+ {{0x451b, 0x2c10, 0x31a4, 0x2022, 0x800b, 0x9ac0, 0x676a, 0x75d6, 0x6c10, 0xece9, 0xedee, 0x94c0, 0x79e1, 0x842b, 0x96c0, 0x9b43 }, 16, 0x000b9da0, 1},
+ {{0x2b03, 0x8018, 0x001c, 0x3a20, 0x2ed0, 0x800c, 0x96c0, 0x551d, 0x2103, 0x8012, 0x94d0, 0x6c10, 0x451a, 0x401c, 0x551d, 0x4512 }, 16, 0x000b9dc0, 1},
+ {{0x98c0, 0x3c20, 0x2f14, 0x800c, 0xf941, 0x3521, 0x2ed0, 0x800c, 0x0594, 0x3321, 0x2e90, 0x800c, 0x98c0, 0x0322, 0x2f10, 0x800c }, 16, 0x000b9de0, 1},
+ {{0xec50, 0x3284, 0x3b70, 0x800b, 0x0614, 0x3820, 0x2f10, 0x800c, 0x276a, 0x35d6, 0x3d20, 0x2e90, 0x800c, 0x94c0, 0x79e1, 0x841d }, 16, 0x000b9e00, 1},
+ {{0x9f43, 0x101d, 0x3820, 0x2f70, 0x800c, 0x2103, 0x800a, 0x94c8, 0x4098, 0x501d, 0x4090, 0x9ac0, 0x676a, 0xe8ee, 0x3a20, 0x2e90 }, 16, 0x000b9e20, 1},
+ {{0x800c, 0x8423, 0x96c0, 0x9b46, 0x2b03, 0x8010, 0x3c20, 0x2ed0, 0x800c, 0x90c0, 0x2e90, 0x1318, 0x5214, 0x94d0, 0x693d, 0x451a }, 16, 0x000b9e40, 1},
+ {{0x7d6f, 0x421c, 0x3d20, 0x2f5c, 0x800c, 0x3421, 0x2ed0, 0x800c, 0x0495, 0x3421, 0x2e90, 0x800c, 0x98c0, 0x0422, 0x2f58, 0x800c }, 16, 0x000b9e60, 1},
+ {{0xed50, 0x3284, 0x3b70, 0x800b, 0x0615, 0x3820, 0x2f58, 0x800c, 0x276a, 0x3556, 0x3820, 0x2f70, 0x800c, 0x94c0, 0x7961, 0x842b }, 16, 0x000b9e80, 1},
+ {{0x98c0, 0x3c20, 0x2e90, 0x800c, 0x9f42, 0xeae8, 0x149a, 0x511c, 0x96c0, 0x6cc4, 0x2103, 0x8012, 0x94d0, 0x509a, 0x571c, 0x2cc3 }, 16, 0x000b9ea0, 1},
+ {{0x4198, 0x4190, 0x9ac0, 0x676a, 0x3f20, 0x2ed0, 0x800c, 0xebee, 0x8419, 0x96c0, 0x9b46, 0x2b03, 0x800a, 0xecef, 0x131c, 0x501b }, 16, 0x000b9ec0, 1},
+ {{0x92d0, 0x6933, 0x7d6f, 0x421f, 0x3f20, 0x2f44, 0x800c, 0x3321, 0x2ed0, 0x800c, 0x0397, 0x3021, 0x2e90, 0x800c, 0x98c0, 0x0022 }, 16, 0x000b9ee0, 1},
+ {{0x2f40, 0x800c, 0xef50, 0x3284, 0x3b70, 0x800b, 0x0617, 0x3820, 0x2f40, 0x800c, 0x276a, 0x36d6, 0x3c20, 0x2f70, 0x800c, 0x94c0 }, 16, 0x000b9f00, 1},
+ {{0x7ae1, 0x842b, 0x98c0, 0x3d20, 0x2e90, 0x800c, 0x9f45, 0xebec, 0x139b, 0x511d, 0x96c0, 0x6c59, 0x2103, 0x8012, 0x94d0, 0x559b }, 16, 0x000b9f20, 1},
+ {{0x511d, 0x2c45, 0x409c, 0x4094, 0x276a, 0x3f20, 0x2ed0, 0x800c, 0x8421, 0x96c0, 0x9b46, 0x2b03, 0x800a, 0xecef, 0x111e, 0x531c }, 16, 0x000b9f40, 1},
+ {{0x2af4, 0xd893, 0x7eef, 0x94d0, 0x3427, 0x8005, 0x7fef, 0x471f, 0x3b20, 0x2f2c, 0x800c, 0x3121, 0x2ed0, 0x800c, 0x0193, 0x3721 }, 16, 0x000b9f60, 1},
+ {{0x2e90, 0x800c, 0x98c0, 0x0722, 0x2f28, 0x800c, 0xeb50, 0x3284, 0x3b70, 0x800b, 0x0613, 0x3820, 0x2f28, 0x800c, 0x9cc0, 0x676a }, 16, 0x000b9f80, 1},
+ {{0x77d6, 0xf9c1, 0x3c20, 0x2f70, 0x800c, 0x94c0, 0x7be1, 0x842b, 0x98c0, 0x3d20, 0x2e90, 0x800c, 0x9f47, 0xeeec, 0x129e, 0x541d }, 16, 0x000b9fa0, 1},
+ {{0x96c0, 0x6cc8, 0x2103, 0x8012, 0x94d0, 0x539e, 0x551d, 0x2ccd, 0x419c, 0x4194, 0x9ac0, 0x676a, 0xeae9, 0x3820, 0x2f70, 0x800c }, 16, 0x000b9fc0, 1},
+ {{0x8419, 0x96c0, 0x9b46, 0x2b03, 0x8008, 0x5398, 0x7dc8, 0x65e5, 0x92d0, 0x7dc8, 0x75db, 0x435a, 0x0dc6, 0x38d0, 0x8008, 0x90c0 }, 16, 0x000b9fe0, 1},
+ {{0x2d0c, 0x82b0, 0x5414, 0x6669, 0x8419, 0x276a, 0x3e20, 0x33b4, 0x8009, 0x840f, 0x9f46, 0x90c0, 0x90c0, 0x92d0, 0x5019, 0x401e }, 16, 0x000ba000, 1},
+ {{0x6c10, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ba020, 1},
+ {{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0xc1f3, 0x05c6, 0x3684, 0x8009, 0x98c0, 0xdc01, 0x3b19 }, 16, 0x000ba040, 1},
+ {{0x800c, 0x9f70, 0xdc19, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x9cc0, 0x646a, 0xd190, 0xe748, 0x3b80, 0x3330, 0x8008, 0x98c0 }, 16, 0x000ba060, 1},
+ {{0x65e4, 0xc59e, 0x2121, 0x8688, 0x9ec7, 0x8438, 0x90c0, 0xd413, 0x90c0, 0x6e8d, 0x24c0, 0x83ca, 0x92c3, 0xf442, 0x96c0, 0x30c8 }, 16, 0x000ba080, 1},
+ {{0x8216, 0x7ec8, 0xcc40, 0x90c0, 0xec1b, 0x9cbc, 0xcc4a, 0x7472, 0xd445, 0x3c10, 0x9400, 0x3e10, 0x800a, 0x62f4, 0x6ef4, 0xf542 }, 16, 0x000ba0a0, 1},
+ {{0xf2c2, 0x3d48, 0xe768, 0x6565, 0x7d48, 0x94c0, 0x755a, 0x9f70, 0xd81a, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ba0c0, 1},
+ {{0x9cc0, 0x6e10, 0x6f90, 0x6f10, 0x6d90, 0xcd56, 0xce57, 0x9ac0, 0x74d7, 0x270b, 0x80a0, 0x7454, 0x9745, 0xe7eb, 0x96c0, 0xc94a }, 16, 0x000ba0e0, 1},
+ {{0x280a, 0x8104, 0x3a80, 0xa104, 0x7752, 0x7556, 0xeaef, 0xe9ee, 0x96c0, 0x4492, 0x27e8, 0x9fb0, 0x9ac0, 0x27ef, 0x9fd8, 0x90c0 }, 16, 0x000ba100, 1},
+ {{0x27ec, 0x9f88, 0x27e9, 0x9f60, 0x94d0, 0xc819, 0xc81c, 0x94c0, 0xc818, 0xc81f, 0x3a00, 0xb000, 0x7752, 0x7556, 0x2704, 0x8080 }, 16, 0x000ba120, 1},
+ {{0x9ac0, 0x7650, 0x77d1, 0xc942, 0x2000, 0x8081, 0x90c0, 0x5399, 0x71f4, 0x98d0, 0xd253, 0xd3d6, 0x7b41, 0x5399, 0x71f4, 0x9ac0 }, 16, 0x000ba140, 1},
+ {{0x6e90, 0x2a0e, 0x8016, 0xd3d6, 0xc181, 0x1316, 0x0778, 0x9f60, 0x9ac0, 0xd5a1, 0x7653, 0xcb42, 0x27ec, 0x9f62, 0x94c0, 0x7a61 }, 16, 0x000ba160, 1},
+ {{0x8483, 0x9cc0, 0x9944, 0x2903, 0x800e, 0x90c0, 0x90c0, 0x90c0, 0x9ec0, 0x6f10, 0x9a40, 0x2a03, 0x8010, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ba180, 1},
+ {{0x98c0, 0x2b03, 0x8010, 0x6e10, 0x9b41, 0x94c0, 0x27ed, 0x9f60, 0x3420, 0xa000, 0x5215, 0x3400, 0xa004, 0x7165, 0x90c0, 0x96c2 }, 16, 0x000ba1a0, 1},
+ {{0xc481, 0x2003, 0x8010, 0x92d0, 0xed42, 0x90c0, 0x90c0, 0x3420, 0xa000, 0x549b, 0x3400, 0xa800, 0x7374, 0x800d, 0x6669, 0x3600 }, 16, 0x000ba1c0, 1},
+ {{0xa800, 0xd354, 0xd3d5, 0x92d0, 0x7ac1, 0x90c0, 0x90c0, 0x9ad0, 0x6e90, 0x2d00, 0x8204, 0x78c1, 0x471c, 0x90c0, 0xeb3d, 0x9ac0 }, 16, 0x000ba1e0, 1},
+ {{0x65ea, 0x7753, 0xefee, 0x27e8, 0x9f88, 0x94c0, 0xef6a, 0x844b, 0x96c0, 0xcc53, 0x27ed, 0x9f60, 0x1717, 0xc942, 0x5c1d, 0x90c0 }, 16, 0x000ba200, 1},
+ {{0xecfe, 0x98c0, 0xec19, 0x32a4, 0x2070, 0x800b, 0x5094, 0x246a, 0x7b61, 0x94c3, 0x3100, 0x80ff, 0x7c68, 0x73f0, 0x92c2, 0x6e90 }, 16, 0x000ba220, 1},
+ {{0x94c7, 0x676a, 0xc581, 0x94c0, 0x4518, 0x81d7, 0x3600, 0xa800, 0x7556, 0xcc5b, 0x9ac0, 0x65ea, 0x7653, 0xe9ee, 0x27ed, 0x9fb0 }, 16, 0x000ba240, 1},
+ {{0x96c0, 0xe968, 0x2718, 0x814e, 0x1511, 0xcc53, 0x3c00, 0xa001, 0x27ec, 0x9f60, 0x75d5, 0x27ef, 0x9f88, 0x2c90, 0x161f, 0x5014 }, 16, 0x000ba260, 1},
+ {{0x2f10, 0xd321, 0x2718, 0x8118, 0x3e00, 0xa003, 0x646a, 0x74d0, 0x77d4, 0x74d0, 0xc942, 0xc782, 0x98c0, 0x7cc2, 0xe0ec, 0x2718 }, 16, 0x000ba280, 1},
+ {{0x80f2, 0xcb41, 0x90c0, 0xeb19, 0x3620, 0xa000, 0x5493, 0x90c0, 0x3c00, 0xac00, 0x34e1, 0x8001, 0x90c0, 0x36e0, 0x8001, 0x3600 }, 16, 0x000ba2a0, 1},
+ {{0xa800, 0x30e1, 0x8001, 0x3400, 0xa004, 0xd811, 0x3600, 0xb004, 0xd440, 0x7454, 0x3400, 0xa004, 0x6461, 0x3600, 0xa004, 0x3610 }, 16, 0x000ba2c0, 1},
+ {{0x8080, 0x8045, 0x33a4, 0x2070, 0x800b, 0x3600, 0xa00c, 0x7c42, 0x76d0, 0x3480, 0xa000, 0xc840, 0x90c0, 0x98c0, 0xe819, 0x32a4 }, 16, 0x000ba2e0, 1},
+ {{0x2070, 0x800b, 0x5090, 0x3400, 0xa800, 0x6c81, 0x64ea, 0x94c3, 0x3301, 0x80ff, 0x7ce8, 0x3400, 0xa004, 0x71f1, 0x92c3, 0x7b41 }, 16, 0x000ba300, 1},
+ {{0x31a4, 0x237a, 0x800b, 0x3e00, 0xba02, 0x7454, 0x7556, 0x7657, 0x3610, 0x80ff, 0xece0, 0x8055, 0x33a4, 0x2070, 0x800b, 0x3800 }, 16, 0x000ba320, 1},
+ {{0xa004, 0x7550, 0x2100, 0x8100, 0x3400, 0xa040, 0x6e91, 0x7ec2, 0xcb45, 0x90c0, 0x98c0, 0xeb19, 0x32a4, 0x2070, 0x800b, 0x5093 }, 16, 0x000ba340, 1},
+ {{0x3400, 0xa800, 0x6c92, 0x64ea, 0x94c3, 0x3301, 0x80ff, 0x7ce8, 0x3400, 0xa004, 0x71f1, 0x92c3, 0x7b41, 0x7bc1, 0xd7a3, 0x8533 }, 16, 0x000ba360, 1},
+ {{0x3800, 0xb800, 0x7556, 0x7657, 0xece0, 0xd322, 0x92c3, 0x6f10, 0x98c6, 0x30a4, 0x239e, 0x800b, 0xc681, 0x4615, 0x4115, 0x96c0 }, 16, 0x000ba380, 1},
+ {{0x7a61, 0xec42, 0xed42, 0x666a, 0x2dff, 0x9ed3, 0xcc5b, 0x9ac0, 0x65ea, 0x7453, 0xebee, 0x27e9, 0x9fd8, 0x96c0, 0xeb66, 0x2718 }, 16, 0x000ba3a0, 1},
+ {{0x8122, 0x1713, 0xcc53, 0x3c00, 0xa001, 0x27e8, 0x9f60, 0x7457, 0x27ec, 0x9fb0, 0x27eb, 0x9f88, 0x111b, 0x5614, 0xd0a1, 0x2718 }, 16, 0x000ba3c0, 1},
+ {{0x80e8, 0x2769, 0x2c90, 0x5310, 0x2718, 0x80de, 0xd5a4, 0x84c7, 0x9cc0, 0x3613, 0x807c, 0xc682, 0x3705, 0x8002, 0xc352, 0x3c00 }, 16, 0x000ba3e0, 1},
+ {{0xa101, 0x6e2e, 0x7ec2, 0x75d0, 0xcc4c, 0x80b7, 0x3a00, 0xa100, 0x7dc2, 0x7e42, 0xcd45, 0xcb4f, 0x94c0, 0xc553, 0xcf44, 0xc683 }, 16, 0x000ba400, 1},
+ {{0x36e0, 0xa000, 0xed1b, 0xef1b, 0x36e0, 0xa000, 0x5195, 0xed1b, 0x32a4, 0x2070, 0x800b, 0x3600, 0xa800, 0x7451, 0x77d1, 0x32a4 }, 16, 0x000ba420, 1},
+ {{0x2070, 0x800b, 0x3600, 0xa004, 0x7550, 0x509d, 0x3800, 0xa200, 0x7650, 0x74d7, 0x7451, 0x3400, 0xa800, 0x6ea8, 0x66ea, 0x94c3 }, 16, 0x000ba440, 1},
+ {{0x3b05, 0x80ff, 0x7ee8, 0x3400, 0xa004, 0x7075, 0x98c7, 0x32a4, 0x2070, 0x800b, 0x78c1, 0x77d1, 0x32a4, 0x2070, 0x800b, 0x3600 }, 16, 0x000ba460, 1},
+ {{0xa004, 0x76d0, 0x508f, 0x3800, 0xb000, 0x74d7, 0x6f81, 0x7b61, 0x67ea, 0x94c3, 0x3f07, 0x80ff, 0x7fe8, 0x3400, 0xa004, 0x7077 }, 16, 0x000ba480, 1},
+ {{0x94c7, 0x676a, 0x78c1, 0x818b, 0x3a80, 0xb900, 0x7556, 0x7453, 0xcc44, 0xcb47, 0xd0a6, 0x92c3, 0x6f10, 0x98c6, 0x30a4, 0x24ca }, 16, 0x000ba4a0, 1},
+ {{0x800b, 0xc681, 0x4611, 0x6c90, 0x4111, 0x96c0, 0x7861, 0xe942, 0xec42, 0x246a, 0xe842, 0x2dff, 0x9f03, 0xcc5b, 0x2e90, 0xe8ee }, 16, 0x000ba4c0, 1},
+ {{0xe86e, 0x96c0, 0x5410, 0x280c, 0x800c, 0x5614, 0x7276, 0x2718, 0x8174, 0x9ac0, 0x2e09, 0x8004, 0x65ea, 0x27e8, 0x9f60, 0x94c0 }, 16, 0x000ba4e0, 1},
+ {{0xebe9, 0x84a3, 0x96c0, 0xeb68, 0x27ed, 0x9fd8, 0x96c0, 0x5713, 0x27ef, 0x9fb0, 0x1117, 0x5415, 0xd0a1, 0x8007, 0xd221, 0x8475 }, 16, 0x000ba500, 1},
+ {{0x276a, 0x2e10, 0x2c90, 0x3553, 0x5010, 0x8449, 0x96c0, 0x9a46, 0x2a03, 0x800a, 0x90c0, 0x3600, 0xa008, 0x656a, 0x6a38, 0x3680 }, 16, 0x000ba520, 1},
+ {{0xa000, 0xcb44, 0x842b, 0x96c0, 0x9b42, 0x2b03, 0x800c, 0xebfc, 0xeb19, 0x5313, 0x71e0, 0x92c2, 0x7a41, 0x94c2, 0x2003, 0x800e }, 16, 0x000ba540, 1},
+ {{0x92d0, 0xeb42, 0x90c0, 0x90c0, 0x92d0, 0x78c1, 0x90c0, 0x90c0, 0x75d2, 0x73f4, 0x92c2, 0x6c10, 0x92c3, 0xc081, 0xd021, 0x90c0 }, 16, 0x000ba560, 1},
+ {{0x96c2, 0xc081, 0x2e0b, 0x8504, 0x2418, 0x8116, 0x94c2, 0x4092, 0x4013, 0x96c0, 0x7ac1, 0xe842, 0xef42, 0x31f5, 0xed42, 0x8177 }, 16, 0x000ba580, 1},
+ {{0x9ac0, 0x7b61, 0x2e0f, 0x8004, 0x6e90, 0xc781, 0x676a, 0x846b, 0x2e10, 0x5116, 0x64ea, 0x8457, 0x5216, 0x9ac0, 0x34e1, 0x8002 }, 16, 0x000ba5a0, 1},
+ {{0x90c0, 0x34a3, 0x8002, 0x9ac0, 0x30e1, 0x8002, 0x90c0, 0x30a3, 0x8002, 0x9cc0, 0x36a3, 0x8002, 0xd891, 0x36e2, 0x8002, 0xd813 }, 16, 0x000ba5c0, 1},
+ {{0x94c0, 0xd4c2, 0xd443, 0x96c0, 0xd4c4, 0xd444, 0x7a41, 0x94c0, 0xcd41, 0xcb40, 0x90c0, 0x94c0, 0xedfc, 0xebfc, 0x94c0, 0xed1f }, 16, 0x000ba5e0, 1},
+ {{0xeb1f, 0x5115, 0x4113, 0x5216, 0x7174, 0x81af, 0x3ac1, 0x3bc1, 0x5314, 0x79e1, 0x71f5, 0x819b, 0x98c0, 0x6d10, 0x5316, 0x2e0a }, 16, 0x000ba600, 1},
+ {{0x8004, 0x96c0, 0x65ea, 0x27e8, 0x9f60, 0x8469, 0x1414, 0x5716, 0x3a61, 0x5118, 0x9ac0, 0x3480, 0x8007, 0x90c0, 0x3683, 0x8007 }, 16, 0x000ba620, 1},
+ {{0x3080, 0x8007, 0xda90, 0xd6c3, 0x3941, 0xd6c2, 0xc945, 0x90c0, 0xe9fc, 0xe91a, 0x4111, 0x5516, 0x72f2, 0x81d3, 0x31a4, 0x2692 }, 16, 0x000ba640, 1},
+ {{0x800b, 0x9ac0, 0x2e0b, 0x8004, 0x65ea, 0x27ec, 0x9f60, 0x841f, 0x34d5, 0x3ac1, 0x1410, 0x5016, 0x2880, 0x531c, 0xc941, 0x90c0 }, 16, 0x000ba660, 1},
+ {{0xe9fc, 0xe91b, 0x4311, 0x5116, 0x70f5, 0x81e7, 0x5310, 0x79c1, 0x4310, 0x98c0, 0x2e0b, 0x8504, 0x6c10, 0xc281, 0x4213, 0x96c0 }, 16, 0x000ba680, 1},
+ {{0xce5f, 0x27ec, 0x9f60, 0x94c0, 0xe7ec, 0xcd5e, 0x9f70, 0x3660, 0xa000, 0xefea, 0xeee9, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000ba6a0, 1},
+ {{0x96c0, 0x6d90, 0x9620, 0x9720, 0x2704, 0x8100, 0x94c0, 0x9e20, 0x9f20, 0x94c0, 0xe748, 0xebe8, 0x92c8, 0x9383, 0x3c80, 0xa000 }, 16, 0x000ba6c0, 1},
+ {{0x280e, 0x8108, 0x6d90, 0x2d00, 0x8514, 0x3c40, 0xa000, 0x2b00, 0x8520, 0x90c0, 0x2e08, 0x8518, 0x9ac0, 0x2002, 0x851c, 0x90c0 }, 16, 0x000ba6e0, 1},
+ {{0x2102, 0x8512, 0x94c0, 0xeee8, 0xece8, 0x94c0, 0xefe8, 0xeae8, 0x3680, 0xa000, 0xebe8, 0xee3d, 0x94c0, 0xec3b, 0xf491, 0x3620 }, 16, 0x000ba700, 1},
+ {{0xa000, 0xef39, 0xea62, 0x36a0, 0xa000, 0xeb38, 0x4316, 0x0394, 0x4410, 0x0312, 0x4317, 0x3680, 0xa100, 0x4393, 0x4396, 0x98c0 }, 16, 0x000ba720, 1},
+ {{0x0dc6, 0x38d0, 0x8008, 0xc19e, 0x98c0, 0x2e00, 0x850e, 0x77d1, 0xece8, 0x96c0, 0xc581, 0x2d0f, 0x84a2, 0x3620, 0xa000, 0x5717 }, 16, 0x000ba740, 1},
+ {{0xec3e, 0x3c00, 0xa800, 0x3ffb, 0x9f00, 0xede8, 0x2e00, 0x850c, 0x98c0, 0x2a00, 0x8510, 0x7de8, 0xc49e, 0x96c0, 0x6f7d, 0xed3e }, 16, 0x000ba760, 1},
+ {{0xebe8, 0x96c0, 0x74d7, 0xeb3a, 0xc29e, 0x98c0, 0x2f00, 0x850a, 0x6d7c, 0xeae8, 0x0514, 0xc685, 0x98c0, 0x0cc6, 0x38d0, 0x8008 }, 16, 0x000ba780, 1},
+ {{0xea3f, 0x94c0, 0xefe8, 0xc3a0, 0x9ac0, 0x2c0e, 0x84a2, 0x90c0, 0x2c00, 0x8508, 0x3820, 0xa000, 0x5716, 0x2e00, 0x8506, 0x3a00 }, 16, 0x000ba7a0, 1},
+ {{0xa800, 0x3f18, 0x80ff, 0xef3c, 0xc782, 0x3820, 0xa000, 0x6c7d, 0xece8, 0xc0a0, 0x3820, 0xa000, 0x7652, 0x4413, 0xc484, 0x3a60 }, 16, 0x000ba7c0, 1},
+ {{0xa000, 0x0cc6, 0x38d0, 0x8008, 0xc194, 0x3820, 0xa100, 0xc585, 0x280d, 0x8002, 0x3840, 0xa000, 0xec3e, 0x2c0b, 0x84a4, 0x3820 }, 16, 0x000ba7e0, 1},
+ {{0xa000, 0x5213, 0x2100, 0x8064, 0x3600, 0xa800, 0x35f8, 0x9f00, 0x7c68, 0x6c7d, 0x3554, 0x7653, 0x6e7c, 0x4615, 0x0dc6, 0x38d0 }, 16, 0x000ba800, 1},
+ {{0x8008, 0x90c0, 0x2d0e, 0x84a4, 0x3420, 0xa000, 0x5316, 0x3600, 0xa800, 0x3718, 0x80ff, 0x6c7d, 0x3600, 0xb000, 0x75d4, 0x7650 }, 16, 0x000ba820, 1},
+ {{0x6f7c, 0x4712, 0x0ec6, 0x38d0, 0x8008, 0x90c0, 0x2e0d, 0x84a6, 0x3420, 0xa000, 0x5615, 0x3600, 0xa800, 0x3df8, 0x9f00, 0x7c68 }, 16, 0x000ba840, 1},
+ {{0x6c7d, 0x3600, 0xb004, 0x7454, 0x7651, 0x3400, 0xa804, 0x6c7c, 0x3420, 0xa000, 0x4417, 0x0dc6, 0x38d0, 0x8008, 0x90c0, 0x2d0f }, 16, 0x000ba860, 1},
+ {{0x84a6, 0x5517, 0x3b18, 0x80ff, 0x6c7d, 0x3400, 0xa004, 0x74d4, 0x3400, 0xa804, 0x6d7c, 0x3420, 0xa000, 0x4514, 0x0dc6, 0x38d0 }, 16, 0x000ba880, 1},
+ {{0x8008, 0x90c0, 0x2d0b, 0x8490, 0x3420, 0xa000, 0x5513, 0x3600, 0xa804, 0x3b19, 0x8001, 0x34a0, 0xa000, 0x411d, 0x0ec6, 0x38d0 }, 16, 0x000ba8a0, 1},
+ {{0x8008, 0x90c0, 0x2e0e, 0x8490, 0x3420, 0xa000, 0x5516, 0x3600, 0xa804, 0x3b19, 0x8002, 0x3400, 0xa804, 0x74c1, 0x34a0, 0xa000 }, 16, 0x000ba8c0, 1},
+ {{0x411d, 0x0fc6, 0x38d0, 0x8008, 0x90c0, 0x2f0a, 0x8490, 0x3420, 0xa000, 0x5512, 0x3600, 0xa804, 0x3b19, 0x8004, 0x3400, 0xa004 }, 16, 0x000ba8e0, 1},
+ {{0x7ce2, 0x34a0, 0xa000, 0x411d, 0x0cc6, 0x38d0, 0x8008, 0x90c0, 0x2c0d, 0x8490, 0x3420, 0xa000, 0x5115, 0x3600, 0xa804, 0x331d }, 16, 0x000ba900, 1},
+ {{0x8008, 0x3400, 0xa004, 0x7ee3, 0x34a0, 0xa000, 0x451d, 0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x2b0f, 0x8492, 0x3420, 0xa000, 0x5517 }, 16, 0x000ba920, 1},
+ {{0x34a0, 0xa000, 0x451d, 0x0bc6, 0x38d0, 0x8008, 0x90c0, 0x2b0c, 0x8496, 0x3420, 0xa000, 0x5114, 0x34a0, 0xa000, 0x411d, 0x0cc6 }, 16, 0x000ba940, 1},
+ {{0x38d0, 0x8008, 0x90c0, 0x2c0a, 0x8498, 0x3420, 0xa000, 0x5112, 0x34a0, 0xa000, 0x411d, 0x0fc6, 0x38d0, 0x8008, 0x3620, 0xa000 }, 16, 0x000ba960, 1},
+ {{0x2d0a, 0x8002, 0x9ac0, 0x2f0e, 0x849a, 0x90c0, 0x2a0d, 0x8002, 0x3420, 0xa000, 0x5116, 0x34a0, 0xa000, 0x4115, 0x3a40, 0xa100 }, 16, 0x000ba980, 1},
+ {{0x0ec6, 0x38d0, 0x8008, 0x5515, 0x3400, 0xa800, 0xd815, 0x96c0, 0x6461, 0x2e0b, 0x8494, 0x3a20, 0xa000, 0x5113, 0x32e4, 0x3c48 }, 16, 0x000ba9a0, 1},
+ {{0x8001, 0x3420, 0xa000, 0x4112, 0x3620, 0xa000, 0x5512, 0x409d, 0x3800, 0xa800, 0xd815, 0x2100, 0x8064, 0x32e4, 0x3c48, 0x8001 }, 16, 0x000ba9c0, 1},
+ {{0x6461, 0x3820, 0xa000, 0x6c90, 0x4095, 0x5510, 0x3600, 0xa004, 0xd2a1, 0xed50, 0x4115, 0x3626, 0xa000, 0xc1f7, 0xed48, 0x0995 }, 16, 0x000ba9e0, 1},
+ {{0xeaed, 0xea66, 0x4112, 0x96c2, 0x01c6, 0x3684, 0x8009, 0x3606, 0xa800, 0xdc81, 0x8034, 0x96c2, 0x01c2, 0x3684, 0x8009, 0x3400 }, 16, 0x000baa00, 1},
+ {{0xa004, 0xd2a2, 0x90c0, 0x3a62, 0xa000, 0x05c6, 0x3684, 0x8009, 0xc1fb, 0x3402, 0xa804, 0xde81, 0x3822, 0xa000, 0x05c2, 0x3684 }, 16, 0x000baa20, 1},
+ {{0x8009, 0x3840, 0xa004, 0x6e90, 0xc181, 0x5895, 0x3640, 0xa000, 0x5112, 0xf542, 0x3244, 0x33d0, 0x800b, 0x3420, 0xa000, 0xf141 }, 16, 0x000baa40, 1},
+ {{0x2c10, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000baa60, 1},
+ {{0x9ac0, 0x64e9, 0x0dc6, 0x38d0, 0x8008, 0xc19e, 0x98c0, 0x280c, 0x8112, 0x7651, 0xc581, 0x3c61, 0xa000, 0x2100, 0x84a2, 0x90c0 }, 16, 0x000baa80, 1},
+ {{0x2100, 0x84a8, 0x3a26, 0xa100, 0x90c0, 0xcb41, 0x2300, 0x84a2, 0x3a27, 0xa000, 0x90c0, 0xeaec, 0x2300, 0x84a8, 0x3600, 0xa100 }, 16, 0x000baaa0, 1},
+ {{0xeb1d, 0xc843, 0x94c0, 0x5313, 0x9620, 0x98c0, 0x37f8, 0x9f00, 0xc69e, 0xea62, 0x7c68, 0x2c7d, 0x4014, 0x34d4, 0x4414, 0x6d7c }, 16, 0x000baac0, 1},
+ {{0x4514, 0x0bc6, 0x38d0, 0x8008, 0x90c0, 0xe81b, 0x5010, 0x311a, 0x80ff, 0x2e7d, 0x4212, 0x4612, 0x94c0, 0x4612, 0x9621, 0x9f71 }, 16, 0x000baae0, 1},
+ {{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x96c0, 0xcd83, 0x280e, 0x8648, 0x3820, 0xa000, 0x5d16, 0x270c, 0x8020, 0x3a20 }, 16, 0x000bab00, 1},
+ {{0xa000, 0x0dc2, 0x3688, 0x8009, 0xe7ec, 0x36c0, 0xa100, 0xed8d, 0xeeed, 0x3880, 0xa000, 0xedfe, 0x2518, 0x8550, 0x3c20, 0xa000 }, 16, 0x000bab20, 1},
+ {{0x64e9, 0x3cc0, 0x3670, 0x8009, 0xc9ff, 0x9ac0, 0x2e0f, 0x8004, 0x90c0, 0x2e09, 0x8004, 0x3680, 0xa000, 0xed1c, 0xeaef, 0x3a80 }, 16, 0x000bab40, 1},
+ {{0xa000, 0x5b95, 0x34f9, 0x3fff, 0xbfff, 0x90c0, 0x9b61, 0x96c0, 0x8023, 0x2e09, 0x8002, 0x94c0, 0xcca0, 0xebe9, 0xc581, 0x0516 }, 16, 0x000bab60, 1},
+ {{0xeb3c, 0x1513, 0x5313, 0x0519, 0x30a4, 0x3082, 0x800b, 0x4311, 0x2e0b, 0x8004, 0xeceb, 0xec62, 0x1614, 0x30a4, 0x3082, 0x800b }, 16, 0x000bab80, 1},
+ {{0x4613, 0x96c0, 0x64e9, 0xcba2, 0xe9ef, 0xe97a, 0xea3b, 0x94c0, 0x5712, 0x84b4, 0x4717, 0x1011, 0xebee, 0x96c0, 0x6469, 0xeaee }, 16, 0x000baba0, 1},
+ {{0xeb70, 0x94c0, 0xea6c, 0x80a1, 0x1293, 0x39c8, 0x3c00, 0xbfff, 0x0292, 0xccff, 0x1d91, 0x34f9, 0x3fff, 0xbfff, 0x1193, 0xf442 }, 16, 0x000babc0, 1},
+ {{0x98c0, 0xecad, 0x3ac8, 0x3c04, 0xbfff, 0x801b, 0x39c8, 0x3c00, 0xbfff, 0x5092, 0x5591, 0xcb45, 0x90c0, 0xebad, 0x85f7, 0x94c0 }, 16, 0x000babe0, 1},
+ {{0xf542, 0xf045, 0x98c0, 0x6e90, 0x6f90, 0xf3c2, 0xf6c5, 0x98c0, 0x65e0, 0x3cce, 0x8410, 0x7ed0, 0x98c0, 0x36cc, 0x9410, 0x7dd0 }, 16, 0x000bac00, 1},
+ {{0x6761, 0x96c0, 0x65e1, 0x38ed, 0x8400, 0xd5c6, 0x1505, 0xa001, 0x90c0, 0x9ac6, 0xeaee, 0xc681, 0xd6c7, 0x90c0, 0x6c10, 0x9ac6 }, 16, 0x000bac20, 1},
+ {{0xea68, 0x90c0, 0x64e1, 0xd6c6, 0x65e1, 0xd4c3, 0x1505, 0xa001, 0x90c0, 0x96c6, 0xd445, 0xc581, 0xc282, 0x94c6, 0x4216, 0xd445 }, 16, 0x000bac40, 1},
+ {{0xc012, 0xef62, 0x2f09, 0x8002, 0x1511, 0x30a4, 0x3082, 0x800b, 0x4517, 0x98c0, 0xefe9, 0x3bc8, 0x3c00, 0xbfff, 0x94c0, 0xef62 }, 16, 0x000bac60, 1},
+ {{0xf445, 0x1417, 0x3ac8, 0x3c00, 0xbfff, 0x4411, 0x1c93, 0x3bc8, 0x3c04, 0xbfff, 0x90c0, 0x3480, 0xa000, 0xe9ac, 0x8019, 0x5693 }, 16, 0x000bac80, 1},
+ {{0x5592, 0xc055, 0x90c0, 0x3480, 0xa000, 0xe8ac, 0x85f3, 0x94c0, 0xf545, 0xf643, 0x98c0, 0x6e10, 0x6e90, 0xf7c5, 0xf3c3, 0x98c0 }, 16, 0x000baca0, 1},
+ {{0x67e0, 0x36c9, 0x8410, 0x7e50, 0x98c0, 0x3eca, 0x9410, 0x7fd0, 0x64e1, 0x96c0, 0x67e1, 0x34ec, 0x8400, 0xd7c1, 0x1505, 0xa001 }, 16, 0x000bacc0, 1},
+ {{0x90c0, 0x9ac6, 0xecee, 0x90c0, 0x67e0, 0xc581, 0xd645, 0x94c6, 0xec68, 0xd645, 0x2660, 0xc114, 0x307c, 0x64e0, 0x2518, 0x8386 }, 16, 0x000bace0, 1},
+ {{0x7064, 0x8409, 0x70ff, 0x2518, 0x837c, 0x3680, 0xa000, 0xe8ee, 0x5617, 0x3a80, 0xa000, 0xe87c, 0x3bc8, 0x3c00, 0xbfff, 0x3680 }, 16, 0x000bad00, 1},
+ {{0xa000, 0x5710, 0xeaee, 0x96c0, 0x6fdf, 0xea74, 0xc159, 0x3677, 0x0717, 0xf145, 0x666a, 0x92c2, 0x6c10, 0x92c2, 0x4017, 0x5317 }, 16, 0x000bad20, 1},
+ {{0x4311, 0x1f93, 0x5192, 0x3ac8, 0x3c04, 0xbfff, 0x3a80, 0xa000, 0xe9af, 0x3bc8, 0x3c00, 0xbfff, 0x8015, 0x5392, 0x5593, 0xc945 }, 16, 0x000bad40, 1},
+ {{0x90c0, 0xe9af, 0x85f7, 0x94c0, 0xf545, 0xf348, 0x98c0, 0x6d10, 0x6f90, 0xf6c5, 0xf3c8, 0x98c0, 0x6760, 0x36cb, 0x8410, 0x7d50 }, 16, 0x000bad60, 1},
+ {{0x98c0, 0x3ccd, 0x9410, 0x7f50, 0x65e1, 0x96c0, 0x6761, 0x3aea, 0x8400, 0xd743, 0x1505, 0xa001, 0x90c0, 0x96c6, 0xd547, 0xc381 }, 16, 0x000bad80, 1},
+ {{0x64e1, 0x96c6, 0x6c10, 0xd543, 0x6761, 0xd4c6, 0x1505, 0xa001, 0x96c0, 0xd442, 0xcba0, 0xe9ee, 0x94c6, 0x4d16, 0xc281, 0x94c6 }, 16, 0x000bada0, 1},
+ {{0xe93b, 0xd442, 0x1411, 0xc014, 0x2669, 0xc181, 0x2718, 0x82b6, 0x33a4, 0x2a80, 0x800b, 0x31a4, 0x3082, 0x800b, 0x96c0, 0x64e9 }, 16, 0x000badc0, 1},
+ {{0xcaa2, 0xebee, 0x9ac0, 0x2e09, 0x8002, 0x90c0, 0x2518, 0x812e, 0x94c0, 0xeb3a, 0xefee, 0x1513, 0xecee, 0x96c0, 0x66e9, 0xef7c }, 16, 0x000bade0, 1},
+ {{0xec7a, 0x94c0, 0x5517, 0x8017, 0x1714, 0x5211, 0x6edb, 0x2f29, 0x30a4, 0x2e26, 0x800b, 0x4611, 0x94c0, 0xcca0, 0xeae9, 0x90c0 }, 16, 0x000bae00, 1},
+ {{0xea3c, 0x5612, 0x4611, 0x94c0, 0xe942, 0xcca8, 0x94c0, 0xebe9, 0xefee, 0x94c0, 0xeb62, 0xef70, 0x1513, 0xebee, 0x0511, 0xeb6c }, 16, 0x000bae20, 1},
+ {{0x1597, 0xe93c, 0x1411, 0xe9ee, 0x9ac0, 0x6669, 0x3401, 0x2000, 0x801e, 0xe96c, 0x94c0, 0x5091, 0x8017, 0x7c41, 0x307c, 0x4091 }, 16, 0x000bae40, 1},
+ {{0x840d, 0x0491, 0x31a4, 0x2e6c, 0x800b, 0x4593, 0x98c0, 0x3bc8, 0x3c00, 0xbfff, 0xcaff, 0x98c0, 0xefee, 0x37f9, 0x3fff, 0xbfff }, 16, 0x000bae60, 1},
+ {{0x1993, 0xef6c, 0x1197, 0xf748, 0x98c0, 0xeaa9, 0x3bc8, 0x3c04, 0xbfff, 0x801b, 0x3ac8, 0x3c00, 0xbfff, 0x5093, 0x5792, 0xcd47 }, 16, 0x000bae80, 1},
+ {{0x90c0, 0xeda9, 0x85f7, 0x94c0, 0xf748, 0xf046, 0x98c0, 0x6e90, 0x6f90, 0xf2c8, 0xf4c6, 0x98c0, 0x6560, 0x38cc, 0x8410, 0x7ed0 }, 16, 0x000baea0, 1},
+ {{0x98c0, 0x34ce, 0x9410, 0x7d50, 0x6661, 0x96c0, 0x6561, 0x3ced, 0x8400, 0xd544, 0x1505, 0xa001, 0x90c0, 0x9ac6, 0xeaee, 0xc481 }, 16, 0x000baec0, 1},
+ {{0xd6c7, 0x90c0, 0x6c10, 0x9ac6, 0xea68, 0x90c0, 0x64e1, 0xd6c4, 0x6561, 0xd4c2, 0x1505, 0xa001, 0x90c0, 0x96c6, 0xd445, 0xc581 }, 16, 0x000baee0, 1},
+ {{0xc682, 0x94c6, 0x4616, 0xd445, 0x98c0, 0xc012, 0x31a4, 0x3082, 0x800b, 0x3a40, 0xa000, 0x3cc8, 0x3c00, 0xbfff, 0xc9ff, 0x31f9 }, 16, 0x000baf00, 1},
+ {{0x3fff, 0xbfff, 0x1a94, 0xf148, 0x3bc8, 0x3c04, 0xbfff, 0x3a80, 0xa000, 0xe9aa, 0x39c8, 0x3c00, 0xbfff, 0x8015, 0x5393, 0x5491 }, 16, 0x000baf20, 1},
+ {{0xcf44, 0x90c0, 0xefaa, 0x85f7, 0x94c0, 0xf448, 0xf347, 0x98c0, 0x6e90, 0x6c90, 0xf7c8, 0xf3c7, 0x98c0, 0x67e0, 0x36c8, 0x8410 }, 16, 0x000baf40, 1},
+ {{0x7ed0, 0x98c0, 0x3ece, 0x9410, 0x7fd0, 0x6461, 0x96c0, 0x67e1, 0x3ced, 0x8400, 0xd7c0, 0x1505, 0xa001, 0x90c0, 0x9ac6, 0xefee }, 16, 0x000baf60, 1},
+ {{0x90c0, 0x67e0, 0xc181, 0xd6c1, 0x94c6, 0xef68, 0xd6c1, 0x26e0, 0xc117, 0x307d, 0x64e0, 0x2518, 0x80e0, 0x7065, 0x8409, 0x70ff }, 16, 0x000baf80, 1},
+ {{0x2518, 0x80d6, 0x98c0, 0x2e0b, 0x8002, 0x6d90, 0xeaee, 0x2c90, 0x1013, 0xea7c, 0x2469, 0x1412, 0x39c8, 0x3c00, 0xbfff, 0x94c0 }, 16, 0x000bafa0, 1},
+ {{0xc15e, 0x8419, 0xeb42, 0x0313, 0x32a4, 0x2a80, 0x800b, 0x4316, 0x31a4, 0x3082, 0x800b, 0x98c0, 0x6ec0, 0xf648, 0x2b0c, 0x8002 }, 16, 0x000bafc0, 1},
+ {{0x34f5, 0x0513, 0x3ac8, 0x3c04, 0xbfff, 0x64ea, 0x92c2, 0x6f10, 0x92c2, 0x4613, 0x5513, 0x4514, 0x1b91, 0xec78, 0x1194, 0x39c8 }, 16, 0x000bafe0, 1},
+ {{0x3c00, 0xbfff, 0x3480, 0xa000, 0xe9ab, 0x8015, 0x5592, 0x5291, 0xc842, 0x90c0, 0xe8ab, 0x85f7, 0x94c0, 0xf248, 0xf544, 0x98c0 }, 16, 0x000bb000, 1},
+ {{0x6f10, 0x6f90, 0xf3c8, 0xf5c4, 0x98c0, 0x65e0, 0x3aca, 0x8410, 0x7f50, 0x98c0, 0x36cd, 0x9410, 0x7dd0, 0x6561, 0x96c0, 0x65e1 }, 16, 0x000bb020, 1},
+ {{0x3aee, 0x8400, 0xd5c2, 0x1505, 0xa001, 0x90c0, 0x96c6, 0xd747, 0xc281, 0x6c10, 0x96c6, 0x64e1, 0xd742, 0x65e1, 0xd4c3, 0x1505 }, 16, 0x000bb040, 1},
+ {{0xa001, 0x90c0, 0x94c6, 0xd446, 0xc681, 0x98c6, 0x30a4, 0x3082, 0x800b, 0xd446, 0xc017, 0x2e09, 0x8004, 0xebe9, 0xeb62, 0x5613 }, 16, 0x000bb060, 1},
+ {{0x4611, 0x96c0, 0x5916, 0x27ec, 0x9fe0, 0x94c0, 0xe7ec, 0xee44, 0x3620, 0xa000, 0xe9ae, 0x5016, 0x94c0, 0x9e21, 0x9f21, 0x94c0 }, 16, 0x000bb080, 1},
+ {{0x9621, 0x9721, 0x9f70, 0x96c3, 0x09c2, 0x3688, 0x8009, 0x90c0, 0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x96c0, 0xe748 }, 16, 0x000bb0a0, 1},
+ {{0x280f, 0x8622, 0x1417, 0xebef, 0x98c0, 0x6669, 0xeb62, 0x2e00, 0x851e, 0x94c0, 0x5213, 0x845d, 0xd121, 0x90c0, 0x98c2, 0x04c6 }, 16, 0x000bb0c0, 1},
+ {{0x3684, 0x8009, 0xc6f7, 0x94c6, 0x8028, 0xde06, 0x96c2, 0x04c2, 0x3684, 0x8009, 0xd122, 0x90c0, 0x98c2, 0x06c6, 0x3684, 0x8009 }, 16, 0x000bb0e0, 1},
+ {{0xc5fb, 0x92c2, 0xdf05, 0x96c2, 0x06c2, 0x3684, 0x8009, 0x98c0, 0x2f0c, 0x802e, 0x6d10, 0xc481, 0x2c90, 0x1894, 0xf242, 0x3244 }, 16, 0x000bb100, 1},
+ {{0x33d0, 0x800b, 0xf441, 0x2c10, 0x31a4, 0x32b4, 0x800b, 0x94c0, 0xebef, 0xf6c9, 0x96c0, 0xeb3e, 0x2a00, 0x8514, 0x96c0, 0x5193 }, 16, 0x000bb120, 1},
+ {{0x2b00, 0x8522, 0x98c0, 0x2202, 0x851a, 0x64ea, 0xedef, 0x94c0, 0xeeef, 0xecef, 0x98c6, 0xed3a, 0x02c6, 0x3680, 0x8009, 0x94c6 }, 16, 0x000bb140, 1},
+ {{0xee3b, 0x7941, 0x3e46, 0xa000, 0x90c0, 0xec3a, 0x02c2, 0x3680, 0x8009, 0x676a, 0x8471, 0x98c0, 0x9b46, 0x2b03, 0x800a, 0x90c0 }, 16, 0x000bb160, 1},
+ {{0x24e9, 0x5515, 0x94c0, 0x7ac1, 0x8458, 0x4515, 0x5411, 0x3674, 0x9f00, 0x800d, 0x3694, 0x80ff, 0x94c6, 0x8009, 0x6c90, 0xc181 }, 16, 0x000bb180, 1},
+ {{0x1b96, 0x5594, 0x90c0, 0xeb18, 0x92bb, 0x6e09, 0x0494, 0xd641, 0x4494, 0x5b96, 0x90c0, 0xeb18, 0x919b, 0x5396, 0x79c1, 0x96c0 }, 16, 0x000bb1a0, 1},
+ {{0x3613, 0x80ff, 0x4396, 0x92c2, 0x6f90, 0x92c2, 0x4796, 0x5794, 0x3617, 0x8095, 0x92c3, 0x6c90, 0x92c2, 0xc181, 0x92d0, 0xe942 }, 16, 0x000bb1c0, 1},
+ {{0x90c0, 0x90c0, 0xeeef, 0xee62, 0x5516, 0xd2a1, 0x8437, 0x24e9, 0xc0f7, 0x90c0, 0x96c3, 0x03c6, 0x3684, 0x8009, 0x96c7, 0x845a }, 16, 0x000bb1e0, 1},
+ {{0x0903, 0xa008, 0x96c3, 0x03c2, 0x3684, 0x8009, 0x07c6, 0x3684, 0x8009, 0x98c0, 0xdf80, 0x30a4, 0x3256, 0x800b, 0x07c2, 0x3684 }, 16, 0x000bb200, 1},
+ {{0x8009, 0xd2a2, 0x8433, 0x64e9, 0x90c0, 0x98c1, 0x05c6, 0x3684, 0x8009, 0xc3fb, 0x96c2, 0x02c6, 0x3684, 0x8009, 0x98c1, 0x0905 }, 16, 0x000bb220, 1},
+ {{0xa004, 0x90c0, 0xdd03, 0x96c3, 0x05c2, 0x3684, 0x8009, 0x96c2, 0x02c2, 0x3684, 0x8009, 0x33a4, 0x2b00, 0x800b, 0x1116, 0x0ac6 }, 16, 0x000bb240, 1},
+ {{0x38d0, 0x8008, 0xd0a2, 0x96c0, 0x8435, 0x2a0c, 0x82b0, 0x5514, 0xd2a2, 0x8429, 0x96c0, 0x676a, 0x2f0c, 0x802a, 0x841f, 0x96c0 }, 16, 0x000bb260, 1},
+ {{0x9b46, 0x2b03, 0x8012, 0x3d20, 0x33b4, 0x8009, 0x92c0, 0x90c0, 0x92d0, 0x5014, 0x3e10, 0x8147, 0x401d, 0x98c0, 0x2f0a, 0x802e }, 16, 0x000bb280, 1},
+ {{0x6c10, 0xc181, 0x188a, 0xf141, 0x3244, 0x33d0, 0x800b, 0x1112, 0xf042, 0x6c10, 0xe768, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621 }, 16, 0x000bb2a0, 1},
+ {{0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x96c0, 0x6c90, 0x9620, 0xc390, 0x94c0, 0x9e20, 0xc94e, 0x94c0 }, 16, 0x000bb2c0, 1},
+ {{0xe748, 0xeee8, 0x32e4, 0x3c8a, 0x8001, 0xf341, 0x98c0, 0x2e0c, 0x8002, 0x6e10, 0xc946, 0x0414, 0x3a80, 0x31a4, 0x8009, 0xec44 }, 16, 0x000bb2e0, 1},
+ {{0x0414, 0xedec, 0x1019, 0xed62, 0x0016, 0xec42, 0x1311, 0xe942, 0x4315, 0x55d2, 0x3b1b, 0x8001, 0x65e9, 0x90c0, 0x92c3, 0x5816 }, 16, 0x000bb300, 1},
+ {{0x90c0, 0x92c3, 0xe8fc, 0x92c3, 0x4816, 0x5111, 0x331c, 0x800f, 0x441c, 0x1411, 0xcc4e, 0x38cb, 0x8104, 0x32c4, 0x20c0, 0x800a }, 16, 0x000bb320, 1},
+ {{0x4314, 0x94c0, 0xcc46, 0xe768, 0x9e21, 0x94c0, 0xec42, 0x9621, 0x9f70, 0x4894, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000bb340, 1},
+ {{0x3c80, 0xa006, 0x7456, 0x2809, 0x800c, 0x74d7, 0xe8ef, 0x5d91, 0x90c0, 0x5f95, 0x90c0, 0x2f0b, 0x8004, 0x5493, 0x9ac0, 0x399b }, 16, 0x000bb360, 1},
+ {{0x8000, 0x90c0, 0x390d, 0x8001, 0x65e9, 0x849d, 0x96c0, 0x66e9, 0x395a, 0x8000, 0x8493, 0x2569, 0x5597, 0x96c0, 0x3b1e, 0x8010 }, 16, 0x000bb380, 1},
+ {{0x808d, 0x96c0, 0x6769, 0x3b08, 0x8020, 0x847d, 0x96c0, 0x6469, 0x3b5b, 0x8000, 0x8473, 0x96c0, 0x65e9, 0x390a, 0x8200, 0x8099 }, 16, 0x000bb3a0, 1},
+ {{0x6569, 0x94c0, 0x9f51, 0x9a51, 0x94c2, 0x0914, 0xa200, 0x94c2, 0x4493, 0xef68, 0x94c2, 0x5217, 0xea66, 0x92c2, 0x4212, 0x5393 }, 16, 0x000bb3c0, 1},
+ {{0x370d, 0x8100, 0x66e9, 0x90c0, 0x96c3, 0xe96a, 0x0913, 0xa080, 0x94c7, 0xede9, 0x4393, 0x94c7, 0xed66, 0x5710, 0x94c7, 0x845b }, 16, 0x000bb3e0, 1},
+ {{0x4711, 0x2e10, 0x1015, 0xe96a, 0x3861, 0xd420, 0x94c0, 0x4015, 0x804b, 0x4415, 0x5793, 0x0917, 0xa180, 0x4793, 0x1610, 0x30a4 }, 16, 0x000bb400, 1},
+ {{0x3456, 0x800b, 0x4611, 0x98c0, 0x32f8, 0x3fff, 0xbf7f, 0xe96a, 0xdd04, 0x4293, 0x5311, 0x39e1, 0xd5a0, 0x94c7, 0x4311, 0x6f10 }, 16, 0x000bb420, 1},
+ {{0x98c3, 0x4611, 0x33f8, 0x3fff, 0xbcff, 0x92c3, 0x5293, 0x92c3, 0xdd82, 0x92c3, 0x4393, 0x1693, 0xeb4a, 0x96c0, 0x3d0d, 0x8100 }, 16, 0x000bb440, 1},
+ {{0x5613, 0x96c0, 0x66e9, 0x3d1f, 0x8001, 0x96c0, 0x3d1e, 0x801f, 0x8035, 0x27e9, 0x77c6, 0x94c0, 0xd49f, 0x8029, 0x3551, 0x24e8 }, 16, 0x000bb460, 1},
+ {{0x64e6, 0x2566, 0x7ceb, 0x9ac0, 0x351a, 0x87ff, 0x90c0, 0x3e11, 0x85a9, 0x3e12, 0x85a9, 0x7d6b, 0x6cd8, 0x92c3, 0x64e4, 0x3c40 }, 16, 0x000bb480, 1},
+ {{0xb200, 0x7471, 0x77d1, 0x7750, 0xefe8, 0x9f71, 0x90c0, 0x90c0, 0x98c0, 0x38c0, 0x368c, 0x8009, 0x9f71, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000bb4a0, 1},
+ {{0x94c0, 0x9220, 0x9320, 0x9420, 0x6d6c, 0x75fa, 0x6d70, 0x6d60, 0xda12, 0x6661, 0x6d74, 0x6ccc, 0x7452, 0x64e0, 0x9421, 0x94c0 }, 16, 0x000bb4c0, 1},
+ {{0x9221, 0x9321, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x9530, 0x1005, 0xa004, 0x90c0, 0x90c0, 0x9220, 0x7550, 0xd0a1 }, 16, 0x000bb4e0, 1},
+ {{0x8029, 0x34f1, 0x9fff, 0x8021, 0x9750, 0xd891, 0x6466, 0x6c50, 0x1005, 0xa001, 0x90c0, 0x90c0, 0x92c8, 0x7051, 0x7470, 0xdd11 }, 16, 0x000bb500, 1},
+ {{0x656a, 0x2518, 0x8006, 0x6464, 0x9221, 0x9531, 0x90c0, 0x90c0, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000bb520, 1},
+ {{0x9530, 0x1005, 0xa004, 0x90c0, 0x90c0, 0x9220, 0x7478, 0x74f9, 0x3260, 0x3fff, 0x8000, 0xd0a1, 0x2518, 0x8026, 0x70fa, 0x2518 }, 16, 0x000bb540, 1},
+ {{0x8014, 0x9750, 0x6c50, 0xd891, 0x92c8, 0x7051, 0x7470, 0x2118, 0x8010, 0x7061, 0x92c3, 0x7079, 0x6c10, 0x92c2, 0x7841, 0x9221 }, 16, 0x000bb560, 1},
+ {{0x9531, 0x90c0, 0x90c0, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x9750, 0x1005, 0xa001, 0xd810, 0xd891, 0x92c8, 0x7051, 0x7470 }, 16, 0x000bb580, 1},
+ {{0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x9530, 0x1005, 0xa004, 0x90c0, 0x90c0, 0x94c0, 0x9220, 0x9320 }, 16, 0x000bb5a0, 1},
+ {{0x7550, 0xd991, 0x9750, 0x6466, 0x64e6, 0x1005, 0xa001, 0x90c0, 0x90c0, 0x92c8, 0x7053, 0xd818, 0x6468, 0x92c3, 0x6c51, 0x6568 }, 16, 0x000bb5c0, 1},
+ {{0x92c3, 0x6464, 0x94c0, 0x9221, 0x9321, 0x9531, 0x90c0, 0x90c0, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000bb5e0, 1},
+ {{0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000bb600, 1},
+ {{0xfffe, 0x000a, 0x000c, 0xfff6, 0xffff, 0xfffd, 0x0010, 0xfff0, 0x000c, 0x000a, 0xfff4, 0xffff, 0x0005, 0x0026, 0xfff4, 0x0031 }, 16, 0x000bf000, 1},
+ {{0xffa8, 0x004e, 0xff6a, 0x0113, 0xfe58, 0x0273, 0xfc44, 0x069d, 0xf4da, 0x199b, 0x2e6c, 0x995b, 0x1e2a, 0xdac1, 0x27d5, 0xe6c7 }, 16, 0x000bf020, 1},
+ {{0x2576, 0xe6e1, 0x1083, 0x05b4, 0x0797, 0x0789, 0xfe41, 0xf10c, 0x0325, 0xfc82, 0x0094, 0xfeed, 0x062a, 0xfbbd, 0x0926, 0xf621 }, 16, 0x000bf040, 1},
+ {{0xfff5, 0xf8c4, 0x0190, 0xfb4e, 0xfee9, 0xf9d1, 0x0005, 0xff24, 0x0788, 0x035d, 0x07c8, 0x039c, 0x03ee, 0xfe80, 0x009a, 0xfc47 }, 16, 0x000bf060, 1},
+ {{0xfff6, 0xfde7, 0xff09, 0xfbcc, 0xff37, 0xff13, 0x01e1, 0x0209, 0x01c4, 0xfd68, 0x0044, 0xfe82, 0x0042, 0xfe7d, 0xfebb, 0xfe5e }, 16, 0x000bf080, 1},
+ {{0x01e0, 0x0169, 0x02c1, 0x0013, 0xff5b, 0x0097, 0x01bf, 0x015e, 0xff3e, 0xfd80, 0xfe46, 0xff38, 0x00ab, 0x00b7, 0x0018, 0xff39 }, 16, 0x000bf0a0, 1},
+ {{0x006c, 0x0066, 0x0147, 0x0040, 0xff6a, 0xff6f, 0xffd5, 0x005c, 0xfff8, 0xff7e, 0xff44, 0x000c, 0x0018, 0x004f, 0xffd9, 0xff7c }, 16, 0x000bf0c0, 1},
+ {{0xff81, 0xffae, 0x0039, 0xffab, 0xffa4, 0xff8f, 0x000b, 0x0051, 0x00ab, 0x007d, 0xffd6, 0x0033, 0x0030, 0x00be, 0x0035, 0xffe2 }, 16, 0x000bf0e0, 1},
+ {{0xff46, 0xffa2, 0xffc7, 0xffd9, 0xffd5, 0xff3f, 0xff1d, 0xff3c, 0xffd1, 0xffc1, 0x0006, 0xffd7, 0xfff8, 0xffe6, 0x0002, 0x0026 }, 16, 0x000bf100, 1},
+ {{0x0007, 0x004d, 0x0054, 0x006d, 0x0025, 0xfffe, 0xffe8, 0xfff9, 0xffe1, 0xffb4, 0xffa0, 0xff82, 0xff7b, 0xff88, 0xff97, 0xffbd }, 16, 0x000bf120, 1},
+ {{0xffc4, 0xffb7, 0xff74, 0xffcd, 0xffd1, 0x0003, 0xffee, 0xfffb, 0xfff3, 0xffed, 0x000f, 0x0047, 0x0056, 0x002e, 0x0028, 0xffe4 }, 16, 0x000bf140, 1},
+ {{0xffa6, 0xff9e, 0xff9c, 0xff91, 0xff88, 0xff7f, 0xffad, 0xffbe, 0xffcd, 0xffdf, 0xffcf, 0xffa6, 0xffad, 0xffe2, 0x0004, 0xfffb }, 16, 0x000bf160, 1},
+ {{0xfff1, 0xffed, 0xfffb, 0x0011, 0x0016, 0xfff0, 0xffe4, 0xffb2, 0xffba, 0xffc8, 0xffc8, 0xffc8, 0xffc9, 0xffa3, 0xffbe, 0xffc2 }, 16, 0x000bf180, 1},
+ {{0xffd4, 0xffe5, 0xffe3, 0xffcb, 0xffde, 0xffe4, 0xffef, 0x0002, 0x0005, 0xffde, 0xfff5, 0xfff4, 0xfff9, 0xffde, 0xffb7, 0xffce }, 16, 0x000bf1a0, 1},
+ {{0xffb7, 0xffec, 0xffeb, 0xffd4, 0xffcf, 0xffcf, 0xffbd, 0xffd1, 0xffdf, 0xffcc, 0xffed, 0xfff2, 0xfff1, 0x000d, 0x001d, 0x0015 }, 16, 0x000bf1c0, 1},
+ {{0xffe7, 0x000f, 0xffee, 0xffe1, 0xfff2, 0xffdb, 0xffd6, 0xffce, 0xffdb, 0xffd7, 0xffe5, 0xffdc, 0xffc2, 0xffc8, 0xffcd, 0x0026 }, 16, 0x000bf1e0, 1},
+ {{0x0073, 0xffba, 0xfff2, 0xffe6, 0x000c, 0xfff6, 0xffda, 0xfff8, 0xffce, 0xffdc, 0x0000, 0x0032, 0xffe0, 0x001e, 0xffd6, 0x002f }, 16, 0x000bf200, 1},
+ {{0x005c, 0xffee, 0x000e, 0x0033, 0xffa6, 0xffd6, 0x00df, 0x0013, 0x003c, 0xff5e, 0xfa90, 0x043f, 0xfdb3, 0x0574, 0xfd1e, 0x02f5 }, 16, 0x000bf220, 1},
+ {{0xfea4, 0x0322, 0xffcc, 0xfdca, 0x00a2, 0xfb86, 0x0116, 0xfdde, 0x009c, 0xff8b, 0x0147, 0xffe6, 0x0093, 0x009f, 0xff83, 0x01a7 }, 16, 0x000bf240, 1},
+ {{0xff8c, 0x0065, 0xff4e, 0xffd9, 0x00dd, 0x009e, 0x00ef, 0x000b, 0xffda, 0xffd1, 0xff7c, 0xff37, 0xff70, 0xfed0, 0xfef6, 0xffb6 }, 16, 0x000bf260, 1},
+ {{0xffca, 0x009b, 0x0073, 0x00e0, 0x00d8, 0x004a, 0x0099, 0xffee, 0x0005, 0xffe8, 0xffcb, 0xffea, 0xffea, 0x000c, 0x0002, 0x0059 }, 16, 0x000bf280, 1},
+ {{0xffbb, 0xfff4, 0xff94, 0x0004, 0xffee, 0xffe0, 0xffbb, 0xff90, 0xffeb, 0x0063, 0x003c, 0xffe5, 0x004c, 0x0008, 0x004e, 0x0079 }, 16, 0x000bf2a0, 1},
+ {{0xffb8, 0x0025, 0xff9a, 0xffd7, 0x0020, 0xff70, 0x004f, 0xff88, 0x004c, 0x000c, 0xfff6, 0x0038, 0xffa4, 0x002c, 0x0021, 0x0038 }, 16, 0x000bf2c0, 1},
+ {{0x0004, 0xfff4, 0x0000, 0x003e, 0x0055, 0x0031, 0xffdf, 0xffdf, 0xffd3, 0xfffd, 0xff97, 0xfffc, 0xff60, 0xffeb, 0xffa2, 0xfffd }, 16, 0x000bf2e0, 1},
+ {{0x0039, 0xffd6, 0x0055, 0xffcb, 0x008b, 0x002a, 0x0039, 0x002b, 0x0053, 0xffeb, 0x0046, 0xffd6, 0x0077, 0xfffb, 0xff8b, 0x0058 }, 16, 0x000bf300, 1},
+ {{0xff3c, 0x0063, 0xff0e, 0x005a, 0xff81, 0x0001, 0xff84, 0xfff8, 0x005a, 0xffd6, 0x001c, 0xffe7, 0x007c, 0xffcc, 0x0078, 0xfff2 }, 16, 0x000bf320, 1},
+ {{0x0066, 0xffd6, 0x005f, 0xfff3, 0xff9d, 0xffff, 0x007f, 0xfff5, 0xffca, 0xffff, 0xffc2, 0x0047, 0xff5c, 0x003a, 0xffc3, 0x000f }, 16, 0x000bf340, 1},
+ {{0xff94, 0xfffe, 0x0032, 0xfff6, 0x000d, 0x0005, 0xffcc, 0x000d, 0x0087, 0xfff8, 0xfffd, 0xffed, 0x0025, 0xffda, 0x0069, 0xffdc }, 16, 0x000bf360, 1},
+ {{0xffdc, 0x0024, 0xffc4, 0x0007, 0x0009, 0xfffc, 0xfff7, 0x002d, 0xff7a, 0x0029, 0x0002, 0x0012, 0xffec, 0xfffc, 0xfff8, 0xffd9 }, 16, 0x000bf380, 1},
+ {{0x0063, 0xffd6, 0x0017, 0xffec, 0x0056, 0xffe5, 0x0007, 0x0003, 0xffca, 0x002e, 0xffc0, 0x0007, 0xffb5, 0xffff, 0x0037, 0xffc9 }, 16, 0x000bf3a0, 1},
+ {{0x0062, 0xffe8, 0x003c, 0x0016, 0xffcb, 0x0025, 0xffce, 0x003c, 0xffb0, 0x001b, 0xffce, 0x000b, 0x008b, 0xffdb, 0xfff1, 0xfff7 }, 16, 0x000bf3c0, 1},
+ {{0xffdc, 0x0038, 0xffbf, 0xfff4, 0xffdc, 0xfff0, 0x0029, 0xffdc, 0x0099, 0xffd7, 0x0076, 0xffcf, 0x0041, 0xffea, 0x000a, 0xffc7 }, 16, 0x000bf3e0, 1},
+ {{0xff46, 0x0045, 0xffe7, 0xffea, 0x004c, 0xfffb, 0x000e, 0x006e, 0x003d, 0x0080, 0xfed2, 0x0057, 0xff3d, 0x0097, 0xffb4, 0x0062 }, 16, 0x000bf400, 1},
+ {{0xff8e, 0x00d5, 0xff34, 0x0074, 0x019a, 0xfed4, 0x00e9, 0x003a, 0xfe16, 0xfe86, 0xfdf9, 0xfb2a, 0x0b7f, 0x00f9, 0xfe1d, 0x00c9 }, 16, 0x000bf420, 1},
+ {{0xfbc0, 0x07e8, 0xfe7e, 0xfe95, 0x0067, 0xf66c, 0x002c, 0xfdbd, 0x00df, 0x026f, 0x00ed, 0x01d1, 0xffa3, 0x02b6, 0xfff2, 0x01a5 }, 16, 0x000bf440, 1},
+ {{0x00f8, 0xfed9, 0xffde, 0x001b, 0x01cb, 0x00a7, 0x0045, 0xfe90, 0xfed2, 0xff58, 0xfefe, 0xff27, 0xfdb9, 0xfecd, 0xfde5, 0xffb0 }, 16, 0x000bf460, 1},
+ {{0x0115, 0x00c4, 0x01e0, 0x01bd, 0x012d, 0x00aa, 0x00ca, 0x00f3, 0x0038, 0xffaf, 0xff4a, 0xff07, 0xff4b, 0xffec, 0x00b3, 0xffbb }, 16, 0x000bf480, 1},
+ {{0xffe4, 0xffe9, 0xffbd, 0xfffc, 0xff74, 0xffaa, 0xff2e, 0xff63, 0x0008, 0x018d, 0xff5e, 0x00f6, 0x0042, 0x0055, 0x0013, 0x00da }, 16, 0x000bf4a0, 1},
+ {{0xff8f, 0xffe0, 0xffe7, 0xff78, 0x002e, 0xff66, 0x002f, 0xffa8, 0xffd2, 0x00b1, 0xffa8, 0x0051, 0xffe4, 0x0048, 0x000c, 0xffe6 }, 16, 0x000bf4c0, 1},
+ {{0x0002, 0xffd1, 0x009e, 0xffee, 0x0028, 0xffba, 0xffd7, 0x0052, 0xfff4, 0xff78, 0x001e, 0xff7a, 0x004a, 0xff12, 0x006d, 0x004e }, 16, 0x000bf4e0, 1},
+ {{0x005b, 0xffc9, 0xffd0, 0x0042, 0x0006, 0x008a, 0x0032, 0xffd3, 0x000e, 0x0075, 0x006e, 0xffd3, 0xffd1, 0xffc8, 0x0037, 0xffc6 }, 16, 0x000bf500, 1},
+ {{0x005a, 0xfec9, 0x0036, 0xff04, 0x007e, 0x0028, 0x0033, 0x0002, 0xff7f, 0x00e5, 0xff98, 0x0087, 0xffd8, 0x0029, 0x0012, 0xffa2 }, 16, 0x000bf520, 1},
+ {{0xff70, 0x017e, 0xff5c, 0x0048, 0x0041, 0xffc8, 0x0066, 0xff9a, 0x0038, 0xfec3, 0x0017, 0xff5e, 0xffe9, 0x0083, 0x0027, 0xffe6 }, 16, 0x000bf540, 1},
+ {{0x0006, 0x001b, 0x0006, 0x00c1, 0xff78, 0x0041, 0x0001, 0xffd0, 0x0000, 0x000e, 0x001a, 0x000e, 0x003a, 0x004e, 0xffc0, 0x0008 }, 16, 0x000bf560, 1},
+ {{0x005e, 0xfea4, 0x0074, 0xff9f, 0x0031, 0xff7d, 0xffee, 0x004e, 0x0007, 0x0066, 0xff59, 0x00ec, 0xffd3, 0x006c, 0xfff9, 0xff78 }, 16, 0x000bf580, 1},
+ {{0x0026, 0xffe3, 0x000f, 0x0062, 0x0000, 0xffc8, 0x002f, 0xffb0, 0x0058, 0xff81, 0xffb5, 0x003f, 0xffc3, 0x0029, 0xffed, 0x005f }, 16, 0x000bf5a0, 1},
+ {{0x000e, 0xffe0, 0xffc0, 0x0017, 0xffb2, 0x010c, 0xffac, 0x0076, 0xffb4, 0xffde, 0x006b, 0xff2e, 0x0063, 0xff8f, 0xffed, 0x005c }, 16, 0x000bf5c0, 1},
+ {{0xfffe, 0xff81, 0x0041, 0xff37, 0x008e, 0xffb3, 0xffd1, 0x011d, 0xffa2, 0xffed, 0xffd2, 0x0043, 0xffee, 0x00c2, 0xfff6, 0x0037 }, 16, 0x000bf5e0, 1},
+ {{0xffd9, 0x0082, 0x003e, 0x002c, 0xff99, 0x00a7, 0xfec8, 0x0174, 0xff13, 0xffa4, 0x0008, 0xff9e, 0x007a, 0xff92, 0x00d5, 0xffa8 }, 16, 0x000bf600, 1},
+ {{0x0156, 0xfefa, 0x0095, 0xffe3, 0x0030, 0xffcd, 0xff85, 0xff77, 0x002e, 0xfe46, 0xf637, 0x109f, 0xfadb, 0x05b4, 0xff8e, 0xfe8b }, 16, 0x000bf620, 1},
+ {{0xfff4, 0x01e7, 0xffac, 0xfc1a, 0xfdb6, 0xfcf7, 0xfe93, 0x0043, 0xff80, 0x0052, 0x01f5, 0xff5a, 0x00b0, 0x0269, 0x00d2, 0x0158 }, 16, 0x000bf640, 1},
+ {{0x0222, 0x010d, 0x0034, 0x00af, 0x01f2, 0x0076, 0xff77, 0xfe8f, 0xfe2d, 0xfdd8, 0xfeca, 0xfe0c, 0xfdb1, 0xfeec, 0xfda8, 0x00ce }, 16, 0x000bf660, 1},
+ {{0x0021, 0x010d, 0x022d, 0x0152, 0x0199, 0x01b7, 0x00d4, 0x00c1, 0x0089, 0xffff, 0x0049, 0xff76, 0xff54, 0x0070, 0xff28, 0x0068 }, 16, 0x000bf680, 1},
+ {{0xfe78, 0xff3a, 0x00dd, 0xfda3, 0x004d, 0xfecf, 0xffd2, 0x002c, 0xff3f, 0x0181, 0x0031, 0x013e, 0x002d, 0x00ca, 0xffd0, 0x00be }, 16, 0x000bf6a0, 1},
+ {{0xfec9, 0x01a9, 0xfeb7, 0x0022, 0xffc9, 0xff50, 0xffe4, 0xfff6, 0xffd1, 0x0031, 0xff21, 0x0038, 0x00b4, 0xff07, 0x013b, 0xfee8 }, 16, 0x000bf6c0, 1},
+ {{0x012a, 0xfffd, 0x003f, 0x00ac, 0xffa3, 0x0073, 0xffa6, 0xfffa, 0x0023, 0xff37, 0xfffd, 0xff92, 0xffcc, 0xff65, 0xfff7, 0x0000 }, 16, 0x000bf6e0, 1},
+ {{0x0034, 0xffac, 0x0038, 0xffa9, 0x006f, 0x00c4, 0x0053, 0xffc1, 0x005c, 0x0092, 0x0070, 0x009d, 0xff55, 0x00c6, 0xff76, 0xfff7 }, 16, 0x000bf700, 1},
+ {{0xfeed, 0x00b5, 0xfe16, 0x00c0, 0xfede, 0x00d9, 0xfed8, 0x00a0, 0xffb5, 0xfff4, 0x0091, 0xff30, 0x00f6, 0x0065, 0x001f, 0x0098 }, 16, 0x000bf720, 1},
+ {{0xff72, 0xff46, 0x010c, 0xff8d, 0x00a7, 0xff0e, 0x00a6, 0x00de, 0xfdaf, 0x0231, 0xfe17, 0x0149, 0xfecb, 0xffe9, 0x0033, 0xffc3 }, 16, 0x000bf740, 1},
+ {{0xffa3, 0xffe8, 0x0103, 0xfeea, 0x0153, 0xff00, 0x00bc, 0xff5b, 0x01a4, 0xfe5b, 0x0165, 0xfe61, 0x01de, 0xff3c, 0x0087, 0x0026 }, 16, 0x000bf760, 1},
+ {{0xff72, 0x009e, 0xfe76, 0x0182, 0xfe79, 0x00e1, 0xff48, 0xffc4, 0xffec, 0xfffb, 0xffe6, 0xffcc, 0x008f, 0x0057, 0xffa5, 0x0025 }, 16, 0x000bf780, 1},
+ {{0x00ca, 0xff2d, 0x0135, 0xff33, 0x00e3, 0x0036, 0xff95, 0x0057, 0xfee2, 0x00cd, 0xfe12, 0x01d4, 0xfe71, 0xfffe, 0x00d7, 0xff53 }, 16, 0x000bf7a0, 1},
+ {{0x0114, 0xffac, 0xff8d, 0x004e, 0xffa3, 0xff16, 0x01e4, 0xff24, 0x0082, 0xffb7, 0x0083, 0xff8b, 0x00e2, 0xffc8, 0xfec7, 0x017c }, 16, 0x000bf7c0, 1},
+ {{0xfe10, 0x011f, 0xfe2b, 0x0070, 0x00c0, 0xffbf, 0xff42, 0x01f5, 0xfeb9, 0xff95, 0x0195, 0xfe88, 0x02f9, 0xfe40, 0x0080, 0xffd0 }, 16, 0x000bf7e0, 1},
+ {{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x32c4, 0x20c0, 0x800a, 0xeee8, 0x32a4, 0x34b0, 0x800b, 0xefe8, 0x98c0, 0x09c6 }, 16, 0x000c3000, 1},
+ {{0x2100, 0x8009, 0xeae8, 0x96c0, 0xe8ee, 0x2f0b, 0x8080, 0x98c0, 0xca4e, 0x3244, 0x3eb0, 0x800a, 0x96c0, 0x5f93, 0x2909, 0x80a8 }, 16, 0x000c3020, 1},
+ {{0x96c0, 0x6c90, 0xee44, 0xca46, 0x4196, 0x98c0, 0x09c6, 0x2100, 0x8009, 0xe8ea, 0x32a4, 0x32d0, 0x800b, 0xe948, 0x94c0, 0x6f90 }, 16, 0x000c3040, 1},
+ {{0x9770, 0x3b80, 0x2462, 0x8009, 0x3980, 0x2460, 0x8009, 0x2b02, 0x8002, 0x90c0, 0x94c8, 0x4739, 0x473b, 0x94c0, 0xc683, 0x90c0 }, 16, 0x000c3060, 1},
+ {{0x3457, 0x0cc6, 0x2100, 0x8009, 0x3264, 0x3890, 0x800a, 0x2c09, 0x8038, 0x3457, 0x08c6, 0x2100, 0x8009, 0x3264, 0x3c90, 0x800a }, 16, 0x000c3080, 1},
+ {{0x2809, 0x8044, 0x3224, 0x3ef0, 0x800c, 0x7457, 0x3457, 0x0ec6, 0x2100, 0x8009, 0x3264, 0x3400, 0x800a, 0x2e09, 0x8030, 0x3457 }, 16, 0x000c30a0, 1},
+ {{0x0dc6, 0x2100, 0x8009, 0x3264, 0x2ee0, 0x800a, 0x2d09, 0x80dc, 0x3b61, 0x7bc1, 0x676a, 0x81ab, 0x3224, 0x3ef0, 0x800c, 0xc083 }, 16, 0x000c30c0, 1},
+ {{0x98c0, 0x0ac6, 0x2100, 0x8009, 0xc083, 0x3264, 0x3400, 0x800a, 0x2a09, 0x8028, 0x98c0, 0x0cc6, 0x38d0, 0x8008, 0xe8ef, 0x32c4 }, 16, 0x000c30e0, 1},
+ {{0x3c20, 0x800a, 0x2c09, 0x8200, 0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0 }, 16, 0x000c3100, 1},
+ {{0x94c0, 0x9620, 0x9720, 0x94c0, 0x9e20, 0x9f20, 0x96c0, 0xefe9, 0x270a, 0x80d8, 0xe7ea, 0x94c0, 0xfdfd, 0xfafe, 0x98c0, 0xf847 }, 16, 0x000c3120, 1},
+ {{0x32c4, 0x20c0, 0x800a, 0x1615, 0x5712, 0x96c0, 0x5c90, 0x280e, 0x8024, 0x3820, 0xa000, 0x5896, 0x2e0b, 0x805c, 0x3660, 0xa000 }, 16, 0x000c3140, 1},
+ {{0x5993, 0xf849, 0x32a4, 0x34b0, 0x800b, 0x3640, 0xa000, 0xfc48, 0xf94a, 0x98c0, 0x0d26, 0x3534, 0x8009, 0xfcc8, 0x98c0, 0x0bc6 }, 16, 0x000c3160, 1},
+ {{0x2100, 0x8009, 0xeae8, 0x94c0, 0xed41, 0xff41, 0x98c0, 0x0d22, 0x3534, 0x8009, 0xf9c7, 0x96c0, 0xfa4b, 0x2b0b, 0x80d4, 0x11db }, 16, 0x000c3180, 1},
+ {{0xe8ec, 0x54d3, 0xda94, 0x98c0, 0xde99, 0x3264, 0x2420, 0x800a, 0x4594, 0x94c0, 0xfcc8, 0xf9ff, 0xf94c, 0x3800, 0xa100, 0x5011 }, 16, 0x000c31a0, 1},
+ {{0x2c0e, 0x82be, 0x3264, 0x2120, 0x800a, 0x36c0, 0xa000, 0x5116, 0xfe4d, 0x3640, 0xa000, 0xfcc8, 0xfecd, 0x90c0, 0x3600, 0xa100 }, 16, 0x000c31c0, 1},
+ {{0x5194, 0x4016, 0x9ac0, 0x331c, 0x8002, 0x90c0, 0x331a, 0x8001, 0x6669, 0x2718, 0x8cca, 0x96c0, 0x6569, 0x330b, 0x8200, 0x8013 }, 16, 0x000c31e0, 1},
+ {{0x3364, 0x2480, 0x800a, 0x98c0, 0xfcc8, 0x3124, 0x3ebc, 0x800c, 0x3ca0, 0xa000, 0x6e10, 0x2502, 0x82ba, 0x65e9, 0xeaee, 0x9ac0 }, 16, 0x000c3200, 1},
+ {{0x2302, 0x8296, 0x90c0, 0x2718, 0x881c, 0x3820, 0xa000, 0xe8ee, 0x2b00, 0x828e, 0x3660, 0xa000, 0xe83b, 0xeeee, 0x9ac0, 0x2d00 }, 16, 0x000c3220, 1},
+ {{0x824c, 0x90c0, 0x2302, 0x8210, 0x3640, 0xa100, 0xee3b, 0xea3d, 0x3820, 0xa000, 0xebee, 0x2900, 0x827e, 0x96c0, 0xeb3d, 0x2f00 }, 16, 0x000c3240, 1},
+ {{0x8216, 0x96c0, 0xfb51, 0x2502, 0x8212, 0x3660, 0xa000, 0xedee, 0xebee, 0x9ac0, 0x2702, 0x8226, 0x90c0, 0x2402, 0x8222, 0x94c0 }, 16, 0x000c3260, 1},
+ {{0xeb39, 0xed3f, 0x3660, 0xa000, 0xe9ee, 0xefee, 0x36c0, 0xa000, 0x5192, 0xe93f, 0x3820, 0xa000, 0xef3c, 0x25a0, 0x9fdf, 0x38e0 }, 16, 0x000c3280, 1},
+ {{0xa100, 0xde81, 0xecee, 0xefee, 0x36e0, 0xa100, 0xec3b, 0xef3d, 0x3620, 0xa100, 0xfa52, 0x4592, 0x94c0, 0xf84e, 0xfe4f, 0x94c0 }, 16, 0x000c32a0, 1},
+ {{0xc383, 0xf850, 0x94c0, 0xfd53, 0xfb54, 0x36c0, 0xa000, 0xeae9, 0xfc55, 0x3420, 0xa000, 0xff56, 0x96c0, 0x7454, 0xf9d0, 0xf457 }, 16, 0x000c32c0, 1},
+ {{0x3264, 0x3240, 0x800a, 0x3640, 0xa000, 0xf358, 0xfa59, 0x94c0, 0xfcd6, 0xf8c8, 0x94c0, 0xf4d7, 0xf9d0, 0x4014, 0x5090, 0x310d }, 16, 0x000c32e0, 1},
+ {{0x8008, 0x66e9, 0x94c0, 0xfbd5, 0x8051, 0x9ac0, 0xd222, 0x32f8, 0x3fff, 0xbff7, 0xc5f7, 0x94c0, 0xdd00, 0x841b, 0x4290, 0x0dc6 }, 16, 0x000c3300, 1},
+ {{0x2100, 0x8009, 0x90c0, 0x2d0b, 0x80d6, 0x51d3, 0xde81, 0x4513, 0x3454, 0x0cc6, 0x2100, 0x8009, 0x3264, 0x2ee0, 0x800a, 0x2c09 }, 16, 0x000c3320, 1},
+ {{0x80dc, 0x3a20, 0xa000, 0xfad9, 0x3024, 0x33f8, 0x800c, 0x94c0, 0xf4d7, 0xf3d8, 0x90c0, 0x1113, 0x3264, 0x2140, 0x800a, 0xf15a }, 16, 0x000c3340, 1},
+ {{0x98c0, 0x6469, 0x6e90, 0xfbcf, 0xfcd5, 0x94c0, 0xf1da, 0xf4d7, 0x96c3, 0x5093, 0x22a0, 0x9fff, 0x3a47, 0xa000, 0x90c0, 0xfad9 }, 16, 0x000c3360, 1},
+ {{0x0900, 0xa020, 0x98c7, 0x7454, 0x4093, 0x90c0, 0xdd00, 0x92c3, 0x4293, 0x5214, 0x96c0, 0x7161, 0x2200, 0x8200, 0x94c0, 0xfdd4 }, 16, 0x000c3380, 1},
+ {{0x8037, 0x3680, 0xa000, 0x4592, 0xf8d3, 0x4597, 0x4595, 0x4290, 0x0bc6, 0x2100, 0x8009, 0x3264, 0x2ee0, 0x800a, 0x2b09, 0x80dc }, 16, 0x000c33a0, 1},
+ {{0x3a20, 0xa000, 0xfad9, 0x3024, 0x33f8, 0x800c, 0x94c0, 0xf4d7, 0xf3d8, 0x96c0, 0x7454, 0xf9d1, 0xfcd6, 0xfdcc, 0x1211, 0x5514 }, 16, 0x000c33c0, 1},
+ {{0x1115, 0xf502, 0x3264, 0x3160, 0x800a, 0xf201, 0x94c0, 0xf4d7, 0xf3d8, 0x3420, 0xa000, 0xfad9, 0x98c0, 0x79e1, 0x7a41, 0xf9d0 }, 16, 0x000c33e0, 1},
+ {{0xfbcf, 0x96c0, 0x65ea, 0xfdd5, 0xfcd6, 0x1111, 0xf9d1, 0x98c0, 0x3e51, 0x8020, 0x5293, 0xfbd2, 0x9ac0, 0x2d0d, 0x808c, 0xdc82 }, 16, 0x000c3400, 1},
+ {{0x2909, 0x808c, 0x1593, 0xf8d3, 0x98c0, 0xdc9d, 0xfbcf, 0x2c0c, 0x808c, 0x94c0, 0xfd55, 0xfdd4, 0x94c0, 0xf951, 0xf9d0, 0x94c0 }, 16, 0x000c3420, 1},
+ {{0xfc56, 0xfcd2, 0x9ac0, 0x2808, 0x808c, 0x90c0, 0x2d0d, 0x808c, 0x9ac0, 0x2b0b, 0x808c, 0x90c0, 0x2909, 0x808c, 0x96c0, 0xfb4f }, 16, 0x000c3440, 1},
+ {{0x2f0f, 0x808c, 0x3840, 0xa100, 0x4194, 0x2a0a, 0x808c, 0x96c0, 0xf950, 0x2cff, 0x9e6b, 0x94c0, 0xfd54, 0xf853, 0x3820, 0xa000 }, 16, 0x000c3460, 1},
+ {{0xfecd, 0x2402, 0x8052, 0x9ac0, 0x2f00, 0x804e, 0x90c0, 0x2d00, 0x8050, 0x38a0, 0xa000, 0xefee, 0x2900, 0x8044, 0x36e0, 0xa000 }, 16, 0x000c3480, 1},
+ {{0xef3c, 0xe8ee, 0x36c0, 0xa100, 0x5217, 0xefee, 0x3880, 0xa000, 0xef3f, 0x2302, 0x8134, 0x3640, 0xa000, 0xe83d, 0xefee, 0x3820 }, 16, 0x000c34a0, 1},
+ {{0xa000, 0xf9ca, 0x2d00, 0x824c, 0x36a0, 0xa000, 0xedee, 0xef39, 0x36e0, 0xa000, 0xed3b, 0xe9ee, 0x9ac0, 0x2402, 0x81c0, 0x90c0 }, 16, 0x000c34c0, 1},
+ {{0x2b00, 0x8040, 0x3600, 0xa100, 0xe93d, 0x4715, 0x3660, 0xa100, 0xedee, 0xedee, 0x1310, 0xed3b, 0x36e0, 0xa000, 0xed3c, 0xe8e9 }, 16, 0x000c34e0, 1},
+ {{0x0217, 0x4311, 0x3680, 0xa000, 0x4217, 0x4315, 0x36c0, 0xa000, 0x4615, 0xff5b, 0x32c4, 0x3dd0, 0x800a, 0xf95c, 0x3a40, 0xa000 }, 16, 0x000c3500, 1},
+ {{0x6d90, 0xfecd, 0x2502, 0x82b2, 0x9ac0, 0x2302, 0x8286, 0x90c0, 0x2402, 0x8276, 0x3660, 0xa000, 0xedee, 0xebee, 0x3820, 0xa000 }, 16, 0x000c3520, 1},
+ {{0xed3d, 0x2800, 0x822c, 0x3640, 0xa000, 0xfd5f, 0xeb3c, 0x3660, 0xa000, 0xedee, 0xfad2, 0x3660, 0xa100, 0xed3b, 0xecee, 0x3880 }, 16, 0x000c3540, 1},
+ {{0xa000, 0xec38, 0x2302, 0x8284, 0x3a00, 0xa100, 0x31f8, 0x3ffd, 0xbff7, 0x5292, 0x3840, 0xa000, 0xdc82, 0xe8ee, 0xfb60, 0x96c0 }, 16, 0x000c3560, 1},
+ {{0xf00c, 0x2b00, 0x8282, 0x94c0, 0xf05d, 0xc083, 0x38e0, 0xa004, 0x7450, 0xe83b, 0xedee, 0x3680, 0xa100, 0x4192, 0xed3b, 0x94c0 }, 16, 0x000c3580, 1},
+ {{0xfe5e, 0xfd61, 0xf862, 0x98c0, 0xf8df, 0x3d20, 0x3538, 0x8009, 0x94c0, 0xf9dc, 0xc28e, 0x1110, 0xf363, 0x3e40, 0xa000, 0x331d }, 16, 0x000c35a0, 1},
+ {{0x8003, 0x5011, 0x331c, 0x801c, 0xf064, 0x3a60, 0xa000, 0x7ec1, 0x7e62, 0xfc65, 0xfd66, 0x2ea8, 0xcb45, 0x90c0, 0xeb1d, 0x5213 }, 16, 0x000c35c0, 1},
+ {{0x2832, 0x3264, 0x2400, 0x800a, 0xd41d, 0x94c0, 0xf8e2, 0xf9dc, 0x3264, 0x2120, 0x800a, 0x1110, 0x4011, 0x3840, 0xa000, 0x7650 }, 16, 0x000c35e0, 1},
+ {{0xfde6, 0xfde1, 0xf8e2, 0x3600, 0xa100, 0x5015, 0x5115, 0x3264, 0x2120, 0x800a, 0x4410, 0x3a20, 0xa004, 0x7550, 0x6e90, 0xfce5 }, 16, 0x000c3600, 1},
+ {{0xfbe0, 0x3640, 0xa000, 0xf9de, 0xfde6, 0x3680, 0xa000, 0x5114, 0x5293, 0x1491, 0xf3e3, 0x3840, 0xa000, 0x7453, 0xc682, 0xf444 }, 16, 0x000c3620, 1},
+ {{0x36e0, 0xa000, 0x4215, 0xf645, 0x96c0, 0xf242, 0x057c, 0x9ff7, 0x3264, 0x3750, 0x800a, 0xf101, 0x98c0, 0xf3e3, 0x3224, 0x3f40 }, 16, 0x000c3640, 1},
+ {{0x800c, 0x7453, 0x94c0, 0xf9dc, 0xf8e2, 0x3640, 0xa000, 0xfde1, 0xfde6, 0x9ac0, 0x2808, 0x808c, 0x90c0, 0x2909, 0x808c, 0x94c0 }, 16, 0x000c3660, 1},
+ {{0xf862, 0xf8e0, 0x3620, 0xa000, 0xf0e4, 0xf95c, 0x3820, 0xa004, 0x7861, 0xf9de, 0xfce5, 0x3c00, 0xa001, 0x2d0d, 0x808c, 0x646a }, 16, 0x000c3680, 1},
+ {{0x2808, 0x808c, 0x96c0, 0xf3e3, 0x2909, 0x808c, 0x3aa0, 0xa000, 0x79c1, 0xfd61, 0x2c0c, 0x808c, 0x96c0, 0xf95e, 0x2cff, 0x9eef }, 16, 0x000c36a0, 1},
+ {{0x3840, 0xa100, 0xf860, 0x2d0d, 0x808c, 0x3640, 0xa000, 0xfcc8, 0xfecd, 0x3820, 0xa000, 0xffdb, 0x2900, 0x82ac, 0x3640, 0xa000 }, 16, 0x000c36c0, 1},
+ {{0x5394, 0xe8ee, 0x3c20, 0xa000, 0x3718, 0x8200, 0xebee, 0x2d00, 0x8056, 0x3880, 0xa000, 0x6469, 0xe839, 0x5117, 0x94c0, 0x5010 }, 16, 0x000c36e0, 1},
+ {{0x8427, 0x96c0, 0x3118, 0x80ff, 0xeb3d, 0x3264, 0x2350, 0x800a, 0xfb41, 0x3660, 0xa000, 0xffdb, 0xfecd, 0x90c0, 0x3480, 0xa000 }, 16, 0x000c3700, 1},
+ {{0x4017, 0x96c0, 0xc9b2, 0x2d00, 0x82b6, 0x3660, 0xa000, 0xebee, 0xe8ee, 0x94c0, 0xeb3d, 0xe839, 0x3680, 0xa000, 0x5317, 0x5490 }, 16, 0x000c3720, 1},
+ {{0x1293, 0xc582, 0x94c0, 0xc181, 0xf545, 0x96c0, 0xf244, 0x017c, 0x9ff7, 0x94c0, 0xf442, 0xf301, 0x94c0, 0xe9eb, 0xc083, 0x3264 }, 16, 0x000c3740, 1},
+ {{0x3750, 0x800a, 0xfb67, 0x3640, 0xa000, 0xfbe7, 0xfad2, 0x3660, 0xa000, 0xfecd, 0xffdb, 0x3600, 0xa100, 0x5393, 0x5592, 0x3a60 }, 16, 0x000c3760, 1},
+ {{0xa000, 0x3708, 0x8004, 0xccb6, 0xedee, 0x9ac0, 0xdc1d, 0x6e90, 0xfcc8, 0x2900, 0x82a6, 0x36c0, 0xa000, 0x4092, 0xed3c, 0x36c0 }, 16, 0x000c3780, 1},
+ {{0xa000, 0x5317, 0xf8c9, 0x3640, 0xa000, 0x4315, 0xe8ee, 0x1194, 0xe839, 0x98c0, 0x331a, 0x8080, 0x5010, 0xfacb, 0x3e40, 0xa000 }, 16, 0x000c37a0, 1},
+ {{0x7640, 0x2809, 0x85b4, 0x6569, 0x2160, 0x9fff, 0x8015, 0x4410, 0x5217, 0x69a8, 0x7def, 0x0317, 0x3024, 0x38ac, 0x800c, 0x4511 }, 16, 0x000c37c0, 1},
+ {{0x96c0, 0x7c41, 0xf868, 0xf969, 0x3284, 0x2100, 0x800a, 0x7841, 0x3820, 0xa000, 0x74d0, 0xf8e8, 0xffdb, 0xc083, 0x4110, 0x3480 }, 16, 0x000c37e0, 1},
+ {{0xa000, 0x5417, 0x6a24, 0x3e6f, 0x3224, 0x3f40, 0x800c, 0x4417, 0x94c0, 0xfcc8, 0xf9e9, 0x1217, 0x3264, 0x20b0, 0x800a, 0x0211 }, 16, 0x000c3800, 1},
+ {{0xe8ec, 0x3820, 0xa000, 0xfecd, 0x2900, 0x8062, 0x3860, 0x22f4, 0x8009, 0x3660, 0xa100, 0xedee, 0xefee, 0x3600, 0xa100, 0xed39 }, 16, 0x000c3820, 1},
+ {{0xef66, 0x0015, 0x3244, 0x3310, 0x800b, 0x3480, 0xa000, 0x5117, 0x3620, 0xa000, 0xf9ca, 0xfcc8, 0x3640, 0xa000, 0xfacb, 0xfad2 }, 16, 0x000c3840, 1},
+ {{0x3680, 0xa000, 0x51d1, 0xfbe7, 0x3820, 0xa000, 0x331c, 0x8001, 0xc2ef, 0x2669, 0x09c6, 0x2100, 0x8009, 0x94c0, 0xf4dd, 0x8025 }, 16, 0x000c3860, 1},
+ {{0x4417, 0x5293, 0x3400, 0xa004, 0xdd02, 0x3420, 0xa000, 0x4293, 0x5194, 0x0901, 0xb000, 0x0194, 0x3124, 0x38ac, 0x800c, 0x2909 }, 16, 0x000c3880, 1},
+ {{0x80d4, 0x52d9, 0x55d1, 0xda95, 0xde9a, 0x4594, 0x3600, 0xa100, 0x5293, 0x5392, 0x96c0, 0x351c, 0x8010, 0xe8ea, 0x6669, 0x90c0 }, 16, 0x000c38a0, 1},
+ {{0x94c1, 0xc190, 0xc1ef, 0x94c1, 0xdc9b, 0xdc83, 0x3480, 0xa000, 0x4192, 0x5517, 0x7ec8, 0x66e5, 0x7ec8, 0x36dd, 0x32a4, 0x3360 }, 16, 0x000c38c0, 1},
+ {{0x800b, 0xd89d, 0x3a60, 0xa000, 0x7c48, 0x6e10, 0xfecd, 0xfad2, 0x3e00, 0xa002, 0x6465, 0x2702, 0x8042, 0x7654, 0x2800, 0x8212 }, 16, 0x000c38e0, 1},
+ {{0x3860, 0xa000, 0x7c48, 0xeaee, 0xedee, 0x3c40, 0xa000, 0x7458, 0xea3f, 0x3298, 0x23df, 0xbfcd, 0x96c0, 0x4052, 0x2702, 0x822a }, 16, 0x000c3900, 1},
+ {{0x0057, 0xed38, 0x36c0, 0xa000, 0x5592, 0xe9ee, 0x3820, 0xa000, 0xdd05, 0xc383, 0xe93f, 0x3680, 0xa000, 0x4292, 0xfe6a, 0x98c0 }, 16, 0x000c3920, 1},
+ {{0x3422, 0x3554, 0x8009, 0xff6b, 0x96c0, 0xfd6c, 0x90c0, 0x90c0, 0x3800, 0xa800, 0x74d4, 0xfaec, 0xfdcc, 0x94c0, 0xf8c8, 0xf36d }, 16, 0x000c3940, 1},
+ {{0x3640, 0xa000, 0x5012, 0xfc6e, 0x0011, 0xf96f, 0x3600, 0xa100, 0x5515, 0xcf44, 0x3264, 0x2870, 0x800a, 0xf501, 0x3600, 0xa100 }, 16, 0x000c3960, 1},
+ {{0xfeeb, 0xcf4c, 0x3a00, 0xa800, 0x7454, 0x3264, 0x3d70, 0x800a, 0x5116, 0x3620, 0xa000, 0xfcee, 0xf8ce, 0x3264, 0x22a0, 0x800a }, 16, 0x000c3980, 1},
+ {{0x3480, 0xa000, 0x4014, 0x3264, 0x21c0, 0x800a, 0xf8ce, 0x98c0, 0xf8ce, 0x3460, 0x3c20, 0x8032, 0x3680, 0xa000, 0xcf4c, 0xffd2 }, 16, 0x000c39a0, 1},
+ {{0x3800, 0xa004, 0x7a41, 0x5010, 0xf8ea, 0x9cc0, 0x3485, 0x8000, 0xfaec, 0x3682, 0x8000, 0xf3ed, 0x9cc0, 0x79e1, 0x3085, 0x8000 }, 16, 0x000c39c0, 1},
+ {{0x5190, 0x2808, 0x808c, 0x98c0, 0xda15, 0x65ea, 0xf86a, 0xf8ce, 0x3820, 0xa000, 0xd642, 0xf9ef, 0xfcee, 0x3a40, 0xa000, 0xde01 }, 16, 0x000c39e0, 1},
+ {{0x5397, 0x2a0a, 0x808c, 0x3a00, 0xa200, 0x2808, 0x808c, 0xde1b, 0xecef, 0x0494, 0xf84e, 0x96c0, 0x813a, 0x2909, 0x808c, 0x3680 }, 16, 0x000c3a00, 1},
+ {{0xa000, 0xec54, 0xfa6c, 0x3a40, 0xa000, 0x3938, 0x8000, 0xfbe7, 0xfecd, 0x90c0, 0x5193, 0xdc19, 0x4093, 0x3a40, 0xa000, 0x2a00 }, 16, 0x000c3a20, 1},
+ {{0x82ba, 0x6e90, 0xebee, 0x38a0, 0xa000, 0xeaee, 0x2e00, 0x8296, 0x98c0, 0xeb3a, 0x34f8, 0x3fbf, 0xb7bf, 0x96c0, 0x5093, 0x2702 }, 16, 0x000c3a40, 1},
+ {{0x828a, 0x9ac0, 0x2900, 0x828e, 0xde00, 0x2800, 0x8286, 0x3a80, 0xa000, 0xea3e, 0x3180, 0x2000, 0x8001, 0x3860, 0xa000, 0xdc9c }, 16, 0x000c3a60, 1},
+ {{0xeeee, 0xeaee, 0x3620, 0xa000, 0xefee, 0x4193, 0x3620, 0xa000, 0xedea, 0xef39, 0x3640, 0xa000, 0xc483, 0xee3f, 0x3640, 0xa000 }, 16, 0x000c3a80, 1},
+ {{0xea38, 0xfa70, 0x3455, 0x1216, 0xfb71, 0x0212, 0xf572, 0x94c0, 0xf473, 0xfd74, 0x3264, 0x3910, 0x800a, 0xfa75, 0x94c0, 0xfdf4 }, 16, 0x000c3aa0, 1},
+ {{0xfbf1, 0x94c0, 0xf5f2, 0xf4f3, 0x1315, 0xfaf5, 0x25e9, 0x1397, 0x3000, 0x2040, 0x8840, 0x94c0, 0xdc03, 0x801b, 0x1393, 0x3278 }, 16, 0x000c3ac0, 1},
+ {{0x3fff, 0xbffe, 0xdc1b, 0x4093, 0x5197, 0xdd19, 0xdd00, 0x4293, 0x9ac0, 0x7a61, 0x7ac1, 0xf8c8, 0x2f0f, 0x808c, 0x2d0d, 0x808c }, 16, 0x000c3ae0, 1},
+ {{0x5090, 0x3108, 0x8400, 0x6469, 0x90c0, 0x98c6, 0x2e0e, 0x808c, 0x90c0, 0x5116, 0x94c6, 0x666a, 0x4112, 0x96c0, 0x818b, 0x2a0a }, 16, 0x000c3b00, 1},
+ {{0x808c, 0x3640, 0xa000, 0x5293, 0xfecd, 0x3c20, 0xa000, 0x359c, 0x8000, 0xfaf0, 0x2e00, 0x82b6, 0x3a40, 0xa000, 0x6669, 0xe9ee }, 16, 0x000c3b20, 1},
+ {{0x2a00, 0x8040, 0x96c0, 0xe93e, 0x2f00, 0x820a, 0x98c7, 0x5391, 0x3581, 0x2000, 0x8000, 0x98c1, 0xde9b, 0x3578, 0x3fff, 0xbfff }, 16, 0x000c3b40, 1},
+ {{0x3646, 0xa000, 0xde83, 0xeeee, 0x0591, 0xee3a, 0x3ac0, 0xa000, 0x5312, 0x0ac6, 0x38d0, 0x8008, 0x3820, 0xa000, 0xeaee, 0x2900 }, 16, 0x000c3b60, 1},
+ {{0x817e, 0x3680, 0xa000, 0xea48, 0xea3f, 0x36c0, 0xa000, 0x5112, 0xefee, 0x98c0, 0x331d, 0x8001, 0xef39, 0xece8, 0x3640, 0xa000 }, 16, 0x000c3b80, 1},
+ {{0x66e9, 0xf8c9, 0x3646, 0xa000, 0x6d10, 0x995e, 0x94c3, 0x2202, 0x8286, 0x90c0, 0x3423, 0xa000, 0xe93a, 0x92c3, 0x5211, 0x693d }, 16, 0x000c3ba0, 1},
+ {{0x0216, 0xda92, 0x26e1, 0x1312, 0x0ac6, 0x38d0, 0x8008, 0x90c0, 0xea48, 0x5112, 0x331c, 0x8002, 0x6669, 0x3646, 0xa100, 0x6d10 }, 16, 0x000c3bc0, 1},
+ {{0x9a5e, 0x94c3, 0x2a00, 0x81fa, 0x90c0, 0x3483, 0xa000, 0xea3a, 0x3483, 0xa000, 0x5212, 0x69bd, 0x7473, 0xd890, 0x6dc5, 0x4356 }, 16, 0x000c3be0, 1},
+ {{0x1117, 0x0ac6, 0x38d0, 0x8008, 0x3620, 0xa000, 0x280f, 0x85b6, 0xea48, 0x5212, 0x3518, 0x8004, 0x6469, 0x3646, 0xa100, 0x6e90 }, 16, 0x000c3c00, 1},
+ {{0x9a5e, 0x94c3, 0x2a00, 0x816e, 0x90c0, 0x3483, 0xa000, 0xea3a, 0x3483, 0xa000, 0x5512, 0x6a25, 0xd914, 0x6561, 0x6ddd, 0x4356 }, 16, 0x000c3c20, 1},
+ {{0x5294, 0x9ac0, 0x351d, 0x8020, 0x90c0, 0x350c, 0x8200, 0x66e9, 0x84c3, 0x3ca0, 0xa000, 0x6669, 0x2a00, 0x8050, 0x74d6, 0xeaee }, 16, 0x000c3c40, 1},
+ {{0x96c0, 0x8047, 0x2702, 0x8052, 0x36c0, 0xa000, 0xea3a, 0xe9ee, 0x3680, 0xa000, 0x5612, 0xeaef, 0x3640, 0xa000, 0x4617, 0xe93f }, 16, 0x000c3c60, 1},
+ {{0x1511, 0xea62, 0x0512, 0xf701, 0x32a4, 0x2c10, 0x800a, 0x3420, 0xa000, 0xe8e8, 0x98c0, 0xfbf1, 0x3024, 0x3cf2, 0x800c, 0x3640 }, 16, 0x000c3c80, 1},
+ {{0xa000, 0xfcc8, 0xfecd, 0x38a0, 0xa000, 0xeaee, 0x2a00, 0x8286, 0x9ac0, 0x2702, 0x816e, 0x90c0, 0x2900, 0x81fa, 0x36c0, 0xa000 }, 16, 0x000c3ca0, 1},
+ {{0xea3a, 0xedee, 0x36c0, 0xa000, 0x5712, 0xeaee, 0x3640, 0xa000, 0x4717, 0xea3f, 0x1012, 0xed39, 0x3620, 0xa000, 0xe8e8, 0xf001 }, 16, 0x000c3cc0, 1},
+ {{0x32a4, 0x2c10, 0x800a, 0x5115, 0x3640, 0xa000, 0xfcc8, 0xfecd, 0xfbf1, 0x90c0, 0x1194, 0xef42, 0x96c0, 0x331f, 0x8020, 0x5617 }, 16, 0x000c3ce0, 1},
+ {{0x67e9, 0x8411, 0x4616, 0x5394, 0x370e, 0x8200, 0x6769, 0x2718, 0x81ae, 0x5494, 0x391f, 0x8010, 0x96c0, 0x67e9, 0x390f, 0x8020 }, 16, 0x000c3d00, 1},
+ {{0x842d, 0x96c0, 0x67e9, 0x390a, 0x8040, 0x8423, 0x96c0, 0x6569, 0x391c, 0x8020, 0x8019, 0x2669, 0x5293, 0x96c0, 0x350c, 0x8001 }, 16, 0x000c3d20, 1},
+ {{0x8013, 0x6669, 0x92c3, 0x6e90, 0x92c3, 0x4516, 0x5694, 0x9ac0, 0x3d2d, 0x8000, 0x90c0, 0x3d0c, 0x8800, 0x66e9, 0x841d, 0x2669 }, 16, 0x000c3d40, 1},
+ {{0x5293, 0x96c0, 0x355b, 0x8000, 0x8027, 0x96c0, 0x65e9, 0x351e, 0x8020, 0x8417, 0x6769, 0x8413, 0x3244, 0x3dd0, 0x800a, 0xe8ec }, 16, 0x000c3d60, 1},
+ {{0x3420, 0xa000, 0xfecd, 0x90c0, 0x38a0, 0xa000, 0xeaee, 0x2a00, 0x82b2, 0x3860, 0x27e0, 0x8009, 0x3a80, 0xa000, 0xea3a, 0x3244 }, 16, 0x000c3d80, 1},
+ {{0x3390, 0x800b, 0x3480, 0xa000, 0x5112, 0x3640, 0xa000, 0xfcc8, 0xfecd, 0x3820, 0xa000, 0xf9ca, 0x2a00, 0x82a4, 0x3640, 0xa000 }, 16, 0x000c3da0, 1},
+ {{0x5194, 0xefee, 0x96c0, 0x331c, 0x8100, 0xef3a, 0x2669, 0x5017, 0x96c7, 0x7c41, 0x74c0, 0x8422, 0x94c7, 0x7841, 0x4117, 0x3284 }, 16, 0x000c3dc0, 1},
+ {{0x2100, 0x800a, 0x2160, 0x9fff, 0x3660, 0xa000, 0xf9ca, 0xfecd, 0x4017, 0x1117, 0x5516, 0x3640, 0xa000, 0x6a25, 0xeaee, 0x3e6f }, 16, 0x000c3de0, 1},
+ {{0xea62, 0x0416, 0xca4e, 0x3480, 0xa000, 0x57d1, 0x3f18, 0x8002, 0x6469, 0x90c0, 0x92c3, 0xf48c, 0x98c7, 0x3264, 0x2120, 0x800a }, 16, 0x000c3e00, 1},
+ {{0x4416, 0x1016, 0x5112, 0x3620, 0xa000, 0xfecd, 0xca46, 0x3420, 0xa000, 0xcab6, 0x36e0, 0xa000, 0xe8ee, 0xefee, 0x3640, 0xa100 }, 16, 0x000c3e20, 1},
+ {{0x4012, 0xe83a, 0x3600, 0xa100, 0xef64, 0x5010, 0x3264, 0x2120, 0x800a, 0x5117, 0x3820, 0xa000, 0xfecd, 0x2a00, 0x8216, 0x96c0 }, 16, 0x000c3e40, 1},
+ {{0x4017, 0x2102, 0x8226, 0x3620, 0xa000, 0xeeee, 0xc783, 0x98c0, 0x3f20, 0x355a, 0x8009, 0xee3a, 0x36a0, 0xa000, 0xee39, 0x90c0 }, 16, 0x000c3e60, 1},
+ {{0x3680, 0xa000, 0x5496, 0x5096, 0x3820, 0xa100, 0x6c7c, 0x5196, 0xfe4d, 0x3264, 0x33a0, 0x800a, 0x3454, 0x4496, 0x3840, 0xa000 }, 16, 0x000c3e80, 1},
+ {{0x7be1, 0xfecd, 0x4017, 0x27ea, 0xef54, 0x81d6, 0x3ca0, 0xa000, 0x2e0e, 0x808c, 0x90c0, 0x2e0e, 0x808c, 0xfcc8, 0x3264, 0x2760 }, 16, 0x000c3ea0, 1},
+ {{0x800a, 0xe8ec, 0x96c0, 0xfcc8, 0x16f8, 0x9f00, 0x94c0, 0xf9cc, 0xf641, 0x3264, 0x2440, 0x800a, 0xe8ec, 0x27ec, 0x9f28, 0xe7ec }, 16, 0x000c3ec0, 1},
+ {{0x94c0, 0x9e21, 0x9f21, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0, 0x98c0, 0x6c90, 0x7750, 0x9620, 0x9720, 0x98c0, 0x3721, 0x3694 }, 16, 0x000c3ee0, 1},
+ {{0x8009, 0xc49c, 0x2b80, 0xe748, 0x32e4, 0x3c8a, 0x8001, 0x94c0, 0xf441, 0xc847, 0x33c4, 0x20c0, 0x800a, 0x94c0, 0xd722, 0xcb47 }, 16, 0x000c3f00, 1},
+ {{0x90c0, 0x9ac7, 0x2b0a, 0x8018, 0x90c0, 0x2400, 0x9000, 0x94c7, 0x4892, 0x4493, 0xe768, 0x94c0, 0x9621, 0x9721, 0x9f71, 0x90c0 }, 16, 0x000c3f20, 1},
+ {{0x96c0, 0xd422, 0xcd57, 0xc79c, 0x3a20, 0xa000, 0x3421, 0x3694, 0x8009, 0xcc56, 0x3880, 0xa104, 0x6a03, 0xe9ef, 0xe8ee, 0x3a07 }, 16, 0x000c3f40, 1},
+ {{0xa100, 0x90c0, 0xc844, 0x3e10, 0x808c, 0x94c3, 0xcb40, 0xcc40, 0x9ac6, 0x280f, 0x8018, 0x90c0, 0x2602, 0x8268, 0x3620, 0xa000 }, 16, 0x000c3f60, 1},
+ {{0x5c97, 0xeaef, 0x1290, 0xea74, 0x3680, 0xa000, 0x5d94, 0x5392, 0x3c80, 0xa000, 0x6e3d, 0x30e0, 0x3fff, 0x8001, 0xeaef, 0x9cc1 }, 16, 0x000c3f80, 1},
+ {{0x6c7d, 0x2d0e, 0x8270, 0x6c7d, 0x2d0e, 0x8038, 0x3680, 0xa000, 0x9d5e, 0x9c56, 0x94c7, 0x9b56, 0xeb1e, 0x3a01, 0xa100, 0x90c0 }, 16, 0x000c3fa0, 1},
+ {{0xed68, 0x2900, 0x804e, 0x3823, 0xa000, 0xec1d, 0x2900, 0x8284, 0x3a26, 0xa000, 0xec3e, 0x3673, 0x9fef, 0xed50, 0x1115, 0x3018 }, 16, 0x000c3fc0, 1},
+ {{0x2001, 0xbffe, 0x3e06, 0xa100, 0x90c0, 0xea70, 0x90c0, 0x6c7c, 0x36cb, 0x9608, 0x3c00, 0xa104, 0x3462, 0x8001, 0x7e4e, 0x5712 }, 16, 0x000c3fe0, 1},
+ {{0xe91e, 0x3e00, 0xa004, 0x3062, 0x8001, 0x5513, 0x3660, 0x8001, 0x5611, 0x3a06, 0xa400, 0x7e68, 0x3617, 0x80ff, 0xd992, 0x9ac0 }, 16, 0x000c4000, 1},
+ {{0x66e6, 0xd5c0, 0x7bc1, 0xeeef, 0x802f, 0x3880, 0xa000, 0x7475, 0xef6c, 0x4712, 0x5597, 0x2c41, 0x35e8, 0x3fff, 0xbfff, 0x2468 }, 16, 0x000c4020, 1},
+ {{0x4097, 0x80b3, 0x0597, 0x3144, 0x20f4, 0x800c, 0x2d10, 0x0292, 0xee6c, 0x3620, 0xa000, 0x5590, 0x5796, 0x3a00, 0xa805, 0x3b07 }, 16, 0x000c4040, 1},
+ {{0x8001, 0x75d7, 0xef68, 0x3e20, 0xa00c, 0x7fc9, 0x7dc8, 0x5217, 0x35e0, 0x3000, 0x807f, 0x3a00, 0xa20d, 0x67e1, 0x65e1, 0x3500 }, 16, 0x000c4060, 1},
+ {{0x8003, 0x3820, 0xb848, 0x6cdb, 0x74f0, 0x4017, 0x3640, 0xa000, 0x7ce9, 0x5296, 0x3400, 0xa004, 0x7751, 0x3400, 0xa004, 0x7f49 }, 16, 0x000c4080, 1},
+ {{0x3400, 0xa804, 0x71f6, 0x3606, 0xa008, 0x7ccc, 0xd2d7, 0x3602, 0xa004, 0x7ec1, 0x64e1, 0x3402, 0xa004, 0x66e1, 0x3402, 0xa800 }, 16, 0x000c40a0, 1},
+ {{0x6cc5, 0x92c2, 0x7cec, 0x73f1, 0xd059, 0x92c3, 0x7c41, 0x3403, 0xa004, 0x6e51, 0x3403, 0xa040, 0x6cd7, 0x3607, 0xb008, 0x7ce2 }, 16, 0x000c40c0, 1},
+ {{0x7171, 0x6d7d, 0x3423, 0xa000, 0x4217, 0x4590, 0x3480, 0xa000, 0x4212, 0x4296, 0x98c0, 0x65e1, 0x5794, 0x2d0e, 0x824e, 0x7273 }, 16, 0x000c40e0, 1},
+ {{0x92c3, 0x6e10, 0x92c2, 0xc481, 0x6669, 0x90c0, 0x92c2, 0xc1ef, 0x94c6, 0x802a, 0xdc87, 0x92c2, 0x4194, 0x0907, 0xa010, 0x4794 }, 16, 0x000c4100, 1},
+ {{0x5216, 0x7d44, 0x3518, 0x87f0, 0x7370, 0x90c0, 0x94c3, 0x5794, 0xc1ef, 0x92c3, 0xdc87, 0x92c3, 0x4194, 0x94c0, 0xcd5f, 0xcc5e }, 16, 0x000c4120, 1},
+ {{0x9f70, 0x3660, 0xa000, 0xefe9, 0xeee8, 0x90c0, 0x90c0, 0x90c0, 0x98c0, 0x3421, 0x3694, 0x8009, 0xc39c, 0x6a13, 0x94c0, 0xc844 }, 16, 0x000c4140, 1},
+ {{0x9f71, }, 1, 0x000c4160, 1},
+ {{0xf947, 0x0000, 0x0009, 0xe140, 0x2cf9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0004, 0x0100, 0x5434, 0x0008, 0x4000 }, 16, 0x00080128, 1},
+ {{0x0101, 0xd520, 0x0009, 0xe100, 0x0100, 0x0800, 0x000b, 0xf000, 0x0100, 0x1162, 0x000c, 0x3000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080148, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080168, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x00080188, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000801a8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 16, 0x000801c8, 1},
+ {{0x0000, 0x0000, 0x0000, 0x0000, 0x0800, 0x9331, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, }, 12, 0x000801e8, 1},
+};
+const unsigned short zl_firmwareBlockSize = 16;
+const unsigned long programBaseAddress = 0x00080200;
+const unsigned long executionAddress = 0x0009e140;
+const unsigned char haveProgramBaseAddress = 1;
+const unsigned short firmwareStreamLen = 4704;
diff --git a/sound/soc/codecs/zl380tw_firmware.h b/sound/soc/codecs/zl380tw_firmware.h
new file mode 100644
index 00000000..ba6b1fc4
--- /dev/null
+++ b/sound/soc/codecs/zl380tw_firmware.h
@@ -0,0 +1,27 @@
+#ifndef __ZL380TW_FIRMWARE_H_
+#define __ZL380TW_FIRMWARE_H_
+
+#define ZL380XX_FWR_BLOCK_SIZE 16
+typedef struct {
+ unsigned short buf[ZL380XX_FWR_BLOCK_SIZE]; /*the firmware data block to send to the device*/
+ unsigned char numWords; /*the number of words within the block of data stored in buf[]*/
+ unsigned long targetAddr; /*the target base address to write to register 0x00c of the device*/
+ unsigned char useTargetAddr; /*this value is either 0 or 1. When 1 the tarGetAddr must be written to the device*/
+} twFwr;
+
+typedef struct {
+ twFwr *st_Fwr;
+ unsigned char havePrgmBase;
+ unsigned long prgmBase;
+ unsigned long execAddr; /*The execution start address of the firmware in RAM*/
+ unsigned short twFirmwareStreamLen; /*The number of blocks within the firmware*/
+ unsigned long byteCount; /*The total number of bytes within the firmware - NOT USED*/
+} twFirmware;
+
+extern const twFwr st_twFirmware[];
+extern const unsigned short firmwareStreamLen;
+extern const unsigned long programBaseAddress;
+extern const unsigned long executionAddress;
+extern const unsigned char haveProgramBaseAddress;
+extern const unsigned short zl_firmwareBlockSize;
+#endif
diff --git a/tools/lib/lk/Makefile b/tools/lib/lk/Makefile
index 926cbf3e..2c5a1973 100644
--- a/tools/lib/lk/Makefile
+++ b/tools/lib/lk/Makefile
@@ -1,5 +1,8 @@
include ../../scripts/Makefile.include
+CC = $(CROSS_COMPILE)gcc
+AR = $(CROSS_COMPILE)ar
+
# guard against environment variables
LIB_H=
LIB_OBJS=