Merge branch 'LA.UM.9.6.2.c25' into int/11/fp3
* LA.UM.9.6.2.c25:
disp: msm: sde: protect file private structure with mutex lock
msm: adsprpc: Allocate buffer taking NULL byte into consideration
msm: kgsl: Update register protection config
msm: adsprpc: null pointer check for fl
msm: kgsl: Fix out of bound write in adreno_profile_submit_time
msm: adsprpc: overflow vulnerability by race condition in adsprpc driver
disp: msm: sde: add null check for drm file in msm_release
msm: adsprpc: Handle UAF in process shell memory
msm: adsprpc: Fix race condition in internal_control
net:sockev: hold file reference till the sock event is sent
Change-Id: I365c83e64ccd60c3748e8413f03af884cc34f582
diff --git a/AndroidKernel.mk b/AndroidKernel.mk
index d48eecd..35726c3 100644
--- a/AndroidKernel.mk
+++ b/AndroidKernel.mk
@@ -26,7 +26,6 @@
ifeq ($(TARGET_KERNEL_HEADER_ARCH),)
KERNEL_HEADER_ARCH := $(KERNEL_ARCH)
else
-$(warning Forcing kernel header generation only for '$(TARGET_KERNEL_HEADER_ARCH)')
KERNEL_HEADER_ARCH := $(TARGET_KERNEL_HEADER_ARCH)
endif
@@ -42,13 +41,6 @@
endif
endif
-TARGET_KERNEL_CROSS_COMPILE_PREFIX := $(strip $(TARGET_KERNEL_CROSS_COMPILE_PREFIX))
-ifeq ($(TARGET_KERNEL_CROSS_COMPILE_PREFIX),)
-KERNEL_CROSS_COMPILE := arm-eabi-
-else
-KERNEL_CROSS_COMPILE := $(TARGET_KERNEL_CROSS_COMPILE_PREFIX)
-endif
-
ifeq ($(KERNEL_LLVM_SUPPORT), true)
ifeq ($(KERNEL_SD_LLVM_SUPPORT), true) #Using sd-llvm compiler
ifeq ($(shell echo $(SDCLANG_PATH) | head -c 1),/)
@@ -59,7 +51,6 @@
$(warning "Using sdllvm" $(KERNEL_LLVM_BIN))
else
KERNEL_LLVM_BIN := $(shell pwd)/$(CLANG) #Using aosp-llvm compiler
- $(warning "Using aosp-llvm" $(KERNEL_LLVM_BIN))
endif
endif
@@ -177,6 +168,14 @@
endif
endif
+TARGET_KERNEL_CLANG_PATH ?= $(BUILD_TOP)/prebuilts/clang/host/$(HOST_OS)-x86/$(KERNEL_CLANG_VERSION)
+PATH_OVERRIDE := PATH=$(TARGET_KERNEL_CLANG_PATH)/bin:$$PATH LD_LIBRARY_PATH=$(TARGET_KERNEL_CLANG_PATH)/lib64:$$LD_LIBRARY_PATH
+
+PATH_OVERRIDE += PATH=$(KERNEL_TOOLCHAIN_PATH_gcc)/bin:$$PATH
+
+# System tools are no longer allowed on 10+
+PATH_OVERRIDE += $(TOOLS_PATH_OVERRIDE)
+
ifneq ($(KERNEL_VM_DEFCONFIG),)
$(KERNEL_VM_OUT):
mkdir -p $(KERNEL_VM_OUT);
@@ -208,7 +207,7 @@
mkdir -p $(KERNEL_OUT)
$(KERNEL_CONFIG): $(KERNEL_OUT)
- $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_DEFCONFIG)
+ $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) $(KERNEL_DEFCONFIG)
$(hide) if [ ! -z "$(KERNEL_CONFIG_OVERRIDE)" ]; then \
echo "Overriding kernel config with '$(KERNEL_CONFIG_OVERRIDE)'"; \
echo $(KERNEL_CONFIG_OVERRIDE) >> $(KERNEL_OUT)/.config; \
@@ -219,16 +218,16 @@
$(TARGET_PREBUILT_INT_KERNEL_IMAGE): $(KERNEL_USR)
$(TARGET_PREBUILT_INT_KERNEL_IMAGE): $(KERNEL_OUT) $(KERNEL_HEADERS_INSTALL)
$(hide) echo "Building kernel modules..."
- $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_CFLAGS) Image
- $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_CFLAGS) modules
- $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) INSTALL_MOD_PATH=$(BUILD_ROOT_LOC)../$(KERNEL_MODULES_INSTALL) INSTALL_MOD_STRIP=1 $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) modules_install
+ $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) Image
+ $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) modules
+ $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) INSTALL_MOD_PATH=$(BUILD_ROOT_LOC)../$(KERNEL_MODULES_INSTALL) INSTALL_MOD_STRIP=1 $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) modules_install
$(mv-modules)
$(clean-module-folder)
$(TARGET_PREBUILT_INT_KERNEL): $(TARGET_PREBUILT_INT_KERNEL_IMAGE)
$(hide) echo "Building kernel..."
$(hide) rm -rf $(KERNEL_OUT)/arch/$(KERNEL_ARCH)/boot/dts
- $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_CFLAGS)
+ $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) $(KERNEL_CFLAGS)
else
TARGET_PREBUILT_INT_KERNEL_IMAGE := $(TARGET_PREBUILT_INT_KERNEL)
$(TARGET_PREBUILT_INT_KERNEL): $(KERNEL_OUT) $(KERNEL_HEADERS_INSTALL)
@@ -243,8 +242,8 @@
$(KERNEL_HEADERS_INSTALL): $(KERNEL_OUT)
$(hide) if [ ! -z "$(KERNEL_HEADER_DEFCONFIG)" ]; then \
rm -f $(BUILD_ROOT_LOC)$(KERNEL_CONFIG); \
- $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_HEADER_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_HEADER_DEFCONFIG); \
- $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_HEADER_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) headers_install;\
+ $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD)$(KERNEL_HEADER_DEFCONFIG); \
+ $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) headers_install;\
if [ -d "$(KERNEL_HEADERS_INSTALL)/include/bringup_headers" ]; then \
cp -Rf $(KERNEL_HEADERS_INSTALL)/include/bringup_headers/* $(KERNEL_HEADERS_INSTALL)/include/ ;\
fi ;\
@@ -252,22 +251,22 @@
$(hide) if [ "$(KERNEL_HEADER_DEFCONFIG)" != "$(KERNEL_DEFCONFIG)" ]; then \
echo "Used a different defconfig for header generation"; \
rm -f $(BUILD_ROOT_LOC)$(KERNEL_CONFIG); \
- $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_DEFCONFIG); fi
+ $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) $(KERNEL_DEFCONFIG); fi
$(hide) if [ ! -z "$(KERNEL_CONFIG_OVERRIDE)" ]; then \
echo "Overriding kernel config with '$(KERNEL_CONFIG_OVERRIDE)'"; \
echo $(KERNEL_CONFIG_OVERRIDE) >> $(KERNEL_OUT)/.config; \
- $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) oldconfig; fi
+ $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) oldconfig; fi
.PHONY: kerneltags
kerneltags: $(KERNEL_OUT) $(KERNEL_CONFIG)
- $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) tags
+ $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) tags
.PHONY: kernelconfig
kernelconfig: $(KERNEL_OUT) $(KERNEL_CONFIG)
env KCONFIG_NOTIMESTAMP=true \
- $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) menuconfig
+ $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) menuconfig
env KCONFIG_NOTIMESTAMP=true \
- $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) savedefconfig
+ $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) savedefconfig
cp $(KERNEL_OUT)/defconfig $(TARGET_KERNEL_SOURCE)/arch/$(KERNEL_ARCH)/configs/$(KERNEL_DEFCONFIG)
endif
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 12d9a68..54de8ff 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -912,12 +912,14 @@
icmp_msgs_per_sec - INTEGER
Limit maximal number of ICMP packets sent per second from this host.
Only messages whose type matches icmp_ratemask (see below) are
- controlled by this limit.
+ controlled by this limit. For security reasons, the precise count
+ of messages per second is randomized.
Default: 1000
icmp_msgs_burst - INTEGER
icmp_msgs_per_sec controls number of ICMP packets sent per second,
while icmp_msgs_burst controls the burst size of these packets.
+ For security reasons, the precise burst size is randomized.
Default: 50
icmp_ratemask - INTEGER
diff --git a/arch/arm64/boot/dts/qcom/dsi-hx83112b-djn-1080p-cmd.dtsi b/arch/arm64/boot/dts/qcom/dsi-hx83112b-djn-1080p-cmd.dtsi
new file mode 100755
index 0000000..54e4d6c
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/dsi-hx83112b-djn-1080p-cmd.dtsi
@@ -0,0 +1,154 @@
+/* Copyright (c) 2017, 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.
+ */
+
+&mdss_mdp {
+ dsi_djn_hx83112b_1080p_cmd: qcom,mdss_dsi_djn_hx83112b_1080p_cmd {
+ qcom,mdss-dsi-panel-name =
+ "djn hx83112b 1080p cmd mode dsi panel";
+ qcom,mdss-dsi-panel-type = "dsi_cmd_mode";
+ qcom,mdss-dsi-panel-framerate = <60>;
+ qcom,mdss-dsi-virtual-channel-id = <0>;
+ qcom,mdss-dsi-stream = <0>;
+ qcom,mdss-dsi-panel-width = <1080>;
+ qcom,mdss-dsi-panel-height = <2160>;
+ qcom,mdss-dsi-h-front-porch = <40>;
+ qcom,mdss-dsi-h-back-porch = <12>;
+ qcom,mdss-dsi-h-pulse-width = <4>;
+ qcom,mdss-dsi-h-sync-skew = <0>;
+ qcom,mdss-dsi-v-back-porch = <2>;
+ qcom,mdss-dsi-v-front-porch = <32>;
+ qcom,mdss-dsi-v-pulse-width = <2>;
+ qcom,mdss-dsi-h-left-border = <0>;
+ qcom,mdss-dsi-h-right-border = <0>;
+ qcom,mdss-dsi-v-top-border = <0>;
+ qcom,mdss-dsi-v-bottom-border = <0>;
+ qcom,mdss-dsi-bpp = <24>;
+ qcom,mdss-dsi-underflow-color = <0xff>;
+ qcom,mdss-dsi-border-color = <0>;
+ qcom,mdss-dsi-te-pin-select = <1>;
+ qcom,mdss-dsi-te-dcs-command = <1>;
+ qcom,mdss-dsi-te-check-enable;
+ qcom,mdss-dsi-te-using-te-pin;
+ qcom,mdss-tear-check-sync-init-val = <2160>;
+ qcom,mdss-tear-check-sync-threshold-start = <4>;
+ qcom,mdss-tear-check-sync-threshold-continue = <4>;
+ qcom,mdss-tear-check-start-pos = <2160>;
+ qcom,mdss-dsi-h-sync-pulse = <0>;
+ qcom,mdss-dsi-traffic-mode = "burst_mode";
+ qcom,mdss-dsi-bllp-eof-power-mode;
+ qcom,mdss-dsi-bllp-power-mode;
+ qcom,mdss-dsi-lane-0-state;
+ qcom,mdss-dsi-lane-1-state;
+ qcom,mdss-dsi-lane-2-state;
+ qcom,mdss-dsi-lane-3-state;
+ qcom,mdss-dsi-hsa-power-mode;
+ qcom,mdss-pan-physical-width-dimension=<65>;
+ qcom,mdss-pan-physical-height-dimension=<128>;
+ qcom,mdss-dsi-panel-timings = [e6 38 26 00 68 6e 2a
+ 3c 44 03 04 00];
+ qcom,mdss-dsi-t-clk-post = <0x0d>;
+ qcom,mdss-dsi-t-clk-pre = <0x2f>;
+ qcom,mdss-dsi-bl-min-level = <1>;
+ qcom,mdss-dsi-bl-max-level = <4095>;
+ qcom,mdss-dsi-dma-trigger = "trigger_sw";
+ qcom,mdss-dsi-mdp-trigger = "none";
+ qcom,mdss-dsi-on-command = [39 01 00 00 00 00 04 B9 83 11 2B
+ 39 01 00 00 00 00 02 BD 01
+ 39 01 00 00 00 00 03 C2 08 70
+ 39 01 00 00 00 00 02 BD 03
+ 39 01 00 00 00 00 05 B2 04 38 08 70
+ 39 01 00 00 00 00 02 BD 00
+ 39 01 00 00 00 00 0B B1 F8 27 27 00 00 0B 0E 0B 0E 33
+ 39 01 00 00 00 00 03 D2 2D 2D
+ 39 01 00 00 00 00 0C B2 80 02 18 80 70 00 08 1C 08 11 05
+ 39 01 00 00 00 00 02 E9 D1
+ 39 01 00 00 00 00 03 B2 00 08
+ 39 01 00 00 00 00 02 E9 00
+ 39 01 00 00 00 00 02 BD 02
+ 39 01 00 00 00 00 03 B2 B5 0A
+ 39 01 00 00 00 00 02 BD 00
+ 39 01 00 00 00 00 09 DD 00 00 08 1C 08 34 34 88
+ 39 01 00 00 00 00 19 B4 65 6B 00 00 D0 D4 36 CF 06 CE 00 CE 00 00 00 07 00 2A 07 01 07 00 00 2A
+ 39 01 00 00 00 00 02 BD 03
+ 39 01 00 00 00 00 02 E9 C3
+ 39 01 00 00 00 00 04 B4 01 67 2A
+ 39 01 00 00 00 00 02 E9 00
+ 39 01 00 00 00 00 02 BD 00
+ 39 01 00 00 00 00 02 C1 01
+ 39 01 00 00 00 00 02 BD 01
+ 39 01 00 00 00 00 3A C1 FF FB F9 F6 F4 F1 EF EA E7 E5 E2 DF DD DA D8 D5 D2 CF CC C5 BE B7 B0 A8 A0 98 8E 85 7B 72 69 5E 53 48 3E 35 2B 22 17 0D 09 07 05 01 00 26 F0 86 25 6E B6 DD F3 D8 CC 9B 00
+ 39 01 00 00 00 00 02 BD 02
+ 39 01 00 00 00 00 3A C1 FF FB F9 F6 F4 F1 EF EA E7 E5 E2 DF DD DA D8 D5 D2 CF CC C5 BE B7 B0 A8 A0 98 8E 85 7B 72 69 5E 53 48 3E 35 2B 22 17 0D 09 07 05 01 00 26 F0 86 25 6E B6 DD F3 D8 CC 9B 00
+ 39 01 00 00 00 00 02 BD 03
+ 39 01 00 00 00 00 3A C1 FF FB F9 F6 F4 F1 EF EA E7 E5 E2 DF DD DA D8 D5 D2 CF CC C5 BE B7 B0 A8 A0 98 8E 85 7B 72 69 5E 53 48 3E 35 2B 22 17 0D 09 07 05 01 00 26 F0 86 25 6E B6 DD F3 D8 CC 9B 00
+ 39 01 00 00 00 00 02 BD 00
+ 39 01 00 00 00 00 02 C2 C8
+ 39 01 00 00 00 00 02 CC 08
+ 39 01 00 00 00 00 26 D3 81 00 00 00 00 01 00 04 00 01 13 40 04 09 09 0B 0B 32 10 08 00 08 32 10 08 00 08 32 10 08 00 08 00 00 0A 08 7B
+ 39 01 00 00 00 00 02 E9 C5
+ 39 01 00 00 00 00 02 C6 F7
+ 39 01 00 00 00 00 02 E9 00
+ 39 01 00 00 00 00 02 E9 D4
+ 39 01 00 00 00 00 02 C6 6E
+ 39 01 00 00 00 00 02 E9 00
+ 39 01 00 00 00 00 02 E9 EF
+ 39 01 00 00 00 00 02 D3 0C
+ 39 01 00 00 00 00 02 E9 00
+ 39 01 00 00 00 00 02 BD 01
+ 39 01 00 00 00 00 02 E9 C8
+ 39 01 00 00 00 00 02 D3 A1
+ 39 01 00 00 00 00 02 E9 00
+ 39 01 00 00 00 00 02 BD 00
+ 39 01 00 00 00 00 39 D5 18 18 19 18 18 20 18 18 18 10 10 18 18 00 00 18 18 01 01 18 18 28 28 18 18 18 18 18 2F 2F 30 30 31 31 35 35 36 36 37 37 18 18 18 18 18 18 18 18 FC FC 00 00 FC FC 00 00
+ 39 01 00 00 00 00 31 D6 18 18 19 18 18 20 19 18 18 10 10 18 18 00 00 18 18 01 01 18 18 28 28 18 18 18 18 18 2F 2F 30 30 31 31 35 35 36 36 37 37 18 18 18 18 18 18 18 18
+ 39 01 00 00 00 00 19 D8 AA AA AA AF EA AA AA AA AA AF EA AA AA AA AB AF EF AA AA AA AA AF EA AA
+ 39 01 00 00 00 00 02 BD 01
+ 39 01 00 00 00 00 0D D8 AA AA AB AF EA AA AA AA AE AF EA AA
+ 39 01 00 00 00 00 02 BD 02
+ 39 01 00 00 00 00 0D D8 AA AA AA AF EA AA AA AA AA AF EA AA
+ 39 01 00 00 00 00 02 BD 03
+ 39 01 00 00 00 00 19 D8 BA AA AA AF EA AA AA AA AA AF EA AA BA AA AA AF EA AA AA AA AA AF EA AA
+ 39 01 00 00 00 00 02 BD 00
+ 39 01 00 00 00 00 02 E9 E4
+ 39 01 00 00 00 00 03 E7 17 69
+ 39 01 00 00 00 00 02 E9 00
+ 39 01 00 00 00 00 1A E7 09 09 00 07 E8 00 26 00 07 00 00 E8 32 00 E9 0A 0A 00 00 00 01 01 00 12 04
+ 39 01 00 00 00 00 02 BD 01
+ 39 01 00 00 00 00 0A E7 02 00 01 20 01 18 08 A8 09
+ 39 01 00 00 00 00 02 BD 02
+ 39 01 00 00 00 00 04 E7 20 20 00
+ 39 01 00 00 00 00 02 BD 03
+ 39 01 00 00 00 00 07 E7 00 DC 11 70 00 20
+ 39 01 00 00 00 00 02 E9 C9
+ 39 01 00 00 00 00 07 E7 2A CE 02 70 01 04
+ 39 01 00 00 00 00 02 E9 00
+ 39 01 00 00 00 00 02 BD 00
+ 39 01 00 00 00 00 02 D1 27
+ 05 01 00 00 78 00 02 11 00
+ 05 01 00 00 14 00 02 29 00
+ 39 01 00 00 00 00 03 51 00 00
+ 39 01 00 00 00 00 02 53 24];
+ qcom,mdss-dsi-off-command = [05 01 00 00 14 00 02 28 00
+ 05 01 00 00 78 00 02 10 00];
+ qcom,mdss-dsi-off-dstb-command = [
+ 39 01 00 00 00 00 04 B9 83 11 2A
+ 39 01 00 00 00 00 02 BD 00
+ 39 01 00 00 50 00 02 B1 09];
+ qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
+ qcom,mdss-dsi-off-command-state = "dsi_lp_mode";
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs";
+ qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>;
+ qcom,mdss-dsi-tx-eot-append;
+ qcom,mdss-dsi-lp11-init;
+ qcom,mdss-dsi-post-init-delay = <1>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/dsi-hx83112b-truly-1080p-video.dtsi b/arch/arm64/boot/dts/qcom/dsi-hx83112b-truly-1080p-video.dtsi
new file mode 100755
index 0000000..bbb4716
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/dsi-hx83112b-truly-1080p-video.dtsi
@@ -0,0 +1,152 @@
+/* Copyright (c) 2017, 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.
+ */
+
+&mdss_mdp {
+ dsi_hx83112b_truly_1080p_video: qcom,mdss_dsi_hx83112b_truly_1080p_video {
+ qcom,mdss-dsi-panel-name =
+ "hx83112b truly 1080p video mode dsi panel";
+ qcom,mdss-dsi-panel-type = "dsi_cmd_mode";
+ qcom,mdss-dsi-panel-framerate = <60>;
+ qcom,mdss-dsi-virtual-channel-id = <0>;
+ qcom,mdss-dsi-stream = <0>;
+ qcom,mdss-dsi-panel-width = <1080>;
+ qcom,mdss-dsi-panel-height = <2160>;
+ qcom,mdss-dsi-h-front-porch = <40>;
+ qcom,mdss-dsi-h-back-porch = <12>;
+ qcom,mdss-dsi-h-pulse-width = <4>;
+ qcom,mdss-dsi-h-sync-skew = <0>;
+ qcom,mdss-dsi-v-back-porch = <2>;
+ qcom,mdss-dsi-v-front-porch = <32>;
+ qcom,mdss-dsi-v-pulse-width = <2>;
+ qcom,mdss-dsi-h-left-border = <0>;
+ qcom,mdss-dsi-h-right-border = <0>;
+ qcom,mdss-dsi-v-top-border = <0>;
+ qcom,mdss-dsi-v-bottom-border = <0>;
+ qcom,mdss-dsi-bpp = <24>;
+ qcom,mdss-dsi-underflow-color = <0xff>;
+ qcom,mdss-dsi-border-color = <0>;
+ qcom,mdss-dsi-te-pin-select = <1>;
+ qcom,mdss-dsi-te-dcs-command = <1>;
+ qcom,mdss-dsi-te-check-enable;
+ qcom,mdss-dsi-te-using-te-pin;
+ qcom,mdss-dsi-h-sync-pulse = <0>;
+ qcom,mdss-dsi-traffic-mode = "burst_mode";
+ qcom,mdss-dsi-bllp-eof-power-mode;
+ qcom,mdss-dsi-bllp-power-mode;
+ qcom,mdss-dsi-lane-0-state;
+ qcom,mdss-dsi-lane-1-state;
+ qcom,mdss-dsi-lane-2-state;
+ qcom,mdss-dsi-lane-3-state;
+ //qcom,mdss-dsi-hfp-power-mode;
+ //qcom,mdss-dsi-hbp-power-mode;
+ qcom,mdss-dsi-hsa-power-mode;
+ qcom,mdss-pan-physical-width-dimension=<65>;
+ qcom,mdss-pan-physical-height-dimension=<128>;
+ qcom,mdss-dsi-panel-timings = [e6 38 26 00 68 6e 2a
+ 3c 44 03 04 00];
+ qcom,mdss-dsi-t-clk-post = <0x0d>;
+ qcom,mdss-dsi-t-clk-pre = <0x2f>;
+ qcom,mdss-dsi-bl-min-level = <1>;
+ qcom,mdss-dsi-bl-max-level = <4095>;
+ qcom,mdss-dsi-dma-trigger = "trigger_sw";
+ qcom,mdss-dsi-mdp-trigger = "none";
+ qcom,mdss-dsi-on-command = [39 01 00 00 00 00 04 B9 83 11 2B
+ 39 01 00 00 00 00 02 BD 01
+ 39 01 00 00 00 00 03 C2 08 70
+ 39 01 00 00 00 00 02 BD 03
+ 39 01 00 00 00 00 05 B2 04 38 08 70
+ 39 01 00 00 00 00 02 BD 00
+ 39 01 00 00 00 00 0B B1 F8 27 27 00 00 0B 0E 0B 0E 33
+ 39 01 00 00 00 00 03 D2 2D 2D
+ 39 01 00 00 00 00 0C B2 80 02 18 80 70 00 08 1C 08 11 05
+ 39 01 00 00 00 00 02 E9 D1
+ 39 01 00 00 00 00 03 B2 00 08
+ 39 01 00 00 00 00 02 E9 00
+ 39 01 00 00 00 00 02 BD 02
+ 39 01 00 00 00 00 03 B2 B5 0A
+ 39 01 00 00 00 00 02 BD 00
+ 39 01 00 00 00 00 09 DD 00 00 08 1C 08 34 34 88
+ 39 01 00 00 00 00 19 B4 65 6B 00 00 D0 D4 36 CF 06 CE 00 CE 00 00 00 07 00 2A 07 01 07 00 00 2A
+ 39 01 00 00 00 00 02 BD 03
+ 39 01 00 00 00 00 02 E9 C3
+ 39 01 00 00 00 00 04 B4 01 67 2A
+ 39 01 00 00 00 00 02 E9 00
+ 39 01 00 00 00 00 02 BD 00
+ 39 01 00 00 00 00 02 C1 01
+ 39 01 00 00 00 00 02 BD 01
+ 39 01 00 00 00 00 3A C1 FF FB F9 F6 F4 F1 EF EA E7 E5 E2 DF DD DA D8 D5 D2 CF CC C5 BE B7 B0 A8 A0 98 8E 85 7B 72 69 5E 53 48 3E 35 2B 22 17 0D 09 07 05 01 00 26 F0 86 25 6E B6 DD F3 D8 CC 9B 00
+ 39 01 00 00 00 00 02 BD 02
+ 39 01 00 00 00 00 3A C1 FF FB F9 F6 F4 F1 EF EA E7 E5 E2 DF DD DA D8 D5 D2 CF CC C5 BE B7 B0 A8 A0 98 8E 85 7B 72 69 5E 53 48 3E 35 2B 22 17 0D 09 07 05 01 00 26 F0 86 25 6E B6 DD F3 D8 CC 9B 00
+ 39 01 00 00 00 00 02 BD 03
+ 39 01 00 00 00 00 3A C1 FF FB F9 F6 F4 F1 EF EA E7 E5 E2 DF DD DA D8 D5 D2 CF CC C5 BE B7 B0 A8 A0 98 8E 85 7B 72 69 5E 53 48 3E 35 2B 22 17 0D 09 07 05 01 00 26 F0 86 25 6E B6 DD F3 D8 CC 9B 00
+ 39 01 00 00 00 00 02 BD 00
+ 39 01 00 00 00 00 02 C2 C8
+ 39 01 00 00 00 00 02 CC 08
+ 39 01 00 00 00 00 26 D3 81 00 00 00 00 01 00 04 00 01 13 40 04 09 09 0B 0B 32 10 08 00 08 32 10 08 00 08 32 10 08 00 08 00 00 0A 08 7B
+ 39 01 00 00 00 00 02 E9 C5
+ 39 01 00 00 00 00 02 C6 F7
+ 39 01 00 00 00 00 02 E9 00
+ 39 01 00 00 00 00 02 E9 D4
+ 39 01 00 00 00 00 02 C6 6E
+ 39 01 00 00 00 00 02 E9 00
+ 39 01 00 00 00 00 02 E9 EF
+ 39 01 00 00 00 00 02 D3 0C
+ 39 01 00 00 00 00 02 E9 00
+ 39 01 00 00 00 00 02 BD 01
+ 39 01 00 00 00 00 02 E9 C8
+ 39 01 00 00 00 00 02 D3 A1
+ 39 01 00 00 00 00 02 E9 00
+ 39 01 00 00 00 00 02 BD 00
+ 39 01 00 00 00 00 39 D5 18 18 19 18 18 20 18 18 18 10 10 18 18 00 00 18 18 01 01 18 18 28 28 18 18 18 18 18 2F 2F 30 30 31 31 35 35 36 36 37 37 18 18 18 18 18 18 18 18 FC FC 00 00 FC FC 00 00
+ 39 01 00 00 00 00 31 D6 18 18 19 18 18 20 19 18 18 10 10 18 18 00 00 18 18 01 01 18 18 28 28 18 18 18 18 18 2F 2F 30 30 31 31 35 35 36 36 37 37 18 18 18 18 18 18 18 18
+ 39 01 00 00 00 00 19 D8 AA AA AA AF EA AA AA AA AA AF EA AA AA AA AB AF EF AA AA AA AA AF EA AA
+ 39 01 00 00 00 00 02 BD 01
+ 39 01 00 00 00 00 0D D8 AA AA AB AF EA AA AA AA AE AF EA AA
+ 39 01 00 00 00 00 02 BD 02
+ 39 01 00 00 00 00 0D D8 AA AA AA AF EA AA AA AA AA AF EA AA
+ 39 01 00 00 00 00 02 BD 03
+ 39 01 00 00 00 00 19 D8 BA AA AA AF EA AA AA AA AA AF EA AA BA AA AA AF EA AA AA AA AA AF EA AA
+ 39 01 00 00 00 00 02 BD 00
+ 39 01 00 00 00 00 02 E9 E4
+ 39 01 00 00 00 00 03 E7 17 69
+ 39 01 00 00 00 00 02 E9 00
+ 39 01 00 00 00 00 1A E7 09 09 00 07 E8 00 26 00 07 00 00 E8 32 00 E9 0A 0A 00 00 00 01 01 00 12 04
+ 39 01 00 00 00 00 02 BD 01
+ 39 01 00 00 00 00 0A E7 02 00 01 20 01 18 08 A8 09
+ 39 01 00 00 00 00 02 BD 02
+ 39 01 00 00 00 00 04 E7 20 20 00
+ 39 01 00 00 00 00 02 BD 03
+ 39 01 00 00 00 00 07 E7 00 DC 11 70 00 20
+ 39 01 00 00 00 00 02 E9 C9
+ 39 01 00 00 00 00 07 E7 2A CE 02 70 01 04
+ 39 01 00 00 00 00 02 E9 00
+ 39 01 00 00 00 00 02 BD 00
+ 39 01 00 00 00 00 02 D1 27
+ 05 01 00 00 78 00 02 11 00
+ 05 01 00 00 14 00 02 29 00
+ 39 01 00 00 00 00 03 51 00 00
+ 39 01 00 00 00 00 02 53 24];
+ qcom,mdss-dsi-off-command = [05 01 00 00 14 00 02 28 00
+ 05 01 00 00 78 00 02 10 00];
+ qcom,mdss-dsi-off-dstb-command = [
+ 39 01 00 00 00 00 04 B9 83 11 2A
+ 39 01 00 00 00 00 02 BD 00
+ 39 01 00 00 50 00 02 B1 09];
+ qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
+ qcom,mdss-dsi-off-command-state = "dsi_lp_mode";
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs";
+ qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>;
+ qcom,mdss-dsi-tx-eot-append;
+ qcom,mdss-dsi-lp11-init;
+ qcom,mdss-dsi-post-init-delay = <1>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi b/arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi
old mode 100644
new mode 100755
index bb05a2e..bd1c232
--- a/arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi
@@ -115,19 +115,20 @@
qcom,msm-mi2s-tx-lines = <2>;
};
- dai_mi2s4: qcom,msm-dai-q6-mi2s-quin {
+ dai_mi2s4: qcom,msm-dai-q6-mi2s-senary {
compatible = "qcom,msm-dai-q6-mi2s";
qcom,msm-dai-q6-mi2s-dev-id = <4>;
- qcom,msm-mi2s-rx-lines = <1>;
- qcom,msm-mi2s-tx-lines = <2>;
+ qcom,msm-mi2s-rx-lines = <3>;
+ qcom,msm-mi2s-tx-lines = <0>;
};
- dai_mi2s5: qcom,msm-dai-q6-mi2s-senary {
+ dai_mi2s5: qcom,msm-dai-q6-mi2s-quin {
compatible = "qcom,msm-dai-q6-mi2s";
- qcom,msm-dai-q6-mi2s-dev-id = <6>;
- qcom,msm-mi2s-rx-lines = <0>;
- qcom,msm-mi2s-tx-lines = <3>;
+ qcom,msm-dai-q6-mi2s-dev-id = <4>;
+ qcom,msm-mi2s-rx-lines = <3>;
+ qcom,msm-mi2s-tx-lines = <0>;
};
+
};
lsm: qcom,msm-lsm-client {
diff --git a/arch/arm64/boot/dts/qcom/msm8953-audio.dtsi b/arch/arm64/boot/dts/qcom/msm8953-audio.dtsi
old mode 100644
new mode 100755
index 9e07534..b812f89
--- a/arch/arm64/boot/dts/qcom/msm8953-audio.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-audio.dtsi
@@ -36,7 +36,7 @@
};
int_codec: sound {
- status = "okay";
+ status = "disabled";
compatible = "qcom,msm8952-audio-codec";
qcom,model = "msm8953-snd-card-mtp";
reg = <0xc051000 0x4>,
@@ -76,10 +76,10 @@
"WSA_SPK OUT", "VDD_WSA_SWITCH",
"SpkrMono WSA_IN", "WSA_SPK OUT";
- qcom,cdc-us-euro-gpios = <&tlmm 63 0>;
- qcom,cdc-us-eu-gpios = <&cdc_us_euro_sw>;
- qcom,cdc-comp-gpios = <&cdc_comp_gpios>;
- qcom,pri-mi2s-gpios = <&cdc_pri_mi2s_gpios>;
+ //qcom,cdc-us-euro-gpios = <&tlmm 63 0>;
+ //qcom,cdc-us-eu-gpios = <&cdc_us_euro_sw>;
+ //qcom,cdc-comp-gpios = <&cdc_comp_gpios>;
+ //qcom,pri-mi2s-gpios = <&cdc_pri_mi2s_gpios>;
qcom,quin-mi2s-gpios = <&cdc_quin_mi2s_gpios>;
qcom,afe-rxtx-lb;
@@ -136,14 +136,8 @@
qcom,msm-vdd-wsa-switch-current = <10000>;
};
- cdc_us_euro_sw: msm_cdc_pinctrl_us_euro_sw {
- compatible = "qcom,msm-cdc-pinctrl";
- pinctrl-names = "aud_active", "aud_sleep";
- pinctrl-0 = <&cross_conn_det_act>;
- pinctrl-1 = <&cross_conn_det_sus>;
- };
-
cdc_comp_gpios: cdc_comp_pinctrl {
+ status = "disabled";
compatible = "qcom,msm-cdc-pinctrl";
pinctrl-names = "aud_active", "aud_sleep";
pinctrl-0 = <&cdc_pdm_comp_lines_act>;
@@ -151,6 +145,7 @@
};
cdc_pri_mi2s_gpios: msm_cdc_pinctrl_pri {
+ status = "disabled";
compatible = "qcom,msm-cdc-pinctrl";
pinctrl-names = "aud_active", "aud_sleep";
pinctrl-0 = <&cdc_pdm_lines_act &cdc_pdm_lines_2_act>;
@@ -170,7 +165,7 @@
#address-cells = <1>;
#size-cells = <0>;
wsa881x_i2c_f: wsa881x-i2c-codec@f {
- status = "okay";
+ status = "disabled";
compatible = "qcom,wsa881x-i2c-codec";
reg = <0x0f>;
qcom,wsa-analog-vi-gpio = <&wsa881x_analog_vi_gpio>;
@@ -179,7 +174,7 @@
<&wsa881x_analog_reset_gpio>;
};
wsa881x_i2c_45: wsa881x-i2c-codec@45 {
- status = "okay";
+ status = "disabled";
compatible = "qcom,wsa881x-i2c-codec";
reg = <0x45>;
};
@@ -198,25 +193,34 @@
pinctrl-1 = <&wsa_clk_off>;
};
wsa881x_analog_reset_gpio: wsa881x_analog_reset_pctrl {
- compatible = "qcom,msm-cdc-pinctrl";
- pinctrl-names = "aud_active", "aud_sleep";
- pinctrl-0 = <&wsa_reset_on>;
- pinctrl-1 = <&wsa_reset_off>;
+ status = "disabled";
+ //compatible = "qcom,msm-cdc-pinctrl";
+ //pinctrl-names = "aud_active", "aud_sleep";
+ //pinctrl-0 = <&wsa_reset_on>;
+ //pinctrl-1 = <&wsa_reset_off>;
};
ext_codec: sound-9335 {
- status = "disabled";
+ status = "okay";
compatible = "qcom,msm8952-audio-slim-codec";
qcom,model = "msm8953-tasha-snd-card";
reg = <0xc051000 0x4>,
<0xc051004 0x4>,
<0xc055000 0x4>,
- <0xc052000 0x4>;
+ <0xc052000 0x4>,
+ <0x0c056000 0x4>,
+ <0x0c054000 0x4>,
+ <0x0c053000 0x4>;
reg-names = "csr_gp_io_mux_mic_ctl",
"csr_gp_io_mux_spkr_ctl",
"csr_gp_io_lpaif_pri_pcm_pri_mode_muxsel",
- "csr_gp_io_mux_quin_ctl";
+ "csr_gp_io_mux_quin_ctl",
+ "csr_gp_io_lpaif_qui_pcm_sec_mode_muxsel",
+ "csr_gp_io_mux_mic_ext_clk_ctl",
+ "csr_gp_io_mux_sec_tlmm_ctl";
+
+ qcom,msm-ext-pa = "quinary";
qcom,audio-routing =
"AIF4 VI", "MCLK",
@@ -254,10 +258,8 @@
"SpkrRight IN", "SPK2 OUT";
qcom,tasha-mclk-clk-freq = <9600000>;
- qcom,cdc-us-euro-gpios = <&tlmm 63 0>;
- qcom,msm-mbhc-hphl-swh = <0>;
- qcom,msm-mbhc-gnd-swh = <0>;
- qcom,cdc-us-eu-gpios = <&cdc_us_euro_sw>;
+ qcom,msm-mbhc-hphl-swh = <1>;
+ qcom,msm-mbhc-gnd-swh = <1>;
qcom,quin-mi2s-gpios = <&cdc_quin_mi2s_gpios>;
asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>,
@@ -302,10 +304,10 @@
"msm-dai-q6-dev.12293", "msm-dai-q6-dev.16396",
"msm-dai-q6-dev.8194", "msm-dai-q6-dev.8195";
- asoc-codec = <&stub_codec>, <&hdmi_dba>;
- asoc-codec-names = "msm-stub-codec.1", "msm-hdmi-dba-codec-rx";
+ asoc-codec = <&stub_codec>, <&dai_mi2s5>;
+ asoc-codec-names = "msm-stub-codec.1", "msm-dai-q6-mi2s.5";
- qcom,wsa-max-devs = <2>;
+ qcom,wsa-max-devs = <0>;
qcom,wsa-devs = <&wsa881x_211>, <&wsa881x_212>,
<&wsa881x_213>, <&wsa881x_214>;
qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrRight",
@@ -317,7 +319,7 @@
};
wcd9xxx_intc: wcd9xxx-irq {
- status = "disabled";
+ status = "okay";
compatible = "qcom,wcd9xxx-irq";
interrupt-controller;
#interrupt-cells = <1>;
@@ -328,7 +330,7 @@
};
clock_audio: audio_ext_clk {
- status = "disabled";
+ status = "okay";
compatible = "qcom,audio-ref-clk";
clock-names = "osr_clk";
qcom,node_has_rpm_clock;
@@ -341,7 +343,7 @@
};
wcd_rst_gpio: msm_cdc_pinctrl@67 {
- status = "disabled";
+ status = "okay";
compatible = "qcom,msm-cdc-pinctrl";
pinctrl-names = "aud_active", "aud_sleep";
pinctrl-0 = <&cdc_reset_active>;
@@ -350,16 +352,16 @@
};
&slim_msm {
- status = "disabled";
+ status = "okay";
dai_slim: msm_dai_slim {
- status = "disabled";
+ status = "okay";
compatible = "qcom,msm-dai-slim";
elemental-addr = [ff ff ff fe 17 02];
};
wcd9335: tasha_codec {
- status = "disabled";
+ status = "okay";
compatible = "qcom,tasha-slim-pgd";
elemental-addr = [00 01 A0 01 17 02];
@@ -385,7 +387,7 @@
qcom,cdc-on-demand-supplies = "cdc-vdd-mic-bias";
qcom,cdc-micbias1-mv = <1800>;
- qcom,cdc-micbias2-mv = <1800>;
+ qcom,cdc-micbias2-mv = <2800>;
qcom,cdc-micbias3-mv = <1800>;
qcom,cdc-micbias4-mv = <1800>;
@@ -442,7 +444,7 @@
&pm8953_1 {
pmic_analog_codec: analog-codec@f000 {
- status = "okay";
+ status = "disabled";
compatible = "qcom,pmic-analog-codec";
reg = <0xf000 0x200>;
#address-cells = <2>;
diff --git a/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-mtp.dtsi
old mode 100644
new mode 100755
index f3e13c0..4134611
--- a/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-mtp.dtsi
@@ -20,7 +20,6 @@
reg = <0x0>;
compatible = "qcom,actuator";
qcom,cci-master = <0>;
- cam_vaf-supply = <&pm8953_l17>;
qcom,cam-vreg-name = "cam_vaf";
qcom,cam-vreg-min-voltage = <2850000>;
qcom,cam-vreg-max-voltage = <2850000>;
@@ -44,111 +43,85 @@
compatible = "qcom,eeprom";
qcom,cci-master = <0>;
reg = <0x0>;
- cam_vio-supply = <&pm8953_l6>;
- cam_vdig-supply = <&pm8953_l2>;
- cam_vaf-supply = <&pm8953_l17>;
- qcom,cam-vreg-name = "cam_vio", "cam_vdig", "cam_vaf";
- qcom,cam-vreg-min-voltage = <0 1200000 2850000>;
- qcom,cam-vreg-max-voltage = <0 1200000 2850000>;
- qcom,cam-vreg-op-mode = <0 105000 100000>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_v_custom1-supply = <&pm8953_l2>;
+ qcom,cam-vreg-name = "cam_vana", "cam_v_custom1";
+ qcom,cam-vreg-min-voltage = <2800000 1175000>;
+ qcom,cam-vreg-max-voltage = <2800000 1175000>;
+ qcom,cam-vreg-op-mode = <80000 105000>;
pinctrl-names = "cam_default", "cam_suspend";
- pinctrl-0 = <&cam_sensor_mclk0_default
- &cam_sensor_rear_default
- &cam_sensor_rear_vana>;
- pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep
- &cam_sensor_rear_vana_sleep>;
+ pinctrl-0 = <&cam_sensor_mclk0_default &cam_sensor_rear_default>;
+ pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep>;
gpios = <&tlmm 26 0>,
<&tlmm 40 0>,
- <&tlmm 39 0>,
- <&tlmm 134 0>;
+ <&tlmm 130 0>;
qcom,gpio-reset = <1>;
- qcom,gpio-standby = <2>;
- qcom,gpio-vana = <3>;
- qcom,gpio-req-tbl-num = <0 1 2 3>;
- qcom,gpio-req-tbl-flags = <1 0 0 0>;
+ qcom,gpio-vio = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
qcom,gpio-req-tbl-label = "CAMIF_MCLK0",
"CAM_RESET0",
- "CAM_STANDBY0",
- "CAM_VANA";
+ "CAM_VIO";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
status = "ok";
clocks = <&clock_gcc clk_mclk0_clk_src>,
<&clock_gcc clk_gcc_camss_mclk0_clk>;
clock-names = "cam_src_clk", "cam_clk";
- qcom,clock-rates = <19200000 0>;
+ qcom,clock-rates = <24000000 0>;
};
eeprom1: qcom,eeprom@1 {
cell-index = <1>;
- reg = <0x1>;
compatible = "qcom,eeprom";
qcom,cci-master = <1>;
- cam_vdig-supply = <&pm8953_l23>;
- cam_vio-supply = <&pm8953_l6>;
+ reg = <0x1>;
+
cam_vana-supply = <&pm8953_l22>;
- cam_vaf-supply = <&pm8953_l17>;
- qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
- "cam_vaf";
- qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
- qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
- qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ qcom,cam-vreg-name = "cam_vana";
+ qcom,cam-vreg-min-voltage = <2800000>;
+ qcom,cam-vreg-max-voltage = <2800000>;
+ qcom,cam-vreg-op-mode = <80000>;
qcom,gpio-no-mux = <0>;
+
pinctrl-names = "cam_default", "cam_suspend";
pinctrl-0 = <&cam_sensor_mclk1_default
- &cam_sensor_front1_default>;
+ &cam_sensor_front1_default
+ &cam_sensor_front1_vdig_default
+ &cam_sensor_front1_vio_default>;
pinctrl-1 = <&cam_sensor_mclk1_sleep
- &cam_sensor_front1_sleep>;
- gpios = <&tlmm 27 0>,
- <&tlmm 129 0>,
- <&tlmm 130 0>;
- qcom,gpio-reset = <1>;
- qcom,gpio-standby = <2>;
- qcom,gpio-req-tbl-num = <0 1 2>;
- qcom,gpio-req-tbl-flags = <1 0 0>;
- qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
- "CAM_RESET2",
- "CAM_STANDBY2";
- qcom,sensor-position = <1>;
- qcom,sensor-mode = <0>;
- status = "ok";
- clocks = <&clock_gcc clk_mclk1_clk_src>,
- <&clock_gcc clk_gcc_camss_mclk1_clk>;
- clock-names = "cam_src_clk", "cam_clk";
- qcom,clock-rates = <19200000 0>;
- };
+ &cam_sensor_front1_sleep
+ &cam_sensor_front1_vdig_sleep
+ &cam_sensor_front1_vio_sleep>;
- eeprom2: qcom,eeprom@2 {
- cell-index = <2>;
- compatible = "qcom,eeprom";
- qcom,cci-master = <1>;
- reg = <0x2>;
- cam_vdig-supply = <&pm8953_l23>;
- cam_vana-supply = <&pm8953_l22>;
- cam_vio-supply = <&pm8953_l6>;
- cam_vaf-supply = <&pm8953_l17>;
- qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
- "cam_vaf";
- qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
- qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
- qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
- pinctrl-names = "cam_default", "cam_suspend";
- pinctrl-0 = <&cam_sensor_mclk2_default
- &cam_sensor_front_default>;
- pinctrl-1 = <&cam_sensor_mclk2_sleep
- &cam_sensor_front_sleep>;
- gpios = <&tlmm 28 0>,
- <&tlmm 131 0>,
- <&tlmm 132 0>;
+ gpios = <&tlmm 27 0>,
+ <&tlmm 129 0>,
+ <&tlmm 46 0>,
+ <&tlmm 130 0>;
qcom,gpio-reset = <1>;
- qcom,gpio-standby = <2>;
- qcom,gpio-req-tbl-num = <0 1 2>;
- qcom,gpio-req-tbl-flags = <1 0 0>;
- qcom,gpio-req-tbl-label = "CAMIF_MCLK1",
- "CAM_RESET1",
- "CAM_STANDBY1";
+ qcom,gpio-vdig = <2>;
+ qcom,gpio-vio = <3>;
+ qcom,gpio-req-tbl-num = <0 1 2 3>;
+ qcom,gpio-req-tbl-flags = <1 0 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+ "CAM_RESET2",
+ "CAM_VDIG2",
+ "CAM_VIO2";
+
status = "ok";
- clocks = <&clock_gcc clk_mclk2_clk_src>,
- <&clock_gcc clk_gcc_camss_mclk2_clk>;
+ qcom,cam-power-seq-val = "sensor_gpio_reset",
+ "cam_vana", "sensor_gpio_vdig",
+ "sensor_gpio_vio", "sensor_gpio_reset",
+ "sensor_cam_mclk";
+ qcom,cam-power-seq-type = "sensor_gpio",
+ "sensor_vreg", "sensor_gpio",
+ "sensor_gpio", "sensor_gpio",
+ "sensor_clk";
+ qcom,cam-power-seq-cfg-val = <0 1 1 1 1 24000000>;
+ qcom,cam-power-seq-delay = <5 1 1 3 3 10>;
clock-names = "cam_src_clk", "cam_clk";
+ clocks = <&clock_gcc clk_mclk1_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk1_clk>;
qcom,clock-rates = <19200000 0>;
};
@@ -162,16 +135,12 @@
qcom,led-flash-src = <&led_flash0>;
qcom,eeprom-src = <&eeprom0>;
qcom,actuator-src = <&actuator0>;
- cam_vio-supply = <&pm8953_l6>;
- cam_vdig-supply = <&pm8953_l2>;
- cam_vaf-supply = <&pm8953_l17>;
cam_vana-supply = <&pm8953_l22>;
- cam_v_custom1-supply = <&pm8953_l23>;
- qcom,cam-vreg-name = "cam_vio", "cam_vdig", "cam_vaf",
- "cam_vana", "cam_v_custom1";
- qcom,cam-vreg-min-voltage = <0 1200000 2850000 2800000 1200000>;
- qcom,cam-vreg-max-voltage = <0 1200000 2850000 2800000 1200000>;
- qcom,cam-vreg-op-mode = <0 105000 100000 80000 105000>;
+ cam_v_custom1-supply = <&pm8953_l2>;
+ qcom,cam-vreg-name = "cam_vana", "cam_v_custom1";
+ qcom,cam-vreg-min-voltage = <2800000 1175000>;
+ qcom,cam-vreg-max-voltage = <2800000 1175000>;
+ qcom,cam-vreg-op-mode = <80000 105000>;
pinctrl-names = "cam_default", "cam_suspend";
pinctrl-0 = <&cam_sensor_mclk0_default
&cam_sensor_rear_default
@@ -180,17 +149,17 @@
&cam_sensor_rear_vana_sleep>;
gpios = <&tlmm 26 0>,
<&tlmm 40 0>,
- <&tlmm 39 0>,
- <&tlmm 134 0>;
+ <&tlmm 130 0>,
+ <&tlmm 128 0>;
qcom,gpio-reset = <1>;
- qcom,gpio-standby = <2>;
- qcom,gpio-vana = <3>;
+ qcom,gpio-vio = <2>;
+ qcom,gpio-vaf = <3>;
qcom,gpio-req-tbl-num = <0 1 2 3>;
qcom,gpio-req-tbl-flags = <1 0 0 0>;
qcom,gpio-req-tbl-label = "CAMIF_MCLK0",
"CAM_RESET0",
- "CAM_STANDBY0",
- "CAM_VANA";
+ "CAM_VIO",
+ "CAM_VAF";
qcom,sensor-position = <0>;
qcom,sensor-mode = <0>;
qcom,cci-master = <0>;
@@ -201,90 +170,52 @@
qcom,clock-rates = <24000000 0>;
};
- qcom,camera@1 {
- cell-index = <1>;
- compatible = "qcom,camera";
- reg = <0x1>;
- qcom,csiphy-sd-index = <1>;
- qcom,csid-sd-index = <1>;
- qcom,mount-angle = <90>;
- qcom,eeprom-src = <&eeprom2>;
- qcom,actuator-src = <&actuator1>;
- cam_vdig-supply = <&pm8953_l23>;
- cam_vana-supply = <&pm8953_l22>;
- cam_vio-supply = <&pm8953_l6>;
- cam_vaf-supply = <&pm8953_l17>;
- qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
- "cam_vaf";
- qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
- qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
- qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
- pinctrl-names = "cam_default", "cam_suspend";
- pinctrl-0 = <&cam_sensor_mclk2_default
- &cam_sensor_front_default>;
- pinctrl-1 = <&cam_sensor_mclk2_sleep
- &cam_sensor_front_sleep>;
- gpios = <&tlmm 28 0>,
- <&tlmm 131 0>,
- <&tlmm 132 0>;
- qcom,gpio-reset = <1>;
- qcom,gpio-standby = <2>;
- qcom,gpio-req-tbl-num = <0 1 2>;
- qcom,gpio-req-tbl-flags = <1 0 0>;
- qcom,gpio-req-tbl-label = "CAMIF_MCLK1",
- "CAM_RESET1",
- "CAM_STANDBY1";
- qcom,sensor-position = <0x100>;
- qcom,sensor-mode = <1>;
- qcom,cci-master = <1>;
- status = "ok";
- clocks = <&clock_gcc clk_mclk2_clk_src>,
- <&clock_gcc clk_gcc_camss_mclk2_clk>;
- clock-names = "cam_src_clk", "cam_clk";
- qcom,clock-rates = <24000000 0>;
- };
-
- qcom,camera@2 {
+ camera2: qcom,camera@2 {
cell-index = <2>;
compatible = "qcom,camera";
reg = <0x02>;
qcom,csiphy-sd-index = <2>;
- qcom,csid-sd-index = <2>;
- qcom,mount-angle = <90>;
+ qcom,csid-sd-index = <1>;
+ qcom,mount-angle = <270>;
qcom,eeprom-src = <&eeprom1>;
- qcom,actuator-src = <&actuator1>;
- cam_vdig-supply = <&pm8953_l23>;
- cam_vio-supply = <&pm8953_l6>;
cam_vana-supply = <&pm8953_l22>;
- cam_vaf-supply = <&pm8953_l17>;
- qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
- "cam_vaf";
- qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
- qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
- qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ qcom,cam-vreg-name = "cam_vana";
+ qcom,cam-vreg-min-voltage = <2800000>;
+ qcom,cam-vreg-max-voltage = <2800000>;
+ qcom,cam-vreg-op-mode = <80000>;
qcom,gpio-no-mux = <0>;
+
pinctrl-names = "cam_default", "cam_suspend";
pinctrl-0 = <&cam_sensor_mclk1_default
- &cam_sensor_front1_default>;
+ &cam_sensor_front1_default
+ &cam_sensor_front1_vdig_default
+ &cam_sensor_front1_vio_default>;
pinctrl-1 = <&cam_sensor_mclk1_sleep
- &cam_sensor_front1_sleep>;
+ &cam_sensor_front1_sleep
+ &cam_sensor_front1_vdig_sleep
+ &cam_sensor_front1_vio_sleep>;
+
gpios = <&tlmm 27 0>,
- <&tlmm 129 0>,
- <&tlmm 130 0>;
+ <&tlmm 129 0>,
+ <&tlmm 46 0>,
+ <&tlmm 130 0>;
qcom,gpio-reset = <1>;
- qcom,gpio-standby = <2>;
- qcom,gpio-req-tbl-num = <0 1 2>;
- qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-vdig = <2>;
+ qcom,gpio-vio = <3>;
+ qcom,gpio-req-tbl-num = <0 1 2 3>;
+ qcom,gpio-req-tbl-flags = <1 0 0 0>;
qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
- "CAM_RESET2",
- "CAM_STANDBY2";
+ "CAM_RESET2",
+ "CAM_VDIG2",
+ "CAM_VIO2";
+
qcom,sensor-position = <1>;
qcom,sensor-mode = <0>;
qcom,cci-master = <1>;
status = "ok";
- clocks = <&clock_gcc clk_mclk1_clk_src>,
- <&clock_gcc clk_gcc_camss_mclk1_clk>;
clock-names = "cam_src_clk", "cam_clk";
+ clocks = <&clock_gcc clk_mclk1_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk1_clk>;
qcom,clock-rates = <24000000 0>;
};
};
diff --git a/arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi b/arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi
old mode 100644
new mode 100755
index fa218ca..a4f4851
--- a/arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi
@@ -28,6 +28,8 @@
#include "dsi-panel-boent51021-1200p-video.dtsi"
#include "dsi-panel-hx8394d-wxga-video.dtsi"
#include "dsi-panel-inxnt51021-1200p-video.dtsi"
+#include "dsi-hx83112b-truly-1080p-video.dtsi"
+#include "dsi-hx83112b-djn-1080p-cmd.dtsi"
&soc {
dsi_panel_pwr_supply: dsi_panel_pwr_supply {
@@ -71,6 +73,32 @@
};
};
+&dsi_hx83112b_truly_1080p_video {
+ qcom,mdss-dsi-panel-timings-phy-v2 = [24 1e 08 09 05 03 04 a0
+ 24 1e 08 09 05 03 04 a0
+ 24 1e 08 09 05 03 04 a0
+ 24 1e 08 09 05 03 04 a0
+ 24 1a 08 09 05 03 04 a0];
+ qcom,mdss-dsi-min-refresh-rate = <48>;
+ qcom,mdss-dsi-max-refresh-rate = <60>;
+ qcom,mdss-dsi-pan-enable-dynamic-fps;
+ qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp";
+ qcom,mdss-dsi-panel-status-command-state = "dsi_hs_mode";
+};
+
+&dsi_djn_hx83112b_1080p_cmd {
+ qcom,mdss-dsi-panel-timings-phy-v2 = [24 1e 08 09 05 03 04 a0
+ 24 1e 08 09 05 03 04 a0
+ 24 1e 08 09 05 03 04 a0
+ 24 1e 08 09 05 03 04 a0
+ 24 1a 08 09 05 03 04 a0];
+ qcom,mdss-dsi-min-refresh-rate = <48>;
+ qcom,mdss-dsi-max-refresh-rate = <60>;
+ qcom,mdss-dsi-pan-enable-dynamic-fps;
+ qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp";
+ qcom,mdss-dsi-panel-status-command-state = "dsi_hs_mode";
+};
+
&dsi_truly_1080_vid {
qcom,mdss-dsi-panel-timings-phy-v2 = [23 1e 08 09 05 03 04 a0
23 1e 08 09 05 03 04 a0
diff --git a/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi
old mode 100644
new mode 100755
index 69cf52e..71c68d5
--- a/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi
@@ -44,7 +44,7 @@
qcom,nq-ven = <&tlmm 16 0x00>;
qcom,nq-firm = <&tlmm 62 0x00>;
qcom,nq-clkreq = <&pm8953_gpios 2 0x00>;
- qcom,nq-esepwr = <&tlmm 141 0x00>;
+ qcom,nq-esepwr = <&tlmm 134 0x00>;
interrupt-parent = <&tlmm>;
qcom,clk-src = "BBCLK2";
interrupts = <17 0>;
@@ -58,6 +58,30 @@
};
};
+&i2c_6 { /* BLSP2 QUP2 (smart amp) */
+ status = "ok";
+ /* AWINIC AW8898 Smart PA */
+ aw8898_smartpa@34{
+ compatible = "awinic,aw8898_smartpa";
+ reg = <0x34>;
+ reset-gpio = <&tlmm 21 0>;
+ irq-gpio = <&tlmm 20 0>;
+ status = "okay";
+ };
+ /* AWINIC AW8898 Smart PA End */
+
+ tas2557@4c {
+ sound-dai-cells = <1>;
+ compatible = "ti,tas2557";
+ reg = <0x4c>;
+ ti,cdc-reset-gpio = <&tlmm 21 0>;
+ ti,irq-gpio = <&tlmm 20 0>;
+ ti,i2s-bits = <16>;
+ ti,bypass-tmax = <0>;
+ status = "ok";
+ };
+};
+
&sdhc_1 {
/* device core power supply */
vdd-supply = <&pm8953_l8>;
@@ -127,14 +151,18 @@
};
&mdss_dsi0 {
+ #if 1
+ qcom,dsi-pref-prim-pan = <&dsi_djn_hx83112b_1080p_cmd>;
+ #else
qcom,dsi-pref-prim-pan = <&dsi_truly_1080_vid>;
+ #endif
pinctrl-names = "mdss_default", "mdss_sleep";
pinctrl-0 = <&mdss_dsi_active &mdss_te_active>;
pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>;
qcom,platform-te-gpio = <&tlmm 24 0>;
- qcom,platform-reset-gpio = <&tlmm 61 0>;
- qcom,platform-bklight-en-gpio = <&tlmm 59 0>;
+ qcom,platform-reset-gpio = <&tlmm 61 0>;
+ qcom,platform-bklight-en-gpio = <&tlmm 96 0>;
};
&mdss_dsi1 {
@@ -150,6 +178,20 @@
qcom,platform-bklight-en-gpio = <&tlmm 59 0>;
};
+&dsi_hx83112b_truly_1080p_video {
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs";
+ qcom,mdss-dsi-bl-min-level = <1>;
+ qcom,mdss-dsi-bl-max-level = <4095>;
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+};
+
+&dsi_djn_hx83112b_1080p_cmd {
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs";
+ qcom,mdss-dsi-bl-min-level = <1>;
+ qcom,mdss-dsi-bl-max-level = <4095>;
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+};
+
&dsi_truly_1080_vid {
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
qcom,mdss-dsi-pan-enable-dynamic-fps;
diff --git a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi
old mode 100644
new mode 100755
index 9da42f9..fd31fc9
--- a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi
@@ -50,32 +50,6 @@
bias-pull-down;
};
};
-
- uart1_console_active: uart1_console_active {
- mux {
- pins = "gpio20", "gpio21";
- function = "blsp_uart6";
- };
-
- config {
- pins = "gpio20", "gpio21";
- drive-strength = <2>;
- bias-disable;
- };
- };
-
- uart1_console_sleep: uart1_console_sleep {
- mux {
- pins = "gpio20", "gpio21";
- function = "blsp_uart6";
- };
-
- config {
- pins = "gpio20", "gpio21";
- drive-strength = <2>;
- bias-pull-down;
- };
- };
};
cci {
cci0_active: cci0_active {
@@ -118,7 +92,7 @@
config {
pins = "gpio31", "gpio32";
- drive-strength = <2>; /* 2 MA */
+ drive-strength = <4>; /* 4 MA */
bias-disable; /* No PULL */
};
};
@@ -229,12 +203,12 @@
cam_sensor_rear_vana: cam_sensor_rear_vdig {
/* VDIG */
mux {
- pins = "gpio134";
+ pins = "gpio128";
function = "gpio";
};
config {
- pins = "gpio134";
+ pins = "gpio128";
bias-disable; /* No PULL */
drive-strength = <2>; /* 2 MA */
};
@@ -243,12 +217,12 @@
cam_sensor_rear_vana_sleep: cam_sensor_rear_vdig_sleep {
/* VDIG */
mux {
- pins = "gpio134";
+ pins = "gpio128";
function = "gpio";
};
config {
- pins = "gpio134";
+ pins = "gpio128";
bias-disable; /* No PULL */
drive-strength = <2>; /* 2 MA */
};
@@ -265,7 +239,7 @@
config {
pins = "gpio27";
bias-disable; /* No PULL */
- drive-strength = <2>; /* 2 MA */
+ drive-strength = <8>; /* 8 MA */
};
};
@@ -342,15 +316,71 @@
};
};
- cam_sensor_front1_default: cam_sensor_front1_default {
- /* RESET, STANDBY */
+ cam_sensor_front1_vio_default: cam_sensor_front1_vio_default {
+ /* CAM IOVDD */
mux {
- pins = "gpio129", "gpio130";
+ pins = "gpio130";
function = "gpio";
};
config {
- pins = "gpio129", "gpio130";
+ pins = "gpio130";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_front1_vio_sleep: cam_sensor_front1_vio_sleep {
+ /* CAM IOVDD */
+ mux {
+ pins = "gpio130";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio130";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_front1_vdig_default: cam_sensor_front1_vdig_default {
+ /* CAM DVDD */
+ mux {
+ pins = "gpio46";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio46";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_front1_vdig_sleep: cam_sensor_front1_vdig_sleep {
+ /* CAM DVDD */
+ mux {
+ pins = "gpio46";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio46";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_front1_default: cam_sensor_front1_default {
+ /* RESET, STANDBY */
+ mux {
+ pins = "gpio129"; /* Only Reset,Non-standby GPIO */
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio129"; /* Only Reset,Non-standby GPIO */
bias-disable; /* No PULL */
drive-strength = <2>; /* 2 MA */
};
@@ -359,12 +389,12 @@
cam_sensor_front1_sleep: cam_sensor_front1_sleep {
/* RESET, STANDBY */
mux {
- pins = "gpio129", "gpio130";
+ pins = "gpio129"; /* Only Reset,Non-standby GPIO */
function = "gpio";
};
config {
- pins = "gpio129", "gpio130";
+ pins = "gpio129"; /* Only Reset,Non-standby GPIO */
bias-disable; /* No PULL */
drive-strength = <2>; /* 2 MA */
};
@@ -399,15 +429,70 @@
};
- pmx_mdss: pmx_mdss {
- mdss_dsi_active: mdss_dsi_active {
+ fps {
+ fps_int_active: fps_int_active {
mux {
- pins = "gpio61", "gpio59";
+ pins = "gpio48";
function = "gpio";
};
config {
- pins = "gpio61", "gpio59";
+ pins = "gpio48";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+ };
+
+ fps_int_suspend: fps_int_suspend {
+ mux {
+ pins = "gpio48";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio48";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ };
+
+ fps_reset_active: fps_reset_active {
+ mux {
+ pins = "gpio140";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio140";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+ };
+
+ fps_reset_suspend1: fps_reset_suspend1 {
+ mux {
+ pins = "gpio140";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio140";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ };
+ };
+
+ pmx_mdss: pmx_mdss {
+
+ mdss_dsi_active: mdss_dsi_active {
+ mux {
+ pins = "gpio61", "gpio96";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio61", "gpio96";
drive-strength = <8>; /* 8 mA */
bias-disable = <0>; /* no pull */
output-high;
@@ -416,16 +501,17 @@
mdss_dsi_suspend: mdss_dsi_suspend {
mux {
- pins = "gpio61", "gpio59";
+ pins = "gpio61", "gpio96";
function = "gpio";
};
config {
- pins = "gpio61", "gpio59";
+ pins = "gpio61", "gpio96";
drive-strength = <2>; /* 2 mA */
bias-pull-down; /* pull down */
};
};
+
mdss_dsi_gpio: mdss_dsi_gpio {
mux {
pins = "gpio141";
@@ -628,32 +714,6 @@
};
};
- blsp2_uart1_active: blsp2_uart1_active {
- mux {
- pins = "gpio20", "gpio21", "gpio22", "gpio23";
- function = "blsp_uart6";
- };
-
- config {
- pins = "gpio20", "gpio21", "gpio22", "gpio23";
- drive-strength = <16>;
- bias-disable;
- };
- };
-
- blsp2_uart1_sleep: blsp2_uart1_sleep {
- mux {
- pins = "gpio20", "gpio21", "gpio22", "gpio23";
- function = "gpio";
- };
-
- config {
- pins = "gpio20", "gpio21", "gpio22", "gpio23";
- drive-strength = <2>;
- bias-disable;
- };
- };
-
/* SDC pin type */
sdc1_clk_on: sdc1_clk_on {
config {
@@ -908,6 +968,36 @@
};
};
+ i2c_6 {
+ i2c_6_active: i2c_6_active {
+ /* active state */
+ mux {
+ pins = "gpio22", "gpio23";
+ function = "blsp_i2c6";
+ };
+
+ config {
+ pins = "gpio22", "gpio23";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ i2c_6_sleep: i2c_6_sleep {
+ /* suspended state */
+ mux {
+ pins = "gpio22", "gpio23";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio22", "gpio23";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+ };
+
nfc {
nfc_int_active: nfc_int_active {
/* active state */
@@ -943,13 +1033,13 @@
/* active state */
mux {
/* 16: NFC ENABLE 62: FW DNLD */
- /* 141: ESE Enable */
- pins = "gpio16", "gpio62", "gpio141";
+ /* 134: ESE Enable */
+ pins = "gpio16", "gpio62", "gpio134";
function = "gpio";
};
config {
- pins = "gpio16", "gpio62", "gpio141";
+ pins = "gpio16", "gpio62", "gpio134";
drive-strength = <2>; /* 2 MA */
bias-pull-up;
};
@@ -959,13 +1049,13 @@
/* sleep state */
mux {
/* 16: NFC ENABLE 62: FW DNLD */
- /* 141: ESE Enable */
- pins = "gpio16", "gpio62", "gpio141";
+ /* 134: ESE Enable */
+ pins = "gpio16", "gpio62", "gpio134";
function = "gpio";
};
config {
- pins = "gpio16", "gpio62", "gpio141";
+ pins = "gpio16", "gpio62", "gpio134";
drive-strength = <2>; /* 2 MA */
bias-disable;
};
@@ -1198,35 +1288,6 @@
};
};
- cross-conn-det {
- cross_conn_det_act: lines_on {
- mux {
- pins = "gpio63";
- function = "gpio";
- };
-
- config {
- pins = "gpio63";
- drive-strength = <8>;
- output-low;
- bias-pull-down;
- };
- };
-
- cross_conn_det_sus: lines_off {
- mux {
- pins = "gpio63";
- function = "gpio";
- };
-
- config {
- pins = "gpio63";
- drive-strength = <2>;
- bias-pull-down;
- };
- };
- };
-
/* WSA VI sense */
wsa-vi {
wsa_vi_on: wsa_vi_on {
@@ -1260,12 +1321,10 @@
wsa_reset {
wsa_reset_on: wsa_reset_on {
mux {
- pins = "gpio96";
function = "gpio";
};
config {
- pins = "gpio96";
drive-strength = <2>; /* 2 MA */
output-high;
};
@@ -1273,14 +1332,12 @@
wsa_reset_off: wsa_reset_off {
mux {
- pins = "gpio96";
function = "gpio";
};
config {
- pins = "gpio96";
drive-strength = <2>; /* 2 MA */
- output-low;
+ output-high;
};
};
};
@@ -1318,24 +1375,24 @@
pri-tlmm-lines {
pri_tlmm_lines_act: pri_tlmm_lines_act {
mux {
- pins = "gpio91", "gpio93";
+ pins = "gpio91", "gpio93", "gpio88";
function = "pri_mi2s";
};
config {
- pins = "gpio91", "gpio93";
+ pins = "gpio91", "gpio93", "gpio88";
drive-strength = <8>;
};
};
pri_tlmm_lines_sus: pri_tlmm_lines_sus {
mux {
- pins = "gpio91", "gpio93";
+ pins = "gpio91", "gpio93", "gpio88";
function = "pri_mi2s";
};
config {
- pins = "gpio91", "gpio93";
+ pins = "gpio91", "gpio93", "gpio88";
drive-strength = <2>;
bias-pull-down;
};
@@ -1369,126 +1426,6 @@
};
};
- spi3 {
- spi3_default: spi3_default {
- /* active state */
- mux {
- /* MOSI, MISO, CLK */
- pins = "gpio8", "gpio9", "gpio11";
- function = "blsp_spi3";
- };
-
- config {
- pins = "gpio8", "gpio9", "gpio11";
- drive-strength = <12>; /* 12 MA */
- bias-disable = <0>; /* No PULL */
- };
- };
-
- spi3_sleep: spi3_sleep {
- /* suspended state */
- mux {
- /* MOSI, MISO, CLK */
- pins = "gpio8", "gpio9", "gpio11";
- function = "gpio";
- };
-
- config {
- pins = "gpio8", "gpio9", "gpio11";
- drive-strength = <2>; /* 2 MA */
- bias-pull-down; /* PULL Down */
- };
- };
-
- spi3_cs0_active: cs0_active {
- /* CS */
- mux {
- pins = "gpio10";
- function = "blsp_spi3";
- };
-
- config {
- pins = "gpio10";
- drive-strength = <2>;
- bias-disable = <0>;
- };
- };
-
- spi3_cs0_sleep: cs0_sleep {
- /* CS */
- mux {
- pins = "gpio10";
- function = "gpio";
- };
-
- config {
- pins = "gpio10";
- drive-strength = <2>;
- bias-disable = <0>;
- };
- };
- };
-
- spi6 {
- spi6_default: spi6_default {
- /* active state */
- mux {
- /* MOSI, MISO, CLK */
- pins = "gpio20", "gpio21", "gpio23";
- function = "blsp_spi6";
- };
-
- config {
- pins = "gpio20", "gpio21", "gpio23";
- drive-strength = <12>; /* 12 MA */
- bias-disable = <0>; /* No PULL */
- };
- };
-
- spi6_sleep: spi6_sleep {
- /* suspended state */
- mux {
- /* MOSI, MISO, CLK */
- pins = "gpio20", "gpio21", "gpio23";
- function = "gpio";
- };
-
- config {
- pins = "gpio20", "gpio21", "gpio23";
- drive-strength = <2>; /* 2 MA */
- bias-pull-down; /* PULL Down */
- };
- };
-
- spi6_cs0_active: cs0_active {
- /* CS */
- mux {
- pins = "gpio22";
- function = "blsp_spi6";
- };
-
- config {
- pins = "gpio22";
- drive-strength = <2>;
- bias-disable = <0>;
- };
- };
-
- spi6_cs0_sleep: cs0_sleep {
- /* CS */
- mux {
- pins = "gpio22";
- function = "gpio";
- };
-
- config {
- pins = "gpio22";
- drive-strength = <2>;
- bias-disable = <0>;
- };
- };
- };
-
/* add pingrp for touchscreen */
ts_int_default: ts_int_default {
mux {
diff --git a/arch/arm64/boot/dts/qcom/msm8953-wsa881x.dtsi b/arch/arm64/boot/dts/qcom/msm8953-wsa881x.dtsi
old mode 100644
new mode 100755
index 86f5323..00521c4
--- a/arch/arm64/boot/dts/qcom/msm8953-wsa881x.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-wsa881x.dtsi
@@ -20,27 +20,27 @@
#size-cells = <0>;
wsa881x_211: wsa881x@20170211 {
+ status = "disabled";
compatible = "qcom,wsa881x";
reg = <0x00 0x20170211>;
- qcom,spkr-sd-n-gpio = <&tlmm 96 0>;
};
wsa881x_212: wsa881x@20170212 {
+ status = "disabled";
compatible = "qcom,wsa881x";
reg = <0x00 0x20170212>;
- qcom,spkr-sd-n-gpio = <&tlmm 96 0>;
};
wsa881x_213: wsa881x@21170213 {
+ status = "disabled";
compatible = "qcom,wsa881x";
reg = <0x00 0x21170213>;
- qcom,spkr-sd-n-gpio = <&tlmm 96 0>;
};
wsa881x_214: wsa881x@21170214 {
+ status = "disabled";
compatible = "qcom,wsa881x";
reg = <0x00 0x21170214>;
- qcom,spkr-sd-n-gpio = <&tlmm 96 0>;
};
};
};
diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi
old mode 100644
new mode 100755
index 1d78b6b..5f11113
--- a/arch/arm64/boot/dts/qcom/msm8953.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi
@@ -42,7 +42,7 @@
compatible = "android,firmware";
vbmeta {
compatible = "android,vbmeta";
- parts = "vbmeta,boot,system,vendor,dtbo,recovery";
+ parts = "vbmeta,boot,system,vendor,dtbo";
};
fstab {
@@ -52,7 +52,7 @@
dev = "/dev/block/platform/soc/7824900.sdhci/by-name/vendor";
type = "ext4";
mnt_flags = "ro,barrier=1,discard";
- fsmgr_flags = "wait,avb";
+ fsmgr_flags = "wait,slotselect,avb";
status = "ok";
};
@@ -188,8 +188,7 @@
i2c2 = &i2c_2;
i2c3 = &i2c_3;
i2c5 = &i2c_5;
- spi3 = &spi_3;
- spi6 = &spi_6;
+ i2c6 = &i2c_6;
};
soc: soc {
@@ -625,42 +624,6 @@
status = "disabled";
};
- blsp2_uart1: uart@7af0000 {
- compatible = "qcom,msm-hsuart-v14";
- reg = <0x7af0000 0x200>,
- <0x7ac4000 0x1f000>;
- reg-names = "core_mem", "bam_mem";
-
- interrupt-names = "core_irq", "bam_irq", "wakeup_irq";
- #address-cells = <0>;
- interrupt-parent = <&blsp2_uart1>;
- interrupts = <0 1 2>;
- #interrupt-cells = <1>;
- interrupt-map-mask = <0xffffffff>;
- interrupt-map = <0 &intc 0 307 0
- 1 &intc 0 239 0
- 2 &tlmm 21 0>;
-
- qcom,inject-rx-on-wakeup;
- qcom,rx-char-to-inject = <0xFD>;
- qcom,master-id = <84>;
- clock-names = "core_clk", "iface_clk";
- clocks = <&clock_gcc clk_gcc_blsp2_uart2_apps_clk>,
- <&clock_gcc clk_gcc_blsp2_ahb_clk>;
- pinctrl-names = "sleep", "default";
- pinctrl-0 = <&blsp2_uart1_sleep>;
- pinctrl-1 = <&blsp2_uart1_active>;
- qcom,bam-tx-ep-pipe-index = <2>;
- qcom,bam-rx-ep-pipe-index = <3>;
- qcom,msm-bus,name = "blsp2_uart1";
- qcom,msm-bus,num-cases = <2>;
- qcom,msm-bus,num-paths = <1>;
- qcom,msm-bus,vectors-KBps =
- <84 512 0 0>,
- <84 512 500 800>;
- status = "disabled";
- };
-
blsp1_serial1: serial@78b0000 {
compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
reg = <0x78b0000 0x200>;
@@ -687,58 +650,6 @@
qcom,summing-threshold = <10>;
};
- spi_3: spi@78b7000 { /* BLSP1 QUP3 */
- compatible = "qcom,spi-qup-v2";
- #address-cells = <1>;
- #size-cells = <0>;
- reg-names = "spi_physical", "spi_bam_physical";
- reg = <0x78b7000 0x600>,
- <0x7884000 0x1f000>;
- interrupt-names = "spi_irq", "spi_bam_irq";
- interrupts = <0 97 0>, <0 238 0>;
- spi-max-frequency = <19200000>;
- pinctrl-names = "spi_default", "spi_sleep";
- pinctrl-0 = <&spi3_default &spi3_cs0_active>;
- pinctrl-1 = <&spi3_sleep &spi3_cs0_sleep>;
- clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
- <&clock_gcc clk_gcc_blsp1_qup3_spi_apps_clk>;
- clock-names = "iface_clk", "core_clk";
- qcom,infinite-mode = <0>;
- qcom,use-bam;
- qcom,use-pinctrl;
- qcom,ver-reg-exists;
- qcom,bam-consumer-pipe-index = <8>;
- qcom,bam-producer-pipe-index = <9>;
- qcom,master-id = <86>;
- status = "disabled";
- };
-
- spi_6: spi@7af6000 { /* BLSP2 QUP2 */
- compatible = "qcom,spi-qup-v2";
- #address-cells = <1>;
- #size-cells = <0>;
- reg-names = "spi_physical", "spi_bam_physical";
- reg = <0x7af6000 0x600>,
- <0x7ac4000 0x1f000>;
- interrupt-names = "spi_irq", "spi_bam_irq";
- interrupts = <0 300 0>, <0 239 0>;
- spi-max-frequency = <19200000>;
- pinctrl-names = "spi_default", "spi_sleep";
- pinctrl-0 = <&spi6_default &spi6_cs0_active>;
- pinctrl-1 = <&spi6_sleep &spi6_cs0_sleep>;
- clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>,
- <&clock_gcc clk_gcc_blsp2_qup2_spi_apps_clk>;
- clock-names = "iface_clk", "core_clk";
- qcom,infinite-mode = <0>;
- qcom,use-bam;
- qcom,use-pinctrl;
- qcom,ver-reg-exists;
- qcom,bam-consumer-pipe-index = <6>;
- qcom,bam-producer-pipe-index = <7>;
- qcom,master-id = <84>;
- status = "disabled";
- };
-
i2c_1: i2c@78b5000 { /* BLSP1 QUP1 */
compatible = "qcom,i2c-msm-v2";
#address-cells = <1>;
@@ -813,7 +724,7 @@
dmas = <&dma_blsp1 8 64 0x20000020 0x20>,
<&dma_blsp1 9 32 0x20000020 0x20>;
dma-names = "tx", "rx";
- status = "disabled";
+ status = "ok";
};
i2c_5: i2c@7af5000 { /* BLSP2 QUP1 */
@@ -842,6 +753,32 @@
status = "disabled";
};
+ i2c_6: i2c@7af6000 { /* BLSP2 QUP2 */
+ compatible = "qcom,i2c-msm-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "qup_phys_addr";
+ reg = <0x7af6000 0x600>;
+ interrupt-names = "qup_irq";
+ interrupts = <0 300 0>;
+ qcom,clk-freq-out = <400000>;
+ qcom,clk-freq-in = <19200000>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>,
+ <&clock_gcc clk_gcc_blsp2_qup2_i2c_apps_clk>;
+
+ pinctrl-names = "i2c_active", "i2c_sleep";
+ pinctrl-0 = <&i2c_6_active>;
+ pinctrl-1 = <&i2c_6_sleep>;
+ qcom,noise-rjct-scl = <0>;
+ qcom,noise-rjct-sda = <0>;
+ qcom,master-id = <84>;
+ dmas = <&dma_blsp2 6 64 0x20000020 0x20>,
+ <&dma_blsp2 7 32 0x20000020 0x20>;
+ dma-names = "tx", "rx";
+ status = "ok";
+ };
+
slim_msm: slim@c140000{
cell-index = <1>;
compatible = "qcom,slim-ngd";
@@ -2319,3 +2256,14 @@
&gdsc_usb30 {
status = "okay";
};
+
+&soc {
+ elan {
+ compatible = "elan,elan_fp";
+ interrupt-parent = <&tlmm>;
+ interrupts = <48 0>;
+ elan,irq-gpio = <&tlmm 48 0>;
+ elan,rst-gpio = <&tlmm 140 0>;
+ elan,vdd-gpio = <&tlmm 90 0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/pmi632.dtsi b/arch/arm64/boot/dts/qcom/pmi632.dtsi
old mode 100644
new mode 100755
index 6919e74..ab3b369
--- a/arch/arm64/boot/dts/qcom/pmi632.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmi632.dtsi
@@ -314,7 +314,7 @@
qcom,pmic-revid = <&pmi632_revid>;
dpdm-supply = <&qusb_phy>;
- qcom,auto-recharge-soc = <98>;
+ qcom,auto-recharge-vbat-mv = <4300>;
qcom,chg-vadc = <&pmi632_vadc>;
qcom,flash-disable-soc = <10>;
qcom,sw-jeita-enable;
@@ -324,9 +324,11 @@
qcom,connector-internal-pull-kohm = <100>;
qcom,thermal-mitigation
- = <3000000 2500000 2000000 1500000
- 1000000 500000>;
+ = <2000000 1500000 1000000 500000
+ 500000 500000>;
+ qcom,chg-term-src = <1>;
+ qcom,chg-term-current-ma = <(-100)>;
qcom,chgr@1000 {
reg = <0x1000 0x100>;
interrupts =
@@ -483,9 +485,7 @@
#address-cells = <1>;
#size-cells = <1>;
- qcom,qg-iterm-ma = <100>;
- qcom,hold-soc-while-full;
- qcom,linearize-soc;
+ qcom,qg-iterm-ma = <150>;
qcom,qg-vadc = <&pmi632_vadc>;
qcom,pmic-revid = <&pmi632_revid>;
@@ -565,29 +565,35 @@
nvmem = <&pmi632_sdam7>;
qcom,pbs-client = <&pmi632_pbs_client3>;
qcom,lut-sdam-base = <0x80>;
- qcom,lut-patterns = <0 0 0 14 28 42 56 70 84 100
- 100 84 70 56 42 28 14 0 0 0>;
+ qcom,lut-patterns = <0 0 0 0 0 0 0 0 2 16 30 44 58 72 86 96 100 100
+ 100 100 96 86 72 58 44 30 16 2 0 0 0 0 0 0 0 0>;
lpg@1 {
qcom,lpg-chan-id = <1>;
- qcom,ramp-step-ms = <200>;
+ qcom,ramp-step-ms = <60>;
+ qcom,ramp-pause-hi-count = <80>;
+ qcom,ramp-pause-lo-count = <80>;
qcom,ramp-low-index = <0>;
- qcom,ramp-high-index = <19>;
+ qcom,ramp-high-index = <35>;
qcom,ramp-pattern-repeat;
qcom,lpg-sdam-base = <0x48>;
};
lpg@2 {
qcom,lpg-chan-id = <2>;
- qcom,ramp-step-ms = <200>;
+ qcom,ramp-step-ms = <60>;
+ qcom,ramp-pause-hi-count = <80>;
+ qcom,ramp-pause-lo-count = <80>;
qcom,ramp-low-index = <0>;
- qcom,ramp-high-index = <19>;
+ qcom,ramp-high-index = <35>;
qcom,ramp-pattern-repeat;
qcom,lpg-sdam-base = <0x56>;
};
lpg@3 {
qcom,lpg-chan-id = <3>;
- qcom,ramp-step-ms = <200>;
+ qcom,ramp-step-ms = <60>;
+ qcom,ramp-pause-hi-count = <80>;
+ qcom,ramp-pause-lo-count = <80>;
qcom,ramp-low-index = <0>;
- qcom,ramp-high-index = <19>;
+ qcom,ramp-high-index = <35>;
qcom,ramp-pattern-repeat;
qcom,lpg-sdam-base = <0x64>;
};
diff --git a/arch/arm64/boot/dts/qcom/qg-batterydata-Fuji-3000mah-Jan22th2019-pmi632.dtsi b/arch/arm64/boot/dts/qcom/qg-batterydata-Fuji-3000mah-Jan22th2019-pmi632.dtsi
new file mode 100755
index 0000000..c3655c0
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qg-batterydata-Fuji-3000mah-Jan22th2019-pmi632.dtsi
@@ -0,0 +1,1049 @@
+/* Copyright (c) 2018, 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.
+ */
+qcom,batterydata_fuji_3000mah {
+ /* 3804571_Arima_8901_Fuji_3000mAH_FG_averaged_MasterSlave_Jan22th2019 */
+ qcom,max-voltage-uv = <4390000>;
+ qcom,v-cutoff-uv = <3400000>;
+ qcom,fg-cc-cv-threshold-mv = <4380>;
+
+ qcom,fcc-max-ua = <2000000>;
+ qcom,fastchg-current-ma = <2000>;
+ qcom,chg-term-ua = <100000>;
+
+ qcom,batt-id-kohm = <10>;
+ qcom,battery-beta = <4100>;
+ qcom,battery-therm-kohm = <100>;
+ qcom,battery-type =
+ "Fuji_3000mAH_FG_averaged_MasterSlave_Jan22th2019";
+ qcom,qg-batt-profile-ver = <100>;
+
+ qcom,jeita-fcc-ranges = <0 150 600000
+ 151 400 2000000
+ 401 450 1500000
+ 451 550 1000000
+ 551 600 0>;
+ qcom,jeita-fv-ranges = <0 150 4400000
+ 151 400 4400000
+ 401 450 4400000
+ 451 550 4100000
+ 551 600 3300000>;
+
+ /* COOL = 15 DegC, WARM = 45 DegC */
+ qcom,jeita-soft-thresholds = <0x44FF 0x2204>;
+ /* COLD = 0 DegC, HOT = 55 DegC */
+ qcom,jeita-hard-thresholds = <0x5675 0x1987>;
+
+ qcom,fcc1-temp-lut {
+ qcom,lut-col-legend = <0 10 25 40 50>;
+ qcom,lut-data = <2865 2966 3060 3122 3139>;
+ };
+
+ qcom,fcc2-temp-lut {
+ qcom,lut-col-legend = <(-10) 0 10 25 40 50>;
+ qcom,lut-data = <2964 3062 3085 3043 3073 3084>;
+ };
+
+ qcom,pc-temp-v1-lut {
+ qcom,lut-col-legend = <0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200>,
+ <9000 8800 8600 8400 8200>,
+ <8000 7800 7600 7400 7200>,
+ <7000 6800 6600 6400 6200>,
+ <6000 5800 5600 5400 5200>,
+ <5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200>,
+ <3000 2800 2600 2400 2200>,
+ <2000 1800 1600 1400 1200>,
+ <1000 900 800 700 600>,
+ <500 400 300 200 100>,
+ <0>;
+ qcom,lut-data = <43284 43531 43756 43842 43863>,
+ <43035 43269 43533 43627 43647>,
+ <42788 43017 43288 43406 43431>,
+ <42545 42778 43048 43178 43209>,
+ <42307 42546 42811 42943 42981>,
+ <42074 42313 42575 42706 42747>,
+ <41845 42081 42342 42469 42511>,
+ <41622 41854 42110 42233 42274>,
+ <41406 41630 41881 42000 42041>,
+ <41204 41411 41654 41770 41809>,
+ <41011 41204 41429 41542 41580>,
+ <40801 41011 41212 41319 41355>,
+ <40550 40819 41007 41100 41134>,
+ <40289 40612 40807 40887 40921>,
+ <40063 40394 40602 40682 40712>,
+ <39865 40195 40395 40484 40510>,
+ <39698 40019 40206 40294 40315>,
+ <39558 39864 40038 40115 40132>,
+ <39432 39730 39880 39943 39960>,
+ <39303 39606 39725 39775 39791>,
+ <39169 39484 39573 39617 39628>,
+ <39039 39364 39419 39446 39459>,
+ <38920 39243 39268 39205 39244>,
+ <38809 39118 39104 38925 38987>,
+ <38706 38995 38900 38754 38801>,
+ <38609 38886 38687 38657 38686>,
+ <38521 38792 38545 38574 38589>,
+ <38447 38703 38445 38490 38487>,
+ <38383 38606 38368 38410 38392>,
+ <38327 38500 38306 38331 38306>,
+ <38279 38414 38255 38252 38230>,
+ <38236 38348 38214 38183 38160>,
+ <38195 38294 38182 38127 38101>,
+ <38155 38248 38148 38074 38045>,
+ <38115 38208 38113 38025 37991>,
+ <38070 38172 38076 37979 37937>,
+ <38019 38140 38037 37930 37877>,
+ <37980 38104 37995 37880 37810>,
+ <37979 38053 37936 37818 37735>,
+ <37989 37979 37842 37732 37651>,
+ <37954 37885 37727 37624 37556>,
+ <37853 37750 37609 37504 37443>,
+ <37727 37596 37477 37366 37307>,
+ <37570 37437 37322 37204 37147>,
+ <37405 37295 37175 37057 36996>,
+ <37275 37197 37079 36975 36913>,
+ <37228 37152 37054 36955 36894>,
+ <37187 37128 37032 36940 36880>,
+ <37145 37096 37015 36923 36865>,
+ <37083 37054 36984 36882 36824>,
+ <36912 36900 36821 36673 36613>,
+ <36504 36491 36441 36265 36205>,
+ <35936 35949 35916 35716 35662>,
+ <35181 35220 35209 34971 34929>,
+ <33991 34089 34155 33851 33829>,
+ <30000 30000 30000 30000 30000>;
+ };
+
+ qcom,pc-temp-v2-lut {
+ qcom,lut-col-legend = <(-10) 0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>,
+ <8800 8600 8400 8200 8000 7800>,
+ <7600 7400 7200 7000 6800 6600>,
+ <6400 6200 6000 5800 5600 5400>,
+ <5200 5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200 3000>,
+ <2800 2600 2400 2200 2000 1800>,
+ <1600 1400 1200 1000 900 800>,
+ <700 600 500 400 300 200>,
+ <100 0>;
+ qcom,lut-data = <43865 43810 43785 43700 43675 43665>,
+ <43445 43386 43420 43374 43403 43411>,
+ <43061 43012 43087 43074 43142 43164>,
+ <42715 42699 42792 42806 42895 42924>,
+ <42400 42432 42528 42566 42661 42693>,
+ <42116 42193 42275 42331 42430 42462>,
+ <41856 41988 42029 42097 42198 42230>,
+ <41623 41789 41786 41867 41968 41999>,
+ <41426 41533 41519 41640 41739 41772>,
+ <41256 41231 41242 41417 41512 41547>,
+ <41083 41027 41055 41200 41291 41325>,
+ <40887 40937 40957 40990 41076 41108>,
+ <40674 40843 40851 40786 40867 40894>,
+ <40418 40575 40624 40587 40663 40690>,
+ <40052 40115 40304 40393 40464 40490>,
+ <39703 39807 40049 40214 40273 40298>,
+ <39484 39642 39853 40060 40089 40112>,
+ <39316 39494 39659 39905 39915 39934>,
+ <39146 39312 39445 39713 39757 39769>,
+ <38969 39122 39229 39495 39604 39604>,
+ <38801 38939 39031 39277 39409 39409>,
+ <38645 38757 38848 39052 39154 39173>,
+ <38500 38588 38674 38846 38924 38957>,
+ <38379 38430 38503 38682 38751 38779>,
+ <38282 38292 38345 38540 38606 38627>,
+ <38200 38194 38221 38416 38483 38503>,
+ <38126 38119 38122 38305 38376 38396>,
+ <38060 38053 38050 38204 38281 38299>,
+ <37997 37990 37995 38111 38195 38209>,
+ <37934 37932 37946 38024 38116 38126>,
+ <37873 37874 37900 37951 38038 38051>,
+ <37814 37818 37859 37886 37961 37982>,
+ <37757 37761 37815 37830 37889 37918>,
+ <37698 37702 37770 37782 37823 37860>,
+ <37639 37642 37721 37740 37760 37795>,
+ <37579 37580 37669 37699 37692 37701>,
+ <37519 37515 37611 37658 37622 37590>,
+ <37460 37451 37548 37613 37546 37491>,
+ <37397 37386 37478 37553 37467 37405>,
+ <37332 37321 37398 37482 37384 37323>,
+ <37263 37258 37299 37394 37300 37242>,
+ <37188 37195 37188 37281 37202 37148>,
+ <37104 37132 37077 37156 37078 37026>,
+ <37008 37062 36981 37012 36935 36888>,
+ <36897 36973 36906 36861 36810 36769>,
+ <36753 36865 36836 36801 36780 36742>,
+ <36665 36812 36803 36782 36767 36730>,
+ <36551 36742 36771 36769 36750 36716>,
+ <36416 36637 36719 36736 36721 36684>,
+ <36223 36466 36610 36679 36634 36594>,
+ <35963 36186 36375 36502 36349 36303>,
+ <35623 35770 35979 36106 35895 35839>,
+ <35148 35191 35403 35552 35295 35244>,
+ <34444 34358 34580 34813 34488 34441>,
+ <33312 33033 33293 33745 33316 33316>,
+ <31012 30090 30748 31936 31165 30645>;
+ };
+
+ qcom,pc-temp-z1-lut {
+ qcom,lut-col-legend = <0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200>,
+ <9000 8800 8600 8400 8200>,
+ <8000 7800 7600 7400 7200>,
+ <7000 6800 6600 6400 6200>,
+ <6000 5800 5600 5400 5200>,
+ <5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200>,
+ <3000 2800 2600 2400 2200>,
+ <2000 1800 1600 1400 1200>,
+ <1000 900 800 700 600>,
+ <500 400 300 200 100>,
+ <0>;
+ qcom,lut-data = <17054 15240 13662 12757 12408>,
+ <17124 15229 13698 12768 12438>,
+ <17016 15219 13668 12726 12417>,
+ <16914 15183 13617 12701 12397>,
+ <16838 15155 13583 12668 12382>,
+ <16744 15143 13558 12638 12370>,
+ <16640 15093 13528 12609 12359>,
+ <16529 15012 13482 12590 12352>,
+ <16427 14931 13442 12580 12348>,
+ <16342 14856 13422 12574 12346>,
+ <16264 14788 13406 12572 12345>,
+ <16170 14704 13400 12569 12346>,
+ <16019 14604 13414 12569 12347>,
+ <15850 14481 13431 12570 12349>,
+ <15738 14362 13422 12573 12352>,
+ <15657 14330 13401 12574 12355>,
+ <15581 14346 13398 12577 12358>,
+ <15496 14373 13416 12581 12363>,
+ <15420 14400 13430 12589 12368>,
+ <15369 14430 13439 12596 12373>,
+ <15329 14464 13455 12602 12378>,
+ <15295 14511 13473 12609 12383>,
+ <15264 14559 13503 12615 12389>,
+ <15235 14602 13523 12621 12394>,
+ <15225 14639 13527 12629 12400>,
+ <15259 14663 13531 12640 12409>,
+ <15299 14691 13544 12651 12418>,
+ <15307 14724 13572 12661 12427>,
+ <15298 14758 13586 12672 12435>,
+ <15297 14796 13584 12682 12444>,
+ <15325 14832 13582 12692 12454>,
+ <15372 14866 13587 12702 12463>,
+ <15403 14897 13616 12713 12472>,
+ <15419 14941 13638 12726 12481>,
+ <15435 15005 13645 12741 12490>,
+ <15466 15037 13651 12757 12499>,
+ <15533 15047 13666 12768 12508>,
+ <15611 15059 13689 12775 12517>,
+ <15713 15086 13712 12783 12525>,
+ <15815 15129 13745 12797 12534>,
+ <15877 15157 13778 12814 12544>,
+ <15962 15156 13793 12827 12553>,
+ <16018 15159 13807 12840 12562>,
+ <16054 15244 13834 12856 12571>,
+ <16139 15219 13861 12870 12581>,
+ <16155 15207 13872 12888 12593>,
+ <16128 15182 13833 12892 12600>,
+ <16123 15232 13881 12902 12605>,
+ <16064 15224 13854 12918 12610>,
+ <16159 15224 13885 12928 12621>,
+ <16206 15263 13908 12947 12632>,
+ <16240 15262 13928 12953 12645>,
+ <16304 15324 13949 12982 12663>,
+ <16264 15364 13995 13019 12688>,
+ <16264 15364 13995 13019 12688>,
+ <16264 15364 13995 13019 12688>;
+ };
+
+ qcom,pc-temp-z2-lut {
+ qcom,lut-col-legend = <0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200>,
+ <9000 8800 8600 8400 8200>,
+ <8000 7800 7600 7400 7200>,
+ <7000 6800 6600 6400 6200>,
+ <6000 5800 5600 5400 5200>,
+ <5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200>,
+ <3000 2800 2600 2400 2200>,
+ <2000 1800 1600 1400 1200>,
+ <1000 900 800 700 600>,
+ <500 400 300 200 100>,
+ <0>;
+ qcom,lut-data = <9350 9754 9949 10368 10349>,
+ <9479 9908 10066 10325 10322>,
+ <9559 9989 10154 10384 10464>,
+ <9616 10006 10169 10359 10507>,
+ <9660 10015 10160 10338 10448>,
+ <9687 10030 10125 10312 10406>,
+ <9695 10019 10096 10277 10379>,
+ <9698 9989 10087 10254 10355>,
+ <9700 9988 10091 10245 10335>,
+ <9700 9993 10097 10241 10323>,
+ <9699 9995 10102 10249 10325>,
+ <9700 9986 10105 10264 10316>,
+ <9712 9970 10090 10274 10298>,
+ <9728 9962 10066 10285 10271>,
+ <9739 9951 10067 10291 10260>,
+ <9746 9935 10080 10269 10272>,
+ <9748 9920 10092 10244 10286>,
+ <9730 9905 10101 10251 10287>,
+ <9701 9875 10113 10278 10301>,
+ <9681 9840 10131 10302 10317>,
+ <9655 9822 10159 10343 10330>,
+ <9630 9813 10191 10378 10342>,
+ <9617 9809 10233 10329 10330>,
+ <9607 9828 10258 10225 10299>,
+ <9604 9858 10240 10187 10291>,
+ <9606 9862 10214 10182 10339>,
+ <9607 9842 10211 10192 10409>,
+ <9605 9825 10202 10281 10482>,
+ <9593 9853 10196 10410 10548>,
+ <9580 9988 10211 10450 10534>,
+ <9575 10068 10236 10463 10429>,
+ <9569 10061 10257 10460 10363>,
+ <9553 10046 10276 10423 10353>,
+ <9505 10042 10293 10391 10352>,
+ <9460 10041 10308 10400 10381>,
+ <9448 10041 10319 10429 10460>,
+ <9448 10044 10324 10456 10531>,
+ <9447 10049 10328 10483 10597>,
+ <9421 10058 10333 10510 10636>,
+ <9375 10076 10351 10539 10644>,
+ <9330 10095 10369 10563 10643>,
+ <9274 10114 10376 10558 10608>,
+ <9238 10135 10380 10536 10508>,
+ <9214 10156 10366 10535 10521>,
+ <9259 10180 10386 10536 10557>,
+ <9240 10062 10415 10512 10526>,
+ <9254 10173 10397 10455 10497>,
+ <9279 9874 10392 10437 10496>,
+ <9290 9778 10398 10442 10527>,
+ <9293 9745 10432 10482 10608>,
+ <9286 9862 10424 10564 10552>,
+ <9238 10014 10422 10498 10451>,
+ <9256 9882 10280 10429 10345>,
+ <9197 9773 10194 10309 10327>,
+ <9197 9773 10194 10309 10327>,
+ <9197 9773 10194 10309 10327>;
+ };
+
+ qcom,pc-temp-z3-lut {
+ qcom,lut-col-legend = <0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200>,
+ <9000 8800 8600 8400 8200>,
+ <8000 7800 7600 7400 7200>,
+ <7000 6800 6600 6400 6200>,
+ <6000 5800 5600 5400 5200>,
+ <5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200>,
+ <3000 2800 2600 2400 2200>,
+ <2000 1800 1600 1400 1200>,
+ <1000 900 800 700 600>,
+ <500 400 300 200 100>,
+ <0>;
+ qcom,lut-data = <19799 19569 19396 19351 19342>,
+ <19912 19746 19493 19399 19368>,
+ <19966 19815 19586 19441 19391>,
+ <19983 19811 19632 19464 19415>,
+ <19985 19772 19643 19476 19423>,
+ <19980 19735 19646 19481 19427>,
+ <19971 19703 19645 19484 19429>,
+ <19953 19677 19638 19484 19428>,
+ <19929 19656 19629 19474 19421>,
+ <19904 19637 19622 19459 19409>,
+ <19879 19613 19614 19447 19401>,
+ <19855 19584 19603 19437 19392>,
+ <19832 19555 19583 19429 19384>,
+ <19811 19527 19565 19424 19376>,
+ <19797 19502 19554 19418 19371>,
+ <19788 19486 19545 19407 19369>,
+ <19778 19477 19534 19397 19367>,
+ <19759 19468 19520 19394 19363>,
+ <19734 19452 19507 19392 19356>,
+ <19712 19435 19500 19392 19352>,
+ <19692 19424 19494 19394 19354>,
+ <19675 19418 19494 19397 19356>,
+ <19660 19414 19497 19400 19356>,
+ <19647 19456 19499 19403 19354>,
+ <19637 19525 19503 19401 19351>,
+ <19629 19538 19508 19385 19344>,
+ <19622 19532 19509 19374 19339>,
+ <19614 19525 19505 19375 19359>,
+ <19605 19550 19502 19379 19396>,
+ <19596 19670 19499 19394 19406>,
+ <19586 19740 19497 19431 19405>,
+ <19574 19731 19496 19445 19403>,
+ <19563 19717 19495 19440 19396>,
+ <19552 19703 19494 19431 19385>,
+ <19539 19688 19496 19423 19378>,
+ <19523 19671 19498 19413 19371>,
+ <19505 19648 19497 19408 19369>,
+ <19488 19627 19493 19406 19371>,
+ <19457 19610 19490 19404 19373>,
+ <19409 19596 19488 19402 19373>,
+ <19364 19591 19485 19401 19371>,
+ <19319 19593 19484 19398 19367>,
+ <19308 19595 19482 19395 19360>,
+ <19312 19583 19473 19395 19361>,
+ <19289 19511 19455 19391 19362>,
+ <19288 19392 19434 19372 19348>,
+ <19287 19411 19424 19366 19342>,
+ <19283 19309 19418 19359 19339>,
+ <19281 19283 19366 19356 19334>,
+ <19281 19281 19345 19353 19329>,
+ <19281 19311 19408 19343 19338>,
+ <19288 19382 19391 19345 19344>,
+ <19284 19387 19369 19346 19352>,
+ <19293 19386 19360 19355 19342>,
+ <19293 19386 19360 19355 19342>,
+ <19293 19386 19360 19355 19342>;
+ };
+
+ qcom,pc-temp-z4-lut {
+ qcom,lut-col-legend = <0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200>,
+ <9000 8800 8600 8400 8200>,
+ <8000 7800 7600 7400 7200>,
+ <7000 6800 6600 6400 6200>,
+ <6000 5800 5600 5400 5200>,
+ <5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200>,
+ <3000 2800 2600 2400 2200>,
+ <2000 1800 1600 1400 1200>,
+ <1000 900 800 700 600>,
+ <500 400 300 200 100>,
+ <0>;
+ qcom,lut-data = <17587 16958 15547 15139 15017>,
+ <17976 16963 15776 15093 14962>,
+ <17856 16883 15807 15147 14959>,
+ <17670 16658 15582 15132 14987>,
+ <17371 16377 15400 15029 14926>,
+ <17004 16165 15259 14955 14873>,
+ <16727 15984 15149 14898 14833>,
+ <16521 15829 15064 14854 14802>,
+ <16352 15706 14994 14820 14782>,
+ <16206 15607 14932 14796 14767>,
+ <16076 15526 14876 14782 14755>,
+ <15991 15453 14840 14772 14747>,
+ <15948 15394 14819 14761 14740>,
+ <15916 15360 14805 14747 14732>,
+ <15878 15335 14797 14737 14722>,
+ <15812 15316 14791 14732 14711>,
+ <15741 15300 14784 14728 14699>,
+ <15679 15285 14769 14720 14691>,
+ <15628 15271 14754 14705 14684>,
+ <15613 15258 14746 14699 14680>,
+ <15616 15248 14740 14697 14679>,
+ <15621 15240 14739 14696 14680>,
+ <15628 15229 14743 14759 14721>,
+ <15635 15172 14751 14896 14839>,
+ <15641 15093 14811 14935 14887>,
+ <15651 15073 14906 14927 14882>,
+ <15665 15073 14932 14916 14872>,
+ <15674 15071 14939 14897 14836>,
+ <15678 15038 14941 14868 14777>,
+ <15680 14913 14928 14830 14746>,
+ <15677 14839 14904 14778 14728>,
+ <15671 14839 14881 14751 14717>,
+ <15668 14839 14855 14743 14709>,
+ <15665 14837 14830 14739 14705>,
+ <15662 14828 14808 14740 14706>,
+ <15662 14818 14790 14743 14712>,
+ <15662 14807 14776 14747 14721>,
+ <15653 14796 14764 14750 14737>,
+ <15602 14787 14762 14754 14748>,
+ <15521 14779 14776 14760 14747>,
+ <15466 14774 14789 14764 14743>,
+ <15431 14773 14783 14761 14737>,
+ <15379 14772 14770 14749 14728>,
+ <15284 14765 14766 14746 14727>,
+ <15126 14773 14749 14739 14724>,
+ <15091 14844 14714 14701 14695>,
+ <15083 14814 14704 14690 14684>,
+ <15073 14915 14690 14674 14662>,
+ <15060 14935 14729 14654 14644>,
+ <15049 14929 14743 14656 14648>,
+ <15047 14898 14697 14703 14670>,
+ <15089 14864 14750 14712 14672>,
+ <15142 14893 14793 14714 14664>,
+ <15193 14919 14820 14707 14678>,
+ <15193 14919 14820 14707 14678>,
+ <15193 14919 14820 14707 14678>;
+ };
+
+ qcom,pc-temp-z5-lut {
+ qcom,lut-col-legend = <0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200>,
+ <9000 8800 8600 8400 8200>,
+ <8000 7800 7600 7400 7200>,
+ <7000 6800 6600 6400 6200>,
+ <6000 5800 5600 5400 5200>,
+ <5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200>,
+ <3000 2800 2600 2400 2200>,
+ <2000 1800 1600 1400 1200>,
+ <1000 900 800 700 600>,
+ <500 400 300 200 100>,
+ <0>;
+ qcom,lut-data = <11358 11494 11908 12557 13389>,
+ <11833 12183 12842 14487 15070>,
+ <12405 12614 13565 15212 16202>,
+ <13059 12845 14214 15154 15974>,
+ <13839 13016 14733 15844 16391>,
+ <14725 13243 15142 16503 17010>,
+ <15596 13561 15530 17246 17748>,
+ <16428 13923 15943 17791 18190>,
+ <17232 14315 16465 18116 18220>,
+ <18038 14676 17422 18276 18181>,
+ <18865 14865 18877 18272 18221>,
+ <19674 14984 19625 18249 18128>,
+ <20431 15072 19727 18334 17870>,
+ <21130 15054 19828 18929 17679>,
+ <21810 14893 20358 19394 17847>,
+ <22506 14672 21207 19043 18615>,
+ <23103 14352 21538 18592 19519>,
+ <23615 13980 21561 18936 19805>,
+ <24007 13586 21664 20345 19853>,
+ <24079 13189 22550 21969 20033>,
+ <23879 12900 24359 24356 21912>,
+ <23551 12671 26666 26933 24174>,
+ <23128 12532 29984 28811 24236>,
+ <22573 16009 33223 30302 22786>,
+ <22055 21616 36917 29852 20806>,
+ <21614 22839 40896 23931 17498>,
+ <21164 22782 41274 18905 15329>,
+ <20626 22748 37726 17548 16139>,
+ <19994 24693 34208 16813 18506>,
+ <19350 32731 32197 17946 20729>,
+ <18718 37419 30660 22928 22860>,
+ <18080 37241 29522 27156 24796>,
+ <17492 36724 28389 30069 26670>,
+ <16942 35950 27991 31898 28277>,
+ <16419 34643 29482 32339 29267>,
+ <15905 32897 31269 32587 29981>,
+ <15355 29571 32211 32574 30108>,
+ <14748 26352 33439 31949 29477>,
+ <13625 25160 33934 30921 28421>,
+ <12198 24457 33717 28597 26596>,
+ <11393 24278 33374 25720 24194>,
+ <10921 27010 32613 24473 22458>,
+ <10794 29096 30844 23817 21101>,
+ <10850 27893 27612 23152 20368>,
+ <11132 22763 26589 22273 20057>,
+ <11208 13720 25644 21579 19840>,
+ <11175 14905 22757 20915 19343>,
+ <11126 11694 21938 20443 21124>,
+ <11126 11332 15067 22031 23038>,
+ <11136 11316 13648 21640 21325>,
+ <11203 11811 21336 16010 17501>,
+ <11383 13311 15695 14689 17028>,
+ <11284 12864 13476 14307 17977>,
+ <11138 12491 12651 14501 15692>,
+ <11138 12491 12651 14501 15692>,
+ <11138 12491 12651 14501 15692>;
+ };
+
+ qcom,pc-temp-z6-lut {
+ qcom,lut-col-legend = <0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200>,
+ <9000 8800 8600 8400 8200>,
+ <8000 7800 7600 7400 7200>,
+ <7000 6800 6600 6400 6200>,
+ <6000 5800 5600 5400 5200>,
+ <5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200>,
+ <3000 2800 2600 2400 2200>,
+ <2000 1800 1600 1400 1200>,
+ <1000 900 800 700 600>,
+ <500 400 300 200 100>,
+ <0>;
+ qcom,lut-data = <18743 17091 15593 15023 14880>,
+ <18832 17074 15694 15021 14873>,
+ <18667 17018 15717 15055 14880>,
+ <18442 16858 15615 15051 14899>,
+ <18182 16642 15523 15006 14876>,
+ <17900 16469 15442 14972 14854>,
+ <17667 16323 15372 14945 14837>,
+ <17477 16198 15314 14920 14821>,
+ <17311 16093 15265 14896 14807>,
+ <17163 16004 15224 14877 14794>,
+ <17028 15920 15186 14864 14785>,
+ <16900 15837 15158 14853 14777>,
+ <16781 15757 15140 14844 14769>,
+ <16675 15682 15125 14836 14761>,
+ <16585 15617 15114 14828 14754>,
+ <16505 15585 15104 14820 14748>,
+ <16434 15572 15094 14813 14743>,
+ <16368 15564 15082 14807 14737>,
+ <16311 15560 15073 14802 14731>,
+ <16274 15557 15071 14800 14728>,
+ <16252 15557 15069 14801 14729>,
+ <16234 15561 15069 14804 14732>,
+ <16218 15568 15075 14834 14752>,
+ <16204 15580 15086 14895 14802>,
+ <16195 15595 15118 14912 14821>,
+ <16195 15605 15163 14904 14818>,
+ <16200 15611 15177 14894 14813>,
+ <16204 15619 15181 14886 14809>,
+ <16206 15631 15183 14880 14805>,
+ <16209 15650 15178 14876 14800>,
+ <16213 15665 15171 14875 14794>,
+ <16218 15672 15165 14872 14788>,
+ <16222 15677 15156 14868 14781>,
+ <16226 15679 15150 14864 14776>,
+ <16231 15679 15146 14862 14775>,
+ <16239 15678 15144 14861 14776>,
+ <16249 15673 15143 14861 14778>,
+ <16254 15669 15144 14863 14787>,
+ <16253 15670 15145 14866 14794>,
+ <16249 15674 15157 14871 14794>,
+ <16257 15680 15169 14875 14794>,
+ <16286 15693 15172 14875 14791>,
+ <16316 15704 15173 14872 14786>,
+ <16342 15708 15173 14873 14787>,
+ <16325 15691 15169 14872 14788>,
+ <16317 15673 15152 14851 14771>,
+ <16313 15670 15145 14844 14764>,
+ <16314 15661 15139 14835 14754>,
+ <16312 15666 15131 14827 14744>,
+ <16314 15671 15133 14830 14745>,
+ <16332 15687 15154 14849 14762>,
+ <16363 15720 15177 14859 14770>,
+ <16400 15752 15199 14867 14775>,
+ <16456 15793 15224 14878 14780>,
+ <16456 15793 15224 14878 14780>,
+ <16456 15793 15224 14878 14780>;
+ };
+
+ qcom,pc-temp-y1-lut {
+ qcom,lut-col-legend = <(-10) 0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>,
+ <8800 8600 8400 8200 8000 7800>,
+ <7600 7400 7200 7000 6800 6600>,
+ <6400 6200 6000 5800 5600 5400>,
+ <5200 5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200 3000>,
+ <2800 2600 2400 2200 2000 1800>,
+ <1600 1400 1200 1000 900 800>,
+ <700 600 500 400 300 200>,
+ <100 0>;
+ qcom,lut-data = <8808 7810 7119 6408 5842 5630>,
+ <8786 7775 7119 6399 5837 5635>,
+ <8736 7762 7115 6384 5832 5636>,
+ <8678 7760 7110 6366 5827 5636>,
+ <8629 7765 7105 6351 5820 5634>,
+ <8607 7767 7104 6346 5814 5631>,
+ <8601 7778 7101 6343 5808 5626>,
+ <8591 7794 7099 6340 5801 5619>,
+ <8582 7787 7102 6338 5795 5615>,
+ <8573 7757 7116 6335 5790 5611>,
+ <8570 7745 7124 6331 5785 5608>,
+ <8624 7765 7127 6328 5779 5606>,
+ <8727 7788 7126 6326 5774 5605>,
+ <8752 7789 7127 6327 5770 5604>,
+ <8709 7780 7131 6333 5768 5603>,
+ <8675 7786 7134 6341 5767 5603>,
+ <8674 7825 7137 6350 5771 5603>,
+ <8678 7854 7137 6359 5774 5605>,
+ <8683 7852 7147 6363 5774 5607>,
+ <8693 7848 7161 6366 5773 5609>,
+ <8706 7850 7165 6372 5774 5612>,
+ <8744 7872 7164 6387 5778 5614>,
+ <8799 7893 7165 6399 5784 5617>,
+ <8812 7904 7178 6400 5791 5621>,
+ <8806 7914 7197 6400 5800 5626>,
+ <8795 7914 7204 6407 5807 5630>,
+ <8773 7885 7208 6428 5812 5636>,
+ <8743 7863 7210 6443 5819 5641>,
+ <8735 7872 7220 6445 5827 5646>,
+ <8759 7886 7233 6445 5834 5652>,
+ <8772 7888 7234 6446 5843 5659>,
+ <8759 7882 7226 6449 5852 5665>,
+ <8766 7881 7224 6454 5862 5672>,
+ <8792 7916 7232 6468 5871 5679>,
+ <8813 7964 7241 6486 5880 5686>,
+ <8815 7988 7255 6492 5888 5692>,
+ <8814 8004 7277 6497 5894 5697>,
+ <8836 8004 7284 6502 5901 5702>,
+ <8866 7958 7264 6515 5912 5708>,
+ <8906 7919 7248 6530 5925 5714>,
+ <8961 7936 7272 6538 5941 5722>,
+ <8999 7955 7306 6561 5956 5731>,
+ <9030 7948 7304 6572 5971 5741>,
+ <9138 7971 7313 6570 5991 5752>,
+ <9293 8063 7376 6564 6002 5762>,
+ <9280 8096 7390 6587 6025 5773>,
+ <9284 8110 7390 6636 6033 5780>,
+ <9320 8108 7371 6593 6049 5787>,
+ <9330 8116 7400 6614 6059 5790>,
+ <9393 8172 7426 6617 6073 5796>,
+ <9703 8314 7410 6624 6079 5798>,
+ <9758 8346 7470 6622 6098 5814>,
+ <9705 8401 7565 6635 6133 5835>,
+ <10044 8597 7580 6686 6162 5853>,
+ <10044 8597 7580 6686 6162 5853>,
+ <10044 8597 7580 6686 6162 5853>;
+ };
+
+ qcom,pc-temp-y2-lut {
+ qcom,lut-col-legend = <(-10) 0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>,
+ <8800 8600 8400 8200 8000 7800>,
+ <7600 7400 7200 7000 6800 6600>,
+ <6400 6200 6000 5800 5600 5400>,
+ <5200 5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200 3000>,
+ <2800 2600 2400 2200 2000 1800>,
+ <1600 1400 1200 1000 900 800>,
+ <700 600 500 400 300 200>,
+ <100 0>;
+ qcom,lut-data = <9675 9851 9914 10743 11138 11081>,
+ <9669 9878 9974 10737 11099 11049>,
+ <9666 9917 10046 10731 11053 11013>,
+ <9667 9967 10118 10726 11008 10976>,
+ <9670 10024 10176 10721 10968 10946>,
+ <9677 10089 10208 10716 10940 10925>,
+ <9780 10167 10219 10712 10918 10911>,
+ <9972 10248 10230 10708 10901 10901>,
+ <10034 10326 10320 10707 10889 10894>,
+ <10038 10403 10526 10711 10878 10888>,
+ <10042 10429 10594 10717 10875 10888>,
+ <10180 10418 10528 10741 10888 10901>,
+ <10405 10407 10470 10772 10910 10922>,
+ <10410 10441 10537 10793 10939 10952>,
+ <10025 10548 10688 10814 10981 10998>,
+ <9694 10633 10768 10844 11028 11051>,
+ <9679 10703 10805 10909 11082 11129>,
+ <9679 10742 10840 10969 11141 11206>,
+ <9679 10736 10890 10994 11214 11272>,
+ <9677 10717 10932 11012 11286 11322>,
+ <9675 10674 10922 11016 11287 11314>,
+ <9674 10440 10844 11003 11197 11231>,
+ <9672 10221 10781 10994 11134 11160>,
+ <9670 10009 10759 11001 11138 11131>,
+ <9669 9764 10742 11020 11147 11115>,
+ <9668 9717 10681 11032 11159 11129>,
+ <9667 9704 10412 11038 11174 11163>,
+ <9667 9696 10242 11039 11192 11197>,
+ <9666 9690 10281 11029 11245 11226>,
+ <9666 9685 10329 11015 11312 11253>,
+ <9665 9681 10171 11007 11347 11291>,
+ <9664 9676 9906 10994 11376 11370>,
+ <9664 9673 9790 10983 11380 11454>,
+ <9663 9671 9739 10978 11359 11538>,
+ <9663 9669 9708 10974 11332 11581>,
+ <9662 9668 9690 10971 11303 11512>,
+ <9662 9666 9679 10963 11266 11359>,
+ <9661 9665 9674 10949 11229 11276>,
+ <9661 9664 9670 10923 11193 11241>,
+ <9660 9663 9668 10883 11153 11227>,
+ <9659 9662 9666 10838 11111 11226>,
+ <9658 9661 9665 10778 11067 11210>,
+ <9656 9661 9664 10708 11026 11160>,
+ <9655 9660 9662 10622 10943 11138>,
+ <9654 9659 9662 10228 10911 11078>,
+ <9653 9658 9660 10125 10831 10967>,
+ <9653 9657 9659 10114 10830 10950>,
+ <9653 9657 9659 10273 10823 11000>,
+ <9652 9656 9658 10052 10816 10977>,
+ <9651 9655 9658 10003 10819 10980>,
+ <9650 9653 9657 9927 10781 10944>,
+ <9650 9652 9656 9774 10694 10866>,
+ <9649 9650 9654 9711 10638 10811>,
+ <9648 9648 9651 9680 10579 10795>,
+ <9648 9648 9651 9680 10579 10795>,
+ <9648 9648 9651 9680 10579 10795>;
+ };
+
+ qcom,pc-temp-y3-lut {
+ qcom,lut-col-legend = <(-10) 0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>,
+ <8800 8600 8400 8200 8000 7800>,
+ <7600 7400 7200 7000 6800 6600>,
+ <6400 6200 6000 5800 5600 5400>,
+ <5200 5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200 3000>,
+ <2800 2600 2400 2200 2000 1800>,
+ <1600 1400 1200 1000 900 800>,
+ <700 600 500 400 300 200>,
+ <100 0>;
+ qcom,lut-data = <14144 13709 13581 13347 13296 13282>,
+ <14059 13689 13577 13349 13297 13282>,
+ <13977 13665 13573 13351 13298 13283>,
+ <13900 13641 13566 13353 13299 13284>,
+ <13833 13622 13559 13355 13301 13285>,
+ <13778 13611 13551 13357 13302 13286>,
+ <13735 13607 13542 13359 13304 13287>,
+ <13700 13604 13531 13360 13306 13289>,
+ <13663 13576 13516 13360 13306 13290>,
+ <13615 13504 13494 13359 13305 13292>,
+ <13577 13472 13473 13357 13305 13293>,
+ <13559 13471 13452 13353 13308 13293>,
+ <13546 13471 13439 13349 13311 13294>,
+ <13545 13467 13441 13347 13311 13297>,
+ <13547 13457 13444 13346 13310 13301>,
+ <13549 13448 13443 13345 13308 13302>,
+ <13548 13440 13428 13347 13305 13301>,
+ <13545 13432 13411 13349 13303 13300>,
+ <13545 13423 13398 13348 13304 13298>,
+ <13546 13414 13385 13342 13306 13294>,
+ <13548 13407 13375 13337 13305 13291>,
+ <13543 13401 13365 13331 13300 13288>,
+ <13530 13397 13359 13326 13296 13285>,
+ <13524 13394 13357 13323 13294 13283>,
+ <13527 13393 13355 13320 13293 13282>,
+ <13532 13396 13344 13318 13292 13282>,
+ <13542 13405 13313 13315 13291 13281>,
+ <13563 13412 13299 13313 13290 13281>,
+ <13584 13417 13311 13314 13292 13281>,
+ <13601 13422 13330 13315 13293 13281>,
+ <13619 13428 13342 13315 13294 13282>,
+ <13646 13438 13352 13315 13294 13282>,
+ <13681 13451 13363 13316 13293 13283>,
+ <13714 13471 13379 13316 13292 13285>,
+ <13744 13493 13393 13317 13291 13287>,
+ <13776 13513 13404 13318 13291 13286>,
+ <13808 13534 13413 13320 13291 13282>,
+ <13840 13557 13426 13322 13291 13280>,
+ <13880 13581 13444 13324 13290 13280>,
+ <13935 13607 13463 13327 13290 13279>,
+ <14003 13634 13478 13327 13291 13280>,
+ <14085 13664 13495 13326 13292 13280>,
+ <14183 13700 13511 13327 13294 13280>,
+ <14296 13732 13519 13329 13294 13281>,
+ <14422 13708 13517 13321 13291 13281>,
+ <14457 13757 13563 13325 13298 13285>,
+ <14503 13801 13590 13331 13304 13289>,
+ <14521 13839 13628 13342 13308 13295>,
+ <14713 13901 13658 13344 13315 13298>,
+ <14935 14010 13687 13353 13319 13301>,
+ <15231 14155 13722 13360 13315 13297>,
+ <15654 14400 13776 13376 13318 13298>,
+ <16286 14815 13917 13404 13325 13302>,
+ <17253 15517 14206 13445 13334 13308>,
+ <17253 15517 14206 13445 13334 13308>,
+ <17253 15517 14206 13445 13334 13308>;
+ };
+
+ qcom,pc-temp-y4-lut {
+ qcom,lut-col-legend = <(-10) 0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>,
+ <8800 8600 8400 8200 8000 7800>,
+ <7600 7400 7200 7000 6800 6600>,
+ <6400 6200 6000 5800 5600 5400>,
+ <5200 5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200 3000>,
+ <2800 2600 2400 2200 2000 1800>,
+ <1600 1400 1200 1000 900 800>,
+ <700 600 500 400 300 200>,
+ <100 0>;
+ qcom,lut-data = <16880 16884 16843 16611 16506 16469>,
+ <17007 16924 16871 16627 16508 16469>,
+ <17093 16973 16919 16648 16510 16469>,
+ <17145 17019 16971 16670 16510 16470>,
+ <17172 17053 17011 16687 16510 16470>,
+ <17179 17065 17025 16693 16510 16470>,
+ <17149 17056 17023 16691 16508 16471>,
+ <17093 17046 17018 16687 16507 16471>,
+ <17094 17059 17011 16687 16508 16472>,
+ <17226 17114 17000 16690 16513 16475>,
+ <17333 17176 17007 16695 16518 16478>,
+ <17293 17260 17141 16712 16521 16484>,
+ <17204 17323 17260 16733 16525 16490>,
+ <17135 17210 17179 16744 16533 16494>,
+ <17035 16910 16999 16752 16549 16497>,
+ <16948 16809 16929 16761 16566 16503>,
+ <16928 16821 16912 16775 16589 16517>,
+ <16919 16831 16893 16785 16611 16536>,
+ <16904 16817 16852 16772 16634 16565>,
+ <16871 16780 16801 16731 16654 16596>,
+ <16843 16747 16757 16685 16645 16593>,
+ <16842 16716 16720 16629 16574 16546>,
+ <16845 16694 16678 16583 16515 16502>,
+ <16850 16683 16617 16562 16493 16476>,
+ <16865 16674 16566 16549 16480 16460>,
+ <16884 16670 16562 16543 16480 16460>,
+ <16890 16668 16600 16542 16487 16466>,
+ <16893 16668 16626 16539 16496 16474>,
+ <16898 16673 16612 16531 16505 16485>,
+ <16914 16680 16593 16518 16515 16497>,
+ <16931 16687 16601 16515 16520 16510>,
+ <16940 16695 16621 16515 16523 16524>,
+ <16946 16700 16638 16515 16526 16533>,
+ <16955 16703 16653 16523 16529 16540>,
+ <16968 16707 16669 16538 16531 16542>,
+ <16987 16715 16686 16553 16526 16525>,
+ <17010 16726 16701 16572 16512 16494>,
+ <17038 16740 16707 16587 16503 16478>,
+ <17075 16758 16709 16598 16496 16471>,
+ <17132 16779 16708 16605 16494 16470>,
+ <17202 16805 16693 16606 16500 16476>,
+ <17280 16832 16672 16605 16509 16481>,
+ <17371 16860 16659 16599 16511 16480>,
+ <17453 16867 16656 16576 16509 16478>,
+ <17499 16793 16648 16557 16478 16450>,
+ <17354 16787 16668 16568 16493 16466>,
+ <17325 16805 16690 16584 16507 16478>,
+ <17230 16828 16716 16599 16525 16487>,
+ <17314 16853 16750 16641 16543 16505>,
+ <17418 16879 16774 16676 16557 16515>,
+ <17579 16937 16765 16673 16529 16487>,
+ <17841 17050 16758 16641 16533 16488>,
+ <18286 17288 16811 16646 16553 16508>,
+ <19246 17929 17050 16675 16600 16553>,
+ <19246 17929 17050 16675 16600 16553>,
+ <19246 17929 17050 16675 16600 16553>;
+ };
+
+ qcom,pc-temp-y5-lut {
+ qcom,lut-col-legend = <(-10) 0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>,
+ <8800 8600 8400 8200 8000 7800>,
+ <7600 7400 7200 7000 6800 6600>,
+ <6400 6200 6000 5800 5600 5400>,
+ <5200 5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200 3000>,
+ <2800 2600 2400 2200 2000 1800>,
+ <1600 1400 1200 1000 900 800>,
+ <700 600 500 400 300 200>,
+ <100 0>;
+ qcom,lut-data = <13349 13500 12008 16323 17921 18586>,
+ <13013 13211 12999 16372 18068 18170>,
+ <13045 13460 14163 16440 18117 17710>,
+ <13320 14144 15309 16514 18105 17265>,
+ <13715 15164 16245 16584 18071 16894>,
+ <14107 16431 16784 16639 18053 16652>,
+ <15410 18600 17088 16695 17996 16513>,
+ <17536 20511 17255 16740 17870 16387>,
+ <18076 19525 16766 16676 17290 16217>,
+ <17054 15658 15346 16346 15850 16011>,
+ <16481 14123 14892 15892 15277 15729>,
+ <19499 17492 16061 14980 15396 15204>,
+ <24621 21017 17812 14144 15517 14821>,
+ <25408 20858 19909 14373 15176 15053>,
+ <19266 19889 22106 15510 14330 15539>,
+ <14011 19657 22597 16782 13917 15522>,
+ <13930 20662 22429 18272 13747 14811>,
+ <14318 21567 22355 19738 13690 14376>,
+ <14451 21644 22492 20874 14676 14378>,
+ <14374 21674 22713 21825 16938 14452>,
+ <14244 21685 22878 22222 19000 15411>,
+ <13814 20618 23037 22357 21260 18677>,
+ <12837 19295 23301 22430 22271 20342>,
+ <12176 16786 23920 22466 21851 20137>,
+ <11864 13808 23986 22484 20993 19645>,
+ <11690 13424 20980 22476 20018 18847>,
+ <11718 13473 14954 22064 18767 17527>,
+ <11839 13487 12836 21697 18243 16702>,
+ <11898 13409 13272 22531 19014 16373>,
+ <11842 13290 13839 24064 20139 16235>,
+ <11799 13214 13911 24209 20558 16295>,
+ <11882 13197 13854 22855 20583 16587>,
+ <12081 13234 13947 21466 20365 17253>,
+ <12245 13308 14112 20300 20058 19153>,
+ <12343 13345 14250 19299 19990 20733>,
+ <12425 13241 14355 18875 20397 20809>,
+ <12521 13059 14473 18615 20909 20171>,
+ <12618 12937 14722 18543 20846 19319>,
+ <12669 12781 15271 18808 19408 18313>,
+ <12666 12638 15669 19097 17814 17411>,
+ <12672 12597 15667 18859 16901 16533>,
+ <12691 12631 15351 17917 16234 15888>,
+ <12643 12878 14521 18213 16069 15695>,
+ <12660 13276 13856 19221 16226 15964>,
+ <12919 13897 13862 16001 18127 19756>,
+ <13276 14032 13814 14924 17294 17122>,
+ <13415 14407 13713 14773 16651 16358>,
+ <13462 14550 14038 15725 15949 16993>,
+ <13362 14718 14211 14276 16288 16750>,
+ <12923 14999 14569 14561 17215 18436>,
+ <12369 14407 14848 14966 18423 20471>,
+ <11893 13109 14633 14660 19769 21365>,
+ <11228 12058 13726 14484 20580 22907>,
+ <10382 11039 12284 14642 21348 24120>,
+ <10382 11039 12284 14642 21348 24120>,
+ <10382 11039 12284 14642 21348 24120>;
+ };
+
+ qcom,pc-temp-y6-lut {
+ qcom,lut-col-legend = <(-10) 0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>,
+ <8800 8600 8400 8200 8000 7800>,
+ <7600 7400 7200 7000 6800 6600>,
+ <6400 6200 6000 5800 5600 5400>,
+ <5200 5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200 3000>,
+ <2800 2600 2400 2200 2000 1800>,
+ <1600 1400 1200 1000 900 800>,
+ <700 600 500 400 300 200>,
+ <100 0>;
+ qcom,lut-data = <7174 6488 5990 5336 5123 5070>,
+ <7088 6443 5977 5337 5122 5071>,
+ <7004 6400 5963 5338 5122 5072>,
+ <6926 6360 5948 5338 5122 5072>,
+ <6857 6324 5931 5338 5121 5073>,
+ <6801 6295 5913 5338 5121 5074>,
+ <6753 6272 5893 5335 5121 5074>,
+ <6715 6251 5872 5331 5120 5075>,
+ <6695 6217 5847 5327 5120 5076>,
+ <6680 6173 5819 5324 5120 5077>,
+ <6668 6156 5812 5323 5120 5078>,
+ <6655 6172 5831 5323 5122 5080>,
+ <6635 6187 5849 5323 5125 5082>,
+ <6610 6157 5830 5323 5128 5085>,
+ <6553 6076 5788 5324 5130 5088>,
+ <6504 6045 5764 5326 5134 5091>,
+ <6492 6044 5753 5332 5138 5095>,
+ <6487 6042 5741 5337 5143 5100>,
+ <6483 6035 5724 5333 5150 5106>,
+ <6479 6023 5705 5318 5157 5112>,
+ <6476 6013 5690 5302 5154 5110>,
+ <6474 6004 5678 5283 5130 5094>,
+ <6471 5997 5668 5269 5111 5079>,
+ <6471 5991 5658 5264 5104 5071>,
+ <6481 5986 5652 5262 5100 5066>,
+ <6497 5988 5652 5262 5100 5066>,
+ <6513 6004 5658 5264 5102 5068>,
+ <6530 6022 5667 5266 5105 5070>,
+ <6549 6037 5688 5268 5110 5074>,
+ <6571 6054 5714 5271 5115 5078>,
+ <6596 6076 5739 5274 5118 5083>,
+ <6624 6104 5768 5281 5120 5088>,
+ <6656 6132 5800 5289 5122 5093>,
+ <6689 6159 5834 5300 5123 5097>,
+ <6723 6188 5870 5315 5124 5099>,
+ <6759 6220 5907 5331 5124 5093>,
+ <6795 6256 5946 5351 5121 5083>,
+ <6833 6291 5985 5373 5121 5078>,
+ <6885 6324 6023 5395 5121 5076>,
+ <6968 6358 6057 5419 5121 5076>,
+ <7077 6396 6083 5441 5126 5079>,
+ <7209 6437 6107 5463 5133 5082>,
+ <7380 6484 6136 5487 5140 5084>,
+ <7573 6535 6166 5510 5144 5084>,
+ <7769 6532 6182 5515 5136 5078>,
+ <7828 6592 6243 5539 5150 5087>,
+ <7890 6644 6283 5566 5161 5094>,
+ <7929 6694 6329 5597 5173 5102>,
+ <8177 6776 6372 5629 5187 5111>,
+ <8470 6929 6419 5671 5197 5116>,
+ <8868 7149 6460 5696 5190 5106>,
+ <9428 7492 6523 5720 5201 5109>,
+ <10244 8043 6746 5788 5225 5121>,
+ <11535 8996 7213 5886 5260 5142>,
+ <11535 8996 7213 5886 5260 5142>,
+ <11535 8996 7213 5886 5260 5142>;
+ };
+
+};
diff --git a/arch/arm64/boot/dts/qcom/qg-batterydata-Kayo-3000mah-Nov4th2019-pmi632.dtsi b/arch/arm64/boot/dts/qcom/qg-batterydata-Kayo-3000mah-Nov4th2019-pmi632.dtsi
new file mode 100755
index 0000000..ce1d887
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qg-batterydata-Kayo-3000mah-Nov4th2019-pmi632.dtsi
@@ -0,0 +1,1038 @@
+
+qcom,4184448_Arima_8902EU_3000mAh {
+ qcom,max-voltage-uv = <4390000>;
+ qcom,v-cutoff-uv = <3400000>;
+ qcom,fg-cc-cv-threshold-mv = <4380>;
+ qcom,fcc-max-ua = <2700000>;
+ qcom,fastchg-current-ma = <2700>;
+ qcom,chg-term-ua = <100000>;
+ qcom,batt-id-kohm = <50>;
+ qcom,battery-beta = <4100>;
+ qcom,battery-therm-kohm = <100>;
+ qcom,battery-type = "Kayo_3000mAh_FG_averaged_MasterSlave_Nov4th2019";
+ qcom,qg-batt-profile-ver = <100>;
+
+ qcom,jeita-fcc-ranges = <0 200 600000
+ 201 400 2700000
+ 401 450 1500000
+ 451 550 1000000
+ 551 600 0>;
+ qcom,jeita-fv-ranges = <0 200 4400000
+ 201 400 4400000
+ 401 450 4400000
+ 451 550 4100000
+ 551 600 3300000>;
+
+ /* COOL = 20 DegC, WARM = 45 DegC */
+ qcom,jeita-soft-thresholds = <0x3EBC 0x2204>;
+ /* COLD = 0 DegC, HOT = 55 DegC */
+ qcom,jeita-hard-thresholds = <0x5675 0x1987>;
+
+ qcom,step-chg-ranges = <3500000 4200000 2700000
+ 4200001 4400000 1500000>;
+
+ qcom,fcc1-temp-lut {
+ qcom,lut-col-legend = <0 10 25 40 50>;
+ qcom,lut-data = <2916 2987 3056 3077 3086>;
+ };
+
+ qcom,fcc2-temp-lut {
+ qcom,lut-col-legend = <(-10) 0 10 25 40 50>;
+ qcom,lut-data = <3049 3044 3049 3058 3057 3057>;
+ };
+
+ qcom,pc-temp-v1-lut {
+ qcom,lut-col-legend = <0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200>,
+ <9000 8800 8600 8400 8200>,
+ <8000 7800 7600 7400 7200>,
+ <7000 6800 6600 6400 6200>,
+ <6000 5800 5600 5400 5200>,
+ <5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200>,
+ <3000 2800 2600 2400 2200>,
+ <2000 1800 1600 1400 1200>,
+ <1000 900 800 700 600>,
+ <500 400 300 200 100>,
+ <0>;
+ qcom,lut-data = <43505 43700 43831 43863 43874>,
+ <43223 43436 43575 43604 43615>,
+ <42972 43181 43325 43357 43374>,
+ <42740 42936 43082 43121 43135>,
+ <42513 42699 42840 42885 42899>,
+ <42290 42465 42600 42648 42664>,
+ <42072 42233 42363 42413 42432>,
+ <41858 42006 42129 42179 42200>,
+ <41647 41788 41899 41947 41970>,
+ <41449 41575 41673 41719 41742>,
+ <41275 41375 41449 41492 41515>,
+ <41102 41200 41240 41272 41292>,
+ <40890 41023 41056 41058 41076>,
+ <40629 40803 40869 40853 40867>,
+ <40376 40537 40638 40648 40663>,
+ <40152 40296 40381 40446 40464>,
+ <39950 40096 40175 40254 40274>,
+ <39795 39922 40019 40078 40095>,
+ <39678 39783 39875 39911 39925>,
+ <39570 39672 39732 39752 39761>,
+ <39450 39550 39589 39601 39607>,
+ <39330 39403 39402 39421 39432>,
+ <39209 39239 39142 39161 39196>,
+ <39089 39046 38910 38917 38962>,
+ <38970 38812 38757 38775 38807>,
+ <38852 38639 38636 38670 38688>,
+ <38735 38538 38540 38571 38578>,
+ <38629 38463 38464 38475 38471>,
+ <38529 38404 38394 38385 38374>,
+ <38442 38358 38325 38300 38288>,
+ <38382 38316 38262 38221 38211>,
+ <38336 38275 38203 38152 38140>,
+ <38298 38238 38150 38094 38075>,
+ <38263 38204 38102 38040 38015>,
+ <38232 38174 38062 37995 37962>,
+ <38200 38141 38025 37953 37911>,
+ <38170 38109 37989 37905 37853>,
+ <38133 38072 37953 37854 37789>,
+ <38079 38016 37902 37791 37717>,
+ <38002 37926 37815 37710 37637>,
+ <37909 37822 37708 37612 37545>,
+ <37785 37705 37596 37502 37437>,
+ <37643 37570 37468 37372 37309>,
+ <37484 37410 37312 37219 37153>,
+ <37344 37263 37166 37074 37009>,
+ <37241 37162 37070 36982 36924>,
+ <37211 37136 37044 36961 36902>,
+ <37186 37117 37031 36946 36887>,
+ <37160 37097 37013 36929 36872>,
+ <37119 37062 36976 36885 36821>,
+ <36940 36869 36767 36648 36564>,
+ <36508 36448 36348 36223 36135>,
+ <35949 35887 35785 35659 35574>,
+ <35193 35123 35019 34892 34806>,
+ <34002 33937 33832 33710 33623>,
+ <30000 30000 30000 30000 30000>;
+ };
+
+ qcom,pc-temp-v2-lut {
+ qcom,lut-col-legend = <(-10) 0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>,
+ <8800 8600 8400 8200 8000 7800>,
+ <7600 7400 7200 7000 6800 6600>,
+ <6400 6200 6000 5800 5600 5400>,
+ <5200 5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200 3000>,
+ <2800 2600 2400 2200 2000 1800>,
+ <1600 1400 1200 1000 900 800>,
+ <700 600 500 400 300 200>,
+ <100 0>;
+ qcom,lut-data = <43915 43870 43850 43820 43770 43750>,
+ <43535 43503 43526 43515 43483 43471>,
+ <43192 43171 43226 43231 43212 43205>,
+ <42893 42880 42955 42969 42957 42954>,
+ <42631 42624 42711 42728 42719 42717>,
+ <42381 42377 42473 42491 42484 42483>,
+ <42137 42128 42235 42256 42250 42250>,
+ <41898 41886 42002 42023 42018 42018>,
+ <41638 41652 41774 41795 41789 41789>,
+ <41360 41423 41550 41569 41563 41564>,
+ <41149 41218 41333 41347 41340 41341>,
+ <41029 41055 41126 41127 41123 41123>,
+ <40908 40891 40923 40915 40910 40909>,
+ <40654 40662 40723 40720 40707 40705>,
+ <40246 40370 40525 40536 40508 40506>,
+ <39909 40095 40311 40337 40316 40315>,
+ <39663 39845 40066 40107 40125 40128>,
+ <39457 39615 39829 39895 39943 39949>,
+ <39287 39422 39645 39742 39778 39783>,
+ <39141 39249 39486 39614 39622 39623>,
+ <38988 39077 39308 39444 39440 39439>,
+ <38821 38900 39097 39205 39217 39219>,
+ <38660 38734 38898 38976 39002 39007>,
+ <38512 38588 38738 38797 38820 38826>,
+ <38375 38456 38599 38642 38658 38665>,
+ <38270 38332 38474 38513 38526 38532>,
+ <38188 38210 38363 38405 38418 38423>,
+ <38118 38110 38263 38308 38321 38325>,
+ <38055 38039 38174 38217 38232 38234>,
+ <37999 37982 38093 38134 38149 38150>,
+ <37947 37935 38016 38061 38075 38074>,
+ <37899 37897 37941 37993 38005 38002>,
+ <37853 37861 37879 37930 37940 37936>,
+ <37805 37827 37835 37869 37884 37880>,
+ <37757 37793 37798 37812 37826 37821>,
+ <37705 37751 37759 37755 37749 37733>,
+ <37651 37702 37720 37698 37652 37610>,
+ <37590 37647 37676 37636 37559 37500>,
+ <37518 37583 37622 37565 37474 37411>,
+ <37439 37509 37558 37488 37392 37328>,
+ <37359 37421 37477 37410 37316 37250>,
+ <37274 37316 37371 37325 37237 37170>,
+ <37195 37197 37249 37215 37129 37062>,
+ <37117 37071 37108 37079 36992 36926>,
+ <37035 36961 36966 36930 36852 36793>,
+ <36948 36867 36890 36881 36816 36763>,
+ <36898 36819 36867 36867 36808 36752>,
+ <36843 36772 36841 36853 36793 36736>,
+ <36764 36701 36805 36823 36765 36710>,
+ <36632 36595 36726 36763 36696 36625>,
+ <36401 36395 36513 36551 36435 36335>,
+ <36034 36017 36066 36101 35970 35860>,
+ <35477 35437 35421 35504 35356 35242>,
+ <34667 34604 34564 34707 34524 34396>,
+ <33357 33266 33270 33533 33299 33148>,
+ <29584 29579 29543 29540 29552 29553>;
+ };
+
+ qcom,pc-temp-z1-lut {
+ qcom,lut-col-legend = <0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200>,
+ <9000 8800 8600 8400 8200>,
+ <8000 7800 7600 7400 7200>,
+ <7000 6800 6600 6400 6200>,
+ <6000 5800 5600 5400 5200>,
+ <5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200>,
+ <3000 2800 2600 2400 2200>,
+ <2000 1800 1600 1400 1200>,
+ <1000 900 800 700 600>,
+ <500 400 300 200 100>,
+ <0>;
+ qcom,lut-data = <14599 13422 12448 12029 11916>,
+ <14539 13426 12442 12038 11932>,
+ <14504 13419 12430 12034 11931>,
+ <14480 13395 12421 12028 11929>,
+ <14463 13354 12410 12025 11928>,
+ <14447 13327 12396 12022 11929>,
+ <14438 13311 12386 12020 11931>,
+ <14441 13299 12379 12020 11932>,
+ <14453 13289 12375 12021 11933>,
+ <14459 13281 12375 12022 11934>,
+ <14440 13277 12379 12022 11935>,
+ <14406 13281 12381 12022 11936>,
+ <14374 13285 12383 12024 11938>,
+ <14335 13275 12384 12027 11941>,
+ <14301 13247 12376 12027 11943>,
+ <14274 13229 12357 12027 11944>,
+ <14252 13221 12352 12027 11946>,
+ <14250 13215 12360 12029 11948>,
+ <14266 13222 12371 12033 11951>,
+ <14280 13248 12379 12036 11953>,
+ <14289 13268 12386 12039 11956>,
+ <14303 13281 12392 12041 11958>,
+ <14310 13291 12397 12042 11960>,
+ <14326 13292 12401 12044 11961>,
+ <14348 13290 12406 12047 11964>,
+ <14369 13290 12412 12053 11968>,
+ <14403 13309 12418 12058 11972>,
+ <14418 13335 12424 12062 11976>,
+ <14390 13338 12430 12067 11981>,
+ <14356 13331 12437 12072 11985>,
+ <14352 13331 12443 12077 11989>,
+ <14358 13341 12450 12082 11992>,
+ <14367 13353 12456 12086 11996>,
+ <14380 13362 12463 12090 12000>,
+ <14397 13370 12471 12095 12003>,
+ <14416 13375 12480 12099 12006>,
+ <14441 13382 12488 12103 12009>,
+ <14462 13391 12496 12106 12011>,
+ <14468 13404 12504 12109 12013>,
+ <14469 13424 12511 12113 12016>,
+ <14474 13437 12519 12117 12019>,
+ <14490 13441 12525 12121 12022>,
+ <14495 13445 12530 12125 12025>,
+ <14477 13454 12538 12128 12028>,
+ <14505 13478 12547 12133 12032>,
+ <14495 13462 12558 12136 12033>,
+ <14465 13457 12554 12138 12034>,
+ <14488 13470 12557 12139 12036>,
+ <14524 13460 12560 12141 12037>,
+ <14513 13470 12566 12144 12040>,
+ <14515 13503 12576 12150 12046>,
+ <14537 13510 12589 12161 12053>,
+ <14588 13546 12611 12175 12068>,
+ <14625 13621 12652 12200 12088>,
+ <14625 13621 12652 12200 12088>,
+ <14625 13621 12652 12200 12088>;
+ };
+
+ qcom,pc-temp-z2-lut {
+ qcom,lut-col-legend = <0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200>,
+ <9000 8800 8600 8400 8200>,
+ <8000 7800 7600 7400 7200>,
+ <7000 6800 6600 6400 6200>,
+ <6000 5800 5600 5400 5200>,
+ <5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200>,
+ <3000 2800 2600 2400 2200>,
+ <2000 1800 1600 1400 1200>,
+ <1000 900 800 700 600>,
+ <500 400 300 200 100>,
+ <0>;
+ qcom,lut-data = <9712 9885 10112 10225 10274>,
+ <9792 9893 10141 10307 10271>,
+ <9825 9895 10133 10369 10364>,
+ <9845 9888 10112 10341 10395>,
+ <9860 9865 10090 10310 10403>,
+ <9873 9846 10063 10269 10370>,
+ <9881 9834 10046 10241 10329>,
+ <9879 9826 10039 10243 10320>,
+ <9870 9826 10036 10252 10316>,
+ <9860 9826 10044 10264 10310>,
+ <9853 9827 10063 10282 10288>,
+ <9843 9840 10079 10296 10267>,
+ <9825 9856 10092 10291 10258>,
+ <9789 9861 10105 10275 10255>,
+ <9767 9862 10122 10264 10264>,
+ <9768 9865 10140 10241 10282>,
+ <9770 9879 10151 10233 10304>,
+ <9776 9901 10158 10243 10333>,
+ <9796 9923 10164 10256 10364>,
+ <9810 9949 10177 10268 10383>,
+ <9805 9965 10195 10282 10398>,
+ <9793 9972 10203 10305 10403>,
+ <9785 9976 10206 10367 10381>,
+ <9781 9978 10206 10419 10355>,
+ <9779 9979 10189 10387 10375>,
+ <9781 9981 10163 10306 10447>,
+ <9788 9986 10160 10287 10494>,
+ <9795 9992 10174 10329 10528>,
+ <9802 9992 10187 10361 10545>,
+ <9807 9989 10205 10357 10449>,
+ <9812 9987 10223 10347 10264>,
+ <9815 9991 10222 10333 10218>,
+ <9819 9997 10208 10311 10224>,
+ <9824 10003 10201 10300 10234>,
+ <9830 10008 10205 10325 10274>,
+ <9838 10014 10212 10371 10343>,
+ <9852 10020 10217 10413 10412>,
+ <9867 10027 10226 10458 10494>,
+ <9881 10036 10238 10490 10530>,
+ <9895 10047 10268 10511 10526>,
+ <9909 10057 10292 10523 10518>,
+ <9922 10062 10289 10521 10514>,
+ <9942 10068 10281 10514 10512>,
+ <9986 10083 10287 10466 10501>,
+ <10168 10194 10324 10440 10492>,
+ <10204 10275 10381 10463 10512>,
+ <10117 10323 10371 10461 10519>,
+ <10078 10427 10370 10454 10521>,
+ <10040 10550 10407 10447 10559>,
+ <10045 10586 10407 10549 10754>,
+ <10031 10491 10568 10539 10410>,
+ <10023 10462 10575 10439 10280>,
+ <9876 10362 10543 10309 10300>,
+ <9730 10231 10462 10272 10258>,
+ <9730 10231 10462 10272 10258>,
+ <9730 10231 10462 10272 10258>;
+ };
+
+ qcom,pc-temp-z3-lut {
+ qcom,lut-col-legend = <0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200>,
+ <9000 8800 8600 8400 8200>,
+ <8000 7800 7600 7400 7200>,
+ <7000 6800 6600 6400 6200>,
+ <6000 5800 5600 5400 5200>,
+ <5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200>,
+ <3000 2800 2600 2400 2200>,
+ <2000 1800 1600 1400 1200>,
+ <1000 900 800 700 600>,
+ <500 400 300 200 100>,
+ <0>;
+ qcom,lut-data = <19803 19568 19401 19348 19348>,
+ <20075 19716 19528 19411 19369>,
+ <20081 19811 19562 19454 19411>,
+ <20062 19834 19578 19464 19433>,
+ <20034 19844 19582 19468 19440>,
+ <19966 19847 19584 19469 19440>,
+ <19907 19848 19584 19470 19440>,
+ <19901 19848 19574 19463 19434>,
+ <19900 19843 19559 19448 19417>,
+ <19900 19825 19547 19436 19406>,
+ <19899 19804 19534 19427 19401>,
+ <19898 19774 19526 19420 19396>,
+ <19910 19745 19516 19414 19385>,
+ <19966 19736 19507 19404 19372>,
+ <20004 19733 19504 19397 19367>,
+ <19994 19728 19503 19385 19365>,
+ <19971 19712 19499 19378 19363>,
+ <19943 19687 19487 19377 19355>,
+ <19899 19665 19475 19375 19344>,
+ <19869 19642 19470 19374 19342>,
+ <19877 19632 19466 19372 19342>,
+ <19901 19647 19469 19372 19343>,
+ <19923 19671 19495 19388 19349>,
+ <19942 19689 19514 19404 19356>,
+ <19958 19707 19506 19392 19349>,
+ <19971 19715 19491 19363 19328>,
+ <19982 19714 19480 19354 19324>,
+ <19987 19712 19471 19361 19367>,
+ <19987 19708 19467 19371 19406>,
+ <19986 19700 19472 19393 19402>,
+ <19981 19693 19482 19420 19389>,
+ <19964 19687 19491 19424 19380>,
+ <19944 19681 19501 19417 19375>,
+ <19927 19674 19505 19408 19370>,
+ <19909 19667 19502 19400 19364>,
+ <19887 19661 19496 19393 19359>,
+ <19857 19654 19490 19391 19359>,
+ <19833 19648 19482 19390 19361>,
+ <19823 19645 19476 19388 19361>,
+ <19817 19642 19472 19384 19360>,
+ <19809 19639 19469 19380 19357>,
+ <19799 19633 19467 19379 19354>,
+ <19782 19623 19464 19379 19350>,
+ <19746 19608 19456 19370 19351>,
+ <19539 19554 19438 19361 19350>,
+ <19448 19517 19424 19359 19336>,
+ <19360 19487 19421 19353 19336>,
+ <19338 19415 19383 19350 19334>,
+ <19334 19359 19380 19350 19322>,
+ <19331 19356 19379 19342 19311>,
+ <19336 19407 19355 19344 19349>,
+ <19363 19368 19347 19351 19359>,
+ <19378 19358 19345 19361 19341>,
+ <19370 19355 19344 19360 19341>,
+ <19370 19355 19344 19360 19341>,
+ <19370 19355 19344 19360 19341>;
+ };
+
+ qcom,pc-temp-z4-lut {
+ qcom,lut-col-legend = <0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200>,
+ <9000 8800 8600 8400 8200>,
+ <8000 7800 7600 7400 7200>,
+ <7000 6800 6600 6400 6200>,
+ <6000 5800 5600 5400 5200>,
+ <5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200>,
+ <3000 2800 2600 2400 2200>,
+ <2000 1800 1600 1400 1200>,
+ <1000 900 800 700 600>,
+ <500 400 300 200 100>,
+ <0>;
+ qcom,lut-data = <17301 16140 15222 15043 14943>,
+ <17308 15962 15418 15009 14905>,
+ <17122 15786 15328 15050 14950>,
+ <16727 15606 15162 14976 14903>,
+ <16433 15424 15062 14917 14859>,
+ <16251 15281 14992 14877 14826>,
+ <16097 15174 14938 14845 14801>,
+ <15952 15090 14895 14822 14787>,
+ <15818 15031 14862 14805 14779>,
+ <15698 14987 14843 14793 14770>,
+ <15592 14949 14829 14783 14761>,
+ <15496 14907 14817 14775 14753>,
+ <15401 14876 14803 14767 14749>,
+ <15307 14870 14793 14758 14746>,
+ <15235 14869 14788 14757 14740>,
+ <15190 14866 14784 14753 14727>,
+ <15156 14857 14776 14747 14716>,
+ <15122 14842 14753 14733 14710>,
+ <15093 14830 14734 14716 14706>,
+ <15061 14817 14728 14709 14701>,
+ <15019 14806 14725 14705 14695>,
+ <14971 14793 14734 14708 14694>,
+ <14933 14784 14809 14785 14760>,
+ <14900 14807 14876 14871 14845>,
+ <14879 14900 14900 14891 14870>,
+ <14875 14951 14915 14901 14882>,
+ <14873 14946 14914 14901 14881>,
+ <14874 14934 14897 14876 14817>,
+ <14882 14919 14874 14840 14752>,
+ <14892 14896 14848 14796 14738>,
+ <14893 14874 14819 14748 14730>,
+ <14887 14854 14793 14729 14721>,
+ <14880 14837 14768 14720 14708>,
+ <14873 14820 14753 14716 14702>,
+ <14865 14805 14745 14714 14702>,
+ <14862 14792 14740 14713 14703>,
+ <14861 14779 14737 14715 14707>,
+ <14860 14769 14734 14723 14723>,
+ <14851 14768 14734 14731 14732>,
+ <14832 14769 14745 14740 14734>,
+ <14825 14770 14755 14747 14735>,
+ <14824 14765 14748 14740 14731>,
+ <14823 14760 14735 14728 14721>,
+ <14824 14761 14737 14735 14723>,
+ <14909 14753 14731 14734 14720>,
+ <14962 14738 14704 14705 14702>,
+ <15055 14759 14693 14694 14688>,
+ <15069 14828 14716 14674 14667>,
+ <15067 14881 14704 14652 14654>,
+ <15059 14879 14702 14660 14665>,
+ <15048 14832 14755 14694 14659>,
+ <15060 14897 14775 14692 14655>,
+ <15071 14921 14782 14684 14675>,
+ <15107 14937 14788 14688 14676>,
+ <15107 14937 14788 14688 14676>,
+ <15107 14937 14788 14688 14676>;
+ };
+
+ qcom,pc-temp-z5-lut {
+ qcom,lut-col-legend = <0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200>,
+ <9000 8800 8600 8400 8200>,
+ <8000 7800 7600 7400 7200>,
+ <7000 6800 6600 6400 6200>,
+ <6000 5800 5600 5400 5200>,
+ <5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200>,
+ <3000 2800 2600 2400 2200>,
+ <2000 1800 1600 1400 1200>,
+ <1000 900 800 700 600>,
+ <500 400 300 200 100>,
+ <0>;
+ qcom,lut-data = <11454 11745 12182 12555 13430>,
+ <12243 12652 13896 14662 14641>,
+ <12436 13367 14441 15536 15665>,
+ <12532 13830 14827 15834 16844>,
+ <12552 14152 15222 16091 17560>,
+ <12527 14535 15609 16368 17875>,
+ <12502 15138 15928 16601 18050>,
+ <12551 15743 16212 16735 17898>,
+ <12726 16087 16403 16725 17371>,
+ <12887 16332 16498 16662 17155>,
+ <12979 16550 16698 16583 17268>,
+ <13082 16850 16825 16576 17355>,
+ <13409 17177 17092 16656 16992>,
+ <14282 17631 17333 16659 16294>,
+ <14830 18572 17534 16467 16225>,
+ <14822 19041 18085 15934 16905>,
+ <14790 18616 18533 15813 17373>,
+ <14713 18031 18902 16522 17104>,
+ <14449 17791 19349 17525 16697>,
+ <14245 17646 19899 18215 16853>,
+ <14598 17636 20709 18771 17988>,
+ <15691 20478 23295 19826 18918>,
+ <17030 25517 32932 23676 19820>,
+ <18860 30303 39368 27018 20550>,
+ <21143 35691 34703 24339 19129>,
+ <23928 38044 26187 17537 15121>,
+ <27393 36280 21987 15112 13807>,
+ <30042 33236 19473 14804 16059>,
+ <32020 30881 18529 14686 18244>,
+ <33389 28692 18785 16275 18450>,
+ <33081 27358 19394 19654 18492>,
+ <30672 26749 20802 21861 18808>,
+ <28094 26332 24167 23393 20141>,
+ <26285 26063 26973 24608 21754>,
+ <24607 25796 29058 25724 23548>,
+ <22853 25708 30393 26520 25129>,
+ <20734 25757 30186 26653 25308>,
+ <19445 25839 29114 26586 25032>,
+ <19728 26174 27935 26310 24544>,
+ <20483 27216 26468 23530 22587>,
+ <20945 27813 25238 20623 20253>,
+ <21181 26835 24812 20503 19350>,
+ <21204 25242 24404 20657 18824>,
+ <20042 23391 22263 18651 18178>,
+ <15624 21181 21039 17430 17655>,
+ <13453 19868 21195 18547 16954>,
+ <11648 17113 21109 18133 17459>,
+ <11421 13549 15913 18875 18995>,
+ <11379 12104 15838 21530 18855>,
+ <11375 12108 15893 19283 16193>,
+ <11506 13512 13714 15340 18602>,
+ <11658 12181 12915 15355 19788>,
+ <11612 11862 12663 15997 15501>,
+ <11332 11678 12471 15399 15001>,
+ <11332 11678 12471 15399 15001>,
+ <11332 11678 12471 15399 15001>;
+ };
+
+ qcom,pc-temp-z6-lut {
+ qcom,lut-col-legend = <0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200>,
+ <9000 8800 8600 8400 8200>,
+ <8000 7800 7600 7400 7200>,
+ <7000 6800 6600 6400 6200>,
+ <6000 5800 5600 5400 5200>,
+ <5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200>,
+ <3000 2800 2600 2400 2200>,
+ <2000 1800 1600 1400 1200>,
+ <1000 900 800 700 600>,
+ <500 400 300 200 100>,
+ <0>;
+ qcom,lut-data = <16973 15807 15018 14827 14765>,
+ <17065 15779 15164 14847 14763>,
+ <16980 15735 15135 14883 14799>,
+ <16753 15671 15074 14859 14791>,
+ <16567 15579 15033 14838 14782>,
+ <16430 15503 15001 14823 14772>,
+ <16316 15449 14974 14808 14760>,
+ <16229 15404 14948 14793 14748>,
+ <16160 15366 14926 14779 14736>,
+ <16098 15334 14911 14767 14727>,
+ <16041 15303 14899 14759 14720>,
+ <15989 15268 14889 14751 14714>,
+ <15949 15238 14879 14743 14707>,
+ <15916 15223 14869 14736 14699>,
+ <15884 15215 14863 14729 14692>,
+ <15850 15206 14857 14722 14686>,
+ <15816 15191 14849 14715 14680>,
+ <15783 15173 14834 14707 14673>,
+ <15748 15158 14822 14701 14666>,
+ <15725 15144 14818 14697 14663>,
+ <15719 15138 14816 14695 14660>,
+ <15716 15143 14822 14696 14660>,
+ <15716 15153 14871 14740 14695>,
+ <15717 15177 14908 14785 14735>,
+ <15720 15227 14913 14785 14738>,
+ <15724 15253 14914 14778 14736>,
+ <15733 15252 14911 14772 14734>,
+ <15741 15248 14900 14765 14730>,
+ <15748 15243 14889 14758 14724>,
+ <15754 15231 14882 14752 14717>,
+ <15753 15219 14876 14746 14708>,
+ <15745 15210 14870 14740 14699>,
+ <15735 15201 14866 14733 14692>,
+ <15727 15194 14862 14727 14686>,
+ <15719 15186 14858 14722 14683>,
+ <15710 15181 14855 14718 14680>,
+ <15700 15176 14851 14718 14682>,
+ <15693 15173 14847 14721 14689>,
+ <15690 15173 14846 14724 14694>,
+ <15687 15178 14850 14725 14694>,
+ <15687 15181 14854 14727 14693>,
+ <15688 15180 14851 14725 14690>,
+ <15688 15179 14846 14720 14685>,
+ <15677 15176 14844 14719 14686>,
+ <15623 15154 14835 14714 14685>,
+ <15600 15133 14818 14701 14671>,
+ <15596 15128 14812 14694 14664>,
+ <15593 15123 14803 14684 14654>,
+ <15591 15118 14797 14674 14642>,
+ <15592 15120 14796 14674 14642>,
+ <15601 15133 14809 14690 14660>,
+ <15634 15150 14818 14696 14667>,
+ <15666 15168 14825 14701 14669>,
+ <15707 15193 14837 14707 14674>,
+ <15707 15193 14837 14707 14674>,
+ <15707 15193 14837 14707 14674>;
+ };
+
+ qcom,pc-temp-y1-lut {
+ qcom,lut-col-legend = <(-10) 0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>,
+ <8800 8600 8400 8200 8000 7800>,
+ <7600 7400 7200 7000 6800 6600>,
+ <6400 6200 6000 5800 5600 5400>,
+ <5200 5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200 3000>,
+ <2800 2600 2400 2200 2000 1800>,
+ <1600 1400 1200 1000 900 800>,
+ <700 600 500 400 300 200>,
+ <100 0>;
+ qcom,lut-data = <7552 6810 6241 5686 5442 5364>,
+ <7545 6802 6232 5681 5439 5365>,
+ <7543 6796 6224 5677 5437 5366>,
+ <7546 6794 6215 5672 5434 5367>,
+ <7553 6793 6208 5668 5432 5367>,
+ <7561 6793 6202 5664 5430 5367>,
+ <7572 6804 6199 5660 5429 5367>,
+ <7581 6819 6195 5656 5427 5366>,
+ <7576 6820 6192 5654 5427 5366>,
+ <7550 6812 6189 5652 5426 5366>,
+ <7540 6808 6187 5649 5425 5367>,
+ <7553 6811 6186 5648 5425 5367>,
+ <7568 6816 6186 5646 5424 5367>,
+ <7570 6816 6186 5644 5424 5368>,
+ <7562 6813 6184 5642 5424 5370>,
+ <7564 6815 6183 5642 5425 5371>,
+ <7576 6837 6188 5650 5426 5372>,
+ <7587 6859 6195 5657 5427 5373>,
+ <7588 6854 6198 5656 5427 5373>,
+ <7579 6834 6203 5655 5428 5373>,
+ <7572 6826 6206 5655 5429 5374>,
+ <7556 6818 6208 5656 5431 5375>,
+ <7544 6814 6209 5658 5432 5375>,
+ <7553 6824 6207 5662 5434 5377>,
+ <7570 6842 6203 5666 5435 5380>,
+ <7573 6846 6202 5670 5437 5381>,
+ <7567 6832 6209 5674 5440 5383>,
+ <7559 6821 6217 5679 5443 5384>,
+ <7555 6821 6225 5684 5445 5386>,
+ <7555 6822 6231 5690 5448 5388>,
+ <7553 6823 6235 5695 5451 5390>,
+ <7541 6824 6242 5700 5455 5393>,
+ <7532 6824 6249 5706 5458 5396>,
+ <7541 6826 6256 5712 5461 5399>,
+ <7554 6829 6262 5718 5464 5401>,
+ <7555 6829 6265 5725 5467 5403>,
+ <7551 6826 6262 5734 5471 5405>,
+ <7546 6825 6258 5738 5474 5408>,
+ <7535 6832 6263 5739 5475 5411>,
+ <7526 6841 6270 5740 5476 5414>,
+ <7539 6844 6274 5742 5479 5415>,
+ <7576 6860 6278 5746 5482 5415>,
+ <7552 6858 6295 5752 5483 5416>,
+ <7527 6841 6309 5758 5486 5418>,
+ <7601 6836 6293 5763 5490 5421>,
+ <7546 6867 6308 5765 5492 5421>,
+ <7555 6871 6310 5772 5494 5424>,
+ <7582 6861 6320 5779 5494 5424>,
+ <7584 6849 6325 5788 5497 5425>,
+ <7612 6861 6321 5791 5498 5425>,
+ <7599 6858 6326 5796 5500 5427>,
+ <7691 6876 6346 5806 5508 5435>,
+ <7678 6902 6371 5830 5519 5444>,
+ <7757 6955 6381 5870 5536 5456>,
+ <7757 6955 6381 5870 5536 5456>,
+ <7757 6955 6381 5870 5536 5456>;
+ };
+
+ qcom,pc-temp-y2-lut {
+ qcom,lut-col-legend = <(-10) 0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>,
+ <8800 8600 8400 8200 8000 7800>,
+ <7600 7400 7200 7000 6800 6600>,
+ <6400 6200 6000 5800 5600 5400>,
+ <5200 5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200 3000>,
+ <2800 2600 2400 2200 2000 1800>,
+ <1600 1400 1200 1000 900 800>,
+ <700 600 500 400 300 200>,
+ <100 0>;
+ qcom,lut-data = <9914 10222 10683 10964 11183 11045>,
+ <9946 10230 10651 10941 11126 11069>,
+ <9983 10240 10621 10918 11071 11067>,
+ <10020 10249 10593 10895 11020 11052>,
+ <10050 10257 10567 10872 10975 11035>,
+ <10068 10262 10544 10849 10941 11028>,
+ <10074 10265 10523 10825 10911 11019>,
+ <10079 10267 10506 10802 10890 11002>,
+ <10101 10266 10496 10774 10887 10976>,
+ <10158 10263 10488 10742 10895 10930>,
+ <10213 10263 10483 10729 10900 10910>,
+ <10266 10342 10478 10738 10902 10910>,
+ <10305 10434 10476 10748 10902 10910>,
+ <10314 10433 10492 10751 10898 10920>,
+ <10318 10403 10543 10754 10887 10947>,
+ <10326 10392 10576 10759 10885 10954>,
+ <10351 10419 10589 10776 10908 10926>,
+ <10387 10455 10601 10800 10946 10901>,
+ <10432 10476 10615 10843 10994 10928>,
+ <10484 10492 10630 10897 11052 10992>,
+ <10484 10511 10647 10908 11086 11025>,
+ <10286 10534 10664 10894 11107 11052>,
+ <10094 10558 10683 10883 11119 11075>,
+ <9952 10585 10701 10892 11121 11108>,
+ <9736 10611 10721 10911 11120 11155>,
+ <9680 10616 10741 10926 11122 11189>,
+ <9673 10605 10765 10949 11123 11222>,
+ <9668 10592 10780 10972 11125 11238>,
+ <9666 10579 10784 10989 11140 11234>,
+ <9664 10561 10786 11002 11163 11228>,
+ <9663 10538 10790 11008 11178 11230>,
+ <9661 10508 10798 11010 11191 11244>,
+ <9660 10466 10803 11011 11200 11260>,
+ <9659 10335 10790 11004 11211 11279>,
+ <9658 10135 10767 10993 11219 11295>,
+ <9657 10006 10747 10986 11196 11289>,
+ <9655 9805 10727 10977 11126 11262>,
+ <9655 9695 10703 10967 11096 11241>,
+ <9654 9677 10673 10957 11113 11231>,
+ <9653 9667 10636 10946 11131 11227>,
+ <9653 9661 10595 10934 11116 11220>,
+ <9652 9658 10547 10920 11077 11193>,
+ <9652 9656 10487 10904 11077 11137>,
+ <9652 9653 10419 10885 11093 11129>,
+ <9651 9652 10290 10865 11083 11158>,
+ <9651 9652 10140 10837 11039 11066>,
+ <9651 9651 10260 10820 10979 10993>,
+ <9651 9651 10216 10799 10953 10940>,
+ <9651 9651 10188 10795 10964 10908>,
+ <9650 9650 10170 10774 10960 10865>,
+ <9650 9650 10144 10741 10924 10853>,
+ <9649 9650 9941 10682 10864 10805>,
+ <9648 9649 9709 10605 10800 10758>,
+ <9647 9648 9665 10555 10732 10653>,
+ <9647 9648 9665 10555 10732 10653>,
+ <9647 9648 9665 10555 10732 10653>;
+ };
+
+ qcom,pc-temp-y3-lut {
+ qcom,lut-col-legend = <(-10) 0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>,
+ <8800 8600 8400 8200 8000 7800>,
+ <7600 7400 7200 7000 6800 6600>,
+ <6400 6200 6000 5800 5600 5400>,
+ <5200 5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200 3000>,
+ <2800 2600 2400 2200 2000 1800>,
+ <1600 1400 1200 1000 900 800>,
+ <700 600 500 400 300 200>,
+ <100 0>;
+ qcom,lut-data = <13564 13490 13355 13305 13277 13275>,
+ <13617 13499 13361 13303 13278 13276>,
+ <13666 13512 13367 13302 13280 13277>,
+ <13707 13527 13372 13301 13282 13278>,
+ <13735 13539 13377 13301 13283 13279>,
+ <13744 13545 13381 13302 13284 13280>,
+ <13734 13546 13384 13303 13284 13281>,
+ <13717 13547 13386 13304 13285 13282>,
+ <13707 13555 13388 13304 13285 13283>,
+ <13699 13577 13389 13302 13285 13283>,
+ <13686 13587 13391 13302 13286 13283>,
+ <13638 13554 13394 13308 13290 13283>,
+ <13591 13513 13397 13316 13295 13283>,
+ <13592 13504 13398 13319 13295 13285>,
+ <13607 13500 13401 13321 13294 13289>,
+ <13611 13496 13402 13322 13294 13291>,
+ <13582 13489 13399 13324 13296 13289>,
+ <13549 13479 13393 13326 13298 13288>,
+ <13536 13470 13388 13326 13300 13289>,
+ <13527 13460 13382 13327 13301 13291>,
+ <13514 13451 13375 13326 13301 13292>,
+ <13488 13442 13368 13321 13297 13288>,
+ <13467 13432 13361 13315 13293 13283>,
+ <13461 13421 13356 13309 13288 13280>,
+ <13459 13409 13352 13303 13284 13278>,
+ <13456 13398 13348 13301 13282 13277>,
+ <13449 13388 13344 13300 13281 13277>,
+ <13445 13380 13342 13300 13281 13276>,
+ <13452 13373 13342 13300 13282 13277>,
+ <13468 13368 13344 13301 13283 13278>,
+ <13489 13368 13343 13302 13284 13278>,
+ <13523 13374 13338 13306 13284 13278>,
+ <13561 13381 13335 13307 13284 13278>,
+ <13598 13391 13338 13307 13285 13279>,
+ <13641 13402 13343 13307 13286 13280>,
+ <13695 13412 13344 13306 13286 13279>,
+ <13766 13428 13344 13306 13285 13277>,
+ <13844 13447 13344 13305 13285 13276>,
+ <13929 13471 13348 13303 13283 13276>,
+ <14023 13502 13352 13301 13282 13276>,
+ <14128 13548 13355 13300 13282 13277>,
+ <14249 13625 13357 13300 13284 13278>,
+ <14381 13738 13361 13300 13284 13278>,
+ <14524 13900 13364 13301 13283 13278>,
+ <14576 14042 13355 13301 13282 13277>,
+ <14696 14187 13357 13304 13281 13279>,
+ <14828 14350 13379 13307 13288 13282>,
+ <14982 14536 13393 13314 13290 13285>,
+ <15128 14688 13413 13314 13293 13290>,
+ <15291 14820 13436 13324 13301 13291>,
+ <15495 14916 13453 13326 13297 13287>,
+ <16003 15021 13463 13324 13297 13287>,
+ <16900 15292 13520 13334 13299 13291>,
+ <18414 16030 13693 13348 13304 13295>,
+ <18414 16030 13693 13348 13304 13295>,
+ <18414 16030 13693 13348 13304 13295>;
+ };
+
+ qcom,pc-temp-y4-lut {
+ qcom,lut-col-legend = <(-10) 0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>,
+ <8800 8600 8400 8200 8000 7800>,
+ <7600 7400 7200 7000 6800 6600>,
+ <6400 6200 6000 5800 5600 5400>,
+ <5200 5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200 3000>,
+ <2800 2600 2400 2200 2000 1800>,
+ <1600 1400 1200 1000 900 800>,
+ <700 600 500 400 300 200>,
+ <100 0>;
+ qcom,lut-data = <17336 16910 16654 16528 16493 16478>,
+ <17345 16950 16664 16529 16489 16472>,
+ <17360 17005 16676 16531 16486 16469>,
+ <17381 17063 16687 16534 16484 16467>,
+ <17406 17111 16697 16537 16484 16466>,
+ <17436 17135 16702 16541 16484 16466>,
+ <17481 17143 16704 16544 16486 16467>,
+ <17521 17148 16706 16548 16491 16469>,
+ <17513 17139 16712 16557 16497 16473>,
+ <17470 17104 16727 16572 16504 16478>,
+ <17459 17092 16742 16580 16508 16483>,
+ <17755 17309 16753 16581 16509 16491>,
+ <18088 17561 16766 16582 16510 16498>,
+ <17958 17551 16815 16591 16517 16502>,
+ <17483 17428 16913 16615 16533 16505>,
+ <17227 17302 16949 16639 16547 16510>,
+ <17152 17162 16927 16660 16558 16522>,
+ <17111 17048 16899 16684 16570 16539>,
+ <17097 17011 16885 16729 16597 16559>,
+ <17088 16991 16873 16782 16631 16581>,
+ <17080 16960 16846 16784 16637 16584>,
+ <17062 16899 16748 16691 16606 16566>,
+ <17049 16842 16657 16597 16566 16541>,
+ <17037 16811 16626 16552 16527 16511>,
+ <17009 16787 16606 16520 16491 16481>,
+ <17003 16757 16600 16515 16484 16475>,
+ <17010 16710 16599 16517 16487 16477>,
+ <17017 16681 16598 16519 16491 16481>,
+ <17024 16688 16598 16523 16497 16486>,
+ <17030 16703 16597 16529 16505 16495>,
+ <17032 16714 16595 16536 16516 16504>,
+ <17032 16722 16591 16544 16529 16517>,
+ <17032 16731 16588 16551 16542 16529>,
+ <17037 16752 16591 16558 16557 16544>,
+ <17043 16787 16596 16562 16569 16556>,
+ <17045 16818 16605 16560 16557 16543>,
+ <17047 16862 16620 16550 16515 16500>,
+ <17047 16896 16633 16539 16491 16478>,
+ <17044 16920 16644 16524 16483 16474>,
+ <17040 16937 16653 16513 16480 16472>,
+ <17042 16938 16659 16518 16485 16476>,
+ <17050 16933 16664 16530 16495 16484>,
+ <17067 16920 16673 16537 16496 16484>,
+ <17092 16909 16677 16539 16494 16481>,
+ <17104 16907 16671 16514 16472 16460>,
+ <17107 16918 16696 16522 16490 16475>,
+ <17141 16963 16691 16540 16499 16485>,
+ <17180 17018 16736 16559 16512 16499>,
+ <17223 17102 16796 16588 16529 16521>,
+ <17257 17205 16887 16618 16545 16531>,
+ <17284 17261 16939 16607 16502 16483>,
+ <17442 17263 16943 16591 16494 16478>,
+ <17801 17305 16996 16625 16510 16492>,
+ <18794 17772 17141 16709 16559 16537>,
+ <18794 17772 17141 16709 16559 16537>,
+ <18794 17772 17141 16709 16559 16537>;
+ };
+
+ qcom,pc-temp-y5-lut {
+ qcom,lut-col-legend = <(-10) 0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>,
+ <8800 8600 8400 8200 8000 7800>,
+ <7600 7400 7200 7000 6800 6600>,
+ <6400 6200 6000 5800 5600 5400>,
+ <5200 5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200 3000>,
+ <2800 2600 2400 2200 2000 1800>,
+ <1600 1400 1200 1000 900 800>,
+ <700 600 500 400 300 200>,
+ <100 0>;
+ qcom,lut-data = <9561 11462 13393 14613 13122 14203>,
+ <9957 11826 13761 14231 13403 14561>,
+ <10618 12421 14121 13799 13565 14776>,
+ <11343 13062 14429 13377 13638 14881>,
+ <11936 13568 14640 13030 13650 14906>,
+ <12198 13754 14711 12818 13629 14882>,
+ <12254 13708 14658 12725 13485 14774>,
+ <12284 13647 14543 12646 13248 14586>,
+ <12201 13889 14333 12429 12994 14346>,
+ <11891 14806 13915 12024 12697 14004>,
+ <11748 15214 13562 11873 12606 13650>,
+ <11989 13951 13266 12314 13123 13214>,
+ <12478 12499 13067 12783 13673 12899>,
+ <13614 13075 13078 12724 13468 13090>,
+ <15670 15217 13175 12491 12829 13652>,
+ <16335 16082 13356 12416 12608 13810>,
+ <14952 15650 14131 12486 12710 13221>,
+ <13612 15209 15044 12618 12838 12684>,
+ <13802 15292 15557 12917 12912 12716>,
+ <14381 15573 15951 13533 12986 12878>,
+ <14504 15710 16197 14452 13314 13166>,
+ <13761 15755 16381 16253 14962 13950>,
+ <12935 15775 16472 17409 16182 14687>,
+ <12235 15674 16267 16729 15958 15068>,
+ <11340 15417 15775 15439 15458 15333>,
+ <11015 15120 15370 14948 15046 15286>,
+ <10875 14344 14909 14766 14607 14758>,
+ <10796 13500 14656 14670 14389 14416>,
+ <10768 12866 15021 14698 14575 14530>,
+ <10751 12339 15579 14865 14855 14693>,
+ <10767 12262 15511 15302 14928 14662>,
+ <10867 12492 14847 16313 14894 14420>,
+ <10973 12673 14461 16966 14961 14292>,
+ <11046 12827 14863 17184 15410 14669>,
+ <11116 12947 15446 17313 16009 15211>,
+ <11204 12748 15461 17316 16488 15448>,
+ <11313 12067 15082 17145 16940 15612>,
+ <11359 11737 14859 16910 17040 15654>,
+ <11304 11697 15027 16281 16164 15541>,
+ <11202 11634 15240 15482 15226 15343>,
+ <11077 11632 15141 14907 15093 15094>,
+ <10923 11665 14782 14443 15099 14773>,
+ <10879 11630 14532 14078 14642 14517>,
+ <10913 11485 14265 14000 14412 14404>,
+ <10872 11371 13177 14806 15169 15860>,
+ <11038 11318 12659 14742 13466 14171>,
+ <11078 11212 13426 14374 14372 13964>,
+ <11252 11405 13433 14745 13876 14003>,
+ <11425 11431 13705 13712 13947 14775>,
+ <11572 11839 14106 14341 15142 14609>,
+ <11569 12340 14307 15209 16090 15443>,
+ <11194 12346 13428 15199 17270 15675>,
+ <10507 11656 11893 15949 16875 17050>,
+ <9839 10544 11476 16641 17739 18076>,
+ <9839 10544 11476 16641 17739 18076>,
+ <9839 10544 11476 16641 17739 18076>;
+ };
+
+ qcom,pc-temp-y6-lut {
+ qcom,lut-col-legend = <(-10) 0 10 25 40 50>;
+ qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>,
+ <8800 8600 8400 8200 8000 7800>,
+ <7600 7400 7200 7000 6800 6600>,
+ <6400 6200 6000 5800 5600 5400>,
+ <5200 5000 4800 4600 4400 4200>,
+ <4000 3800 3600 3400 3200 3000>,
+ <2800 2600 2400 2200 2000 1800>,
+ <1600 1400 1200 1000 900 800>,
+ <700 600 500 400 300 200>,
+ <100 0>;
+ qcom,lut-data = <6387 5774 5317 5112 5054 5039>,
+ <6411 5795 5320 5111 5053 5039>,
+ <6428 5812 5324 5111 5053 5039>,
+ <6437 5825 5327 5111 5053 5039>,
+ <6442 5832 5330 5112 5054 5040>,
+ <6443 5834 5331 5112 5055 5040>,
+ <6439 5829 5330 5114 5056 5042>,
+ <6429 5822 5329 5115 5058 5043>,
+ <6412 5817 5329 5117 5060 5044>,
+ <6381 5813 5332 5119 5061 5046>,
+ <6369 5812 5334 5122 5064 5048>,
+ <6420 5844 5337 5126 5067 5050>,
+ <6476 5880 5341 5131 5070 5052>,
+ <6446 5873 5355 5137 5073 5055>,
+ <6336 5837 5382 5144 5077 5059>,
+ <6270 5799 5392 5152 5080 5062>,
+ <6242 5757 5384 5160 5085 5065>,
+ <6227 5722 5373 5168 5090 5068>,
+ <6231 5707 5366 5181 5099 5075>,
+ <6242 5698 5358 5196 5110 5083>,
+ <6244 5686 5345 5196 5111 5084>,
+ <6237 5667 5312 5166 5099 5076>,
+ <6231 5652 5283 5134 5084 5065>,
+ <6231 5645 5271 5117 5069 5054>,
+ <6236 5640 5264 5104 5056 5043>,
+ <6245 5639 5261 5102 5054 5041>,
+ <6273 5638 5261 5103 5054 5042>,
+ <6307 5638 5261 5104 5055 5042>,
+ <6341 5647 5264 5106 5057 5045>,
+ <6379 5671 5269 5109 5061 5048>,
+ <6419 5697 5271 5113 5064 5051>,
+ <6462 5727 5271 5118 5068 5055>,
+ <6509 5761 5272 5122 5073 5058>,
+ <6559 5800 5278 5125 5078 5064>,
+ <6613 5845 5288 5127 5083 5068>,
+ <6673 5893 5296 5127 5079 5064>,
+ <6740 5947 5305 5124 5067 5050>,
+ <6813 6009 5315 5122 5060 5044>,
+ <6893 6082 5328 5117 5057 5043>,
+ <6978 6167 5342 5113 5056 5043>,
+ <7070 6263 5358 5114 5058 5044>,
+ <7171 6377 5375 5119 5062 5047>,
+ <7283 6510 5400 5123 5063 5048>,
+ <7405 6670 5428 5125 5062 5047>,
+ <7460 6806 5437 5119 5055 5041>,
+ <7557 6935 5466 5125 5060 5047>,
+ <7667 7081 5510 5134 5068 5052>,
+ <7794 7244 5568 5145 5073 5058>,
+ <7924 7388 5641 5155 5081 5069>,
+ <8062 7523 5723 5173 5091 5072>,
+ <8242 7618 5792 5173 5076 5056>,
+ <8750 7710 5851 5170 5075 5055>,
+ <9655 7965 5997 5194 5082 5063>,
+ <11188 8777 6283 5238 5102 5081>,
+ <11188 8777 6283 5238 5102 5081>,
+ <11188 8777 6283 5238 5102 5081>;
+ };
+
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm450-pmi632-mtp-s3.dtsi b/arch/arm64/boot/dts/qcom/sdm450-pmi632-mtp-s3.dtsi
old mode 100644
new mode 100755
index 1afea68..c253ac4
--- a/arch/arm64/boot/dts/qcom/sdm450-pmi632-mtp-s3.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm450-pmi632-mtp-s3.dtsi
@@ -24,10 +24,6 @@
&mdss_dsi0 {
qcom,dsi-pref-prim-pan = <&dsi_hx8399c_truly_vid>;
pinctrl-names = "mdss_default", "mdss_sleep";
- pinctrl-0 = <&mdss_dsi_active &mdss_te_active &bklt_en_default>;
- pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>;
-
- qcom,platform-bklight-en-gpio = <&pm8953_gpios 4 0>;
lab-supply = <&lcdb_ldo_vreg>;
ibb-supply = <&lcdb_ncp_vreg>;
diff --git a/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi b/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi
old mode 100644
new mode 100755
index 6e39327..e57f2df
--- a/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi
@@ -36,8 +36,8 @@
/{
mtp_batterydata: qcom,battery-data {
qcom,batt-id-range-pct = <15>;
- #include "qg-batterydata-ascent-3450mah.dtsi"
- #include "qg-batterydata-mlp356477-2800mah.dtsi"
+ #include "qg-batterydata-Fuji-3000mah-Jan22th2019-pmi632.dtsi"
+ #include "qg-batterydata-Kayo-3000mah-Nov4th2019-pmi632.dtsi"
};
};
@@ -373,23 +373,19 @@
};
};
-&tlmm {
- pmx_mdss {
- mdss_dsi_active: mdss_dsi_active {
- mux {
- pins = "gpio61";
- };
- config {
- pins = "gpio61";
- };
- };
- mdss_dsi_suspend: mdss_dsi_suspend {
- mux {
- pins = "gpio61";
- };
- config {
- pins = "gpio61";
- };
- };
+&i2c_3 {
+ status = "ok";
+ himax_ts@48 {
+ compatible = "himax,hxcommon";
+ reg = <0x48>;
+ interrupt-parent = <&tlmm>;
+ interrupts = <65 0x2008>;
+ vcc_i2c-supply = <&pm8953_l6>;
+ vdd-ana-supply = <&pm8953_l10>;
+ himax,display-coords = <0 1080 0 2160>;
+ himax,panel-coords = <0 1080 0 2160>;
+ himax,irq-gpio = <&tlmm 65 0x2008>;
+ himax,rst-gpio = <&tlmm 64 0x00>;
+ report_type = <1>;
};
};
diff --git a/arch/arm64/boot/dts/qcom/sdm450.dtsi b/arch/arm64/boot/dts/qcom/sdm450.dtsi
index 34c6815..67177fb 100644
--- a/arch/arm64/boot/dts/qcom/sdm450.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm450.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018, 2021 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
@@ -146,3 +146,8 @@
/delete-node/ case-therm-adc;
/delete-node/ case-therm-step;
};
+&soc {
+ qcom,vidc@1d00000 {
+ qcom,max-hw-load = <734400>; /* 1080p@60 dec + 1080p@30 enc */
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-mtp.dtsi
index 19dca08..a886b86 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-mtp.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020, 2021 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
@@ -411,7 +411,7 @@
};
qcom,cam-sensor@3 {
- cell-index = <0>;
+ cell-index = <3>;
compatible = "qcom,cam-sensor";
reg = <0x0>;
csiphy-sd-index = <0>;
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi
index da62c46..2d4e060 100644
--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -571,7 +571,7 @@
alloc-ranges = <0 0x00000000 0 0xffffffff>;
reusable;
alignment = <0 0x400000>;
- size = <0 0x400000>;
+ size = <0 0x800000>;
};
qseecom_ta_mem: qseecom_ta_region {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-audio.dtsi b/arch/arm64/boot/dts/qcom/sdm845-audio.dtsi
index a64467c..83be256 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-audio.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-audio.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2019, 2021, 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
@@ -68,7 +68,8 @@
<&dai_sec_tdm_rx_0>, <&dai_sec_tdm_tx_0>,
<&dai_tert_tdm_rx_0>, <&dai_tert_tdm_tx_0>,
<&dai_quat_tdm_rx_0>, <&dai_quat_tdm_tx_0>,
- <&dai_quat_tdm_rx_1>;
+ <&dai_quat_tdm_rx_1>,
+ <&proxy_rx>, <&proxy_tx>;
asoc-cpu-names = "msm-dai-q6-hdmi.8", "msm-dai-q6-dp.24608",
"msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1",
"msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3",
@@ -91,7 +92,8 @@
"msm-dai-q6-tdm.36880", "msm-dai-q6-tdm.36881",
"msm-dai-q6-tdm.36896", "msm-dai-q6-tdm.36897",
"msm-dai-q6-tdm.36912", "msm-dai-q6-tdm.36913",
- "msm-dai-q6-tdm.36914";
+ "msm-dai-q6-tdm.36914",
+ "msm-dai-q6-dev.8194", "msm-dai-q6-dev.8195";
};
};
diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig
index b1ac518..6011a1b 100755
--- a/arch/arm64/configs/msm8953-perf_defconfig
+++ b/arch/arm64/configs/msm8953-perf_defconfig
@@ -320,12 +320,11 @@
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_JOYSTICK=y
CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_CORE_v26=y
-CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI_DEV_v26=y
-CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v26=y
-CONFIG_SECURE_TOUCH_SYNAPTICS_DSX_V26=y
+CONFIG_TOUCHSCREEN_HIMAX_CHIPSET=y
+CONFIG_TOUCHSCREEN_HIMAX_I2C=y
+CONFIG_TOUCHSCREEN_HIMAX_DEBUG=y
CONFIG_INPUT_MISC=y
-CONFIG_INPUT_HBTP_INPUT=y
+# CONFIG_INPUT_HBTP_INPUT=y
CONFIG_INPUT_QPNP_POWER_ON=y
CONFIG_INPUT_UINPUT=y
# CONFIG_SERIO_SERPORT is not set
@@ -684,3 +683,9 @@
CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y
CONFIG_CRYPTO_CRC32_ARM64=y
CONFIG_QMI_ENCDEC=y
+CONFIG_ELAN_FINGERPRINT=y
+CONFIG_SND_SMARTPA_AW8898=y
+CONFIG_SND_SOC_TAS2557=y
+CONFIG_TAS2557_REGMAP=y
+CONFIG_TAS2557_CODEC=y
+CONFIG_TAS2557_MISC=y
diff --git a/arch/arm64/configs/msm8953_defconfig b/arch/arm64/configs/msm8953_defconfig
index 99f879e..0fb0e89 100755
--- a/arch/arm64/configs/msm8953_defconfig
+++ b/arch/arm64/configs/msm8953_defconfig
@@ -327,12 +327,11 @@
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_JOYSTICK=y
CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_CORE_v26=y
-CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI_DEV_v26=y
-CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v26=y
-CONFIG_SECURE_TOUCH_SYNAPTICS_DSX_V26=y
+CONFIG_TOUCHSCREEN_HIMAX_CHIPSET=y
+CONFIG_TOUCHSCREEN_HIMAX_I2C=y
+CONFIG_TOUCHSCREEN_HIMAX_DEBUG=y
CONFIG_INPUT_MISC=y
-CONFIG_INPUT_HBTP_INPUT=y
+# CONFIG_INPUT_HBTP_INPUT=y
CONFIG_INPUT_QPNP_POWER_ON=y
CONFIG_INPUT_UINPUT=y
# CONFIG_SERIO_SERPORT is not set
@@ -748,3 +747,9 @@
CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y
CONFIG_CRYPTO_CRC32_ARM64=y
CONFIG_QMI_ENCDEC=y
+CONFIG_ELAN_FINGERPRINT=y
+CONFIG_SND_SMARTPA_AW8898=y
+CONFIG_SND_SOC_TAS2557=y
+CONFIG_TAS2557_REGMAP=y
+CONFIG_TAS2557_CODEC=y
+CONFIG_TAS2557_MISC=y
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
old mode 100644
new mode 100755
index e9ba70a..cd0d55a
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -81,7 +81,10 @@
#define ARCH_LOW_ADDRESS_LIMIT (arm64_dma_phys_limit - 1)
extern unsigned int boot_reason;
+extern unsigned int qpnp_pon_reason_extern;
+extern unsigned int qpnp_poff_reason_extern;
extern unsigned int cold_boot;
+extern char ddr_vendor[32];
struct debug_info {
/* Have we suspended stepping by a debugger? */
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
old mode 100644
new mode 100755
index 813a191..d49131b
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -294,6 +294,7 @@
static char fw_path_para[256];
static const char * const fw_path[] = {
fw_path_para,
+ "/system/vendor/firmware",
"/lib/firmware/updates/" UTS_RELEASE,
"/lib/firmware/updates",
"/lib/firmware/" UTS_RELEASE,
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index 4398d60..642bd4a 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -17,7 +17,6 @@
#include <linux/completion.h>
#include <linux/pagemap.h>
#include <linux/mm.h>
-#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/module.h>
#include <linux/cdev.h>
@@ -32,7 +31,6 @@
#include <soc/qcom/service-notifier.h>
#include <soc/qcom/service-locator.h>
#include <linux/scatterlist.h>
-#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/device.h>
#include <linux/of.h>
@@ -51,6 +49,8 @@
#include <soc/qcom/ramdump.h>
#include <linux/debugfs.h>
#include <linux/pm_qos.h>
+#include <linux/stat.h>
+
#define TZ_PIL_PROTECT_MEM_SUBSYS_ID 0x0C
#define TZ_PIL_CLEAR_PROTECT_MEM_SUBSYS_ID 0x0D
#define TZ_PIL_AUTH_QDSP6_PROC 1
@@ -106,8 +106,9 @@
#define FASTRPC_GLINK_INTENT_NUM (16)
#define PERF_KEYS \
- "count:flush:map:copy:glink:getargs:putargs:invalidate:invoke:tid:ptr"
-#define FASTRPC_STATIC_HANDLE_KERNEL (1)
+ "count:flush:map:copy:rpmsg:getargs:putargs:invalidate:invoke:tid:ptr"
+#define FASTRPC_STATIC_HANDLE_PROCESS_GROUP (1)
+#define FASTRPC_STATIC_HANDLE_DSP_UTILITIES (2)
#define FASTRPC_STATIC_HANDLE_LISTENER (3)
#define FASTRPC_STATIC_HANDLE_MAX (20)
#define FASTRPC_LATENCY_CTRL_ENB (1)
@@ -285,6 +286,11 @@
void *link_notify_handle;
};
+struct fastrpc_dsp_capabilities {
+ uint32_t is_cached; //! Flag if dsp attributes are cached
+ uint32_t dsp_attributes[FASTRPC_MAX_DSP_ATTRIBUTES];
+};
+
struct fastrpc_channel_ctx {
char *name;
char *subsys;
@@ -309,6 +315,9 @@
struct fastrpc_glink_info link;
/* Indicates, if channel is restricted to secure node only */
int secure;
+ struct fastrpc_dsp_capabilities dsp_cap_kernel;
+ /* Indicates whether the channel supports unsigned PD */
+ bool unsigned_support;
};
struct fastrpc_apps {
@@ -2037,9 +2046,12 @@
me->channel[i].sesscount = 0;
/* All channels are secure by default except CDSP */
me->channel[i].secure = SECURE_CHANNEL;
+ me->channel[i].unsigned_support = false;
}
/* Set CDSP channel to non secure */
me->channel[CDSP_DOMAIN_ID].secure = NON_SECURE_CHANNEL;
+ /* Set CDSP channel unsigned_support to true*/
+ me->channel[CDSP_DOMAIN_ID].unsigned_support = true;
}
static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl);
@@ -2071,10 +2083,13 @@
getnstimeofday(&invoket);
if (!kernel) {
- VERIFY(err, invoke->handle != FASTRPC_STATIC_HANDLE_KERNEL);
+ VERIFY(err, invoke->handle !=
+ FASTRPC_STATIC_HANDLE_PROCESS_GROUP);
+ VERIFY(err, invoke->handle !=
+ FASTRPC_STATIC_HANDLE_DSP_UTILITIES);
if (err) {
- pr_err("adsprpc: ERROR: %s: user application %s trying to send a kernel RPC message to channel %d",
- __func__, current->comm, cid);
+ pr_err("adsprpc: ERROR: %s: user application %s trying to send a kernel RPC message to channel %d, handle 0x%x\n",
+ __func__, current->comm, cid, invoke->handle);
goto bail;
}
}
@@ -2198,6 +2213,20 @@
struct fastrpc_buf *imem = NULL;
unsigned long imem_dma_attr = 0;
char *proc_name = NULL;
+ int unsigned_request = (uproc->attrs & FASTRPC_MODE_UNSIGNED_MODULE);
+ int cid = fl->cid;
+ struct fastrpc_channel_ctx *chan = &me->channel[cid];
+
+ if (chan->unsigned_support &&
+ fl->dev_minor == MINOR_NUM_DEV) {
+ /* Make sure third party applications */
+ /* can spawn only unsigned PD when */
+ /* channel configured as secure. */
+ if (chan->secure && !unsigned_request) {
+ err = -ECONNREFUSED;
+ goto bail;
+ }
+ }
VERIFY(err, 0 == (err = fastrpc_channel_open(fl)));
if (err)
@@ -2209,7 +2238,7 @@
ra[0].buf.pv = (void *)&tgid;
ra[0].buf.len = sizeof(tgid);
- ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
+ ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
ioctl.inv.sc = REMOTE_SCALARS_MAKE(0, 1, 0);
ioctl.inv.pra = ra;
ioctl.fds = NULL;
@@ -2306,7 +2335,7 @@
ra[5].buf.len = sizeof(inbuf.siglen);
fds[5] = 0;
- ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
+ ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
ioctl.inv.sc = REMOTE_SCALARS_MAKE(6, 4, 0);
if (uproc->attrs)
ioctl.inv.sc = REMOTE_SCALARS_MAKE(7, 6, 0);
@@ -2392,7 +2421,7 @@
ra[2].buf.pv = (void *)pages;
ra[2].buf.len = sizeof(*pages);
fds[2] = 0;
- ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
+ ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
ioctl.inv.sc = REMOTE_SCALARS_MAKE(8, 3, 0);
ioctl.inv.pra = ra;
@@ -2428,6 +2457,119 @@
return err;
}
+static int fastrpc_get_info_from_dsp(struct fastrpc_file *fl,
+ uint32_t *dsp_attr_buf,
+ uint32_t dsp_attr_buf_len,
+ uint32_t domain)
+{
+ int err = 0, dsp_support = 0;
+ struct fastrpc_ioctl_invoke_crc ioctl;
+ remote_arg_t ra[2];
+ struct fastrpc_apps *me = &gfa;
+
+ // Querying device about DSP support
+ switch (domain) {
+ case ADSP_DOMAIN_ID:
+ case SDSP_DOMAIN_ID:
+ case CDSP_DOMAIN_ID:
+ if (me->channel[domain].issubsystemup)
+ dsp_support = 1;
+ break;
+ case MDSP_DOMAIN_ID:
+ //Modem not supported for fastRPC
+ break;
+ default:
+ dsp_support = 0;
+ break;
+ }
+ dsp_attr_buf[0] = dsp_support;
+
+ if (dsp_support == 0) {
+ err = -ENOTCONN;
+ goto bail;
+ }
+
+ err = fastrpc_channel_open(fl);
+ if (err)
+ goto bail;
+
+ ra[0].buf.pv = (void *)&dsp_attr_buf_len;
+ ra[0].buf.len = sizeof(dsp_attr_buf_len);
+ ra[1].buf.pv = (void *)(&dsp_attr_buf[1]);
+ ra[1].buf.len = dsp_attr_buf_len * sizeof(uint32_t);
+ ioctl.inv.handle = FASTRPC_STATIC_HANDLE_DSP_UTILITIES;
+ ioctl.inv.sc = REMOTE_SCALARS_MAKE(0, 1, 1);
+ ioctl.inv.pra = ra;
+ ioctl.fds = NULL;
+ ioctl.attrs = NULL;
+ ioctl.crc = NULL;
+ fl->pd = 1;
+
+ err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl);
+bail:
+
+ if (err)
+ pr_err("adsprpc: %s: %s: could not obtain dsp information, err val 0x%x\n",
+ current->comm, __func__, err);
+ return err;
+}
+
+static int fastrpc_get_info_from_kernel(
+ struct fastrpc_ioctl_dsp_capabilities *dsp_cap,
+ struct fastrpc_file *fl)
+{
+ int err = 0;
+ uint32_t domain_support;
+ uint32_t domain = dsp_cap->domain;
+
+ if (!gcinfo[domain].dsp_cap_kernel.is_cached) {
+ /*
+ * Information not on kernel, query device for information
+ * and cache on kernel
+ */
+ err = fastrpc_get_info_from_dsp(fl, dsp_cap->dsp_attributes,
+ FASTRPC_MAX_DSP_ATTRIBUTES - 1,
+ domain);
+ if (err)
+ goto bail;
+
+ domain_support = dsp_cap->dsp_attributes[0];
+ switch (domain_support) {
+ case 0:
+ memset(dsp_cap->dsp_attributes, 0,
+ sizeof(dsp_cap->dsp_attributes));
+ memset(&gcinfo[domain].dsp_cap_kernel.dsp_attributes,
+ 0, sizeof(dsp_cap->dsp_attributes));
+ break;
+ case 1:
+ memcpy(&gcinfo[domain].dsp_cap_kernel.dsp_attributes,
+ dsp_cap->dsp_attributes,
+ sizeof(dsp_cap->dsp_attributes));
+ break;
+ default:
+ err = -1;
+ /*
+ * Reset is_cached flag to 0 so subsequent calls
+ * can try to query dsp again
+ */
+ gcinfo[domain].dsp_cap_kernel.is_cached = 0;
+ pr_warn("adsprpc: %s: %s: returned bad domain support value %d\n",
+ current->comm,
+ __func__,
+ domain_support);
+ goto bail;
+ }
+ gcinfo[domain].dsp_cap_kernel.is_cached = 1;
+ } else {
+ // Information on Kernel, pass it to user
+ memcpy(dsp_cap->dsp_attributes,
+ &gcinfo[domain].dsp_cap_kernel.dsp_attributes,
+ sizeof(dsp_cap->dsp_attributes));
+ }
+bail:
+ return err;
+}
+
static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl)
{
int err = 0;
@@ -2447,7 +2589,7 @@
tgid = fl->tgid;
ra[0].buf.pv = (void *)&tgid;
ra[0].buf.len = sizeof(tgid);
- ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
+ ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
ioctl.inv.sc = REMOTE_SCALARS_MAKE(1, 1, 0);
ioctl.inv.pra = ra;
ioctl.fds = NULL;
@@ -2493,7 +2635,7 @@
ra[2].buf.pv = (void *)&routargs;
ra[2].buf.len = sizeof(routargs);
- ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
+ ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
if (fl->apps->compat)
ioctl.inv.sc = REMOTE_SCALARS_MAKE(4, 2, 1);
else
@@ -2554,7 +2696,7 @@
ra[1].buf.pv = (void *)&routargs;
ra[1].buf.len = sizeof(routargs);
- ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
+ ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
ioctl.inv.sc = REMOTE_SCALARS_MAKE(9, 1, 1);
ioctl.inv.pra = ra;
ioctl.fds = NULL;
@@ -2616,7 +2758,7 @@
ra[0].buf.pv = (void *)&inargs;
ra[0].buf.len = sizeof(inargs);
- ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
+ ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
if (fl->apps->compat)
ioctl.inv.sc = REMOTE_SCALARS_MAKE(5, 1, 0);
else
@@ -3658,6 +3800,7 @@
{
int err = 0;
uint32_t cid;
+ struct fastrpc_apps *me = &gfa;
VERIFY(err, fl != NULL);
if (err)
@@ -3665,8 +3808,10 @@
err = fastrpc_set_process_info(fl);
if (err)
goto bail;
+ cid = *info;
if (fl->cid == -1) {
- cid = *info;
+ struct fastrpc_channel_ctx *chan = &me->channel[cid];
+
VERIFY(err, cid < NUM_CHANNELS);
if (err)
goto bail;
@@ -3674,13 +3819,13 @@
if (fl->dev_minor == MINOR_NUM_DEV &&
fl->apps->secure_flag == true) {
/*
- * For non secure device node check and make sure that
- * the channel allows non-secure access
- * If not, bail. Session will not start.
- * cid will remain -1 and client will not be able to
- * invoke any other methods without failure
+ * If an app is trying to offload to a secure remote
+ * channel by opening the non-secure device node, allow
+ * the access if the subsystem supports unsigned
+ * offload. Untrusted apps will be restricted.
*/
- if (fl->apps->channel[cid].secure == SECURE_CHANNEL) {
+ if (chan->secure == SECURE_CHANNEL &&
+ !chan->unsigned_support) {
err = -EPERM;
pr_err("adsprpc: GetInfo failed dev %d, cid %d, secure %d\n",
fl->dev_minor, cid,
@@ -3750,6 +3895,47 @@
return err;
}
+static int fastrpc_get_dsp_info(struct fastrpc_ioctl_dsp_capabilities *dsp_cap,
+ void *param, struct fastrpc_file *fl)
+{
+ int err = 0;
+
+ K_COPY_FROM_USER(err, 0, dsp_cap, param,
+ sizeof(struct fastrpc_ioctl_dsp_capabilities));
+ VERIFY(err, dsp_cap->domain < NUM_CHANNELS);
+ if (err)
+ goto bail;
+
+ err = fastrpc_get_info_from_kernel(dsp_cap, fl);
+ if (err)
+ goto bail;
+ K_COPY_TO_USER(err, 0, param, dsp_cap,
+ sizeof(struct fastrpc_ioctl_dsp_capabilities));
+bail:
+ return err;
+}
+
+static int fastrpc_update_cdsp_support(struct fastrpc_file *fl)
+{
+ struct fastrpc_ioctl_dsp_capabilities *dsp_query;
+ struct fastrpc_apps *me = &gfa;
+ int err = 0;
+
+ VERIFY(err, NULL != (dsp_query = kzalloc(sizeof(*dsp_query),
+ GFP_KERNEL)));
+ if (err)
+ goto bail;
+ dsp_query->domain = CDSP_DOMAIN_ID;
+ err = fastrpc_get_info_from_kernel(dsp_query, fl);
+ if (err)
+ goto bail;
+ if (!(dsp_query->dsp_attributes[1]))
+ me->channel[CDSP_DOMAIN_ID].unsigned_support = false;
+bail:
+ kfree(dsp_query);
+ return err;
+}
+
static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
unsigned long ioctl_param)
{
@@ -3763,6 +3949,7 @@
struct fastrpc_ioctl_init_attrs init;
struct fastrpc_ioctl_perf perf;
struct fastrpc_ioctl_control cp;
+ struct fastrpc_ioctl_dsp_capabilities dsp_cap;
} p;
union {
struct fastrpc_ioctl_mmap mmap;
@@ -3770,8 +3957,9 @@
} i;
void *param = (char *)ioctl_param;
struct fastrpc_file *fl = (struct fastrpc_file *)file->private_data;
- int size = 0, err = 0;
+ int size = 0, err = 0, req_complete = 0;
uint32_t info;
+ static bool isQueryDone;
VERIFY(err, fl != NULL);
if (err) {
@@ -3972,8 +4160,15 @@
VERIFY(err, 0 == (err = fastrpc_init_process(fl, &p.init)));
if (err)
goto bail;
+ if ((fl->cid == CDSP_DOMAIN_ID) && !isQueryDone) {
+ req_complete = fastrpc_update_cdsp_support(fl);
+ if (!req_complete)
+ isQueryDone = true;
+ }
break;
-
+ case FASTRPC_IOCTL_GET_DSP_INFO:
+ err = fastrpc_get_dsp_info(&p.dsp_cap, param, fl);
+ break;
default:
err = -ENOTTY;
pr_info("bad ioctl: %d\n", ioctl_num);
diff --git a/drivers/char/adsprpc_compat.c b/drivers/char/adsprpc_compat.c
index 3b54243..3d72ad2 100644
--- a/drivers/char/adsprpc_compat.c
+++ b/drivers/char/adsprpc_compat.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2021, 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
@@ -43,6 +43,8 @@
_IOWR('R', 14, struct compat_fastrpc_ioctl_mmap_64)
#define COMPAT_FASTRPC_IOCTL_MUNMAP_64 \
_IOWR('R', 15, struct compat_fastrpc_ioctl_munmap_64)
+#define COMPAT_FASTRPC_IOCTL_GET_DSP_INFO \
+ _IOWR('R', 16, struct compat_fastrpc_ioctl_dsp_capabilities)
struct compat_remote_buf {
compat_uptr_t pv; /* buffer pointer */
@@ -151,6 +153,11 @@
};
};
+struct compat_fastrpc_ioctl_dsp_capabilities {
+ compat_uint_t domain; /* DSP domain to query capabilities */
+ compat_uint_t dsp_attributes[FASTRPC_MAX_DSP_ATTRIBUTES];
+};
+
static int compat_get_fastrpc_ioctl_invoke(
struct compat_fastrpc_ioctl_invoke_crc __user *inv32,
struct fastrpc_ioctl_invoke_crc __user **inva,
@@ -389,6 +396,53 @@
return err;
}
+static int compat_put_fastrpc_ioctl_get_dsp_info(
+ struct compat_fastrpc_ioctl_dsp_capabilities __user *info32,
+ struct fastrpc_ioctl_dsp_capabilities __user *info)
+{
+ compat_uint_t u;
+ int err, ii;
+
+ for (ii = 0, err = 0; ii < FASTRPC_MAX_DSP_ATTRIBUTES; ii++) {
+ err |= get_user(u, &info->dsp_attributes[ii]);
+ err |= put_user(u, &info32->dsp_attributes[ii]);
+ }
+
+ return err;
+}
+
+
+
+static int compat_fastrpc_get_dsp_info(struct file *filp,
+ unsigned long arg)
+{
+ struct compat_fastrpc_ioctl_dsp_capabilities __user *info32;
+ struct fastrpc_ioctl_dsp_capabilities __user *info;
+ compat_uint_t u;
+ long ret;
+ int err = 0;
+
+ info32 = compat_ptr(arg);
+ VERIFY(err, NULL != (info = compat_alloc_user_space(
+ sizeof(*info))));
+ if (err)
+ return -EFAULT;
+
+ err = get_user(u, &info32->domain);
+ err |= put_user(u, &info->domain);
+ if (err)
+ return err;
+
+ ret = filp->f_op->unlocked_ioctl(filp,
+ FASTRPC_IOCTL_GET_DSP_INFO,
+ (unsigned long)info);
+ if (ret)
+ return ret;
+
+ err = compat_put_fastrpc_ioctl_get_dsp_info(info32, info);
+ return err;
+}
+
long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
@@ -588,6 +642,8 @@
err |= put_user(u, &perf32->numkeys);
return err;
}
+ case COMPAT_FASTRPC_IOCTL_GET_DSP_INFO:
+ return compat_fastrpc_get_dsp_info(filp, arg);
default:
return -ENOIOCTLCMD;
}
diff --git a/drivers/char/adsprpc_shared.h b/drivers/char/adsprpc_shared.h
index 24fad76..6fcf826 100644
--- a/drivers/char/adsprpc_shared.h
+++ b/drivers/char/adsprpc_shared.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2021, 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
@@ -32,6 +32,8 @@
#define FASTRPC_IOCTL_INVOKE_CRC _IOWR('R', 11, struct fastrpc_ioctl_invoke_crc)
#define FASTRPC_IOCTL_CONTROL _IOWR('R', 12, struct fastrpc_ioctl_control)
#define FASTRPC_IOCTL_MUNMAP_FD _IOWR('R', 13, struct fastrpc_ioctl_munmap_fd)
+#define FASTRPC_IOCTL_GET_DSP_INFO \
+ _IOWR('R', 16, struct fastrpc_ioctl_dsp_capabilities)
#define FASTRPC_GLINK_GUID "fastrpcglink-apps-dsp"
#define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp"
@@ -269,6 +271,12 @@
};
};
+#define FASTRPC_MAX_DSP_ATTRIBUTES (7)
+struct fastrpc_ioctl_dsp_capabilities {
+ uint32_t domain; //! DSP domain to query capabilities
+ uint32_t dsp_attributes[FASTRPC_MAX_DSP_ATTRIBUTES];
+};
+
struct smq_null_invoke {
uint64_t ctx; /* invoke caller context */
uint32_t handle; /* handle to invoke */
@@ -317,4 +325,19 @@
return (struct smq_phy_page *)(&buf[nTotal]);
}
+enum fastrpc_proc_attr {
+ /* Macro for Debug attr */
+ FASTRPC_MODE_DEBUG = 1 << 0,
+ /* Macro for Ptrace */
+ FASTRPC_MODE_PTRACE = 1 << 1,
+ /* Macro for CRC Check */
+ FASTRPC_MODE_CRC = 1 << 2,
+ /* Macro for Unsigned PD */
+ FASTRPC_MODE_UNSIGNED_MODULE = 1 << 3,
+ /* Macro for Adaptive QoS */
+ FASTRPC_MODE_ADAPTIVE_QOS = 1 << 4,
+ /* Macro for System Process */
+ FASTRPC_MODE_SYSTEM_PROCESS = 1 << 5,
+};
+
#endif
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
index f531c38..ba07d79 100644
--- a/drivers/char/diag/diag_dci.c
+++ b/drivers/char/diag/diag_dci.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2021, 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
@@ -1063,6 +1063,11 @@
return;
}
+ if (token != entry->client_info.token) {
+ mutex_unlock(&driver->dci_mutex);
+ return;
+ }
+
mutex_lock(&entry->buffers[data_source].buf_mutex);
rsp_buf = entry->buffers[data_source].buf_cmd;
diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c
index cf539f1..3215b95 100644
--- a/drivers/crypto/msm/qce50.c
+++ b/drivers/crypto/msm/qce50.c
@@ -1,7 +1,7 @@
/*
* QTI Crypto Engine driver.
*
- * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2021, 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
@@ -870,6 +870,11 @@
break;
case CIPHER_ALG_3DES:
if (creq->mode != QCE_MODE_ECB) {
+ if (ivsize > MAX_IV_LENGTH) {
+ pr_err("%s: error: Invalid length parameter\n",
+ __func__);
+ return -EINVAL;
+ }
_byte_stream_to_net_words(enciv32, creq->iv, ivsize);
pce = cmdlistinfo->encr_cntr_iv;
pce->data = enciv32[0];
@@ -918,6 +923,11 @@
}
}
if (creq->mode != QCE_MODE_ECB) {
+ if (ivsize > MAX_IV_LENGTH) {
+ pr_err("%s: error: Invalid length parameter\n",
+ __func__);
+ return -EINVAL;
+ }
if (creq->mode == QCE_MODE_XTS)
_byte_stream_swap_to_net_words(enciv32,
creq->iv, ivsize);
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index 9bf732b..eed9eff 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2021, 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
@@ -780,6 +780,9 @@
return -ENODEV;
}
+ if (dp->usbpd->hpd_high && dp->usbpd->hpd_irq)
+ drm_dp_cec_irq(dp->aux->drm_aux);
+
if (dp->usbpd->hpd_irq && dp->usbpd->hpd_high &&
dp->power_on) {
dp->link->process_request(dp->link);
@@ -1053,25 +1056,6 @@
mode->timing.bpp = dp->panel->get_mode_bpp(dp->panel,
mode->timing.bpp, pixel_clk_khz);
- /* Refactor bits per pixel for YUV422 format */
- if (mode->timing.out_format == MSM_MODE_FLAG_COLOR_FORMAT_YCBCR422) {
- switch (mode->timing.bpp) {
- case 18:
- mode->timing.bpp = 24;
- break;
- case 24:
- mode->timing.bpp = 30;
- break;
- case 30:
- mode->timing.bpp = 36;
- break;
- default:
- mode->timing.bpp = 30;
- break;
- };
- pr_debug("YCC422 bpp = %d\n", mode->timing.bpp);
- }
-
dp->panel->pinfo = mode->timing;
dp->panel->init(dp->panel);
mutex_unlock(&dp->session_lock);
diff --git a/drivers/gpu/drm/msm/dp/dp_link.c b/drivers/gpu/drm/msm/dp/dp_link.c
index a188cfa..410e075 100644
--- a/drivers/gpu/drm/msm/dp/dp_link.c
+++ b/drivers/gpu/drm/msm/dp/dp_link.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2018, 2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018,2020-2021, 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
@@ -790,8 +790,6 @@
pr_debug("device service irq vector = 0x%x\n", data);
- drm_dp_cec_irq(link->aux->drm_aux);
-
if (!(data & DP_AUTOMATED_TEST_REQUEST)) {
pr_debug("no test requested\n");
return 0;
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 0577b6d..edfb2ca 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -263,9 +263,9 @@
kref_init(&entry->refcount);
/* put this ref in userspace memory alloc and map ioctls */
kref_get(&entry->refcount);
+ atomic_set(&entry->map_count, 0);
}
- atomic_set(&entry->map_count, 0);
return entry;
}
#ifdef CONFIG_DMA_SHARED_BUFFER
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index 82536f4..399eb6d 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -225,8 +225,9 @@
static void kgsl_iommu_add_global(struct kgsl_mmu *mmu,
struct kgsl_memdesc *memdesc, const char *name)
{
- u32 bit, start = 0;
+ u32 bit;
u64 size = kgsl_memdesc_footprint(memdesc);
+ int start = 0;
if (memdesc->gpuaddr != 0)
return;
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 4b781b3..5717f6f 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -91,7 +91,7 @@
* Register a new field for this report.
*/
-static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values)
+static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages)
{
struct hid_field *field;
@@ -102,7 +102,7 @@
field = kzalloc((sizeof(struct hid_field) +
usages * sizeof(struct hid_usage) +
- values * sizeof(unsigned)), GFP_KERNEL);
+ usages * sizeof(unsigned)), GFP_KERNEL);
if (!field)
return NULL;
@@ -281,7 +281,7 @@
usages = max_t(unsigned, parser->local.usage_index,
parser->global.report_count);
- field = hid_register_field(report, usages, parser->global.report_count);
+ field = hid_register_field(report, usages);
if (!field)
return 0;
diff --git a/drivers/hwmon/qpnp-adc-common.c b/drivers/hwmon/qpnp-adc-common.c
old mode 100644
new mode 100755
index 5a54b73..2d3a901
--- a/drivers/hwmon/qpnp-adc-common.c
+++ b/drivers/hwmon/qpnp-adc-common.c
@@ -659,76 +659,76 @@
/* Voltage to temperature */
static const struct qpnp_vadc_map_pt adcmap_batt_therm[] = {
- {1770, -400},
- {1757, -380},
- {1743, -360},
- {1727, -340},
- {1710, -320},
- {1691, -300},
- {1671, -280},
- {1650, -260},
- {1627, -240},
- {1602, -220},
- {1576, -200},
- {1548, -180},
- {1519, -160},
- {1488, -140},
- {1456, -120},
- {1423, -100},
- {1388, -80},
- {1353, -60},
- {1316, -40},
- {1278, -20},
- {1240, 0},
- {1201, 20},
- {1162, 40},
- {1122, 60},
- {1082, 80},
- {1042, 100},
- {1003, 120},
- {964, 140},
- {925, 160},
- {887, 180},
- {849, 200},
- {812, 220},
- {777, 240},
- {742, 260},
- {708, 280},
- {675, 300},
- {643, 320},
- {613, 340},
- {583, 360},
- {555, 380},
- {528, 400},
- {502, 420},
- {477, 440},
- {453, 460},
- {430, 480},
- {409, 500},
- {388, 520},
- {369, 540},
- {350, 560},
- {333, 580},
- {316, 600},
- {300, 620},
- {285, 640},
- {271, 660},
- {257, 680},
- {245, 700},
- {233, 720},
- {221, 740},
- {210, 760},
- {200, 780},
- {190, 800},
- {181, 820},
- {173, 840},
- {164, 860},
- {157, 880},
- {149, 900},
- {142, 920},
- {136, 940},
- {129, 960},
- {124, 980}
+ {1819, -400},
+ {1812, -380},
+ {1803, -360},
+ {1794, -340},
+ {1784, -320},
+ {1773, -300},
+ {1761, -280},
+ {1747, -260},
+ {1732, -240},
+ {1716, -220},
+ {1699, -200},
+ {1680, -180},
+ {1659, -160},
+ {1637, -140},
+ {1613, -120},
+ {1588, -100},
+ {1561, -80},
+ {1532, -60},
+ {1501, -40},
+ {1470, -20},
+ {1436, 0},
+ {1401, 20},
+ {1365, 40},
+ {1327, 60},
+ {1289, 80},
+ {1249, 100},
+ {1209, 120},
+ {1167, 140},
+ {1126, 160},
+ {1084, 180},
+ {1042, 200},
+ {1000, 220},
+ {958, 240},
+ {916, 260},
+ {875, 280},
+ {835, 300},
+ {796, 320},
+ {757, 340},
+ {720, 360},
+ {683, 380},
+ {648, 400},
+ {614, 420},
+ {581, 440},
+ {550, 460},
+ {520, 480},
+ {491, 500},
+ {463, 520},
+ {437, 540},
+ {412, 560},
+ {389, 580},
+ {367, 600},
+ {345, 620},
+ {325, 640},
+ {306, 660},
+ {289, 680},
+ {272, 700},
+ {256, 720},
+ {241, 740},
+ {227, 760},
+ {214, 780},
+ {201, 800},
+ {190, 820},
+ {179, 840},
+ {169, 860},
+ {159, 880},
+ {150, 900},
+ {141, 920},
+ {133, 940},
+ {126, 960},
+ {119, 980}
};
/* Voltage to temperature */
@@ -2471,7 +2471,7 @@
pr_debug("raw_code:%x, v_adc:%lld\n", adc_code,
adc_chan_result->physical);
- /* T = (1.49322 – V) / 0.00356 */
+ /* T = (1.49322 ??V) / 0.00356 */
adc_chan_result->physical = 1493220 - adc_chan_result->physical;
adc_chan_result->physical = div64_s64(adc_chan_result->physical, 356);
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
old mode 100644
new mode 100755
index de41b16..411bf8e
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -200,6 +200,15 @@
---help---
Say Y here if you want to take action when some keys are pressed;
+config ELAN_FINGERPRINT
+ tristate "ELAN Fingerprint"
+ default n
+ ---help---
+ Fingerprint qualcomm driver enable/disable in the kernel.
+ Say Y here if you want to use qualcomm fingerprint driver,
+ fingerprint driver will support fingerprint function in TEE,
+ it supports ELNA's all fingerprint device.
+
comment "Input Device Drivers"
source "drivers/input/keyboard/Kconfig"
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
old mode 100644
new mode 100755
index 7ff1b70..9d9d222
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -34,3 +34,5 @@
obj-$(CONFIG_INPUT_KEYRESET) += keyreset.o
obj-$(CONFIG_INPUT_KEYCOMBO) += keycombo.o
obj-$(CONFIG_SMI130) += sensors/smi130/
+
+obj-$(CONFIG_ELAN_FINGERPRINT) +=fingerprint/
diff --git a/drivers/input/fingerprint/Makefile b/drivers/input/fingerprint/Makefile
new file mode 100755
index 0000000..4b4eb3a
--- /dev/null
+++ b/drivers/input/fingerprint/Makefile
@@ -0,0 +1,2 @@
+
+obj-$(CONFIG_ELAN_FINGERPRINT)=elan_fp_qcom_tee.o
\ No newline at end of file
diff --git a/drivers/input/fingerprint/elan_fp_qcom_tee.c b/drivers/input/fingerprint/elan_fp_qcom_tee.c
new file mode 100755
index 0000000..b9efba4
--- /dev/null
+++ b/drivers/input/fingerprint/elan_fp_qcom_tee.c
@@ -0,0 +1,683 @@
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/input/mt.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/async.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/kthread.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+#include <linux/version.h>
+#include <linux/slab.h>
+#include <linux/wait.h>
+#include <linux/io.h>
+#include <linux/ioctl.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/syscalls.h>
+#include <linux/err.h>
+#include <linux/cdev.h>
+#include <linux/types.h>
+#include <linux/pm_wakeup.h> //#include <linux/wakelock.h>
+#include <linux/sched.h>
+#include <linux/mutex.h>
+#include <linux/pm.h>
+#include <linux/time.h>
+#include <linux/namei.h>
+#include <linux/mount.h>
+#include <linux/poll.h>
+#include <linux/of_gpio.h>
+#include "elan_fp_qcom_tee.h"
+
+#define VERSION_LOG "2.2.1"
+
+static int elan_debug = 1;
+#define ELAN_DEBUG(format, args ...) \
+do { \
+ if (elan_debug) \
+ printk("[ELAN] " format, ##args); \
+ } while(0)
+
+#define KEY_FP_INT KEY_POWER //KEY_WAKEUP // change by customer & framework support
+#define KEY_FP_INT2 KEY_1 // change by customer & framework support
+#define SET_SPI_OWNER (0)
+#if SET_SPI_OWNER
+#include <soc/qcom/scm.h>
+#endif
+
+#if defined(CONFIG_FB)
+#include <linux/notifier.h>
+#include <linux/fb.h>
+#include <linux/signal.h>
+#endif
+
+static int factory_status = 0;
+static DEFINE_MUTEX(elan_factory_mutex);
+static DECLARE_WAIT_QUEUE_HEAD(elan_poll_wq);
+static int elan_work_flag = 0;
+#if defined(CONFIG_FB)
+static struct notifier_block fb_notif;
+static int pid_fp = -1;
+static int display_status = -1;
+#endif
+#define VDD_POWER_GPIO 1
+struct elan_data {
+ int int_gpio;
+ int irq;
+ int rst_gpio;
+ int irq_is_disable;
+ struct miscdevice elan_dev; /* char device for ioctl */
+ struct platform_device *pdev;
+ struct input_dev *input_dev;
+ spinlock_t irq_lock;
+ struct wakeup_source wake_lock; //struct wake_lock wake_lock;
+ struct wakeup_source hal_wake_lock; //struct wake_lock hal_wake_lock;
+#if VDD_POWER_GPIO
+ int vdd_gpio;
+#endif
+};
+
+void elan_irq_enable(void *_fp)
+{
+ struct elan_data *fp = _fp;
+ unsigned long irqflags = 0;
+ ELAN_DEBUG("IRQ Enable = %d.\n", fp->irq);
+
+ spin_lock_irqsave(&fp->irq_lock, irqflags);
+ if (fp->irq_is_disable)
+ {
+ enable_irq(fp->irq);
+ fp->irq_is_disable = 0;
+ }
+ spin_unlock_irqrestore(&fp->irq_lock, irqflags);
+}
+
+void elan_irq_disable(void *_fp)
+{
+ struct elan_data *fp = _fp;
+ unsigned long irqflags;
+ ELAN_DEBUG("IRQ Disable = %d.\n", fp->irq);
+
+ spin_lock_irqsave(&fp->irq_lock, irqflags);
+ if (!fp->irq_is_disable)
+ {
+ fp->irq_is_disable = 1;
+ disable_irq_nosync(fp->irq);
+ }
+ spin_unlock_irqrestore(&fp->irq_lock, irqflags);
+}
+
+static ssize_t show_drv_version_value(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%s\n", VERSION_LOG);
+}
+static DEVICE_ATTR(drv_version, S_IRUGO, show_drv_version_value, NULL);
+
+static ssize_t elan_debug_value(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ if(elan_debug){
+ elan_debug=0;
+ } else {
+ elan_debug=1;
+ }
+ return sprintf(buf, "[ELAN] elan debug %d\n", elan_debug);
+}
+static DEVICE_ATTR(elan_debug, S_IRUGO, elan_debug_value, NULL);
+
+static struct attribute *elan_attributes[] = {
+ &dev_attr_drv_version.attr,
+ &dev_attr_elan_debug.attr,
+ NULL
+};
+
+static struct attribute_group elan_attr_group = {
+ .attrs = elan_attributes,
+};
+
+static void elan_reset(struct elan_data *fp)
+{
+ /* Developement platform */
+ gpio_set_value(fp->rst_gpio, 0);
+ mdelay(5);
+ gpio_set_value(fp->rst_gpio, 1);
+ mdelay(50);
+}
+
+#if defined(CONFIG_FB)
+
+static int send_sig_to_pid(int sig, pid_t pid)
+{
+ struct siginfo info;
+
+ info.si_signo = sig;
+ info.si_errno = 0;
+ info.si_code = SI_USER;
+ info.si_pid = get_current()->pid;
+ info.si_uid = from_kuid_munged(current_user_ns(), current_uid());
+
+ return kill_proc_info(sig, &info, pid);
+}
+
+static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data)
+{
+ struct fb_event *evdata = data;
+ int *blank ;
+
+ if (event != 0x10)
+ return 0;
+
+ if(evdata == NULL)
+ {
+ pr_err("%s data is NULL\n",__func__);
+ return 0;
+ }
+ blank = evdata->data;
+ if(blank == NULL)
+ {
+ pr_err("%s blank is NULL\n",__func__);
+ return 0;
+ }
+ ELAN_DEBUG("%s fb notifier callback event = %lu, evdata->data = %d\n",__func__, event, *blank);
+ if (evdata && evdata->data) {
+ if (event == 0x10) {
+ if (*blank == FB_BLANK_UNBLANK) {
+ display_status = 0;
+ if(pid_fp != -1)
+ send_sig_to_pid(SIGUSR2,pid_fp);
+ ELAN_DEBUG("Display On\n");
+ }
+ else if (*blank == FB_BLANK_POWERDOWN) {
+ display_status = 1;
+ if(pid_fp != -1)
+ send_sig_to_pid(SIGUSR2,pid_fp);
+ ELAN_DEBUG("Display Off\n");
+ }
+ }
+ }
+ return 0;
+}
+#endif
+
+static long elan_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ struct elan_data *fp = filp->private_data;
+ int keycode;
+ int wake_lock_arg;
+
+ ELAN_DEBUG("%s() : cmd = [%04X]\n", __func__, cmd);
+
+ switch(cmd)
+ {
+ case ID_IOCTL_RESET: //6
+ elan_reset(fp);
+ ELAN_DEBUG("[IOCTL] RESET\n");
+ break;
+
+ case ID_IOCTL_POLL_INIT: //20
+ elan_work_flag = 0;
+ ELAN_DEBUG("[IOCTL] POLL INIT\n");
+ break;
+
+ case ID_IOCTL_POLL_EXIT: //23
+ elan_work_flag = 1;
+ wake_up(&elan_poll_wq);
+ ELAN_DEBUG("[IOCTL] POLL EXIT\n");
+ break;
+
+ case ID_IOCTL_INPUT_KEYCODE: //22
+ keycode =(int __user)arg;
+ ELAN_DEBUG("[IOCTL] KEYCODE DOWN & UP, keycode = %d \n", keycode);
+ if (!keycode) {
+ ELAN_DEBUG("Keycode %d not defined, ignored\n", (int __user)arg);
+ break ;
+ }
+ input_report_key(fp->input_dev, keycode, 1); // Added for KEY Event
+ input_sync(fp->input_dev);
+ input_report_key(fp->input_dev, keycode, 0); // Added for KEY Event
+ input_sync(fp->input_dev);
+ break;
+
+ case ID_IOCTL_SET_KEYCODE: //24
+ keycode =(int __user)arg;
+ ELAN_DEBUG("[IOCTL] SET KEYCODE, keycode = %d \n", keycode);
+ if (!keycode) {
+ ELAN_DEBUG("Keycode %d not defined, ignored\n", (int __user)arg);
+ break ;
+ }
+ input_set_capability(fp->input_dev, EV_KEY, keycode);
+ set_bit(keycode, fp->input_dev->keybit);
+ break;
+
+ case ID_IOCTL_INPUT_KEYCODE_DOWN: //28
+ keycode =(int __user)arg;
+ ELAN_DEBUG("[IOCTL] KEYCODE DOWN, keycode = %d \n", keycode);
+ if(!keycode) {
+ ELAN_DEBUG("Keycode %d not defined, ignored\n", (int __user)arg);
+ break ;
+ }
+ input_report_key(fp->input_dev, keycode, 1);
+ input_sync(fp->input_dev);
+ break;
+
+ case ID_IOCTL_INPUT_KEYCODE_UP: //29
+ keycode =(int __user)arg;
+ ELAN_DEBUG("[IOCTL] KEYCODE UP, keycode = %d \n", keycode);
+ if(!keycode) {
+ ELAN_DEBUG("Keycode %d not defined, ignored\n", (int __user)arg);
+ break ;
+ }
+ input_report_key(fp->input_dev, keycode, 0);
+ input_sync(fp->input_dev);
+ break;
+
+ case ID_IOCTL_READ_FACTORY_STATUS: //26
+ mutex_lock(&elan_factory_mutex);
+ ELAN_DEBUG("[IOCTL] READ factory_status = %d\n", factory_status);
+ mutex_unlock(&elan_factory_mutex);
+ return factory_status;
+ break;
+
+ case ID_IOCTL_WRITE_FACTORY_STATUS: //27
+ mutex_lock(&elan_factory_mutex);
+ factory_status = (int __user)arg;
+ ELAN_DEBUG("[IOCTL] WRITE factory_status = %d\n", factory_status);
+ mutex_unlock(&elan_factory_mutex);
+ break;
+
+ case ID_IOCTL_INT_STATUS: //40
+ return gpio_get_value(fp->int_gpio);
+
+ case ID_IOCTL_WAKE_LOCK_UNLOCK: //41
+ wake_lock_arg = (int __user)arg;
+ if(!wake_lock_arg)
+ {
+ __pm_relax(&fp->hal_wake_lock); //wake_unlock(&fp->hal_wake_lock);
+ ELAN_DEBUG("[IOCTL] HAL WAKE UNLOCK = %d\n", wake_lock_arg);
+ }
+ else if(wake_lock_arg)
+ {
+ __pm_stay_awake(&fp->hal_wake_lock); //wake_lock(&fp->hal_wake_lock);
+ ELAN_DEBUG("[IOCTL] HAL WAKE LOCK = %d\n", wake_lock_arg);
+ }
+ else
+ ELAN_DEBUG("[IOCTL] ERROR WAKE LOCK ARGUMENT\n");
+ break;
+
+ case ID_IOCTL_EN_IRQ: //55
+ elan_irq_enable(fp);
+ ELAN_DEBUG("[IOCTL] ENABLE IRQ\n");
+ break;
+
+ case ID_IOCTL_DIS_IRQ: //66
+ elan_irq_disable(fp);
+ ELAN_DEBUG("[IOCTL] DISABLE IRQ\n");
+ break;
+
+ case ID_IOCTL_SET_IRQ_TYPE: //91
+ ELAN_DEBUG("[IOCTL] SET IRQ TYPE\n");
+ irq_set_irq_type(fp->irq, IRQF_TRIGGER_FALLING | IRQF_NO_SUSPEND | IRQF_ONESHOT);
+ break;
+
+ case ID_IOCTL_DISPLAY_STATUS: //93
+ ELAN_DEBUG("[IOCTL] DISPLAY_STATUS = %d\n", display_status);
+ return display_status;
+
+ case ID_IOCTL_DISPLAY_NOTIFY: //94
+ break;
+
+ case ID_IOCTL_SET_PID: //94
+ pid_fp = (int __user)arg;
+ ELAN_DEBUG("[IOCTL] ID_IOCTL_SET_PID = %d\n", pid_fp);
+ break;
+
+ default:
+ ELAN_DEBUG("INVALID COMMAND\n");
+ break;
+ }
+ return 0;
+}
+
+static unsigned int elan_poll(struct file *file, poll_table *wait)
+{
+ int mask=0;
+ ELAN_DEBUG("%s()\n",__func__);
+
+ wait_event_interruptible(elan_poll_wq, elan_work_flag > 0);
+ if(elan_work_flag > 0)
+ mask = elan_work_flag;
+
+ elan_work_flag = 0;
+ return mask;
+}
+
+static int elan_open(struct inode *inode, struct file *filp)
+{
+ struct elan_data *fp = container_of(filp->private_data, struct elan_data, elan_dev);
+ filp->private_data = fp;
+ ELAN_DEBUG("%s()\n", __func__);
+ return 0;
+}
+
+static int elan_close(struct inode *inode, struct file *filp)
+{
+ ELAN_DEBUG("%s()\n", __func__);
+ return 0;
+}
+
+static const struct file_operations elan_fops = {
+ .owner = THIS_MODULE,
+ .open = elan_open,
+ .unlocked_ioctl = elan_ioctl,
+ .poll = elan_poll,
+ .release = elan_close,
+};
+
+#if SET_SPI_OWNER
+static int set_pipe_ownership(void)
+{
+ const u32 TZ_BLSP_MODIFY_OWNERSHIP_ID = 3;
+ const u32 TZBSP_TZ_ID = 3;
+ int rc;
+ struct scm_desc desc = {
+ .arginfo = SCM_ARGS(2),
+ .args[0] = 3,
+ .args[1] = TZBSP_TZ_ID,
+ };
+
+ rc = scm_call2(SCM_SIP_FNID(SCM_SVC_TZ, TZ_BLSP_MODIFY_OWNERSHIP_ID), &desc);
+
+ if(rc || desc.ret[0])
+ {
+ ELAN_DEBUG("%s() FAIL\n", __func__);
+ return -EINVAL;
+ }
+ ELAN_DEBUG("%s() Success\n", __func__);
+ return 0;
+}
+#endif
+
+static irqreturn_t elan_irq_handler(int irq, void *dev_id)
+{
+ struct elan_data *fp = (struct elan_data *)dev_id;
+
+ ELAN_DEBUG("%s()\n", __func__);
+ __pm_wakeup_event(&fp->wake_lock, msecs_to_jiffies(1000)); //wake_lock_timeout(&fp->wake_lock, msecs_to_jiffies(1000));
+ if(fp == NULL)
+ return IRQ_NONE;
+ elan_work_flag = 1;
+ wake_up(&elan_poll_wq);
+
+ return IRQ_HANDLED;
+}
+
+static int elan_setup_cdev(struct elan_data *fp)
+{
+
+ fp->elan_dev.minor = MISC_DYNAMIC_MINOR;
+ fp->elan_dev.name = "elan_fp";
+ fp->elan_dev.fops = &elan_fops;
+ fp->elan_dev.mode = S_IFREG|S_IRWXUGO;
+ if (misc_register(&fp->elan_dev) < 0) {
+ ELAN_DEBUG("misc_register failed\n");
+ return -1;
+ }
+ else {
+ ELAN_DEBUG("misc_register finished\n");
+ }
+ return 0;
+}
+
+static int elan_sysfs_create(struct elan_data *sysfs)
+{
+ struct elan_data *fp = platform_get_drvdata(sysfs->pdev);
+ int ret = 0;
+
+ /* Register sysfs */
+ ret = sysfs_create_group(&fp->pdev->dev.kobj, &elan_attr_group);
+ if (ret) {
+ ELAN_DEBUG("create sysfs attributes failed, ret = %d\n", ret);
+ goto fail_un;
+ }
+ return 0;
+fail_un:
+ /* Remove sysfs */
+ sysfs_remove_group(&fp->pdev->dev.kobj, &elan_attr_group);
+
+ return ret;
+}
+
+static int elan_gpio_config(struct elan_data *fp)
+{
+ int ret = 0;
+
+ // Configure INT GPIO (Input)
+ ret = gpio_request(fp->int_gpio, "elan-irq");
+ if (ret < 0)
+ ELAN_DEBUG("interrupt pin request gpio failed, ret = %d\n", ret);
+ else {
+ gpio_direction_input(fp->int_gpio);
+ fp->irq = gpio_to_irq(fp->int_gpio);
+ if(fp->irq < 0) {
+ ELAN_DEBUG("gpio to irq failed, irq = %d\n", fp->irq);
+ ret = -1;
+ }
+ else
+ ELAN_DEBUG("gpio to irq success, irq = %d\n",fp->irq);
+ }
+
+ // Configure RST GPIO (Output)
+ ret = gpio_request(fp->rst_gpio, "elan-rst");
+ if (ret < 0) {
+ gpio_free(fp->int_gpio);
+ free_irq(fp->irq, fp);
+ ELAN_DEBUG("reset pin request gpio failed, ret = %d\n", ret);
+ }
+ else
+ gpio_direction_output(fp->rst_gpio, 1);
+#if VDD_POWER_GPIO
+ // Configure VDD GPIO (Output)
+ ret = gpio_request(fp->vdd_gpio, "elan-vdd");
+ if (ret < 0) {
+ gpio_free(fp->rst_gpio);
+ gpio_free(fp->int_gpio);
+ free_irq(fp->irq, fp);
+ ELAN_DEBUG("reset pin request gpio failed, ret = %d\n", ret);
+ }
+ else
+ gpio_direction_output(fp->vdd_gpio, 1);
+#endif
+ return ret;
+}
+
+static int elan_dts_init(struct elan_data *fp, struct device_node *np)
+{
+ fp->rst_gpio = of_get_named_gpio(np, "elan,rst-gpio", 0);
+ ELAN_DEBUG("rst_gpio = %d\n", fp->rst_gpio);
+ if (fp->rst_gpio < 0)
+ return fp->rst_gpio;
+
+ fp->int_gpio = of_get_named_gpio(np, "elan,irq-gpio", 0);
+ ELAN_DEBUG("int_gpio = %d\n", fp->int_gpio);
+ if (fp->int_gpio < 0)
+ return fp->int_gpio;
+#if VDD_POWER_GPIO
+ fp->vdd_gpio = of_get_named_gpio(np, "elan,vdd-gpio", 0);
+ ELAN_DEBUG("vdd_gpio = %d\n", fp->vdd_gpio);
+ if (fp->vdd_gpio < 0)
+ return fp->vdd_gpio;
+#endif
+ return 0;
+}
+
+static int elan_probe(struct platform_device *pdev)
+{
+ struct elan_data *fp = NULL;
+ struct input_dev *input_dev = NULL;
+ int ret = 0;
+
+ ELAN_DEBUG("%s(), version = %s\n", __func__, VERSION_LOG);
+
+ /* Allocate Device Data */
+ fp = devm_kzalloc(&pdev->dev, sizeof(struct elan_data), GFP_KERNEL);
+ if(!fp)
+ ELAN_DEBUG("kzmalloc elan data failed\n");
+
+ /* Init Input Device */
+ input_dev = input_allocate_device();
+ if (!input_dev)
+ ELAN_DEBUG("alloc input_dev failed\n");
+
+ fp->pdev = pdev;
+
+ platform_set_drvdata(pdev, fp);
+
+ input_dev->name = "elan";
+ input_dev->id.bustype = BUS_SPI;
+ input_dev->dev.parent = &pdev->dev;
+ input_set_drvdata(input_dev, fp);
+
+ input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY);
+ input_set_capability(input_dev, EV_KEY, KEY_FP_INT); // change by customer, send key event to framework. KEY_xxx could be changed.
+ input_set_capability(input_dev, EV_KEY, KEY_FP_INT2); // change by customer, send key event to framework. KEY_xxx could be changed.
+
+ fp->input_dev = input_dev;
+
+ /* Init Sysfs */
+ ret = elan_sysfs_create(fp);
+ if(ret < 0)
+ ELAN_DEBUG("sysfs create failed, ret = %d\n", ret);
+
+ /* Init Char Device */
+ ret = elan_setup_cdev(fp);
+ if(ret < 0)
+ ELAN_DEBUG("setup device failed, ret = %d\n", ret);
+
+ /* Register Input Device */
+ ret = input_register_device(input_dev);
+ if(ret)
+ ELAN_DEBUG("register input device failed, ret = %d\n", ret);
+
+ ret = elan_dts_init(fp, pdev->dev.of_node);
+ if(ret < 0)
+ ELAN_DEBUG("device tree initial failed, ret = %d\n", ret);
+
+ ret = elan_gpio_config(fp);
+ if(ret < 0)
+ ELAN_DEBUG("gpio config failed, ret = %d\n", ret);
+
+ wakeup_source_init(&fp->wake_lock, "fp_wake_lock"); //wake_lock_init(&fp->wake_lock, WAKE_LOCK_SUSPEND, "fp_wake_lock");
+ wakeup_source_init(&fp->hal_wake_lock, "hal_fp_wake_lock"); //wake_lock_init(&fp->hal_wake_lock, WAKE_LOCK_SUSPEND, "hal_fp_wake_lock");
+
+ ret = request_irq(fp->irq, elan_irq_handler,
+ IRQF_NO_SUSPEND | IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+ pdev->dev.driver->name, fp);
+ if(ret)
+ ELAN_DEBUG("request irq failed, ret = %d\n", ret);
+
+ irq_set_irq_wake(fp->irq, 1);
+
+ spin_lock_init(&fp->irq_lock);
+
+#if defined(CONFIG_FB)
+ fb_notif.notifier_call = fb_notifier_callback;
+ fb_register_client(&fb_notif);
+#endif
+
+ /* Set Spi to TZ */
+#if SET_SPI_OWNER
+ ret = set_pipe_ownership();
+#endif
+
+ ELAN_DEBUG("%s() End\n", __func__);
+ return 0;
+}
+
+static int elan_remove(struct platform_device *pdev)
+{
+ struct elan_data *fp = platform_get_drvdata(pdev);
+
+ if (fp->irq)
+ free_irq(fp->irq, fp);
+#if VDD_POWER_GPIO
+ gpio_free(fp->vdd_gpio);
+#endif
+ gpio_free(fp->int_gpio);
+ gpio_free(fp->rst_gpio);
+
+ misc_deregister(&fp->elan_dev);
+ input_free_device(fp->input_dev);
+
+#if defined(CONFIG_FB)
+ fb_unregister_client(&fb_notif);
+#endif
+
+ kfree(fp);
+
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int elan_suspend(struct device *dev)
+{
+ ELAN_DEBUG("elan suspend!\n");
+ return 0;
+}
+
+static int elan_resume(struct device *dev)
+{
+ ELAN_DEBUG("elan resume!\n");
+ return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(elan_pm_ops, elan_suspend, elan_resume);
+
+#ifdef CONFIG_OF
+static struct of_device_id elan_metallica_table[] = {
+ { .compatible = "elan,elan_fp",},
+ { },
+};
+#else
+#define elan_metallica_table NULL
+#endif
+
+static struct platform_driver elan_driver = {
+ .driver = {
+ .name = "elan",
+ .owner = THIS_MODULE,
+ .pm = &elan_pm_ops,
+ .of_match_table = elan_metallica_table,
+ },
+ .probe = elan_probe,
+ .remove = elan_remove,
+};
+
+static int __init elan_init(void)
+{
+ int ret = 0;
+ ELAN_DEBUG("%s() Start\n", __func__);
+
+ ret = platform_driver_register(&elan_driver);
+ if(ret < 0)
+ ELAN_DEBUG("%s FAIL !\n", __func__);
+
+ ELAN_DEBUG("%s() End\n", __func__);
+ return 0;
+}
+
+static void __exit elan_exist(void)
+{
+ platform_driver_unregister(&elan_driver);
+}
+
+module_init(elan_init);
+module_exit(elan_exist);
+
+MODULE_AUTHOR("Elan");
+MODULE_DESCRIPTION("ELAN SPI FingerPrint driver");
+MODULE_VERSION(VERSION_LOG);
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/fingerprint/elan_fp_qcom_tee.h b/drivers/input/fingerprint/elan_fp_qcom_tee.h
new file mode 100755
index 0000000..a7a74fc
--- /dev/null
+++ b/drivers/input/fingerprint/elan_fp_qcom_tee.h
@@ -0,0 +1,26 @@
+#ifndef _LINUX_ELAN_FP_H
+#define _LINUX_ELAN_FP_H
+
+#define FINGERPRINT_IOCTL 0x80
+#define ID_IOCTL_RESET _IOW(FINGERPRINT_IOCTL, 6, int)
+#define ID_IOCTL_POLL_INIT _IOW(FINGERPRINT_IOCTL, 20, int)
+#define ID_IOCTL_INPUT_KEYCODE _IOW(FINGERPRINT_IOCTL, 22, int)
+#define ID_IOCTL_POLL_EXIT _IOW(FINGERPRINT_IOCTL, 23, int)
+#define ID_IOCTL_SET_KEYCODE _IOW(FINGERPRINT_IOCTL, 24, int)
+#define ID_IOCTL_READ_FACTORY_STATUS _IOW(FINGERPRINT_IOCTL, 26, int)
+#define ID_IOCTL_WRITE_FACTORY_STATUS _IOW(FINGERPRINT_IOCTL, 27, int)
+#define ID_IOCTL_INPUT_KEYCODE_DOWN _IOW(FINGERPRINT_IOCTL, 28, int)
+#define ID_IOCTL_INPUT_KEYCODE_UP _IOW(FINGERPRINT_IOCTL, 29, int)
+#define ID_IOCTL_INT_STATUS _IOW(FINGERPRINT_IOCTL, 40, int)
+#define ID_IOCTL_WAKE_LOCK_UNLOCK _IOW(FINGERPRINT_IOCTL, 41, int)
+#define ID_IOCTL_EN_IRQ _IOW(FINGERPRINT_IOCTL, 55, int)
+#define ID_IOCTL_DIS_IRQ _IOW(FINGERPRINT_IOCTL, 66, int)
+#define ID_IOCTL_SET_IRQ_TYPE _IOW(FINGERPRINT_IOCTL, 91, int)
+#define ID_IOCTL_DISPLAY_STATUS _IOW(FINGERPRINT_IOCTL, 93, int)
+#define ID_IOCTL_DISPLAY_NOTIFY _IOW(FINGERPRINT_IOCTL, 94, int)
+#define ID_IOCTL_SET_PID _IOW(FINGERPRINT_IOCTL, 95, int)
+
+#define CUSTOMER_IOCTLID 0xD0 //For customer define
+
+#endif /* _LINUX_ELAN_FP_H */
+
diff --git a/drivers/input/misc/qpnp-power-on.c b/drivers/input/misc/qpnp-power-on.c
old mode 100644
new mode 100755
index 65379ed..edb21cf
--- a/drivers/input/misc/qpnp-power-on.c
+++ b/drivers/input/misc/qpnp-power-on.c
@@ -313,6 +313,8 @@
[39] = "Triggered from S3_RESET_KPDPWR_ANDOR_RESIN (power key and/or reset line)",
};
+unsigned int qpnp_pon_reason_extern = 0;
+unsigned int qpnp_poff_reason_extern = 0;
static int
qpnp_pon_masked_write(struct qpnp_pon *pon, u16 addr, u8 mask, u8 val)
{
@@ -2287,8 +2289,10 @@
goto err_out;
}
- if (sys_reset)
+ if (sys_reset) {
boot_reason = ffs(pon_sts);
+ qpnp_pon_reason_extern = ffs(pon_sts);
+ }
index = ffs(pon_sts) - 1;
cold_boot = !qpnp_pon_is_warm_reset();
@@ -2322,6 +2326,9 @@
}
poff_sts = buf[0] | (buf[1] << 8);
}
+ if (sys_reset) {
+ qpnp_poff_reason_extern = ffs(poff_sts);
+ }
index = ffs(poff_sts) - 1 + reason_index_offset;
if (index >= ARRAY_SIZE(qpnp_poff_reason) || index < 0) {
dev_info(&pon->pdev->dev,
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
old mode 100644
new mode 100755
index 1e620a9..6caf213
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -11,7 +11,7 @@
if INPUT_TOUCHSCREEN
-source "drivers/input/touchscreen/synaptics_dsx_2.6/Kconfig"
+#source "drivers/input/touchscreen/synaptics_dsx_2.6/Kconfig"
config TOUCHSCREEN_PROPERTIES
def_tristate INPUT
@@ -1373,7 +1373,7 @@
If unsure, say N.
-source "drivers/input/touchscreen/synaptics_dsx/Kconfig"
+#source "drivers/input/touchscreen/synaptics_dsx/Kconfig"
source "drivers/input/touchscreen/focaltech_touch/Kconfig"
config TOUCHSCREEN_FT5X06
@@ -1432,7 +1432,8 @@
If unsure, say N.
-source "drivers/input/touchscreen/hxchipset/Kconfig"
+#source "drivers/input/touchscreen/hxchipset/Kconfig"
+source "drivers/input/touchscreen/hxchipset83112b/Kconfig"
config TOUCHSCREEN_EKTF3XXX_CHIPSET
bool "Elan EKTF3XXX touchpanel CHIPSET"
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
old mode 100644
new mode 100755
index 59cf967..24f1dcd
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -106,6 +106,7 @@
obj-$(CONFIG_TOUCHSCREEN_ROHM_BU21023) += rohm_bu21023.o
obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_touch/
obj-$(CONFIG_TOUCHSCREEN_GT9XX_v28) += gt9xx_v2.8/
-obj-$(CONFIG_TOUCHSCREEN_HIMAX_CHIPSET) += hxchipset/
+# obj-$(CONFIG_TOUCHSCREEN_HIMAX_CHIPSET) += hxchipset/
+obj-$(CONFIG_TOUCHSCREEN_HIMAX_CHIPSET) += hxchipset83112b/
obj-$(CONFIG_TOUCHSCREEN_EKTF3XXX_CHIPSET) += ektf3xxx/
obj-$(CONFIG_TOUCHSCREEN_RAYDIUM_CHIPSET) += raydium_wt030/
diff --git a/drivers/input/touchscreen/hxchipset83112b/FP_DJN_Arima_CID0804_D02_C14_20190903.i b/drivers/input/touchscreen/hxchipset83112b/FP_DJN_Arima_CID0804_D02_C14_20190903.i
new file mode 100755
index 0000000..fdb82bf
--- /dev/null
+++ b/drivers/input/touchscreen/hxchipset83112b/FP_DJN_Arima_CID0804_D02_C14_20190903.i
@@ -0,0 +1,4096 @@
+0x48,0x00,0x01,0x94,0x48,0x00,0x00,0x30,0x48,0x00,0x00,0x2E,0x48,0x00,0x00,0x2C,
+0x48,0x00,0x00,0x2A,0x48,0x00,0x00,0x49,0x48,0x00,0x00,0x69,0x48,0x00,0x00,0x89,
+0x48,0x00,0x00,0xA9,0x48,0x00,0x00,0xDE,0x48,0x00,0x01,0x38,0x48,0x00,0x01,0x3A,
+0x48,0x00,0x01,0x3C,0x48,0x00,0x01,0x3E,0x48,0x00,0x01,0x2C,0x48,0x00,0x01,0x3E,
+0x50,0x03,0x00,0x40,0x50,0x03,0x00,0x40,0x50,0x03,0x00,0x40,0x8E,0x03,0x00,0x40,
+0x96,0x03,0x00,0x40,0x9E,0x03,0x00,0x40,0xA4,0x03,0x00,0x40,0xAC,0x03,0x00,0x40,
+0xB2,0x03,0x00,0x40,0xD5,0x00,0x3A,0x0F,0x94,0x3C,0x3A,0xFF,0xEF,0xBC,0x42,0x2E,
+0x80,0x20,0x3A,0x2F,0x88,0x3C,0x64,0x02,0x00,0x02,0x64,0x12,0xA4,0x02,0x64,0x22,
+0x04,0x02,0x3A,0x0F,0x88,0x3C,0x9E,0x02,0x64,0x02,0x00,0x03,0x64,0x00,0x00,0x08,
+0x80,0x5F,0xEF,0xFC,0x43,0xFF,0x88,0x09,0xB6,0x5F,0x46,0xF4,0x00,0x00,0x58,0xF7,
+0x83,0x50,0x4A,0x00,0x3C,0x00,0xD5,0x00,0x3A,0x0F,0x94,0x3C,0x3A,0xFF,0xEF,0xBC,
+0x42,0x2E,0x80,0x20,0x3A,0x2F,0x88,0x3C,0x64,0x02,0x00,0x02,0x64,0x12,0xA4,0x02,
+0x64,0x22,0x04,0x02,0x3A,0x0F,0x88,0x3C,0x9E,0x02,0x64,0x02,0x00,0x03,0x64,0x00,
+0x00,0x08,0x80,0x5F,0xEF,0xFC,0x43,0xFF,0x88,0x09,0xB6,0x5F,0x84,0x05,0x46,0xF4,
+0x00,0x00,0x58,0xF7,0x83,0x50,0x4A,0x00,0x3C,0x00,0xD5,0x00,0x3A,0x0F,0x94,0x3C,
+0x3A,0xFF,0xEF,0xBC,0x42,0x2E,0x80,0x20,0x3A,0x2F,0x88,0x3C,0x64,0x02,0x00,0x02,
+0x64,0x12,0xA4,0x02,0x64,0x22,0x04,0x02,0x3A,0x0F,0x88,0x3C,0x9E,0x02,0x64,0x02,
+0x00,0x03,0x64,0x00,0x00,0x08,0x80,0x5F,0xEF,0xFC,0x43,0xFF,0x88,0x09,0xB6,0x5F,
+0x84,0x06,0x46,0xF4,0x00,0x00,0x58,0xF7,0x83,0x50,0x4A,0x00,0x3C,0x00,0xD5,0x00,
+0x3A,0x0F,0x94,0x3C,0x3A,0xFF,0xEF,0xBC,0x42,0x2E,0x80,0x20,0x3A,0x2F,0x88,0x3C,
+0x64,0x02,0x00,0x02,0x64,0x12,0xA4,0x02,0x64,0x22,0x04,0x02,0x3A,0x0F,0x88,0x3C,
+0x9E,0x02,0x64,0x02,0x00,0x03,0x64,0x00,0x00,0x08,0x80,0x5F,0xEF,0xFC,0x43,0xFF,
+0x88,0x09,0xB6,0x5F,0x84,0x07,0x46,0xF4,0x00,0x00,0x58,0xF7,0x83,0x50,0x4A,0x00,
+0x3C,0x00,0x3A,0x1F,0xA4,0x3C,0x3A,0xFF,0xEF,0xBC,0x42,0x6E,0x80,0x20,0x3A,0x6F,
+0x98,0x3C,0x64,0x62,0x00,0x02,0x64,0x72,0xA4,0x02,0x9D,0xFC,0x64,0x82,0x04,0x02,
+0x3A,0x6F,0xA0,0x3C,0x9F,0xB2,0x64,0x62,0x00,0x03,0x64,0x00,0x00,0x08,0x80,0xDF,
+0xEF,0xFC,0x43,0xFF,0x88,0x09,0xB6,0xDF,0x46,0xF4,0x00,0x00,0x58,0xF7,0x83,0x50,
+0x4B,0xE0,0x3C,0x01,0x05,0xFF,0x80,0x00,0x3A,0x6F,0xA0,0x04,0x64,0x62,0x00,0x03,
+0x64,0x00,0x00,0x08,0x64,0x72,0xA4,0x03,0x64,0x82,0x04,0x03,0x3A,0x6F,0x98,0x04,
+0x42,0x6E,0x80,0x21,0x3A,0xFF,0xEF,0x84,0x3A,0x1F,0xA4,0x04,0x64,0x00,0x00,0x04,
+0x3A,0x0F,0x94,0x3C,0x3A,0xFF,0xEF,0xBC,0x42,0x2E,0x80,0x20,0x3A,0x2F,0x88,0x3C,
+0x80,0x5F,0xEF,0xFC,0x43,0xFF,0x88,0x09,0xB6,0x5F,0x84,0x00,0x46,0x14,0x00,0x00,
+0x58,0x10,0x83,0x8E,0xDD,0x21,0x05,0xFF,0x80,0x00,0x3A,0x2F,0x88,0x04,0x42,0x2E,
+0x80,0x21,0x3A,0xFF,0xEF,0x84,0x3A,0x0F,0x94,0x04,0x64,0x00,0x00,0x04,0x3A,0x1F,
+0x94,0x3C,0x3A,0xFF,0xEF,0xBC,0x42,0x2E,0x80,0x20,0x3A,0x2F,0x88,0x3C,0x64,0x12,
+0x00,0x02,0x64,0x22,0xA4,0x02,0x64,0x32,0x04,0x02,0x3A,0x1F,0x8C,0x3C,0x9E,0x4A,
+0x64,0x12,0x00,0x03,0x80,0x5F,0xEF,0xFC,0x43,0xFF,0x88,0x09,0xB6,0x5F,0x46,0x14,
+0x00,0x00,0x58,0x10,0x80,0x4C,0x38,0x10,0x82,0x02,0xDD,0x21,0x05,0xFF,0x80,0x00,
+0x3A,0x0F,0x88,0x04,0x64,0x02,0x00,0x43,0x64,0x00,0x00,0x08,0x64,0x02,0x00,0x03,
+0x64,0x12,0xA4,0x03,0x64,0x22,0x04,0x03,0x3A,0x2F,0x88,0x04,0x42,0x2E,0x80,0x21,
+0x3A,0xFF,0xEF,0x84,0x3A,0x1F,0x94,0x04,0x3A,0x0F,0x80,0x04,0x64,0x00,0x00,0x04,
+0x3A,0x0F,0x80,0x3C,0x84,0x05,0xD5,0xC4,0x3A,0x0F,0x80,0x3C,0x84,0x01,0xD5,0xC0,
+0x3A,0x0F,0x80,0x3C,0x84,0x02,0xD5,0xBC,0x3A,0x0F,0x80,0x3C,0x84,0x03,0xD5,0xB8,
+0x3A,0x0F,0x80,0x3C,0x84,0x04,0xD5,0xB4,0x3A,0x0F,0x94,0x3C,0x3A,0xFF,0xEF,0xBC,
+0x42,0x2E,0x80,0x20,0x3A,0x2F,0x88,0x3C,0x64,0x02,0x00,0x02,0x64,0x12,0xA4,0x02,
+0x64,0x22,0x04,0x02,0x3A,0x0F,0x88,0x3C,0x9E,0x02,0x64,0x02,0x00,0x03,0x64,0x00,
+0x00,0x08,0x80,0x5F,0xEF,0xFC,0x43,0xFF,0x88,0x09,0xB6,0x5F,0x84,0x0F,0x46,0x14,
+0x00,0x00,0x58,0x10,0x83,0x50,0xDD,0x21,0x05,0xFF,0x80,0x00,0x3A,0x0F,0x88,0x04,
+0x64,0x02,0x00,0x03,0x64,0x00,0x00,0x08,0x64,0x12,0xA4,0x03,0x64,0x22,0x04,0x03,
+0x3A,0x2F,0x88,0x04,0x42,0x2E,0x80,0x21,0x3A,0xFF,0xEF,0x84,0x3A,0x0F,0x94,0x04,
+0x64,0x00,0x00,0x04,0x40,0x00,0x00,0x09,0x47,0xD4,0x00,0x0B,0x59,0xDE,0x82,0x08,
+0x3E,0x0F,0xF5,0x0C,0x42,0x0E,0x00,0x21,0x3F,0xC8,0x00,0x00,0x3F,0xF8,0x0D,0xF8,
+0x49,0x00,0x00,0x1E,0x49,0x00,0x00,0x18,0x49,0x00,0x11,0xA6,0xD5,0x00,0x92,0x00,
+0xD5,0x00,0x84,0x00,0x64,0x05,0xE4,0x03,0x46,0x04,0x00,0x00,0x58,0x00,0x00,0x00,
+0x64,0x02,0x24,0x03,0x64,0x02,0x00,0x02,0x66,0x00,0x00,0x06,0x64,0x02,0x00,0x03,
+0xEA,0x5C,0xDD,0x9E,0xFC,0x00,0x49,0xFF,0xFF,0xEE,0xFC,0x80,0x46,0x04,0x00,0x00,
+0x58,0x00,0x00,0x00,0xEA,0x37,0x64,0x04,0xC0,0x03,0xEA,0x5C,0xDD,0x9E,0xFC,0x00,
+0x49,0x00,0x44,0xF2,0xFC,0x80,0xFC,0x00,0x49,0x00,0x4A,0x1C,0xFC,0x80,0x40,0x00,
+0x00,0x09,0xDD,0x9E,0xFC,0x00,0x49,0x00,0x45,0x49,0xFC,0x80,0x40,0x00,0x00,0x09,
+0xDD,0x9E,0xFC,0x00,0x49,0x00,0x47,0xEA,0xFC,0x80,0x00,0x00,0x80,0xA0,0x94,0x91,
+0x88,0x02,0x92,0x00,0x1A,0x12,0x80,0x01,0xD8,0xFE,0xDD,0x9E,0x80,0xA0,0x80,0x62,
+0x96,0x8F,0x8A,0x62,0xC2,0x06,0x88,0x02,0x18,0x12,0x80,0x01,0xD8,0xFE,0x8A,0x02,
+0xC3,0x06,0x88,0x02,0x88,0x03,0x3A,0x12,0x84,0x24,0xD8,0xFE,0xDD,0x9E,0x80,0xA2,
+0x80,0x60,0x96,0x0F,0x8A,0x60,0xC0,0x08,0x88,0x02,0x28,0x42,0x80,0x01,0x18,0x40,
+0x80,0x01,0xD8,0xFC,0x8A,0x02,0xC3,0x08,0x88,0x02,0x88,0x03,0x3A,0x42,0x90,0x04,
+0x3A,0x40,0x90,0x24,0xD8,0xFC,0xDD,0x9E,0xFC,0x01,0xF0,0x81,0xF0,0x01,0x8E,0x01,
+0xF0,0x81,0xC0,0x03,0xEA,0x6E,0xD5,0xFB,0xFC,0x81,0xFC,0x01,0xF0,0x81,0xF0,0x01,
+0x8E,0x01,0xF0,0x81,0xC0,0x05,0xEA,0x33,0xC0,0x03,0xEA,0x6E,0xD5,0xF9,0xFC,0x81,
+0xFC,0x01,0x84,0xCE,0xF0,0x81,0xF0,0x01,0x8E,0xC1,0xDD,0x4A,0x97,0xB0,0x84,0x05,
+0xDD,0x50,0xCE,0xFA,0xFC,0x81,0x80,0x3F,0x3E,0x08,0x03,0x08,0x9A,0x08,0x5C,0xF0,
+0x00,0x3D,0xE8,0x05,0x3C,0x1F,0xFF,0x7F,0x84,0x01,0xDD,0x9E,0x3E,0x08,0x0D,0xF8,
+0x8A,0x01,0x3C,0x1D,0xFF,0x7F,0xE2,0x20,0xE8,0x03,0x3C,0x0F,0xFF,0x7F,0x84,0x00,
+0xDD,0x9E,0xFC,0x00,0xDD,0x4B,0x5A,0x00,0x08,0x18,0x5A,0x00,0x06,0x16,0xEA,0xB2,
+0xEB,0x22,0xEB,0x2F,0xEB,0x57,0xEA,0x67,0xDD,0x48,0x2E,0x07,0xFD,0x71,0x3E,0x07,
+0xFD,0x77,0x46,0x21,0x00,0x05,0x58,0x21,0x08,0x88,0xEA,0x5A,0x46,0x11,0x00,0x05,
+0x58,0x10,0x86,0xD8,0xD5,0x06,0xEA,0x5A,0xEB,0x22,0xEB,0x2F,0xEB,0x57,0xEA,0x67,
+0xDD,0x48,0x84,0x00,0xDD,0x55,0xDD,0x4B,0x5A,0x00,0x08,0x17,0x5A,0x00,0x06,0x15,
+0x84,0xA0,0x80,0x05,0xEB,0x6F,0x58,0x31,0x81,0x44,0xDD,0x4F,0x50,0x12,0x8F,0x34,
+0x88,0x23,0xA4,0x48,0x8C,0xA2,0xE6,0x21,0x88,0x0F,0x96,0x01,0xDA,0xF8,0x5C,0xF0,
+0x00,0xD9,0xE9,0x02,0xD5,0x00,0xFC,0x80,0xFC,0x41,0x3F,0xCF,0xFD,0xD8,0x84,0x00,
+0x3E,0x07,0xFD,0x0A,0x49,0x00,0x4B,0xB8,0x3E,0x07,0xFD,0x17,0x84,0x20,0xF1,0x81,
+0x4E,0x02,0x00,0xB6,0xEB,0x5A,0x02,0x50,0x80,0x00,0x44,0x10,0xA5,0x5A,0x46,0x71,
+0x00,0x00,0x58,0x73,0x80,0x00,0x4C,0x50,0x80,0xAB,0xEB,0x5A,0x02,0x50,0x80,0x00,
+0x44,0x10,0xA3,0x3A,0x4C,0x50,0x80,0xA4,0x9E,0x41,0xE6,0x27,0xE9,0x04,0x5A,0x08,
+0x09,0x14,0xD5,0x06,0x84,0x21,0x3E,0x17,0xFD,0x0A,0x5A,0x08,0x01,0x0E,0xB8,0x00,
+0x5A,0x00,0x08,0x07,0x5A,0x00,0x06,0x05,0xEB,0x54,0xEA,0xAC,0xD5,0x03,0xEB,0x51,
+0xEA,0xFA,0xF0,0x81,0xD5,0x0E,0x54,0x10,0x00,0xF7,0x5A,0x18,0x02,0x05,0xEB,0x54,
+0xEA,0x72,0xD5,0xF8,0x5A,0x18,0x03,0x04,0xB8,0x1A,0xD5,0xF4,0x5A,0x00,0x08,0xFE,
+0xB0,0x41,0x3E,0x0F,0xFD,0x17,0x49,0x00,0x07,0x09,0xF5,0x01,0x46,0x11,0x00,0x04,
+0x58,0x10,0x84,0xB8,0x84,0xC1,0xD1,0x07,0x50,0x10,0x85,0xF0,0x40,0x62,0x84,0x03,
+0x5C,0x63,0x00,0x01,0xEA,0xAE,0xEA,0xD1,0x84,0x20,0xFE,0x84,0xEB,0x81,0x58,0x00,
+0x00,0x04,0x94,0x91,0xDD,0x42,0xB8,0x00,0x5A,0x08,0x08,0x08,0xEA,0x5A,0xEB,0x5A,
+0xEB,0x30,0xF2,0x01,0xDD,0x48,0xD5,0x46,0x5A,0x00,0x06,0xFA,0x84,0x00,0xF1,0x01,
+0x49,0x00,0x07,0x18,0xC8,0xF4,0xF1,0x01,0xB8,0x1A,0x4C,0x10,0x40,0x0E,0x46,0x91,
+0x00,0x04,0x58,0x94,0x8A,0xA8,0xF0,0x01,0x80,0x29,0x84,0x40,0x49,0x00,0x41,0x48,
+0x14,0x9F,0x80,0x01,0xD5,0x09,0xEB,0x54,0xEA,0x72,0x4C,0x10,0x3F,0xF2,0x84,0x01,
+0x49,0x00,0x07,0x00,0xC8,0xED,0x2F,0x30,0x00,0x11,0x2F,0x10,0x00,0x10,0x50,0x03,
+0x00,0x12,0x94,0x41,0x42,0x60,0x98,0x73,0x94,0x82,0x84,0x00,0x05,0x2F,0x80,0x01,
+0x40,0x98,0x84,0x08,0x95,0xB1,0x80,0xA0,0x80,0x80,0x9C,0x6C,0xE2,0x93,0x41,0x03,
+0x84,0x00,0xE8,0x10,0x98,0xC6,0x88,0x72,0x84,0x20,0xE2,0x31,0xE8,0x07,0x38,0xA1,
+0x85,0x01,0x38,0xA8,0x05,0x09,0x8C,0x21,0xD5,0xF9,0x8C,0x81,0x88,0xA9,0x88,0x02,
+0xD5,0xED,0xEA,0xAE,0x2E,0x10,0x00,0x10,0x42,0x01,0x04,0x24,0x88,0x41,0x8C,0x02,
+0x40,0x03,0x80,0x20,0x84,0x20,0x94,0x91,0xDD,0x42,0xEA,0x84,0x54,0x00,0x00,0xF7,
+0x5A,0x08,0x01,0x04,0x49,0x00,0x00,0xCC,0x49,0x00,0x4B,0x66,0xFC,0xC1,0xFC,0x00,
+0xDD,0x4D,0x96,0x04,0xC0,0x09,0xEA,0x33,0xC0,0x08,0x2E,0x07,0xFE,0x79,0xC8,0x05,
+0x49,0x00,0x4A,0x6E,0xD5,0x02,0xEA,0x6D,0xFC,0x80,0x2E,0x17,0xFD,0x1C,0xFE,0x0C,
+0x96,0x01,0xDD,0x9E,0xFC,0x60,0xDD,0x57,0x04,0x70,0x00,0x3F,0x92,0xF8,0x96,0x78,
+0x5A,0x10,0xAA,0x06,0x5A,0x10,0xCC,0x04,0x5A,0x18,0xDD,0x46,0x04,0x60,0x00,0x3F,
+0x40,0x03,0x40,0x09,0xEA,0xEB,0x96,0x31,0x40,0x90,0x20,0x09,0x97,0xB0,0xEA,0x4A,
+0x5A,0x70,0xCC,0x19,0x5A,0x70,0xDD,0x28,0x5A,0x78,0xAA,0x2D,0x84,0xE0,0x46,0xC1,
+0x00,0x07,0x58,0xC6,0x0F,0x80,0x96,0x38,0xE2,0x06,0xE8,0x24,0x50,0xB3,0x80,0x01,
+0x80,0x0A,0x80,0x29,0x40,0x25,0x80,0x13,0xEA,0x3A,0x38,0x06,0x1C,0x08,0x80,0xEB,
+0xD5,0xF3,0x84,0x40,0x46,0xB1,0x00,0x07,0x58,0xB5,0x8F,0x80,0x96,0x10,0xE2,0x06,
+0xE8,0x11,0x9D,0xD1,0x38,0x35,0x88,0x00,0x80,0x0A,0x96,0xB9,0x80,0x29,0xDD,0x4E,
+0x80,0x47,0xD5,0xF5,0xEB,0x61,0x00,0x30,0x0F,0x80,0x80,0x29,0x80,0x0A,0x80,0x46,
+0xDD,0x4E,0xEA,0x3E,0x83,0x81,0xB8,0x3F,0x46,0x2B,0xB0,0x00,0xEA,0xB1,0x40,0x01,
+0x01,0x15,0xB8,0xBF,0xFC,0xE0,0xFC,0x00,0xDD,0x52,0x4E,0x00,0x4C,0x03,0x84,0x62,
+0xDD,0x4E,0xF8,0x24,0x84,0x42,0xDD,0x4E,0xF8,0x21,0x84,0x43,0xDD,0x4E,0xF8,0x15,
+0xDD,0x4E,0x84,0x0A,0xDD,0x50,0xF8,0x1A,0x84,0x44,0xDD,0x4E,0xF8,0x1D,0xEA,0x3A,
+0x3E,0x07,0xFD,0x1B,0xF8,0x13,0x84,0x41,0xDD,0x4E,0x4E,0x00,0x4B,0xF3,0xFA,0x64,
+0xDD,0x4E,0xF8,0x0C,0x84,0x43,0xDD,0x4E,0x84,0x20,0x84,0x44,0x44,0x30,0x00,0x80,
+0xDD,0x53,0x83,0xFF,0xDD,0x4E,0x84,0x0A,0xDD,0x50,0x84,0x20,0x80,0x61,0xDD,0x53,
+0x83,0xFF,0x84,0x44,0xDD,0x4E,0x84,0x20,0x84,0x45,0xDD,0x53,0x83,0xFF,0xEA,0x3A,
+0x3E,0x07,0xFD,0x04,0xFC,0x80,0xFC,0x00,0x84,0x0E,0xDD,0x40,0xC8,0x1B,0xFA,0x02,
+0xDD,0x40,0xC8,0x18,0xFA,0x06,0xDD,0x40,0xC8,0x15,0x84,0x0A,0xDD,0x40,0xC8,0x12,
+0xFA,0x0A,0xDD,0x40,0xC8,0x0F,0xFA,0x13,0xDD,0x40,0xC8,0x0C,0xFA,0x0E,0xDD,0x40,
+0xC8,0x09,0xFA,0x18,0xDD,0x40,0xC8,0x06,0xFA,0x1C,0xDD,0x40,0xC8,0x03,0xDD,0x47,
+0xDD,0x40,0xEA,0x28,0x02,0x00,0x80,0x9C,0x02,0x10,0x80,0x0A,0x8A,0x01,0x44,0x10,
+0x06,0x5C,0xFE,0x0C,0x84,0x2A,0xEA,0xDD,0x92,0x04,0xFC,0x80,0xFC,0x40,0x3F,0xCF,
+0xFD,0xD8,0xEB,0x51,0x00,0x20,0x02,0xC0,0xC2,0x04,0xEB,0x51,0x10,0x20,0x02,0xC1,
+0xBD,0x11,0x5A,0x58,0x05,0x06,0x84,0x00,0xEB,0x78,0x10,0x00,0x82,0xC1,0x2E,0x47,
+0xFD,0x4B,0xEB,0x43,0x44,0x30,0x03,0xE8,0x44,0x10,0x27,0x10,0xFE,0x1C,0x42,0x02,
+0x04,0x73,0xB9,0x0C,0x84,0x8A,0x88,0x01,0x42,0x02,0x90,0x73,0xEB,0x84,0x96,0x01,
+0x12,0x00,0x87,0xA2,0x2E,0x57,0xFD,0x65,0xEB,0x61,0x00,0x00,0x00,0x80,0xEA,0x2A,
+0xFE,0x24,0x42,0x02,0x84,0x73,0x2E,0x57,0xFD,0x50,0x96,0x91,0x88,0x05,0x96,0x01,
+0xEB,0x5F,0x12,0x02,0x87,0xA3,0xEB,0x4E,0xEA,0xA4,0xEB,0x5F,0x12,0x02,0x87,0xA5,
+0xEB,0x64,0x02,0x00,0x00,0x5E,0xEB,0x5F,0x92,0x01,0x12,0x02,0x87,0xA6,0xEB,0x64,
+0x02,0x00,0x00,0x64,0xEB,0x5F,0x92,0x01,0x12,0x02,0x87,0xA7,0xEA,0x40,0xEB,0x5F,
+0x12,0x02,0x87,0xA8,0xB8,0x19,0xEB,0x5F,0x96,0x01,0x12,0x02,0x87,0xA9,0x3C,0x03,
+0xFF,0x1A,0xEB,0x5F,0x12,0x02,0x87,0xAA,0xEA,0xE3,0xEB,0x5F,0x12,0x02,0x87,0xAB,
+0xEA,0xC9,0xEB,0x5F,0x12,0x02,0x87,0xAC,0x3C,0x03,0xFE,0xFE,0xEB,0x5F,0x12,0x02,
+0x87,0xB0,0x2E,0x07,0xFD,0x43,0xEB,0x5F,0x12,0x02,0x87,0xB1,0xEB,0x61,0x12,0x20,
+0x07,0xB2,0xEB,0x51,0x00,0x00,0x02,0xC1,0xEB,0x72,0x12,0x01,0x07,0xB3,0x2E,0x27,
+0xFD,0x29,0xEA,0xE6,0xEB,0x01,0xEB,0x72,0x12,0x01,0x07,0xB4,0x2E,0x27,0xFD,0x6C,
+0xEB,0x61,0x02,0x00,0x07,0xB5,0xEB,0x01,0xEB,0x72,0x96,0x01,0x12,0x01,0x07,0xB5,
+0x2E,0x27,0xFD,0x6E,0xEA,0x2B,0xFE,0x1C,0x42,0x01,0x10,0x73,0xEB,0x72,0x96,0x01,
+0x12,0x01,0x07,0xB6,0x3C,0x03,0xFF,0x38,0xEB,0x72,0x12,0x01,0x07,0xB7,0x3C,0x03,
+0xFF,0x36,0xEB,0x72,0x12,0x01,0x07,0xB8,0xBA,0x10,0x2E,0x07,0xFD,0x22,0xEB,0x01,
+0xEB,0x72,0x96,0x01,0x12,0x01,0x07,0xB9,0xEB,0x61,0x02,0x20,0x07,0xBA,0x2E,0x47,
+0xFD,0x68,0x2E,0x07,0xFD,0x55,0xFE,0x0C,0x42,0x02,0x0C,0x73,0x88,0x02,0x96,0x01,
+0xEB,0x72,0x12,0x01,0x07,0xBA,0xEB,0x72,0x3C,0x03,0xFE,0xFC,0x12,0x01,0x07,0xBE,
+0x3C,0x03,0xFE,0xC3,0x12,0x01,0x07,0xBE,0x2E,0x27,0xFF,0xA4,0x42,0x01,0x18,0x0B,
+0xC0,0x0B,0x2E,0x38,0x02,0xD4,0x2E,0x08,0x02,0xD5,0x42,0x01,0x84,0x73,0xEB,0x84,
+0x96,0x01,0x12,0x00,0x87,0xBF,0xEB,0x4E,0x02,0x00,0x02,0xD5,0xEB,0x84,0x96,0x92,
+0x12,0x00,0x81,0xD8,0x4E,0x25,0x00,0x17,0x2E,0x00,0x00,0x65,0x92,0x07,0x4E,0x02,
+0x00,0x76,0xEB,0x4A,0xEA,0xD1,0xEB,0x57,0x58,0x21,0x00,0x00,0xFE,0x44,0xEB,0x4D,
+0x8C,0x22,0x40,0x11,0x04,0x20,0xEB,0x72,0x58,0x21,0x0F,0x44,0xDD,0x48,0x48,0x00,
+0x00,0x66,0x84,0x0E,0xDD,0x40,0xC8,0xE9,0xFA,0x02,0xDD,0x40,0xC8,0xE6,0xFA,0x06,
+0xDD,0x40,0xC8,0xE3,0x84,0x0A,0xDD,0x40,0xC8,0xE0,0xFA,0x0A,0xDD,0x40,0xC8,0xDD,
+0xFA,0x13,0xDD,0x40,0xC8,0xDA,0xFA,0x0E,0xDD,0x40,0xC8,0xD7,0xFA,0x18,0xDD,0x40,
+0xC8,0xD4,0xFA,0x1C,0xDD,0x40,0xC8,0xD1,0xDD,0x47,0xDD,0x40,0xC8,0xCE,0xB8,0x12,
+0x5A,0x08,0x01,0xCC,0x2E,0x60,0x00,0x10,0xB8,0x00,0x46,0x41,0x00,0x00,0x58,0x42,
+0x00,0x00,0x5A,0x08,0x08,0x0C,0x2E,0x30,0x00,0x11,0x42,0x21,0x98,0x24,0x9C,0x52,
+0x8A,0x46,0x40,0x12,0x04,0x20,0x8C,0x42,0xD5,0x09,0x2E,0x00,0x00,0x65,0x96,0x37,
+0xFE,0x34,0x8C,0x02,0x40,0x12,0x00,0x20,0x98,0x86,0x40,0x62,0x08,0x20,0xEB,0x4D,
+0xEB,0x72,0x58,0x21,0x0F,0x44,0xDD,0x48,0x46,0x97,0xFF,0xFF,0x80,0x26,0xEB,0x4D,
+0xEB,0x72,0x58,0x21,0x03,0xB0,0xDD,0x48,0x84,0xC0,0x50,0x94,0x8F,0xFF,0x46,0xA1,
+0x00,0x00,0x58,0xA5,0x00,0x04,0xEA,0xB0,0xE2,0xC0,0x4E,0xF2,0xFF,0x97,0xEA,0x3C,
+0x40,0x70,0x24,0x00,0x42,0x73,0x00,0x73,0x80,0x06,0x40,0x75,0x1C,0x20,0x49,0x00,
+0x23,0xF1,0x8C,0xC1,0xAC,0x38,0x97,0xB0,0xD5,0xEF,0xFC,0xC0,0xFC,0x60,0x84,0x07,
+0x46,0x11,0x00,0x07,0x10,0x00,0x8B,0x0E,0x46,0x11,0x00,0x07,0x10,0x00,0x8B,0x22,
+0x46,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x5A,0x00,0xA5,0x04,0x48,0x00,0x01,0x87,
+0xEB,0x61,0x04,0x50,0x03,0xC0,0xEB,0x04,0x97,0x69,0x4C,0x50,0x00,0xDA,0xEB,0x7E,
+0x00,0x00,0x08,0x3B,0xEB,0x5D,0x10,0x00,0x8B,0x8B,0xEB,0x7E,0x00,0x00,0x08,0x3C,
+0xEB,0x5D,0x10,0x00,0x8B,0x8C,0xEB,0x7E,0x00,0x00,0x08,0x3D,0xEB,0x5D,0x10,0x00,
+0x8B,0x8D,0xEB,0x7E,0x00,0x00,0x08,0x3E,0xEB,0x5D,0x10,0x00,0x8B,0x8E,0xEB,0x7E,
+0x00,0x00,0x08,0x3F,0xEB,0x5D,0x10,0x00,0x8B,0x8F,0xEB,0x7E,0x02,0x00,0x04,0x0F,
+0xEB,0x5D,0x12,0x00,0x85,0xB7,0xEB,0x7E,0x02,0x00,0x04,0x10,0xEB,0x5D,0x12,0x00,
+0x85,0xB8,0xEB,0x7E,0x02,0x00,0x04,0x11,0xEB,0x5D,0x12,0x00,0x85,0xB9,0xEB,0x7E,
+0x04,0x00,0x01,0xF8,0xEB,0x5D,0x14,0x00,0x82,0xCC,0xEB,0x7E,0x02,0x00,0x04,0x0D,
+0xEB,0x5D,0x12,0x00,0x85,0xB5,0xEB,0x7E,0x02,0x00,0x04,0x0E,0xEB,0x5D,0x12,0x00,
+0x85,0xB6,0xEB,0x7E,0x00,0x00,0x09,0xE7,0xEB,0x5D,0x10,0x00,0x8D,0x37,0xEB,0x7E,
+0x00,0x00,0x09,0xE8,0xEB,0x5D,0x10,0x00,0x8D,0x38,0xEB,0x7E,0x00,0x00,0x09,0xE9,
+0xEB,0x5D,0x10,0x00,0x8D,0x39,0xEB,0x7E,0x00,0x00,0x09,0xEA,0xEB,0x5D,0x10,0x00,
+0x8D,0x3A,0xEB,0x7E,0x00,0x00,0x09,0xEB,0xEB,0x5D,0x10,0x00,0x8D,0x3B,0xEB,0x7E,
+0x02,0x00,0x04,0xE5,0xEB,0x5D,0x12,0x00,0x86,0x8D,0xEB,0x7E,0x02,0x00,0x04,0xE6,
+0xEB,0x5D,0x12,0x00,0x86,0x8E,0xEB,0x7E,0x02,0x00,0x04,0xE7,0xEB,0x5D,0x12,0x00,
+0x86,0x8F,0xEB,0x7E,0x04,0x00,0x02,0x63,0xEB,0x5D,0x14,0x00,0x83,0x37,0xEB,0x7E,
+0x02,0x00,0x04,0xE3,0xEB,0x5D,0x12,0x00,0x86,0x8B,0xEB,0x7E,0x02,0x00,0x04,0xE4,
+0xEB,0x5D,0x12,0x00,0x86,0x8C,0x44,0x20,0xC0,0x00,0x44,0x00,0x00,0x80,0x46,0x11,
+0x00,0x07,0x58,0x10,0x80,0x00,0xDD,0x48,0x44,0x00,0x01,0x80,0x46,0x11,0x00,0x07,
+0x58,0x10,0x80,0x86,0x44,0x20,0xC1,0x00,0xDD,0x48,0xFA,0x1A,0x46,0x11,0x00,0x07,
+0x58,0x10,0x82,0x66,0x44,0x20,0xC2,0xE0,0xDD,0x48,0x44,0x00,0x00,0x38,0x46,0x11,
+0x00,0x07,0x58,0x10,0x83,0x48,0x44,0x20,0xCA,0x48,0xDD,0x48,0xDD,0x47,0x46,0x11,
+0x00,0x07,0x58,0x10,0x83,0x80,0x44,0x20,0xCA,0x80,0xDD,0x48,0xFA,0x08,0x46,0x11,
+0x00,0x07,0x58,0x10,0x82,0x06,0x44,0x20,0xC2,0x80,0xDD,0x48,0xFA,0x08,0x46,0x11,
+0x00,0x07,0x58,0x10,0x82,0x36,0x44,0x20,0xC2,0xB0,0xDD,0x48,0xFA,0x08,0x46,0x11,
+0x00,0x07,0x58,0x10,0x82,0x1E,0x44,0x20,0xC2,0x98,0xDD,0x48,0xFA,0x08,0x46,0x11,
+0x00,0x07,0x58,0x10,0x82,0x4E,0x44,0x20,0xC2,0xC8,0xDD,0x48,0x46,0x00,0x00,0x0C,
+0x04,0x00,0x00,0xCF,0x46,0x11,0x00,0x07,0x14,0x00,0x80,0xA5,0xD5,0x04,0xEB,0x61,
+0x04,0x00,0x00,0xA5,0x3C,0x0F,0xFF,0x88,0x84,0x08,0x46,0x11,0x00,0x07,0x10,0x00,
+0x80,0x02,0x84,0x04,0x46,0x11,0x00,0x07,0x10,0x00,0x80,0x03,0x46,0x21,0x00,0x07,
+0x58,0x21,0x00,0x86,0x44,0x00,0x01,0x80,0xEA,0x4C,0xDD,0x48,0x2E,0x00,0x00,0x11,
+0x3E,0x00,0x01,0x29,0x2E,0x10,0x00,0x10,0x88,0x01,0x3E,0x10,0x01,0x28,0x2E,0x20,
+0x00,0x12,0x84,0xA0,0x3E,0x00,0x01,0x31,0x45,0x00,0xE0,0x00,0xEB,0x61,0x3E,0x20,
+0x01,0x2B,0x14,0x50,0x00,0xB1,0x80,0x45,0x44,0x90,0xFF,0xFF,0x81,0x50,0x44,0xB0,
+0x00,0x48,0x46,0xC1,0x00,0x07,0x58,0xC6,0x05,0x00,0x44,0x40,0x00,0x6C,0x86,0x23,
+0x45,0x20,0x00,0xD8,0x44,0xDF,0xFF,0x94,0x45,0x30,0x05,0x10,0x38,0x08,0x14,0x01,
+0x4C,0x04,0x80,0x32,0x80,0xCC,0x42,0x61,0x2C,0x73,0x84,0x60,0x40,0xE5,0x14,0x00,
+0x38,0x17,0x0D,0x01,0x95,0xD9,0x9E,0x09,0x41,0x40,0x12,0x96,0x40,0x8A,0x46,0x96,
+0x5C,0xF0,0x81,0x45,0x40,0x8A,0x00,0x13,0xE8,0x05,0x42,0x04,0x34,0x73,0x96,0x01,
+0xD5,0x11,0x52,0x00,0x82,0x88,0x40,0x10,0x10,0x16,0x50,0x00,0x00,0x6C,0x96,0x01,
+0x4E,0x83,0x00,0x07,0x50,0x1A,0x00,0x02,0x42,0x00,0xC8,0x73,0xD5,0x05,0x5A,0x80,
+0x02,0x04,0x42,0x04,0x48,0x73,0x8C,0x61,0x38,0x03,0x1C,0x09,0x5A,0x38,0x24,0xDA,
+0x8C,0x41,0x96,0x91,0x50,0x52,0x80,0x48,0x4C,0x59,0xFF,0xCA,0x46,0x00,0x00,0x0C,
+0x04,0x00,0x02,0xC3,0x46,0x11,0x00,0x07,0x14,0x00,0x83,0xF7,0x46,0x00,0x00,0x0C,
+0x02,0x00,0x05,0x85,0x46,0x11,0x00,0x07,0x12,0x00,0x87,0xED,0x46,0x00,0x00,0x0C,
+0x02,0x00,0x05,0x84,0x46,0x11,0x00,0x07,0x12,0x00,0x87,0xEC,0x46,0x00,0x00,0x0C,
+0x04,0x00,0x02,0xC1,0x46,0x11,0x00,0x07,0x14,0x00,0x83,0xF5,0x46,0x00,0x00,0x0C,
+0x46,0x11,0x00,0x07,0x04,0x00,0x02,0xC0,0x14,0x00,0x83,0xF4,0xEA,0x9B,0x44,0x00,
+0x72,0xC0,0x46,0x11,0x00,0x07,0x14,0x00,0x80,0xB0,0xFC,0xE0,0xFC,0x21,0x46,0x69,
+0x00,0x08,0x44,0x70,0x35,0xCA,0x12,0x73,0x00,0x08,0xEA,0x4A,0xC8,0x20,0x12,0x73,
+0x00,0x08,0x46,0x10,0x00,0x0C,0x00,0x10,0x81,0x03,0xEA,0x5B,0xC1,0x13,0xF0,0x81,
+0x49,0xFF,0xFC,0xAB,0x46,0x00,0x00,0x0C,0x00,0x10,0x01,0x06,0xF0,0x01,0xC9,0x04,
+0x44,0x00,0xE8,0x00,0xD5,0x05,0x5A,0x18,0x02,0x06,0x44,0x00,0xEC,0x00,0x49,0x00,
+0x3B,0x57,0xEA,0xE9,0x12,0x13,0x00,0x08,0x96,0x00,0xD5,0x03,0x44,0x00,0x00,0xF0,
+0xFC,0xA1,0xFC,0x00,0x46,0x09,0x00,0x08,0xEA,0xE9,0x12,0x10,0x00,0x08,0xEA,0xB9,
+0x02,0x01,0x00,0x72,0x42,0x30,0x0C,0x0B,0xCB,0x34,0x02,0x11,0x00,0x72,0x42,0x00,
+0x90,0x0B,0xC8,0x31,0x02,0x11,0x00,0x72,0xEA,0xD7,0xC9,0x2E,0x2E,0x17,0xFF,0xA3,
+0x42,0x00,0x88,0x0B,0xC8,0x03,0xEB,0x2B,0xD5,0x06,0x49,0x00,0x3B,0xF8,0x44,0x00,
+0x00,0xF1,0xD5,0x22,0xB4,0x02,0x96,0x16,0xC0,0xFE,0x46,0x09,0x00,0x08,0x44,0x20,
+0x35,0xCA,0x12,0x20,0x00,0x08,0x42,0x20,0x8C,0x0B,0x80,0x20,0xCA,0x04,0xEA,0xB9,
+0xEB,0x2B,0xD5,0x06,0x49,0x00,0x3B,0xEC,0x44,0x00,0x00,0xF2,0xD5,0x0D,0xB4,0x02,
+0x92,0x0C,0x96,0x0F,0x5A,0x08,0x03,0xFD,0x44,0x00,0x35,0xCA,0x12,0x00,0x80,0x08,
+0x84,0x00,0xD5,0x02,0x80,0x03,0xFC,0x80,0xFC,0x00,0x5C,0xF0,0x00,0x31,0x4E,0xF2,
+0x01,0x56,0x3E,0xFF,0x5C,0xB8,0x38,0x07,0x81,0x01,0x40,0xF0,0x3C,0x00,0xDD,0x0F,
+0x62,0x00,0x68,0x00,0x72,0x00,0x7C,0x00,0x86,0x00,0x90,0x00,0x9A,0x00,0xAC,0x00,
+0xB6,0x00,0xC0,0x00,0xCA,0x00,0xDC,0x00,0xE6,0x00,0xF0,0x00,0xFA,0x00,0x06,0x01,
+0x10,0x01,0x1A,0x01,0x26,0x01,0x32,0x01,0x3C,0x01,0x46,0x01,0x50,0x01,0x5E,0x01,
+0x68,0x01,0x72,0x01,0x7C,0x01,0x92,0x01,0x9C,0x01,0xA6,0x01,0xB0,0x01,0xC8,0x01,
+0x9A,0x02,0xD4,0x01,0xDE,0x01,0xE8,0x01,0xFE,0x01,0x9A,0x02,0x08,0x02,0x12,0x02,
+0x1C,0x02,0x32,0x02,0x3C,0x02,0x46,0x02,0x50,0x02,0x5E,0x02,0x68,0x02,0x72,0x02,
+0x80,0x02,0xEB,0x61,0xDD,0x5E,0xF8,0x5E,0xEB,0x61,0xDD,0x5E,0x50,0x00,0x76,0xF7,
+0xF8,0x59,0xEB,0x61,0xDD,0x44,0x44,0x0F,0x66,0x67,0xF8,0xAB,0xEB,0x61,0xDD,0x5E,
+0x50,0x00,0x7E,0xFF,0xF8,0x4F,0xEB,0x61,0xDD,0x5E,0x50,0x00,0x7E,0x6F,0xF8,0x4A,
+0xEB,0x61,0xDD,0x44,0x44,0x0F,0x6E,0x6F,0xF8,0x9C,0x84,0x04,0xDD,0x40,0x80,0xC0,
+0xC0,0x04,0x85,0xE1,0x48,0x00,0x00,0xFC,0x84,0x05,0xF8,0x8D,0xEB,0x61,0xDD,0x5E,
+0x50,0x00,0x5D,0xDE,0xF8,0x37,0xEB,0x61,0xDD,0x5E,0x50,0x00,0x5B,0xDC,0xF8,0x32,
+0xEB,0x61,0xDD,0x44,0x44,0x0F,0xBB,0xBC,0xF8,0x84,0x84,0x07,0xDD,0x40,0xC8,0xEA,
+0x84,0x08,0xDD,0x40,0x80,0xC0,0x84,0x09,0xCE,0xE5,0xF8,0x75,0xEB,0x61,0xDD,0x44,
+0x44,0x0F,0x55,0x56,0xF8,0x76,0xEB,0x61,0xDD,0x44,0x44,0x0F,0x53,0x54,0xF8,0x71,
+0xEB,0x61,0xDD,0x44,0x44,0x0F,0x33,0x34,0xF8,0x6C,0x84,0x0C,0xDD,0x40,0x80,0xC0,
+0x84,0x0D,0xCE,0xD0,0xF8,0x60,0xEB,0x61,0xDD,0x5E,0x50,0x00,0x6E,0xEF,0xF8,0x0A,
+0xEB,0x61,0xDD,0x5E,0x50,0x00,0x6C,0xED,0xF8,0x05,0xEB,0x61,0xDD,0x5E,0x50,0x00,
+0x4C,0xCD,0x48,0x00,0x00,0xAD,0xFA,0x00,0xDD,0x40,0x80,0xC0,0xC8,0xBB,0xFA,0x01,
+0xF8,0x4A,0xEB,0x61,0xDD,0x44,0x44,0x0F,0x88,0x89,0xF8,0x4B,0xEB,0x61,0xDD,0x44,
+0x44,0x0F,0x87,0x88,0xF8,0x46,0xEB,0x61,0xDD,0x44,0x44,0x0F,0x77,0x78,0xF8,0x41,
+0xFA,0x04,0xDD,0x40,0x80,0xC0,0x4E,0x03,0xFF,0xA6,0xFA,0x05,0xF8,0x34,0xEB,0x61,
+0xDD,0x44,0x44,0x0F,0xAA,0xAB,0xF8,0x35,0xEB,0x61,0xDD,0x44,0x44,0x0F,0xA9,0xAA,
+0xF8,0x30,0xEB,0x61,0xDD,0x44,0x44,0x0F,0x99,0x9A,0xF8,0x2B,0xFA,0x07,0xDD,0x40,
+0x4E,0x03,0xFF,0x91,0xFA,0x08,0xDD,0x40,0x80,0xC0,0x4E,0x03,0xFF,0x8C,0xFA,0x09,
+0xF8,0x1A,0xEB,0x61,0xDD,0x44,0x44,0x0F,0xAE,0xAF,0xF8,0x1B,0xEB,0x61,0xDD,0x44,
+0x44,0x0F,0xAE,0x9F,0xF8,0x16,0xEB,0x61,0xDD,0x44,0x44,0x0F,0x9E,0x9F,0xF8,0x11,
+0xFA,0x0B,0xDD,0x40,0x4E,0x03,0xFF,0x77,0xFA,0x0C,0xDD,0x40,0x80,0xC0,0x4E,0x03,
+0xFF,0x72,0xFA,0x0D,0x48,0x00,0x00,0x68,0xEB,0x61,0xDD,0x44,0x44,0x0F,0xAF,0xB0,
+0x48,0x00,0x00,0x55,0xEB,0x61,0xDD,0x44,0x44,0x0F,0xAF,0xA0,0xD5,0x4F,0xEB,0x61,
+0xDD,0x44,0x44,0x0F,0x9F,0xA0,0xD5,0x4A,0xFA,0x0F,0xDD,0x40,0x4E,0x03,0xFF,0x5B,
+0xFA,0x11,0xDD,0x40,0x80,0xC0,0x4E,0x03,0xFF,0x56,0xFA,0x12,0xD5,0x4C,0xEB,0x61,
+0xDD,0x44,0x44,0x0F,0xAD,0xAE,0xD5,0x3A,0xEB,0x61,0xDD,0x44,0x44,0x0F,0xAD,0x9E,
+0xD5,0x35,0xEB,0x61,0xDD,0x44,0x44,0x0F,0x9D,0x9E,0xD5,0x30,0xFA,0x14,0xDD,0x40,
+0x4E,0x03,0xFF,0x41,0xFA,0x16,0xDD,0x40,0x80,0xC0,0x4E,0x03,0xFF,0x3C,0xFA,0x17,
+0xD5,0x32,0xEB,0x61,0xDD,0x44,0x44,0x0F,0xAC,0xAD,0xD5,0x20,0xEB,0x61,0xDD,0x44,
+0x44,0x0F,0xAC,0x9D,0xD5,0x1B,0xEB,0x61,0xDD,0x44,0x44,0x0F,0x9C,0x9D,0xD5,0x16,
+0xFA,0x1A,0xDD,0x40,0x80,0xC0,0x4E,0x03,0xFF,0x26,0xFA,0x1B,0xD5,0x1C,0xEB,0x61,
+0xDD,0x44,0x44,0x0F,0x44,0x45,0xD5,0x0A,0xEB,0x61,0xDD,0x44,0x44,0x0F,0x40,0x41,
+0xD5,0x05,0xEB,0x61,0xDD,0x44,0x44,0x0F,0x00,0x01,0x88,0x01,0xE6,0x01,0xD5,0x0F,
+0xFA,0x1D,0xDD,0x40,0x4E,0x03,0xFF,0x0F,0xFA,0x1E,0xDD,0x40,0x80,0xC0,0x4E,0x03,
+0xFF,0x0A,0xFA,0x1F,0xDD,0x40,0xE2,0xC0,0xD5,0x02,0x85,0xE0,0x80,0x0F,0xFC,0x80,
+0x92,0x00,0xFC,0x00,0x84,0x00,0xDD,0x40,0xC8,0x43,0x84,0x0B,0xDD,0x40,0xC0,0x04,
+0x44,0x00,0xAC,0xAC,0xD5,0x3F,0x84,0x0F,0xDD,0x40,0xC0,0x04,0x44,0x00,0x13,0x13,
+0xD5,0x39,0xFA,0x03,0xDD,0x40,0xC0,0x04,0x44,0x00,0x78,0x78,0xD5,0x33,0x84,0x07,
+0xDD,0x40,0xC0,0x04,0x44,0x00,0x22,0x22,0xD5,0x2D,0xFA,0x07,0xDD,0x40,0xC0,0x04,
+0x44,0x00,0x55,0x55,0xD5,0x27,0xFA,0x0B,0xDD,0x40,0xC0,0x04,0x44,0x00,0x51,0x51,
+0xD5,0x21,0xFA,0x0F,0xDD,0x40,0xC0,0x04,0x44,0x00,0x50,0x50,0xD5,0x1B,0xFA,0x14,
+0xDD,0x40,0xC0,0x04,0x44,0x00,0x52,0x52,0xD5,0x15,0xFA,0x19,0xDD,0x40,0xC0,0x04,
+0x44,0x00,0x53,0x63,0xD5,0x0F,0xFA,0x1D,0xDD,0x40,0xC0,0x04,0x44,0x00,0xBB,0xBB,
+0xD5,0x09,0x84,0x03,0xDD,0x40,0xC0,0x04,0x44,0x00,0x01,0x91,0xD5,0x03,0x44,0x00,
+0x09,0x09,0x46,0x11,0x00,0x07,0xEA,0x30,0xFC,0x80,0xFC,0x00,0x3F,0xCF,0xFD,0xF8,
+0xEB,0x81,0x58,0x00,0x06,0x04,0x84,0x20,0xDD,0x4F,0xDD,0x42,0x84,0x00,0x3E,0x07,
+0xFD,0x51,0x84,0x20,0xB9,0x80,0xEB,0x6A,0x46,0x27,0x2C,0x80,0x14,0x21,0x80,0xB2,
+0x3E,0x17,0xFD,0x3F,0x3E,0x07,0xFD,0x63,0xB8,0x0A,0x44,0x10,0x72,0xC8,0x40,0x50,
+0x40,0x09,0xD9,0x07,0x96,0x01,0xB8,0x8A,0x84,0x01,0x3E,0x07,0xFD,0x3F,0xD5,0x09,
+0x44,0x10,0x7F,0x0C,0xD9,0x06,0x96,0x01,0xB8,0x8A,0x84,0x01,0x3E,0x07,0xFD,0x63,
+0xB8,0x0A,0x44,0x10,0xFF,0xFE,0x8E,0x01,0xE2,0x20,0xE8,0x03,0x84,0x01,0xB8,0x8A,
+0x84,0x0E,0xDD,0x40,0xC0,0x06,0xDD,0x4D,0x96,0x37,0x3E,0x07,0xFF,0xA3,0xD5,0x1F,
+0xFA,0x02,0xDD,0x40,0xC8,0xF9,0xFA,0x06,0xDD,0x40,0xC8,0xF6,0x84,0x0A,0xDD,0x40,
+0xC8,0xF3,0xFA,0x0A,0xDD,0x40,0xC8,0xF0,0xFA,0x13,0xDD,0x40,0xC8,0xED,0xFA,0x0E,
+0xDD,0x40,0xC8,0xEA,0xFA,0x18,0xDD,0x40,0xC8,0xE7,0xFA,0x1C,0xDD,0x40,0xC8,0xE4,
+0xDD,0x47,0xDD,0x40,0xC8,0xE1,0xB8,0x0A,0x5A,0x08,0x01,0xDF,0xDD,0x47,0xDD,0x40,
+0xC0,0x0B,0xEB,0x64,0xDD,0x5D,0x84,0x20,0xDD,0x4F,0xEB,0x1F,0xEB,0x54,0xEA,0x72,
+0x84,0x3F,0xDD,0x4F,0xEB,0x1F,0xFC,0x80,0xEA,0x40,0x8C,0x01,0x96,0x00,0xEA,0xC3,
+0xEA,0x40,0x2E,0x10,0x00,0x0E,0xE2,0x01,0x56,0x07,0x80,0x01,0xEA,0xAA,0xEA,0x40,
+0x46,0x11,0x00,0x07,0x12,0x00,0x87,0xA5,0xDD,0x9E,0xFC,0x00,0x84,0x0E,0xDD,0x40,
+0xC0,0x07,0x84,0x0C,0xDD,0x40,0xC0,0x0B,0x44,0x00,0xCC,0xCC,0xD5,0x13,0xFA,0x02,
+0xDD,0x40,0xC8,0xF8,0xFA,0x06,0xDD,0x40,0xC8,0xF5,0xD5,0x12,0xFA,0x00,0xDD,0x40,
+0xC0,0x04,0x44,0x00,0x33,0x33,0xD5,0x06,0xFA,0x04,0xDD,0x40,0xC0,0x3D,0x44,0x00,
+0x88,0x88,0x46,0x11,0x00,0x07,0xEA,0x30,0x84,0x01,0xDD,0x55,0xD5,0x35,0x84,0x0A,
+0xDD,0x40,0xC0,0x04,0x44,0x00,0x44,0x44,0xD5,0x2C,0xFA,0x0A,0xDD,0x40,0xC0,0x04,
+0x44,0x00,0x66,0x66,0xD5,0x26,0xFA,0x0E,0xDD,0x40,0xC0,0x04,0x44,0x00,0x61,0x61,
+0xD5,0x20,0xFA,0x13,0xDD,0x40,0xC0,0x04,0x44,0x00,0x60,0x60,0xD5,0x1A,0xFA,0x18,
+0xDD,0x40,0xC0,0x04,0x44,0x00,0x62,0x62,0xD5,0x14,0xFA,0x1C,0xDD,0x40,0xC0,0x04,
+0x44,0x00,0x63,0x63,0xD5,0x0E,0xDD,0x47,0xDD,0x40,0xC0,0x03,0xEA,0x29,0xD5,0x09,
+0x84,0x06,0xDD,0x40,0xC0,0x04,0x44,0x00,0x91,0x91,0xD5,0x03,0x44,0x00,0x99,0x99,
+0x46,0x11,0x00,0x07,0xEA,0x30,0xFC,0x80,0xFC,0x00,0xA6,0x00,0x80,0xC1,0x5A,0x08,
+0x0A,0x0E,0x84,0x0E,0xDD,0x40,0xC8,0x07,0xFA,0x02,0xDD,0x40,0xC8,0x04,0xFA,0x06,
+0xDD,0x40,0xC0,0x26,0xEB,0x54,0xEA,0x72,0xD5,0x22,0x5A,0x08,0x0B,0x04,0xDD,0x47,
+0xD5,0xF8,0x5A,0x08,0x0C,0x18,0xFA,0x0A,0xDD,0x40,0xC0,0x05,0xEB,0x64,0xDD,0x5D,
+0xB6,0x06,0xD5,0x0A,0xFA,0x13,0xDD,0x40,0xC8,0xFA,0xFA,0x0E,0xDD,0x40,0xC8,0xF7,
+0xFA,0x18,0xDD,0x40,0xC8,0xF4,0xDD,0x47,0xDD,0x40,0xC0,0x0A,0xEB,0x64,0xDD,0x5D,
+0xD5,0x06,0x5A,0x08,0x0F,0x06,0xEB,0x81,0x58,0x00,0x06,0x04,0xB6,0x06,0xFC,0x80,
+0xC0,0x04,0x5A,0x00,0x01,0x1A,0xD5,0x29,0xFC,0x00,0xFA,0x13,0x80,0xC1,0xDD,0x40,
+0xC0,0x07,0xEB,0x64,0xDD,0x5D,0x4C,0x60,0x40,0x04,0x84,0x01,0xD5,0x20,0xFA,0x18,
+0xDD,0x40,0xC0,0x1D,0x46,0x31,0x00,0x02,0x58,0x31,0x86,0x58,0x40,0x03,0x0C,0x03,
+0x5C,0x00,0x00,0x01,0xD5,0x14,0x46,0x21,0x00,0x03,0x58,0x21,0x00,0x78,0x4C,0x11,
+0x00,0x10,0x50,0x01,0x75,0xE0,0x4C,0x10,0x00,0x0C,0x50,0x21,0x70,0xD0,0x40,0x00,
+0x88,0x03,0x5C,0x00,0x00,0x01,0xDD,0x9E,0x84,0x00,0xDD,0x9E,0xFC,0x80,0x84,0x01,
+0xDD,0x9E,0xEA,0x4C,0x00,0x00,0x80,0x70,0x00,0x10,0x80,0x71,0x8C,0x01,0x42,0x00,
+0x80,0x73,0x96,0x01,0x2E,0x37,0xFD,0x3F,0x9E,0x86,0xEB,0x5A,0x58,0x10,0x80,0x00,
+0xEA,0xBD,0xEB,0x6A,0x9E,0x85,0x02,0x31,0x81,0x64,0xEA,0xBD,0x46,0x21,0x00,0x07,
+0x04,0x21,0x03,0xF2,0x9E,0xC4,0x96,0x91,0x38,0x20,0x8D,0x09,0x9E,0x83,0x3C,0x33,
+0xFE,0xFC,0xEA,0xBD,0x9E,0x82,0x3C,0x33,0xFF,0x10,0xEA,0xBD,0x46,0x21,0x00,0x07,
+0x04,0x21,0x03,0xC1,0x9E,0xC1,0x96,0x91,0x92,0x48,0x38,0x20,0x8D,0x09,0x46,0x21,
+0x00,0x07,0x04,0x21,0x03,0xC1,0x96,0x90,0x38,0x20,0x81,0x09,0xDD,0x9E,0x44,0x10,
+0x22,0xB8,0x50,0x00,0x7C,0x18,0xFE,0x0C,0x44,0x11,0x86,0xA0,0xEA,0xDD,0x50,0x00,
+0x00,0x56,0x96,0x01,0xDD,0x9E,0xFC,0x00,0xFA,0x02,0xDD,0x40,0xC0,0x05,0x2E,0x10,
+0x00,0xD9,0xDD,0x5C,0xD5,0x0E,0xFA,0x06,0xDD,0x40,0xC0,0x0F,0x49,0x00,0x43,0xBC,
+0xEA,0x2A,0x5A,0x08,0x0C,0x05,0x2E,0x00,0x00,0xDB,0xD5,0x03,0x2E,0x00,0x00,0xDA,
+0xFE,0x0C,0x49,0xFF,0xFF,0xDE,0xD5,0x03,0x49,0xFF,0xF9,0x4F,0x46,0x11,0x00,0x07,
+0x14,0x00,0x83,0xF2,0xFC,0x80,0xFC,0x00,0x84,0xA0,0x97,0x29,0xE2,0x81,0xE8,0x10,
+0xA5,0x18,0x38,0x61,0x15,0x01,0x5A,0x08,0x01,0x06,0xE2,0x86,0x40,0x43,0x3C,0x1B,
+0xD5,0x03,0x42,0x42,0x18,0x01,0x1A,0x41,0x80,0x01,0x8C,0xA1,0xD5,0xEF,0xFC,0x80,
+0xFC,0x20,0x2F,0x17,0xFD,0x63,0x84,0x60,0xFB,0x94,0x2E,0x20,0x01,0x29,0xE2,0x62,
+0xE8,0x22,0x42,0x71,0xC0,0x24,0x84,0x40,0x2E,0x40,0x01,0x28,0xE2,0x44,0xE8,0x18,
+0x99,0x57,0x40,0x60,0x94,0x20,0x22,0x43,0x00,0x00,0x38,0x50,0x15,0x11,0x4F,0x12,
+0x00,0x0A,0x43,0x32,0x00,0x03,0x42,0xF2,0x80,0x03,0xE1,0xEF,0x40,0x42,0xBC,0x1B,
+0xD5,0x03,0x42,0x42,0x90,0x00,0x8C,0x41,0xAD,0x30,0x96,0x90,0xD5,0xE6,0x8C,0x61,
+0x96,0xD8,0xD5,0xDC,0xFC,0xA0,0xFC,0x00,0x3F,0xCF,0xFD,0xD8,0xB8,0x12,0xB9,0x08,
+0xE2,0x20,0xE8,0x10,0xB8,0x00,0x5A,0x00,0x08,0x04,0x5A,0x08,0x06,0x05,0xEB,0x51,
+0xEA,0xFA,0xD5,0x05,0xEB,0x46,0xC8,0x06,0xEB,0x54,0xEA,0xAC,0xEB,0x5A,0xEA,0x8C,
+0xEB,0x13,0xB8,0x08,0xB9,0x12,0xE2,0x01,0xE8,0x04,0x8C,0x01,0xB8,0x88,0xD5,0x02,
+0xEA,0x53,0xFC,0x80,0xFC,0x00,0x3C,0x0D,0xFF,0x88,0x3C,0x2D,0xFF,0x7E,0xE2,0x40,
+0xE8,0x19,0xEB,0x61,0x04,0x00,0x00,0xB2,0x96,0x81,0xE2,0x41,0xE8,0x13,0x96,0x49,
+0x92,0x10,0xEB,0x49,0x46,0x11,0x00,0x07,0x14,0x00,0x80,0xB2,0xEB,0x46,0x5A,0x08,
+0x01,0x0A,0xEA,0xB2,0xEB,0x5A,0xEA,0x8C,0x46,0x21,0x00,0x03,0x58,0x21,0x0A,0x98,
+0xDD,0x48,0xFC,0x80,0x46,0x38,0x00,0x30,0x4E,0x00,0x42,0xE9,0xCA,0xFE,0x4E,0x00,
+0x42,0xEC,0xDD,0x9E,0xFC,0x63,0x3F,0xCF,0xFD,0xD4,0x81,0x20,0xB1,0x81,0x3E,0x0F,
+0xFB,0x28,0x3B,0x00,0x4C,0x04,0x80,0xE1,0x80,0x26,0x3B,0x00,0xCC,0x24,0xA4,0x00,
+0xAC,0x08,0x2E,0x80,0x00,0xD5,0x81,0x42,0x40,0x04,0x00,0x10,0x85,0x81,0x4E,0x04,
+0x00,0x04,0x44,0xC0,0xFF,0xFF,0xEA,0x28,0x02,0x00,0x80,0x9C,0x02,0x30,0x80,0x0A,
+0x40,0xB0,0x0C,0x01,0x84,0x0E,0xDD,0x40,0x40,0xB5,0xA4,0x08,0x84,0x60,0xC8,0x09,
+0x54,0x44,0x00,0x7F,0x44,0x50,0x00,0x64,0xFF,0x2C,0x42,0x46,0x10,0x24,0x96,0xE3,
+0x88,0x6B,0xBB,0x80,0x3C,0x0D,0xFF,0x75,0xFE,0x02,0xB8,0x84,0x84,0x04,0x49,0xFF,
+0xFF,0xC3,0xB9,0x04,0xEB,0x57,0xEA,0x67,0x80,0x09,0x49,0x00,0x42,0xBF,0x84,0x06,
+0x42,0x64,0x80,0x73,0x40,0x25,0x00,0x13,0x84,0x00,0x46,0x41,0x00,0x00,0x58,0x42,
+0x0B,0x14,0x44,0x30,0x01,0xB0,0x38,0x13,0x00,0x00,0x81,0x27,0x42,0x90,0x8C,0x73,
+0x38,0x52,0x09,0x01,0x38,0x54,0x89,0x09,0x99,0x70,0xA7,0x69,0x81,0x27,0x50,0x11,
+0x00,0x6C,0x42,0x92,0x8C,0x73,0x39,0x02,0x05,0x01,0x50,0x21,0x00,0x24,0x8C,0x02,
+0x39,0x04,0x85,0x09,0x96,0x91,0x5A,0x08,0x06,0xE8,0xFC,0xE3,0x46,0x10,0x00,0xE0,
+0xDD,0x43,0x8C,0x27,0xEA,0xCB,0x46,0x10,0x01,0xC0,0x8C,0x35,0x14,0x10,0x01,0x60,
+0x46,0x10,0x02,0xA0,0x50,0x10,0x80,0x23,0x14,0x10,0x01,0x61,0x84,0x20,0x14,0x10,
+0x01,0x62,0x14,0x10,0x01,0x63,0x14,0x10,0x01,0x64,0x14,0x10,0x01,0x65,0x14,0x10,
+0x01,0x66,0x14,0x10,0x01,0x67,0x14,0x10,0x01,0x68,0xDD,0x9E,0xFC,0x60,0xEE,0xE0,
+0x3E,0x1F,0xFB,0x3C,0x80,0xE0,0x50,0xAF,0x80,0x30,0x3E,0x0F,0xFB,0x60,0xB1,0x83,
+0x3B,0x00,0xE0,0x00,0x44,0x20,0x00,0xF0,0x3B,0x03,0x60,0x20,0x84,0x20,0x3B,0x00,
+0x48,0x00,0x80,0x0A,0x3B,0x0F,0xC8,0x20,0xDD,0x42,0x84,0x20,0x80,0x0A,0xA8,0x41,
+0xA8,0x42,0xA8,0x43,0xA8,0x44,0xA8,0x45,0xA8,0x46,0xF1,0x8C,0xFA,0x22,0x40,0x13,
+0x84,0x57,0x96,0x90,0x81,0x3F,0x94,0x91,0x86,0x67,0x44,0x00,0x00,0x55,0x46,0xE3,
+0x00,0x00,0x45,0x43,0x00,0x00,0xE6,0x42,0xE8,0x0A,0x38,0x53,0x08,0x00,0x84,0x20,
+0x40,0x50,0x14,0x0C,0xF8,0x12,0x82,0x21,0x82,0x41,0xD5,0x3D,0xE6,0x48,0xE8,0x07,
+0xEA,0xBE,0x41,0x20,0x04,0x0C,0xF8,0x08,0x82,0x21,0xD5,0x0C,0xE6,0x4E,0xE8,0x0C,
+0xEA,0xBE,0x41,0x10,0x04,0x0C,0x84,0x20,0x80,0x61,0x80,0xE1,0x82,0x01,0x83,0xFF,
+0x82,0x41,0x80,0xA1,0xD5,0x28,0xE6,0x54,0xE8,0x08,0xEA,0xBE,0x41,0x00,0x04,0x0C,
+0x84,0x20,0x80,0x61,0x80,0xE1,0xD5,0x14,0xE6,0x5A,0xE8,0x08,0x38,0x73,0x08,0x00,
+0x84,0x20,0x40,0x70,0x1C,0x0C,0x80,0x61,0xD5,0x0A,0x5C,0xF1,0x00,0x20,0xE8,0x0A,
+0x38,0x33,0x08,0x00,0x84,0x20,0x40,0x30,0x0C,0x0C,0x80,0xE1,0x82,0x01,0x82,0x21,
+0xD5,0xE0,0xEA,0xBE,0x84,0x60,0x40,0x10,0x04,0x0C,0x80,0xE3,0x82,0x03,0x82,0x23,
+0x82,0x43,0x80,0xA3,0x80,0x93,0x85,0x60,0x88,0xAE,0x88,0x34,0x38,0x84,0xAE,0x02,
+0x50,0xC2,0x00,0x01,0xEA,0x56,0x89,0x05,0x38,0x85,0x12,0x0A,0x39,0x25,0x32,0x0A,
+0x50,0xC2,0x00,0x02,0xEA,0x56,0x39,0x15,0x32,0x0A,0x50,0xC2,0x00,0x03,0xEA,0x56,
+0x39,0x05,0x32,0x0A,0x50,0xC2,0x00,0x04,0xEA,0x56,0x38,0x75,0x32,0x0A,0x50,0xD2,
+0x00,0x05,0x50,0xC2,0x00,0x06,0xEA,0x56,0x54,0xD6,0x80,0xFF,0x8C,0x87,0x8D,0x61,
+0x38,0x35,0x36,0x0A,0x97,0x20,0x38,0x15,0x32,0x0A,0x5A,0xB8,0x03,0xD9,0x50,0x19,
+0x80,0x15,0x8C,0x41,0x55,0x30,0x80,0xFF,0x96,0x91,0x5B,0x30,0x31,0x04,0x48,0xFF,
+0xFF,0x84,0x84,0x00,0x46,0x32,0x00,0x00,0x40,0x15,0x00,0x00,0x5A,0x00,0xC8,0x0A,
+0x98,0x83,0xB4,0x81,0xB6,0x82,0xB4,0xA2,0xB4,0x81,0xDC,0xFC,0x8C,0x04,0xD5,0xF5,
+0xED,0x20,0xFC,0xE0,0xFC,0x00,0x80,0xC0,0x5A,0x08,0x01,0x0C,0xDD,0x43,0x84,0x22,
+0xEA,0x58,0x84,0x23,0xEA,0x47,0xEA,0x59,0xC8,0x04,0xEA,0x42,0xE6,0x01,0xEA,0x66,
+0x9E,0x31,0x96,0x40,0xE6,0x26,0xE8,0x18,0x84,0x43,0x40,0x10,0x08,0x16,0xE2,0x46,
+0x2E,0x27,0xFD,0x51,0x96,0x00,0x40,0x27,0x88,0x20,0xEB,0x22,0xEB,0x2F,0x96,0x90,
+0x49,0xFF,0xFE,0xA2,0x5A,0x68,0x06,0x16,0xEA,0x59,0x5A,0x08,0x11,0x13,0xEA,0x24,
+0x96,0x00,0xDD,0x55,0xD5,0x0E,0x5A,0x68,0x08,0x0D,0xEA,0x59,0x8C,0x01,0x96,0x00,
+0xE6,0x12,0xE9,0x02,0x84,0x00,0x3E,0x07,0xFD,0x51,0xEA,0x59,0x49,0xFF,0xFF,0x10,
+0xFC,0x80,0xFC,0x00,0x2E,0x17,0xFD,0x24,0x2E,0x07,0xFF,0xDB,0xFE,0x0C,0x3C,0x0F,
+0xFF,0x8D,0x84,0x00,0x3C,0x0F,0xFF,0x87,0x49,0x00,0x2C,0xAD,0xFC,0x80,0xFC,0x40,
+0x2E,0x47,0xFF,0xA9,0x84,0x20,0xFF,0x04,0x2F,0x20,0x01,0x29,0x2F,0x30,0x01,0x28,
+0x80,0x41,0x84,0x01,0x80,0xA1,0x45,0x10,0x00,0x48,0x47,0x01,0x00,0x00,0x59,0x08,
+0x06,0x04,0x44,0x90,0x00,0x64,0x4C,0x59,0x00,0x19,0x80,0xF0,0x42,0x72,0xC4,0x73,
+0x84,0x60,0x97,0x98,0xE2,0xD3,0xE8,0x0E,0x38,0x63,0x8D,0x11,0x42,0xF3,0x24,0x24,
+0xE0,0x8F,0xE8,0x04,0x8C,0x21,0x96,0x48,0x84,0x00,0x42,0x23,0x08,0x00,0x8C,0x61,
+0xD5,0xF1,0x8C,0xA1,0x97,0x68,0xD5,0xE8,0x96,0x91,0x46,0x31,0x00,0x07,0x12,0x21,
+0x87,0x99,0x96,0x49,0x46,0x21,0x00,0x07,0x12,0x11,0x07,0x9A,0xFC,0xC0,0x46,0x11,
+0x00,0x07,0x04,0x20,0x80,0xB2,0xEA,0x2A,0x96,0xD1,0xFE,0xCC,0x2E,0x47,0xFF,0xB6,
+0x2E,0x17,0xFF,0xAF,0xFE,0x64,0xFE,0x0C,0xE2,0x03,0xE8,0x04,0x84,0x21,0x84,0x00,
+0xD5,0x03,0x84,0x20,0x84,0x01,0x96,0x91,0x46,0x31,0x00,0x07,0x12,0x21,0x87,0x99,
+0x96,0x49,0x46,0x21,0x00,0x07,0x12,0x11,0x07,0x9A,0xDD,0x9E,0xFC,0x42,0x44,0x00,
+0x87,0x87,0x46,0x11,0x00,0x07,0x14,0x00,0x83,0xC6,0x3C,0x2D,0xFF,0x90,0x84,0x00,
+0x12,0x0F,0x80,0x07,0x12,0x0F,0x80,0x03,0x12,0x0F,0x80,0x02,0x12,0x0F,0x80,0x01,
+0x84,0x1F,0x12,0x0F,0x80,0x06,0x12,0x0F,0x80,0x05,0x12,0x0F,0x80,0x04,0xEB,0x61,
+0x00,0x70,0x0F,0x1C,0xEB,0x61,0x00,0x60,0x0F,0x1D,0xEB,0x61,0x00,0x00,0x0F,0x20,
+0x97,0xF8,0x97,0xB0,0x54,0x90,0x00,0xFF,0x84,0xA0,0x44,0x10,0x05,0x10,0x98,0x15,
+0xA4,0x00,0x96,0x01,0x12,0x0F,0x80,0x07,0xEA,0x26,0x02,0x3F,0x80,0x01,0xE2,0x60,
+0xEA,0x26,0xE8,0x05,0x96,0x01,0x12,0x0F,0x80,0x01,0xD5,0x1F,0x02,0x3F,0x80,0x02,
+0xE2,0x60,0xE8,0x0A,0xEA,0x23,0xEA,0xD2,0x4C,0x30,0x00,0x07,0xEA,0x26,0x96,0x01,
+0x12,0x0F,0x80,0x02,0xD5,0x12,0xEA,0x26,0x02,0x3F,0x80,0x03,0xE2,0x60,0xE8,0x0D,
+0xEA,0x23,0xEA,0xD2,0x4C,0x30,0x00,0x0A,0xEA,0x23,0xEA,0xD3,0x4C,0x30,0x00,0x06,
+0xEA,0x26,0x96,0x01,0x12,0x0F,0x80,0x03,0xEA,0x23,0xEA,0x81,0xE2,0x60,0xE8,0x06,
+0xEA,0x26,0x96,0x01,0x12,0x0F,0x80,0x04,0xD5,0x1F,0xEA,0x23,0xEA,0xE5,0xE2,0x60,
+0xE8,0x0A,0xEA,0x23,0xEA,0x81,0x4C,0x30,0x00,0x07,0xEA,0x26,0x96,0x01,0x12,0x0F,
+0x80,0x05,0xD5,0x12,0xEA,0x23,0x02,0x0F,0x80,0x06,0xE2,0x60,0xE8,0x0D,0xEA,0x23,
+0xEA,0x81,0x4C,0x30,0x00,0x0A,0xEA,0x23,0xEA,0xE5,0x4C,0x30,0x00,0x06,0xEA,0x26,
+0x96,0x01,0x12,0x0F,0x80,0x06,0x8C,0xA2,0xD9,0xAB,0x84,0x20,0xFA,0x44,0xEB,0x61,
+0x58,0x00,0x0F,0x24,0xDD,0x42,0x49,0xFF,0xF6,0x60,0xFF,0xC4,0xEA,0x2A,0x40,0x73,
+0x84,0xF7,0x02,0x2F,0x80,0x01,0x97,0xF9,0xE2,0xE2,0xE9,0x09,0xFF,0x84,0x02,0x2F,
+0x80,0x04,0x40,0x63,0x04,0xD7,0x97,0xB1,0xE2,0x46,0xE8,0x07,0xEB,0x61,0xEA,0xE2,
+0x46,0x11,0x00,0x07,0xEA,0x37,0xEA,0xE1,0xEB,0x46,0xC0,0x05,0x80,0x09,0x49,0xFF,
+0xFF,0x40,0xD5,0x04,0x80,0x09,0x49,0xFF,0xFF,0x04,0xC8,0x07,0xEB,0x61,0xEA,0xE2,
+0x46,0x11,0x00,0x07,0xEB,0x05,0xEA,0xE1,0xEB,0x61,0xEA,0xE2,0xC8,0x06,0x44,0x0F,
+0xAA,0xAA,0x46,0x11,0x00,0x07,0xEA,0xE1,0xEA,0xD2,0x46,0x11,0x00,0x07,0x96,0x01,
+0x12,0x00,0x87,0x93,0xEA,0xD3,0x46,0x11,0x00,0x07,0x96,0x01,0x12,0x00,0x87,0x94,
+0x02,0x0F,0x80,0x03,0x46,0x11,0x00,0x07,0x96,0x01,0x12,0x00,0x87,0x95,0xEA,0x81,
+0x46,0x11,0x00,0x07,0x96,0x01,0x12,0x00,0x87,0x96,0xEA,0xE5,0x46,0x11,0x00,0x07,
+0x96,0x01,0x12,0x00,0x87,0x97,0x02,0x0F,0x80,0x06,0x46,0x11,0x00,0x07,0x96,0x01,
+0x12,0x00,0x87,0x98,0x84,0x00,0x46,0x11,0x00,0x07,0x12,0x00,0x87,0x9B,0x44,0x00,
+0xA6,0x6A,0x46,0x11,0x00,0x07,0x14,0x00,0x83,0xC6,0xFC,0xC2,0x46,0x08,0x00,0x20,
+0x04,0x10,0x00,0x0E,0x42,0x10,0xD4,0x08,0xEB,0x1A,0x4E,0x00,0x3D,0x27,0x4E,0x00,
+0x3D,0x2C,0x4E,0x00,0x3D,0x28,0x44,0x10,0xFB,0xFF,0x4E,0x00,0x3D,0x26,0x4E,0x00,
+0x3D,0x2C,0x46,0x11,0x00,0x07,0x02,0x10,0x80,0x40,0x84,0x45,0xE6,0x22,0x46,0x19,
+0x00,0x68,0xE9,0x02,0x84,0x4F,0x10,0x20,0x89,0x04,0x02,0x10,0x00,0x1E,0x84,0x44,
+0x58,0x10,0x80,0x01,0xEA,0x32,0x02,0x10,0x00,0x1E,0xEA,0xB3,0xEA,0x32,0x84,0x20,
+0xEA,0x75,0xEA,0x61,0xEB,0x2D,0xEA,0xDF,0xEA,0x3E,0x10,0x20,0x80,0x28,0xF8,0x76,
+0xDD,0x9E,0xFC,0x20,0x46,0x68,0x00,0x20,0x10,0x03,0x00,0x48,0x05,0x03,0x00,0x0E,
+0x46,0x7F,0xFE,0x3F,0x84,0x07,0x50,0x73,0x8F,0xFF,0xFE,0x46,0x40,0x78,0x1C,0x02,
+0x83,0x86,0x40,0x73,0x86,0x44,0xBF,0x8E,0xB9,0x0E,0xFE,0x86,0x66,0x10,0x80,0x38,
+0x40,0x20,0x88,0x64,0xBA,0x8E,0x12,0x33,0x00,0x9C,0x12,0x43,0x00,0x8A,0x12,0x53,
+0x00,0x0A,0xFC,0xA0,0xFC,0x00,0xEA,0x4C,0x00,0x50,0x81,0x2C,0x84,0x0A,0xFF,0x44,
+0x00,0x10,0x81,0x39,0x80,0x65,0xDD,0x5C,0x42,0x30,0x80,0x73,0x84,0x46,0x96,0xD9,
+0xFA,0x01,0x84,0x27,0x84,0x81,0xF8,0x17,0xFC,0x80,0xFC,0x00,0xEA,0x4C,0x00,0x40,
+0x81,0x2D,0x84,0x0A,0xFF,0x04,0x00,0x30,0x81,0x3A,0x80,0xA4,0xDD,0x5C,0x00,0x20,
+0x81,0x2F,0x42,0x51,0x80,0x73,0x00,0x00,0x81,0x2E,0x96,0xE9,0x40,0x11,0x10,0x09,
+0x80,0xA4,0x96,0x9F,0x49,0xFF,0xFF,0xB7,0xFC,0x80,0xFC,0x01,0x84,0x20,0xF0,0x81,
+0x46,0x09,0x00,0x68,0x10,0x10,0x09,0x04,0x84,0x0E,0xDD,0x40,0xC0,0x35,0x84,0x0E,
+0xDD,0x40,0xC0,0x39,0xDD,0x43,0xEB,0x0F,0x44,0x10,0xFF,0xDF,0x4E,0x00,0x3C,0xA5,
+0x44,0x10,0xFE,0xFF,0x4E,0x00,0x3C,0xA1,0x4E,0x00,0x3C,0x9D,0x44,0x10,0xFB,0xFF,
+0xFE,0x56,0xEA,0x32,0x51,0xC0,0x00,0x38,0xB9,0x7F,0x2E,0x20,0x00,0xBF,0x66,0x10,
+0x8F,0x00,0x96,0x9F,0x40,0x10,0x89,0x04,0xB9,0xFF,0x44,0x10,0x00,0x32,0x12,0x10,
+0x00,0x9A,0x83,0xFF,0x84,0x21,0xEA,0x75,0xB4,0x5C,0x46,0x1F,0xFE,0x3F,0xEA,0x7F,
+0xFE,0x56,0x42,0x10,0xC8,0x08,0xB6,0x3C,0xB4,0x3C,0x66,0x10,0x80,0x38,0x58,0x10,
+0x80,0x08,0xB6,0x3C,0xD5,0x18,0xFA,0x02,0xDD,0x40,0xC8,0xCA,0xFA,0x06,0xDD,0x40,
+0xC8,0xC7,0xD5,0x17,0xFA,0x02,0xDD,0x40,0xC0,0x06,0xF8,0x08,0xF0,0x01,0x49,0xFF,
+0xFF,0x8B,0xD5,0x09,0xFA,0x06,0xDD,0x40,0xC0,0x06,0x49,0xFF,0xFF,0x31,0xF0,0x01,
+0x49,0xFF,0xFF,0x95,0xF0,0x01,0x49,0xFF,0xFC,0xCB,0xEA,0x59,0x49,0xFF,0xFC,0xE8,
+0xDD,0x47,0xDD,0x40,0xEA,0x28,0xC0,0x02,0x84,0x01,0x10,0x00,0x80,0x68,0x10,0x00,
+0x80,0x6C,0xFC,0x81,0xFC,0x00,0x84,0x07,0xDD,0x40,0xC0,0x1F,0xDD,0x4B,0x5A,0x00,
+0x07,0x05,0x66,0x10,0x00,0x02,0xC9,0x04,0x49,0xFF,0xFD,0xC5,0xD5,0x1C,0x2E,0x10,
+0x00,0xDF,0xEA,0x5B,0xC1,0x0C,0x5A,0x00,0x06,0x0B,0xDD,0x43,0x84,0x26,0xEB,0x31,
+0x84,0x20,0xEB,0x32,0x44,0x1F,0xFC,0x78,0x4E,0x00,0x40,0xA9,0x44,0x00,0x24,0x24,
+0x46,0x11,0x00,0x07,0xEA,0x30,0xD5,0x07,0x84,0x08,0xDD,0x40,0xC0,0x03,0xF9,0x85,
+0xD5,0x02,0xF9,0x49,0xFC,0x80,0xEA,0x35,0x96,0x04,0xC0,0x09,0xFC,0x00,0x49,0x00,
+0x34,0x48,0xC8,0xFE,0x49,0x00,0x34,0x2A,0xC8,0xFE,0xFC,0x80,0xDD,0x9E,0xFC,0x00,
+0xFA,0x13,0xDD,0x40,0xC0,0x0F,0xEB,0x51,0x58,0x00,0x04,0x74,0x3C,0x0F,0xFF,0x90,
+0x84,0x21,0x84,0x08,0xEA,0x34,0x84,0x01,0xEB,0x3C,0xEB,0x0C,0x84,0x00,0xEB,0x2E,
+0xD5,0x0B,0xFA,0x18,0xDD,0x40,0xC8,0xF0,0xEB,0x64,0xEB,0x47,0x3C,0x0F,0xFF,0x90,
+0x84,0x07,0x84,0x21,0xEA,0x34,0xFC,0x80,0xEA,0x35,0x96,0x04,0xC0,0x09,0xFC,0x00,
+0x49,0x00,0x34,0x0D,0xC8,0xFE,0x49,0x00,0x34,0x13,0xC8,0xFE,0xFC,0x80,0xDD,0x9E,
+0xFC,0x00,0xEA,0x4C,0xA6,0x0B,0x58,0x00,0x00,0x10,0xAE,0x0B,0x4E,0x00,0x04,0xC0,
+0x46,0x11,0x00,0x07,0xEA,0x70,0xF8,0xBF,0xFC,0x80,0xFC,0x00,0x80,0xC0,0xFA,0x08,
+0xDD,0x40,0xC0,0x0D,0xEA,0x35,0xEA,0x8A,0xC0,0x0A,0x40,0x03,0x10,0x09,0xEA,0x28,
+0x12,0x00,0x82,0xB8,0x50,0x00,0x00,0x64,0x12,0x00,0x80,0xB6,0xFA,0x11,0xDD,0x40,
+0xC0,0x0C,0xEA,0x35,0xEA,0x8A,0xC0,0x09,0x92,0xC1,0xDD,0x43,0x12,0x60,0x02,0xB8,
+0x50,0x63,0x00,0x64,0x12,0x60,0x00,0xB6,0xFC,0x80,0xFC,0x00,0xEB,0x7B,0x58,0x10,
+0x86,0x58,0xEA,0xB2,0x50,0x20,0x8A,0x20,0xDD,0x48,0xFC,0x80,0xFC,0x00,0x3F,0xCF,
+0xFD,0xD8,0xFA,0x07,0xDD,0x40,0xC0,0x05,0xEA,0x50,0x44,0x00,0x56,0x56,0xD5,0x21,
+0xFA,0x08,0xDD,0x40,0xC0,0x18,0xB8,0x00,0x5A,0x08,0x07,0x30,0xB8,0x12,0xB9,0x08,
+0xE2,0x20,0xE8,0x08,0x49,0xFF,0xFF,0xE3,0xEB,0x54,0xEA,0xAC,0xEB,0x5A,0xEA,0x8C,
+0xEB,0x13,0xB8,0x08,0xB9,0x12,0xE2,0x01,0xE8,0x04,0x8C,0x01,0xB8,0x88,0xD5,0x1D,
+0xEB,0x39,0xD5,0x11,0xFA,0x0B,0xDD,0x40,0xC0,0x08,0xEA,0x50,0x44,0x00,0x51,0x61,
+0x46,0x11,0x00,0x07,0xEA,0x30,0xD5,0x11,0xFA,0x0C,0xDD,0x40,0xC0,0x06,0xB8,0x00,
+0x5A,0x08,0x07,0x0C,0xEA,0x53,0xD5,0x09,0xFA,0x0D,0xDD,0x40,0xC0,0xFC,0xB8,0x00,
+0x5A,0x08,0x07,0x04,0x49,0xFF,0xFF,0xBB,0xFC,0x80,0xFC,0x00,0xEB,0x7B,0x58,0x10,
+0x86,0x58,0xEA,0x5A,0x50,0x20,0x8A,0x20,0xDD,0x48,0xFC,0x80,0xFC,0x00,0x3F,0xCF,
+0xFD,0xD8,0xFA,0x0F,0xDD,0x40,0xC0,0x05,0xEA,0x50,0x44,0x00,0x50,0x60,0xD5,0x24,
+0xFA,0x11,0xDD,0x40,0xC0,0x1B,0xB8,0x00,0x5A,0x08,0x08,0x33,0xB8,0x12,0xB9,0x08,
+0xE2,0x20,0xE8,0x0A,0x49,0xFF,0xFF,0xE3,0x49,0x00,0x2A,0x54,0xEB,0x51,0xEA,0xFA,
+0xEB,0x5A,0xEA,0x8C,0xEB,0x13,0xB8,0x08,0xB9,0x12,0xE2,0x01,0xE8,0x03,0x8C,0x01,
+0xB8,0x88,0xBD,0x08,0xD9,0x1D,0xEB,0x39,0xD5,0x11,0xFA,0x14,0xDD,0x40,0xC0,0x08,
+0xEA,0x50,0x44,0x00,0x52,0x62,0x46,0x11,0x00,0x07,0xEA,0x30,0xD5,0x11,0xFA,0x16,
+0xDD,0x40,0xC0,0x06,0xB8,0x00,0x5A,0x08,0x08,0x0C,0xEA,0x53,0xD5,0x09,0xFA,0x17,
+0xDD,0x40,0xC0,0xFC,0xB8,0x00,0x5A,0x08,0x08,0x04,0x49,0xFF,0xFF,0xB8,0xFC,0x80,
+0xFC,0x00,0xEA,0x4C,0xA6,0x0B,0x66,0x00,0x00,0x10,0xAE,0x0B,0x84,0x00,0x46,0x11,
+0x00,0x07,0xEA,0x70,0x49,0xFF,0xFF,0x01,0xF8,0x46,0xFC,0x80,0xFC,0x00,0x3F,0xCF,
+0xFD,0xD8,0xFA,0x1D,0xDD,0x40,0xC0,0x0B,0xEA,0x35,0x96,0x04,0xC0,0x02,0xEA,0x50,
+0x44,0x00,0xBF,0xBF,0x46,0x11,0x00,0x07,0xEA,0x30,0xD5,0x30,0xFA,0x1E,0xDD,0x40,
+0xC0,0x2C,0xEA,0x35,0x96,0x04,0xC0,0x04,0xB8,0x00,0x5A,0x08,0x07,0x28,0xB8,0x12,
+0xB9,0x08,0xE2,0x20,0xE8,0x17,0x84,0x01,0x44,0x10,0x02,0x88,0xEB,0x57,0xEA,0x67,
+0x46,0x31,0x00,0x02,0x58,0x31,0x86,0x58,0x49,0xFF,0xFA,0x7F,0x84,0x00,0x44,0x10,
+0x02,0x88,0xEB,0x57,0xEA,0x67,0x46,0x31,0x00,0x03,0x58,0x31,0x80,0x78,0x49,0xFF,
+0xFA,0x74,0xB8,0x08,0xB9,0x12,0xE2,0x01,0xE8,0x04,0x8C,0x01,0xB8,0x88,0xD5,0x06,
+0xEA,0x35,0x96,0x04,0xC0,0x02,0xEB,0x39,0xEA,0x53,0xFC,0x80,0xFC,0x00,0x84,0x0E,
+0xDD,0x40,0xC0,0x03,0xEA,0x53,0xF8,0x0C,0xFA,0x02,0xDD,0x40,0xC8,0xFC,0xFA,0x06,
+0xDD,0x40,0xC8,0xF9,0x84,0x0A,0xDD,0x40,0xC0,0x05,0x49,0xFF,0xFE,0x85,0x48,0x00,
+0x00,0x3A,0xFA,0x0A,0xDD,0x40,0xC0,0x04,0x49,0xFF,0xFF,0x12,0xD5,0x33,0xFA,0x0E,
+0xDD,0x40,0xC8,0xFB,0xFA,0x13,0xDD,0x40,0xC0,0x04,0x49,0xFF,0xFF,0x51,0xD5,0x2A,
+0xFA,0x18,0xDD,0x40,0xC8,0xFB,0xFA,0x1C,0xDD,0x40,0xC0,0x04,0x49,0xFF,0xFF,0x8A,
+0xD5,0x21,0xDD,0x47,0xDD,0x40,0xC0,0x04,0x49,0xFF,0xFF,0x92,0xD5,0x1B,0x84,0x06,
+0xDD,0x40,0xC0,0x0B,0xEA,0x6A,0x66,0x00,0x00,0x08,0x3E,0x07,0xFF,0xA2,0x84,0x00,
+0xEB,0x3C,0x84,0x00,0x3C,0x0F,0xFF,0x8D,0x49,0xFF,0xFA,0x67,0xEB,0x61,0x04,0x50,
+0x03,0xC6,0x44,0x00,0x6A,0xA6,0xD8,0x06,0x84,0x02,0xDD,0x40,0xC0,0x03,0x49,0xFF,
+0xFC,0x7F,0xFC,0x80,0xFC,0x00,0xDD,0x4D,0x96,0x04,0xC0,0x16,0xEA,0x33,0xC0,0x07,
+0x2E,0x07,0xFE,0x79,0x2E,0x17,0xFF,0xF1,0xE2,0x01,0xE9,0x05,0x84,0x00,0x3E,0x07,
+0xFE,0x79,0xD5,0x0C,0x8C,0x01,0x3E,0x07,0xFE,0x79,0x2E,0x07,0xFE,0x78,0x8C,0x01,
+0x3E,0x07,0xFE,0x78,0xD5,0x03,0x84,0x02,0xEA,0x6D,0xFC,0x80,0xFC,0x40,0xEA,0x2C,
+0x84,0x24,0x9D,0x82,0x8E,0x01,0xEA,0xDD,0x46,0x90,0x0F,0xFF,0x88,0xC0,0x97,0xB0,
+0x84,0xE0,0x50,0x94,0x8F,0xFF,0xC6,0x12,0x5A,0x68,0x01,0x09,0x52,0x73,0xFE,0x03,
+0x97,0xF9,0x40,0x04,0x9F,0x04,0xDD,0x4A,0xD5,0x06,0x84,0x1F,0x50,0x73,0x83,0xFC,
+0xDD,0x4A,0x97,0xF9,0x8E,0xC1,0x97,0xB0,0xD5,0xEF,0x3E,0x67,0xFD,0x1A,0xFC,0xC0,
+0xFC,0x60,0x80,0xC0,0x3C,0xCD,0xFF,0x93,0x2E,0x87,0xFD,0x28,0x3C,0x9D,0xFF,0x82,
+0xEA,0x45,0xEA,0xEB,0x3C,0x0D,0xFF,0x8A,0xC0,0x04,0x00,0x73,0x00,0x92,0xC7,0x03,
+0x2E,0x77,0xFD,0x68,0x85,0x60,0x81,0xA6,0x81,0xCB,0xEA,0x2C,0x40,0xF7,0x00,0x06,
+0xE8,0x34,0x2E,0x00,0x00,0x14,0xEA,0xA3,0xC0,0x0B,0x04,0x16,0x80,0x01,0x96,0x09,
+0xEA,0xB1,0x96,0x49,0x96,0x01,0x40,0x20,0x05,0x15,0xB4,0x2D,0xD5,0x0A,0xB4,0x2D,
+0x96,0x09,0xEA,0xB1,0x96,0x49,0x96,0x01,0x40,0x20,0x05,0x15,0x04,0x16,0x80,0x01,
+0x96,0x09,0xEA,0xB1,0x96,0x01,0x96,0x49,0x40,0x10,0x05,0x15,0x40,0x01,0x06,0x00,
+0xDD,0x4A,0xB4,0x2D,0x04,0x26,0x80,0x01,0x96,0x08,0x40,0x10,0x05,0x1C,0x89,0x61,
+0x40,0xB5,0x89,0x1C,0x96,0x90,0x40,0x05,0x88,0x00,0x40,0xB0,0x00,0x13,0x50,0xE7,
+0x00,0x01,0x50,0xD6,0x80,0x0C,0xD5,0xCA,0x00,0x03,0x00,0x20,0x00,0x23,0x00,0x14,
+0x00,0x13,0x00,0x08,0xEA,0xE8,0x40,0x00,0x09,0x00,0x88,0x01,0x00,0x13,0x00,0x2C,
+0xEA,0x87,0xDD,0x4A,0x84,0x0A,0xDD,0x50,0xEA,0x2C,0xE6,0x05,0xE9,0x11,0x00,0x03,
+0x00,0x50,0x00,0x23,0x00,0x44,0x00,0x13,0x00,0x38,0xEA,0xE8,0x40,0x00,0x09,0x00,
+0x88,0x01,0x00,0x13,0x00,0x5C,0xEA,0x87,0xDD,0x4A,0x84,0x0A,0xDD,0x50,0xEA,0x2C,
+0xE6,0x09,0xE9,0x0A,0x00,0x13,0x00,0x74,0x00,0x03,0x00,0x68,0x40,0x00,0x05,0x00,
+0xDD,0x4A,0x84,0x0A,0xDD,0x50,0xEA,0xDB,0x84,0x20,0x84,0x6C,0xE2,0x22,0xE8,0x0B,
+0x80,0x06,0x42,0x00,0x8C,0x73,0x8C,0x21,0x00,0x00,0x00,0x08,0x88,0x0B,0x40,0xB0,
+0x00,0x13,0xD5,0xF5,0xEA,0x69,0xEA,0x8A,0xC0,0x15,0xEA,0xFD,0xEA,0x2B,0xE3,0x0C,
+0x94,0x05,0x40,0xA0,0x28,0x64,0x40,0xA5,0x04,0x24,0x8F,0x23,0x40,0x85,0x3C,0x04,
+0xE7,0x21,0x40,0xF4,0x3C,0x44,0x40,0x77,0x9C,0x84,0x12,0x73,0x00,0x48,0x3E,0x17,
+0xFD,0x5E,0x02,0x23,0x00,0x48,0x00,0x13,0x00,0x92,0x40,0x31,0x20,0x09,0x96,0x10,
+0x96,0x90,0x88,0x43,0x58,0x10,0x80,0xF0,0x40,0x00,0x81,0x00,0x88,0x22,0x40,0x00,
+0x0E,0x00,0x89,0x61,0x40,0x00,0x2F,0x01,0xDD,0x4A,0xFC,0xE0,0xFC,0x00,0xEA,0x51,
+0x5A,0x08,0x01,0x04,0x49,0x00,0x2C,0x21,0x49,0x00,0x2C,0x1A,0x80,0xC0,0xEA,0x51,
+0xC0,0x07,0xEA,0x51,0x5A,0x08,0x01,0x0A,0xEA,0x52,0x5A,0x08,0x01,0x07,0x3C,0x03,
+0xFE,0xC3,0x8C,0x01,0x3C,0x0B,0xFE,0xC3,0xEA,0x84,0xC8,0x1B,0xEA,0x51,0xC0,0x07,
+0xEA,0x51,0x5A,0x08,0x01,0x17,0xEA,0x52,0x5A,0x08,0x01,0x14,0x84,0x01,0x3E,0x07,
+0xFD,0x07,0x49,0xFF,0xFE,0xE9,0xEA,0x33,0xC8,0x0C,0xEA,0xEE,0xC0,0x05,0x80,0x06,
+0x49,0xFF,0xFF,0x20,0xD5,0x05,0x2E,0x07,0xFE,0x7A,0xC0,0x03,0xEA,0xB7,0xEA,0xC4,
+0xEA,0xEE,0x3E,0x07,0xFE,0x7A,0xFC,0x80,0xFC,0x40,0x3F,0xCF,0xFD,0xD8,0x80,0xC0,
+0x49,0xFF,0xFE,0xD2,0xEA,0x33,0x81,0x20,0x49,0x00,0x3C,0xDA,0x4E,0x02,0x00,0xF3,
+0x5C,0x94,0x80,0x01,0x4E,0x92,0x00,0x07,0x2E,0x07,0xFD,0x1A,0xC0,0x03,0xEA,0xB7,
+0xEA,0xF6,0xBA,0x00,0x9E,0x17,0xE6,0x02,0xEA,0x7B,0xE8,0x08,0xC9,0x07,0x5A,0x20,
+0x07,0x03,0xEA,0xF6,0x49,0x00,0x18,0x5F,0xEA,0xF6,0x4E,0x12,0x00,0x50,0x84,0x3F,
+0x3E,0x17,0xFE,0x24,0x2E,0x17,0xFD,0x0A,0xC9,0x49,0x4E,0x92,0x00,0x48,0xDD,0x4D,
+0x96,0x04,0xC8,0x02,0xEA,0x6D,0x2E,0x07,0xFD,0x08,0x44,0x10,0xA5,0x5A,0xEB,0x49,
+0xEA,0x7B,0xEA,0x87,0xDD,0x4A,0x2E,0x67,0xFD,0x08,0x44,0x2F,0xA5,0x5A,0x44,0x10,
+0x00,0x3D,0x88,0x46,0xEA,0x84,0xFF,0x8C,0x40,0x21,0x01,0x00,0x8C,0xC2,0xEB,0x81,
+0x58,0x00,0x00,0x00,0x40,0x60,0x18,0x20,0x96,0x91,0x80,0xA6,0x50,0x03,0x00,0x7A,
+0x0A,0x12,0x80,0x01,0x88,0x41,0x96,0x91,0xD8,0xFC,0xFE,0x92,0x40,0x71,0x40,0x08,
+0x85,0x40,0xA4,0x30,0x5A,0xA8,0x1E,0x05,0x8C,0xC2,0x88,0x07,0xD5,0x05,0xA4,0x71,
+0x8C,0xC4,0x40,0x00,0x06,0x00,0xDD,0x4A,0x8D,0x41,0xFA,0x0E,0xDD,0x50,0x5A,0xA8,
+0x1F,0xF2,0x2E,0x07,0xFD,0x08,0x8C,0x01,0x96,0x00,0xEA,0xC2,0x2E,0x17,0xFD,0x11,
+0xE2,0x01,0xE9,0x21,0x84,0x00,0xEA,0xC2,0xD5,0x1E,0x00,0x23,0x00,0x92,0x4E,0x23,
+0x00,0x7A,0xEA,0xF4,0xEA,0x5B,0xC1,0x09,0x2E,0x57,0xFD,0x65,0x2E,0x17,0xFD,0x5E,
+0xD1,0x04,0xE6,0x02,0x4E,0xF2,0x00,0x6F,0xEA,0x52,0xC8,0x0D,0xB8,0x14,0xC8,0x04,
+0x2E,0x07,0xFD,0x0A,0xC0,0x08,0x4E,0x92,0x00,0x04,0xEA,0xB7,0xD5,0x04,0x84,0x01,
+0x3E,0x07,0xFD,0x1A,0x2E,0x07,0xFD,0x0A,0x4E,0x02,0x00,0x6D,0x4E,0x92,0x00,0x6B,
+0xDD,0x4D,0x96,0x04,0xC8,0x02,0xEA,0x6D,0x2E,0x07,0xFD,0x09,0x8C,0x01,0x96,0x00,
+0x3E,0x07,0xFD,0x09,0x2E,0x17,0xFD,0x0C,0xE2,0x20,0xE8,0x04,0x84,0x01,0x3E,0x07,
+0xFD,0x09,0x2E,0x07,0xFD,0x09,0x2E,0x77,0xFD,0x10,0x9E,0x41,0x92,0xE1,0xFF,0xCC,
+0xEB,0x5A,0xEB,0x30,0x40,0x70,0x9C,0x20,0x2E,0x17,0xFD,0x34,0xC1,0x11,0x44,0x10,
+0xA3,0x3A,0xEB,0x49,0xEA,0x7B,0xEA,0x87,0xDD,0x4A,0x2E,0x17,0xFD,0x09,0x44,0x0F,
+0xA3,0x3A,0x88,0x01,0xEA,0x7B,0x40,0x00,0x05,0x00,0x96,0x01,0xD5,0x07,0x46,0x00,
+0x40,0x30,0x50,0x00,0x02,0x01,0xDD,0x4A,0x84,0x0A,0x2E,0x27,0xFD,0x10,0x84,0x20,
+0x92,0x41,0xE2,0x22,0xE8,0x07,0x38,0x33,0x85,0x01,0x8C,0x21,0x88,0x03,0x96,0x01,
+0xD5,0xF9,0xFE,0x02,0x40,0x60,0x40,0x08,0x85,0x20,0x2E,0x17,0xFD,0x10,0x8C,0x22,
+0x90,0x22,0xE3,0x21,0xE8,0x1F,0x8E,0x21,0xA4,0x38,0x4C,0x90,0xC0,0x05,0x8C,0xE2,
+0x88,0x06,0xD5,0x05,0xA4,0x79,0x8C,0xE4,0x40,0x00,0x06,0x00,0xDD,0x4A,0x8D,0x21,
+0xD5,0xED,0x5A,0x90,0x01,0x04,0x48,0xFF,0xFF,0x9F,0xEA,0x52,0x4E,0x03,0xFF,0x9C,
+0xB8,0x14,0xC0,0x03,0x4E,0x22,0xFF,0x93,0x80,0x06,0x49,0xFF,0xFE,0x1B,0x48,0xFF,
+0xFF,0x93,0xFC,0xC0,0xFC,0x20,0x80,0xE0,0x80,0xC1,0x49,0x00,0x27,0xB9,0xDD,0x4B,
+0x84,0x20,0x49,0x00,0x29,0xAB,0xEA,0xAE,0x3E,0x20,0x01,0x29,0x84,0x00,0xEA,0xD6,
+0x3E,0x07,0xFD,0x14,0xEB,0x5A,0x10,0x00,0x86,0x01,0xFA,0x00,0x3E,0x07,0xFD,0x03,
+0xFA,0x14,0xFA,0x30,0x49,0x00,0x3B,0x0E,0xEA,0xDB,0x84,0x25,0xFE,0x8C,0x96,0x90,
+0x54,0x01,0x00,0x03,0xC8,0x03,0x8C,0x44,0xD5,0x02,0x8C,0x48,0x96,0x90,0x66,0x21,
+0x00,0x03,0x52,0x21,0x00,0x7A,0x96,0x90,0x3E,0x27,0xFD,0x10,0x2E,0x40,0x01,0x29,
+0x2E,0x30,0x01,0x28,0x2E,0x10,0x01,0x31,0x42,0x12,0x0C,0x73,0x92,0x41,0x40,0x20,
+0x88,0x17,0x96,0x90,0xC0,0x02,0x8C,0x41,0x3E,0x27,0xFD,0x0C,0x44,0x20,0x00,0x3D,
+0x40,0x20,0x88,0x37,0x96,0x90,0xC1,0x02,0x8C,0x41,0x3E,0x27,0xFD,0x11,0x84,0x00,
+0xEA,0xC2,0x2E,0x17,0xFF,0xAF,0x3E,0x17,0xFD,0x1C,0x3E,0x07,0xFD,0x1A,0x2E,0x00,
+0x00,0x16,0x2E,0x20,0x00,0x17,0x40,0x21,0x01,0x04,0x3C,0x2E,0x00,0x48,0x2E,0x00,
+0x00,0x18,0x2E,0x10,0x00,0x19,0x40,0x10,0x81,0x04,0x3C,0x1E,0x00,0x49,0x40,0x21,
+0x0C,0x57,0x40,0x10,0x90,0x37,0x3E,0x20,0x01,0x32,0x3E,0x10,0x01,0x33,0x8C,0x82,
+0x3E,0x47,0xFD,0x16,0x8C,0x62,0x3E,0x37,0xFD,0x05,0x84,0x00,0x3C,0x0B,0xFE,0xC1,
+0xCF,0x21,0xEB,0x61,0x14,0x70,0x03,0xF1,0xDD,0x4D,0x96,0x04,0xC0,0x05,0x84,0x01,
+0xEB,0x48,0x84,0x02,0xEA,0x6D,0xEB,0x61,0x58,0x00,0x0F,0x44,0x84,0x20,0x44,0x20,
+0x00,0x3C,0xDD,0x42,0xCE,0x08,0xEB,0x61,0x58,0x00,0x03,0xB0,0x80,0x26,0x44,0x20,
+0x00,0x3C,0xDD,0x42,0xEB,0x61,0x58,0x00,0x0F,0x80,0x84,0x20,0x44,0x20,0x00,0x40,
+0xDD,0x42,0x46,0x19,0x00,0x08,0xA4,0x08,0x96,0x01,0x3C,0x0B,0xFE,0xBE,0x92,0x01,
+0x3C,0x0B,0xFE,0xBF,0xA4,0x0A,0x3C,0x0B,0xFE,0xBD,0x49,0x00,0x05,0x0B,0x84,0x1F,
+0x3E,0x07,0xFE,0x24,0x84,0x00,0xEA,0xC8,0x3E,0x07,0xFD,0x0B,0x84,0x00,0x3C,0x0B,
+0xFE,0xC3,0xFC,0xA0,0xFC,0x61,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,
+0x96,0x01,0xDD,0x58,0xEA,0x37,0xDD,0x45,0x46,0x01,0x00,0x07,0x04,0x50,0x03,0xF0,
+0x44,0x00,0xA1,0x1A,0x92,0xB0,0xD8,0x03,0x49,0x00,0x2F,0xE4,0x49,0x00,0x3B,0x8E,
+0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x58,0xEB,0x03,
+0xDD,0x45,0x49,0x00,0x35,0x0D,0xC8,0xFE,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,
+0x00,0x07,0x96,0x01,0xDD,0x58,0x58,0x00,0x00,0x03,0xDD,0x45,0x49,0x00,0x3B,0xB8,
+0x49,0xFF,0xF3,0x6E,0xC0,0x02,0x96,0x01,0x46,0x11,0x00,0x07,0x12,0x00,0x87,0xA1,
+0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x58,0xEB,0x05,
+0xDD,0x45,0xFA,0x4F,0x44,0x00,0x00,0xE7,0x84,0x22,0x44,0x30,0x00,0xF8,0xDD,0x4E,
+0x49,0xFF,0xF1,0xBE,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,
+0xDD,0x58,0x58,0x00,0x00,0x05,0xDD,0x45,0x84,0x01,0x44,0x10,0x01,0xE0,0x84,0x45,
+0x44,0x30,0x02,0x58,0x49,0x00,0x34,0x84,0x80,0xC0,0xC8,0xF7,0x84,0x45,0x84,0x01,
+0x44,0x10,0x00,0x80,0x49,0x00,0x34,0xB9,0x46,0x01,0x00,0x07,0xEA,0xBA,0x96,0x49,
+0xEA,0x6F,0x58,0x10,0x80,0x06,0xEA,0x7C,0x49,0xFF,0xF4,0xFD,0x49,0xFF,0xF5,0x47,
+0x4E,0x00,0x33,0x6E,0x80,0x06,0xEA,0x5B,0xEA,0xAB,0x84,0x21,0xEB,0x81,0x12,0x60,
+0x00,0x00,0x80,0x41,0x44,0x00,0x00,0xE7,0xEA,0x3A,0x96,0x01,0x46,0x11,0x00,0x07,
+0x12,0x00,0x87,0xAF,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,
+0xDD,0x58,0x58,0x00,0x00,0x07,0xDD,0x45,0xFA,0x0A,0xDD,0x40,0xC8,0x19,0xFA,0x0E,
+0xDD,0x40,0xC8,0x16,0xFA,0x13,0xDD,0x40,0xC8,0x13,0xFA,0x18,0xDD,0x40,0xC8,0x10,
+0x46,0x01,0x00,0x07,0xEA,0x63,0x4E,0x00,0x33,0x04,0xD8,0x08,0xEA,0x21,0xEA,0x20,
+0x83,0xFF,0x46,0x11,0x00,0x07,0xEA,0x70,0xD5,0x03,0x49,0xFF,0xF3,0x24,0x49,0x00,
+0x3B,0xA6,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x58,
+0x58,0x00,0x00,0x08,0xDD,0x45,0x84,0x00,0xDD,0x55,0x84,0xC0,0x3C,0x6F,0xFF,0x7C,
+0x46,0x01,0x00,0x07,0xEA,0xBA,0x84,0x41,0x96,0x49,0xEA,0x6F,0x10,0x2F,0x80,0x00,
+0x10,0x2F,0x80,0x01,0x10,0x2F,0x80,0x02,0x10,0x2F,0x80,0x03,0x10,0x2F,0x80,0x04,
+0x58,0x10,0x80,0x09,0xEA,0x7C,0x3A,0x0F,0x84,0x00,0x49,0x00,0x2F,0x3C,0x80,0x06,
+0x84,0x26,0x49,0x00,0x3A,0x62,0x46,0x00,0x0E,0xD0,0x46,0x10,0x20,0x0C,0x50,0x00,
+0x00,0x40,0x8C,0x26,0x49,0x00,0x3A,0x54,0x46,0x09,0x00,0x20,0xB4,0x20,0x66,0x10,
+0x80,0x40,0xB6,0x20,0xEA,0xF4,0xEA,0x8B,0xC1,0x05,0xA0,0x41,0x58,0x10,0x80,0x08,
+0xA8,0x41,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x58,
+0x58,0x00,0x00,0x0A,0xDD,0x45,0x84,0x41,0x44,0x00,0x00,0xBC,0x84,0x20,0x84,0x66,
+0x46,0x78,0x00,0x20,0x46,0x9A,0x33,0xAA,0xDD,0x4E,0x84,0xC0,0x50,0xA3,0x84,0xF4,
+0x50,0x94,0x83,0x3A,0x46,0xB9,0x00,0x90,0x84,0x07,0x49,0x00,0x2D,0x55,0x8C,0x05,
+0x46,0x11,0x00,0x07,0x14,0x00,0x83,0xF9,0xEA,0x42,0x4E,0x02,0x00,0xC7,0xEA,0x93,
+0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x58,0x58,0x00,
+0x00,0x0B,0xDD,0x45,0x84,0x0E,0xDD,0x40,0xC0,0x04,0x84,0x00,0xDD,0x55,0xD5,0x0C,
+0xFA,0x02,0xDD,0x40,0xC8,0xFB,0xFA,0x06,0xDD,0x40,0xC8,0xF8,0xDD,0x47,0xDD,0x40,
+0xC8,0xF5,0x49,0xFF,0xED,0xD0,0x49,0x00,0x02,0xD1,0xC8,0x1E,0x46,0x01,0x00,0x07,
+0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x58,0x58,0x00,0x00,0x0C,0xDD,0x45,
+0x84,0x0E,0xDD,0x40,0xC0,0x04,0x49,0xFF,0xF4,0xE1,0xF8,0x0C,0xFA,0x02,0xDD,0x40,
+0xC8,0xFB,0xFA,0x06,0xDD,0x40,0xC8,0xF8,0xDD,0x47,0xDD,0x40,0xC8,0xF5,0x49,0x00,
+0x02,0x09,0x48,0x00,0x00,0x83,0x84,0x00,0x3E,0x07,0xFD,0x00,0x3E,0x07,0xFD,0x07,
+0x46,0x01,0x00,0x07,0xEA,0xBA,0x96,0x49,0xEA,0x6F,0x58,0x10,0x80,0x0D,0xEA,0x7C,
+0x84,0x0E,0xDD,0x40,0xC8,0x28,0xFA,0x02,0xDD,0x40,0xC8,0x25,0xFA,0x06,0xDD,0x40,
+0xC8,0x22,0xDD,0x47,0xDD,0x40,0xC8,0x1F,0xDD,0x4B,0x5A,0x00,0x08,0x15,0x5A,0x00,
+0x06,0x13,0xDD,0x59,0x5A,0x08,0x01,0x06,0xF8,0x4C,0xC8,0x03,0x49,0x00,0x29,0x4D,
+0xEB,0x21,0xC8,0x0D,0x49,0x00,0x11,0xE8,0x49,0x00,0x2A,0x7E,0x49,0x00,0x27,0xB0,
+0x80,0xC0,0xD5,0x05,0x49,0x00,0x25,0x46,0x49,0x00,0x25,0x22,0xEB,0x21,0xC8,0x03,
+0x49,0x00,0x02,0x48,0x49,0xFF,0xFB,0x64,0x49,0xFF,0xED,0xB0,0x84,0x01,0x3E,0x07,
+0xFD,0x00,0x80,0x06,0x49,0xFF,0xFC,0xD2,0xEA,0xEE,0x49,0x00,0x28,0xD4,0xEA,0x52,
+0xC8,0x02,0xEA,0xC4,0x49,0x00,0x01,0x9F,0x84,0x0E,0xDD,0x40,0xC8,0x36,0xFA,0x02,
+0xDD,0x40,0xC8,0x33,0xFA,0x06,0xDD,0x40,0xC8,0x30,0x84,0x0A,0xDD,0x40,0xC8,0x2D,
+0xFA,0x0A,0xDD,0x40,0xC8,0x2A,0xFA,0x13,0xDD,0x40,0xC8,0x27,0xFA,0x0E,0xDD,0x40,
+0xC8,0x24,0xFA,0x18,0xDD,0x40,0xC8,0x21,0xFA,0x1C,0xDD,0x40,0xC8,0x1E,0xDD,0x47,
+0xDD,0x40,0xC8,0x1B,0x3C,0x0D,0xFF,0x88,0x5A,0x08,0x01,0x18,0xEB,0x21,0xC8,0x13,
+0xEA,0xDC,0x5A,0x08,0x01,0x09,0x00,0x05,0x00,0x00,0x96,0x04,0xC8,0x04,0x49,0x00,
+0x24,0x8B,0xD5,0x07,0x00,0x05,0x00,0x00,0x96,0x0E,0xC8,0x03,0x49,0x00,0x24,0x3B,
+0x49,0x00,0x25,0x48,0x49,0x00,0x29,0xE6,0x46,0x01,0x00,0x07,0xEA,0xBA,0x96,0x49,
+0xEA,0x6F,0x58,0x10,0x80,0x0E,0xEA,0x7C,0xDD,0x4B,0x5A,0x08,0x07,0x07,0x00,0x53,
+0x83,0x40,0xEA,0x57,0xD8,0x19,0xD5,0x0C,0x5A,0x08,0x08,0x17,0x00,0x53,0x83,0x40,
+0xEA,0x82,0xD8,0x12,0x00,0x05,0x80,0x00,0xC8,0xFE,0x49,0x00,0x33,0x93,0x49,0x00,
+0x34,0x4E,0x46,0x01,0x00,0x07,0xEA,0x63,0x4C,0x54,0xC0,0x07,0x84,0x21,0xDD,0x4B,
+0xEA,0x34,0x84,0x00,0xEA,0xC8,0x84,0x0E,0xDD,0x40,0xC8,0x13,0xFA,0x02,0xDD,0x40,
+0xC8,0x10,0xFA,0x06,0xDD,0x40,0xC8,0x0D,0x84,0x0A,0xDD,0x40,0xC8,0x0A,0xFA,0x0A,
+0xDD,0x40,0xC8,0x07,0xFA,0x13,0xDD,0x40,0xC8,0x04,0xDD,0x47,0xDD,0x40,0xC0,0x05,
+0x84,0x01,0xF8,0x05,0xC8,0xFE,0xF8,0x06,0x2E,0x07,0xFD,0x0D,0x49,0x00,0x2E,0x98,
+0xC8,0xFC,0x48,0xFF,0xFE,0xF3,0xFC,0x00,0x46,0x61,0x00,0x03,0x58,0x63,0x0A,0x98,
+0x80,0x06,0x84,0x20,0xDD,0x4F,0xDD,0x42,0x50,0x03,0x05,0x10,0x84,0x20,0xDD,0x4F,
+0xDD,0x42,0x50,0x03,0x10,0x10,0x84,0x20,0x44,0x20,0x05,0xF0,0xDD,0x42,0x50,0x03,
+0x16,0x00,0x84,0x20,0xDD,0x4F,0xDD,0x42,0x84,0x00,0x3C,0x0F,0xFF,0x8F,0xFC,0x80,
+0xFC,0x20,0x3F,0xCF,0xFD,0xD8,0xB8,0x00,0x5A,0x00,0x08,0x05,0x84,0xC3,0x5A,0x08,
+0x06,0x03,0x84,0xC1,0xB9,0x19,0x2E,0x27,0xFD,0x2F,0x2E,0x07,0xFD,0x40,0x88,0x02,
+0xE2,0x20,0x4E,0xF2,0x00,0x5B,0xB9,0x19,0xC9,0x05,0xEB,0x4E,0xEA,0x62,0xDD,0x4F,
+0xDD,0x42,0xB9,0x19,0x2E,0x07,0xFD,0x2F,0x84,0x80,0xE2,0x20,0xE8,0x2D,0x2E,0x37,
+0xFF,0xA9,0x2E,0x07,0xFF,0xDF,0x44,0x10,0x00,0xD8,0x88,0x60,0xFE,0x74,0xBD,0x1A,
+0x94,0xDA,0x46,0x21,0x00,0x05,0x58,0x21,0x00,0x98,0x40,0x12,0x84,0x20,0x84,0x80,
+0x45,0x00,0x6D,0x60,0x45,0x10,0xDA,0xC0,0xD1,0x17,0x02,0x01,0x6F,0xF0,0xA5,0xE8,
+0x8A,0x07,0x96,0x01,0x97,0xC3,0x42,0x73,0x80,0x03,0xE0,0xE3,0xE8,0x04,0xA5,0xD0,
+0x88,0x07,0xAC,0x10,0x2A,0x01,0x00,0x01,0x88,0x10,0x96,0x01,0xE3,0xA0,0xE8,0x02,
+0x84,0x81,0x8C,0xA2,0xD5,0xEA,0xB8,0x19,0x8C,0x01,0xB8,0x99,0x5A,0x48,0x01,0x1E,
+0x44,0x20,0x00,0xD8,0xFE,0xB4,0xBD,0x1A,0x46,0x31,0x00,0x05,0x58,0x31,0x80,0x98,
+0x40,0x22,0x88,0x20,0x84,0x80,0xD2,0x0F,0xA5,0xE8,0xB8,0x19,0x22,0x11,0x80,0x00,
+0x96,0x03,0x40,0x00,0x80,0x16,0x88,0x07,0x96,0x01,0x1A,0x02,0x80,0x01,0x1A,0x41,
+0x80,0x01,0xD5,0xF2,0x84,0x00,0xB8,0x99,0xB9,0x19,0x2E,0x47,0xFD,0x2F,0x2E,0x07,
+0xFD,0x40,0x88,0x04,0xE2,0x20,0xE9,0x3A,0x84,0x40,0xBA,0x99,0xBD,0x1A,0x44,0x00,
+0x00,0xD8,0x42,0x13,0x00,0x24,0x46,0x31,0x00,0x05,0x58,0x31,0x80,0x98,0x40,0x12,
+0x84,0x20,0xD1,0x0D,0x22,0x01,0x80,0x00,0xA5,0xA8,0x40,0x00,0x10,0x16,0x88,0x06,
+0x96,0x01,0x1A,0x02,0x80,0x01,0x1A,0x21,0x80,0x01,0xD5,0xF4,0xB8,0x00,0x5A,0x08,
+0x02,0x1E,0x2E,0x07,0xFD,0x22,0x2E,0x10,0x00,0x70,0xE2,0x20,0xE8,0x05,0x84,0x01,
+0xB8,0x90,0x84,0x00,0xD5,0x11,0x2E,0x2F,0xFF,0xA3,0x4E,0x24,0x00,0x10,0x3C,0x33,
+0xFE,0xE2,0xBA,0x26,0xE2,0x62,0xE9,0x0A,0x3C,0x33,0xFE,0xE7,0xBA,0x25,0xE2,0x62,
+0xE9,0x05,0xC1,0x04,0x8C,0x01,0x3E,0x07,0xFD,0x22,0xFC,0xA0,0xFC,0x20,0x3C,0x1D,
+0xFF,0x90,0xEA,0x40,0x2E,0x37,0xFD,0x64,0xE2,0x03,0xE8,0x48,0xEB,0x27,0x5A,0x08,
+0x01,0x2C,0x2E,0x57,0xFD,0x48,0x9E,0x19,0xD8,0x27,0x2E,0x70,0x00,0x0A,0x84,0xA0,
+0x47,0x01,0x00,0x02,0x59,0x08,0x01,0x44,0x44,0x60,0x05,0x10,0x50,0x22,0x8F,0x34,
+0x99,0x0D,0x88,0x50,0xA4,0x20,0x03,0x11,0x00,0x00,0xE3,0xA0,0xE8,0x04,0xA4,0x20,
+0xA4,0x90,0xD5,0x03,0xA4,0x10,0xA4,0xA0,0x8A,0x02,0xE0,0xE0,0xE8,0x05,0x84,0x00,
+0x3E,0x07,0xFD,0x30,0xD5,0x03,0x8C,0xA2,0xDE,0xEA,0xEB,0x27,0x5A,0x08,0x01,0x05,
+0x3E,0x37,0xFD,0x45,0xD5,0x1D,0xEB,0x27,0xC8,0x1B,0xDD,0x4B,0x8E,0x02,0xE6,0x07,
+0xE8,0x17,0x3E,0xFF,0x7A,0xC8,0x38,0x07,0x80,0x00,0xEA,0xAF,0x4A,0x00,0x3C,0x00,
+0x08,0x1E,0x1E,0x1E,0x0C,0x08,0x0C,0x00,0xEA,0xB2,0xD5,0x02,0xEA,0x5A,0x46,0x21,
+0x00,0x03,0x58,0x21,0x00,0x78,0xDD,0x48,0xD5,0x03,0x49,0xFF,0xFF,0x03,0xFC,0xA0,
+0x92,0x00,0xFC,0x00,0xEB,0x38,0xC0,0x1C,0x2E,0x07,0xFD,0x4D,0x2E,0x17,0xFF,0xDE,
+0xE2,0x01,0xE9,0x10,0x84,0x00,0x3E,0x07,0xFD,0x3B,0x84,0x20,0x3C,0x1F,0xFF,0x8F,
+0x2E,0x07,0xFD,0x47,0x3E,0x07,0xFD,0x2F,0xEB,0x4E,0xEA,0x62,0xDD,0x4F,0xDD,0x42,
+0xD5,0x07,0x3C,0x1D,0xFF,0x87,0xC9,0x04,0x8C,0x01,0x3E,0x07,0xFD,0x4D,0xFC,0x80,
+0xFC,0x00,0x3F,0xCF,0xFD,0xD8,0x2E,0x17,0xFD,0x48,0x2E,0x07,0xFD,0x45,0xE2,0x20,
+0xE9,0x05,0x84,0x01,0xEA,0xAA,0x84,0x0A,0xD5,0x03,0x84,0x00,0xEA,0xAA,0x3E,0x07,
+0xFD,0x40,0x2E,0x07,0xFD,0x34,0xC0,0x2A,0x84,0x01,0xEB,0x25,0x84,0x01,0x3E,0x07,
+0xFD,0x30,0x84,0x02,0xEA,0xF9,0xBE,0x00,0x5A,0x68,0x02,0x18,0x2E,0x07,0xFD,0x5F,
+0x5A,0x08,0x01,0x14,0xEA,0x2B,0xE6,0x01,0x3E,0xF7,0xFD,0x79,0x80,0x06,0x80,0x26,
+0xEA,0x34,0x3E,0x67,0xFD,0x5F,0xEA,0x2B,0xC0,0x04,0xEB,0x64,0xDD,0x5D,0xD5,0x03,
+0xEB,0x64,0xEA,0xB6,0xB8,0x9A,0xD5,0x2B,0x84,0x00,0x3E,0x07,0xFD,0x59,0x2E,0x07,
+0xFD,0x43,0x8C,0x01,0x3E,0x07,0xFD,0x43,0xD5,0x08,0x49,0xFF,0xFF,0x51,0x2E,0x07,
+0xFD,0x59,0x8C,0x01,0x3E,0x07,0xFD,0x59,0xEB,0x81,0x02,0x50,0x03,0x01,0xEB,0x04,
+0xD0,0x09,0x2E,0x0F,0xFF,0xA2,0x4E,0x04,0x00,0x06,0xB8,0x00,0x8E,0x07,0xE6,0x02,
+0xE8,0x06,0xEA,0x40,0x8C,0x01,0x96,0x00,0xEA,0xC3,0xD5,0x09,0xEB,0x81,0x00,0x00,
+0x06,0x01,0xEB,0x5A,0x8C,0x01,0x96,0x00,0x10,0x00,0x86,0x01,0xFC,0x80,0xFC,0x20,
+0x3C,0x7D,0xFF,0x90,0x84,0xA0,0xEB,0x19,0xEB,0x24,0x84,0x63,0xDD,0x4F,0x98,0x7D,
+0x50,0x02,0x8F,0x34,0xA5,0x08,0x88,0x06,0xA4,0x00,0x42,0x02,0x0C,0x73,0x8C,0xA2,
+0x90,0x02,0x96,0x01,0xAC,0x08,0xDA,0xF4,0x84,0x03,0x3C,0x0F,0xFF,0x86,0xFC,0xA0,
+0xFC,0x00,0x3F,0xCF,0xFD,0xD8,0xB8,0x00,0x5A,0x00,0x08,0x04,0x5A,0x08,0x06,0x05,
+0xEB,0x4E,0xEA,0xA4,0xD5,0x04,0xB8,0x11,0xC8,0x04,0xEA,0x96,0xE6,0x01,0xD5,0x02,
+0x85,0xE0,0x3E,0xF7,0xFD,0x50,0xEA,0x6A,0xEA,0xA3,0xC0,0x0F,0x2E,0x07,0xFD,0x50,
+0xC0,0x0C,0xB8,0x10,0x5A,0x00,0x02,0x0A,0x49,0xFF,0xFE,0x4C,0x84,0x00,0x3E,0x07,
+0xFD,0x2D,0x84,0x00,0xEA,0x64,0xD5,0x10,0x84,0xC0,0xBE,0x99,0x80,0x26,0xEB,0x4E,
+0xEA,0x62,0xDD,0x4F,0xDD,0x42,0xB8,0x10,0x5A,0x08,0x02,0x05,0x49,0xFF,0xFF,0xB9,
+0xD5,0x03,0x3E,0x67,0xFD,0x22,0xFC,0x80,0x2E,0x07,0xFD,0x34,0xDD,0x9E,0xFC,0x60,
+0x3D,0x3C,0x00,0x49,0x2E,0x90,0x00,0x8A,0x2E,0x47,0xFF,0xA5,0x92,0x84,0x3C,0x2C,
+0x00,0x48,0x4E,0x42,0x00,0xF1,0x3F,0x18,0x02,0x5C,0x38,0x38,0x80,0x00,0x5A,0x38,
+0x01,0x13,0xEA,0xC6,0xFF,0x04,0x44,0x30,0xFF,0xFF,0x99,0xCC,0xA1,0xBE,0x4C,0x61,
+0xC0,0x0B,0xA1,0x7B,0xDE,0x08,0x38,0x30,0x90,0x02,0x4C,0x32,0xC0,0x05,0x84,0x60,
+0x38,0x38,0x80,0x08,0xEA,0xC6,0x42,0x30,0x10,0x24,0xEA,0x89,0x99,0xCB,0xB4,0xA7,
+0x8E,0x41,0x8F,0xE1,0xDC,0x54,0x50,0x41,0x80,0x0C,0x88,0x81,0xB5,0x84,0x4D,0x02,
+0x80,0x4F,0x51,0x21,0x80,0x18,0x89,0xC1,0xB4,0xD2,0x4C,0x62,0x80,0x49,0xA0,0xE1,
+0x40,0x18,0x04,0x08,0xE0,0x26,0x04,0x09,0x00,0x01,0x95,0xD9,0xE9,0x0B,0xE0,0xE0,
+0xE8,0x19,0x40,0x18,0x18,0x01,0xFE,0x5C,0x9A,0x83,0x40,0x10,0x88,0x36,0x88,0x30,
+0xD5,0x02,0x84,0x20,0xE0,0xE0,0xB6,0x24,0xE8,0x04,0x84,0x00,0xA8,0x21,0xF8,0x2D,
+0x9A,0x18,0x42,0x18,0x00,0x24,0x40,0x53,0x40,0x01,0x40,0x00,0x94,0x16,0x99,0x58,
+0xD5,0x23,0x99,0x72,0xE0,0xA1,0x41,0x10,0x4C,0x00,0xE9,0x0F,0xE1,0xA7,0x4E,0xF2,
+0x00,0x9B,0x40,0x58,0x18,0x01,0x40,0x11,0xCC,0x01,0xFE,0x6C,0x9B,0x43,0x40,0x10,
+0x94,0x36,0x88,0x30,0xB6,0x24,0xD5,0x02,0xB6,0x44,0xE1,0xA7,0xE8,0x04,0x15,0x32,
+0x00,0x01,0xF8,0x0B,0x40,0x58,0x08,0x01,0x9A,0x18,0xFE,0x2C,0x40,0x53,0x40,0x01,
+0x40,0x50,0x14,0xB6,0x88,0xA3,0xA9,0x61,0x48,0x00,0x00,0x7E,0x46,0x41,0x00,0x01,
+0x58,0x42,0x0D,0x80,0x40,0x42,0x00,0x20,0xA7,0x21,0x5A,0x40,0xFE,0x0D,0x2E,0x47,
+0xFD,0x67,0xCC,0x71,0xEA,0x89,0xD4,0x6F,0xA1,0xBB,0x4C,0x62,0x00,0x6D,0xA1,0xBE,
+0x4C,0x62,0x40,0x6A,0x8C,0x6C,0x38,0xB8,0x80,0x00,0x88,0x61,0xB5,0x83,0x05,0x21,
+0x80,0x01,0xA0,0x79,0x4E,0xB3,0x00,0x60,0x40,0x68,0x04,0x08,0x40,0x33,0x24,0x01,
+0xE0,0x65,0x40,0x39,0x04,0x08,0xE9,0x10,0x40,0x41,0xA4,0x01,0xE0,0x81,0xE8,0x1B,
+0x40,0x28,0x14,0x01,0x42,0x29,0x08,0x24,0x40,0x40,0xC8,0x01,0x40,0x21,0x10,0x56,
+0x88,0x50,0xA8,0xBE,0xD5,0x03,0x14,0xB3,0x80,0x06,0x8A,0x69,0xE0,0x61,0xE9,0x3C,
+0x40,0x39,0x04,0x01,0x42,0x38,0x0C,0x24,0x8A,0xB0,0x40,0x21,0x94,0x56,0x40,0x59,
+0x08,0x00,0xD5,0x30,0x99,0x2A,0x8A,0x89,0xE0,0x86,0x40,0xA0,0xCC,0x00,0xE9,0x06,
+0x40,0x45,0x24,0x01,0xE0,0x83,0xE9,0x04,0xD5,0x2E,0xA8,0xBE,0xD5,0x11,0x40,0x68,
+0x14,0x01,0x40,0x49,0x4C,0x01,0xFF,0x34,0x40,0x60,0xC8,0x01,0x40,0x42,0x18,0x96,
+0x88,0x90,0x4E,0x45,0x00,0x04,0xA9,0x3E,0xD5,0x03,0x14,0xB3,0x80,0x06,0x40,0x95,
+0x24,0x01,0xE1,0x23,0xE8,0x04,0x15,0x33,0x80,0x07,0xD5,0x12,0x40,0x38,0x08,0x01,
+0x40,0x29,0x04,0x01,0xFE,0x9C,0x8A,0xB0,0x40,0x51,0x14,0xB6,0x88,0xB2,0x4E,0x55,
+0x00,0x04,0xA9,0x7F,0xD5,0x05,0x50,0x13,0x80,0x18,0x84,0x40,0xA8,0x89,0x84,0x21,
+0x38,0x18,0x80,0x08,0xFC,0xE0,0x3E,0x18,0x02,0x5C,0x38,0x00,0x80,0x00,0xDD,0x9E,
+0xFC,0x20,0x3F,0xCF,0xFE,0x00,0x3E,0x68,0x01,0x40,0x84,0x1F,0x84,0xE0,0x12,0x03,
+0x00,0x44,0x12,0x03,0x00,0x45,0x84,0x20,0x50,0x03,0x00,0x60,0x84,0x4C,0x12,0x73,
+0x00,0x42,0x12,0x73,0x00,0x43,0xDD,0x42,0x80,0x06,0x44,0x10,0xFF,0xFF,0x44,0x20,
+0x00,0x60,0xDD,0x42,0x50,0x03,0x00,0x78,0x84,0x20,0x84,0x4C,0xDD,0x42,0x46,0x11,
+0x41,0x41,0x50,0x03,0x00,0x6C,0x50,0x10,0x84,0x14,0x84,0x4C,0xDD,0x42,0x46,0x01,
+0x00,0x07,0x58,0x00,0x02,0x66,0xA6,0x40,0xA6,0x81,0xEA,0x31,0xB9,0x81,0xA6,0x42,
+0xA6,0x83,0xEA,0x31,0xB9,0x8E,0xA6,0x45,0xA6,0x86,0xEA,0x31,0xB9,0x80,0xA6,0x47,
+0xEB,0x0E,0xEA,0x31,0xB9,0x94,0x00,0x10,0x00,0x0A,0x00,0x20,0x00,0x0B,0xEA,0x31,
+0xB9,0x96,0x00,0x10,0x00,0x0C,0x00,0x20,0x00,0x0D,0xEA,0x31,0xB9,0x97,0x00,0x10,
+0x00,0x0F,0x00,0x20,0x00,0x10,0xEA,0x31,0xB9,0x8C,0x00,0x10,0x00,0x11,0x00,0x00,
+0x00,0x12,0x40,0x00,0x05,0x04,0xB8,0x85,0x3C,0x7B,0xFE,0xDA,0x84,0x20,0x3E,0x08,
+0x02,0xA4,0xFA,0x48,0xDD,0x42,0xFC,0xA0,0xFC,0x20,0x46,0x71,0x00,0x07,0x58,0x73,
+0x83,0x48,0x82,0x00,0x46,0x51,0x00,0x01,0x58,0x52,0x8F,0xF4,0x84,0x00,0x47,0x11,
+0x00,0x01,0x59,0x18,0x8D,0x68,0x00,0x68,0x00,0x00,0x38,0x43,0x98,0x00,0x5A,0x40,
+0xFF,0x18,0x41,0x23,0x98,0x00,0x41,0x32,0x10,0x09,0x01,0x29,0x00,0x01,0x4C,0x29,
+0xC0,0x0C,0x97,0x1F,0xE2,0x64,0xE9,0x08,0x38,0x48,0x84,0x00,0x38,0x42,0x92,0x02,
+0xE2,0x92,0xE9,0x02,0x84,0x01,0x8C,0xC2,0x10,0x68,0x00,0x00,0xD5,0xE5,0xFC,0xA0,
+0x46,0x31,0x00,0x07,0x58,0x31,0x83,0x48,0xA6,0x80,0x38,0x41,0x88,0x00,0x8C,0x41,
+0x5A,0x48,0xFF,0x04,0xAE,0x80,0xDD,0x9E,0xC9,0xFE,0xAE,0x80,0xD5,0xF6,0x3C,0x3D,
+0xFF,0x87,0x84,0x28,0x3E,0x08,0x01,0xFC,0xEA,0x89,0xEB,0x0E,0xC2,0x08,0xCB,0x04,
+0x10,0x30,0x00,0x08,0xD5,0x04,0x8E,0x41,0x10,0x20,0x00,0x08,0xEB,0x0E,0xCA,0x03,
+0xB6,0x80,0xA9,0x01,0x8E,0x21,0x96,0x48,0x8C,0x0C,0xC9,0xF0,0xDD,0x9E,0xFC,0x01,
+0x84,0x6C,0xEA,0x38,0x80,0x5F,0x84,0x00,0x3E,0x48,0x01,0xFC,0x80,0x24,0x42,0x10,
+0x0C,0x73,0x00,0x50,0x80,0x08,0xCD,0x0A,0x46,0x01,0x00,0x07,0x3B,0x01,0x44,0x00,
+0x00,0x00,0x02,0x7A,0xEA,0xEA,0xEA,0xFB,0xD5,0x04,0x8C,0x01,0x5A,0x08,0x08,0xF0,
+0xFC,0x81,0xFC,0x21,0xEA,0x38,0x80,0x80,0x46,0x01,0x00,0x07,0x00,0x60,0x02,0x7D,
+0x46,0x01,0x00,0x07,0x00,0x70,0x02,0x7E,0x46,0x01,0x00,0x07,0x80,0xA1,0x01,0x00,
+0x02,0x7A,0x3E,0x18,0x01,0xFC,0x84,0x68,0x84,0x00,0x00,0x20,0x80,0x08,0xC2,0x14,
+0xB4,0x41,0xE2,0x82,0xE8,0x03,0x8A,0x44,0xD5,0x02,0x9A,0xA2,0xE2,0x46,0xE8,0x0C,
+0xA0,0x89,0xE2,0xA2,0xE8,0x03,0x8A,0x45,0xD5,0x02,0x9A,0xAA,0xE2,0x47,0xE8,0x04,
+0x11,0x00,0x80,0x08,0x84,0x01,0x8E,0x61,0x96,0xD8,0x8C,0x2C,0xCB,0xE7,0xFC,0xA1,
+0xFC,0x01,0xEA,0x38,0x80,0xC0,0x80,0x01,0x2E,0x17,0xFD,0x6D,0xC1,0x04,0x84,0x21,
+0x84,0xA2,0xD5,0x03,0x84,0x22,0x84,0xA1,0x3E,0x48,0x01,0x40,0x38,0x32,0x0B,0x02,
+0xE2,0x66,0xE8,0x03,0x9A,0xF3,0xD5,0x02,0x8A,0x66,0x46,0x61,0x00,0x07,0x00,0x63,
+0x02,0x7F,0xFF,0x74,0xE2,0xA3,0xE9,0x0D,0x40,0x32,0x08,0x60,0xA0,0x99,0xE2,0x40,
+0xE8,0x03,0x9A,0x82,0xD5,0x02,0x8A,0x40,0xFE,0x74,0x40,0x00,0x88,0x06,0xD5,0x02,
+0x84,0x01,0xFC,0x81,0xFC,0x20,0x84,0x00,0x3C,0x0B,0xFE,0xD4,0x3C,0x0B,0xFE,0xE0,
+0x3C,0x0B,0xFE,0xDE,0x46,0x11,0x00,0x07,0x04,0x70,0x83,0xCF,0x46,0x11,0x00,0x07,
+0x00,0x60,0x82,0x6A,0x46,0x11,0x00,0x07,0x00,0x50,0x82,0x6F,0x46,0x11,0x00,0x07,
+0x00,0x40,0x82,0x74,0x46,0x11,0x00,0x07,0x00,0x30,0x82,0x79,0x46,0x11,0x00,0x07,
+0x00,0x20,0x82,0x88,0x46,0x1A,0x11,0xAA,0x50,0x10,0x81,0x1A,0x4C,0x70,0x80,0x0C,
+0x46,0x11,0x00,0x07,0x04,0x70,0x83,0xCF,0x46,0x1A,0x33,0xAA,0x50,0x10,0x83,0x3A,
+0x4C,0x70,0xC0,0x26,0x84,0x00,0x3E,0x07,0xFD,0x6D,0x44,0x00,0x00,0x96,0x3C,0x0B,
+0xFE,0xDD,0x44,0x00,0x00,0x32,0x3C,0x0B,0xFE,0xDF,0x3C,0x6B,0xFE,0xD8,0x3C,0x5B,
+0xFE,0xDC,0x3C,0x4B,0xFE,0xD3,0x3C,0x3B,0xFE,0xDB,0x46,0x01,0x00,0x07,0x00,0x00,
+0x02,0x82,0x3C,0x0B,0xFE,0xD5,0x46,0x01,0x00,0x07,0x00,0x00,0x02,0x83,0x94,0x01,
+0x3C,0x0B,0xFE,0xD7,0x3C,0x2B,0xFE,0xD9,0x84,0x00,0xD5,0x21,0x84,0x21,0x3E,0x17,
+0xFD,0x6D,0x44,0x10,0x00,0x32,0x3C,0x1B,0xFE,0xDD,0x3C,0x1B,0xFE,0xDF,0x3C,0x6B,
+0xFE,0xD8,0x3C,0x5B,0xFE,0xDC,0x3C,0x4B,0xFE,0xD3,0x3C,0x3B,0xFE,0xDB,0x46,0x11,
+0x00,0x07,0x00,0x10,0x82,0x84,0x3C,0x1B,0xFE,0xD5,0x46,0x11,0x00,0x07,0x00,0x10,
+0x82,0x85,0x94,0x49,0x3C,0x1B,0xFE,0xD7,0x3C,0x2B,0xFE,0xD9,0x3C,0x0B,0xFE,0xD6,
+0xFC,0xA0,0xFC,0x01,0x3F,0xC8,0x01,0x20,0x46,0x21,0x00,0x07,0x04,0x51,0x03,0xCF,
+0x46,0x3A,0x11,0xAA,0xEA,0x38,0x50,0x31,0x81,0x1A,0x80,0x20,0x3C,0x23,0xFE,0xD7,
+0xF0,0x01,0xDB,0x03,0xE2,0x02,0xD5,0x0D,0x46,0x31,0x00,0x07,0x04,0x51,0x83,0xCF,
+0x46,0x3A,0x33,0xAA,0x50,0x31,0x83,0x3A,0xDB,0x0A,0xBB,0x01,0x9A,0x9A,0xE2,0x40,
+0xE8,0x15,0x3C,0x03,0xFE,0xD5,0xE2,0x20,0xE8,0x0A,0xD5,0x0E,0xE2,0x02,0xE9,0x05,
+0xBB,0x01,0x9A,0x9A,0xE2,0x40,0xE8,0x0A,0x3C,0x03,0xFE,0xD5,0xBA,0x00,0x9A,0x10,
+0x40,0x00,0x04,0x06,0xD5,0x04,0x84,0x01,0xD5,0x02,0x84,0x00,0xFC,0x81,0xFC,0x21,
+0x80,0xE0,0x3A,0x1F,0x88,0x20,0x3A,0x0F,0x84,0x00,0x80,0x47,0x80,0xDF,0x49,0xFF,
+0xFF,0xC2,0x5A,0x08,0x01,0x0A,0x3C,0x13,0xFE,0xDA,0x40,0x20,0x1C,0x0C,0xFE,0x57,
+0x3C,0x1B,0xFE,0xDA,0xD5,0x02,0x84,0x00,0xB4,0x5F,0x3E,0x18,0x02,0x8C,0x38,0x20,
+0x9D,0x09,0xA0,0xB1,0x3E,0x18,0x02,0xBC,0x38,0x20,0x9D,0x09,0xFC,0xA1,0xEB,0x78,
+0xEA,0x71,0x38,0x00,0x80,0x00,0x3E,0x18,0x01,0xCC,0x40,0x10,0x80,0x40,0xA6,0x0A,
+0xA6,0x4B,0x8A,0x01,0x96,0x01,0xDD,0x9E,0xEB,0x78,0xEA,0x71,0x38,0x20,0x80,0x00,
+0x3E,0x18,0x01,0xCC,0x40,0x00,0x88,0x40,0xA6,0x01,0x38,0x10,0x8A,0x00,0x8A,0x01,
+0x96,0x01,0xDD,0x9E,0xEB,0x78,0xEA,0x71,0x38,0x30,0x80,0x00,0x46,0x01,0x00,0x01,
+0x58,0x00,0x0F,0xDC,0x40,0x10,0x0C,0x20,0xA6,0x49,0x80,0x80,0xE6,0x22,0xE8,0x18,
+0x38,0x00,0x0D,0x00,0xE6,0x02,0xE8,0x14,0xEB,0x54,0x22,0xF0,0x05,0x4C,0xF8,0x08,
+0xEB,0x54,0x22,0xF0,0x05,0x70,0xF8,0x04,0xEB,0x54,0x22,0xF0,0x05,0x4D,0xDD,0x5F,
+0x4E,0xF3,0x00,0x79,0x83,0xFF,0xEB,0x54,0x22,0xF0,0x05,0x71,0xD5,0x3D,0xEA,0x3C,
+0x9E,0x82,0xE0,0x22,0x4E,0xF3,0x00,0x6D,0x38,0x52,0x0D,0x00,0xE6,0xA2,0xE8,0x15,
+0x46,0x11,0x00,0x02,0xEB,0x17,0x40,0x20,0x80,0x20,0x22,0xF1,0x0C,0xA9,0xDD,0x5F,
+0xE9,0x61,0x22,0xF1,0x0C,0xCD,0xDD,0x5F,0xE9,0x5D,0x22,0xF1,0x0C,0xA8,0xDD,0x5F,
+0xE9,0x59,0x22,0xF1,0x0C,0xCC,0xD5,0x20,0xE6,0x22,0xE8,0x20,0xEA,0xB0,0x38,0x12,
+0x0D,0x00,0x9F,0x42,0xE0,0x25,0xE9,0x4E,0x9E,0x41,0xEB,0x64,0x58,0x00,0x01,0x44,
+0x44,0x20,0x00,0x48,0x80,0x60,0x42,0x30,0x88,0x73,0x22,0xF1,0x8C,0xAA,0xDD,0x5F,
+0xE9,0x41,0x42,0x02,0x88,0x73,0xF8,0x23,0xE9,0x3D,0x22,0xF1,0x8C,0xAB,0xDD,0x5F,
+0xE9,0x39,0x22,0xF0,0x0C,0xAB,0xF8,0x2C,0xDD,0x9E,0xFC,0x00,0x2E,0x10,0x01,0x29,
+0x9F,0x8A,0xE0,0xA6,0xE9,0x2B,0x8E,0x21,0xFA,0x74,0xFE,0x5C,0x8E,0x01,0x46,0x41,
+0x00,0x02,0x58,0x42,0x01,0x44,0x99,0x48,0x40,0x52,0x14,0x20,0x22,0xF2,0x8C,0xAA,
+0xDD,0x5F,0xE9,0x1C,0xFE,0xF4,0x88,0x03,0x40,0x02,0x00,0x20,0x22,0xF0,0x0C,0xAA,
+0xDD,0x5F,0x83,0xFF,0xE9,0x13,0x88,0x22,0x40,0x12,0x04,0x20,0x22,0xF0,0x8C,0xAA,
+0xDD,0x5F,0xE9,0x0C,0x88,0x43,0x40,0x22,0x08,0x20,0x22,0xF1,0x0C,0xAA,0x44,0x00,
+0x00,0x96,0x40,0x00,0x3C,0x07,0x83,0xFF,0xD5,0x07,0x84,0x00,0xD5,0x05,0xE6,0x22,
+0xE9,0xAE,0x84,0x00,0xDD,0x9E,0xFC,0x80,0xFC,0x62,0x3F,0xC8,0x01,0x20,0xEA,0x38,
+0x81,0x20,0x80,0x02,0x80,0xE2,0x81,0x41,0x49,0xFF,0xFF,0x43,0x54,0xB0,0x00,0xFF,
+0x80,0xC0,0x80,0x07,0x49,0xFF,0xFF,0x4A,0x54,0xC0,0x00,0xFF,0x80,0x80,0x46,0xE1,
+0x00,0x01,0x58,0xE7,0x0D,0x68,0x84,0x00,0x10,0x0F,0x80,0x0F,0xEA,0xCA,0x46,0xD1,
+0x00,0x01,0x58,0xD6,0x8F,0xF4,0xEB,0x37,0x42,0xF6,0x2C,0x24,0xE2,0x0F,0xE8,0x07,
+0x97,0xB0,0x97,0x20,0xFF,0x34,0x9B,0xA0,0x97,0xB1,0xD5,0x03,0x44,0x60,0x00,0xFF,
+0x46,0x01,0x00,0x07,0x00,0x10,0x02,0x7C,0xE3,0x41,0xE9,0x06,0xB8,0x01,0x85,0x00,
+0x8A,0x01,0xE2,0x0A,0xE8,0x09,0xEA,0x39,0x80,0x27,0x80,0x4B,0x80,0x6C,0xEA,0x86,
+0x85,0x00,0x40,0x84,0x00,0x06,0xEA,0x39,0x80,0x28,0xEA,0xBF,0x46,0x01,0x00,0x07,
+0x00,0x00,0x02,0x7C,0xE3,0x40,0xE9,0x05,0xB9,0x01,0x8A,0x20,0xE2,0x2A,0xE8,0x19,
+0xE3,0x20,0xE9,0x05,0xB9,0x00,0x9A,0x08,0xE2,0x09,0xE8,0x13,0xEA,0xCA,0xEB,0x37,
+0xE2,0x06,0xE8,0x0F,0x9A,0x30,0xE6,0x03,0xE9,0x0C,0x80,0x07,0x49,0xFF,0xFF,0x0C,
+0xC0,0x08,0xEA,0x39,0x80,0x27,0x80,0x4B,0x80,0x6C,0xEA,0x86,0xC0,0x02,0x85,0x01,
+0xEA,0x39,0x80,0x28,0xEA,0xBF,0x2E,0x07,0xFD,0x6D,0xC8,0x33,0x46,0x01,0x00,0x07,
+0x00,0x10,0x02,0x7C,0xE3,0x21,0xE9,0x05,0xB8,0x00,0x8A,0x01,0xE2,0x09,0xE8,0x08,
+0xEA,0x39,0x80,0x27,0x80,0x4C,0x80,0x6B,0xEA,0x86,0xC0,0x02,0x85,0x01,0xEA,0x39,
+0x80,0x28,0xEA,0xBF,0x46,0x01,0x00,0x07,0x00,0x00,0x02,0x7C,0xE3,0x40,0xE9,0x05,
+0xB9,0x01,0x8A,0x20,0xE2,0x2A,0xE8,0x15,0xE3,0x20,0xE9,0x05,0xB9,0x00,0x9A,0x08,
+0xE2,0x09,0xE8,0x0F,0xEA,0xCA,0xEB,0x37,0xE2,0x06,0xE8,0x0B,0x8A,0xC0,0xE6,0xC4,
+0xE9,0x08,0xEA,0x39,0x80,0x27,0x80,0x4C,0x80,0x6B,0xEA,0x86,0xC0,0x02,0x85,0x01,
+0x80,0x08,0xFC,0xE2,0x40,0x00,0x04,0x0E,0x96,0x04,0xDD,0x9E,0x84,0x41,0x40,0x11,
+0x04,0x0C,0xA4,0x80,0xFE,0x57,0xAC,0x40,0xDD,0x9E,0x44,0x2E,0xFF,0xFF,0x40,0x11,
+0x04,0x0C,0xA4,0x80,0x40,0x11,0x06,0x1E,0xAC,0x40,0xDD,0x9E,0xFC,0x20,0x3E,0x78,
+0x01,0x40,0x80,0xC0,0x84,0x20,0x98,0x38,0x10,0x10,0x00,0x6C,0x50,0x03,0x80,0x84,
+0x80,0x26,0xF8,0x7E,0x50,0x03,0x80,0x86,0x80,0x26,0xF8,0x7A,0x50,0x03,0x80,0x8A,
+0x80,0x26,0xF8,0x76,0x50,0x03,0x80,0x88,0x80,0x26,0xF8,0x72,0xFC,0xA0,0xFC,0x41,
+0xEA,0x38,0x84,0x01,0x3C,0x10,0x00,0xE3,0x40,0x00,0x08,0x0C,0x96,0x03,0x80,0xC2,
+0xFE,0x47,0x3C,0x18,0x00,0xE3,0x3C,0x10,0x00,0xE2,0x3E,0x98,0x01,0x40,0xFE,0x0F,
+0x3C,0x08,0x00,0xE2,0x40,0x04,0x98,0x00,0x84,0x3F,0xEA,0x2F,0x50,0x04,0x80,0x8A,
+0x80,0x26,0x80,0xE3,0xF8,0x55,0x50,0x04,0x80,0x88,0x80,0x26,0xF8,0x51,0xC7,0x07,
+0x40,0x64,0x98,0x60,0x3B,0x0F,0xC4,0x00,0x3B,0x03,0x44,0x20,0xFC,0xC1,0xFC,0x62,
+0xB6,0x1F,0x50,0x9F,0x80,0x08,0x3A,0x14,0x88,0x20,0xEA,0xDB,0x3C,0x83,0xFE,0xDA,
+0x46,0x01,0x00,0x07,0x00,0xA0,0x02,0x7C,0xEB,0x3D,0x84,0xC0,0x40,0xC0,0x28,0x01,
+0xEA,0xB8,0x50,0xB1,0x80,0x0C,0x40,0xD0,0x28,0x01,0x80,0xE6,0x4C,0x71,0x00,0x1D,
+0x80,0x08,0x80,0x27,0xF2,0x81,0xF8,0x21,0x04,0xE5,0x80,0x00,0x05,0xC5,0x80,0x01,
+0xF2,0x01,0xC8,0x0D,0xE3,0x4E,0xE8,0x0B,0x40,0xF7,0x30,0x06,0xE8,0x08,0xE3,0x5C,
+0xE8,0x06,0x40,0xFE,0x34,0x06,0xE8,0x03,0x8C,0xC1,0x97,0xB0,0x8C,0xE1,0x97,0xF8,
+0x50,0xB5,0x80,0x30,0xD5,0xE4,0xC6,0x07,0x80,0x08,0xB4,0x3F,0xF8,0x06,0x84,0xC0,
+0x40,0x63,0x00,0x06,0x80,0x08,0xB4,0x3F,0xDD,0x56,0xC0,0x0B,0x3A,0x04,0x84,0x00,
+0xB4,0x5F,0x49,0xFF,0xFD,0x1F,0xC0,0x05,0x3E,0x0F,0xFD,0xB4,0xB4,0x3F,0xEA,0x4E,
+0x80,0x06,0xFC,0xE2,0xFC,0x63,0x3F,0xCF,0xFE,0x00,0xEB,0x45,0x42,0x10,0x98,0x0B,
+0x4E,0x12,0x02,0x43,0x46,0x11,0x00,0x07,0x00,0x10,0x82,0x87,0x5A,0x18,0xFF,0x07,
+0x46,0x11,0x00,0x07,0x00,0x10,0x82,0x81,0xD5,0x02,0x96,0x49,0xF1,0x82,0x81,0x80,
+0x84,0xC0,0x49,0xFF,0xFC,0x9E,0x44,0xD0,0xFF,0xFF,0x49,0xFF,0xFD,0x25,0x3E,0x78,
+0x01,0x40,0x50,0xAF,0x80,0x10,0x46,0xE1,0x00,0x01,0x58,0xE7,0x0D,0x08,0xEA,0x2C,
+0xE2,0xC0,0x4E,0xF2,0x01,0xD1,0x81,0x6C,0xDD,0x47,0x42,0xB3,0x00,0x73,0x8D,0x6C,
+0xB5,0x2B,0x4C,0x96,0xC0,0x60,0x54,0x93,0x00,0xFF,0xEB,0x28,0x80,0x29,0xDD,0x56,
+0xC0,0x1F,0xEA,0xA9,0x80,0x29,0xDD,0x56,0xC8,0x1B,0x98,0x3E,0x00,0x10,0x00,0x60,
+0xF2,0x02,0xE2,0x22,0xE8,0x2A,0xE6,0x24,0xE9,0x28,0x46,0x11,0x00,0x07,0x00,0x10,
+0x82,0x86,0x10,0x10,0x00,0x78,0x94,0x33,0x98,0x78,0xEA,0x6B,0x3B,0x05,0xC4,0x20,
+0xEA,0x2A,0x14,0x15,0x80,0x02,0x88,0x0E,0x3B,0x05,0xC4,0x00,0xD5,0x11,0x98,0x7E,
+0x00,0x00,0x80,0x78,0xC0,0x12,0x8E,0x01,0x10,0x00,0x80,0x78,0x94,0x33,0x98,0x78,
+0xEA,0x6B,0xEA,0x2A,0x3B,0x05,0xC4,0x20,0x14,0x15,0x80,0x02,0x88,0x0E,0x3B,0x00,
+0x44,0x20,0xB8,0x11,0x8C,0x01,0xB8,0x91,0x98,0x3E,0x00,0x00,0x00,0x78,0xC8,0x06,
+0xEB,0x44,0x38,0xD3,0x9B,0x0A,0x14,0xD0,0x00,0x01,0x98,0x3E,0x84,0x20,0xEA,0x2F,
+0xFA,0x24,0x10,0x10,0x00,0x6C,0x80,0x29,0x3E,0x08,0x01,0xC8,0xEA,0xF2,0x80,0x29,
+0x3E,0x08,0x01,0xCA,0xEA,0xF2,0x80,0x29,0x3E,0x08,0x01,0xC4,0xEA,0x4E,0x80,0x29,
+0x3E,0x08,0x01,0xC6,0xEA,0x4E,0x3E,0x0F,0xFD,0xB4,0x80,0x29,0xEA,0x4E,0x48,0x00,
+0x01,0x67,0x96,0x30,0x3B,0x05,0xC4,0x00,0xF0,0x81,0x3C,0x00,0x00,0xE4,0xF1,0x01,
+0x3B,0x05,0x44,0x20,0x81,0x11,0xDD,0x56,0xC0,0x1A,0x14,0x9F,0x80,0x04,0x14,0x8F,
+0x80,0x05,0xEA,0x2E,0x49,0xFF,0xFC,0x47,0xC0,0x06,0xEA,0x2E,0xF2,0x01,0x84,0x61,
+0xEA,0xF7,0xD5,0x0D,0xEA,0x2E,0xF2,0x01,0x49,0xFF,0xFE,0x18,0xC0,0x08,0xEA,0x2E,
+0xF2,0x01,0x84,0x61,0xEA,0xF7,0xEA,0x2E,0x49,0xFF,0xFC,0x1B,0x2E,0x17,0xFD,0x6D,
+0x46,0x01,0x00,0x07,0x00,0x00,0x02,0x7C,0xC9,0x07,0xE2,0x09,0xE8,0x10,0xEA,0xDE,
+0x9A,0x08,0xE3,0x20,0xD5,0x07,0xE2,0x08,0xE8,0x0A,0x3C,0x1C,0x00,0x49,0x9A,0x08,
+0xE3,0x00,0xE8,0x05,0x3E,0x08,0x01,0xC8,0xF1,0x01,0xEA,0x4E,0x14,0x9F,0x80,0x04,
+0x14,0x8F,0x80,0x05,0xEA,0x2E,0x49,0xFF,0xFC,0x16,0xEA,0xA9,0xF1,0x01,0xDD,0x56,
+0xC0,0x09,0xEA,0x2E,0xF2,0x01,0x49,0xFF,0xFC,0x3D,0xC0,0x04,0xF0,0x01,0x49,0xFF,
+0xFE,0x97,0x3C,0x00,0x00,0xE5,0xF1,0x01,0xDD,0x56,0xC0,0x44,0x3A,0x15,0x08,0x00,
+0xF0,0x01,0x49,0xFF,0xFD,0x06,0xB9,0x01,0xE2,0x29,0xE8,0x08,0xB9,0x0E,0xE3,0x21,
+0xE8,0x05,0x3C,0x13,0xFE,0xD8,0xE3,0x01,0xE9,0x26,0xB9,0x00,0xE2,0x29,0xE8,0x0B,
+0xB9,0x14,0xE3,0x21,0xE8,0x08,0x3C,0x23,0xFE,0xDC,0x3C,0x1C,0x00,0x49,0x8A,0x22,
+0xE2,0x28,0xE9,0x19,0xB9,0x16,0xE2,0x28,0xE8,0x08,0xB9,0x17,0xE3,0x01,0xE8,0x05,
+0x3C,0x13,0xFE,0xD3,0xE3,0x21,0xE9,0x0F,0xB9,0x0C,0xE2,0x28,0xE8,0x0A,0xB9,0x05,
+0xE3,0x01,0xE8,0x07,0x3C,0x23,0xFE,0xDB,0xEA,0xDE,0x8A,0x22,0xE2,0x29,0xE9,0x03,
+0x96,0x04,0xC0,0x0C,0xEB,0x44,0xB7,0x20,0x14,0x80,0x00,0x01,0xF1,0x01,0x3E,0x08,
+0x01,0xC4,0xEA,0xF2,0x98,0x3E,0x84,0x20,0xEA,0x2F,0x3E,0x08,0x01,0xCA,0xF1,0x01,
+0xEA,0x4E,0xEB,0x28,0xF1,0x01,0xDD,0x56,0xC0,0x33,0xEA,0xA9,0xF1,0x01,0xDD,0x56,
+0xC8,0x2F,0x98,0x7E,0x00,0x00,0x80,0x60,0x5A,0x00,0xFF,0x05,0x8C,0x01,0x10,0x00,
+0x80,0x60,0x38,0x03,0x9B,0x02,0xE2,0x09,0xE8,0x04,0x40,0x04,0x80,0x01,0xD5,0x02,
+0x8A,0x09,0x46,0x11,0x00,0x07,0x00,0x10,0x82,0x80,0xE2,0x20,0xE9,0x16,0xEB,0x44,
+0xA0,0x01,0xE2,0x08,0xE8,0x04,0x40,0x04,0x00,0x01,0xD5,0x02,0x8A,0x08,0xE2,0x20,
+0xE9,0x0C,0x46,0x01,0x00,0x07,0x00,0x00,0x02,0x87,0x5A,0x00,0xFF,0x0A,0x98,0x7E,
+0x00,0x10,0x80,0x60,0xE2,0x01,0xE8,0x04,0xF0,0x01,0x49,0xFF,0xFE,0x19,0xF0,0x01,
+0x3A,0x15,0x08,0x00,0x80,0x6C,0x49,0xFF,0xFE,0x54,0x5A,0x08,0x01,0x06,0xEA,0x2E,
+0xF2,0x01,0x84,0x60,0xEA,0xF7,0xEB,0x28,0xF1,0x01,0xDD,0x56,0x80,0x80,0xC0,0x1A,
+0xF0,0x83,0xEA,0xA9,0xF1,0x01,0xDD,0x56,0xF4,0x03,0xC8,0x14,0x3C,0x13,0xFE,0xD9,
+0xE3,0x01,0xE9,0x0D,0xEA,0xB8,0x8A,0x01,0xE2,0x08,0xE9,0x09,0x3C,0x13,0xFE,0xD6,
+0xE3,0x21,0xE9,0x05,0xEB,0x3D,0x8A,0x01,0xE2,0x09,0xE8,0x04,0x98,0x3E,0x84,0x20,
+0xEA,0x2F,0x98,0x3E,0x00,0x20,0x00,0x6C,0xE6,0x54,0xE8,0x61,0x8C,0x41,0x96,0x90,
+0x46,0x11,0x00,0x07,0x10,0x20,0x00,0x6C,0x00,0x10,0x82,0x87,0x00,0x00,0x00,0x60,
+0x94,0xF3,0xE2,0x01,0xE8,0x3D,0x5A,0x10,0xFF,0x3C,0x38,0x53,0x9B,0x01,0x3D,0x1C,
+0x00,0x48,0x98,0x3B,0x40,0x28,0x94,0x01,0xA4,0x02,0x3D,0x0C,0x00,0x49,0x96,0x91,
+0x40,0x18,0x00,0x01,0xE2,0xA2,0x96,0x49,0xE8,0x08,0xE2,0xA0,0xE8,0x06,0xE2,0xA1,
+0xE8,0x04,0x86,0x40,0x39,0x23,0x9B,0x0A,0xE2,0x45,0xE8,0x08,0xE2,0x40,0xE8,0x06,
+0xE2,0x41,0xE8,0x04,0x8F,0xA1,0x39,0x13,0x9B,0x0A,0xE2,0x05,0xE8,0x0A,0xE2,0x02,
+0xE8,0x08,0xE2,0x01,0xE8,0x06,0x41,0x13,0x8C,0x00,0x86,0x40,0x15,0x28,0x80,0x01,
+0xE2,0x25,0xE8,0x09,0xE2,0x22,0xE8,0x07,0xE2,0x20,0xE8,0x05,0x98,0x3B,0x8F,0x81,
+0x15,0x00,0x00,0x01,0x88,0x67,0xB5,0x23,0x04,0x81,0x80,0x01,0xD5,0x12,0x38,0x03,
+0x9B,0x02,0xFA,0xA4,0x40,0x14,0x80,0x01,0xFE,0x54,0x88,0x67,0x40,0x90,0x95,0x36,
+0x89,0x20,0xA0,0x19,0x40,0x14,0x00,0x01,0xFE,0x54,0x40,0x80,0x95,0x16,0x89,0x00,
+0x98,0x3E,0x84,0x3F,0xB7,0x2B,0x14,0x85,0x80,0x01,0xEA,0x2F,0xC4,0x08,0x84,0x00,
+0x14,0xD5,0x80,0x00,0x14,0xD5,0x80,0x01,0x14,0x05,0x80,0x02,0x8C,0xC1,0x97,0xB1,
+0x48,0xFF,0xFE,0x2F,0x84,0x00,0x49,0xFF,0xFC,0x14,0x46,0x11,0x00,0x07,0x12,0x00,
+0x81,0xDF,0x84,0x00,0x49,0xFF,0xFC,0x1A,0x46,0x11,0x00,0x07,0x12,0x00,0x81,0xE0,
+0x46,0x01,0x00,0x01,0x00,0x10,0x0D,0x68,0x46,0x01,0x00,0x01,0x58,0x00,0x0F,0xF4,
+0x38,0x00,0x06,0x01,0x46,0x11,0x00,0x07,0x12,0x00,0x81,0xE1,0x3C,0x40,0x00,0xE2,
+0x46,0x11,0x00,0x07,0x3C,0x30,0x00,0xE3,0x84,0x00,0x12,0x00,0x81,0xE2,0x46,0x11,
+0x00,0x07,0x12,0x00,0x81,0xE3,0x84,0xAA,0x84,0x25,0x84,0x01,0x46,0x21,0x00,0x07,
+0x02,0x21,0x01,0xE2,0x97,0xA4,0x42,0x20,0x18,0x73,0x46,0x61,0x00,0x07,0x96,0x91,
+0x12,0x23,0x01,0xE2,0x46,0x21,0x00,0x07,0x97,0x9C,0x02,0x21,0x01,0xE3,0x42,0x20,
+0x18,0x73,0x8E,0x21,0xFE,0x2C,0x96,0x91,0x46,0x61,0x00,0x07,0x96,0x49,0x12,0x23,
+0x01,0xE3,0x92,0x81,0x92,0x61,0x96,0x01,0xC9,0xE2,0x2E,0x00,0x01,0xA0,0x46,0x11,
+0x00,0x07,0x12,0x00,0x81,0xE4,0xFC,0xE3,0x3E,0x18,0x01,0x40,0x88,0x01,0x00,0x00,
+0x00,0x78,0xDD,0x9E,0xFC,0x60,0x47,0x01,0x00,0x07,0x59,0x08,0x02,0x4E,0x47,0x21,
+0x00,0x07,0x59,0x29,0x02,0x1E,0x2E,0x90,0x01,0x2B,0x8C,0x04,0x84,0x80,0xEA,0xB5,
+0x46,0x71,0x00,0x01,0x58,0x73,0x8E,0x38,0x81,0x50,0x47,0x11,0x00,0x07,0x59,0x18,
+0x82,0x36,0x81,0x72,0x47,0x31,0x00,0x07,0x59,0x39,0x82,0x06,0x96,0x60,0xE2,0x29,
+0xE8,0x4B,0x04,0x50,0x7F,0xFF,0xD6,0x45,0xB4,0x20,0x4C,0x13,0x00,0x43,0x40,0x23,
+0x90,0x60,0x38,0x53,0x93,0x0A,0xA8,0x51,0xEB,0x45,0xEB,0x34,0xC1,0x1B,0x84,0x41,
+0x38,0x89,0x09,0x01,0xE3,0x05,0xE8,0x04,0x8C,0x41,0x96,0x90,0xD5,0xFA,0x9E,0x51,
+0x96,0x48,0x38,0x39,0x85,0x01,0x38,0xF5,0x85,0x01,0x38,0x19,0x89,0x01,0x8A,0xAF,
+0x8A,0x23,0xFE,0x6C,0x40,0x54,0x3C,0x01,0x40,0x50,0x94,0xB7,0x88,0xA3,0x14,0x50,
+0x7F,0xFF,0xEB,0x45,0xEA,0x8B,0xC1,0x1D,0xB4,0x40,0x84,0x61,0x38,0x18,0x0D,0x01,
+0xE2,0x22,0xE8,0x04,0x8C,0x61,0x96,0xD8,0xD5,0xFA,0x9F,0x59,0x54,0xC2,0x80,0xFF,
+0x38,0xF5,0x31,0x01,0x38,0x58,0xB1,0x01,0x40,0x81,0x3C,0x01,0x38,0x28,0x8D,0x01,
+0x8A,0x2F,0x8A,0x45,0x42,0x24,0x08,0x24,0x40,0x11,0x04,0x37,0x88,0x25,0xB6,0x20,
+0x8C,0x81,0x8C,0x0C,0xD5,0xB4,0xFC,0xE0,0x3C,0x1D,0xFF,0x82,0x5A,0x18,0x02,0x07,
+0x2E,0x37,0xFD,0x54,0x2E,0x47,0xFD,0x6A,0xD5,0x05,0x2E,0x37,0xFD,0x5A,0x2E,0x47,
+0xFD,0x1D,0x2E,0x27,0xFD,0x4B,0xC8,0x12,0x5A,0x28,0x01,0x22,0x2E,0x17,0xFE,0x7C,
+0x8C,0x21,0x96,0x48,0xE2,0x24,0x3E,0x17,0xFE,0x7C,0xE9,0x19,0x3E,0x07,0xFD,0x4B,
+0x3E,0x07,0xFE,0x7C,0x3E,0x07,0xFE,0x7B,0xD5,0x12,0x5A,0x08,0x01,0x11,0xCA,0x0F,
+0x2E,0x17,0xFE,0x7B,0x8C,0x21,0x96,0x48,0xE2,0x23,0x3E,0x17,0xFE,0x7B,0xE9,0x07,
+0x3E,0x07,0xFD,0x4B,0x3E,0x27,0xFE,0x7C,0x3E,0x27,0xFE,0x7B,0x2E,0x57,0xFD,0x4B,
+0xD8,0x06,0x84,0x00,0x3E,0x07,0xFE,0x7C,0x3E,0x07,0xFE,0x7B,0xDD,0x9E,0xFC,0x69,
+0x3F,0xCF,0xFE,0x1C,0x2E,0x77,0xFD,0x4B,0xB8,0x00,0x8E,0xE1,0xE6,0x02,0x5C,0x73,
+0x80,0x01,0x84,0xC0,0xE9,0x04,0x9F,0x81,0xFF,0x84,0x92,0xC1,0x50,0x8F,0x80,0x3C,
+0x80,0x08,0x84,0x20,0x84,0x4C,0xDD,0x42,0x46,0xD1,0x00,0x02,0x58,0xD6,0x80,0xB4,
+0x85,0x60,0x46,0x51,0x00,0x01,0x58,0x52,0x8F,0xDC,0x46,0xA1,0x00,0x02,0x58,0xA5,
+0x00,0x24,0x81,0x2D,0x80,0x6B,0x81,0x85,0x85,0xDF,0x47,0x31,0x00,0x01,0x59,0x39,
+0x8F,0xF4,0xB8,0x00,0xE2,0x60,0xE8,0x68,0x38,0x14,0x0C,0x00,0x51,0x01,0x80,0x01,
+0xC9,0x3C,0x3D,0x13,0xFE,0xD1,0x41,0x21,0x84,0x08,0x80,0x90,0x41,0x48,0x84,0x08,
+0x41,0x59,0x14,0x00,0x4C,0x40,0x00,0x32,0x41,0x72,0x04,0x08,0x40,0x26,0x5C,0x00,
+0x00,0x1A,0x80,0x01,0xA6,0x91,0x8A,0x22,0xEB,0x14,0x96,0x48,0xE6,0x2C,0xE8,0x05,
+0xFE,0x4C,0x55,0x60,0x80,0xFF,0xD5,0x03,0x45,0x60,0x00,0x79,0x38,0x26,0x48,0x00,
+0x38,0x16,0x5C,0x00,0x9A,0x51,0xEB,0x14,0x96,0x48,0xE6,0x2C,0xE8,0x04,0xFE,0x4C,
+0x96,0x48,0xD5,0x03,0x44,0x10,0x00,0x79,0x88,0x36,0x96,0x48,0xE3,0xA1,0xE9,0x07,
+0x38,0xE4,0x0C,0x08,0x84,0xE1,0x38,0xE4,0x10,0x08,0xD5,0x05,0x40,0xFA,0x04,0x07,
+0xE8,0x02,0x8D,0x61,0x8C,0x81,0xD5,0xCF,0x2E,0x07,0xFF,0xCF,0x38,0x19,0x8E,0x02,
+0xE2,0x20,0xE9,0x10,0x80,0x49,0x80,0x6A,0xA0,0x52,0xA0,0x1A,0x88,0x01,0xA8,0x12,
+0xB4,0x29,0xB4,0x0A,0x88,0x01,0xB6,0x09,0xA0,0x51,0xA0,0x19,0x88,0x01,0xA8,0x11,
+0xD5,0x0F,0x96,0x18,0x15,0x3F,0x80,0x03,0xF5,0x82,0x15,0x0F,0x80,0x01,0x49,0x00,
+0x00,0xDF,0x05,0x0F,0x80,0x01,0xF5,0x02,0x05,0x3F,0x80,0x03,0xC8,0xE4,0x80,0x70,
+0x8D,0x2C,0x8D,0x4C,0xD5,0x97,0x4C,0xB3,0x40,0x03,0x84,0xE0,0x80,0x07,0x49,0xFF,
+0xFF,0x2D,0xBF,0x00,0xCF,0x05,0x3E,0x77,0xFD,0x35,0x3E,0x77,0xFD,0x4A,0x3C,0x9C,
+0x00,0x48,0xEA,0x3C,0xF0,0x86,0x3C,0xAC,0x00,0x49,0xEA,0xB0,0xF0,0x87,0x50,0x04,
+0xFF,0xFF,0xF0,0x81,0x50,0x05,0x7F,0xFF,0xF0,0x82,0x2E,0x00,0x00,0x14,0x46,0x81,
+0x00,0x01,0x58,0x84,0x0D,0x98,0x96,0x44,0xEA,0x8A,0xF0,0x8A,0x2E,0x07,0xFD,0x5C,
+0xF0,0x8B,0x2E,0x60,0x00,0x8B,0xF1,0x88,0x54,0x03,0x00,0xF0,0xF0,0x83,0x40,0x05,
+0x00,0x01,0xF0,0x8C,0x95,0xB4,0x2E,0x07,0xFD,0x35,0x97,0xB0,0xF0,0x85,0x40,0x04,
+0x98,0x01,0xF0,0x8D,0x2E,0x17,0xFD,0x6B,0x2E,0x07,0xFD,0x4A,0xF1,0x89,0xF0,0x84,
+0x85,0x60,0x81,0x88,0x4C,0xB3,0x80,0x71,0xB4,0x0D,0x04,0xE6,0x80,0x02,0xF2,0x06,
+0x84,0x60,0x42,0x00,0x24,0x69,0xEA,0x68,0x80,0x4E,0x84,0x60,0xEA,0x68,0xF2,0x06,
+0x40,0x24,0x88,0x57,0x92,0x41,0xC9,0x04,0xC9,0x05,0xE2,0x40,0xE8,0x03,0x8A,0x02,
+0xD5,0x02,0x84,0x00,0xB6,0x08,0x04,0x06,0x80,0x01,0xF2,0x07,0x84,0x60,0x42,0x00,
+0x28,0x69,0xEA,0x68,0x80,0x4E,0x84,0x60,0xEA,0x68,0xF2,0x07,0x40,0x25,0x08,0x57,
+0x92,0x41,0xC9,0x04,0xC9,0x05,0xE2,0x40,0xE8,0x03,0x8A,0x02,0xD5,0x02,0x84,0x00,
+0x14,0x04,0x00,0x01,0xB4,0x08,0xE2,0x09,0xE9,0x03,0xF0,0x01,0xB6,0x08,0x04,0x04,
+0x00,0x01,0xE2,0x0A,0xE9,0x04,0xF0,0x02,0x14,0x04,0x00,0x01,0xF0,0x08,0xC0,0x05,
+0xB4,0x08,0xF1,0x01,0x9A,0x08,0xB6,0x08,0xB4,0x08,0xF1,0x09,0xEB,0x75,0x58,0x21,
+0x0E,0xA4,0x40,0x10,0x04,0x37,0x38,0x11,0x2C,0x08,0xF1,0x0A,0xC1,0x06,0x80,0x68,
+0xA0,0x59,0xF2,0x02,0x9A,0x51,0xA8,0x59,0x04,0x14,0x00,0x01,0xF2,0x0B,0xEB,0x67,
+0x58,0x31,0x8E,0x98,0x40,0x20,0x88,0x57,0x38,0x21,0xAC,0x08,0xF2,0x03,0xE2,0x41,
+0xE8,0x06,0xF2,0x0C,0xE2,0x22,0xE8,0x03,0x84,0x21,0xF1,0x85,0xE2,0xC0,0xE8,0x06,
+0xF1,0x0D,0xE2,0x01,0xE8,0x03,0x84,0x01,0xF0,0x84,0x8D,0x61,0x8D,0x08,0x50,0xD6,
+0x80,0x0C,0x48,0xFF,0xFF,0x91,0x00,0x1F,0x80,0x14,0x3E,0x17,0xFD,0x35,0x00,0x1F,
+0x80,0x10,0x3E,0x17,0xFD,0x4A,0x46,0x01,0x00,0x01,0x02,0x00,0x06,0xCC,0x46,0x11,
+0x00,0x07,0x12,0x00,0x87,0xAD,0x46,0x01,0x00,0x01,0x02,0x00,0x06,0xCE,0x46,0x11,
+0x00,0x07,0x12,0x00,0x87,0xAE,0xEA,0x29,0xE6,0xEC,0xE8,0x08,0x40,0x16,0x1C,0x60,
+0x38,0x06,0x1F,0x0A,0xA8,0x09,0x8C,0xE1,0xD5,0xF8,0xFC,0xE9,0x46,0x31,0x00,0x01,
+0x58,0x31,0x8F,0xDC,0x40,0x41,0x80,0x20,0x2E,0x20,0x01,0x28,0xA7,0x21,0x8E,0x41,
+0xE6,0x82,0x96,0x90,0x2E,0x10,0x01,0x29,0xE9,0x0C,0xE2,0x44,0xE9,0x0A,0x38,0x01,
+0x81,0x00,0xE6,0x02,0xE9,0x06,0x8E,0x21,0x96,0x48,0x40,0x00,0x80,0x06,0xDD,0x9E,
+0x84,0x01,0xDD,0x9E,0xFC,0x00,0x3F,0xCF,0xFE,0x08,0x2E,0x07,0xFD,0x5D,0xC0,0x05,
+0x84,0x00,0xB8,0x85,0x48,0x00,0x00,0x83,0xBE,0x0F,0xCE,0x34,0xB9,0x05,0x8E,0x21,
+0xE6,0x23,0xE8,0x30,0xDD,0x59,0x5A,0x08,0x01,0x0C,0x80,0x06,0x49,0xFF,0xFF,0xD0,
+0xC0,0x04,0x2E,0x07,0xFF,0xB7,0xD5,0x06,0x2E,0x07,0xFF,0xB6,0xD5,0x03,0x2E,0x07,
+0xFF,0xBA,0xB9,0x00,0x5A,0x10,0x03,0x05,0xEA,0xBB,0x5A,0x18,0x01,0x06,0x2E,0x17,
+0xFF,0xB8,0x88,0x01,0x96,0x01,0xDD,0x49,0xEA,0x94,0xC1,0x0B,0x84,0x00,0x49,0xFF,
+0xFF,0xB7,0x2E,0x10,0x00,0x54,0xC0,0x04,0x40,0x00,0x84,0x09,0xD5,0x02,0x96,0x09,
+0x46,0x11,0x00,0x02,0x04,0x10,0x80,0x2F,0x92,0x21,0xE2,0x20,0xE8,0x03,0x84,0x00,
+0xB8,0x85,0xEA,0x96,0x46,0x11,0x00,0x02,0x04,0x10,0x80,0x2F,0xC8,0x07,0x3C,0x03,
+0xFE,0xCF,0x40,0x00,0x80,0x17,0x3E,0x07,0xFD,0x46,0xB8,0x05,0x92,0x21,0x49,0xFF,
+0xEA,0x03,0xB8,0x05,0xE6,0x02,0xE9,0x3A,0xB9,0x0F,0xE2,0x20,0xE8,0x37,0x3C,0x63,
+0xFE,0xD2,0xEB,0x08,0xC8,0x04,0x40,0x13,0x04,0x09,0xD5,0x03,0x94,0x71,0x96,0x49,
+0xEA,0x49,0xC0,0x09,0x2E,0x07,0xFF,0xB4,0xDD,0x49,0x80,0xC0,0x2E,0x07,0xFF,0xB5,
+0xDD,0x49,0x80,0x20,0xEA,0x45,0xC0,0x0A,0x2E,0x00,0x00,0x61,0xDD,0x49,0x80,0xC0,
+0x2E,0x00,0x00,0x61,0xDD,0x49,0x94,0x01,0x96,0x41,0xBA,0x0F,0xBB,0x05,0x84,0x8C,
+0x46,0x51,0x00,0x02,0x58,0x52,0x80,0xB4,0xE2,0x43,0xE8,0x10,0x80,0x05,0x42,0x01,
+0x10,0x73,0xE6,0x42,0xA0,0x02,0x82,0x01,0x92,0x01,0x41,0x03,0x3C,0x1B,0xE2,0x10,
+0xE8,0x03,0xBA,0x85,0xD5,0x03,0x8C,0x41,0xD5,0xF0,0xFC,0x80,0xFC,0x60,0x2E,0x07,
+0xFD,0x60,0x5A,0x08,0x01,0x0D,0x2E,0x07,0xFD,0x37,0xE6,0x15,0xE9,0x05,0x84,0x00,
+0x3E,0x07,0xFD,0x60,0xD5,0x04,0x8C,0x01,0x3E,0x07,0xFD,0x37,0x3C,0x03,0xFE,0xC4,
+0xE6,0x1F,0x2F,0x30,0x01,0x2B,0xE8,0x14,0x2E,0x47,0xFD,0x60,0x2E,0x37,0xFD,0x37,
+0x84,0x00,0xEB,0x78,0x58,0x10,0x8C,0xCC,0x46,0x51,0x00,0x01,0x58,0x52,0x8D,0x98,
+0xEA,0xB5,0x80,0xE0,0x47,0x01,0x00,0x01,0x59,0x08,0x0D,0x74,0xD5,0x1B,0xEB,0x3B,
+0xC8,0xEC,0xEB,0x78,0x58,0x10,0x8C,0x6C,0xEA,0xC7,0xE2,0x13,0xE8,0xE6,0x40,0x30,
+0x80,0x60,0x38,0x20,0x83,0x0A,0xA8,0x99,0x8C,0x01,0xD5,0xF8,0x38,0x22,0x83,0x02,
+0x4C,0x23,0x40,0x13,0xA6,0x88,0x8E,0x41,0xE6,0x53,0xE9,0x07,0xAF,0xC8,0x8C,0x01,
+0x8C,0x21,0xE2,0x13,0xE9,0xF4,0xD5,0x0E,0x38,0x28,0x00,0x00,0x5A,0x28,0x01,0xF8,
+0x80,0x82,0x84,0x60,0xD5,0xF4,0xA6,0x88,0x5A,0x20,0xFF,0xF3,0x8C,0x41,0xAE,0x88,
+0xD5,0xEF,0x3E,0x47,0xFD,0x60,0x46,0xA1,0x00,0x01,0x58,0xA5,0x0B,0xA0,0x3E,0x37,
+0xFD,0x37,0xEB,0x78,0x58,0x10,0x8B,0xAC,0x46,0x31,0x00,0x01,0x58,0x31,0x8D,0x98,
+0x46,0x71,0x00,0x01,0x58,0x73,0x8D,0x74,0x80,0xCA,0x45,0x20,0xFF,0xFF,0x85,0x20,
+0x85,0x61,0x40,0x03,0x28,0x01,0xE2,0x13,0xE8,0x50,0xB4,0x43,0x4C,0x29,0x40,0x08,
+0xB7,0xC1,0x10,0xB3,0x80,0x00,0x10,0xB3,0x00,0x00,0xD5,0x26,0xA6,0x38,0x5A,0x08,
+0x01,0x24,0xB4,0xA1,0x4C,0x59,0x40,0x06,0x3B,0x01,0xC4,0x00,0xEA,0xEA,0xD5,0x1C,
+0xE2,0xA2,0xE8,0x03,0x9A,0x15,0xD5,0x02,0x9A,0x2A,0xA1,0x59,0xA1,0x09,0xE2,0x85,
+0xE8,0x03,0x9B,0x2C,0xD5,0x02,0x8A,0x85,0xFE,0x04,0x42,0x02,0x10,0x73,0x81,0xE0,
+0x2E,0x50,0x01,0x32,0x2E,0x40,0x01,0x33,0xFF,0x2C,0xE2,0x8F,0xE8,0x05,0x10,0x93,
+0x80,0x00,0x3E,0x97,0xFD,0x60,0xB4,0xA1,0x4C,0x59,0x00,0x1B,0x4C,0x29,0x00,0x19,
+0xA6,0x30,0x5A,0x08,0x01,0x16,0xE2,0xA2,0xE8,0x03,0x9B,0x55,0xD5,0x02,0x8A,0xA2,
+0xA0,0x99,0xA0,0x09,0xE2,0x02,0xE8,0x03,0x9A,0x10,0xD5,0x02,0x8A,0x02,0xFF,0x6C,
+0x42,0x50,0x00,0x73,0x5C,0xF2,0xB8,0x41,0xE9,0x03,0x10,0x93,0x00,0x00,0x8C,0xC1,
+0x8C,0x28,0x8C,0x68,0x8C,0xE1,0xD5,0xAE,0xFC,0xE0,0xFC,0x61,0x3F,0xCF,0xFE,0x44,
+0x46,0x71,0x00,0x01,0x58,0x73,0x8D,0x98,0x46,0xB1,0x00,0x01,0x58,0xB5,0x8B,0x88,
+0x46,0x91,0x00,0x01,0x58,0x94,0x8B,0x94,0x84,0xC0,0x81,0x47,0x44,0x80,0xFF,0xFF,
+0x46,0xC1,0x00,0x01,0x58,0xC6,0x0D,0x80,0x44,0xDF,0xFF,0x80,0x46,0xE1,0x00,0x01,
+0x58,0xE7,0x0D,0x08,0x46,0x31,0x00,0x01,0x58,0x31,0x8C,0x6C,0x44,0x10,0xFF,0xFE,
+0xEA,0x2C,0xE2,0xC0,0xE8,0x52,0x96,0x30,0xF1,0x81,0xB6,0x7F,0x49,0xFF,0xF6,0x2D,
+0xB4,0x7F,0xF1,0x01,0x5A,0x08,0x01,0x05,0x2E,0x07,0xFD,0x67,0xEA,0x91,0xB4,0xA7,
+0x4C,0x54,0x40,0x1C,0x00,0x04,0x80,0x00,0x2E,0x27,0xFD,0x67,0xE2,0x02,0xE8,0x06,
+0x8C,0x01,0xEA,0x91,0xB6,0x27,0xA8,0x79,0xD5,0x33,0x84,0x00,0x38,0x57,0x1B,0x02,
+0xEA,0xC0,0x84,0x1F,0xEA,0x91,0x94,0x33,0x4C,0x54,0x00,0x2B,0x98,0x98,0x88,0x0E,
+0x3B,0x00,0x44,0x00,0xEA,0x9E,0xD5,0x24,0xEA,0xE6,0xC0,0x0E,0xC6,0x0D,0x46,0x01,
+0x00,0x01,0x04,0x00,0x03,0x36,0x5C,0xF0,0x00,0xC9,0xE9,0x06,0x2E,0x27,0xFF,0xFB,
+0x3E,0xD7,0xFD,0x58,0xD5,0x03,0x2E,0x27,0xFD,0x23,0x00,0x05,0x80,0x00,0xE2,0x02,
+0xE8,0x0B,0x8C,0x01,0xEA,0xC0,0x84,0x5F,0x40,0x06,0x18,0x20,0xB7,0x07,0x14,0x83,
+0x80,0x01,0xAE,0x81,0xD5,0x05,0x84,0x00,0xEA,0x91,0x84,0x1F,0xEA,0xC0,0x8C,0xC1,
+0x8D,0x61,0x8D,0x21,0x8C,0xE8,0xD5,0xAD,0x84,0xC0,0xBE,0x80,0x84,0x3F,0x46,0x01,
+0x00,0x01,0x58,0x00,0x0D,0x80,0xFA,0x48,0xDD,0x42,0x80,0x06,0x46,0x41,0x00,0x01,
+0x58,0x42,0x0D,0x98,0xEA,0xB5,0x46,0x31,0x00,0x01,0x58,0x31,0x8D,0x08,0x46,0x71,
+0x00,0x01,0x58,0x73,0x8C,0xD8,0x82,0x40,0x45,0x30,0xFF,0xFE,0x46,0x91,0x00,0x01,
+0x58,0x94,0x8D,0x80,0x85,0x7E,0x38,0x55,0x02,0x02,0x94,0x42,0xD6,0x0F,0xBA,0x00,
+0x8C,0x41,0xBA,0x80,0x4C,0x59,0xC0,0x0D,0x98,0xA1,0x88,0x23,0xEA,0x6B,0x40,0x10,
+0x24,0x00,0xEA,0x9E,0x10,0xB0,0x80,0x01,0xD5,0x07,0x39,0x23,0x81,0x0A,0x98,0x99,
+0x88,0x2A,0xEA,0x6B,0xEA,0x9E,0x8C,0x02,0x5A,0x08,0x18,0xE7,0x49,0xFF,0xFE,0x90,
+0xFC,0xE1,0xFC,0x60,0x3F,0xCF,0xFE,0x1C,0xB8,0x0B,0xC0,0x03,0x84,0x00,0xD5,0x04,
+0x2E,0x07,0xFF,0xA5,0x92,0x04,0x3E,0x07,0xFD,0x2B,0xEB,0x16,0xB9,0x04,0x8C,0x01,
+0xE2,0x20,0x46,0x21,0x00,0x01,0x58,0x21,0x09,0x48,0x2E,0x90,0x01,0x2B,0xE9,0x21,
+0x84,0xEC,0x42,0x60,0x1C,0x24,0x84,0x74,0x84,0xA0,0x46,0xB1,0x00,0x01,0x58,0xB5,
+0x8D,0x98,0xB8,0x84,0x88,0x46,0xEB,0x78,0x58,0x10,0x89,0x54,0x43,0x30,0x0C,0x24,
+0x88,0xC3,0x81,0x05,0x46,0xA1,0x00,0x01,0x58,0xA5,0x0D,0x68,0x46,0xC1,0x00,0x02,
+0x58,0xC6,0x00,0xB4,0x3E,0xD8,0x02,0xD4,0xEA,0x89,0x81,0xCB,0x86,0x87,0xD5,0x4E,
+0x84,0x60,0x44,0x60,0x00,0x30,0xE0,0x69,0xE8,0xDC,0x80,0x22,0x42,0x11,0x98,0x73,
+0x84,0x81,0x8C,0x2C,0xE0,0x80,0x8C,0x2C,0xE8,0x09,0x50,0x50,0xFF,0xF4,0x3B,0x02,
+0xC8,0x00,0x8C,0x81,0x3B,0x00,0xC8,0x20,0xD5,0xF6,0x8C,0x61,0xD5,0xED,0x50,0xF1,
+0xFF,0xF4,0x3B,0x01,0xC8,0x00,0x51,0x5A,0x80,0x01,0x3B,0x07,0xC8,0x20,0x40,0xFA,
+0x80,0x07,0x8C,0x6C,0xE9,0xF5,0x2E,0x37,0xFF,0xA4,0x43,0x21,0x98,0x0B,0x38,0x35,
+0x14,0x00,0x4F,0x22,0x00,0x29,0x38,0x36,0x8C,0x10,0x39,0x15,0x97,0x02,0x41,0x02,
+0x8C,0x08,0x4D,0x12,0x00,0x2B,0x2F,0x17,0xFD,0x3A,0xE3,0xA3,0x40,0x38,0xBC,0x1B,
+0x89,0x8E,0x3B,0x08,0x44,0x00,0xEA,0x9E,0x4F,0x23,0x00,0x07,0x05,0x01,0x00,0x02,
+0x42,0x3A,0x40,0x73,0x92,0x63,0xA8,0xD2,0x04,0x30,0xFF,0xFD,0x4C,0x32,0x00,0x18,
+0x8C,0xA1,0x50,0x10,0x80,0x30,0x50,0x21,0x00,0x30,0xE0,0xA9,0xE8,0x2F,0x80,0x61,
+0x86,0xA0,0xD5,0xC6,0x81,0xEC,0x42,0xF1,0x9C,0x73,0x80,0x6F,0x2E,0xF7,0xFD,0x52,
+0xA0,0xDA,0x40,0x31,0xBC,0x0D,0xD5,0xD2,0x84,0x60,0xD5,0xDB,0xB4,0x61,0x4C,0x32,
+0x3F,0xE9,0x5A,0x00,0x01,0xE7,0xBB,0x00,0xE6,0x63,0xE8,0x05,0xA0,0xCB,0x4C,0x32,
+0x40,0x5A,0xD5,0x20,0xA0,0xCB,0x4C,0x32,0x00,0x07,0x5A,0x08,0x03,0xF9,0xA0,0xCE,
+0x4C,0x32,0x7F,0xF6,0x80,0x61,0x86,0x01,0x8D,0x81,0xE0,0x10,0xB6,0x83,0xA9,0x19,
+0x14,0x81,0x80,0x02,0x8C,0x6C,0xE8,0xF9,0xD5,0xEA,0x84,0xC0,0xEA,0x2C,0xE0,0xC0,
+0xE8,0x45,0x96,0x30,0xEB,0x78,0x58,0x10,0x89,0x48,0x49,0xFF,0xF3,0xEA,0x8C,0xC1,
+0xD5,0xF6,0x84,0x61,0x5A,0x08,0x03,0xBE,0x05,0x00,0x80,0x06,0x4D,0x02,0x3F,0xBA,
+0xCB,0xB8,0xB4,0x61,0xB5,0xA2,0x05,0x01,0x00,0x01,0x41,0x58,0x8C,0x01,0xA0,0xC9,
+0x40,0xF8,0x0C,0x01,0x2E,0x30,0x01,0x32,0x42,0xF7,0xBC,0x24,0x41,0x21,0x88,0x09,
+0x2E,0x30,0x01,0x33,0x42,0xFA,0xD4,0x73,0x92,0x62,0xFE,0xDC,0x42,0x39,0x48,0x73,
+0x40,0xF7,0x8C,0x07,0xE8,0x9E,0x41,0x21,0x4C,0x00,0x38,0x39,0x18,0x02,0x89,0xC6,
+0x89,0xA3,0x04,0x39,0x00,0x01,0x93,0xA1,0x88,0x70,0x92,0x61,0x82,0x01,0x86,0x41,
+0x8D,0xC1,0xE0,0x12,0xB7,0xB0,0x14,0x38,0x00,0x01,0x8D,0x8C,0xE8,0xFA,0x48,0xFF,
+0xFF,0x89,0x84,0x60,0x5A,0x00,0x03,0xCA,0xD5,0xCD,0xFC,0xE0,0xFC,0x64,0x81,0x80,
+0x84,0x00,0x12,0x06,0x00,0x48,0x10,0x06,0x00,0x92,0x2E,0x17,0xFD,0x4B,0x2E,0x47,
+0xFF,0xC2,0x2E,0x07,0xFF,0xC1,0xC9,0x05,0xEA,0xBB,0xC9,0x03,0xEA,0x94,0xC1,0x06,
+0x58,0x12,0x00,0x0F,0xB6,0x3F,0x92,0x04,0xD5,0x05,0x97,0x1F,0x94,0x63,0xB6,0x3F,
+0x96,0x1F,0x8C,0x01,0x85,0x48,0x42,0xA0,0x28,0x01,0x2E,0x07,0xFD,0x1F,0xE2,0x0A,
+0xE8,0x03,0x8C,0x01,0xD5,0x04,0xE3,0x40,0xE8,0x03,0x8E,0x01,0xEA,0xEB,0x40,0x05,
+0x04,0x09,0x96,0x00,0xF0,0x82,0x84,0xC0,0x46,0x81,0x00,0x01,0x58,0x84,0x06,0x30,
+0x3C,0xDD,0xFE,0xDB,0x46,0xE1,0x00,0x01,0x58,0xE7,0x06,0x24,0xEA,0x2C,0xE2,0xC0,
+0x4E,0xF2,0x01,0x5A,0x94,0x73,0x46,0x01,0x00,0x01,0x58,0x00,0x0E,0x38,0x39,0x10,
+0x1B,0x02,0x88,0x01,0xF1,0x81,0xA1,0x41,0xEB,0x78,0x58,0x10,0x89,0x48,0xDD,0x47,
+0xEB,0x0D,0x38,0x44,0x18,0x00,0x80,0x01,0x8C,0x0C,0xA1,0xCB,0x04,0x90,0x00,0x01,
+0xEA,0x29,0x46,0x21,0x00,0x01,0x58,0x21,0x06,0x3C,0x4C,0x70,0x40,0x0D,0x4C,0x93,
+0xC0,0x0B,0x44,0x0F,0xFF,0xB4,0x38,0x07,0x18,0x08,0x84,0x00,0x38,0x01,0x18,0x08,
+0x48,0x00,0x01,0x1D,0x00,0x06,0x00,0x92,0x84,0x21,0x8C,0x01,0x10,0x06,0x00,0x92,
+0x02,0x06,0x00,0x48,0x40,0x30,0x98,0x0C,0xFE,0x1F,0x12,0x06,0x00,0x48,0x38,0x01,
+0x18,0x00,0x47,0xC1,0x00,0x01,0x59,0xCE,0x06,0x48,0xC8,0x14,0x46,0x21,0x00,0x01,
+0x58,0x21,0x06,0x3C,0x38,0x11,0x18,0x08,0x94,0xB6,0x40,0x1E,0x00,0x00,0x38,0x70,
+0x88,0x0A,0x8C,0x08,0x88,0x22,0x14,0x90,0x80,0x01,0x5A,0x08,0x40,0xF8,0x48,0x00,
+0x00,0xF8,0xE3,0xA7,0xE8,0x04,0x41,0x33,0xC4,0x01,0xD5,0x03,0x41,0x38,0x9C,0x01,
+0xE2,0xA9,0xE8,0x04,0x41,0x24,0x94,0x01,0xD5,0x03,0x41,0x22,0xA4,0x01,0x42,0x19,
+0xCC,0x24,0x42,0x19,0x48,0x73,0x38,0x07,0x18,0x00,0x92,0x21,0xC8,0x06,0x2E,0x27,
+0xFF,0xBB,0x2E,0x37,0xFF,0xBC,0xD5,0x05,0x2E,0x27,0xFF,0xBF,0x2E,0x37,0xFF,0xC0,
+0x2E,0xF7,0xFD,0x6E,0x47,0x61,0x00,0x01,0x59,0x6B,0x0D,0x68,0xE9,0x10,0x38,0xFB,
+0x18,0x00,0x47,0x01,0x00,0x01,0x59,0x08,0x0F,0xF4,0x2E,0xB7,0xFD,0x49,0x39,0x08,
+0x3E,0x02,0xE3,0x70,0xE9,0x04,0x2E,0xF7,0xFD,0x68,0xE8,0x07,0x86,0x03,0x42,0x21,
+0x40,0x24,0xEA,0xEF,0x96,0x90,0x96,0xD8,0xC8,0x15,0xE2,0xE2,0xE9,0x09,0x3D,0x0C,
+0x00,0x48,0x8F,0x81,0x8B,0x82,0xE3,0x87,0x40,0x20,0x3C,0x1B,0xD5,0x02,0x80,0x40,
+0xE3,0x23,0xE9,0x07,0x3D,0x0C,0x00,0x49,0x8F,0x81,0x8B,0x83,0xE3,0x89,0xE8,0x02,
+0x84,0x60,0x46,0xB1,0x00,0x02,0x58,0xB5,0x80,0xB4,0x38,0xFB,0x18,0x00,0x86,0x0C,
+0x82,0x8B,0x43,0x47,0xC0,0x73,0x04,0xFA,0x00,0x02,0xE9,0x02,0xC0,0x0F,0xE3,0xE2,
+0xE8,0x03,0xE3,0xC3,0xE9,0x09,0x84,0x00,0x46,0x21,0x00,0x01,0x58,0x21,0x06,0x24,
+0x38,0x01,0x18,0x08,0xD5,0x03,0x81,0x25,0x80,0xF1,0xB4,0x1F,0x92,0x22,0x40,0x10,
+0x80,0x37,0x8C,0x21,0xE6,0x31,0xE9,0x02,0xFA,0x20,0xB4,0x1F,0xC0,0x41,0xEB,0x16,
+0xC0,0x09,0xDD,0x47,0x80,0x4D,0x42,0x23,0x00,0x73,0xEA,0x29,0xA0,0x96,0x4C,0x20,
+0x00,0x38,0x80,0x06,0x15,0x6F,0x80,0x07,0xF1,0x86,0xF5,0x85,0x15,0x1F,0x80,0x04,
+0xF4,0x83,0xF8,0x41,0xF4,0x03,0x05,0x1F,0x80,0x04,0xF5,0x05,0xF1,0x06,0x05,0x6F,
+0x80,0x07,0xC8,0x26,0x38,0x2B,0x18,0x00,0x84,0x0C,0x42,0xB1,0x00,0x73,0x04,0x05,
+0x80,0x02,0xC0,0x1E,0x52,0x00,0x80,0x10,0x42,0x20,0x44,0x24,0x42,0x23,0x84,0x73,
+0x95,0xFC,0x82,0x22,0x3C,0x2C,0x00,0x48,0xFF,0x44,0x40,0x73,0x88,0xF7,0x42,0x54,
+0x84,0x73,0x40,0x04,0x90,0x08,0x3C,0x9C,0x00,0x49,0x97,0xF8,0x40,0x00,0x24,0x17,
+0x96,0x00,0x89,0xA7,0x88,0xA0,0x40,0x78,0x90,0x09,0x40,0x92,0x90,0x09,0xF0,0x01,
+0xE6,0x2D,0x88,0x04,0x40,0x0E,0x00,0x60,0xB6,0xE0,0x14,0x90,0x00,0x01,0xE9,0x09,
+0xDD,0x47,0x80,0x2D,0xEB,0x0D,0xEA,0x29,0xA1,0x4E,0xD8,0x03,0xEB,0x16,0xC8,0x23,
+0x80,0x06,0xF4,0x83,0x49,0xFF,0xF3,0x51,0xF4,0x03,0xC8,0x1D,0x80,0xE0,0x80,0xA0,
+0x4C,0x55,0x00,0x13,0xF1,0x01,0x88,0x24,0x38,0x2E,0x07,0x02,0x40,0x1E,0x04,0x60,
+0xA0,0x49,0x88,0xE2,0x88,0x01,0xC4,0x04,0x9E,0x61,0x97,0x08,0xD5,0x02,0x84,0x87,
+0x8C,0xA1,0x97,0x68,0xD5,0xEE,0xF1,0x02,0x88,0xE1,0x88,0x01,0x40,0x73,0xA8,0xF7,
+0x40,0x90,0x29,0x37,0x46,0x01,0x00,0x01,0x58,0x00,0x06,0x30,0x38,0x00,0x18,0x00,
+0x8C,0x01,0x96,0x00,0x5A,0x08,0x08,0x03,0x84,0x00,0x38,0x04,0x18,0x08,0x84,0x0C,
+0x80,0x2C,0xEB,0x0D,0x80,0x4D,0xB6,0xE1,0x14,0x90,0x80,0x01,0x80,0x01,0x44,0x10,
+0x00,0x30,0x42,0x23,0x04,0x73,0x8C,0xC1,0xA0,0x55,0x10,0x10,0x00,0x08,0x97,0xB0,
+0x48,0xFF,0xFE,0xA6,0x3E,0xA7,0xFD,0x1F,0xFC,0xE4,0xEA,0x69,0x42,0x00,0x18,0x0B,
+0x4E,0x02,0x01,0x69,0x84,0x00,0x3E,0x18,0x02,0xD4,0x84,0x41,0x38,0x20,0x80,0x08,
+0x8C,0x01,0x5A,0x08,0x0C,0xFD,0xFC,0x66,0xEB,0x3B,0xF0,0x83,0xEB,0x3D,0xF0,0x81,
+0xEA,0x3C,0xF0,0x84,0xEA,0xB8,0xF0,0x82,0xEA,0xB0,0xF0,0x85,0x2E,0x00,0x01,0x02,
+0xF0,0x86,0x2E,0x00,0x01,0x03,0x85,0x80,0xF0,0x87,0x3E,0x68,0x02,0xD4,0x3E,0xA8,
+0x01,0xCC,0x84,0xE1,0x81,0x6C,0xF0,0x03,0x4C,0xB0,0x01,0x44,0x00,0x15,0x00,0x00,
+0x01,0x05,0x00,0x01,0x01,0x15,0x00,0x02,0x40,0x00,0xC0,0x00,0x40,0x80,0x04,0x0A,
+0x00,0x05,0x00,0x03,0x40,0x28,0x80,0x00,0x41,0x41,0x04,0x0A,0xC1,0x08,0x4F,0x02,
+0x00,0x09,0x4F,0x12,0x00,0x09,0x40,0x70,0x00,0x1A,0xD5,0x06,0x80,0xE1,0xD5,0x04,
+0x80,0xF0,0xD5,0x02,0x80,0xF1,0x44,0x20,0x00,0x48,0x42,0x40,0x08,0x24,0x84,0x60,
+0x40,0x42,0x04,0x20,0x44,0x20,0x00,0x4A,0x42,0x43,0x88,0x75,0x80,0xA1,0x82,0x63,
+0x81,0x23,0x82,0x43,0x83,0x03,0xE3,0x85,0xE9,0x24,0x41,0x51,0x90,0x00,0x46,0x21,
+0x00,0x02,0x58,0x21,0x01,0x44,0x41,0x5A,0x88,0x00,0x81,0xA0,0x85,0xC0,0x40,0x22,
+0xA0,0x06,0xE3,0xAD,0xE9,0x13,0x40,0xFA,0xB8,0x00,0x22,0xF7,0x8C,0xAA,0xC2,0x05,
+0x89,0xCF,0x43,0x37,0x94,0x73,0xD5,0x05,0x41,0x8C,0x3C,0x00,0x42,0x97,0x94,0x73,
+0x50,0xD6,0x80,0x01,0x50,0xE7,0x00,0x48,0xD5,0xED,0x8C,0xA1,0x8C,0x62,0xD5,0xDC,
+0x84,0x60,0x83,0x83,0x81,0xA3,0x81,0xC3,0x81,0x03,0xE3,0x81,0xE9,0x23,0x99,0x5C,
+0x46,0x21,0x00,0x02,0x58,0x21,0x01,0x44,0x41,0x62,0x88,0x00,0x86,0xA0,0x80,0xA0,
+0xE3,0xA5,0xE9,0x15,0xE2,0xB4,0x41,0x7B,0x54,0x00,0xE8,0x07,0x22,0xFB,0x8C,0xAA,
+0x89,0x0F,0x42,0xD7,0x94,0x73,0xD5,0x07,0x22,0xFB,0x8C,0xAA,0x40,0xE7,0x3C,0x00,
+0x43,0xC7,0x94,0x73,0x8C,0xA1,0x51,0x5A,0x80,0x48,0xD5,0xEB,0x8C,0x21,0x8C,0x62,
+0xD5,0xDD,0xF0,0x01,0xF1,0x04,0x80,0x58,0x40,0x40,0x04,0x97,0x84,0x60,0x42,0x04,
+0x90,0x69,0x15,0x3F,0x80,0x0B,0x15,0x2F,0x80,0x0A,0xF4,0x88,0xF8,0x36,0xF4,0x08,
+0x81,0x20,0x40,0x52,0x04,0x09,0x05,0x2F,0x80,0x0A,0x05,0x3F,0x80,0x0B,0xC9,0x05,
+0xC9,0x03,0xE2,0xA0,0xE9,0x02,0x85,0x20,0x42,0x09,0x90,0x69,0x80,0x52,0x84,0x60,
+0xF5,0x88,0xF8,0x23,0x80,0x80,0xF5,0x08,0xC9,0x05,0xC9,0x03,0xE2,0xA0,0xE9,0x02,
+0x84,0x80,0xF0,0x02,0xF1,0x05,0x80,0x4E,0x40,0x50,0x04,0xB7,0x84,0x60,0x42,0x0E,
+0x14,0x69,0xF4,0x8A,0xF5,0x88,0xF8,0x11,0xF5,0x08,0x81,0xC0,0x41,0xC2,0x84,0x09,
+0xF4,0x0A,0xC9,0x06,0xC9,0x04,0x40,0xFE,0x00,0x06,0xE9,0x02,0x85,0xC0,0x80,0x48,
+0x42,0x06,0x94,0x69,0x84,0x60,0xF4,0x88,0xEA,0x68,0x80,0x40,0xF4,0x08,0xC9,0x05,
+0xC9,0x06,0x40,0xFE,0x00,0x06,0xE8,0x03,0x80,0x02,0xD5,0x02,0x84,0x00,0x4E,0x92,
+0x00,0x0C,0xC4,0x0A,0xE2,0x89,0xE8,0x04,0x40,0x44,0x90,0x01,0xD5,0x02,0x8A,0x89,
+0x40,0x92,0x00,0x13,0xD5,0x02,0x85,0x21,0x4E,0xE2,0x00,0x0B,0xC0,0x09,0xE2,0x0E,
+0xE8,0x04,0x40,0x07,0x00,0x01,0xD5,0x02,0x8A,0x0E,0x96,0x01,0xD5,0x02,0x84,0x01,
+0xF8,0x11,0xF8,0x12,0xF8,0x1E,0x84,0x40,0x46,0x34,0x05,0x0C,0xF8,0x1A,0xFD,0x20,
+0xF0,0x88,0xF0,0x02,0xF5,0x89,0xF8,0x1B,0xF8,0x1C,0xF8,0x20,0xF8,0x21,0x81,0x00,
+0x80,0x09,0x49,0x00,0x2C,0xF7,0x46,0x2F,0x5C,0x28,0x46,0x34,0x00,0x15,0x50,0x21,
+0x0F,0x5C,0x50,0x31,0x8C,0x28,0x83,0xFF,0xF8,0x04,0x84,0x40,0x46,0x34,0x06,0x28,
+0x49,0x00,0x2A,0x6C,0xFD,0x20,0xF0,0x88,0xF0,0x01,0xF5,0x89,0x49,0x00,0x2D,0x08,
+0xF4,0x08,0xF5,0x09,0xFD,0x10,0xFD,0x02,0x83,0xFF,0x49,0x00,0x2B,0x4F,0x49,0x00,
+0x2C,0xB3,0xE3,0x00,0x40,0x04,0x3C,0x1A,0x96,0x42,0xE4,0x34,0xE9,0x02,0x85,0x81,
+0xEB,0x78,0x58,0x10,0x8F,0xF4,0x88,0x0C,0x38,0x10,0xAE,0x02,0x96,0x02,0xE2,0x20,
+0x80,0x46,0xAE,0x30,0xE8,0x02,0xAE,0x70,0xF0,0x06,0xE2,0x20,0xE9,0x0A,0x46,0x01,
+0x00,0x01,0x58,0x00,0x0C,0xCC,0x38,0x00,0x2C,0x00,0xF1,0x07,0xE2,0x01,0xE8,0x05,
+0x20,0x03,0x00,0x00,0x90,0x01,0xAE,0x30,0x20,0x01,0x00,0x00,0x8C,0xC1,0x4E,0x06,
+0x00,0x05,0x84,0x01,0x10,0x03,0x7F,0xFF,0x8D,0x61,0x8D,0x44,0x48,0xFF,0xFE,0xBD,
+0xFC,0xE6,0xDD,0x9E,0xFC,0x60,0x3F,0xCF,0xFE,0x08,0x46,0x01,0x00,0x01,0x58,0x00,
+0x00,0x28,0x84,0x20,0xFA,0x54,0xDD,0x42,0xEA,0x6A,0xEA,0xF0,0xC0,0x1F,0xDD,0x59,
+0x5A,0x08,0x01,0x12,0xEB,0x38,0xC8,0x0C,0xEB,0x23,0x2E,0x07,0xFF,0xDF,0xC1,0x03,
+0x2E,0x00,0x00,0x72,0xEA,0x94,0xC1,0x09,0x2E,0x00,0x00,0x55,0xD5,0x06,0x2E,0x07,
+0xFF,0xE2,0xD5,0x03,0x2E,0x07,0xFF,0xE0,0xB9,0x00,0x5A,0x18,0x03,0x04,0x2E,0x07,
+0xFF,0xE3,0xEA,0xBB,0xC1,0x03,0x2E,0x00,0x00,0x73,0xEA,0xF5,0xEA,0x8B,0xC1,0x18,
+0xB9,0x00,0x5A,0x18,0x02,0x06,0x2E,0x27,0xFD,0x6E,0x5A,0x20,0x01,0x05,0x2E,0x27,
+0xFD,0x4F,0xC2,0x04,0x2E,0x17,0xFF,0xE8,0xD5,0x0B,0x5A,0x10,0x03,0x05,0xEA,0xBB,
+0x5A,0x18,0x01,0x05,0x2E,0x17,0xFF,0xE7,0xD5,0x03,0x2E,0x17,0xFF,0xE6,0x46,0x21,
+0x00,0x07,0x12,0x01,0x07,0xA4,0x2E,0x27,0xFD,0x46,0x2E,0x30,0x00,0xE7,0xE2,0x62,
+0xE8,0x03,0x8A,0x43,0xD5,0x02,0x84,0x40,0x3E,0x27,0xFD,0x46,0x2F,0x37,0xFD,0x46,
+0x46,0x21,0x00,0x07,0x02,0x21,0x07,0xA4,0x40,0x99,0x80,0x13,0x88,0x49,0x96,0x91,
+0x46,0x31,0x00,0x07,0x12,0x21,0x87,0xA4,0x46,0x21,0x00,0x01,0x96,0x03,0x12,0x11,
+0x00,0x13,0x46,0x21,0x00,0x01,0x12,0x01,0x00,0x12,0x84,0x00,0x46,0x21,0x00,0x05,
+0x12,0x01,0x02,0xD6,0x2F,0x10,0x01,0x29,0x2F,0x20,0x01,0x28,0x3C,0x8D,0xFF,0x90,
+0x46,0x71,0x00,0x03,0x58,0x73,0x80,0x78,0x46,0x01,0x00,0x01,0x58,0x00,0x00,0x28,
+0x84,0x80,0x81,0x80,0x44,0xE0,0x00,0x48,0x46,0xD1,0x00,0x07,0x58,0xD6,0x85,0x00,
+0x44,0xA0,0x00,0x4C,0x51,0x43,0xF0,0xCC,0xE2,0x91,0xE8,0x3B,0x81,0x6D,0x42,0xB2,
+0x38,0x73,0x43,0x02,0x28,0x24,0x84,0x60,0xE2,0x72,0xE8,0x29,0x38,0x55,0x8D,0x01,
+0x40,0x68,0x0C,0x20,0x38,0x23,0x95,0x01,0x38,0x54,0x15,0x01,0x88,0xD4,0x8A,0x45,
+0x96,0x91,0x97,0x53,0x12,0x53,0x14,0xB2,0xA5,0x80,0xE0,0xC5,0xE8,0x02,0xAC,0x80,
+0x4E,0x57,0x00,0x14,0x46,0x61,0x00,0x05,0x02,0x63,0x02,0xD6,0xE0,0xC5,0xE8,0x0D,
+0x46,0x51,0x00,0x05,0x12,0x22,0x82,0xD6,0x46,0x21,0x00,0x05,0x10,0x41,0x05,0xAE,
+0x46,0x21,0x00,0x05,0x10,0x31,0x05,0xAF,0x8C,0x61,0xD5,0xD7,0xC9,0x03,0xAC,0x40,
+0xD5,0x05,0xA4,0x80,0x40,0x21,0x04,0x57,0xAC,0x80,0x8C,0x81,0x8C,0x02,0xD5,0xC5,
+0xEB,0x4E,0x46,0x21,0x00,0x05,0x02,0x10,0x02,0xD6,0x00,0x21,0x05,0xAE,0x46,0x01,
+0x00,0x01,0x02,0x00,0x00,0x12,0x38,0x26,0x09,0x01,0x96,0x03,0x88,0x02,0xE0,0x01,
+0xEB,0x19,0xEB,0x24,0xE8,0x0C,0x46,0x01,0x00,0x01,0x02,0x00,0x00,0x12,0x96,0x03,
+0x88,0x40,0x8A,0x22,0xEB,0x4E,0x12,0x10,0x02,0xD6,0xD5,0x06,0x84,0x00,0x46,0x11,
+0x00,0x05,0x12,0x00,0x82,0xD6,0xEB,0x4E,0xEB,0x1C,0x84,0x40,0x40,0xA0,0x04,0x09,
+0x2E,0x87,0xFF,0xAC,0x2F,0x40,0x00,0x15,0x46,0x01,0x00,0x01,0x00,0x70,0x02,0xC0,
+0x2E,0xB7,0xFD,0x4C,0x80,0x82,0x80,0x62,0x44,0xE0,0x00,0x4C,0x80,0xA2,0x53,0x59,
+0x80,0x00,0xE2,0x71,0xE8,0x52,0x80,0x06,0x42,0x01,0xB8,0x73,0x40,0xD1,0x84,0x08,
+0x50,0x00,0x29,0x64,0x86,0x00,0xE3,0x92,0xE8,0x46,0x22,0x10,0x00,0x00,0x4E,0x15,
+0x00,0x13,0xEA,0x85,0xEA,0x99,0x39,0x66,0x34,0x01,0xEA,0x7E,0x40,0xFB,0x3C,0x00,
+0x40,0xF7,0x84,0x07,0xE8,0x14,0xEA,0x85,0xEA,0x99,0xEA,0x7E,0x40,0xFB,0x3C,0x00,
+0x8A,0x2F,0xD5,0x0B,0xEA,0x85,0xEA,0x99,0xEA,0x7E,0x52,0xF7,0x80,0x00,0xE0,0x2F,
+0xE8,0x06,0xEA,0x85,0xEA,0x99,0x88,0x2F,0xAC,0x40,0xD5,0x02,0xAD,0x40,0x22,0x10,
+0x00,0x00,0x4E,0x17,0x00,0x08,0xE0,0x2A,0xE8,0x0B,0xE1,0xE1,0xE8,0x08,0x8A,0x29,
+0xD5,0x04,0xE0,0x35,0xE8,0x04,0x88,0x29,0xAC,0x40,0xD5,0x02,0xAD,0x40,0x2A,0x10,
+0x00,0x01,0x40,0xF0,0xA0,0x00,0x4E,0xF4,0x00,0x09,0x8C,0x81,0x97,0x21,0xE2,0x94,
+0xE9,0x04,0x58,0x73,0x80,0x01,0x85,0x61,0x4E,0x14,0x00,0x04,0x8A,0x41,0x96,0x91,
+0x8D,0x81,0xD5,0xBA,0x8C,0x61,0xD5,0xAE,0x46,0x01,0x00,0x01,0x10,0x70,0x02,0xC0,
+0x3E,0xB7,0xFD,0x4C,0x2E,0x00,0x00,0x46,0x94,0x05,0xE0,0x02,0xE8,0x07,0x96,0x38,
+0xEB,0x03,0xEB,0x78,0xEA,0xEC,0x84,0x01,0xEA,0x76,0x46,0x01,0x00,0x07,0x04,0x10,
+0x03,0xF2,0xEB,0x4E,0xEB,0x1C,0xE2,0x20,0xE8,0x11,0x46,0x01,0x00,0x01,0x00,0x00,
+0x02,0xC0,0xEB,0x78,0xEB,0x05,0xEA,0xEC,0x84,0x21,0x3E,0x17,0xFD,0x4C,0x2E,0x07,
+0xFD,0x28,0x8C,0x01,0xB8,0x91,0x3E,0x17,0xFD,0x5D,0xB8,0x00,0x5A,0x08,0x03,0x05,
+0x84,0xA1,0x84,0xE4,0xD5,0x03,0x84,0xA0,0x84,0xE1,0xEB,0x08,0x5A,0x08,0x01,0x04,
+0x80,0xA0,0x84,0xE2,0x40,0x03,0x94,0x20,0x54,0x90,0x00,0xFF,0x2F,0x67,0xFD,0x6E,
+0x2F,0x37,0xFD,0x78,0x84,0x80,0x51,0x79,0xFF,0xFF,0x80,0x44,0x45,0x50,0x00,0x26,
+0x45,0x40,0x00,0x24,0x44,0xE0,0x00,0x48,0x44,0xDF,0xFF,0xB8,0xE2,0x51,0xE8,0x41,
+0x42,0xA1,0x38,0x24,0x52,0x12,0x29,0x64,0x50,0x35,0x19,0x54,0x42,0xB1,0x54,0x24,
+0x42,0x81,0x50,0x24,0x88,0x26,0x88,0x66,0x42,0xC1,0x34,0x24,0x86,0x00,0xE3,0x92,
+0xE8,0x2C,0x40,0xF0,0x90,0x00,0x4F,0x62,0x00,0x0D,0x4F,0x32,0x00,0x0B,0x38,0x07,
+0xAD,0x11,0x22,0xF0,0xFD,0x2F,0x42,0x07,0xDC,0x73,0x40,0x00,0x4C,0x16,0xD5,0x12,
+0x40,0x01,0xB0,0x00,0x38,0x00,0x21,0x11,0x39,0x87,0xAD,0x11,0x40,0xF7,0xA8,0x00,
+0xFE,0x2C,0x22,0xF7,0xFA,0x80,0x42,0x0C,0x1C,0x73,0x42,0x07,0x94,0x73,0x40,0x00,
+0x24,0x16,0x12,0x00,0xFD,0x2F,0xA4,0x18,0x12,0x01,0x82,0x88,0x2A,0x00,0x80,0x01,
+0x1A,0x01,0x80,0x01,0x8D,0x81,0xD5,0xD4,0x8C,0x41,0x50,0x42,0x7F,0xB4,0xD5,0xBF,
+0x46,0x01,0x00,0x04,0x58,0x00,0x0A,0xA8,0x44,0x10,0x00,0xFD,0x44,0x20,0x02,0xF8,
+0xEB,0x1F,0x2E,0x08,0x00,0x14,0x4E,0x04,0x00,0xAC,0x2E,0x07,0xFD,0x35,0xC8,0x04,
+0x2F,0x00,0x00,0x8C,0xD5,0x03,0x45,0x00,0x00,0xFF,0x2E,0x07,0xFD,0x4A,0xC8,0x04,
+0x2E,0x70,0x00,0x8C,0xD5,0x02,0xEA,0xE4,0x2E,0x50,0x01,0x29,0xEA,0x3C,0x9D,0x29,
+0x50,0x90,0x7F,0xFF,0x51,0x10,0x00,0x01,0x46,0x11,0x00,0x04,0x58,0x10,0x85,0x04,
+0x84,0x61,0x86,0x40,0xE2,0x64,0xE8,0x20,0x22,0x20,0x80,0x01,0x23,0x30,0x80,0x02,
+0xE1,0xE2,0xE8,0x06,0x8A,0x53,0xFE,0xBC,0x90,0x48,0xAC,0x88,0xD5,0x03,0x13,0x20,
+0x80,0x00,0x38,0x20,0x81,0x11,0x39,0x30,0xA5,0x11,0xE1,0xE2,0xE8,0x07,0x8A,0x53,
+0xFE,0xBC,0x90,0x48,0x38,0x20,0xC5,0x09,0xD5,0x03,0x39,0x20,0xC5,0x09,0x8C,0x61,
+0x50,0x10,0x80,0x4C,0xD5,0xE0,0x44,0x70,0x00,0x4C,0xFF,0xEC,0x9C,0x81,0x46,0x11,
+0x00,0x04,0x58,0x10,0x84,0xBA,0x51,0x23,0x80,0x4C,0x86,0x21,0x86,0x60,0xE3,0xA2,
+0xE8,0x21,0x22,0x30,0x80,0x26,0x22,0x90,0x80,0x4C,0xE1,0x23,0xE8,0x06,0x8A,0x69,
+0xEA,0xEF,0x90,0x68,0xAC,0xC8,0xD5,0x03,0x13,0x30,0x80,0x00,0x40,0x90,0x9C,0x00,
+0x38,0x30,0x9C,0x11,0x22,0x94,0xFF,0xDA,0xE1,0x23,0xE8,0x07,0x8A,0x69,0xEA,0xEF,
+0x90,0x68,0x38,0x30,0xC8,0x09,0xD5,0x03,0x39,0x30,0xC8,0x09,0x8D,0xA1,0x8C,0x22,
+0xD5,0xDF,0x46,0x11,0x00,0x04,0x22,0x30,0x82,0x5D,0x46,0x11,0x00,0x04,0x22,0x10,
+0x82,0x82,0x44,0x70,0x00,0x4C,0x88,0x23,0x90,0x21,0x46,0x31,0x00,0x04,0x12,0x11,
+0x82,0x5C,0x80,0x66,0x80,0x26,0x42,0x32,0x1C,0x73,0x42,0x12,0x9C,0x73,0x23,0x01,
+0x91,0xBB,0x22,0x10,0x91,0xBA,0x88,0x30,0x90,0x21,0x12,0x11,0x91,0xBA,0x40,0x33,
+0x08,0x20,0x40,0x13,0x00,0x20,0x22,0x70,0x91,0xBA,0x22,0x11,0x91,0xE0,0x88,0x27,
+0x90,0x21,0x12,0x11,0x91,0xBA,0xFA,0x76,0xFF,0x1C,0x98,0x62,0x42,0x22,0x8C,0x73,
+0x88,0x04,0x40,0x03,0x00,0x20,0x40,0x13,0x04,0x20,0x40,0x63,0x08,0x20,0x22,0x40,
+0x11,0xBA,0x22,0x03,0x11,0xBA,0x88,0x04,0x90,0x01,0x12,0x00,0x91,0xBA,0xFC,0xE0,
+0xEB,0x78,0x58,0x10,0x80,0x28,0x38,0x00,0x81,0x01,0xDD,0x9E,0xFC,0x40,0x82,0x40,
+0x2E,0x47,0xFE,0xA1,0x3D,0x0C,0x00,0x48,0x3D,0x1C,0x00,0x49,0x84,0x00,0x80,0xE0,
+0x80,0x40,0x86,0x6C,0x44,0x90,0xFF,0xFF,0x85,0x41,0x2E,0x30,0x01,0x2B,0xE2,0x43,
+0xE8,0x2D,0x80,0x72,0x42,0x31,0x4C,0x73,0xB4,0xA3,0xA0,0xD9,0x4C,0x54,0x80,0x24,
+0x40,0x62,0x08,0x0E,0x97,0xB4,0xC6,0x15,0x46,0x61,0x00,0x07,0x00,0x63,0x03,0x99,
+0x40,0xF8,0x18,0x01,0xE2,0xAF,0xE8,0x17,0xE2,0xC5,0xE8,0x15,0x46,0x61,0x00,0x07,
+0x00,0x63,0x03,0x9A,0x40,0xF8,0x98,0x01,0xE2,0x6F,0xE8,0x0D,0xE2,0xC3,0xE8,0x0B,
+0xCF,0x03,0xA9,0x49,0xB6,0x61,0x40,0x35,0x08,0x0C,0x40,0x42,0x0C,0x12,0x9C,0xC1,
+0x96,0x18,0x84,0xE1,0x8C,0x41,0x96,0x90,0xD5,0xD1,0x3E,0x47,0xFE,0xA1,0xFC,0xC0,
+0xFC,0x00,0x84,0x1F,0x3E,0x07,0xFE,0xA1,0x84,0x00,0x3C,0x0B,0xFF,0xC1,0x3C,0x0B,
+0xFF,0xC0,0x84,0x3F,0x3C,0x1B,0xFF,0xBF,0x3C,0x1B,0xFF,0xBE,0x3E,0x2F,0xFF,0x78,
+0xAC,0x10,0xAC,0x11,0x3E,0x2F,0xFF,0x74,0xAC,0x10,0xAC,0x11,0x3E,0x2F,0xFF,0x70,
+0xAC,0x50,0xAC,0x51,0x3E,0x2F,0xFF,0x6C,0xAC,0x50,0xAC,0x51,0x3E,0x07,0xFF,0x14,
+0xEA,0xD5,0x46,0x01,0x00,0x07,0x58,0x00,0x03,0x80,0xA6,0x46,0xA6,0x87,0xEA,0x79,
+0x3C,0x1B,0xFF,0x61,0x00,0x10,0x00,0x08,0x00,0x20,0x00,0x09,0xEA,0x79,0x3C,0x1B,
+0xFF,0x60,0x00,0x10,0x00,0x0A,0x00,0x20,0x00,0x0B,0xEA,0x79,0x3C,0x1B,0xFF,0x5F,
+0x00,0x10,0x00,0x0C,0x3E,0x17,0xFE,0xBD,0x00,0x10,0x00,0x0D,0x3E,0x17,0xFE,0xBC,
+0x00,0x10,0x00,0x0E,0x3E,0x17,0xFE,0xBB,0x00,0x10,0x00,0x0F,0x3E,0x17,0xFE,0xBA,
+0x3E,0x18,0x01,0x20,0xA4,0x8A,0x00,0x30,0x00,0x10,0x9B,0x13,0x3C,0x4B,0xFF,0x5C,
+0x3C,0x3B,0xFF,0x5B,0xA4,0x48,0x00,0x30,0x00,0x11,0x9B,0x0B,0x3C,0x4B,0xFF,0x5A,
+0x3C,0x3B,0xFF,0x59,0x00,0x30,0x00,0x12,0x8A,0x43,0x3C,0x2B,0xFF,0x58,0x3C,0x3B,
+0xFF,0x57,0x00,0x20,0x00,0x13,0x8A,0x22,0x3C,0x1B,0xFF,0x56,0x3C,0x2B,0xFF,0x55,
+0x00,0x10,0x00,0x14,0x00,0x20,0x00,0x15,0xEA,0x79,0x3C,0x1B,0xFF,0x54,0x00,0x10,
+0x00,0x16,0x3C,0x1B,0xFF,0x53,0x00,0x10,0x00,0x17,0x3C,0x1B,0xFF,0x52,0x00,0x00,
+0x00,0x18,0x3C,0x0B,0xFF,0x51,0xFA,0x44,0x3E,0x0F,0xFF,0x00,0x84,0x20,0xDD,0x42,
+0x3E,0x6F,0xFF,0x20,0x3E,0x0F,0xFE,0xEC,0x84,0x20,0xFA,0x44,0xDD,0x42,0x80,0x06,
+0x84,0x3F,0x44,0x20,0x00,0x4C,0xDD,0x42,0x80,0x06,0x84,0x3F,0x44,0x20,0x00,0x4C,
+0xDD,0x42,0xEA,0xD9,0x84,0x20,0xFA,0x56,0xDD,0x42,0x46,0x01,0x00,0x01,0xEA,0xD8,
+0x84,0x20,0xFA,0x43,0xDD,0x42,0x3E,0x0F,0xFF,0x18,0x84,0x20,0x84,0x48,0xDD,0x42,
+0xFC,0x80,0xFC,0x00,0xEA,0x33,0x2E,0x67,0xFE,0x24,0x9E,0x71,0x96,0x48,0x5C,0xF0,
+0x80,0xFE,0xE8,0x23,0xC8,0x22,0x40,0x03,0x40,0x08,0x40,0x00,0x19,0x00,0x88,0x06,
+0x40,0x00,0x1B,0x00,0x95,0xB2,0xDD,0x4A,0x52,0x63,0x7F,0xF0,0x44,0x00,0x44,0xCC,
+0x40,0x00,0x1B,0x00,0xDD,0x4A,0x84,0xCC,0x8E,0xC1,0x84,0x1F,0x97,0xB0,0xDD,0x4A,
+0xCE,0xFC,0x84,0x0A,0x49,0xFF,0xD7,0xCA,0x3E,0x0F,0xFE,0x24,0x84,0x3F,0x84,0x41,
+0xDD,0x42,0x84,0x01,0x3E,0x07,0xFE,0xA0,0xFC,0x80,0x5A,0x08,0x08,0x14,0x5A,0x10,
+0x0C,0x1D,0xE6,0x2D,0xE8,0x08,0xE6,0x25,0xE9,0x17,0xE6,0x27,0xE9,0x0F,0x5A,0x10,
+0x09,0x15,0xD5,0x12,0x5A,0x10,0x2F,0x12,0x5A,0x10,0x79,0x0D,0x5A,0x10,0x1F,0x0E,
+0xD5,0x0B,0x5A,0x10,0xFF,0x0B,0x5A,0x10,0x79,0x06,0x5A,0x18,0x0D,0x07,0x84,0x27,
+0xD5,0x04,0x84,0x29,0xD5,0x02,0x84,0x28,0x80,0x01,0xDD,0x9E,0x2E,0x07,0xFE,0xA0,
+0xDD,0x9E,0x84,0x00,0x3E,0x07,0xFE,0xA0,0xDD,0x9E,0xE2,0x20,0xE8,0x03,0x8A,0x01,
+0xD5,0x02,0x9A,0x08,0x96,0x01,0xDD,0x9E,0xFC,0x60,0x80,0xE0,0xEA,0x5F,0x80,0xC1,
+0xE6,0x02,0xE8,0x0A,0x84,0x20,0x3E,0x17,0xFE,0x9F,0x3E,0x17,0xFE,0x9E,0x3E,0x17,
+0xFE,0x9D,0x3E,0x17,0xFE,0x9C,0x3C,0x13,0xFF,0xBC,0xE2,0x27,0xE8,0x07,0x3C,0x7B,
+0xFF,0xBC,0x3C,0x6B,0xFF,0xBD,0x3C,0x0B,0xFF,0x8F,0xEA,0xA2,0xE2,0xE1,0xE8,0x07,
+0x3C,0x7B,0xFF,0xB8,0x3C,0x6B,0xFF,0xB9,0x3C,0x0B,0xFF,0x8D,0x3C,0x13,0xFF,0xBB,
+0xE2,0x26,0xE8,0x07,0x3C,0x7B,0xFF,0xBA,0x3C,0x6B,0xFF,0xBB,0x3C,0x0B,0xFF,0x8E,
+0xEA,0xA0,0xE2,0xC1,0xE8,0x07,0x3C,0x7B,0xFF,0xB6,0x3C,0x6B,0xFF,0xB7,0x3C,0x0B,
+0xFF,0x8C,0x3C,0xA3,0xFF,0xBF,0x80,0x07,0x80,0x2A,0xDD,0x41,0x81,0x60,0x3C,0x93,
+0xFF,0xBE,0x80,0x06,0x80,0x29,0xDD,0x41,0x46,0x11,0x00,0x07,0x00,0x10,0x83,0x81,
+0xE2,0x2B,0xE9,0x04,0xE2,0x20,0x4E,0xF2,0x00,0x58,0xE3,0x47,0x2E,0x0F,0xFE,0x9D,
+0xE8,0x0B,0x2E,0x37,0xFE,0x9F,0xEB,0x42,0xEA,0x9C,0xE4,0x02,0x8C,0x21,0xEA,0x9F,
+0xE8,0x11,0x8C,0x01,0xD5,0x0D,0xE2,0xEA,0xE8,0x0D,0x2E,0x37,0xFE,0x9F,0xEB,0x42,
+0xEA,0x9C,0x5E,0xF0,0x7F,0xFF,0x8E,0x21,0xEA,0x9F,0xE9,0x04,0x8E,0x01,0x3E,0x07,
+0xFE,0x9D,0xE3,0x26,0x2E,0x0F,0xFE,0x9C,0xE8,0x0C,0x2E,0x37,0xFE,0x9E,0x3E,0x2F,
+0xFE,0xEC,0xEA,0x9C,0xE4,0x02,0x8C,0x21,0xEA,0x9F,0xE8,0x12,0x8C,0x01,0xD5,0x0E,
+0xE2,0xC9,0xE8,0x0E,0x2E,0x37,0xFE,0x9E,0x3E,0x2F,0xFE,0xEC,0xEA,0x9C,0x5E,0xF0,
+0x7F,0xFF,0x8E,0x21,0xEA,0x9F,0xE9,0x04,0x8E,0x01,0x3E,0x07,0xFE,0x9C,0x2E,0x0F,
+0xFE,0x9D,0xC8,0x0C,0x4C,0x75,0x00,0x0B,0x2E,0x07,0xFE,0x9F,0x8C,0x01,0x96,0x00,
+0xE6,0x0A,0xE9,0x02,0x84,0x09,0x3E,0x07,0xFE,0x9F,0x2E,0x0F,0xFE,0x9C,0xC8,0x0C,
+0x4C,0x64,0x80,0x0B,0x2E,0x07,0xFE,0x9E,0x8C,0x01,0x96,0x00,0xE6,0x0A,0xE9,0x02,
+0x84,0x09,0x3E,0x07,0xFE,0x9E,0xFC,0xE0,0xFC,0x61,0x83,0x80,0xEA,0x5F,0x81,0x41,
+0xE6,0x02,0x46,0xD1,0x00,0x01,0x58,0xD6,0x81,0x90,0x46,0xC1,0x00,0x01,0x58,0xC6,
+0x00,0x60,0xE8,0x13,0x84,0x40,0x3E,0x1F,0xFE,0x88,0x80,0x02,0x82,0x42,0xD5,0x11,
+0x38,0x02,0x0D,0x09,0x38,0x03,0x8D,0x09,0x80,0x66,0x5A,0x68,0x08,0x10,0x8C,0x50,
+0x19,0x20,0x80,0x01,0x5A,0x29,0x30,0x06,0x3E,0x8F,0xFE,0x88,0x85,0x20,0xD5,0x0E,
+0x84,0x60,0x40,0x46,0x88,0x00,0x40,0x76,0x08,0x00,0x9D,0x99,0xCB,0xEA,0x39,0xC6,
+0x88,0x09,0x38,0xA6,0x08,0x09,0x80,0x66,0xD5,0xF9,0x46,0x01,0x00,0x01,0xEA,0xD8,
+0x38,0x60,0x24,0x00,0x40,0xB4,0x8C,0x08,0x40,0x05,0x98,0x00,0x38,0x16,0x01,0x01,
+0x38,0x76,0x81,0x01,0xF1,0x81,0x3E,0x1F,0xFB,0x70,0x38,0xE0,0x80,0x00,0x80,0x1C,
+0x80,0x27,0xDD,0x41,0xE6,0x06,0xE9,0x0B,0x5A,0xE8,0x01,0x05,0x40,0x7E,0x1C,0x06,
+0xD5,0x07,0x5A,0xE8,0x03,0x05,0x40,0x73,0xF0,0x06,0xD5,0x02,0xEA,0xE4,0x80,0x0A,
+0xF1,0x01,0xDD,0x41,0xE6,0x06,0xE9,0x0D,0x5A,0xE8,0x02,0x06,0xF0,0x01,0x40,0x75,
+0x00,0x06,0xD5,0x07,0x5A,0xE8,0x04,0x06,0xF0,0x01,0xE2,0x0A,0xE9,0x04,0xD5,0x18,
+0x5A,0x78,0x01,0x16,0x00,0x04,0x00,0x00,0x8C,0x01,0x96,0x00,0x5A,0x08,0x02,0x18,
+0x8C,0xC1,0x84,0x00,0x96,0xB0,0x40,0x65,0x88,0x00,0x10,0x04,0x00,0x00,0x46,0x01,
+0x00,0x01,0xEA,0xD8,0x38,0x20,0x24,0x08,0xF8,0x04,0xD5,0x0B,0xCF,0x0A,0x88,0xCB,
+0x39,0xC6,0x99,0x09,0x38,0xA6,0x19,0x09,0x83,0xFF,0x84,0x00,0x10,0x04,0x00,0x00,
+0x8D,0x21,0x8D,0x01,0x5A,0x98,0x13,0xAB,0xFC,0xE1,0xFC,0x65,0x80,0xC0,0x3C,0xD3,
+0xFF,0xBF,0x3C,0xA3,0xFF,0xBE,0xEA,0x5F,0x80,0xE1,0xE6,0x02,0xE8,0x04,0x84,0x1F,
+0x3E,0x07,0xFE,0x87,0x40,0xF6,0x98,0x06,0xE9,0x04,0x44,0x90,0x00,0x40,0xD5,0x03,
+0x44,0x90,0x00,0x60,0x80,0x06,0x80,0x2D,0xDD,0x41,0xE3,0x47,0x81,0x60,0x85,0x00,
+0xE8,0x02,0xFB,0x10,0x80,0x07,0x80,0x2A,0xDD,0x41,0x80,0x80,0x46,0x01,0x00,0x07,
+0x00,0x00,0x03,0x80,0xB6,0x1F,0x02,0x5F,0x80,0x00,0xE2,0xAB,0xE9,0x03,0xE2,0xA4,
+0xE8,0x09,0x2E,0x07,0xFE,0x87,0x5A,0x08,0xFF,0x06,0xE2,0x8B,0xE8,0x1D,0x3E,0x97,
+0xFE,0x87,0xE2,0xCD,0x14,0xFF,0x80,0x02,0x40,0x16,0x98,0x06,0xF1,0x83,0xE3,0x47,
+0x2E,0x07,0xFE,0x87,0x14,0xFF,0x80,0x04,0xE2,0xEA,0xF0,0x81,0x3E,0xCF,0xFE,0xC4,
+0x3F,0xCF,0xFF,0x20,0x80,0x04,0x82,0xAB,0x85,0xC0,0x86,0x8C,0x14,0xFF,0x80,0x05,
+0x44,0xD0,0x00,0xFF,0xD5,0x06,0xE3,0x64,0xE8,0xE5,0x3E,0x87,0xFE,0x87,0xD5,0xE2,
+0x02,0xA6,0x00,0x00,0x5A,0xA0,0xFF,0x2A,0x02,0x1E,0x00,0x00,0xE2,0x26,0xE9,0x04,
+0x44,0x90,0x00,0x40,0xD5,0x03,0x44,0x90,0x00,0x60,0x80,0x06,0x15,0x4F,0x80,0x08,
+0xF5,0x87,0xF4,0x86,0xDD,0x41,0x02,0x1E,0x00,0x01,0x82,0xA0,0xE2,0x27,0xF4,0x06,
+0xF5,0x07,0x05,0x4F,0x80,0x08,0x85,0x00,0xE8,0x02,0xFB,0x10,0x80,0x07,0x15,0x4F,
+0x80,0x09,0xF5,0x88,0xF4,0x87,0x15,0x5F,0x80,0x06,0xDD,0x41,0x05,0x4F,0x80,0x09,
+0xF5,0x08,0xF4,0x07,0x05,0x5F,0x80,0x06,0x80,0x2A,0x42,0x17,0x50,0x73,0xEA,0xA8,
+0x38,0x11,0x04,0x00,0x40,0xF0,0x9C,0x09,0x5A,0xF8,0x01,0x19,0x5A,0xA0,0xFF,0x17,
+0x55,0x60,0x80,0x60,0x96,0x67,0xC1,0x05,0xB4,0x5F,0xFE,0x54,0x96,0x48,0xD5,0x02,
+0x80,0x2F,0x4D,0x64,0xC0,0x04,0xE2,0x35,0xD5,0x04,0x4D,0x64,0x40,0x08,0xE2,0x20,
+0xE8,0x05,0x50,0x25,0x00,0x01,0x12,0x26,0x00,0x00,0x02,0x16,0x00,0x00,0xC1,0x1E,
+0x5A,0x10,0xFF,0x1D,0xEA,0xA8,0x42,0x27,0x50,0x73,0xF8,0x33,0xC9,0x03,0xF1,0x05,
+0xD5,0x04,0x5A,0x18,0x20,0x06,0xF1,0x04,0xC1,0x11,0xCC,0x0C,0xD5,0x0F,0x5A,0x18,
+0x60,0x04,0xF1,0x03,0xD5,0x04,0x5A,0x18,0x40,0x0A,0xF1,0x02,0xC1,0x07,0x4E,0xB2,
+0x00,0x06,0x12,0x6E,0x00,0x00,0x12,0x7E,0x00,0x01,0x42,0x17,0x50,0x24,0xEA,0xA8,
+0x38,0x11,0x04,0x00,0xF2,0x01,0x54,0x10,0x80,0x60,0xFE,0x55,0x5A,0x18,0x20,0x04,
+0x12,0xD6,0x00,0x00,0x0A,0x16,0x00,0x01,0x42,0xA7,0x50,0x24,0xEA,0xA8,0x40,0x35,
+0x04,0x00,0x38,0x31,0x0C,0x00,0x92,0x67,0xCB,0x18,0x5A,0x10,0xFF,0x17,0x88,0x4A,
+0x88,0x22,0x00,0x10,0xFF,0xFF,0x54,0x10,0x80,0x60,0x83,0xFF,0x40,0x24,0x04,0x03,
+0x5A,0x28,0x20,0x04,0xE2,0xA0,0xE9,0x07,0x40,0x14,0x84,0x03,0x5A,0x18,0x20,0x06,
+0xE2,0xB5,0xE8,0x03,0x12,0xD6,0x7F,0xFF,0x50,0xE7,0x00,0x01,0x51,0xCE,0x00,0x04,
+0x5A,0xE0,0x13,0x04,0x48,0xFF,0xFF,0x5E,0xFC,0xE5,0xFC,0x60,0x80,0xA0,0x46,0x01,
+0x00,0x07,0x02,0x60,0x01,0xDC,0x46,0x01,0x00,0x07,0x02,0x70,0x01,0xDD,0xE6,0x42,
+0x81,0x41,0x81,0x22,0x97,0xB1,0x97,0xF9,0xE9,0x17,0x84,0x05,0x44,0x20,0x27,0x10,
+0xDD,0x5A,0x40,0x03,0x08,0x57,0x44,0x10,0x03,0xE8,0x96,0x91,0x40,0x21,0x04,0x57,
+0x44,0x0F,0xFC,0x18,0x42,0x61,0x00,0x73,0x8C,0x41,0x84,0x0A,0x40,0x21,0x00,0x16,
+0x42,0x60,0x04,0x73,0x97,0xB1,0x2E,0x07,0xFE,0x86,0xC0,0x20,0x5A,0x00,0x05,0x1F,
+0x5A,0x00,0x04,0x07,0x3C,0x03,0xFF,0x42,0x8C,0x01,0x3C,0x0B,0xFF,0x42,0xEB,0x40,
+0x3C,0x13,0xFF,0x5B,0xE2,0x20,0x4E,0xF2,0x00,0xE1,0x3C,0x13,0xFF,0x5C,0xE2,0x01,
+0x4E,0xF2,0x00,0xDC,0xEB,0x3F,0x3C,0x13,0xFF,0x59,0xE2,0x20,0x4E,0xF2,0x00,0xD6,
+0x3C,0x13,0xFF,0x5A,0xE2,0x01,0x4E,0xF2,0x00,0xD1,0x2E,0x27,0xFE,0x86,0xCA,0x15,
+0x5A,0x90,0x01,0x03,0xF8,0x4E,0xEA,0x29,0x4C,0x50,0x00,0xAE,0x3E,0x97,0xFE,0x86,
+0x3C,0x5B,0xFF,0x41,0x3C,0xAB,0xFF,0x40,0x3C,0x2B,0xFF,0x42,0x3C,0x2B,0xFF,0x3F,
+0x84,0x1F,0x3E,0x07,0xFC,0xF8,0xF8,0x3D,0x54,0x01,0x00,0xFD,0x5A,0x00,0x01,0x04,
+0x48,0x00,0x00,0x55,0x5A,0x98,0x01,0x38,0x80,0x25,0xEB,0x40,0xDD,0x41,0x2E,0xB7,
+0xFE,0xBA,0xE3,0x60,0xE9,0x06,0xEB,0x3F,0x80,0x2A,0xDD,0x41,0xE3,0x60,0xE8,0x13,
+0x84,0x05,0xDD,0x5A,0xDD,0x5C,0x40,0x13,0x00,0x17,0x84,0x2A,0x96,0x01,0x40,0x00,
+0x04,0x17,0x84,0x56,0x42,0x60,0x08,0x73,0x8C,0x01,0x40,0x00,0x04,0x56,0x42,0x60,
+0x88,0x73,0xD5,0x16,0x3C,0x13,0xFF,0x42,0x3C,0x23,0xFF,0x3F,0x2E,0x07,0xFE,0xBD,
+0x88,0x02,0xE0,0x01,0x4E,0xF2,0x00,0x70,0x84,0x05,0xDD,0x5A,0x84,0x0A,0x40,0x23,
+0x00,0x37,0x96,0x49,0x8A,0xC1,0x8C,0x21,0x40,0x00,0x80,0x36,0x88,0xC1,0x97,0xB1,
+0x48,0x00,0x00,0x62,0x4E,0x93,0x00,0x60,0x3C,0x03,0xFF,0x42,0x3C,0x33,0xFF,0x3F,
+0xE2,0x60,0xE8,0x11,0x2E,0x17,0xFE,0xBD,0x88,0x23,0xE0,0x20,0xE9,0x0C,0x84,0x22,
+0x5A,0x20,0x01,0x05,0x5A,0x28,0x03,0x05,0x84,0x24,0x3E,0x17,0xFE,0x86,0x3C,0x0B,
+0xFF,0x3F,0xD5,0x49,0x84,0x05,0xDD,0x5A,0xD5,0x46,0x5A,0x28,0x02,0x45,0x3C,0xB3,
+0xFF,0x42,0x3C,0x83,0xFF,0x3F,0xE3,0x68,0xE9,0x32,0x2E,0x07,0xFE,0xBC,0x88,0x08,
+0xE1,0x60,0xE8,0x2D,0x5A,0x98,0x01,0x38,0xEA,0x29,0xD0,0x35,0x80,0x25,0xEB,0x40,
+0xDD,0x41,0x2E,0xC7,0xFE,0xBA,0xE2,0x0C,0xE8,0x10,0xEB,0x3F,0x80,0x2A,0xDD,0x41,
+0xE2,0x0C,0xE8,0x0B,0x2E,0x07,0xFE,0xBB,0x88,0x08,0xE1,0x60,0xE9,0x06,0x84,0x03,
+0xDD,0x5A,0x3C,0xBB,0xFF,0x3F,0xD5,0x1F,0x84,0x05,0xDD,0x5A,0xDD,0x5C,0x40,0x13,
+0x80,0x17,0x84,0x2A,0x96,0x01,0x40,0x00,0x04,0x17,0x84,0x56,0x42,0x70,0x08,0x73,
+0x8C,0x01,0x40,0x00,0x04,0x56,0x42,0x70,0x88,0x73,0xD5,0x0C,0x84,0x05,0xDD,0x5A,
+0x84,0x0A,0x40,0x23,0x80,0x37,0x96,0x49,0x8A,0xE1,0x8C,0x21,0x40,0x00,0x80,0x36,
+0x88,0xE1,0x97,0xF9,0x2E,0x07,0xFE,0x86,0x5A,0x08,0x04,0x09,0x44,0x0F,0xFF,0x80,
+0x3E,0x07,0xFC,0xF8,0x84,0x00,0xDD,0x5A,0xD5,0x07,0x5A,0x08,0x05,0x06,0x4E,0x93,
+0x00,0x04,0x3E,0x97,0xFE,0x86,0x46,0x01,0x00,0x07,0x12,0x60,0x01,0xDC,0x46,0x01,
+0x00,0x07,0x12,0x70,0x01,0xDD,0xFC,0xE0,0x84,0x05,0x44,0x30,0x03,0xE8,0xDD,0x5A,
+0x40,0x03,0x0C,0x77,0xEA,0x2A,0x96,0xD9,0x40,0x31,0x84,0x77,0x44,0x0F,0xFF,0x9C,
+0x42,0x61,0x80,0x73,0x8C,0x61,0x84,0x0A,0x40,0x31,0x80,0x16,0x42,0x60,0x04,0x73,
+0x97,0xB1,0x48,0xFF,0xFF,0x1C,0xFC,0x00,0x84,0x00,0x3E,0x6F,0xFF,0x00,0x3E,0x5F,
+0xFE,0xEC,0x80,0x20,0x80,0x40,0x2A,0x43,0x00,0x01,0xC4,0x0E,0x22,0x33,0x00,0x00,
+0xC3,0x0B,0x42,0x42,0x00,0x03,0xE4,0x85,0xE9,0x07,0x42,0x31,0x80,0x03,0xE4,0x65,
+0xE9,0x03,0x8C,0x21,0x96,0x48,0x2A,0x42,0x80,0x01,0xC4,0x0E,0x22,0x32,0x80,0x00,
+0xC3,0x0B,0x42,0x42,0x00,0x03,0xE4,0x85,0xE9,0x07,0x42,0x31,0x80,0x03,0xE4,0x65,
+0xE9,0x03,0x8C,0x01,0x96,0x00,0x8C,0x41,0x96,0x90,0x5A,0x28,0x09,0xDE,0x8E,0x21,
+0xE6,0x22,0xE8,0x5C,0x8E,0x01,0xE6,0x02,0xE8,0x59,0xEA,0x36,0x3C,0x63,0xFF,0xBF,
+0xE2,0xC0,0xE8,0x03,0x9A,0x86,0xD5,0x02,0x9A,0xB0,0x46,0x11,0x00,0x07,0x00,0x10,
+0x83,0x82,0x46,0x31,0x00,0x07,0x00,0x31,0x83,0x83,0x40,0xF1,0x85,0x00,0xE0,0x4F,
+0xE8,0x45,0x3C,0x23,0xFF,0xC0,0xEA,0x9A,0xE2,0x22,0xE8,0x03,0x9A,0x51,0xD5,0x02,
+0x8A,0x22,0x46,0x21,0x00,0x07,0x00,0x21,0x03,0x84,0x46,0x31,0x00,0x07,0x00,0x31,
+0x83,0x85,0x40,0xF1,0x89,0x00,0xE0,0x2F,0xE8,0x31,0xEA,0xA2,0xDD,0x41,0x5C,0xF0,
+0x00,0x64,0xE8,0x08,0x80,0x06,0x3C,0x13,0xFF,0xBC,0xDD,0x41,0x5C,0xF0,0x00,0x64,
+0xE9,0x25,0x3C,0x43,0xFF,0x8F,0x3C,0x33,0xFF,0x8C,0x84,0x00,0x3E,0x2F,0xFF,0x18,
+0x80,0x20,0x40,0x31,0x90,0x06,0x5A,0x10,0x03,0x07,0xA5,0x10,0xA5,0x51,0xE2,0xA4,
+0xE8,0x05,0xD5,0x02,0xC3,0x03,0x8C,0x01,0xD5,0x02,0x8E,0x01,0x8C,0x21,0x96,0x48,
+0x96,0x02,0x8C,0x42,0x5A,0x18,0x04,0xF1,0x4E,0x07,0x00,0x04,0x84,0x01,0xD5,0x02,
+0x84,0x00,0x3E,0x07,0xFF,0x14,0x84,0x08,0xD5,0x02,0xEA,0x8D,0xFC,0x80,0xFC,0x60,
+0x80,0xE0,0x81,0x21,0x3C,0xA3,0xFF,0x5F,0x5A,0x10,0x0B,0x04,0x5A,0x18,0x07,0x1F,
+0x3C,0x07,0xFF,0x80,0xE4,0x05,0xE9,0x15,0x3C,0xF7,0xFF,0x81,0x5E,0xF7,0xFF,0xFC,
+0xE8,0x10,0x3C,0x07,0xFF,0x82,0xE4,0x05,0xE9,0x0C,0x3C,0x67,0xFF,0x83,0xCE,0x09,
+0x3C,0x07,0xFF,0x84,0xC8,0x07,0x3C,0x67,0xFF,0x85,0x5C,0x63,0x00,0x01,0xD5,0x02,
+0x84,0xC0,0xEA,0x36,0xEB,0x09,0xE2,0x20,0xF8,0x71,0xEB,0x78,0x58,0x10,0x81,0x90,
+0x94,0x3C,0x98,0x81,0x80,0x81,0x5A,0x98,0x0D,0x12,0x3C,0x13,0xFF,0xC1,0x3C,0x03,
+0xFF,0xBF,0xE2,0x20,0x4E,0xF2,0x02,0x3F,0xA4,0x50,0xA4,0x11,0xE2,0x20,0x4E,0xF2,
+0x02,0x3A,0xA4,0x52,0xA4,0x13,0x48,0x00,0x00,0xE5,0xEB,0x78,0x58,0x10,0x80,0x60,
+0x98,0xC1,0x5A,0x90,0x06,0x06,0x5A,0x90,0x09,0x04,0x48,0x00,0x00,0x52,0x38,0xA0,
+0x80,0x01,0xA4,0x19,0xE2,0x0A,0xE9,0x1C,0x3C,0x83,0xFF,0xBE,0x3C,0x63,0xFF,0xBB,
+0x80,0x08,0x80,0x26,0xDD,0x41,0x81,0x80,0x3C,0xB3,0xFF,0xB7,0x80,0x08,0x80,0x2B,
+0xDD,0x41,0xE2,0x0C,0xE9,0x0D,0x3C,0x83,0xFF,0xC0,0x80,0x26,0x80,0x08,0xDD,0x41,
+0x80,0xC0,0x80,0x2B,0x80,0x08,0xDD,0x41,0x40,0x63,0x00,0x06,0xD5,0x02,0x84,0xC1,
+0x5A,0x98,0x06,0x10,0xEA,0xFF,0xE3,0x40,0xE8,0x04,0x40,0x05,0x00,0x11,0xD5,0x02,
+0x96,0x03,0x96,0x01,0xEA,0xA0,0xDD,0x41,0xE6,0x1A,0x4E,0xF3,0x01,0xFA,0xF8,0x9A,
+0x5A,0x90,0x09,0x03,0xF9,0xAB,0x3C,0xB3,0xFF,0xBC,0x3C,0x93,0xFF,0xC1,0x80,0x0B,
+0x80,0x29,0xDD,0x41,0x81,0x80,0x3C,0xA3,0xFF,0xB8,0x80,0x29,0x80,0x0A,0xDD,0x41,
+0xE2,0x0C,0x4E,0xF3,0x01,0xE8,0x3C,0x93,0xFF,0xBF,0x80,0x0B,0x80,0x29,0xDD,0x41,
+0x81,0x60,0x80,0x29,0x80,0x0A,0xDD,0x41,0xE3,0x60,0x48,0x00,0x00,0xFD,0x5A,0x98,
+0x79,0x3A,0x3C,0xA3,0xFF,0xBC,0x3C,0x63,0xFF,0xC1,0x80,0x0A,0x80,0x26,0xDD,0x41,
+0x81,0x60,0x3C,0x93,0xFF,0xB8,0x80,0x26,0x80,0x09,0xDD,0x41,0xE2,0x0B,0x4E,0xF3,
+0x01,0xCA,0x3C,0x63,0xFF,0xBF,0x80,0x0A,0x80,0x26,0xDD,0x41,0x81,0x40,0x80,0x26,
+0x80,0x09,0xDD,0x41,0xE3,0x40,0x4E,0xF3,0x01,0xBE,0x3C,0x93,0xFF,0xB7,0x3C,0x63,
+0xFF,0xC0,0x80,0x09,0x80,0x26,0xDD,0x41,0x81,0x60,0x3C,0xA3,0xFF,0xBB,0x80,0x26,
+0x80,0x0A,0xDD,0x41,0xE2,0x0B,0x4E,0xF3,0x01,0xAE,0x3C,0x63,0xFF,0xBE,0x80,0x0A,
+0x80,0x26,0xDD,0x41,0x81,0x40,0x80,0x26,0x80,0x09,0xDD,0x41,0xE2,0x0A,0x48,0x00,
+0x01,0x9E,0x5A,0x98,0x3D,0x1F,0x84,0x40,0x80,0x22,0x80,0x02,0x3E,0x4F,0xFE,0xEC,
+0x38,0x32,0x09,0x11,0x4E,0x37,0x00,0x05,0x88,0x03,0x96,0x03,0xD5,0x03,0x88,0x23,
+0x96,0x4B,0x8C,0x41,0x5A,0x28,0x0A,0xF6,0x42,0xF0,0x00,0x03,0x42,0x20,0x80,0x03,
+0xE0,0x4F,0xE8,0x04,0x4E,0x13,0x01,0x87,0xF8,0xE4,0x4E,0x03,0x01,0x84,0xF8,0xE1,
+0x5A,0x98,0x05,0x24,0xEB,0x42,0x84,0x29,0x84,0x00,0x2A,0x41,0x00,0x01,0xC4,0x15,
+0x22,0x31,0x00,0x00,0xC3,0x12,0x42,0x52,0x00,0x03,0xE4,0xA5,0xE9,0x0E,0x42,0x51,
+0x80,0x03,0xE4,0xA5,0xE9,0x0A,0xC8,0x06,0x4E,0x44,0x00,0x08,0x40,0x00,0x0C,0x07,
+0xD5,0x04,0x5A,0x08,0x01,0x03,0x84,0x05,0x8E,0x21,0x96,0x48,0xC9,0xE7,0x5A,0x00,
+0x01,0x04,0x48,0x00,0x01,0x60,0xF8,0xBD,0x5A,0x98,0x0E,0x0E,0xA4,0x50,0xEA,0x36,
+0xE2,0x01,0x4E,0xF3,0x01,0x58,0xA4,0x12,0xE2,0x20,0x4E,0xF2,0x01,0x54,0xA4,0x51,
+0xE2,0x20,0xF8,0x49,0x5A,0x98,0x1F,0x21,0xA5,0x51,0xA5,0x12,0xE2,0x85,0x4E,0xF2,
+0x01,0x4A,0xA5,0x13,0x3C,0x63,0xFF,0xC1,0xE2,0xC4,0x4E,0xF2,0x01,0x44,0xA5,0x1C,
+0xEA,0xE0,0xE2,0x04,0x4E,0xF2,0x01,0x3F,0xA4,0x19,0xE2,0x04,0x4E,0xF2,0x01,0x3B,
+0xA4,0x1A,0xE2,0x04,0x4E,0xF2,0x01,0x37,0xA4,0x1B,0xE2,0x04,0x4E,0xF2,0x01,0x33,
+0xA4,0x15,0xE2,0x05,0xF8,0x28,0x5A,0x98,0x2F,0x29,0x3C,0x53,0xFF,0xC1,0x38,0x42,
+0x00,0x01,0xE2,0x85,0x4E,0xF2,0x01,0x27,0x3C,0x43,0xFF,0xC0,0xEA,0xE0,0xE2,0x80,
+0x4E,0xF2,0x01,0x21,0xA5,0x59,0xE2,0x05,0x4E,0xF2,0x01,0x1D,0xA4,0x12,0xA4,0x51,
+0xE2,0x01,0x4E,0xF2,0x01,0x18,0xA4,0x5A,0xE2,0x25,0x4E,0xF2,0x01,0x14,0x3C,0x23,
+0xFF,0xBF,0xE2,0x02,0x4E,0xF2,0x01,0x0F,0x3C,0x03,0xFF,0xBE,0xE2,0x01,0x4E,0xF2,
+0x01,0x0A,0xE2,0x80,0x48,0x00,0x00,0x64,0x5A,0x98,0x0C,0x29,0xEA,0xE0,0xA5,0x19,
+0x02,0xC1,0x80,0x02,0xE2,0x80,0x3C,0xA3,0xFF,0xC1,0x3C,0x83,0xFF,0xBF,0xE8,0x07,
+0xE2,0x8C,0xE8,0x05,0xE3,0x48,0x56,0x67,0x80,0x01,0xD5,0x02,0x84,0xC1,0xA4,0x52,
+0x80,0x0A,0xDD,0x41,0x81,0x20,0x3C,0xB3,0xFF,0xC0,0x80,0x2C,0x80,0x0B,0xDD,0x41,
+0x89,0x20,0x80,0x28,0x80,0x0A,0xDD,0x41,0x81,0x40,0xEA,0x9A,0x80,0x0B,0xDD,0x41,
+0x88,0x0A,0xE0,0x09,0x4E,0xF3,0x00,0xDF,0xF8,0x91,0x5A,0x90,0x0A,0x04,0x5A,0x98,
+0x1D,0x1C,0x84,0x40,0x80,0x22,0x80,0x02,0x3E,0x4F,0xFF,0x00,0x38,0x32,0x09,0x11,
+0x4E,0x37,0x00,0x05,0x88,0x03,0x96,0x03,0xD5,0x03,0x88,0x23,0x96,0x4B,0x8C,0x41,
+0x5A,0x28,0x0A,0xF6,0x42,0x00,0x00,0x03,0xEB,0x14,0xE0,0x20,0xE8,0x03,0xE4,0x24,
+0xD5,0x1E,0xE0,0x01,0xD5,0x19,0x5A,0x98,0x2D,0x1F,0x84,0x40,0x80,0x02,0x80,0x22,
+0x3E,0x3F,0xFE,0xEC,0x38,0xF1,0x89,0x11,0x4E,0xF7,0x00,0x05,0x88,0x2F,0x96,0x4B,
+0xD5,0x03,0x88,0x0F,0x96,0x03,0x8C,0x41,0x5A,0x28,0x0A,0xF6,0x42,0x00,0x00,0x03,
+0x42,0xF0,0x80,0x03,0xE0,0x0F,0x4E,0xF2,0x00,0xAB,0xE4,0x04,0x4E,0xF2,0x00,0xA3,
+0x48,0x00,0x00,0xA6,0x8F,0x21,0xE7,0x24,0x4E,0xF2,0x00,0xA2,0x84,0x00,0x80,0xC0,
+0x81,0x20,0x81,0x60,0x81,0x00,0x3E,0x4F,0xFF,0x00,0x3E,0x5F,0xFE,0xEC,0x38,0x32,
+0x01,0x11,0x94,0x41,0xE4,0x65,0xE9,0x05,0x88,0x6B,0x40,0xB1,0x80,0x11,0xD5,0x07,
+0x5E,0xF1,0xFF,0xFC,0xE8,0x04,0x88,0x69,0x40,0x91,0x80,0x11,0x38,0x12,0x84,0x11,
+0xE4,0x25,0xE9,0x06,0x40,0x20,0xA0,0x00,0x40,0x81,0x00,0x11,0xD5,0x06,0x5E,0xF0,
+0xFF,0xFC,0xE8,0x03,0x88,0xC1,0x97,0xB3,0x8C,0x01,0x5A,0x08,0x0A,0xE2,0xEA,0xD9,
+0x38,0x10,0x1D,0x01,0x84,0x4C,0x3E,0x0F,0xFC,0x08,0x42,0x03,0x88,0x73,0x88,0x01,
+0x00,0x00,0x7F,0xFF,0x54,0x00,0x00,0x60,0xC8,0x1B,0xEA,0x9A,0xEA,0xFF,0xE2,0x20,
+0x4E,0xF2,0x00,0x61,0xDD,0x41,0x3C,0x13,0xFF,0x60,0xE2,0x20,0x4E,0xF2,0x00,0x5B,
+0x3C,0x03,0xFF,0xBC,0xEA,0xA2,0xDD,0x41,0xE2,0x0A,0x4E,0xF2,0x00,0x54,0x4E,0x83,
+0x00,0x52,0x8C,0xC3,0x97,0xB1,0x5C,0x63,0x00,0x07,0x48,0x00,0x00,0x4A,0x5A,0x08,
+0x20,0x18,0xEA,0xFF,0xEA,0x9A,0xE2,0x01,0x4E,0xF2,0x00,0x45,0xDD,0x41,0x3C,0x13,
+0xFF,0x60,0xE2,0x20,0xE8,0x3F,0x3C,0x03,0xFF,0xBC,0xEA,0xA2,0xDD,0x41,0xE2,0x0A,
+0xE8,0x39,0xE5,0x04,0xE9,0x37,0x84,0x20,0x40,0x60,0x98,0x06,0xD5,0x31,0x5A,0x08,
+0x60,0x17,0xEB,0x09,0xEA,0x36,0xE2,0x01,0xE8,0x2D,0xDD,0x41,0x3C,0x13,0xFF,0x61,
+0xE2,0x20,0xE8,0x28,0x3C,0x03,0xFF,0xBB,0xEA,0xA0,0xDD,0x41,0xE2,0x0A,0xE8,0x22,
+0xE5,0x64,0xE9,0x20,0x84,0x20,0x40,0x60,0xA4,0x06,0xD5,0x1A,0x5A,0x08,0x40,0x20,
+0xEA,0x36,0xEB,0x09,0xE2,0x20,0xE8,0x16,0xDD,0x41,0x3C,0x13,0xFF,0x61,0xE2,0x20,
+0xE8,0x11,0x3C,0x03,0xFF,0xBB,0xEA,0xA0,0xDD,0x41,0xE2,0x0A,0xE8,0x0B,0x4E,0xB3,
+0x00,0x0A,0x50,0x64,0x80,0x03,0x97,0xB1,0xE6,0xC7,0xE9,0x04,0xD5,0x08,0x5A,0x68,
+0x01,0x07,0x44,0x10,0x00,0xFF,0xEA,0xD9,0x38,0x10,0x1D,0x09,0xFC,0xE0,0xFC,0x64,
+0x84,0x20,0xB0,0x02,0xFA,0x48,0xDD,0x42,0x84,0x00,0x3E,0x4F,0xFE,0xC4,0x3E,0x3F,
+0xFC,0x08,0x84,0xAC,0x38,0x12,0x01,0x01,0x3E,0xDF,0xFE,0xC4,0x5A,0x10,0xFF,0x13,
+0x42,0x20,0x14,0x24,0x99,0x91,0x38,0x61,0x98,0x10,0x4E,0x65,0x00,0x0C,0x88,0x43,
+0x88,0x22,0xA6,0x89,0xB0,0x42,0x38,0x10,0x88,0x00,0xB1,0x82,0x8C,0x21,0x38,0x13,
+0x08,0x08,0x8C,0x01,0x5A,0x08,0x13,0xE8,0x84,0x00,0xB0,0x42,0x38,0x10,0x80,0x00,
+0x97,0x00,0xC1,0x0A,0x84,0xC0,0x81,0x26,0xEA,0xE4,0x3F,0xCF,0xFE,0xC4,0x3E,0xBF,
+0xFC,0x08,0x85,0xCC,0xD5,0x12,0x8C,0x01,0x5A,0x08,0x18,0xF1,0xEA,0x8D,0xD5,0x35,
+0x42,0xC3,0x38,0x24,0x40,0x06,0x08,0x00,0x38,0x15,0x80,0x00,0x96,0x0A,0x4E,0x04,
+0x00,0x0D,0x8C,0xC1,0x5A,0x60,0x13,0x23,0x38,0x26,0x99,0x01,0x54,0x83,0x00,0xFF,
+0x94,0xF1,0x5A,0x28,0xFF,0xEF,0xD5,0xF6,0x40,0x05,0xB0,0x00,0x88,0x40,0xA7,0x51,
+0xDC,0xF1,0x80,0x08,0xF3,0x81,0xB6,0x9F,0x49,0xFF,0xFD,0x33,0xF3,0x01,0xB4,0x9F,
+0x38,0x2E,0x0C,0x01,0x5A,0x20,0xFF,0xE7,0x50,0x14,0x80,0x01,0x88,0x4C,0x54,0x90,
+0x80,0xFF,0x38,0x75,0x88,0x00,0x81,0x48,0xD5,0xDD,0x5A,0x98,0x01,0xD1,0x38,0x06,
+0xA9,0x01,0x5A,0x00,0xFF,0xCD,0x80,0x07,0xFC,0xE4,0xFC,0x42,0xB0,0xC2,0x97,0x81,
+0x97,0xC9,0x3A,0x01,0x84,0x20,0x81,0x42,0xFD,0x03,0x49,0xFF,0xFB,0x58,0x5A,0xA8,
+0x01,0x3C,0x9E,0x31,0x96,0x01,0x44,0x10,0xFF,0xFD,0xE2,0x20,0x4E,0xF3,0x00,0x50,
+0xEA,0x36,0xC8,0x15,0x3C,0x93,0xFF,0xC0,0x4E,0x93,0x00,0x12,0xF8,0x5F,0x80,0x09,
+0x3E,0x1F,0xFF,0x20,0x38,0x60,0x80,0x09,0x98,0x81,0x8C,0x04,0xAD,0xD1,0x5A,0x08,
+0x4C,0xFB,0x3C,0x6B,0xFF,0xC1,0x3C,0x7B,0xFF,0xC0,0xD5,0x19,0x46,0x11,0x00,0x07,
+0x00,0x10,0x83,0x9B,0x46,0x21,0x00,0x07,0xEA,0x5F,0x00,0x21,0x03,0x9C,0x40,0xF1,
+0x05,0x00,0xE0,0x0F,0xE8,0x03,0x8C,0x01,0xEA,0xD5,0xFD,0x03,0x49,0xFF,0xF9,0x06,
+0xFD,0x03,0x49,0xFF,0xFA,0x2C,0xFD,0x03,0x49,0xFF,0xF9,0xA0,0x3C,0x6B,0xFF,0xBF,
+0x3C,0x7B,0xFF,0xBE,0xD5,0x1C,0x4E,0xA3,0x00,0x1F,0xEA,0x96,0xC0,0x09,0x2E,0x07,
+0xFC,0xF8,0x5A,0x00,0xFF,0x16,0x84,0x3F,0x3E,0x17,0xFC,0xF8,0xD5,0x11,0xEA,0x36,
+0xC0,0xF7,0x49,0xFF,0xFC,0x3A,0xB6,0x1F,0x49,0xFF,0xFF,0x3B,0xF0,0x81,0xF1,0x01,
+0xB4,0x1F,0x49,0xFF,0xF8,0xB4,0x5A,0x08,0xFF,0x04,0xD5,0xEA,0xEA,0x8D,0xEA,0xFD,
+0x5A,0x18,0x01,0x12,0x46,0x11,0x00,0x07,0x00,0x10,0x83,0x9B,0x46,0x21,0x00,0x07,
+0xEA,0x5F,0x00,0x21,0x03,0x9C,0x40,0xF1,0x05,0x00,0xE0,0x0F,0xE8,0x03,0x8C,0x01,
+0xEA,0xD5,0xEA,0x8D,0x4E,0xA3,0x00,0x06,0xB6,0x1F,0x49,0xFF,0xF7,0xCB,0xB4,0x1F,
+0xFC,0xC2,0x3E,0x1F,0xFE,0x64,0xA6,0x08,0xFA,0x56,0xA6,0x49,0x8E,0x01,0x42,0x10,
+0x08,0x73,0xEB,0x64,0x58,0x00,0x01,0x44,0x50,0x40,0x91,0xB8,0x40,0x40,0x10,0x20,
+0xA5,0x62,0x3E,0x28,0x02,0xF4,0x97,0x6B,0xAD,0x50,0x9C,0xE4,0xA5,0x21,0x50,0x10,
+0x94,0xB0,0x97,0x23,0xAD,0x15,0xA5,0x19,0x40,0x00,0x04,0x20,0x97,0x23,0xAD,0x16,
+0x02,0x41,0x80,0x26,0x3E,0x18,0x02,0xE0,0x97,0x23,0xAD,0x14,0x02,0x41,0x80,0x25,
+0x97,0x23,0xAD,0x12,0x02,0x41,0x80,0x27,0x97,0x23,0xAD,0x13,0x02,0x41,0x80,0x4C,
+0x97,0x23,0xAD,0x11,0x02,0x41,0x80,0x4B,0x97,0x23,0xAD,0x17,0x02,0x31,0x80,0x4D,
+0x96,0xDB,0x12,0x31,0x00,0x08,0xA4,0xC2,0x9C,0x84,0x96,0xDB,0xAC,0xC8,0xA4,0x01,
+0x96,0x03,0xAC,0x0D,0xA4,0x11,0x96,0x03,0xAC,0x0E,0x02,0x01,0x00,0x26,0x96,0x03,
+0xAC,0x0C,0x02,0x01,0x00,0x25,0x96,0x03,0xAC,0x0A,0x02,0x01,0x00,0x27,0x96,0x03,
+0xAC,0x0B,0x02,0x01,0x00,0x4C,0x96,0x03,0xAC,0x09,0x02,0x01,0x00,0x4B,0x96,0x03,
+0xAC,0x0F,0x02,0x01,0x00,0x4D,0x96,0x03,0x12,0x00,0x80,0x08,0xDD,0x9E,0x00,0x00,
+0x46,0x21,0x00,0x01,0x58,0x21,0x0F,0xDC,0x38,0x31,0x05,0x00,0x38,0x31,0x01,0x08,
+0x40,0x31,0x04,0x20,0xA6,0xD9,0x40,0x21,0x00,0x20,0xAE,0xD1,0x46,0x21,0x00,0x01,
+0xEB,0x36,0x38,0x31,0x06,0x02,0x38,0x31,0x02,0x0A,0x84,0x4C,0x42,0x30,0x08,0x24,
+0xFE,0x8C,0x46,0x41,0x00,0x02,0x58,0x42,0x00,0xB4,0x99,0x63,0x88,0x82,0x3B,0x02,
+0x48,0x00,0x46,0x41,0x00,0x02,0x58,0x42,0x00,0x24,0x88,0x44,0x3B,0x02,0xC8,0x20,
+0x88,0x64,0x3B,0x01,0x48,0x00,0x3E,0x28,0x01,0xCC,0x3B,0x01,0xC8,0x20,0x40,0x11,
+0x04,0x40,0xEA,0xDA,0x3A,0x10,0x84,0x00,0x3A,0x10,0x04,0x20,0xDD,0x9E,0x92,0x00,
+0x84,0x20,0x46,0x21,0x00,0x01,0xEB,0x36,0x38,0x11,0x02,0x0A,0x84,0x4C,0xFE,0x84,
+0x46,0x31,0x00,0x02,0x58,0x31,0x80,0xB4,0x88,0x62,0xB6,0x23,0xA8,0x59,0xA8,0x5A,
+0x46,0x31,0x00,0x02,0x58,0x31,0x80,0x24,0x88,0x43,0xB6,0x22,0xA8,0x51,0xA8,0x52,
+0x2E,0x37,0xFD,0x05,0x3E,0x28,0x01,0xCC,0x38,0x31,0x02,0x08,0xEA,0xDA,0xAE,0x41,
+0xAE,0x42,0x2E,0x17,0xFD,0x16,0xAE,0x43,0xDD,0x9E,0x92,0x00,0x3B,0xFF,0xFC,0xBC,
+0x51,0xFF,0xFF,0xFC,0x49,0xFF,0xFF,0x3F,0x3C,0x00,0x01,0x7E,0x96,0x03,0x4E,0x05,
+0x00,0xAF,0x3C,0x20,0x01,0x7E,0x80,0xA2,0x46,0x11,0x00,0x01,0x2E,0x07,0xFE,0x65,
+0x00,0x10,0x8F,0xF3,0xE2,0x20,0xE8,0x49,0x9A,0x41,0xE4,0x22,0x4E,0xF3,0x00,0x4A,
+0x2E,0x17,0xFE,0x64,0x46,0x31,0x00,0x02,0x04,0x31,0x80,0x2C,0x98,0x93,0x46,0x31,
+0x00,0x02,0x04,0x41,0x80,0x2A,0x46,0x31,0x00,0x02,0x04,0x31,0x80,0x2B,0xF8,0x52,
+0x46,0x51,0x00,0x02,0x14,0x22,0x80,0x2C,0x46,0x21,0x00,0x02,0x14,0x41,0x00,0x2A,
+0x46,0x21,0x00,0x02,0x14,0x31,0x00,0x2B,0x2E,0x20,0x01,0xF9,0xE2,0x40,0xE8,0x5D,
+0x3E,0x00,0x01,0xF9,0x2E,0x20,0x01,0xFA,0xE2,0x41,0xE8,0x4F,0x3E,0x10,0x01,0xFA,
+0xFA,0x56,0x42,0x00,0x88,0x73,0x46,0x11,0x00,0x02,0xEB,0x17,0x50,0x00,0x14,0xB0,
+0x94,0x01,0x88,0x01,0x22,0x10,0x00,0x02,0x5A,0x10,0xFE,0x50,0xEA,0x4F,0x2E,0x27,
+0xFE,0x64,0xAC,0xC2,0x2E,0x17,0xFE,0x65,0x3E,0x27,0xFE,0x60,0xEC,0x04,0x3E,0x17,
+0xFE,0x61,0x3B,0xFF,0xFC,0x84,0xDD,0x9E,0x8A,0x20,0xE4,0x22,0x4E,0xF2,0xFF,0xBA,
+0x46,0x31,0x00,0x01,0x2E,0x17,0xFE,0x64,0x00,0x31,0x8F,0xF2,0xE2,0x61,0xE8,0x53,
+0x9A,0xCB,0xE4,0x62,0x4E,0xF2,0xFF,0xB0,0x46,0x31,0x00,0x02,0x04,0x31,0x80,0x50,
+0x88,0x43,0x46,0x31,0x00,0x02,0x04,0x41,0x80,0x4E,0x46,0x31,0x00,0x02,0x04,0x31,
+0x80,0x4F,0x42,0x42,0x80,0x73,0x42,0x32,0x84,0x73,0x4A,0x00,0x00,0x60,0x46,0x51,
+0x00,0x02,0x14,0x22,0x80,0x50,0x46,0x21,0x00,0x02,0x14,0x41,0x00,0x4E,0x46,0x21,
+0x00,0x02,0x14,0x31,0x00,0x4F,0xD5,0xA9,0x2E,0x20,0x01,0xFB,0xE2,0x22,0xE8,0xB1,
+0x3E,0x10,0x01,0xFB,0x48,0xFF,0xFF,0xAE,0x2E,0x20,0x01,0xF8,0xE2,0x02,0xE8,0xA3,
+0x3E,0x00,0x01,0xF8,0x48,0xFF,0xFF,0xA0,0x2E,0x27,0xFD,0x36,0x46,0x11,0x00,0x02,
+0x04,0x10,0x80,0x08,0x8C,0x21,0xEA,0x4F,0xAC,0xC2,0xE2,0x41,0xEB,0x64,0x14,0x10,
+0x00,0x08,0xE8,0x17,0x2E,0x17,0xFE,0x64,0x2E,0x07,0xFE,0x65,0x3E,0x17,0xFE,0x60,
+0xEC,0x04,0x3E,0x07,0xFE,0x61,0x3B,0xFF,0xFC,0x84,0xDD,0x9E,0x84,0xA0,0x84,0x40,
+0x48,0xFF,0xFF,0x54,0x8A,0x61,0xE4,0x62,0x4E,0xF2,0xFF,0x5E,0x48,0xFF,0xFF,0xAE,
+0x49,0xFF,0xCE,0xF3,0xC8,0xE8,0xDD,0x5B,0xC1,0x1C,0x3C,0x00,0x01,0x70,0xEA,0xA6,
+0x97,0x43,0xD2,0x17,0xEA,0x22,0xEA,0x80,0xEB,0x1E,0x4E,0x00,0x00,0x56,0xE9,0x11,
+0x8E,0x21,0xDD,0x51,0x49,0xFF,0xFF,0x2C,0x2E,0x07,0xFE,0x60,0x50,0x00,0x00,0x01,
+0x2E,0x17,0xFE,0x61,0x3E,0x07,0xFE,0x64,0xEA,0x7A,0xEA,0x2D,0x2E,0x17,0xFE,0x64,
+0xEA,0xE7,0x8E,0x01,0xE0,0x20,0xE8,0x19,0x3C,0x00,0x01,0x71,0xEA,0xA6,0x97,0x43,
+0xD2,0x14,0xEA,0x22,0xEA,0x80,0xEB,0x1D,0xF8,0x37,0xE9,0x0F,0x9C,0x49,0xDD,0x51,
+0x49,0xFF,0xFF,0x0E,0x2E,0x07,0xFE,0x60,0x50,0x00,0x7F,0xFF,0x2E,0x17,0xFE,0x61,
+0x3E,0x07,0xFE,0x64,0xEA,0x7A,0xEA,0x2D,0xEA,0xCC,0xC1,0x19,0x3C,0x00,0x01,0x72,
+0xEA,0xA6,0x97,0x43,0xD2,0x14,0xEA,0x22,0xEA,0x80,0x3C,0x30,0x01,0x7C,0xF8,0x1C,
+0xE9,0x0E,0x9E,0x49,0xEA,0x7A,0xEA,0x25,0xEA,0x44,0xEA,0x41,0x50,0x00,0x00,0x01,
+0xDD,0x51,0xEA,0x46,0x49,0xFF,0xFE,0x2F,0x2E,0x17,0xFE,0x65,0xEA,0xC5,0x8E,0x01,
+0xE0,0x20,0xE8,0x1B,0x3C,0x00,0x01,0x73,0xEA,0xA6,0x97,0x43,0xD2,0x16,0xEA,0x22,
+0xEA,0x80,0x3C,0x30,0x01,0x7D,0x96,0x03,0x96,0xDB,0x88,0x02,0xE0,0x03,0x83,0xFF,
+0xE9,0x0C,0x9C,0x49,0xEA,0x7A,0xEA,0x25,0xEA,0x44,0xEA,0x41,0x50,0x00,0x7F,0xFF,
+0xDD,0x51,0xEA,0x46,0x49,0xFF,0xFE,0x0F,0xDD,0x5B,0x4E,0x12,0x00,0x51,0xEA,0x83,
+0xC2,0x20,0x3C,0x00,0x01,0x75,0xEA,0x4F,0x97,0x43,0xD3,0x1B,0xEA,0x22,0xEA,0x78,
+0xEB,0x1E,0xF8,0x75,0xE9,0x16,0xEA,0xA1,0x3C,0x00,0x01,0x7C,0xF8,0x7A,0xE9,0x11,
+0x3C,0x00,0x01,0x7A,0x3C,0x40,0x01,0x7C,0x3C,0x50,0x01,0x7F,0x97,0x23,0x96,0x03,
+0xEA,0xA7,0x88,0x04,0x88,0x03,0x97,0x2B,0x40,0xF0,0x10,0x07,0x4E,0xF2,0x00,0xA6,
+0xEA,0xC5,0x8E,0x01,0xE0,0x40,0xE8,0x2B,0x3C,0x00,0x01,0x76,0xEA,0x4F,0x97,0x43,
+0xD3,0x26,0xEA,0x22,0xEA,0x78,0xEB,0x1E,0xF8,0x52,0xE9,0x21,0xEA,0xA1,0x3C,0x00,
+0x01,0x7D,0xF8,0x57,0xE9,0x1C,0x3C,0x00,0x01,0x7A,0x3C,0x40,0x01,0x7D,0x3C,0x50,
+0x01,0x80,0x97,0x23,0x96,0x03,0xEA,0xA7,0x4E,0x00,0x00,0x5C,0xE9,0x10,0x8E,0x21,
+0x8C,0x41,0xDD,0x51,0xEA,0xBC,0xEA,0x25,0xEA,0x41,0xEA,0x44,0x8C,0x21,0x8E,0x01,
+0xDD,0x51,0xEA,0x46,0x49,0xFF,0xFD,0xBF,0x2E,0x17,0xFE,0x64,0xEA,0xE7,0x8E,0x01,
+0xE0,0x20,0x4E,0xF2,0xFF,0x21,0xEA,0x83,0xC2,0x1C,0x3C,0x00,0x01,0x77,0xEA,0x4F,
+0x97,0x43,0xD3,0x17,0xEA,0x22,0xEA,0x78,0xEB,0x1D,0xF8,0x21,0xE9,0x12,0xEA,0xA1,
+0x3C,0x00,0x01,0x7C,0xF8,0x26,0xE9,0x0D,0x3C,0x00,0x01,0x7B,0x3C,0x40,0x01,0x7C,
+0x3C,0x50,0x01,0x81,0x97,0x23,0x96,0x03,0xEA,0xA7,0x4E,0x00,0x00,0x2B,0xE8,0x3D,
+0xEA,0xC5,0x8E,0x01,0xE0,0x40,0x4E,0xF2,0xFE,0xFF,0x3C,0x00,0x01,0x78,0xEA,0x4F,
+0x97,0x43,0x4C,0x51,0xBE,0xF9,0xEA,0x22,0xEA,0x78,0xEB,0x1D,0x96,0x03,0x96,0xDB,
+0x88,0x04,0xE0,0x03,0x83,0xFF,0x4E,0xF3,0xFE,0xEF,0xEA,0xA1,0x3C,0x00,0x01,0x7D,
+0x96,0xDB,0x97,0x43,0x98,0x23,0xE0,0x05,0x83,0xFF,0x4E,0xF3,0xFE,0xE5,0x3C,0x00,
+0x01,0x7B,0x3C,0x40,0x01,0x7D,0x3C,0x50,0x01,0x82,0x97,0x23,0x96,0x03,0xEA,0xA7,
+0x88,0x04,0x88,0x03,0x97,0x2B,0xE0,0x04,0x83,0xFF,0x4E,0xF3,0xFE,0xD5,0x8C,0x21,
+0x9C,0x91,0xDD,0x51,0xEA,0xBC,0xEA,0x25,0xEA,0x41,0xEA,0x44,0x8E,0x21,0x8E,0x01,
+0xDD,0x51,0xEA,0x46,0x48,0xFF,0xFE,0xC8,0x8C,0x21,0x8E,0x41,0xDD,0x51,0xEA,0xBC,
+0x49,0xFF,0xFE,0x16,0xEA,0x41,0xEA,0x44,0x8E,0x21,0x8C,0x01,0xDD,0x51,0xEA,0x46,
+0x49,0xFF,0xFD,0x51,0xEA,0xE7,0xDD,0x5B,0x8E,0x01,0x40,0x00,0x80,0x07,0x4E,0x02,
+0xFE,0xB3,0xEA,0x83,0x48,0xFF,0xFF,0xAE,0x8E,0x21,0x50,0x21,0x7F,0xFF,0xDD,0x51,
+0xEA,0xBC,0xEA,0x25,0xEA,0x41,0xEA,0x44,0x8C,0x21,0x8C,0x01,0xDD,0x51,0xEA,0x46,
+0x49,0xFF,0xFD,0x39,0xDD,0x5B,0x4E,0x12,0xFF,0x7B,0xEA,0x83,0x48,0xFF,0xFF,0x4A,
+0x84,0x00,0x46,0x11,0x00,0x05,0x12,0x00,0x82,0xD4,0x46,0x11,0x00,0x05,0x12,0x00,
+0x82,0xD5,0x2E,0x20,0x01,0x29,0x2E,0x10,0x01,0x28,0x2E,0x37,0xFD,0x2A,0x3A,0x6F,
+0xB4,0x3C,0x2F,0x37,0xFD,0x26,0x84,0x80,0x44,0x90,0x00,0x48,0x47,0x11,0x00,0x02,
+0x59,0x18,0x81,0x44,0x44,0xA0,0x00,0x4C,0x44,0xB0,0x00,0xFE,0x47,0x21,0x00,0x01,
+0x59,0x29,0x0E,0xB0,0x96,0x20,0xE2,0x02,0xE8,0x36,0x80,0xD1,0x80,0xF1,0x42,0x62,
+0x24,0x73,0x42,0x72,0x28,0x73,0x50,0x63,0x19,0x54,0x50,0x73,0xA9,0xB2,0x84,0xA0,
+0x51,0x00,0x00,0x01,0xD1,0x1E,0xA4,0x30,0x8C,0xA1,0x96,0x03,0xE0,0x60,0xE8,0x15,
+0x12,0xB3,0x80,0x00,0xEB,0x4E,0xEA,0xA4,0x40,0xC9,0x00,0x20,0x5C,0xF0,0x00,0x95,
+0x39,0x09,0x01,0x08,0x10,0x56,0x00,0x01,0xE8,0x04,0x8C,0x01,0x40,0x00,0x00,0x13,
+0x46,0xC1,0x00,0x05,0x12,0x06,0x02,0xD4,0x8C,0xC2,0x97,0x68,0x8C,0xE2,0xD5,0xE3,
+0xEB,0x4E,0xEA,0xA4,0x8C,0x81,0xE2,0x13,0xE9,0xCE,0x84,0x01,0xEA,0xF8,0x44,0x00,
+0x00,0x00,0xEA,0x64,0x2E,0x60,0x00,0xFF,0x4E,0x63,0x00,0x0E,0xEB,0x4E,0x02,0x50,
+0x02,0xD5,0xEA,0xD1,0x9F,0x01,0x2E,0x00,0x00,0x11,0x8E,0x01,0xFE,0x24,0xE0,0xA0,
+0xE9,0x26,0xD5,0x23,0x44,0x00,0x00,0x64,0xFF,0x84,0x41,0x00,0x84,0x08,0xEB,0x54,
+0xEA,0xAC,0x84,0xA0,0xD2,0xEC,0x80,0x80,0x41,0x10,0x40,0x00,0x4C,0x48,0x80,0x11,
+0xA5,0xE0,0x97,0xFB,0xE0,0xC7,0xE8,0x0A,0x46,0x71,0x00,0x05,0x02,0x73,0x82,0xD5,
+0x46,0x91,0x00,0x05,0x8C,0xE1,0x12,0x74,0x82,0xD5,0x8C,0x82,0xD5,0xF0,0x8C,0xA1,
+0x97,0x68,0x50,0x00,0x00,0x48,0xD5,0xE7,0x48,0x00,0x00,0x00,0x2E,0x08,0x00,0x14,
+0x4E,0x04,0x00,0x4E,0x46,0x51,0x00,0x02,0x58,0x52,0x81,0x44,0x9D,0xC9,0x84,0x00,
+0x8C,0x41,0x45,0x00,0x00,0x4C,0x82,0x25,0x44,0x60,0x00,0xFC,0xFB,0xD6,0xE0,0x40,
+0xE9,0x1A,0x80,0x85,0x42,0x40,0x40,0x73,0x22,0xF2,0x11,0xBA,0xE0,0x6F,0xE8,0x03,
+0x12,0x62,0x14,0xB2,0x80,0x87,0x42,0x40,0x48,0x73,0x41,0x38,0x90,0x20,0x22,0xF9,
+0x91,0xBA,0xE0,0x6F,0xE8,0x05,0x40,0x42,0x90,0x20,0x12,0x62,0x14,0xB2,0x8C,0x01,
+0x96,0x00,0xD5,0xE6,0x46,0x41,0x00,0x02,0x58,0x42,0x01,0x44,0xFA,0xB6,0x8C,0x21,
+0x84,0x00,0x80,0xE4,0x44,0x60,0x00,0xFC,0xFE,0xAC,0xE0,0x20,0xE9,0x18,0x40,0x52,
+0x00,0x20,0x22,0xF2,0x91,0xBA,0xE0,0x6F,0xE8,0x03,0x12,0x62,0x94,0xB2,0x99,0x50,
+0x41,0x03,0x94,0x20,0x22,0xF8,0x11,0xBA,0xE0,0x6F,0xE8,0x05,0x40,0x52,0x14,0x20,
+0x12,0x62,0x94,0xB2,0x8C,0x01,0x96,0x00,0x48,0xFF,0xFF,0xE9,0x3A,0x6F,0xB4,0x04,
+0xDD,0x9E,0x92,0x00,0x3A,0x6F,0xBA,0xBC,0xEF,0xFC,0x3F,0xCF,0xFE,0x1C,0x84,0xC0,
+0x80,0x06,0x8C,0xC1,0x54,0x63,0x00,0xFF,0x49,0xFF,0xFC,0xDC,0x5A,0x68,0x0C,0xFA,
+0x84,0x20,0xB9,0x80,0xB9,0x8E,0xEB,0x4E,0x02,0x20,0x02,0xD4,0x2E,0x07,0xFD,0x36,
+0x92,0x01,0xE2,0x40,0xE8,0x24,0x3C,0x03,0xFE,0xC7,0x8C,0x01,0x96,0x01,0xEA,0x64,
+0x2E,0x47,0xFF,0xC3,0x84,0x6A,0xFE,0xE4,0xE0,0x60,0xE8,0x19,0x3C,0x1B,0xFE,0xC7,
+0x3E,0x17,0xFD,0x57,0x3E,0x17,0xFD,0x65,0xC2,0x13,0x84,0xC0,0x46,0xB1,0x00,0x02,
+0x58,0xB5,0x80,0xB4,0x80,0xE6,0x46,0x91,0x00,0x01,0x58,0x94,0x8E,0xB0,0x46,0xA1,
+0x00,0x02,0x58,0xA5,0x01,0x44,0x81,0x8B,0x48,0x00,0x00,0x5F,0xCA,0x06,0x84,0x00,
+0xEA,0x64,0x3E,0x07,0xFD,0x57,0xEA,0xF8,0xEA,0x96,0xC0,0xE8,0xEA,0x6A,0x96,0x04,
+0xC0,0xE5,0x84,0x00,0x3E,0x07,0xFD,0x68,0x48,0x00,0x00,0x9E,0x40,0x24,0x84,0x20,
+0xA7,0x11,0x38,0x34,0x85,0x00,0x80,0x44,0x42,0x21,0xC0,0x73,0x41,0x15,0x08,0x20,
+0x23,0x18,0x94,0xB2,0x5B,0x10,0xFE,0x4C,0x8C,0x21,0x96,0x48,0xE2,0x25,0xE9,0xEF,
+0x4E,0x02,0x00,0x74,0x46,0x01,0x00,0x01,0x10,0x70,0x0F,0xF2,0x46,0x01,0x00,0x01,
+0x10,0x60,0x0F,0xF3,0x3E,0x77,0xFE,0x64,0x3E,0x67,0xFE,0x65,0x49,0xFF,0xFC,0xA0,
+0x2E,0x17,0xFD,0x36,0xEB,0x64,0x04,0x00,0x00,0x08,0xE2,0x20,0xE8,0x06,0x84,0x01,
+0x3E,0x07,0xFD,0x57,0x84,0x00,0xEA,0x64,0x2E,0x07,0xFF,0xA2,0x96,0x04,0xC8,0x31,
+0xB8,0x00,0xC0,0x4E,0x9E,0x41,0x84,0x4C,0x80,0x6B,0x42,0x30,0x88,0x73,0x46,0x11,
+0x00,0x02,0xA0,0xDA,0x04,0x10,0x80,0x50,0xE2,0x61,0xE8,0x42,0x96,0x00,0x81,0xC2,
+0x4E,0x03,0x00,0x2A,0xB8,0x00,0xE6,0x0B,0xE8,0x04,0x9C,0x01,0x3C,0x0F,0xFF,0x87,
+0xB8,0x0E,0x8C,0x01,0xB8,0x8E,0x84,0x0B,0x49,0xFF,0xFC,0x4C,0x46,0x01,0x00,0x05,
+0x02,0x50,0x02,0xD4,0x84,0x00,0x80,0x20,0xFB,0x96,0xD5,0xB9,0x40,0x25,0x08,0x20,
+0x22,0x21,0x11,0xBA,0xE0,0x02,0xE8,0xB1,0x96,0x11,0x80,0xC4,0x80,0xE3,0xD5,0xAD,
+0x2E,0x07,0xFD,0x57,0xC0,0xCE,0xEA,0x45,0x96,0x00,0xC8,0xCB,0xB8,0x80,0x84,0x01,
+0xEA,0xF8,0xD5,0x31,0x50,0xD0,0x7F,0xFF,0x80,0x2C,0x42,0x16,0xB8,0x73,0xA0,0x8A,
+0x46,0x11,0x00,0x02,0x04,0x10,0x80,0x50,0xE2,0x41,0xE8,0xCD,0x80,0x2D,0xEA,0xFE,
+0x80,0x0D,0x44,0x10,0x00,0x0B,0xEA,0xFE,0x54,0x06,0x80,0xFF,0xD5,0xC2,0x84,0x2B,
+0x49,0xFF,0xFB,0xE0,0x48,0xFF,0xFF,0xC0,0x3C,0x2D,0xFF,0x87,0x2E,0x37,0xFD,0x49,
+0x46,0x41,0x00,0x01,0x58,0x42,0x0F,0xF4,0x80,0x20,0xE2,0x22,0xE8,0x0A,0x38,0x52,
+0x06,0x02,0xE2,0x65,0xE8,0x03,0x8C,0x01,0x96,0x00,0x8C,0x21,0x96,0x48,0xD5,0xF6,
+0x3E,0x07,0xFD,0x4F,0xEC,0x04,0x3A,0x6F,0xBA,0x84,0xDD,0x9E,0xFC,0x60,0x51,0xFF,
+0xFB,0xA0,0x3D,0x3D,0xFF,0x87,0x4F,0x32,0x02,0xEB,0x46,0x37,0xFF,0xFF,0x84,0x20,
+0xB1,0x50,0xB1,0xDC,0xB1,0xA8,0x51,0x1F,0x80,0xD0,0x51,0x2F,0x81,0x00,0x50,0x2F,
+0x81,0x30,0x50,0xBF,0x81,0x60,0x50,0x31,0x8F,0xFF,0x84,0x00,0xB1,0x04,0x38,0x02,
+0x06,0x0A,0x50,0x4F,0x81,0x90,0x38,0x02,0x06,0x0A,0x50,0x9F,0x82,0x20,0xEA,0xC6,
+0x42,0x90,0x90,0x73,0x38,0x02,0x86,0x0A,0x38,0x03,0x86,0x0A,0x38,0x03,0x06,0x0A,
+0x38,0x08,0x86,0x0A,0x38,0x09,0x06,0x0A,0x38,0x01,0x06,0x0A,0x38,0x05,0x86,0x0A,
+0x80,0x89,0x38,0x32,0x02,0x0A,0x8C,0x01,0x5A,0x08,0x0C,0xFD,0x8C,0x21,0x5A,0x18,
+0x0C,0xDE,0x3C,0x9D,0xFF,0x91,0x84,0x80,0xE3,0x33,0x80,0x13,0x47,0x97,0xFF,0xFF,
+0x40,0x04,0xBC,0x1A,0x80,0x64,0x46,0xC1,0x00,0x01,0x58,0xC6,0x0D,0x08,0x45,0xE0,
+0xFF,0xFF,0x51,0x9C,0x8F,0xFF,0x46,0xD1,0x00,0x01,0x58,0xD6,0x8D,0x98,0x40,0x99,
+0xA4,0x06,0x47,0x51,0x00,0x01,0x59,0x5A,0x8C,0x0C,0x47,0x61,0x00,0x01,0x59,0x6B,
+0x0C,0x3C,0x38,0xE6,0x13,0x02,0x94,0x63,0x4C,0xEF,0x00,0x41,0x50,0xAF,0x82,0x20,
+0x40,0xA5,0x0C,0x40,0x40,0x80,0xB0,0x00,0x41,0x42,0x08,0x08,0x86,0x00,0xE1,0x80,
+0xE8,0x31,0xE3,0x93,0xE8,0x29,0x38,0x16,0xC3,0x02,0x04,0xF4,0x00,0x01,0x41,0x80,
+0xB8,0x01,0x40,0x16,0xC0,0x60,0xA0,0x49,0x40,0xF0,0xBC,0x01,0x43,0x77,0xBC,0x24,
+0x2E,0x17,0xFD,0x27,0x43,0x7C,0x60,0x73,0x15,0x75,0x00,0x00,0xC9,0x17,0x4E,0x92,
+0x00,0x16,0x38,0x1A,0xD0,0x02,0x43,0x8C,0x04,0x24,0x38,0x1B,0x50,0x02,0x42,0x17,
+0x84,0x24,0xE0,0x38,0xE8,0x04,0x40,0x1C,0x04,0x01,0xD5,0x02,0x8A,0x38,0x94,0x4D,
+0x88,0x37,0xB6,0x2A,0xD5,0x03,0x15,0x95,0x00,0x00,0x8D,0x81,0x50,0xA5,0x00,0x30,
+0xD5,0xCF,0xEB,0x10,0x38,0x40,0x8E,0x0A,0x8C,0x61,0x8C,0x81,0x5A,0x48,0x0C,0xBB,
+0x46,0x47,0xFF,0xFF,0x45,0x30,0x00,0x30,0x50,0x42,0x0F,0xFF,0xE0,0x60,0xE8,0x10,
+0x50,0x1F,0x82,0x20,0x41,0x00,0x8C,0x40,0x84,0x20,0xE0,0x20,0xE8,0x07,0x42,0x90,
+0xCC,0x24,0x8C,0x21,0x38,0x48,0x24,0x0A,0xD5,0xF9,0x8C,0x61,0xD5,0xF0,0x84,0x20,
+0x46,0x37,0xFF,0xFF,0x84,0x9F,0x82,0x01,0x50,0x31,0x8F,0xFF,0xE0,0x20,0xE8,0x0B,
+0x38,0x42,0x86,0x0A,0x38,0x43,0x86,0x0A,0x39,0x09,0x06,0x0A,0x38,0x31,0x06,0x0A,
+0x8C,0x21,0xD5,0xF5,0x51,0x0F,0x82,0x20,0x80,0x30,0x86,0x60,0x44,0xA0,0x00,0x30,
+0xE1,0xE0,0xE8,0x1D,0xB4,0x81,0x84,0x61,0xE0,0x60,0xE8,0x09,0x42,0x91,0xA8,0x24,
+0x8C,0x61,0x38,0x90,0xA4,0x02,0x42,0x42,0x24,0x01,0xD5,0xF7,0xC4,0x0D,0x84,0x60,
+0xE0,0x60,0xE8,0x0A,0x42,0xC1,0xA8,0x24,0x8C,0x61,0x38,0x90,0xB0,0x02,0x8B,0x24,
+0x38,0x90,0xB0,0x0A,0xD5,0xF6,0x8D,0xE1,0x8C,0x24,0xD5,0xE3,0x85,0x80,0x80,0x2C,
+0x85,0x5F,0xE0,0x20,0xE8,0x2B,0xB5,0xF0,0x84,0x61,0xE0,0x60,0xE8,0x07,0x38,0x98,
+0x0E,0x02,0x8C,0x61,0x43,0x39,0xA4,0x01,0xD5,0xF9,0x39,0x38,0x86,0x0A,0x84,0x60,
+0xE0,0x60,0xE8,0x11,0x38,0x98,0x0E,0x02,0x4D,0x34,0xC0,0x0C,0x38,0x92,0x8E,0x02,
+0x4E,0x94,0x00,0x08,0xB1,0x04,0x38,0x32,0x06,0x0A,0x38,0x12,0x8E,0x0A,0xD5,0x0A,
+0x8C,0x61,0xD5,0xEF,0xB0,0xC4,0x38,0x13,0x32,0x0A,0x38,0xA1,0x86,0x0A,0x50,0xC6,
+0x00,0x01,0x8C,0x21,0x51,0x08,0x00,0x30,0xD5,0xD5,0x82,0xEC,0x4E,0xC3,0x00,0x0C,
+0x84,0x00,0x50,0xDF,0x81,0xC0,0x46,0x31,0x00,0x01,0x58,0x31,0x8D,0x98,0xEA,0xC7,
+0x48,0x00,0x00,0xAC,0x47,0x37,0xFF,0xFF,0x51,0x39,0x8F,0xFF,0x80,0x6C,0x85,0x40,
+0x44,0xC0,0x00,0x30,0x81,0xB3,0x85,0x1F,0x86,0x80,0x40,0xFA,0x0C,0x07,0xE8,0x2D,
+0x39,0x03,0x52,0x02,0x51,0x5F,0x82,0x20,0x39,0x68,0xC2,0x02,0x43,0x58,0x30,0x73,
+0x84,0x20,0xE0,0x20,0xE8,0x1F,0xEB,0x35,0xE8,0x1B,0x38,0x9A,0x86,0x02,0x40,0xE4,
+0xD8,0x01,0x38,0x49,0x06,0x02,0x88,0x8E,0xE0,0x8F,0xE8,0x12,0xCC,0x0D,0x38,0xE2,
+0x86,0x02,0x4E,0xE5,0x00,0x59,0x38,0xE3,0x0E,0x0A,0x38,0x41,0x06,0x0A,0x39,0x03,
+0x86,0x0A,0x8C,0x61,0xD5,0x05,0x38,0x41,0x06,0x0A,0x39,0x05,0x86,0x0A,0x8C,0x21,
+0xD5,0xE1,0x51,0x4A,0x00,0x01,0xD5,0xD2,0x81,0xCD,0x84,0x20,0xE0,0x20,0xE8,0x07,
+0xEB,0x35,0xE8,0x03,0x42,0xE7,0x3C,0x01,0x8C,0x21,0xD5,0xF9,0x86,0x00,0xE1,0x83,
+0xE8,0x0A,0x38,0x93,0x42,0x02,0x8D,0x81,0x38,0x18,0xA6,0x02,0x88,0x2E,0x38,0x18,
+0xA6,0x0A,0xD5,0xF6,0x43,0x41,0xA8,0x00,0x84,0x20,0xE0,0x20,0xE8,0xB7,0xEB,0x35,
+0x50,0x90,0x80,0x01,0xE8,0x21,0x40,0xF7,0xB8,0x01,0x38,0xF1,0x06,0x0A,0xE9,0x21,
+0x38,0xF2,0x86,0x02,0x39,0x05,0x86,0x02,0x4E,0xF4,0x00,0x11,0x80,0x69,0xE0,0x60,
+0xE8,0x1A,0x38,0xF1,0x0E,0x02,0xE9,0x08,0x50,0x4F,0x81,0x00,0x38,0x92,0x0E,0x02,
+0x89,0x2E,0x38,0x92,0x0E,0x0A,0x8C,0x61,0xD5,0xF3,0x38,0xF3,0x0E,0x0A,0x39,0x03,
+0x86,0x0A,0x8C,0x61,0xD5,0x06,0x39,0x09,0x06,0x02,0x89,0x8E,0x39,0x09,0x06,0x0A,
+0x80,0x29,0xD5,0xD4,0xB0,0xC4,0x38,0x31,0xC2,0x02,0xB1,0x04,0x38,0x12,0x42,0x0A,
+0x39,0x02,0x86,0x0A,0x4E,0x35,0x00,0x06,0x39,0x03,0x8E,0x02,0x80,0x23,0xD5,0xF3,
+0x51,0x7B,0xFF,0xFF,0x4F,0x72,0xFF,0x66,0x84,0x20,0xE0,0x20,0xE8,0x07,0x38,0x83,
+0x86,0x0A,0x39,0x31,0x06,0x0A,0x8C,0x21,0xD5,0xF9,0x84,0x60,0x80,0x23,0xE0,0x20,
+0x4E,0xF2,0xFF,0x6C,0xB1,0x04,0x39,0x02,0x06,0x02,0x4F,0x04,0x00,0x05,0x38,0x13,
+0x0E,0x0A,0x8C,0x61,0x8C,0x21,0xD5,0xF4,0x98,0x58,0xEA,0x6B,0x40,0x40,0x34,0x00,
+0x38,0x21,0x80,0x0A,0x8C,0x08,0x3B,0x02,0x44,0x20,0xA8,0x89,0x47,0x41,0x00,0x01,
+0x59,0x4A,0x0D,0x98,0x5A,0x08,0x60,0xF2,0x84,0xE0,0x47,0x61,0x00,0x01,0x59,0x6B,
+0x0D,0x08,0x46,0xE1,0x00,0x01,0x58,0xE7,0x0C,0x3C,0x47,0x51,0x00,0x01,0x59,0x5A,
+0x8C,0x6C,0x3D,0x3D,0xFF,0x87,0xE2,0xF3,0x4E,0xF2,0x00,0xFA,0x2E,0x57,0xFD,0x61,
+0xB0,0x44,0x38,0x20,0x9E,0x02,0x3C,0x1D,0xFF,0x91,0x2E,0x37,0xFD,0x56,0xE2,0x41,
+0x2E,0x00,0x01,0x32,0x4E,0xF2,0x00,0x77,0xEB,0x10,0x38,0x60,0x8A,0x02,0x46,0xC1,
+0x00,0x01,0x58,0xC6,0x0C,0xD8,0x38,0x16,0x1A,0x02,0xC9,0x03,0xFF,0x44,0xD5,0x03,
+0x44,0x50,0x00,0x64,0x46,0x21,0x00,0x01,0xEB,0x1B,0x38,0x21,0x1B,0x02,0x39,0x06,
+0x9F,0x02,0x40,0x83,0x8C,0x08,0x40,0x98,0x08,0x01,0x40,0x26,0xA0,0x00,0x05,0x11,
+0x00,0x01,0x46,0x21,0x00,0x01,0xEB,0x1B,0x40,0x21,0x18,0x60,0xA0,0x91,0x40,0xA8,
+0x88,0x01,0x46,0x21,0x00,0x01,0x58,0x21,0x0D,0x74,0x38,0x21,0x18,0x00,0x42,0xB5,
+0x28,0x24,0x42,0xB4,0xA4,0x73,0x5A,0x28,0x01,0x2B,0x2F,0xE0,0x01,0x2B,0x3C,0x23,
+0xFE,0xC9,0x84,0x80,0x41,0x21,0x04,0x08,0x3C,0x23,0xFE,0xC5,0x41,0x71,0x04,0x08,
+0xE0,0x9E,0xE8,0x1D,0x38,0x2A,0x93,0x02,0x41,0x82,0x0C,0x08,0xE3,0x82,0xE8,0x03,
+0x8A,0x50,0xD5,0x03,0x40,0x28,0x08,0x01,0xE2,0x52,0xE8,0x0F,0x46,0x21,0x00,0x01,
+0x58,0x21,0x0C,0x6C,0x88,0x58,0xA0,0x91,0xE3,0xA2,0xE8,0x03,0x8A,0x51,0xD5,0x03,
+0x40,0x28,0x88,0x01,0xE2,0x57,0xE9,0x4B,0x8C,0x81,0xD5,0xE3,0x84,0x41,0x96,0xDF,
+0x8C,0x67,0xFE,0x1C,0x88,0x25,0x85,0xE7,0x40,0x15,0x84,0x37,0x40,0xF0,0x3D,0xF6,
+0xE2,0x2F,0xE9,0x42,0x2E,0x07,0xFD,0x4E,0x2E,0x47,0xFD,0x60,0xEB,0x78,0x58,0x10,
+0x8C,0xCC,0x9D,0x43,0x84,0x7D,0x38,0x10,0x98,0x00,0x42,0x52,0x0C,0x73,0xE0,0x25,
+0xE9,0x30,0x84,0x00,0xEA,0xC7,0x46,0x31,0x00,0x01,0x58,0x31,0x8D,0x08,0x38,0x51,
+0x83,0x02,0x94,0x43,0xDA,0x1E,0x44,0x20,0xFF,0xFD,0x46,0x31,0x00,0x01,0x58,0x31,
+0x8C,0x0C,0x38,0x2B,0x03,0x0A,0x84,0x40,0x38,0x21,0x82,0x0A,0x40,0x36,0x9C,0x60,
+0x88,0x34,0x3B,0x01,0xC4,0x00,0xEA,0xEA,0xEB,0x78,0xEA,0x71,0x38,0x70,0x80,0x08,
+0xEB,0x78,0x58,0x10,0x8C,0xD8,0x38,0x27,0x02,0x0A,0x38,0x20,0x82,0x0A,0xD5,0x04,
+0x8C,0x01,0x5A,0x08,0x0C,0xDA,0x8C,0xE1,0x48,0xFF,0xFF,0x4D,0x84,0x42,0xD5,0xB8,
+0xE7,0xE3,0xE8,0xD0,0xC0,0xCF,0x96,0x30,0x15,0x5F,0x80,0x03,0x15,0x6F,0x80,0x02,
+0x15,0x4F,0x80,0x01,0xB6,0x5F,0x49,0xFF,0xE5,0x69,0xB4,0x5F,0x05,0x4F,0x80,0x01,
+0x05,0x6F,0x80,0x02,0x05,0x5F,0x80,0x03,0xC8,0xBD,0x3C,0x33,0xFE,0xC9,0x3C,0x13,
+0xFE,0xC5,0xFE,0x5C,0xFE,0x8C,0xE2,0x4B,0xE8,0x09,0xEB,0x78,0x58,0x10,0x8C,0x0C,
+0x38,0x07,0x1A,0x0A,0x38,0x00,0x9A,0x0A,0xD5,0xD7,0xB0,0x04,0x38,0x00,0x1E,0x02,
+0xEB,0x10,0x38,0x00,0x82,0x02,0x89,0x0D,0x40,0x0A,0x00,0x60,0x3B,0x04,0x44,0x00,
+0x3B,0x00,0x44,0x20,0x46,0x01,0x00,0x01,0x58,0x00,0x0D,0x68,0x38,0x70,0x18,0x08,
+0x2E,0x07,0xFD,0x27,0xC8,0xC1,0x46,0x01,0x00,0x01,0x58,0x00,0x0C,0x0C,0x38,0x97,
+0x1A,0x0A,0x38,0xA0,0x1A,0x0A,0x38,0xB6,0x1A,0x0A,0xD5,0xB6,0x51,0xFF,0x84,0x60,
+0xFC,0xE0,0xFC,0x00,0x3F,0xCF,0xFD,0xD8,0xB9,0x00,0x2E,0x07,0xFF,0xD8,0x5A,0x18,
+0x07,0x03,0x92,0x01,0x3E,0x07,0xFD,0x24,0xB8,0x11,0xC0,0x05,0x2E,0x07,0xFD,0x20,
+0x5A,0x08,0x01,0x37,0x2E,0x37,0xFD,0x24,0x2E,0x27,0xFF,0xDB,0xB8,0x17,0xFE,0x9C,
+0xE2,0x02,0xE8,0x07,0xEA,0xF5,0x42,0x10,0x8C,0x0B,0xC1,0x2C,0x8C,0x01,0xD5,0x29,
+0x84,0x01,0xEB,0x3C,0x84,0x00,0xEB,0x0C,0x84,0x00,0xB8,0x8E,0x84,0x01,0xB8,0x9C,
+0x84,0x08,0x5A,0x10,0x07,0x09,0x5A,0x18,0x02,0x0A,0x2E,0x07,0xFF,0xA7,0x5A,0x08,
+0x03,0x06,0x84,0x06,0x2E,0x17,0xFD,0x31,0xEA,0x34,0x84,0x00,0xEB,0x25,0x2E,0x07,
+0xFD,0x31,0xC0,0x03,0x84,0x00,0xEB,0x2E,0xB8,0x00,0x5A,0x00,0x06,0x04,0x5A,0x08,
+0x08,0x0A,0x46,0x01,0x00,0x01,0x58,0x00,0x04,0x74,0xB8,0x9A,0xD5,0x03,0x84,0x00,
+0xB8,0x97,0xFC,0x80,0xFC,0x00,0x3F,0xCF,0xFD,0xD8,0xB9,0x11,0xB8,0x00,0xC9,0x0F,
+0x5A,0x08,0x08,0x08,0x46,0x11,0x00,0x05,0x02,0x10,0x82,0xD4,0xC9,0x08,0xD5,0x03,
+0x5A,0x00,0x06,0xFA,0x2E,0x17,0xFD,0x20,0x5A,0x18,0x01,0x32,0x84,0x20,0x3E,0x17,
+0xFD,0x3D,0x84,0x20,0xB9,0x97,0x5A,0x00,0x08,0x04,0x5A,0x08,0x06,0x20,0xB9,0x8E,
+0x5A,0x08,0x08,0x04,0x84,0x07,0xD5,0x04,0x5A,0x08,0x06,0x06,0x84,0x02,0x2E,0x17,
+0xFD,0x20,0xEA,0x34,0x84,0x00,0xEB,0x25,0xB8,0x00,0x5A,0x08,0x07,0x05,0xEB,0x64,
+0xEB,0x47,0xD5,0x05,0xEA,0x2B,0xC8,0x05,0xEB,0x64,0xEA,0xB6,0xB8,0x9A,0xD5,0x1E,
+0x5A,0x08,0x01,0x1D,0xEB,0x64,0xDD,0x5D,0xD5,0xFA,0x8E,0x03,0xE6,0x03,0xE8,0x16,
+0xEA,0x43,0xB4,0x01,0x58,0x00,0x04,0x00,0xB6,0x01,0xD5,0x10,0x2E,0x27,0xFF,0xDA,
+0xFA,0x2E,0xFE,0x54,0x2E,0x27,0xFF,0xDB,0xB8,0x0E,0xFE,0x54,0xE2,0x01,0xE8,0x04,
+0x8C,0x01,0xB8,0x8E,0xD5,0x03,0x84,0x01,0xEB,0x0C,0xFC,0x80,0xDD,0x4B,0x5A,0x08,
+0x08,0x05,0x2E,0x27,0xFF,0xAE,0xD5,0x06,0x84,0x40,0x5A,0x08,0x06,0x04,0x2E,0x27,
+0xFF,0xB9,0x84,0x20,0x80,0x01,0x46,0x31,0x00,0x01,0x58,0x31,0x82,0xC4,0x38,0xF1,
+0x85,0x11,0xE0,0x4F,0xE8,0x06,0x5C,0xF0,0x00,0x95,0xE8,0x03,0x8C,0x01,0x96,0x01,
+0x8C,0x21,0x5A,0x18,0xD8,0xF6,0x46,0x11,0x00,0x05,0x12,0x00,0x82,0xD4,0xDD,0x9E,
+0xFC,0x20,0xDD,0x4B,0x5A,0x08,0x08,0x09,0x2E,0x17,0xFF,0xAE,0x94,0x49,0x96,0x4B,
+0x2E,0x57,0xFF,0xE5,0xD5,0x0C,0x5A,0x08,0x06,0x09,0x2E,0x17,0xFF,0xB9,0x94,0x49,
+0x96,0x4B,0x2E,0x57,0xFF,0xE1,0xD5,0x03,0x84,0x20,0x80,0xA1,0x84,0x40,0x3C,0x6D,
+0xFF,0x90,0x80,0x82,0x46,0x71,0x00,0x02,0x58,0x73,0x81,0x44,0x82,0x02,0x47,0x11,
+0x00,0x01,0x59,0x18,0x82,0xC4,0x98,0x17,0x02,0x00,0x07,0x9A,0x38,0x33,0x08,0x01,
+0x9A,0xC3,0x96,0xD9,0x96,0x1B,0x4E,0x05,0x00,0x07,0xE0,0xA0,0x84,0x00,0xE8,0x07,
+0x9A,0x1D,0xD5,0x04,0x88,0x05,0x42,0x00,0x40,0x01,0x96,0x03,0x38,0x08,0x88,0x09,
+0x88,0x01,0x4E,0x04,0x00,0x04,0x8C,0x81,0x97,0x21,0x8C,0x42,0x5A,0x29,0xB0,0xE5,
+0x2E,0x00,0x00,0x15,0xE2,0x04,0xE8,0x0A,0x46,0x01,0x00,0x01,0x00,0x00,0x02,0xC0,
+0xEB,0x78,0xEA,0x37,0xEA,0xEC,0x84,0x01,0xEA,0x76,0xFC,0xA0,0xEB,0x43,0xDD,0x9E,
+0xEB,0x3B,0xC0,0x04,0x84,0x00,0x3C,0x0F,0xFF,0x92,0xDD,0x9E,0xFC,0x40,0x3F,0xCF,
+0xFD,0xF4,0x80,0xE1,0x84,0x20,0x80,0xC0,0x46,0x41,0x00,0x01,0x58,0x42,0x09,0x48,
+0x80,0xA1,0x44,0x30,0xFF,0xFF,0x50,0x00,0x80,0x08,0x88,0x04,0x84,0x40,0x8C,0x41,
+0xB6,0xA0,0x14,0x30,0x7F,0xFE,0x14,0x30,0x7F,0xFF,0x8C,0x0C,0x5A,0x28,0x04,0xF9,
+0x50,0x10,0x80,0x30,0x5A,0x1A,0x40,0xF1,0x84,0x00,0x46,0x21,0x00,0x01,0xEB,0x1B,
+0x44,0x10,0xFF,0xFF,0x38,0x11,0x00,0x0A,0x98,0xC2,0x8C,0x08,0xA8,0x59,0x5A,0x08,
+0x60,0xFB,0x46,0x01,0x00,0x01,0x58,0x00,0x0C,0x3C,0x84,0x20,0xEA,0xED,0xDD,0x42,
+0x46,0x01,0x00,0x01,0x58,0x00,0x0C,0x0C,0x84,0x20,0xEA,0xED,0xDD,0x42,0xC6,0x04,
+0x2E,0x00,0x00,0x0B,0xD5,0x07,0xC7,0x04,0x2E,0x00,0x00,0x0D,0xD5,0x03,0x2E,0x00,
+0x00,0x0F,0x8C,0x01,0xEA,0xF9,0x2E,0x07,0xFD,0x64,0x5A,0x08,0x01,0x04,0x84,0x02,
+0xEA,0xF9,0xEA,0xCF,0x85,0x20,0xEB,0x15,0x3E,0x97,0xFD,0x57,0x3E,0x97,0xFD,0x65,
+0x3E,0x97,0xFD,0x5E,0x84,0x40,0x3E,0x97,0xFD,0x27,0xBA,0x8A,0xBA,0x98,0xEB,0x4E,
+0x12,0x20,0x02,0xD4,0xBA,0x94,0xBA,0x8D,0xBA,0x96,0x3E,0x27,0xFD,0x50,0xBA,0x92,
+0x3E,0x97,0xFD,0x5B,0xBA,0x90,0xEA,0xDE,0x92,0x27,0x8C,0x21,0x96,0x48,0x3E,0x17,
+0xFD,0x6B,0xEA,0xB8,0x92,0x07,0x8C,0x01,0x96,0x00,0x3E,0x07,0xFD,0x5C,0x2E,0x27,
+0xFF,0xBE,0x2E,0x40,0x01,0x32,0x3E,0x27,0xFD,0x56,0x54,0x31,0x00,0x0F,0x42,0x51,
+0x90,0x24,0x92,0x44,0x40,0x12,0x84,0x36,0x3C,0x1B,0xFE,0xC6,0x2E,0x10,0x01,0x33,
+0xFF,0x14,0xFE,0xCC,0xFE,0x8C,0x40,0x01,0x80,0x16,0x3C,0x0B,0xFE,0xCE,0x3C,0x4B,
+0xFE,0xC9,0x3C,0x2B,0xFE,0xC5,0x2E,0x07,0xFF,0xBD,0x54,0x10,0x00,0x0F,0x3E,0x17,
+0xFD,0x4E,0x92,0x04,0x3E,0x07,0xFD,0x61,0x2E,0x07,0xFF,0xA5,0x92,0x04,0x3E,0x07,
+0xFD,0x2B,0x84,0x02,0xB8,0x85,0x2E,0x07,0xFF,0xA8,0xDD,0x49,0x3C,0x0B,0xFE,0xC8,
+0x2E,0x07,0xFF,0xB2,0xDD,0x49,0x3C,0x0B,0xFE,0xCC,0x2E,0x07,0xFF,0xB3,0xDD,0x49,
+0x3C,0x0B,0xFE,0xCD,0x3E,0x97,0xFD,0x41,0x3E,0x97,0xFD,0x66,0x3E,0x97,0xFD,0x42,
+0x2E,0x07,0xFF,0xC6,0xEA,0x98,0x2E,0x07,0xFF,0xC7,0xEA,0xAD,0x2E,0x07,0xFF,0xC9,
+0x40,0x10,0x10,0x09,0x3E,0x17,0xFD,0x52,0x96,0x1F,0x84,0x2A,0xFE,0x0C,0x3E,0x07,
+0xFD,0x3A,0x2E,0x07,0xFF,0xD3,0x3C,0x0B,0xFE,0xD1,0xC7,0x0B,0x2E,0x07,0xFF,0xCE,
+0x54,0x10,0x00,0x0F,0x3E,0x17,0xFD,0x38,0x92,0x04,0x3E,0x07,0xFD,0x2C,0xD5,0x13,
+0x2E,0x07,0xFF,0xCC,0x54,0x10,0x00,0x0F,0x3E,0x17,0xFD,0x38,0x92,0x04,0x3E,0x07,
+0xFD,0x2C,0x2E,0x07,0xFF,0xCD,0x54,0x10,0x00,0x0F,0x3E,0x17,0xFD,0x21,0x92,0x04,
+0x3E,0x07,0xFD,0x39,0x49,0xFF,0xEF,0x2F,0x46,0x01,0x00,0x01,0x58,0x00,0x0B,0x94,
+0x84,0x3F,0x84,0x4C,0xDD,0x42,0x84,0x00,0x3E,0x07,0xFD,0x4D,0x2E,0x17,0xFF,0xDE,
+0x84,0x00,0x40,0x00,0x04,0x06,0x3E,0x07,0xFD,0x3B,0x2E,0x27,0xFF,0xD6,0x3E,0x27,
+0xFD,0x28,0x2E,0x37,0xFF,0xD7,0xFA,0x24,0x42,0x21,0x84,0x73,0x96,0x90,0x3E,0x27,
+0xFD,0x47,0xC0,0x02,0x84,0x44,0x3E,0x27,0xFD,0x2F,0x2E,0x07,0xFF,0xD8,0x84,0x40,
+0x3E,0x07,0xFD,0x24,0x3E,0x27,0xFD,0x46,0x3E,0x27,0xFD,0x68,0x3E,0x27,0xFD,0x55,
+0x3E,0x27,0xFD,0x1E,0x3E,0x27,0xFD,0x3E,0x3E,0x27,0xFD,0x25,0x84,0x00,0x3C,0x0B,
+0xFE,0xCB,0x3E,0x07,0xFD,0x4F,0x2E,0x07,0xFF,0xC8,0x3E,0x07,0xFD,0x49,0x2E,0x00,
+0x01,0x00,0x54,0x10,0x00,0x0F,0x3E,0x17,0xFD,0x54,0x92,0x04,0x3E,0x07,0xFD,0x6A,
+0x2E,0x00,0x01,0x01,0x54,0x10,0x00,0x0F,0x3E,0x17,0xFD,0x5A,0x92,0x04,0x3E,0x07,
+0xFD,0x1D,0x3E,0x27,0xFD,0x6E,0xCE,0x03,0x3E,0x27,0xFD,0x79,0x3E,0x27,0xFD,0x72,
+0x3E,0x27,0xFD,0x77,0x3E,0x27,0xFD,0x6F,0x3E,0x27,0xFD,0x71,0x3E,0x27,0xFD,0x73,
+0x3E,0x27,0xFD,0x76,0x84,0x00,0xB8,0x9F,0xB8,0x9E,0x2E,0x4F,0xFF,0xA3,0x4E,0x45,
+0x00,0x03,0x84,0x02,0x84,0x40,0x3E,0x07,0xFD,0x5F,0x86,0x00,0x3E,0x27,0xFD,0x74,
+0x84,0xA0,0x3D,0x0B,0xFE,0xE6,0xBD,0x9D,0x2E,0x30,0x00,0x6A,0xEA,0x2A,0xFE,0xCC,
+0x3C,0x3B,0xFE,0xE5,0x2E,0x30,0x00,0x6B,0xFE,0xCC,0x3C,0x3B,0xFE,0xE8,0x2E,0x30,
+0x00,0x6C,0xFE,0xCC,0x3C,0x3B,0xFE,0xE2,0x2E,0x30,0x00,0x6D,0xFE,0x5C,0x3C,0x1B,
+0xFE,0xE7,0x2E,0x10,0x00,0x6E,0x3C,0x1B,0xFE,0xE3,0x2E,0x10,0x00,0x6F,0x3E,0x17,
+0xFD,0x75,0x2E,0x10,0x00,0x71,0x3E,0x17,0xFD,0x78,0x3F,0x07,0xFD,0x70,0x3E,0x27,
+0xFD,0x22,0xBD,0x89,0x3E,0x27,0xFD,0x69,0x3E,0x27,0xFD,0x6C,0x3E,0x27,0xFD,0x29,
+0x2E,0x10,0x00,0x62,0x40,0x30,0x90,0x09,0x3E,0x37,0xFD,0x32,0x96,0x5F,0x3E,0x17,
+0xFD,0x53,0xCE,0x10,0x3E,0x27,0xFD,0x3D,0xEB,0x78,0x10,0x20,0x82,0xC0,0xEB,0x78,
+0x10,0x20,0x82,0xC1,0x84,0x21,0x3E,0x17,0xFD,0x30,0x3E,0x27,0xFD,0x59,0xBE,0x80,
+0xBE,0x86,0xC7,0x04,0xEB,0x64,0xEB,0x47,0xD5,0x12,0x4E,0x44,0x00,0x0C,0xC8,0x08,
+0xEA,0x2B,0xE6,0x01,0x3E,0xF7,0xFD,0x79,0x84,0x01,0x3E,0x07,0xFD,0x5F,0xEA,0x2B,
+0xC8,0x04,0xEB,0x64,0xEA,0xB6,0xD5,0x03,0xEB,0x64,0xDD,0x5D,0xB8,0x93,0x84,0xE0,
+0x44,0x20,0x05,0x10,0x3E,0x77,0xFD,0x40,0x84,0x20,0xEB,0x4E,0xEA,0x62,0xDD,0x42,
+0x3E,0x77,0xFD,0x3D,0x84,0x01,0xEB,0x2E,0x84,0xC0,0x3E,0x77,0xFD,0x20,0xBE,0x87,
+0x49,0xFF,0xDC,0x28,0xEB,0x4E,0x12,0x60,0x02,0xD6,0x3C,0x6B,0xFE,0xC7,0x3E,0x67,
+0xFD,0x5D,0x3C,0x6B,0xFE,0xC3,0x46,0x01,0x00,0x05,0x10,0x60,0x06,0xD6,0x46,0x01,
+0x00,0x05,0x12,0x60,0x03,0x6A,0x46,0x01,0x00,0x05,0x10,0x60,0x06,0x42,0x46,0x01,
+0x00,0x05,0x12,0x60,0x03,0x20,0x46,0x31,0x00,0x05,0x58,0x31,0x86,0x44,0xEA,0x29,
+0x46,0x21,0x00,0x05,0x58,0x21,0x05,0xB0,0x98,0x73,0x38,0x01,0x98,0x0A,0x38,0x01,
+0x18,0x0A,0xA8,0x09,0x10,0x70,0x80,0x08,0x98,0x72,0x8C,0xCC,0xA8,0x09,0x10,0x70,
+0x80,0x08,0x5A,0x68,0x90,0xF3,0xFC,0xC0,0x2E,0x27,0xFD,0x64,0x5A,0x18,0x02,0x05,
+0x3E,0x27,0xFD,0x45,0xD5,0x0E,0x8E,0x07,0xE6,0x02,0xE8,0x05,0x2E,0x00,0x00,0x0C,
+0xEA,0xDA,0xD5,0x05,0x2E,0x10,0x00,0x0E,0x40,0x01,0x04,0x40,0x3E,0x07,0xFD,0x45,
+0x84,0x00,0x3E,0x07,0xFD,0x2E,0xEA,0xAA,0xEA,0xC3,0xDD,0x9E,0xFC,0x0B,0x3F,0xCF,
+0xFD,0xD8,0x2E,0x07,0xFD,0x4B,0xC8,0x12,0xB8,0x0C,0x5A,0x00,0x02,0x09,0x2E,0x07,
+0xFF,0xD0,0xDD,0x49,0xEA,0x3D,0x2E,0x07,0xFF,0xD1,0xD5,0x0E,0x2E,0x07,0xFF,0xD4,
+0xDD,0x49,0xEA,0x3D,0x2E,0x07,0xFF,0xD5,0xD5,0x07,0xEA,0x9D,0x96,0x1F,0xDD,0x49,
+0xEA,0x3D,0xEA,0x9D,0x92,0x04,0xDD,0x49,0xEA,0x65,0xEA,0x45,0xC0,0x09,0x2E,0x00,
+0x00,0x63,0xDD,0x49,0xEA,0x3D,0x2E,0x00,0x00,0x63,0xDD,0x49,0xEA,0x65,0xEA,0x49,
+0xC0,0x07,0xEA,0xE3,0x94,0x01,0xEA,0x3D,0xEA,0xC9,0x94,0x01,0xEA,0x65,0xDD,0x59,
+0x5A,0x08,0x01,0x04,0x49,0x00,0x03,0x31,0xEB,0x11,0xEB,0x2A,0xDD,0x4D,0x42,0x00,
+0x18,0x0B,0xC0,0x06,0xDD,0x59,0x5A,0x08,0x01,0x04,0x49,0x00,0x04,0x64,0xB8,0x1B,
+0xB9,0x11,0xE2,0x01,0xE8,0x0C,0xC0,0x0B,0xEA,0x45,0xC0,0x09,0xEA,0xE3,0x94,0x01,
+0xEA,0x3D,0xEA,0xC9,0x94,0x01,0xEA,0x65,0xEB,0x11,0xEB,0x2A,0x84,0x00,0x3E,0x07,
+0xFD,0x58,0xDD,0x4D,0x42,0x00,0x18,0x0B,0xBA,0x11,0xC0,0x33,0xB8,0x14,0x5A,0x08,
+0x01,0x31,0xE6,0x42,0xE9,0x2E,0x46,0x01,0x00,0x01,0x00,0x10,0x0F,0xDC,0x46,0x01,
+0x00,0x01,0x00,0x00,0x0F,0xDE,0xE2,0x01,0xE8,0x03,0x9A,0x08,0xD5,0x02,0x8A,0x01,
+0x2E,0x37,0xFF,0xFA,0xE0,0x03,0xE8,0x1D,0x46,0x01,0x00,0x01,0x00,0x10,0x0F,0xDD,
+0x46,0x01,0x00,0x01,0x00,0x00,0x0F,0xDF,0xE2,0x01,0xE8,0x03,0x9A,0x08,0xD5,0x02,
+0x8A,0x01,0xE0,0x03,0xE8,0x0E,0xEB,0x64,0x04,0x00,0x00,0x2F,0x46,0x11,0x00,0x02,
+0x04,0x10,0x80,0x32,0x92,0x01,0xE2,0x20,0xE8,0x04,0x84,0x01,0x3E,0x07,0xFD,0x58,
+0xB8,0x1B,0xE2,0x40,0xE8,0x12,0x2E,0x07,0xFD,0x4B,0xC0,0x0F,0xEA,0x45,0xC8,0x0D,
+0xEA,0xE6,0xC8,0x0B,0xEA,0x9D,0x96,0x1F,0xDD,0x49,0xEA,0x3D,0xEA,0x9D,0x92,0x04,
+0xDD,0x49,0xEA,0x65,0xEB,0x11,0xEB,0x2A,0xB8,0x11,0xC0,0x1E,0x46,0x11,0x00,0x01,
+0x00,0x10,0x8F,0xDC,0x46,0x01,0x00,0x01,0x8E,0x21,0x00,0x00,0x0F,0xDD,0xFA,0x54,
+0x42,0x00,0x88,0x73,0x46,0x11,0x00,0x02,0xEB,0x17,0x40,0x00,0x80,0x20,0x22,0xF0,
+0x0C,0xA9,0x2E,0x07,0xFF,0xAA,0x94,0x01,0xE0,0x0F,0xE8,0x06,0x84,0x00,0xEB,0x15,
+0xEA,0xFD,0xC1,0x11,0xD5,0x0E,0x3C,0x03,0xFE,0xC4,0x5C,0xF0,0x03,0xE8,0xE8,0x0B,
+0x8C,0x01,0xEB,0x15,0x3C,0x03,0xFE,0xC0,0x5C,0xF0,0x00,0xC8,0xE8,0x04,0x8C,0x01,
+0x3C,0x0B,0xFE,0xC0,0x46,0x01,0x00,0x07,0xEA,0x63,0xEA,0x21,0xEA,0x20,0xD8,0x17,
+0x49,0xFF,0xE3,0x62,0x49,0xFF,0xE1,0xDD,0x49,0xFF,0xF9,0x12,0x49,0xFF,0xE7,0xEF,
+0x49,0xFF,0xE4,0xA5,0x49,0xFF,0xE5,0x57,0xDD,0x59,0x5A,0x08,0x01,0x10,0x46,0x01,
+0x00,0x01,0x58,0x00,0x09,0x48,0x49,0xFF,0xDE,0xD7,0xD5,0x08,0xDD,0x4D,0xEA,0xF0,
+0xC8,0xE8,0xDD,0x59,0x5A,0x08,0x01,0x30,0xD5,0xE4,0x46,0x01,0x00,0x05,0xEA,0x54,
+0x49,0xFF,0xE6,0x3E,0x46,0x01,0x00,0x05,0xEA,0x54,0x49,0xFF,0xE1,0x15,0xB8,0x00,
+0x5A,0x08,0x07,0x1F,0xB1,0x82,0x80,0x26,0x46,0x21,0x00,0x01,0xEB,0x36,0x46,0x01,
+0x00,0x05,0xEA,0x54,0x46,0x31,0x00,0x01,0x58,0x31,0x8D,0x68,0x49,0xFF,0xEB,0xC8,
+0xF0,0x81,0xF2,0x01,0x3A,0x03,0x04,0x00,0x49,0xFF,0xF3,0xC1,0x5A,0x00,0xFF,0x09,
+0x3E,0x07,0xFE,0x24,0x96,0x01,0x46,0x11,0x00,0x07,0x12,0x00,0x81,0xDB,0x84,0x00,
+0x3E,0x07,0xFD,0x27,0x46,0x01,0x00,0x05,0xEA,0x54,0xFC,0x8B,0x46,0x01,0x00,0x05,
+0x58,0x00,0x05,0xB0,0xDD,0x9E,0x46,0x11,0x00,0x05,0x58,0x10,0x85,0xB0,0x46,0x01,
+0x00,0x05,0xEA,0x54,0x3B,0x00,0x64,0x04,0xF8,0x01,0x3B,0x00,0xE4,0x24,0x3B,0x00,
+0x64,0x04,0x83,0xFF,0x3B,0x00,0xE4,0x24,0x3B,0x00,0x58,0x00,0x3B,0x00,0xD8,0x20,
+0xDD,0x9E,0x3C,0x0F,0xFF,0x8A,0xDD,0x9E,0x3C,0x13,0xFE,0xE4,0x3C,0x53,0xFE,0xE3,
+0xD9,0x07,0x84,0x00,0x3E,0x07,0xFD,0x6E,0x84,0x00,0xEA,0xCD,0xDD,0x9E,0xC8,0x06,
+0xEA,0x49,0xC0,0x04,0x8C,0x21,0x3C,0x1B,0xFE,0xE4,0xDD,0x9E,0xFC,0x00,0x84,0x01,
+0x3E,0x07,0xFD,0x72,0x3E,0x07,0xFD,0x74,0x84,0x00,0x3C,0x0B,0xFE,0xE6,0x84,0x21,
+0x3C,0x1F,0xFF,0x9A,0xEA,0xCD,0xFC,0x80,0xFC,0x00,0x3C,0x1D,0xFF,0x9A,0x5A,0x18,
+0x01,0x1F,0x2E,0x17,0xFD,0x72,0x5A,0x18,0x01,0x14,0x84,0x40,0x3E,0x27,0xFD,0x72,
+0x2E,0x37,0xFD,0x79,0xCB,0x04,0x3E,0x17,0xFD,0x79,0xD5,0x06,0x5A,0x38,0x01,0x09,
+0x3E,0x27,0xFD,0x79,0x84,0x20,0x49,0x00,0x06,0xA9,0x49,0x00,0x0A,0xEF,0x2E,0x07,
+0xFD,0x73,0x8C,0x01,0x3E,0x07,0xFD,0x73,0x84,0x02,0xD5,0x07,0x84,0x03,0x5A,0x10,
+0x02,0x05,0x5A,0x18,0x03,0x05,0x84,0x00,0x3C,0x0F,0xFF,0x9A,0xFC,0x80,0xFC,0x00,
+0x3C,0x1F,0xFF,0x90,0x84,0x20,0x3C,0x1F,0xFF,0x8F,0xDD,0x4F,0x46,0x01,0x00,0x05,
+0xEA,0x62,0xDD,0x42,0xFC,0x80,0xFC,0x00,0x3F,0xCF,0xFE,0x18,0xEB,0x23,0xC9,0x04,
+0x3C,0x63,0xFE,0xE5,0xD5,0x07,0x5A,0x18,0x01,0x05,0x3C,0x63,0xFE,0xE8,0xD5,0x02,
+0xEA,0xB5,0x84,0x40,0x80,0x02,0x46,0x41,0x00,0x05,0x58,0x42,0x06,0xD8,0x38,0x32,
+0x09,0x01,0x8C,0x41,0x88,0x03,0x5A,0x28,0xD8,0xFC,0x44,0x20,0x7F,0xFF,0x92,0x04,
+0xE2,0x40,0x40,0x01,0x3C,0x1B,0x2E,0x27,0xFD,0x77,0xCA,0x03,0xB8,0x96,0xD5,0x02,
+0xB8,0x95,0x2E,0x07,0xFD,0x76,0xE6,0x0A,0xE8,0x04,0x8C,0x01,0x3E,0x07,0xFD,0x76,
+0x2E,0x07,0xFD,0x76,0xE6,0x02,0x4E,0xF3,0x00,0x7C,0xC9,0x43,0x3C,0x23,0xFE,0xE2,
+0xB8,0x16,0xE2,0x40,0xE8,0x07,0x84,0x01,0x3E,0x07,0xFD,0x6E,0x3C,0x1B,0xFE,0xE4,
+0xD5,0x04,0xB8,0x01,0x49,0xFF,0xFF,0x6A,0xB8,0x15,0x88,0xC0,0xB8,0x16,0xE2,0xC0,
+0xE8,0x03,0xEA,0x49,0xC8,0x05,0xB8,0x00,0xEB,0x12,0x5A,0x08,0x01,0x12,0x2E,0x0F,
+0xFF,0xA3,0x4E,0x04,0x00,0x0E,0x46,0x01,0x00,0x07,0xEA,0x27,0xEA,0x48,0xEA,0x3F,
+0xD0,0x07,0x46,0x01,0x00,0x07,0xEA,0x27,0xEA,0x21,0xEA,0x20,0xD8,0x08,0x46,0x01,
+0x00,0x07,0xEA,0x27,0xEA,0x21,0xEA,0x20,0x4C,0x50,0x40,0x4B,0xEB,0x0A,0x46,0x01,
+0x00,0x02,0xEA,0xB6,0x50,0x10,0x05,0x10,0x49,0xFF,0xFF,0x8B,0xB8,0x00,0x5A,0x08,
+0x01,0x04,0x84,0x02,0xD5,0x04,0x5A,0x08,0x03,0x3C,0x84,0x00,0xB8,0x80,0xD5,0x38,
+0x5A,0x18,0x01,0x37,0x3C,0x23,0xFE,0xE7,0xB8,0x15,0xE2,0x40,0xE8,0x06,0x3E,0x17,
+0xFD,0x6E,0x84,0x00,0xEA,0xCD,0xD5,0x04,0xB8,0x01,0x49,0xFF,0xFF,0x27,0xB8,0x16,
+0x88,0xC0,0xB8,0x15,0xE2,0xC0,0xE8,0x03,0xEA,0x49,0xC8,0x05,0xB8,0x00,0xEB,0x12,
+0x5A,0x08,0x01,0x12,0x2E,0x0F,0xFF,0xA3,0x4E,0x04,0x00,0x0E,0x46,0x01,0x00,0x07,
+0xEA,0x27,0xEA,0x48,0xEA,0x3F,0xD0,0x07,0x46,0x01,0x00,0x07,0xEA,0x27,0xEA,0x21,
+0xEA,0x20,0xD8,0x07,0x46,0x01,0x00,0x07,0xEA,0x27,0xEA,0x48,0xEA,0x3F,0xD8,0x08,
+0xEB,0x0A,0x46,0x01,0x00,0x02,0xDD,0x5D,0x50,0x10,0x7A,0xF0,0xD5,0xBE,0xB8,0x04,
+0xC8,0x2F,0xEA,0x2B,0x5A,0x08,0x01,0x2D,0x2E,0x17,0xFD,0x3D,0xC9,0x29,0x3C,0x03,
+0xFE,0xE2,0xBA,0x16,0xE2,0x40,0xE8,0x24,0x3C,0x03,0xFE,0xE7,0xBA,0x15,0xE2,0x40,
+0xE8,0x1F,0x46,0x01,0x00,0x07,0xEA,0x27,0xEA,0x21,0xEA,0x20,0xD0,0x19,0x46,0x01,
+0x00,0x07,0xEA,0x27,0xEA,0x48,0xEA,0x3F,0xD0,0x13,0x2E,0x07,0xFD,0x70,0x5C,0xF0,
+0x00,0xC8,0xE8,0x03,0x8C,0x01,0xD5,0x0D,0x3E,0x17,0xFD,0x70,0xEB,0x0A,0x46,0x01,
+0x00,0x02,0xDD,0x5D,0x50,0x10,0x7A,0xF0,0x49,0xFF,0xFF,0x1B,0xD5,0x04,0x84,0x00,
+0x3E,0x07,0xFD,0x70,0xB9,0x01,0x2E,0x07,0xFD,0x74,0xC0,0x0F,0xC9,0x0E,0x3C,0x03,
+0xFE,0xE6,0x2E,0x27,0xFD,0x75,0xE2,0x40,0xE8,0x06,0x3E,0x17,0xFD,0x74,0x3C,0x1B,
+0xFE,0xE6,0xD5,0x06,0x8C,0x01,0xD5,0x02,0x84,0x00,0x3C,0x0B,0xFE,0xE6,0xFC,0x80,
+0xFC,0x00,0x3F,0xCF,0xFE,0x1C,0x3C,0x13,0xFE,0xE2,0xB8,0x15,0xE2,0x20,0xE9,0x06,
+0x3C,0x13,0xFE,0xE7,0xB8,0x14,0xE2,0x20,0xE8,0x05,0x2E,0x07,0xFD,0x5D,0xC8,0x02,
+0xEA,0x76,0x2E,0x07,0xFD,0x4C,0xC0,0x2D,0x84,0x00,0xEA,0x76,0x2E,0x17,0xFD,0x28,
+0xB8,0x0C,0xE2,0x20,0xEA,0xF5,0xE8,0x22,0x42,0x20,0x84,0x0B,0xC2,0x1F,0xBA,0x00,
+0xC2,0x04,0x2E,0x27,0xFD,0x5D,0xC2,0x1A,0xDD,0x59,0x5C,0x10,0x00,0x01,0x84,0x01,
+0xEA,0xAB,0xDD,0x59,0x5A,0x00,0x01,0x04,0x84,0x07,0xD5,0x02,0x84,0x02,0x84,0x22,
+0xEA,0x34,0xDD,0x59,0x80,0xC0,0x5A,0x08,0x01,0x0E,0xEA,0x33,0xC8,0x04,0xEA,0xB7,
+0xEA,0xC4,0xD5,0x08,0x3E,0x67,0xFD,0x1A,0xD5,0x05,0xEA,0x5B,0xC1,0x03,0x8C,0x01,
+0xB8,0x8C,0xFC,0x80,0xFC,0x00,0x3F,0xCF,0xFD,0xD8,0x46,0x01,0x00,0x07,0x04,0x50,
+0x03,0xCE,0xEA,0x21,0xEA,0x20,0xD8,0x03,0x84,0x03,0xD5,0x1E,0x46,0x01,0x00,0x05,
+0xEB,0x1C,0x3C,0x13,0xFE,0xC8,0xE2,0x20,0x84,0x20,0xBA,0x0C,0xE8,0x0B,0xB9,0x8D,
+0xB8,0x07,0xE6,0x03,0xE8,0x04,0x8C,0x01,0xB8,0x87,0xD5,0x0F,0xC2,0x0E,0xB9,0x8C,
+0xD5,0x0C,0xB9,0x87,0xB8,0x0D,0xE6,0x0F,0xE8,0x04,0x8C,0x01,0xB8,0x8D,0xD5,0x05,
+0x5A,0x20,0x02,0x04,0x84,0x02,0xB8,0x8C,0xB8,0x0C,0xC8,0x0A,0x2E,0x07,0xFF,0xA9,
+0xEA,0x4B,0x3C,0x03,0xFE,0xCC,0xEA,0xB4,0x2E,0x07,0xFD,0x38,0xD5,0x22,0x5A,0x08,
+0x02,0x17,0x2E,0x07,0xFF,0xAA,0xEA,0x4B,0x3C,0x03,0xFE,0xCD,0xEA,0xB4,0x2E,0x07,
+0xFD,0x38,0xEA,0x97,0x2E,0x07,0xFD,0x39,0xEA,0x90,0x2E,0x07,0xFF,0xC6,0xEA,0x98,
+0x2E,0x07,0xFF,0xC7,0xEA,0xAD,0x2E,0x00,0x00,0xE6,0xD5,0x16,0x5A,0x08,0x03,0x18,
+0x2E,0x07,0xFF,0xAB,0xEA,0x4B,0x3C,0x03,0xFE,0xCC,0xEA,0xB4,0x2E,0x07,0xFD,0x2C,
+0xEA,0x97,0xEB,0x02,0xEA,0x90,0x2E,0x07,0xFF,0xC4,0xEA,0x98,0x2E,0x07,0xFF,0xC5,
+0xEA,0xAD,0x2E,0x00,0x00,0xE5,0xDD,0x49,0x3C,0x0B,0xFE,0xCF,0xEB,0x08,0xC0,0x1C,
+0xEB,0x38,0xC8,0x1A,0x2E,0x00,0x00,0x52,0xEA,0x4B,0x2E,0x00,0x00,0x54,0xEA,0xB4,
+0x2E,0x00,0x00,0x57,0x40,0x10,0x10,0x09,0x3E,0x17,0xFD,0x23,0xB9,0x1B,0x5A,0x18,
+0x01,0x04,0x96,0x1F,0xD5,0x02,0xEB,0x02,0xEA,0x90,0x2E,0x07,0xFF,0xC4,0xEA,0x98,
+0x2E,0x00,0x00,0x56,0xEA,0xAD,0xB8,0x00,0x5A,0x08,0x07,0x05,0x2E,0x07,0xFF,0xAD,
+0xEA,0x4B,0xEB,0x43,0xC0,0x04,0x2E,0x07,0xFF,0xB9,0xEA,0x4B,0xEA,0x49,0xC0,0x07,
+0x2E,0x07,0xFD,0x2C,0xEA,0x97,0xEB,0x02,0x8C,0x02,0xEA,0x90,0xB8,0x1C,0xC0,0x03,
+0x84,0x00,0xEA,0x97,0xFC,0x80,0xFC,0x40,0x2E,0x50,0x00,0x58,0x40,0x62,0x90,0x09,
+0x4E,0x62,0x01,0x38,0x46,0x01,0x00,0x07,0x04,0x10,0x03,0xC5,0xEA,0x21,0xEA,0x20,
+0x4C,0x10,0x00,0x06,0xDD,0x4D,0xEB,0x18,0x4E,0x02,0x01,0x2C,0xEA,0x94,0x3C,0x0D,
+0xFF,0x8A,0x4E,0x13,0x01,0x0E,0xE6,0x02,0x4E,0xF2,0x01,0x0B,0x2E,0x37,0xFD,0x65,
+0x4E,0x33,0x01,0x07,0x2E,0x20,0x00,0x5C,0x2E,0x70,0x01,0x29,0x54,0x01,0x00,0x0F,
+0x8C,0xE1,0x9C,0x41,0x8A,0xE0,0xEA,0x3C,0x92,0x44,0x51,0x00,0x00,0x01,0x51,0x21,
+0x00,0x01,0x8B,0x82,0x80,0x03,0x80,0x43,0xFB,0xF6,0x46,0x91,0x00,0x04,0x58,0x94,
+0x84,0xB8,0xE0,0x27,0xE8,0x19,0x42,0xA0,0xCC,0x24,0x80,0x92,0xE0,0x90,0xE8,0x11,
+0x41,0x12,0x28,0x00,0x41,0x14,0xC4,0x20,0x02,0xF8,0x80,0x00,0xEA,0x7E,0xE0,0x0F,
+0xE8,0x05,0x02,0x08,0x80,0x00,0x80,0x61,0x80,0x44,0x8C,0x81,0x97,0x20,0xD5,0xEF,
+0x8C,0x21,0x96,0x48,0xD5,0xE7,0x46,0x11,0x00,0x07,0x12,0x00,0x87,0xBB,0x2E,0x40,
+0x00,0x83,0x2E,0x10,0x00,0x84,0xE2,0x04,0x40,0x10,0x80,0x06,0x41,0x07,0x84,0x02,
+0x3F,0x07,0xFD,0x55,0x2E,0x10,0x00,0x5A,0xE2,0x20,0xE8,0x0D,0x2E,0x10,0x00,0x59,
+0xE2,0x01,0xE8,0x09,0x3C,0x43,0xFE,0xC4,0x2E,0x70,0x00,0x5B,0x84,0x2A,0xFE,0x7C,
+0xE0,0x24,0xE9,0x03,0x4F,0x02,0x00,0xB0,0xFA,0x96,0xFF,0x1C,0x47,0x11,0x00,0x04,
+0x59,0x18,0x84,0xB8,0x99,0xE2,0x95,0xF9,0x8E,0xE2,0x40,0x13,0xC4,0x00,0xA4,0x48,
+0x8C,0xE4,0x88,0xF1,0x41,0x20,0x80,0x11,0xA4,0x78,0x50,0x72,0x7F,0xDA,0x96,0x4B,
+0x88,0xE2,0x95,0xF9,0x88,0x32,0x88,0x01,0x40,0x13,0xC4,0x00,0xA4,0x48,0x88,0x01,
+0x50,0x12,0x00,0x26,0x88,0x22,0x94,0x49,0x40,0x40,0xC4,0x00,0xA5,0x20,0x88,0x04,
+0x9F,0x3A,0x88,0x91,0xA5,0x20,0x8C,0xE2,0x88,0xF1,0x88,0x04,0xA5,0x38,0x88,0x04,
+0x9F,0x0A,0x88,0x91,0x8C,0x22,0xA5,0x20,0x88,0x31,0xA4,0x48,0x88,0x04,0x88,0x01,
+0x96,0x01,0x92,0x01,0x46,0x11,0x00,0x07,0x12,0x00,0x87,0xBC,0x2E,0x10,0x00,0x5D,
+0xE2,0x20,0xE8,0x03,0x4F,0x02,0x00,0x0E,0x2E,0x10,0x00,0x86,0xE2,0x20,0x4E,0xF2,
+0x00,0x84,0x2E,0x10,0x00,0x85,0xE2,0x01,0x4E,0xF2,0x00,0x7F,0x4F,0x02,0x00,0x7D,
+0xEA,0x92,0x5A,0x08,0xFF,0x04,0x48,0x00,0x00,0x7D,0xC8,0x08,0x3E,0x27,0xFD,0x3E,
+0x3E,0x37,0xFD,0x25,0x3E,0x07,0xFD,0x33,0xD5,0x4F,0x2E,0x07,0xFD,0x3E,0xE2,0x40,
+0xE8,0x03,0x9A,0x82,0xD5,0x02,0x8A,0x40,0x2E,0x07,0xFD,0x25,0x96,0x90,0xE2,0x60,
+0xE8,0x03,0x9A,0xC3,0xD5,0x02,0x8A,0x60,0xDD,0x5C,0x96,0xD8,0x80,0x82,0x42,0x41,
+0x80,0x73,0x97,0x5F,0x80,0x04,0x46,0x41,0x00,0x07,0x12,0x02,0x07,0xBD,0x9C,0x69,
+0x2E,0x00,0x00,0x5E,0x5A,0x68,0x01,0x0F,0x96,0x1F,0xE0,0x02,0xE9,0x03,0xE0,0x03,
+0xE8,0x03,0x84,0x1F,0xEA,0x8F,0x2E,0x57,0xFD,0x1E,0xD9,0x26,0x84,0x01,0xEA,0xFC,
+0xD5,0x23,0x92,0x04,0xE2,0x02,0xE9,0x03,0xE2,0x03,0xE8,0x04,0x84,0x1F,0xEA,0x8F,
+0xD5,0x1B,0x98,0x1A,0x2E,0x47,0xFD,0x33,0x96,0x00,0xE2,0x04,0xE8,0x07,0x8A,0x80,
+0xE4,0x83,0xE9,0x04,0x84,0x1F,0xEA,0x8F,0xD5,0x03,0x3E,0x07,0xFD,0x33,0xFE,0x94,
+0x42,0x21,0x8C,0x73,0xFE,0x4C,0x96,0x90,0xE0,0x22,0xE8,0x06,0xEA,0x92,0x90,0xA1,
+0xE0,0xA0,0xE9,0xDD,0xD5,0xE4,0xEA,0x92,0x5C,0xF0,0x00,0xF0,0xE8,0x1D,0x8C,0x01,
+0xEA,0x8F,0xD5,0x1A,0x5A,0x60,0x03,0x19,0x3F,0x07,0xFD,0x1E,0xD5,0x15,0x84,0x20,
+0x3E,0x17,0xFD,0x1E,0xC8,0x0E,0x2E,0x20,0x00,0x5F,0x3C,0x13,0xFE,0xCB,0x94,0x91,
+0xE0,0x22,0xE8,0x05,0x8C,0x21,0x3C,0x1B,0xFE,0xCB,0xD5,0x06,0xEA,0xFC,0xD5,0x02,
+0x84,0x00,0x3C,0x0B,0xFE,0xCB,0xEA,0x92,0x46,0x11,0x00,0x07,0x12,0x00,0x87,0xBA,
+0xFC,0xC0,0xFC,0x20,0x3F,0xCF,0xFE,0x1C,0x2E,0x50,0x01,0xCD,0x2E,0x40,0x01,0xCC,
+0x84,0x22,0x9A,0xAC,0x8C,0x41,0x40,0x21,0x04,0x56,0x2F,0x00,0x01,0xCE,0x88,0x44,
+0x2E,0x70,0x01,0xCF,0x96,0x10,0x46,0x21,0x00,0x01,0x00,0x21,0x0F,0xDD,0x46,0x61,
+0x00,0x07,0x9A,0x82,0x42,0x31,0x00,0x03,0x40,0x28,0x1C,0x01,0x8C,0x41,0x40,0x11,
+0x04,0x36,0x46,0x21,0x00,0x01,0x88,0x27,0x00,0x21,0x0F,0xDC,0x96,0x48,0x9A,0x8A,
+0x42,0x21,0x00,0x03,0x88,0x43,0x96,0xD1,0x12,0x33,0x07,0xB5,0x2E,0x37,0xFD,0x29,
+0xCB,0x21,0xB8,0x00,0xC0,0x57,0x46,0x01,0x00,0x01,0x00,0x10,0x0B,0xA0,0xC9,0x52,
+0x2E,0x00,0x00,0x60,0xE0,0x02,0xE8,0x13,0x2E,0x07,0xFD,0x6C,0x8C,0x01,0x96,0x00,
+0x3E,0x07,0xFD,0x6C,0x2E,0x07,0xFD,0x6C,0x2E,0x27,0xFD,0x32,0xE2,0x40,0xE8,0x42,
+0x84,0x01,0x3E,0x07,0xFD,0x29,0x3E,0x17,0xFD,0x68,0xD5,0x3C,0x3E,0x17,0xFD,0x6C,
+0xD5,0x39,0xBA,0x03,0xCA,0x07,0xBA,0x00,0xCA,0x05,0x3E,0x27,0xFD,0x6C,0x3E,0x27,
+0xFD,0x29,0x2E,0x30,0x00,0x64,0x46,0x21,0x00,0x01,0x04,0x21,0x03,0xFD,0xE2,0x62,
+0xE8,0x29,0xFA,0x76,0x80,0x40,0x42,0x23,0x8C,0x73,0xEB,0x19,0xEB,0x24,0x40,0x23,
+0x08,0x20,0x22,0x21,0x14,0xB2,0x5A,0x20,0xFD,0x1E,0x42,0x08,0x0C,0x73,0x40,0x23,
+0x00,0x20,0x22,0x01,0x14,0xB2,0x5A,0x00,0xFD,0x16,0xFE,0x5C,0x98,0x0C,0x40,0x03,
+0x00,0x20,0x22,0x00,0x14,0xB2,0x5A,0x00,0xFD,0x0E,0x88,0xA1,0x40,0x53,0x14,0x20,
+0x22,0x02,0x94,0xB2,0x5A,0x00,0xFD,0x07,0x84,0x00,0x3E,0x07,0xFD,0x6C,0x3E,0x07,
+0xFD,0x29,0xFC,0xA0,0x46,0x19,0x00,0x00,0x04,0x00,0x80,0x30,0xEA,0x37,0x14,0x00,
+0x80,0x30,0xDD,0x9E,0x46,0x19,0x00,0x28,0xA4,0xCA,0x84,0x41,0x40,0x21,0x00,0x0C,
+0x40,0x21,0x88,0x12,0xAC,0x8A,0x50,0x10,0x80,0x74,0x40,0x10,0x80,0x40,0xA6,0x08,
+0xDD,0x9E,0x46,0x09,0x00,0x88,0x84,0x21,0x10,0x10,0x00,0xA8,0x44,0x1F,0xFF,0xA5,
+0x10,0x10,0x00,0xE0,0x46,0x02,0xB1,0x18,0x50,0x00,0x03,0x00,0x46,0x13,0x00,0xB9,
+0xB6,0x01,0x46,0x06,0x65,0x5F,0x50,0x00,0x0F,0x00,0x46,0x13,0x00,0xEB,0xB6,0x01,
+0xDD,0x9E,0xFC,0x40,0x80,0xE1,0x81,0x20,0x80,0xC2,0xDD,0x52,0x46,0x33,0x00,0x00,
+0x88,0x67,0x4E,0x92,0x00,0x04,0xB6,0xC3,0xD5,0x03,0x97,0xB0,0xAF,0x98,0xDD,0x57,
+0x04,0x00,0x00,0x3A,0x92,0x0C,0x96,0x0F,0x5A,0x08,0x03,0x06,0x84,0x20,0x46,0x03,
+0x00,0xB9,0xB6,0x20,0x84,0x20,0xEA,0x5D,0x10,0x10,0x00,0xA8,0xFC,0xC0,0xFC,0x00,
+0xF8,0x32,0x80,0x43,0xDD,0x4C,0xFC,0x80,0xFC,0x20,0x80,0xE0,0x80,0xC1,0xDD,0x52,
+0x46,0x23,0x00,0x00,0xC7,0x13,0x98,0x32,0xA6,0x40,0x9C,0x11,0x88,0x06,0xA7,0x00,
+0x9C,0x12,0x88,0x06,0x9C,0xD3,0xA6,0x00,0x98,0xB3,0xA6,0x90,0xEA,0xE8,0x40,0x00,
+0x0B,0x04,0xFE,0x0F,0x40,0x00,0x11,0x04,0xD5,0x04,0x88,0x46,0xA6,0x10,0x96,0x00,
+0xEA,0x3E,0x04,0x10,0x80,0x3A,0x92,0x2C,0x96,0x4F,0x5A,0x18,0x03,0x06,0x84,0x40,
+0x46,0x13,0x00,0xB9,0xB6,0x41,0x84,0x40,0x46,0x19,0x00,0x88,0x10,0x20,0x80,0xA8,
+0xFC,0xA0,0xFC,0x00,0x40,0x10,0xA8,0x08,0x40,0x10,0x81,0x80,0x88,0x22,0x84,0x00,
+0x83,0xFF,0xEA,0x60,0x96,0x00,0xFC,0x80,0x46,0x38,0x00,0x00,0x84,0x40,0x50,0x31,
+0x80,0x34,0xB4,0x03,0x46,0x18,0x00,0x00,0x96,0x04,0xC0,0x06,0x5A,0x20,0x64,0x2E,
+0x8C,0x41,0x96,0x90,0xD5,0xF7,0x5A,0x20,0x64,0x29,0xA8,0x0C,0xA0,0x8C,0x50,0x40,
+0x80,0x20,0x58,0x21,0x00,0x80,0xA8,0x8C,0xA0,0x8C,0x66,0x21,0x1F,0x00,0x58,0x21,
+0x07,0x00,0xA8,0x8C,0xA0,0xCC,0x44,0x2C,0xFF,0xFF,0xFE,0x9E,0x42,0x21,0x44,0x08,
+0xA8,0x8C,0xB6,0x04,0xB4,0x64,0x46,0x2F,0x0F,0xFF,0x50,0x21,0x0F,0xFF,0xFE,0x9E,
+0x46,0x30,0x70,0x00,0xFE,0x9F,0xB6,0x44,0xB4,0x44,0x42,0x21,0x78,0x08,0xB6,0x44,
+0x84,0x44,0x10,0x20,0x80,0x24,0xDD,0x9E,0xFA,0x11,0xDD,0x9E,0xFC,0x63,0xF0,0x81,
+0xEB,0x5A,0xEB,0x30,0x44,0x00,0x04,0x00,0xF2,0x01,0xDD,0x48,0xEA,0x9B,0x81,0x60,
+0x4E,0x03,0x00,0x9B,0x46,0xEF,0xF0,0x0F,0x81,0x80,0x50,0x07,0x0F,0xFF,0x84,0xC1,
+0x85,0xA4,0xF0,0x84,0xEB,0x81,0x58,0x00,0x00,0x04,0x38,0x70,0x34,0x00,0x8C,0x01,
+0x38,0xA6,0x80,0x00,0x4E,0x72,0x00,0x89,0x54,0x05,0x00,0xFB,0x85,0x00,0xF0,0x83,
+0xE3,0x07,0x4E,0xF2,0x00,0x7B,0x40,0x04,0x34,0x00,0xEB,0x5A,0x58,0x10,0x80,0x00,
+0x88,0x01,0x00,0x90,0x00,0x06,0x5A,0xA0,0xBD,0x6B,0x5A,0xA8,0xE9,0x0C,0x54,0x04,
+0x80,0xC0,0x5A,0x08,0xC0,0x05,0x54,0xE4,0x80,0x3F,0xD5,0x0F,0x85,0xC1,0xC0,0x0D,
+0xD5,0x0B,0x5A,0xA8,0xC1,0x08,0x2E,0x07,0xFD,0x1B,0x81,0xC6,0x5A,0x08,0x01,0x06,
+0xD5,0x58,0x5A,0xA0,0xB6,0x0A,0x81,0xC6,0x88,0xC8,0x96,0x30,0xF0,0x81,0xEA,0xD3,
+0x84,0xC3,0xF0,0x82,0xD5,0x07,0x2E,0x07,0xFD,0x04,0x5A,0x00,0xFF,0xF6,0x81,0xC6,
+0xD5,0x48,0x80,0x0A,0x80,0x2C,0xF2,0x02,0x80,0x69,0xDD,0x54,0x5A,0xA0,0xB9,0x42,
+0xF0,0x03,0x5A,0x00,0xB2,0x3F,0x5A,0xA0,0xE9,0x3D,0x80,0x0A,0x80,0x2C,0xF2,0x02,
+0xEA,0x3A,0xF0,0x85,0x4C,0x90,0x00,0x36,0x44,0x00,0x00,0x32,0xDD,0x50,0x9E,0x31,
+0x97,0x80,0xF3,0x05,0xCE,0xE7,0x46,0x01,0x00,0x07,0x04,0x20,0x03,0xF0,0xF1,0x04,
+0x66,0x21,0x00,0xFF,0x40,0x25,0x08,0x04,0x14,0x20,0x03,0xF0,0x04,0x00,0x03,0xF0,
+0x44,0x2F,0x00,0xFF,0xFE,0x86,0x40,0x21,0x31,0x04,0x46,0x01,0x00,0x07,0x14,0x20,
+0x03,0xF0,0x04,0x00,0x03,0xF0,0x81,0x6A,0xFE,0x0E,0xF1,0x01,0x40,0x60,0x06,0x04,
+0x46,0x01,0x00,0x07,0x14,0x60,0x03,0xF0,0x04,0x10,0x03,0xF0,0x40,0x10,0xA0,0x08,
+0x92,0x28,0x40,0x10,0x8F,0x04,0x14,0x10,0x03,0xF0,0xD5,0x03,0x81,0xC6,0x81,0x89,
+0x8D,0x01,0x80,0xCE,0x48,0xFF,0xFF,0x86,0x8C,0xE2,0x40,0xD6,0x9C,0x00,0x5C,0xF6,
+0x84,0x00,0x4E,0xF3,0xFF,0x71,0x80,0x0B,0xFC,0xE3,0x46,0x09,0x00,0x08,0x02,0x50,
+0x00,0x08,0xEA,0xE9,0xD1,0x03,0x12,0x10,0x00,0x08,0xDD,0x9E,0xFC,0x00,0xEA,0x93,
+0x46,0x10,0x30,0x00,0xEA,0xB9,0x8C,0x21,0xEB,0x2B,0xB4,0x02,0x96,0x04,0xC0,0x04,
+0x8E,0x21,0xC9,0xFC,0xFA,0x14,0xFC,0x80,0xFC,0x00,0xDD,0x52,0x84,0x00,0x44,0x11,
+0x00,0x00,0x80,0x40,0xDD,0x4C,0xEA,0x4A,0xFC,0x80,0xFC,0x00,0xDD,0x52,0x84,0x00,
+0x44,0x11,0x10,0x00,0x80,0x40,0xDD,0x4C,0xEA,0x4A,0xFC,0x80,0xFC,0x00,0xDD,0x52,
+0x84,0x00,0x44,0x12,0x90,0x00,0x80,0x40,0xDD,0x4C,0xEA,0x4A,0xFC,0x80,0xFC,0x00,
+0xDD,0x52,0x84,0x00,0x44,0x12,0x80,0x00,0x80,0x40,0xDD,0x4C,0xEA,0x4A,0xFC,0x80,
+0x46,0x09,0x00,0x08,0xA5,0x46,0x44,0x10,0xAC,0x53,0xD1,0x04,0x44,0x1F,0xAC,0x53,
+0xAC,0x46,0xDD,0x9E,0x46,0x09,0x00,0x08,0xA4,0x46,0xC1,0x03,0x84,0x20,0xAC,0x46,
+0xDD,0x9E,0xFC,0x01,0xEA,0x38,0x00,0x1F,0x80,0x00,0x84,0x01,0x40,0x30,0x80,0x02,
+0x00,0x1F,0x80,0x01,0x00,0x2F,0x80,0x04,0xFE,0x46,0x40,0x11,0x84,0x20,0x00,0x3F,
+0x80,0x02,0xFE,0xC6,0x40,0x10,0x8C,0x60,0x00,0x3F,0x80,0x03,0xFE,0xC6,0x40,0x10,
+0x8C,0x80,0xFE,0x16,0x40,0x00,0x80,0xA0,0xEB,0x3E,0xEB,0x3A,0xEA,0x5C,0xFC,0x81,
+0x9E,0x41,0xE6,0x23,0xE8,0x1B,0xEA,0x28,0x84,0x40,0x10,0x20,0x80,0x94,0x84,0x41,
+0x10,0x20,0x80,0x94,0xEA,0x3E,0x5A,0x00,0x02,0x08,0x5A,0x00,0x03,0x0A,0xEA,0xD0,
+0x12,0x00,0x80,0x0A,0xD5,0x09,0x44,0x00,0x00,0xA5,0xAC,0x0E,0xD5,0x05,0x44,0x00,
+0x00,0x55,0x12,0x00,0x80,0x0C,0x84,0x00,0xDD,0x9E,0xFA,0x02,0xDD,0x9E,0x46,0x20,
+0x4C,0x4B,0x50,0x21,0x04,0x00,0xE2,0x41,0xE9,0x18,0xE6,0x04,0xE8,0x16,0xFC,0x01,
+0xF0,0x81,0x80,0xC1,0x84,0x00,0xF1,0x01,0xEA,0x3B,0x3C,0x1D,0xFF,0xE3,0xFA,0x44,
+0xFF,0x8C,0x84,0x00,0xF1,0x01,0x40,0x23,0x08,0x57,0xF8,0x2C,0x84,0x00,0xF1,0x01,
+0x84,0x48,0xF8,0x2D,0x84,0x00,0xFC,0x81,0xFA,0x02,0xDD,0x9E,0xE6,0x04,0xE8,0x2B,
+0xFC,0x40,0x80,0xE0,0x81,0x21,0x84,0x01,0x80,0x27,0xEA,0x3B,0x46,0x49,0x00,0x80,
+0x8C,0x84,0x40,0x42,0x1C,0xA0,0x44,0x10,0x00,0x65,0x8E,0x21,0x96,0x48,0xB4,0x64,
+0xB4,0x04,0xC1,0x1B,0x40,0x60,0x0C,0x04,0xCE,0xF9,0x40,0x24,0x88,0x09,0xDD,0x5C,
+0x42,0x11,0x00,0x24,0x2E,0x27,0xFD,0xEA,0x84,0x01,0x40,0x20,0x88,0x57,0x80,0x27,
+0x88,0x40,0x49,0x00,0x0A,0x6E,0x84,0x01,0x80,0x40,0x80,0x27,0x49,0x00,0x0A,0x74,
+0x80,0x06,0xD5,0x04,0xFA,0x02,0xDD,0x9E,0xFA,0x14,0xFC,0xC0,0x46,0x18,0x00,0x60,
+0x00,0x00,0x80,0x14,0xEB,0x03,0x10,0x00,0x80,0x14,0xDD,0x9E,0x46,0x08,0x00,0x60,
+0x00,0x10,0x00,0x10,0x84,0x01,0x40,0x00,0x04,0x12,0xDD,0x9E,0xFC,0x01,0x10,0x0F,
+0x80,0x07,0x00,0x0F,0x80,0x07,0x96,0x00,0xE6,0x06,0xE8,0x47,0x3E,0xFF,0xD5,0xF4,
+0x38,0x07,0x80,0x00,0x40,0xF0,0x3C,0x00,0x4A,0x00,0x3C,0x00,0x22,0x06,0x0A,0x10,
+0x16,0x1C,0xEB,0x0B,0xD5,0x0E,0x44,0x60,0x00,0x66,0xD5,0x0B,0x44,0x60,0x00,0x77,
+0xD5,0x08,0x44,0x60,0x00,0x99,0xD5,0x05,0x44,0x60,0x00,0xAA,0xD5,0x02,0x84,0xC0,
+0x46,0x19,0x00,0x78,0x00,0x0F,0x80,0x07,0xF8,0x03,0x46,0x19,0x00,0x70,0x00,0x00,
+0x80,0x08,0xEA,0x37,0xEA,0xFB,0x83,0xFF,0x2E,0x07,0xFD,0x02,0xC0,0x02,0xEB,0x0B,
+0xEA,0x69,0xEA,0xA3,0xC8,0x11,0xEA,0xA5,0xC8,0x0F,0x49,0xFF,0xE6,0x49,0xC8,0x0C,
+0xEA,0x3E,0x04,0x00,0x80,0x10,0x42,0x00,0x44,0x0B,0xC8,0x06,0x04,0x00,0x80,0x10,
+0x42,0x00,0x48,0x0B,0xC0,0x02,0xEB,0x0B,0x97,0xB1,0xDD,0x57,0x12,0x60,0x00,0x50,
+0x64,0x00,0x00,0x00,0x84,0x00,0xD5,0x02,0xFA,0x02,0xFC,0x81,0xFC,0x20,0x84,0xA0,
+0x50,0x21,0x00,0x24,0x80,0x85,0x45,0x20,0x00,0x48,0x47,0x11,0x00,0x07,0x59,0x18,
+0x85,0x00,0x2E,0x30,0x01,0x29,0xE0,0x83,0xE8,0x18,0x82,0x11,0x43,0x02,0x48,0x73,
+0x84,0x60,0x2E,0x60,0x01,0x28,0xE0,0x66,0xE8,0x0D,0x38,0x78,0x0D,0x01,0x99,0x9D,
+0x40,0x70,0x1C,0x20,0xA5,0xF8,0x40,0x60,0x98,0x20,0x97,0xFB,0xAD,0xF0,0x8C,0x61,
+0xD5,0xF1,0x8C,0x81,0x88,0xA2,0xD5,0xE6,0xFC,0xA0,0xFC,0x21,0x3F,0xCF,0xFD,0xD4,
+0xF0,0x81,0xDD,0x47,0x80,0xE1,0x80,0xC2,0xDD,0x40,0xC0,0x02,0x84,0xC4,0xEA,0x24,
+0xC0,0x1A,0xDD,0x43,0x02,0x30,0x00,0x9C,0x02,0x00,0x00,0x0A,0x8A,0x60,0x40,0x31,
+0xA4,0x08,0xBB,0x80,0x3C,0x3D,0xFF,0x75,0xFE,0xDA,0xBB,0x84,0x80,0x06,0x49,0x00,
+0x09,0x7C,0xB9,0x04,0xF0,0x01,0x44,0x20,0x01,0xB0,0x42,0x70,0x08,0x73,0x80,0x47,
+0x49,0x00,0x09,0x8C,0xFC,0xA1,0x00,0x00,0xFC,0x00,0xE6,0x28,0x4E,0xF2,0x01,0x89,
+0x9E,0x82,0xE6,0x47,0x4E,0xF2,0x01,0x85,0x44,0x30,0x01,0xAC,0x3E,0xFF,0xD7,0x34,
+0x38,0x27,0x88,0x00,0x40,0xF1,0x3C,0x00,0x4A,0x00,0x3C,0x00,0x08,0x08,0x08,0x08,
+0x08,0x0E,0x0E,0x00,0x44,0x20,0xD6,0xB0,0xD5,0x03,0x44,0x20,0xD3,0x58,0x42,0x20,
+0x8C,0x73,0x00,0x31,0x01,0x88,0x80,0x22,0xEA,0xB9,0x10,0x31,0x00,0x28,0x3C,0x3D,
+0xFF,0x76,0x8E,0x67,0xE6,0x62,0xE8,0x0F,0x46,0x31,0x00,0x07,0x04,0x51,0x83,0xC4,
+0x46,0x3A,0x55,0xAA,0x50,0x31,0x85,0x5A,0xD3,0x06,0x2E,0x37,0xFF,0xA3,0x42,0x31,
+0x90,0x0B,0xC3,0x05,0x04,0x30,0x80,0x59,0x14,0x31,0x00,0x30,0x46,0x28,0x00,0x20,
+0x00,0x30,0x81,0x89,0x10,0x31,0x02,0xBC,0x00,0x30,0x81,0x8A,0x10,0x31,0x00,0x2C,
+0x00,0x30,0x81,0x8B,0x10,0x31,0x02,0x38,0x04,0x30,0x80,0x4B,0x14,0x31,0x00,0x8D,
+0x04,0x30,0x80,0x4C,0x14,0x31,0x00,0x0E,0x00,0x30,0x81,0x8C,0x10,0x31,0x00,0x40,
+0x00,0x30,0x81,0x8D,0x10,0x31,0x00,0x44,0x00,0x30,0x81,0x8E,0x10,0x31,0x00,0x48,
+0x00,0x30,0x81,0x8F,0x10,0x31,0x00,0x4C,0x00,0x30,0x81,0x90,0x10,0x31,0x00,0x50,
+0x00,0x30,0x81,0x91,0x10,0x31,0x00,0x54,0x00,0x30,0x81,0x92,0x10,0x31,0x00,0x58,
+0x00,0x30,0x81,0x93,0x10,0x31,0x00,0x64,0x02,0x30,0x80,0xB4,0x12,0x31,0x00,0x12,
+0x02,0x30,0x80,0xB5,0x12,0x31,0x00,0x8A,0x02,0x30,0x80,0xB6,0x12,0x31,0x00,0x1E,
+0x00,0x30,0x81,0x94,0x10,0x31,0x00,0x28,0x00,0x30,0x81,0x95,0x10,0x31,0x00,0x34,
+0x00,0x30,0x81,0x96,0x10,0x31,0x02,0xAC,0x00,0x30,0x81,0x97,0x10,0x31,0x00,0x18,
+0x00,0x30,0x81,0x98,0x10,0x31,0x05,0x68,0x00,0x30,0x81,0x99,0x10,0x31,0x05,0x78,
+0x00,0x30,0x81,0x9A,0x10,0x31,0x01,0x30,0x00,0x30,0x81,0x9B,0x10,0x31,0x01,0x2C,
+0x00,0x30,0x81,0x9C,0x10,0x31,0x01,0xDC,0x00,0x30,0x81,0x9D,0x10,0x31,0x02,0x9C,
+0x00,0x30,0x81,0x9E,0x10,0x31,0x01,0xD8,0x02,0x30,0x80,0xB7,0x12,0x31,0x00,0x9A,
+0x02,0x30,0x80,0xB8,0x12,0x31,0x00,0x9C,0x02,0x30,0x80,0xB9,0x12,0x31,0x00,0x0A,
+0x02,0x30,0x80,0xBA,0x12,0x31,0x00,0xF8,0x02,0x30,0x80,0xBB,0x12,0x31,0x00,0xFC,
+0x02,0x30,0x80,0xBC,0x12,0x31,0x00,0xFE,0x02,0x30,0x80,0xBD,0x12,0x31,0x01,0x00,
+0x00,0x30,0x81,0x9F,0x10,0x31,0x02,0x04,0x04,0x30,0x80,0x4D,0x14,0x31,0x00,0x38,
+0x04,0x30,0x80,0x4E,0x14,0x31,0x00,0x39,0x00,0x30,0x81,0xA0,0x10,0x31,0x00,0xCC,
+0x00,0x30,0x81,0xA1,0x10,0x31,0x00,0xD0,0x02,0x30,0x80,0xBE,0x12,0x31,0x00,0xF6,
+0x04,0x30,0x80,0x4F,0x14,0x31,0x00,0x78,0x04,0x30,0x80,0x50,0x14,0x31,0x00,0x79,
+0x02,0x30,0x80,0xBF,0x12,0x31,0x00,0xF4,0x02,0x30,0x80,0xC0,0x12,0x31,0x02,0xB8,
+0x02,0x30,0x80,0xC1,0x12,0x31,0x00,0xB6,0x04,0x30,0x80,0x51,0x14,0x31,0x00,0xB1,
+0x04,0x30,0x80,0x52,0x14,0x31,0x00,0xB3,0x04,0x30,0x80,0x53,0x14,0x31,0x00,0xB4,
+0x04,0x30,0x80,0x3F,0x14,0x31,0x01,0x5F,0x04,0x30,0x80,0x40,0x14,0x31,0x01,0x60,
+0x04,0x30,0x80,0x41,0x14,0x31,0x01,0x61,0x04,0x30,0x80,0x42,0x14,0x31,0x01,0x62,
+0x04,0x30,0x80,0x43,0x14,0x31,0x01,0x63,0x04,0x30,0x80,0x44,0x14,0x31,0x01,0x64,
+0x04,0x30,0x80,0x45,0x14,0x31,0x01,0x65,0x04,0x30,0x80,0x46,0x14,0x31,0x01,0x66,
+0x04,0x30,0x80,0x47,0x14,0x31,0x01,0x67,0x04,0x30,0x80,0x48,0x14,0x31,0x01,0x68,
+0x04,0x30,0x80,0x49,0x14,0x31,0x01,0x69,0x04,0x30,0x80,0x4A,0x14,0x31,0x01,0x6A,
+0x00,0x30,0x81,0xA2,0x10,0x31,0x00,0xD8,0x04,0x30,0x80,0x54,0x14,0x31,0x00,0x30,
+0x04,0x30,0x80,0x55,0x14,0x31,0x00,0x31,0x04,0x30,0x80,0x56,0x14,0x31,0x00,0x32,
+0x00,0x30,0x81,0xA3,0x10,0x31,0x00,0xB0,0x00,0x30,0x81,0xA4,0x10,0x31,0x00,0xB4,
+0x00,0x30,0x81,0xA5,0x10,0x31,0x05,0xBC,0x04,0x30,0x80,0x57,0x14,0x31,0x00,0xB2,
+0x04,0x30,0x80,0x58,0x14,0x31,0x00,0xB0,0x00,0x30,0x81,0xA6,0x10,0x31,0x01,0x58,
+0x00,0x30,0x81,0xA7,0x10,0x31,0x01,0x5C,0x02,0x30,0x80,0xC2,0x46,0x52,0x00,0x00,
+0x12,0x31,0x00,0x94,0x50,0x22,0x80,0xFC,0xB4,0x61,0xB6,0x65,0xB4,0x85,0xB4,0x61,
+0x4C,0x41,0xFF,0xFC,0x8C,0xA4,0x8C,0x24,0xDA,0xF8,0x49,0xFF,0xC8,0x68,0x49,0xFF,
+0xC4,0x7C,0x46,0x00,0x00,0x0D,0x00,0x00,0x04,0xF9,0x8E,0x01,0x96,0x00,0x3E,0x07,
+0xFD,0x0E,0x46,0x00,0x00,0x0D,0x00,0x00,0x06,0xA5,0x8E,0x01,0x96,0x00,0x3E,0x07,
+0xFD,0x15,0xEA,0x9B,0x80,0xC0,0xC8,0x0E,0xDD,0x5C,0xDD,0x50,0xDD,0x4B,0x8E,0x07,
+0xE6,0x02,0xE8,0x08,0x84,0x21,0xDD,0x43,0x10,0x10,0x02,0xA0,0xD5,0x03,0xFA,0x02,
+0xD5,0x02,0x80,0x06,0xFC,0x80,0x92,0x00,0xFC,0x40,0x84,0xC0,0x80,0x26,0x84,0x01,
+0xEA,0x3B,0x80,0x26,0x8C,0xC1,0x84,0x00,0x97,0xB0,0xEA,0x3B,0x5A,0x68,0x04,0xF8,
+0x84,0xE0,0x3E,0x77,0xFD,0x19,0x46,0x68,0x00,0x20,0x85,0x21,0x3E,0x97,0xFD,0x01,
+0x10,0x73,0x01,0x68,0x44,0x00,0x01,0xF4,0x10,0x73,0x02,0x14,0x10,0x73,0x02,0xA0,
+0x10,0x73,0x00,0xB0,0x10,0x73,0x00,0x84,0x10,0x73,0x01,0x00,0x10,0x73,0x00,0x8C,
+0x10,0x73,0x00,0x1C,0x10,0x73,0x00,0x20,0xDD,0x50,0x10,0x93,0x00,0x20,0xDD,0x5C,
+0x10,0x73,0x00,0x94,0xEA,0x6E,0x8E,0x01,0xC8,0xFE,0x84,0x21,0x46,0x28,0x00,0x30,
+0x10,0x13,0x00,0x94,0x12,0x01,0x00,0xE4,0x10,0x13,0x00,0x90,0x46,0x19,0x00,0x68,
+0xAE,0x08,0xDD,0x4B,0x8E,0x07,0xE6,0x02,0xE8,0x0B,0x46,0x01,0x00,0x07,0xEA,0x63,
+0xEA,0x21,0xEA,0x20,0xD0,0x04,0xDD,0x4D,0xEA,0xF0,0xC0,0x02,0xEA,0x5E,0x84,0x20,
+0xEA,0x73,0xAE,0x40,0xDD,0x4F,0x46,0x01,0x00,0x00,0x58,0x00,0x0B,0x14,0x84,0x20,
+0xDD,0x42,0xFC,0xC0,0xFC,0x00,0x3F,0xCF,0xFD,0xD8,0x46,0x10,0x00,0xE7,0x84,0x00,
+0x50,0x10,0x8C,0x15,0x44,0x20,0x00,0x68,0xDD,0x4C,0xDD,0x43,0x84,0x21,0x46,0x20,
+0xFF,0xFF,0xEA,0x47,0x50,0x21,0x0F,0xFF,0x10,0x10,0x00,0x1C,0x10,0x10,0x00,0x84,
+0x10,0x10,0x00,0x80,0xEB,0x4C,0xB4,0xA0,0xEA,0x28,0xDA,0xFE,0x84,0xC1,0x84,0x00,
+0x10,0x60,0x80,0xFC,0x10,0x60,0x81,0x00,0x10,0x00,0x80,0x90,0xB8,0x00,0x8E,0x07,
+0xE6,0x02,0xE8,0x08,0xEA,0x5E,0xEA,0x5D,0xEB,0x00,0xEA,0x43,0xB4,0x01,0xEA,0xF3,
+0xB6,0x01,0x84,0x01,0xEA,0x55,0xB8,0x00,0x8E,0x02,0xE6,0x04,0xE8,0x05,0xFA,0x38,
+0xDD,0x43,0x10,0x10,0x00,0xD8,0xB8,0x00,0x5A,0x08,0x02,0x05,0x84,0x03,0x49,0x00,
+0x08,0xB8,0xB8,0x00,0x5A,0x08,0x06,0x07,0x44,0x10,0xFF,0xEE,0xDD,0x43,0x14,0x10,
+0x00,0xAD,0xFC,0x80,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x00,
+0xDD,0x45,0xDD,0x57,0xF8,0x07,0xC1,0x31,0x00,0x10,0x00,0x50,0x54,0x10,0x80,0xFE,
+0xEA,0xDF,0x04,0x10,0x00,0x15,0x92,0x30,0x96,0x48,0x83,0xFF,0x5A,0x18,0x33,0x26,
+0xEB,0x2C,0x8E,0x27,0xE6,0x22,0xE8,0x21,0x04,0x10,0x00,0x15,0x92,0x38,0x5A,0x18,
+0x11,0x05,0x3E,0x17,0xFD,0x06,0xD5,0x08,0x04,0x00,0x00,0x15,0x92,0x18,0x5A,0x08,
+0x22,0x04,0x3E,0x07,0xFD,0x06,0x2E,0x07,0xFD,0x06,0x5A,0x08,0x22,0x09,0xEA,0x48,
+0xEA,0x3F,0x83,0xFF,0x46,0x11,0x00,0x07,0xEA,0x70,0xD5,0x07,0x2E,0x07,0xFD,0x06,
+0x5A,0x08,0x11,0x04,0x84,0x01,0xEA,0xC8,0xDD,0x57,0x04,0x10,0x00,0x16,0x4E,0x00,
+0xFF,0xD4,0xC1,0x06,0x00,0x10,0x00,0x50,0x54,0x10,0x80,0xFD,0xEA,0xDF,0x04,0x00,
+0x00,0x17,0x5A,0x08,0xA5,0x11,0xFC,0x00,0x44,0x10,0x00,0x87,0xDD,0x57,0x14,0x10,
+0x00,0x17,0xF9,0x9A,0x84,0x00,0xEB,0x3E,0xEB,0x3A,0xEA,0x5C,0xEA,0x93,0xEA,0xCF,
+0xDD,0x50,0xD5,0xFD,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x00,
+0x58,0x00,0x01,0x00,0xDD,0x45,0xDD,0x9E,0xFC,0x00,0x46,0x01,0x00,0x07,0xDD,0x46,
+0x46,0x11,0x00,0x07,0x96,0x00,0x58,0x00,0x30,0x00,0xDD,0x45,0xDD,0x57,0x04,0x10,
+0x00,0x3A,0x83,0xFF,0x42,0x10,0xE0,0x0B,0xC1,0x08,0x44,0x10,0x00,0x49,0x12,0x10,
+0x00,0x0E,0x84,0x20,0x12,0x10,0x00,0x0E,0x04,0x00,0x00,0x3A,0x42,0x00,0x68,0x0B,
+0xC0,0x04,0x84,0x02,0x49,0xFF,0xFC,0x36,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,
+0x00,0x07,0x96,0x00,0x58,0x00,0x31,0x00,0xDD,0x45,0xFC,0x80,0xFC,0x01,0x80,0xC0,
+0x46,0x09,0x00,0x20,0xA0,0x84,0xB6,0x46,0xA0,0x05,0xB6,0x01,0xB4,0x66,0x42,0x11,
+0xC4,0x0B,0xC9,0x04,0x42,0x21,0xC0,0x0B,0xD5,0x03,0x84,0x41,0x80,0x22,0x42,0x01,
+0xC8,0x0B,0xC0,0x03,0x84,0x41,0x84,0x22,0x42,0x01,0xCC,0x0B,0xC0,0x03,0x84,0x41,
+0x84,0x23,0x42,0x01,0xD0,0x0B,0xC0,0x03,0x84,0x40,0x80,0x22,0x42,0x31,0xD4,0x0B,
+0xC3,0x08,0xEA,0x24,0x96,0x00,0xDD,0x55,0x49,0xFF,0xCA,0x02,0x84,0x40,0x84,0x21,
+0xB4,0x06,0x42,0x00,0x58,0x0B,0xC0,0x18,0x3C,0x0D,0xFF,0x77,0x5A,0x08,0x01,0x13,
+0xDD,0x4B,0x5A,0x08,0x06,0x10,0x84,0x25,0x84,0x02,0xEA,0x8E,0x2E,0x17,0xFD,0x13,
+0x8C,0x21,0x96,0x48,0x3E,0x17,0xFD,0x13,0x8C,0x21,0x94,0x09,0x54,0x00,0x00,0xFE,
+0xEB,0x20,0x84,0x40,0x84,0x22,0xB4,0x06,0x84,0xC1,0x42,0x00,0x5C,0x0B,0xC0,0x07,
+0xDD,0x4D,0xFE,0x36,0xC0,0x19,0x80,0x06,0xEB,0x48,0xD5,0x16,0xC2,0x10,0x5A,0x18,
+0x02,0x0B,0xF1,0x81,0xEA,0x93,0xF1,0x01,0x80,0x01,0x44,0x10,0x07,0xD0,0x49,0xFF,
+0xFC,0x0F,0xD5,0x0C,0x80,0x06,0xEA,0x3B,0xEB,0x41,0xD5,0x08,0x5A,0x10,0x02,0x07,
+0x84,0x00,0xEA,0x3B,0xD5,0x03,0x84,0x23,0xD5,0xFC,0xFC,0x81,0xFC,0x20,0x46,0x60,
+0x00,0xCB,0x50,0x73,0x08,0x02,0xDD,0x52,0x80,0x27,0x84,0x00,0xEA,0x60,0x54,0x20,
+0x00,0x7F,0x80,0x27,0x84,0x00,0xDD,0x4C,0x50,0x13,0x08,0x05,0x84,0x00,0xEA,0x60,
+0x96,0x00,0x92,0x03,0xFC,0xA0,0xFC,0x40,0x46,0x60,0x00,0xCB,0x50,0xA3,0x08,0x05,
+0x80,0x2A,0x80,0xE0,0x84,0x00,0xEA,0x60,0x50,0x63,0x08,0x02,0x81,0x20,0xDD,0x52,
+0x80,0x26,0x84,0x00,0xEA,0x60,0x54,0x20,0x00,0x7F,0x80,0x26,0x84,0x00,0xDD,0x4C,
+0x54,0x24,0x80,0x07,0x40,0x21,0x1C,0x64,0x84,0x00,0x80,0x2A,0x96,0x90,0xDD,0x4C,
+0xFC,0xC0,0x2E,0x07,0xFF,0x88,0xC0,0x34,0xFC,0x00,0xEA,0x73,0xA1,0x83,0x49,0xFF,
+0xFF,0xC7,0x46,0x21,0x00,0x00,0x02,0x51,0x03,0x01,0x44,0x20,0xA5,0x5A,0x80,0x20,
+0xDA,0x09,0x46,0x21,0x00,0x00,0x00,0x51,0x06,0x00,0xD0,0x04,0x00,0x01,0x06,0x00,
+0xD5,0x1C,0x3C,0x2D,0xFF,0xE6,0xE2,0x46,0xE8,0x04,0xC0,0x12,0x8E,0x01,0xD5,0x08,
+0x3C,0x2D,0xFF,0xE7,0xE2,0xC2,0xE8,0x06,0xE6,0x1F,0xE8,0x0A,0x8C,0x01,0x96,0x40,
+0xD5,0x07,0x44,0x0F,0xA5,0x5A,0x46,0x21,0x00,0x00,0x12,0x01,0x03,0x01,0x46,0x01,
+0x00,0x00,0x10,0x10,0x06,0x00,0x80,0x01,0x49,0xFF,0xFF,0xAF,0xFC,0x80,0xDD,0x9E,
+0x46,0x09,0x00,0x90,0xEB,0x29,0x58,0x10,0x80,0x04,0xEB,0x07,0x84,0x20,0x10,0x10,
+0x00,0x68,0xEB,0x4B,0x54,0x10,0x80,0xFB,0xEA,0x61,0xDD,0x9E,0xC3,0x20,0xFC,0x00,
+0x3E,0x07,0xFF,0x88,0x3C,0x1F,0xFF,0xE3,0x46,0x50,0x00,0xF4,0x3C,0x2F,0xFF,0xE4,
+0x99,0x8A,0x3C,0x3F,0xFF,0xE5,0x8A,0x22,0x50,0x42,0x82,0x40,0x42,0x53,0x10,0x24,
+0xFF,0x0C,0x40,0x52,0x8C,0xB7,0x40,0x32,0x0C,0x77,0x3C,0x5F,0xFF,0xE6,0x3C,0x3F,
+0xFF,0xE7,0xC0,0x07,0x49,0xFF,0xFF,0xD6,0x84,0x00,0xD5,0x03,0xFA,0x00,0xDD,0x9E,
+0xFC,0x80,0x46,0x09,0x00,0x90,0xEB,0x29,0xEA,0xB3,0xEB,0x07,0x84,0x20,0x10,0x10,
+0x00,0x64,0xEB,0x4B,0x54,0x10,0x80,0xFD,0xEA,0x61,0xDD,0x9E,0x46,0x09,0x00,0x90,
+0xEB,0x29,0x58,0x10,0x80,0x01,0xEB,0x07,0x84,0x2F,0xEA,0x2F,0xEB,0x4B,0x54,0x10,
+0x80,0xFE,0xEA,0x61,0xDD,0x9E,0x3E,0x07,0xFD,0xE8,0x84,0x60,0x3E,0x37,0xFD,0xE9,
+0x3E,0x17,0xFD,0xEA,0x3E,0x17,0xFD,0xEB,0x3E,0x27,0xFD,0xEC,0xC0,0x07,0xFC,0x00,
+0x49,0xFF,0xFF,0xD9,0x49,0xFF,0xFF,0xE4,0xFC,0x80,0xDD,0x9E,0xFC,0x20,0x46,0x08,
+0x00,0x50,0x46,0x69,0x00,0x00,0x84,0xE0,0xB4,0x00,0x12,0x73,0x00,0x4C,0x46,0x00,
+0x00,0x0F,0x04,0x00,0x02,0xC0,0xEA,0x9B,0xC8,0x2F,0x3E,0x77,0xFF,0x88,0x44,0x10,
+0x01,0xF4,0x3C,0x1F,0xFF,0xE3,0x84,0x2A,0x3C,0x1F,0xFF,0xE4,0x44,0x10,0x02,0x58,
+0x3C,0x1F,0xFF,0xE5,0x46,0x10,0x00,0xCF,0x50,0x10,0x88,0x50,0x3C,0x1F,0xFF,0xE6,
+0x46,0x10,0x00,0xC7,0x50,0x10,0x86,0x1A,0x3C,0x1F,0xFF,0xE7,0x44,0x10,0x00,0x80,
+0x84,0x45,0x49,0xFF,0xFF,0xC2,0x49,0xFF,0xFD,0x79,0x49,0x00,0x05,0x44,0x84,0x09,
+0xEB,0x3E,0xEB,0x3A,0xEA,0x5C,0xEA,0x4A,0xC8,0x07,0x44,0x10,0x00,0xDA,0x12,0x13,
+0x00,0x1A,0x12,0x13,0x00,0x1E,0xFC,0xA0,0x2E,0x07,0xFD,0xE8,0xC0,0x09,0x46,0x19,
+0x00,0x90,0xA6,0x08,0xEA,0x37,0xAE,0x08,0x84,0x01,0x3E,0x07,0xFD,0xE9,0xDD,0x9E,
+0x2E,0x07,0xFD,0xE8,0xC0,0x10,0xEB,0x2C,0xEA,0x73,0x5A,0x18,0x08,0x09,0xA0,0x41,
+0x84,0x20,0x3E,0x17,0xFD,0xE9,0x00,0x00,0x00,0x60,0xD5,0x05,0xA0,0x02,0x84,0x00,
+0x3E,0x07,0xFD,0xE9,0x84,0x00,0xDD,0x9E,0x46,0x28,0x00,0x20,0x02,0x11,0x00,0x9C,
+0x02,0x31,0x00,0x0A,0x02,0x01,0x00,0x0A,0x8A,0x23,0x96,0x4B,0x8E,0x09,0x96,0x01,
+0x9E,0xC9,0x12,0x01,0x00,0x94,0x84,0x80,0x46,0x09,0x00,0x68,0x96,0xD9,0xAF,0x00,
+0xAC,0xC2,0x10,0x40,0x00,0x08,0x84,0x83,0x10,0x40,0x00,0x0C,0x02,0x41,0x00,0x9A,
+0x46,0x22,0x00,0x00,0x40,0x21,0x10,0x56,0x8C,0x41,0x90,0x41,0xA8,0x85,0xEA,0xED,
+0x10,0x20,0x00,0x20,0x46,0x20,0x40,0x00,0x40,0x11,0x04,0x36,0x8C,0x21,0x90,0x21,
+0x14,0x10,0x00,0x09,0x84,0x21,0x12,0x30,0x00,0x14,0xAE,0x40,0xDD,0x9E,0x00,0x00,
+0xFC,0x01,0x3F,0xCF,0xFD,0xD8,0xF1,0x81,0xBA,0x00,0xBA,0x82,0xB8,0x80,0xB6,0x1F,
+0x2E,0x27,0xFF,0xA2,0x92,0x47,0x3E,0x27,0xFF,0x88,0x84,0x41,0x3E,0x27,0xFD,0x0D,
+0x3E,0x27,0xFD,0x0B,0x49,0xFF,0xFD,0x02,0xF1,0x01,0xB4,0x1F,0xC1,0x03,0x49,0xFF,
+0xF3,0x35,0xB8,0x00,0x9E,0x42,0xE6,0x27,0xE8,0x20,0x3E,0xFF,0xE0,0x50,0x38,0x17,
+0x84,0x00,0x40,0xF0,0xBC,0x00,0xDD,0x0F,0x08,0x08,0x08,0x08,0x16,0x1E,0x26,0x00,
+0xEB,0x4A,0xEA,0x74,0x2E,0x27,0xFD,0x79,0x84,0x20,0xE2,0x22,0xD5,0x0C,0x84,0x26,
+0xEA,0x74,0x85,0xE2,0xD5,0x08,0xEB,0x4A,0xEA,0x74,0x85,0xE0,0xD5,0x04,0x84,0x26,
+0xEA,0x74,0x85,0xE1,0x3C,0xFF,0xFF,0x7C,0xEA,0xF4,0xEA,0x8B,0xC1,0x03,0x84,0x22,
+0xB9,0x81,0xB9,0x06,0x49,0xFF,0xFB,0x42,0xC8,0x2F,0xB9,0x00,0x8E,0x27,0xE6,0x22,
+0xE8,0x25,0x46,0x11,0x00,0x07,0x04,0x50,0x83,0xC4,0x46,0x1A,0x55,0xAA,0x50,0x10,
+0x85,0x5A,0xD1,0x1C,0x2E,0x17,0xFF,0xA3,0xEB,0x34,0xC9,0x18,0x46,0x01,0x00,0x07,
+0xEA,0x63,0xEA,0x48,0xEA,0x3F,0xD8,0x06,0x44,0x11,0xFF,0x00,0xDD,0x57,0x14,0x10,
+0x00,0x30,0x84,0x05,0xEA,0x55,0xEA,0x93,0x84,0x20,0xDD,0x43,0xEA,0xF1,0x44,0x10,
+0x07,0xD0,0x84,0x02,0x49,0xFF,0xFA,0x3C,0xD5,0x07,0xB6,0x1F,0x49,0xFF,0xFF,0x5E,
+0x49,0xFF,0xFC,0xFA,0xB4,0x1F,0xFC,0x81,0x92,0x00,0x46,0x18,0x00,0x20,0x50,0x10,
+0x85,0xC8,0xA6,0x88,0xDD,0x43,0xCA,0xFE,0xFC,0x00,0x84,0x21,0x10,0x10,0x02,0xA0,
+0xEB,0x2C,0x5A,0x18,0x07,0x0C,0x46,0x10,0x00,0x0D,0x02,0x10,0x82,0x6C,0xEA,0xF1,
+0x46,0x10,0x00,0x0D,0x02,0x10,0x82,0x6D,0xD5,0x0C,0x5A,0x18,0x08,0x0D,0x46,0x10,
+0x00,0x0D,0x02,0x10,0x83,0x42,0xEA,0xF1,0x46,0x10,0x00,0x0D,0x02,0x10,0x83,0x43,
+0x12,0x10,0x00,0xB6,0xEA,0x28,0x02,0x00,0x82,0xB8,0x02,0x10,0x80,0xB6,0x49,0xFF,
+0xC5,0x86,0xEA,0x9B,0xFC,0x80,0x46,0x08,0x00,0x20,0x00,0x10,0x00,0xF8,0xEB,0x4C,
+0xEA,0xB3,0x10,0x10,0x7D,0xBC,0xEA,0xC1,0xEA,0x7F,0xB4,0xA0,0xD9,0xFF,0xDD,0x9E,
+0xC0,0x04,0xFC,0x00,0xEA,0x5E,0xFC,0x80,0xEA,0x3E,0x04,0x00,0x80,0x30,0x66,0x00,
+0x00,0x01,0x14,0x00,0x80,0x30,0xDD,0x9E,0xFC,0x21,0x3F,0xCF,0xFD,0xD8,0x46,0x01,
+0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x00,0x58,0x00,0x50,0x00,0xDD,0x45,
+0x46,0x69,0x00,0x20,0x04,0x03,0x00,0x0A,0xB6,0x1F,0xB4,0x1F,0xEB,0x12,0xB6,0x1F,
+0xF0,0x81,0xF0,0x01,0x66,0x00,0x00,0x04,0xF0,0x81,0xB6,0x1F,0xB4,0x3F,0x84,0x00,
+0x49,0x00,0x04,0x9B,0x80,0x1F,0xB0,0x41,0x49,0xFF,0xFD,0x62,0xB4,0x1F,0x42,0x00,
+0x2C,0x0B,0xC0,0x19,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x00,
+0x58,0x00,0x51,0x00,0xDD,0x45,0xB4,0x06,0x66,0x00,0x08,0x00,0xB6,0x06,0xB8,0x00,
+0x8E,0x07,0xE6,0x02,0xE8,0x08,0x84,0x00,0x49,0xFF,0xFF,0xBC,0xEA,0x5D,0x84,0x21,
+0x10,0x10,0x00,0xA0,0xB4,0x1F,0x42,0x00,0x28,0x0B,0xC0,0x33,0x46,0x01,0x00,0x07,
+0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x00,0x58,0x00,0x52,0x00,0xDD,0x45,0xEA,0x43,
+0xB4,0x01,0x66,0x00,0x04,0x00,0xB6,0x01,0xB8,0x00,0x5A,0x08,0x02,0x09,0xEA,0xDC,
+0x5A,0x08,0x01,0x06,0x84,0x06,0xB8,0x80,0x84,0x04,0xD5,0x0A,0xEA,0xDC,0xC8,0x0A,
+0xB8,0x00,0x8E,0x03,0xE6,0x03,0xE8,0x06,0x84,0x02,0xB8,0x80,0x84,0x03,0x49,0x00,
+0x05,0x40,0xB8,0x01,0x5A,0x08,0x02,0x0E,0xB8,0x00,0x5A,0x08,0x06,0x05,0xB8,0x02,
+0x5A,0x00,0x02,0x04,0x2E,0x07,0xFD,0x03,0x49,0xFF,0xFD,0x8F,0x84,0x00,0xB8,0x81,
+0xB4,0x1F,0x42,0x00,0x4C,0x0B,0xC0,0x0D,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,
+0x00,0x07,0x96,0x00,0x58,0x00,0x53,0x00,0xDD,0x45,0x84,0x00,0x49,0xFF,0xFF,0x72,
+0xF0,0x01,0x42,0x00,0x38,0x0B,0xC0,0x04,0x49,0xFF,0xF8,0xF4,0xD5,0x07,0xF0,0x01,
+0x42,0x00,0x3C,0x0B,0xC0,0x03,0x49,0xFF,0xF8,0xF7,0xF0,0x01,0x84,0xC1,0x42,0x00,
+0x0C,0x0B,0xC0,0x16,0xDD,0x43,0x00,0x00,0x03,0x40,0xB9,0x00,0x96,0x00,0x5A,0x18,
+0x06,0x10,0x54,0x00,0x00,0xFB,0xC8,0x0C,0xB8,0x01,0x5A,0x00,0x02,0x0A,0x84,0x25,
+0x84,0x02,0xEA,0x8E,0x3E,0x67,0xFD,0x13,0x84,0x04,0xEB,0x20,0xBE,0x81,0xF6,0x01,
+0x84,0xE1,0x42,0x63,0x04,0x0B,0x4E,0x62,0x00,0x39,0x46,0x01,0x00,0x07,0xDD,0x46,
+0x46,0x11,0x00,0x07,0x96,0x00,0x58,0x00,0x54,0x00,0xDD,0x45,0x84,0x00,0x80,0x27,
+0xEA,0xAB,0x49,0xFF,0xF9,0x5D,0x84,0x0E,0xDD,0x40,0xC0,0x04,0x49,0xFF,0xC4,0x71,
+0xD5,0x20,0xFA,0x02,0xDD,0x40,0xC8,0xFB,0xFA,0x06,0xDD,0x40,0xC8,0xF8,0x84,0x0A,
+0xDD,0x40,0xC8,0xF5,0xFA,0x0A,0xDD,0x40,0xC8,0xF2,0xFA,0x13,0xDD,0x40,0xC8,0xEF,
+0xFA,0x0E,0xDD,0x40,0xC8,0xEC,0xFA,0x18,0xDD,0x40,0xC8,0xE9,0xFA,0x1C,0xDD,0x40,
+0xC8,0xE6,0xDD,0x47,0xDD,0x40,0xC8,0xE3,0x84,0x07,0x84,0x21,0x49,0xFF,0xFE,0x62,
+0x84,0x00,0x3E,0x07,0xFF,0x87,0xD5,0x24,0xF0,0x01,0xEA,0xA3,0xC0,0x21,0x46,0x01,
+0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x00,0x58,0x00,0x55,0x00,0xDD,0x45,
+0x3E,0x67,0xFD,0x0F,0x80,0x26,0x3E,0x67,0xFD,0x14,0x80,0x06,0xEA,0xAB,0x49,0xFF,
+0xF9,0x1F,0x80,0x27,0x2E,0x07,0xFF,0xA6,0x49,0xFF,0xFE,0x44,0xDD,0x52,0x46,0x10,
+0x00,0xBC,0x80,0x06,0x8C,0x21,0x84,0x46,0xDD,0x4C,0x3E,0x77,0xFF,0x87,0x46,0x01,
+0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x00,0x58,0x00,0x56,0x00,0xDD,0x45,
+0xFC,0xA1,0xFC,0x00,0xE6,0x04,0xE8,0x03,0x8E,0x01,0xD5,0x1B,0x5A,0x00,0x04,0x04,
+0x5A,0x08,0x08,0x14,0x84,0x00,0x46,0x11,0x00,0x05,0x58,0x10,0x88,0x88,0x84,0x44,
+0xF8,0x17,0xEA,0x24,0xC0,0x16,0x2E,0x07,0xFD,0x6F,0x3E,0x07,0xFD,0x71,0x8C,0x01,
+0x96,0x04,0x3E,0x07,0xFD,0x6F,0xD5,0x0D,0x8E,0x05,0x96,0x40,0xE6,0x23,0xE8,0x09,
+0x84,0x23,0x40,0x10,0x04,0x16,0x84,0x44,0x96,0x00,0xEB,0x5A,0xEA,0x77,0xEA,0x7D,
+0xFC,0x80,0xFC,0x00,0x54,0x10,0x00,0xFB,0x5A,0x10,0x03,0x04,0x48,0x00,0x00,0x71,
+0xF8,0x75,0xB4,0xA2,0xDD,0x43,0xD9,0xFE,0xEB,0x0F,0x44,0x10,0xFE,0xFF,0x83,0xFF,
+0xF8,0x03,0x44,0x10,0xFD,0xFF,0xFE,0x56,0xEA,0x32,0xEB,0x0F,0x83,0xFF,0x44,0x10,
+0xFB,0xFF,0x4E,0x00,0xFF,0xFA,0x44,0x10,0xF7,0xFF,0xFE,0x56,0xEA,0x32,0x83,0xFF,
+0xFA,0x20,0xEA,0x61,0x10,0x10,0x00,0x48,0xEB,0x2D,0x2E,0x17,0xFD,0x6F,0xC1,0x22,
+0x5A,0x10,0x01,0x03,0xF8,0x51,0xEB,0x6D,0x02,0x51,0x06,0x8E,0xEB,0x6D,0x02,0x41,
+0x06,0x8F,0xEB,0x6D,0x02,0x31,0x06,0x8D,0xEB,0x6D,0x02,0x21,0x06,0x8B,0xF8,0x1E,
+0xEB,0x6D,0x04,0x21,0x03,0x37,0x83,0x80,0xBA,0x8E,0x84,0x40,0x10,0x20,0x02,0x38,
+0x46,0x20,0x08,0x09,0x50,0x21,0x0A,0x12,0xBA,0x8E,0x50,0x00,0x01,0x9C,0xAE,0x40,
+0xD5,0x2A,0xEB,0x6D,0x02,0x51,0x05,0xB8,0xEB,0x6D,0x02,0x41,0x05,0xB9,0xEB,0x6D,
+0x02,0x31,0x05,0xB7,0xEB,0x6D,0x02,0x21,0x05,0xB5,0x12,0x50,0x00,0x9C,0x12,0x40,
+0x00,0x0A,0x12,0x30,0x00,0x9A,0x12,0x20,0x00,0x8A,0x83,0xFF,0xEB,0x6D,0x04,0x21,
+0x02,0xCC,0x83,0x80,0xBA,0x8E,0xEA,0x75,0x46,0x10,0x08,0x09,0x50,0x10,0x8A,0x12,
+0xB9,0x8E,0x84,0x21,0x10,0x10,0x01,0x9C,0x50,0x00,0x01,0x9C,0xA6,0x40,0x5A,0x10,
+0x01,0xFF,0xF8,0x04,0xA6,0x40,0x5A,0x10,0x01,0xFF,0x48,0x00,0x00,0x6F,0x5A,0x00,
+0x04,0x06,0x5A,0x00,0x08,0x04,0x48,0x00,0x00,0x6B,0x46,0x28,0x00,0x20,0xEA,0xC1,
+0x50,0x21,0x03,0x3C,0xEA,0x7F,0x83,0xFF,0xB4,0xA2,0xDD,0x43,0xD9,0xFE,0x83,0x80,
+0xB9,0x0E,0x42,0x10,0xD4,0x09,0xB9,0x8E,0xEB,0x23,0xC9,0x24,0xEB,0x5D,0x00,0x30,
+0x8B,0x8D,0xEB,0x5D,0x00,0x20,0x8B,0x8E,0xEB,0x5D,0x00,0x10,0x8B,0x8F,0xF8,0x23,
+0xEB,0x5D,0x02,0x40,0x85,0xB8,0xEB,0x5D,0x02,0x30,0x85,0xB9,0xEB,0x5D,0x02,0x20,
+0x85,0xB7,0xEB,0x5D,0x02,0x10,0x85,0xB5,0xF8,0x28,0xEB,0x5D,0x04,0x10,0x82,0xCC,
+0xEB,0x1A,0xEB,0x5D,0x02,0x10,0x85,0xB6,0xEA,0x32,0xEB,0x5D,0x00,0x10,0x8B,0x8B,
+0xD5,0x30,0xEB,0x5D,0x00,0x30,0x8D,0x39,0xEB,0x5D,0x00,0x20,0x8D,0x3A,0xEB,0x5D,
+0x00,0x10,0x8D,0x3B,0x10,0x30,0x00,0x44,0x10,0x20,0x00,0x48,0xEB,0x2D,0x83,0xFF,
+0xEB,0x5D,0x02,0x40,0x86,0x8E,0xEB,0x5D,0x02,0x30,0x86,0x8F,0xEB,0x5D,0x02,0x20,
+0x86,0x8D,0xEB,0x5D,0x02,0x10,0x86,0x8B,0x12,0x40,0x00,0x9C,0x12,0x30,0x00,0x0A,
+0x12,0x20,0x00,0x9A,0x12,0x10,0x00,0x8A,0x83,0xFF,0xEB,0x5D,0x04,0x10,0x83,0x37,
+0xEB,0x1A,0xEB,0x5D,0x02,0x10,0x86,0x8C,0xEA,0x32,0xEB,0x5D,0x00,0x10,0x8D,0x37,
+0xEA,0x75,0x84,0x21,0x10,0x10,0x01,0x9C,0x49,0xFF,0xFC,0xF0,0xFC,0x80,0x00,0x00,
+0xFC,0x20,0x3F,0xCF,0xFD,0xD8,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,
+0x96,0x00,0x58,0x00,0x10,0x00,0xDD,0x45,0xDD,0x43,0x84,0x20,0x10,0x10,0x00,0x88,
+0x00,0x60,0x03,0x40,0xEA,0x69,0x97,0xB0,0xEB,0x18,0xC0,0x0B,0xB8,0x00,0x5A,0x08,
+0x06,0x09,0x84,0x22,0x84,0x00,0xEA,0x3B,0x84,0x02,0xEB,0x20,0x84,0x00,0xB8,0x81,
+0xDD,0x4B,0x8E,0x02,0xE6,0x07,0x4E,0xF2,0x01,0xA2,0x3E,0xFF,0xE6,0x20,0x38,0x07,
+0x81,0x01,0x40,0xF0,0x3C,0x00,0xDD,0x0F,0x0E,0x00,0x32,0x03,0x32,0x03,0x32,0x03,
+0x7C,0x01,0xAA,0x01,0x6E,0x02,0xDD,0x57,0x04,0x10,0x00,0x3A,0x9F,0xF1,0xEA,0xD7,
+0x84,0x01,0xC1,0x09,0x46,0x11,0x00,0x07,0xEA,0xD4,0x40,0x00,0x1C,0x0C,0x40,0x00,
+0x80,0x12,0xD5,0x08,0x46,0x11,0x00,0x07,0xEA,0xD4,0x40,0x00,0x1C,0x0C,0xFE,0x0F,
+0x96,0x01,0x46,0x11,0x00,0x07,0xEA,0x95,0x46,0x01,0x00,0x07,0x02,0x10,0x07,0xF4,
+0x44,0x00,0xDF,0xFF,0xFE,0x0E,0x46,0x11,0x00,0x07,0xEA,0x95,0xEA,0xD4,0x44,0x00,
+0xBF,0xFF,0xFE,0x0E,0x46,0x11,0x00,0x07,0xEA,0x95,0x02,0x00,0x87,0xF4,0x54,0x00,
+0x7F,0xFF,0xEA,0x95,0x84,0x00,0x3E,0x07,0xFF,0x86,0x84,0x0E,0xDD,0x40,0xC0,0x05,
+0x80,0x06,0x49,0xFF,0xC0,0x09,0xEA,0x6C,0xFA,0x02,0xDD,0x40,0xC8,0xFA,0xFA,0x06,
+0xDD,0x40,0xC8,0xF7,0x5A,0x60,0x01,0x04,0x48,0x00,0x01,0x53,0xDD,0x43,0x84,0x22,
+0xEA,0x58,0x84,0x23,0xEA,0x47,0xEA,0x42,0xE6,0x01,0xEA,0x66,0x97,0xF8,0xE6,0xE8,
+0xE8,0x04,0x80,0x06,0x49,0xFF,0xFE,0x6F,0x9E,0x33,0xE6,0x02,0xE9,0x08,0x9E,0x37,
+0xE6,0x02,0xE9,0x05,0x5A,0x60,0x08,0x03,0xEA,0x6C,0xD5,0x0F,0x80,0x06,0x49,0xFF,
+0xFE,0x8A,0x5A,0x60,0x04,0x05,0x5A,0x60,0x08,0x03,0xEA,0x6C,0xB8,0x00,0x49,0xFF,
+0xF1,0x4D,0x5A,0x60,0x04,0x13,0xD5,0xEF,0x84,0x01,0x44,0x10,0x04,0xA6,0xEA,0x8E,
+0x2E,0x07,0xFD,0x0F,0xC8,0x1A,0xEA,0x73,0xA6,0x40,0xEA,0xB3,0xAE,0x40,0xA6,0x40,
+0x58,0x10,0x80,0x04,0xAE,0x40,0xD5,0x11,0xEA,0x24,0x96,0x00,0xDD,0x55,0x49,0xFF,
+0xC4,0xD7,0xEA,0xDC,0x5A,0x00,0x01,0x04,0x48,0x00,0x00,0x4A,0xEA,0x43,0xB4,0x01,
+0x58,0x00,0x04,0x00,0xB6,0x01,0xD5,0x43,0x2E,0x07,0xFD,0x0F,0x8C,0x01,0x96,0x00,
+0xE6,0x04,0xE8,0x03,0xEA,0xD6,0xD5,0x3B,0x84,0x00,0xEA,0xD6,0xDD,0x43,0x00,0x10,
+0x03,0x20,0x5A,0x10,0x10,0x06,0x00,0x10,0x03,0x20,0x5A,0x18,0x06,0x31,0xEA,0xC1,
+0xEB,0x4C,0xEA,0x7F,0xB4,0xA0,0xD9,0xFF,0x46,0x19,0x00,0x90,0xA6,0x08,0xC8,0xFF,
+0x49,0xFF,0xFB,0x21,0xEA,0x69,0xEB,0x18,0xC0,0x09,0x2E,0x0F,0xFF,0xA2,0x4E,0x04,
+0x00,0x06,0x49,0xFF,0xFA,0xE5,0x3E,0x07,0xFD,0x03,0x49,0xFF,0xFB,0xF3,0xC0,0x17,
+0x48,0x00,0x00,0xE5,0x8E,0xC1,0xE6,0xC2,0x4E,0xF2,0x00,0xCE,0xDD,0x43,0x84,0x22,
+0xEA,0x58,0x84,0x23,0xEA,0x47,0xEA,0x42,0xE6,0x01,0xEA,0x66,0x84,0x44,0x84,0x00,
+0xEB,0x5A,0xEA,0x77,0xEA,0x7D,0xEA,0x24,0x96,0x00,0xDD,0x55,0x49,0xFF,0xB6,0x6C,
+0xEA,0x6C,0x5A,0x68,0x01,0x0A,0xDD,0x43,0x84,0x22,0xEA,0x58,0x84,0x23,0xEA,0x47,
+0xEA,0x42,0xE6,0x01,0xEA,0x66,0xDD,0x43,0x84,0x21,0x10,0x10,0x00,0xBC,0x50,0x00,
+0x00,0xBC,0xA6,0x40,0xC9,0xFF,0xEA,0x57,0xE6,0x03,0xEA,0x57,0xE9,0x0C,0x8E,0x02,
+0xE0,0xC0,0xE9,0x11,0xEA,0x57,0xE2,0x06,0xE9,0x0E,0x2E,0x17,0xFD,0x0E,0x9C,0x32,
+0x8A,0x01,0xD5,0x04,0xE2,0x06,0xE9,0x07,0x9E,0x31,0x96,0x00,0xEB,0x5A,0xEA,0x77,
+0x84,0x44,0xEA,0x7D,0xEA,0x57,0x4C,0x60,0x40,0x35,0x84,0xC1,0xDD,0x43,0x12,0x60,
+0x02,0xE0,0xEA,0x24,0x96,0x00,0xDD,0x55,0xEA,0x5E,0xEA,0x5D,0xEB,0x00,0xEA,0x43,
+0xB4,0x01,0xEA,0xF3,0xB6,0x01,0x2E,0x07,0xFF,0x86,0xE6,0x09,0xE9,0x04,0x84,0x04,
+0xEA,0x55,0xD5,0x02,0xEB,0x41,0x46,0x60,0x00,0xD8,0x50,0x63,0x0C,0x0D,0x80,0x26,
+0x44,0x20,0x00,0xAA,0x84,0x00,0xDD,0x4C,0x44,0x00,0x02,0xBC,0xDD,0x50,0x84,0x00,
+0x80,0x26,0x44,0x20,0x00,0xBA,0xDD,0x4C,0x2E,0x07,0xFF,0x86,0xE6,0x14,0xE8,0x04,
+0x8C,0x01,0x3E,0x07,0xFF,0x86,0xEA,0xA5,0x4E,0x02,0x00,0x5E,0x84,0x01,0xD5,0x02,
+0x84,0x02,0xEA,0x55,0xEA,0x6C,0xEA,0x82,0x4C,0x60,0x40,0x56,0x49,0xFF,0xFB,0x66,
+0x2E,0x17,0xFD,0x15,0xDD,0x43,0x5A,0x10,0x01,0x05,0x84,0x22,0x10,0x10,0x00,0xB4,
+0x84,0xC1,0x84,0x22,0x10,0x60,0x01,0xCC,0xEA,0x58,0x84,0x23,0xEA,0x47,0xEA,0x5E,
+0xEA,0x5D,0xEB,0x00,0xEA,0x43,0xB4,0x01,0xEA,0xF3,0xB6,0x01,0xEA,0x82,0x5A,0x08,
+0x01,0x18,0xB8,0x00,0x5A,0x08,0x08,0x15,0x46,0x60,0x00,0xD8,0x50,0x63,0x0C,0x0D,
+0x49,0xFF,0xFC,0x3B,0x80,0x26,0x44,0x20,0x00,0xAA,0x84,0x00,0xDD,0x4C,0x44,0x00,
+0x02,0xBC,0xDD,0x50,0x84,0x00,0x80,0x26,0x44,0x20,0x00,0xBA,0xDD,0x4C,0xEA,0x42,
+0xE6,0x01,0xEA,0x66,0x84,0x44,0x84,0x00,0xEB,0x5A,0xEA,0x77,0xEA,0x7D,0xEA,0x82,
+0x5A,0x00,0x01,0x0E,0xDD,0x43,0x84,0x21,0x10,0x10,0x00,0xBC,0x50,0x10,0x00,0xBC,
+0xA6,0x08,0x96,0x00,0xC8,0xFE,0xEA,0x28,0x10,0x00,0x80,0xB4,0xDD,0x43,0x84,0xC1,
+0x12,0x60,0x02,0xE0,0xEA,0x24,0x96,0x00,0xDD,0x55,0x84,0x04,0xEA,0x55,0xEA,0xA5,
+0xC0,0x02,0xEB,0x41,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x00,
+0x58,0x00,0x11,0x00,0xDD,0x45,0x84,0x00,0xD5,0x09,0xFA,0x02,0xD5,0x07,0x5A,0x60,
+0x05,0x04,0x48,0xFF,0xFE,0xB5,0x48,0xFF,0xFE,0xB0,0xFC,0xA0,0xFC,0x00,0x84,0x00,
+0xEB,0x48,0x2E,0x27,0xFF,0xF0,0x84,0x2A,0xFE,0x54,0x84,0x03,0xEA,0x8E,0xFC,0x80,
+0x2E,0x07,0xFF,0x87,0xDD,0x9E,0x8E,0x01,0xC0,0x03,0xEA,0x6E,0xD5,0xFD,0xDD,0x9E,
+0xFC,0x01,0x10,0x0F,0x80,0x07,0x10,0x1F,0x80,0x06,0x46,0x08,0x00,0x30,0x84,0x20,
+0x10,0x2F,0x80,0x05,0x10,0x10,0x00,0x0C,0x10,0x10,0x00,0x10,0x84,0x21,0x10,0x10,
+0x00,0x14,0x00,0x1F,0x80,0x07,0x96,0x48,0x10,0x10,0x00,0x34,0x00,0x1F,0x80,0x06,
+0x96,0x48,0x10,0x10,0x00,0x38,0x00,0x1F,0x80,0x05,0x96,0x48,0x10,0x10,0x00,0x3C,
+0xFC,0x81,0x84,0x00,0x46,0x21,0x00,0x05,0x58,0x21,0x0A,0x38,0x96,0x40,0x38,0x11,
+0x00,0x08,0x50,0x30,0x00,0x6C,0x56,0x10,0x80,0x80,0x8C,0x01,0x38,0x11,0x0C,0x08,
+0x5A,0x08,0x6C,0xF6,0xDD,0x9E,0x46,0x38,0x00,0x30,0xA6,0x98,0x46,0x18,0x00,0x30,
+0x96,0x90,0x83,0xFF,0xCA,0xFB,0xFA,0x6C,0x10,0x20,0x81,0xB4,0xAE,0xCC,0x10,0x00,
+0x80,0xC4,0x84,0x05,0x10,0x20,0x80,0x18,0x10,0x20,0x81,0x18,0x10,0x00,0x80,0x0C,
+0x84,0x01,0xEA,0xFB,0x83,0xFF,0xDD,0x9E,0x46,0x08,0x00,0x30,0x14,0x10,0x00,0x32,
+0x44,0x1F,0xFF,0xD8,0x10,0x10,0x00,0x34,0x10,0x10,0x00,0x38,0x84,0x20,0x10,0x10,
+0x00,0xC0,0x46,0x11,0x00,0x05,0x58,0x10,0x8A,0x38,0x12,0x10,0x00,0x5C,0x96,0x91,
+0x84,0x21,0x12,0x20,0x00,0x5E,0xAE,0x40,0xA6,0x40,0xC9,0xFF,0xDD,0x9E,0x46,0x19,
+0x00,0x28,0x10,0x00,0x80,0x68,0xDD,0x9E,0x96,0x00,0x46,0x19,0x00,0x28,0x10,0x00,
+0x80,0x60,0xDD,0x9E,0x46,0x08,0x00,0x20,0x00,0x00,0x04,0xB4,0xDD,0x9E,0xE6,0x24,
+0xE8,0x09,0x94,0x4D,0xC0,0x03,0xEB,0x33,0xD5,0x03,0x46,0x09,0x00,0x10,0x88,0x20,
+0xB6,0x41,0xDD,0x9E,0xE6,0x24,0xE8,0x0C,0x94,0x4D,0x96,0x90,0xC0,0x04,0xEB,0x33,
+0x8C,0x10,0xD5,0x04,0x46,0x09,0x00,0x10,0x8C,0x08,0x88,0x20,0xAE,0x88,0xDD,0x9E,
+0xE6,0x24,0xE8,0x1C,0x94,0x4D,0xC0,0x10,0xEB,0x33,0x50,0x30,0x00,0x10,0x88,0x61,
+0x84,0x42,0xAE,0x98,0xA6,0x98,0x96,0x90,0xCA,0xFE,0x8C,0x0C,0x88,0x20,0xAE,0x88,
+0xA6,0x08,0xC8,0xFF,0xDD,0x9E,0x46,0x29,0x00,0x10,0x8C,0x48,0x88,0x22,0xAE,0x08,
+0x44,0x00,0x00,0x40,0xAE,0x08,0xA6,0x08,0xC8,0xFF,0xDD,0x9E,0x46,0x29,0x00,0x20,
+0xB6,0x02,0xA8,0x51,0xDD,0x9E,0x46,0x29,0x00,0x20,0x14,0x01,0x00,0x09,0x14,0x11,
+0x00,0x0A,0xDD,0x9E,0x46,0x18,0x00,0x60,0xB6,0x01,0xDD,0x9E,0x46,0x01,0x00,0x00,
+0xEA,0x4D,0xEB,0x04,0xD0,0x16,0x46,0x01,0x00,0x00,0xEA,0x4D,0x44,0x00,0xA3,0x3A,
+0xD0,0x10,0x46,0x01,0x00,0x00,0xEA,0x4D,0xEB,0x06,0xD0,0x0B,0x46,0x01,0x00,0x00,
+0x02,0x00,0x00,0x00,0x84,0x20,0x50,0x00,0x45,0x5D,0x40,0x00,0x80,0x06,0xDD,0x9E,
+0x84,0x00,0xDD,0x9E,0x46,0x01,0x00,0x00,0xEA,0x4D,0xEB,0x06,0xD0,0x07,0x46,0x01,
+0x00,0x00,0xEA,0x4D,0x44,0x00,0x3A,0xA3,0xD8,0x3F,0xEA,0x84,0xC0,0x3D,0xFC,0x20,
+0x49,0xFF,0xBB,0x81,0xEA,0xAE,0xEA,0x3C,0x84,0xA0,0x98,0x50,0x42,0x11,0x00,0x73,
+0x2E,0x00,0x00,0x02,0x46,0x31,0x00,0x00,0x58,0x31,0x80,0x04,0x88,0x20,0x3C,0x23,
+0xFE,0xC1,0x44,0x60,0x5A,0xA5,0x80,0x05,0xD1,0x11,0x46,0x41,0x00,0x00,0x02,0x42,
+0x00,0x00,0x4C,0x43,0x00,0x06,0x99,0x2A,0x40,0x42,0x04,0xF7,0xAD,0xD8,0x0A,0x41,
+0x80,0x01,0x8C,0xA1,0x88,0x04,0x96,0x01,0xD5,0xF0,0xFE,0x02,0x96,0x01,0xEB,0x5A,
+0x12,0x00,0x80,0x01,0x46,0x01,0x00,0x00,0xEA,0x4D,0xEB,0x06,0xD8,0x04,0x44,0x0F,
+0xA5,0x5A,0xD5,0x03,0x44,0x0F,0xA3,0x3A,0xEB,0x5A,0x12,0x00,0x80,0x00,0x8C,0x41,
+0x3C,0x2B,0xFE,0xC1,0xFC,0xA0,0xDD,0x9E,0xFC,0x00,0xF8,0x15,0x42,0x10,0x8C,0x0B,
+0xC9,0x08,0xF8,0x1C,0xC9,0x06,0x02,0x00,0x00,0x72,0x42,0x00,0x28,0x0B,0xC0,0x36,
+0xDD,0x4D,0x96,0x04,0xC0,0x08,0x46,0x09,0x00,0x28,0x84,0x21,0x10,0x10,0x00,0x68,
+0x84,0x22,0xEA,0x2F,0xDD,0x57,0x02,0x10,0x00,0x72,0x83,0xFF,0xEA,0xD7,0xC1,0x06,
+0x46,0x0E,0xBE,0xBE,0x50,0x00,0x0B,0xEB,0xD5,0x14,0x02,0x10,0x00,0x72,0xEB,0x34,
+0x83,0xFF,0xC1,0x06,0x46,0x0E,0xCE,0xCE,0x50,0x00,0x0C,0xEC,0xD5,0x0A,0x02,0x00,
+0x00,0x72,0x42,0x00,0x0C,0x0B,0xC0,0x07,0x46,0x0E,0xDE,0xDE,0x50,0x00,0x0D,0xED,
+0x49,0xFF,0xB3,0x00,0xDD,0x4D,0x96,0x04,0xC0,0x05,0xEA,0xA5,0xC0,0x03,0x49,0xFF,
+0xFE,0x8F,0x44,0x00,0x13,0x88,0x49,0xFF,0xB2,0xEA,0xFC,0x80,0xFC,0x00,0xEA,0x4A,
+0xDD,0x52,0xEA,0xCE,0x84,0x20,0x84,0x41,0xEA,0x3A,0x5A,0x08,0xEE,0x04,0x84,0x00,
+0xD5,0x20,0xEA,0xCE,0x84,0x20,0x84,0x41,0xEA,0x3A,0x5A,0x08,0xDE,0x04,0x84,0x01,
+0xD5,0x18,0xEA,0xCE,0x84,0x20,0x84,0x41,0xEA,0x3A,0x5A,0x08,0xCE,0x17,0x44,0x00,
+0x00,0xE8,0x84,0x20,0x84,0x46,0xEA,0x3A,0x5A,0x08,0x03,0x04,0x84,0x02,0xD5,0x09,
+0x44,0x00,0x00,0xE8,0x84,0x20,0x84,0x46,0xEA,0x3A,0x5A,0x08,0x04,0x07,0x84,0x03,
+0x46,0x11,0x00,0x07,0x12,0x00,0x80,0x40,0xEA,0x3E,0x46,0x21,0x00,0x07,0x04,0x00,
+0x80,0x34,0x00,0x21,0x00,0x80,0xFE,0x17,0x14,0x00,0x80,0x74,0xFC,0x80,0x5A,0x00,
+0x05,0x0B,0x5A,0x00,0x06,0x14,0x5A,0x08,0x03,0x29,0xF8,0x10,0x44,0x10,0xFF,0x00,
+0xF8,0x15,0xD5,0x1F,0xF8,0x0B,0x84,0x30,0xF8,0x11,0x46,0x13,0x11,0x50,0x50,0x10,
+0x8E,0x07,0xEA,0xCB,0x14,0x10,0x01,0x60,0xD5,0x14,0xDD,0x43,0x84,0x20,0xEB,0x31,
+0xEB,0x32,0x83,0xFF,0xEB,0x31,0xEB,0x32,0x84,0x3A,0x14,0x10,0x00,0xAD,0x84,0x27,
+0x10,0x10,0x02,0xAC,0x83,0xFF,0x46,0x10,0x03,0x10,0x50,0x10,0x80,0x31,0xEA,0xCB,
+0x84,0x21,0xDD,0x43,0x10,0x10,0x01,0xCC,0xDD,0x9E,0xFC,0x40,0xDD,0x52,0xF8,0x03,
+0xFA,0x72,0xDD,0x54,0xDD,0x53,0x84,0x20,0x84,0x4D,0x83,0xFF,0xFA,0x73,0xDD,0x54,
+0xEA,0xCF,0x49,0xFF,0xFE,0x22,0x84,0xE0,0x46,0x91,0x00,0x07,0x58,0x94,0x82,0x98,
+0xDD,0x53,0x84,0x20,0x84,0x41,0x83,0xFF,0x84,0x65,0xDD,0x54,0x50,0x33,0xFF,0xF3,
+0xDD,0x53,0x84,0x20,0x84,0x42,0x83,0xFF,0x96,0xD8,0xDD,0x54,0xDD,0x53,0x84,0x20,
+0x84,0x44,0x44,0x30,0x00,0x80,0xDD,0x54,0x44,0x60,0x00,0x64,0xEA,0x6E,0x8E,0xC1,
+0x97,0xB1,0xCE,0xFD,0xDD,0x53,0x80,0x26,0x84,0x44,0x80,0x66,0xDD,0x54,0xDD,0x53,
+0x80,0x26,0x84,0x45,0xEA,0x3A,0x38,0x04,0x9C,0x08,0x8C,0xE1,0x5A,0x78,0x0D,0xDA,
+0x44,0x00,0x72,0xC4,0x46,0x11,0x00,0x07,0x14,0x00,0x80,0xB1,0x84,0x41,0x80,0x26,
+0xDD,0x53,0x44,0x30,0x00,0x40,0xDD,0x54,0xDD,0x53,0x80,0x26,0x80,0x47,0xFA,0x70,
+0xDD,0x54,0xFC,0xC0,0xFC,0x00,0x84,0x22,0x80,0xC0,0x80,0x41,0xEA,0xD0,0x84,0x61,
+0xDD,0x54,0x84,0x67,0x40,0x31,0x98,0x64,0xEA,0xD0,0x84,0x22,0x84,0x45,0x96,0xD8,
+0xDD,0x54,0xFC,0x80,0x84,0x80,0xD5,0x2D,0x41,0x41,0x40,0x09,0x97,0x41,0x92,0x10,
+0x40,0x40,0xD0,0x37,0x96,0xD1,0x40,0x10,0xC0,0x08,0xFE,0x47,0x42,0x02,0x0C,0x24,
+0xE2,0x20,0xE8,0x09,0x9F,0x21,0x98,0x4A,0xE2,0x22,0xE9,0x05,0xE2,0x20,0xE8,0x03,
+0x9F,0x21,0x98,0x4A,0x9A,0x48,0x40,0x10,0xD0,0x17,0x40,0x00,0x40,0x08,0xFE,0x2F,
+0xFE,0xCC,0xE2,0x03,0xE8,0x09,0x98,0x02,0x9E,0x49,0xE2,0x02,0xE9,0x05,0xE2,0x03,
+0xE8,0x03,0x98,0x02,0x9E,0x49,0x9A,0x03,0x40,0x42,0x40,0x08,0xFE,0x67,0xDD,0x9E,
+0x3B,0xFF,0xFE,0xBC,0xFD,0x80,0xFD,0x91,0x83,0x84,0xCB,0x4D,0xE3,0xB2,0xE8,0x19,
+0x42,0x09,0x00,0x07,0x82,0xA0,0xC0,0x0D,0x41,0x29,0x00,0x0C,0x52,0x50,0x00,0x20,
+0x40,0x58,0x14,0x0D,0x41,0x18,0x80,0x0C,0x41,0x18,0x94,0x04,0x41,0x08,0x00,0x0C,
+0xFD,0x08,0x80,0x52,0x49,0xFF,0xFF,0xBA,0x82,0xC1,0x82,0x00,0x86,0xE0,0xD5,0x23,
+0xC2,0x28,0x42,0x09,0x00,0x07,0x82,0xA0,0xC8,0x04,0x8B,0xB2,0x86,0xE1,0xD5,0x14,
+0x52,0xF0,0x00,0x20,0x41,0x29,0x00,0x0C,0x80,0x52,0x40,0x48,0x3C,0x0D,0x40,0x58,
+0x80,0x0C,0x41,0x08,0x00,0x0C,0x40,0x02,0x90,0x04,0x40,0x18,0xBC,0x0D,0x49,0xFF,
+0xFF,0x9D,0x82,0xE1,0x82,0x20,0xFD,0x08,0x80,0x52,0x49,0xFF,0xFF,0x97,0x82,0xC1,
+0x51,0x00,0x00,0x00,0x4F,0xC2,0x00,0x53,0x86,0x20,0x41,0x08,0x54,0x0D,0xD5,0x4B,
+0x41,0x19,0x4A,0x17,0x84,0x20,0x84,0x00,0x4F,0xC2,0x00,0x4C,0xB7,0x9C,0x15,0x1E,
+0x00,0x01,0xD5,0x47,0xE3,0xB3,0xE9,0xF7,0x42,0x09,0x80,0x07,0x82,0xA0,0xC0,0x44,
+0x52,0x40,0x00,0x20,0x40,0x59,0x10,0x0D,0x40,0x29,0x80,0x0C,0xFE,0xAF,0x82,0x62,
+0x41,0x29,0x00,0x0C,0x40,0x38,0x10,0x0D,0x41,0x08,0x00,0x0C,0x40,0x08,0x80,0x0C,
+0x40,0x18,0x90,0x0D,0xFE,0x1F,0x49,0xFF,0xFF,0x69,0x82,0xC1,0x82,0x20,0x42,0x00,
+0xC8,0x69,0xE3,0xA1,0xE9,0x05,0x4C,0x18,0xC0,0x0C,0xE3,0x80,0xE8,0x09,0x51,0x6B,
+0x7F,0xFF,0x8A,0x33,0x40,0x30,0x48,0x01,0xE2,0x03,0x8A,0x2F,0x80,0x03,0x86,0xE0,
+0x4F,0xC2,0x00,0x15,0x40,0x08,0x00,0x01,0x40,0x18,0x84,0x01,0xE3,0x80,0x8A,0x2F,
+0x52,0x4A,0x80,0x20,0x41,0x10,0x90,0x0C,0x41,0x00,0x54,0x0D,0x41,0x08,0x44,0x04,
+0x41,0x10,0xD4,0x0D,0xB7,0x9C,0x15,0x1E,0x00,0x01,0x80,0x16,0x50,0x1B,0x80,0x00,
+0x3B,0xFF,0xFE,0x84,0xDD,0x9E,0xE3,0xF1,0xE9,0x03,0xE3,0x92,0xE9,0x09,0x86,0xC1,
+0x40,0x48,0x48,0x01,0x8B,0xB3,0xE3,0x84,0x8B,0xAF,0x82,0x04,0xD5,0x02,0x86,0xC0,
+0x86,0xE0,0x4F,0xC3,0xFF,0xE9,0xD5,0xEA,0xFC,0x42,0x95,0x09,0x92,0x95,0x40,0x70,
+0xAC,0x08,0x40,0x60,0x54,0x09,0xFF,0xF7,0x40,0x60,0x2C,0x08,0x47,0xC8,0x00,0x00,
+0x95,0x59,0x92,0xB5,0x40,0x91,0xAC,0x08,0x40,0x81,0x54,0x09,0x40,0x94,0xA0,0x04,
+0x40,0x81,0x2C,0x08,0xFE,0xCD,0x40,0xA1,0xF0,0x02,0x44,0x30,0x07,0xFF,0xC4,0x58,
+0x4C,0x32,0x00,0x75,0x40,0x73,0xF0,0x04,0x4E,0x52,0x00,0x87,0x4C,0x32,0x80,0x79,
+0x40,0x94,0xF0,0x04,0x14,0xAF,0x80,0x03,0x50,0x02,0xFC,0x02,0x99,0x20,0x42,0x23,
+0xA4,0x69,0x42,0x03,0x24,0x69,0x40,0x91,0x04,0x00,0xE3,0x21,0x40,0xA1,0xBC,0x00,
+0x42,0x23,0xA0,0x69,0x99,0xD0,0xE2,0xE0,0x89,0x2F,0xE3,0x2F,0x89,0x4F,0x89,0x23,
+0xE3,0x23,0x89,0x4F,0x42,0x03,0x20,0x69,0x99,0xF9,0xE2,0xE1,0x89,0x2F,0xE3,0x2F,
+0x40,0x15,0x3C,0x00,0xFF,0xC7,0x58,0x04,0x80,0x01,0x40,0x04,0x9C,0x1A,0xE4,0x20,
+0xE9,0x07,0x81,0xE0,0x98,0x00,0xE2,0x0F,0x98,0x49,0x88,0x2F,0x9F,0x21,0x04,0xAF,
+0x80,0x03,0x4E,0x47,0x00,0x71,0x52,0x52,0x07,0xFF,0x4E,0x57,0x00,0x46,0x50,0x00,
+0x04,0x00,0x5C,0xF0,0x04,0x00,0xE8,0x04,0x88,0x2F,0xE2,0x2F,0x88,0x8F,0x40,0x20,
+0x2C,0x09,0x96,0x94,0x9A,0x02,0x92,0x0B,0x40,0x20,0xD4,0x08,0xFE,0x17,0x94,0x49,
+0x92,0x2C,0x40,0x52,0x50,0x08,0xFE,0x6F,0x40,0x10,0xA8,0x04,0xFC,0xC2,0x40,0xF3,
+0x98,0x04,0xE8,0x19,0x40,0xF3,0x7C,0x09,0x99,0xFF,0x88,0xEF,0x99,0xB6,0xCF,0x05,
+0x80,0xE6,0x84,0xC0,0x50,0x42,0x7F,0xE0,0x42,0x03,0x80,0x07,0xC0,0x9E,0x9B,0x20,
+0x52,0x20,0x00,0x20,0x40,0x23,0x08,0x0D,0x40,0x63,0x00,0x0C,0x40,0x73,0x80,0x0C,
+0xFF,0xD7,0xD5,0x93,0xD3,0x15,0x80,0x2A,0xFC,0xC2,0xFF,0xF7,0x4C,0x7E,0x40,0x11,
+0xCD,0x06,0x40,0x24,0x84,0x08,0x40,0x21,0x20,0x04,0xC2,0x0A,0xDB,0x05,0x40,0x94,
+0xA0,0x04,0x4C,0x9E,0x40,0x06,0x84,0x00,0x46,0x17,0xFF,0x00,0xD5,0xCE,0x84,0x00,
+0x44,0x18,0x00,0x00,0xFC,0xC2,0x40,0x04,0xA0,0x04,0xC0,0xE6,0x40,0xF4,0x7C,0x09,
+0x89,0x29,0x89,0x2F,0x89,0x08,0x4E,0x93,0x00,0x06,0x81,0x28,0x85,0x00,0x50,0x52,
+0xFF,0xE0,0x42,0x04,0x80,0x07,0x4E,0x02,0xFF,0x6F,0x9B,0x68,0x52,0x20,0x00,0x20,
+0x40,0x24,0x08,0x0D,0x40,0x84,0x00,0x0C,0x40,0x94,0x80,0x0C,0x40,0x94,0x88,0x04,
+0x48,0xFF,0xFF,0x62,0x84,0xC0,0x52,0x32,0x00,0x01,0x5C,0xF1,0x80,0x20,0xE9,0x0A,
+0x80,0xC0,0x80,0x01,0x84,0x20,0x50,0x31,0xFF,0xE0,0xC0,0x04,0x5C,0xF1,0x80,0x20,
+0xE8,0x1A,0xC3,0x10,0x52,0x21,0x80,0x20,0x40,0x70,0x88,0x0C,0x40,0x50,0x08,0x0C,
+0x40,0x00,0x0C,0x0D,0x40,0x10,0x8C,0x0D,0xFE,0x3F,0xFF,0xAF,0xC6,0x03,0x58,0x00,
+0x00,0x01,0x50,0x00,0x04,0x00,0x5C,0xF0,0x04,0x00,0x88,0x2F,0x40,0x40,0xFC,0x09,
+0x48,0xFF,0xFF,0x77,0x84,0x00,0xD5,0xA0,0xFC,0x42,0x95,0x09,0x92,0x95,0x40,0x70,
+0xAC,0x08,0x40,0x60,0x54,0x09,0xFF,0xF7,0x40,0x60,0x2C,0x08,0x47,0xC8,0x00,0x00,
+0x95,0x59,0x92,0xB5,0x40,0x91,0xAC,0x08,0x40,0x81,0x54,0x09,0x40,0x94,0xA0,0x04,
+0x40,0x81,0x2C,0x08,0xFE,0xCD,0x40,0xA1,0xF0,0x02,0x44,0x30,0x07,0xFF,0x4E,0x42,
+0x00,0xC5,0x4C,0x32,0x00,0xEF,0x40,0x73,0xF0,0x04,0x4E,0x52,0x00,0xFB,0x4C,0x32,
+0x80,0xF3,0x40,0x94,0xF0,0x04,0x9B,0x25,0x50,0x42,0x03,0xFF,0x92,0xC1,0x40,0x13,
+0xFC,0x08,0xFF,0x8F,0x92,0xE1,0x40,0x24,0xC0,0x09,0x40,0x33,0x88,0xF7,0x40,0x14,
+0x80,0x13,0x42,0x50,0x8C,0x24,0x40,0x73,0xC0,0x08,0x40,0x03,0x40,0x09,0xFF,0xC7,
+0x80,0x07,0x9B,0xFD,0xE2,0x07,0xE8,0x05,0x9E,0xD9,0x88,0xE9,0xE2,0xE9,0xE8,0xFD,
+0x40,0x23,0x88,0xF7,0x42,0x50,0x88,0x24,0x40,0x73,0xC0,0x08,0x96,0x31,0xFF,0xC7,
+0x80,0x07,0x9B,0xFD,0xE2,0x07,0xE8,0x05,0x9E,0x91,0x88,0xE9,0xE2,0xE9,0xE8,0xFD,
+0x40,0x31,0xC0,0x08,0x98,0xDA,0x42,0x01,0xA0,0x69,0xFF,0x82,0x80,0x07,0x9B,0xF9,
+0xE2,0x07,0xC6,0x05,0x80,0x07,0x9F,0xF9,0xE9,0x03,0xE2,0x07,0xE8,0x0C,0x9E,0xD9,
+0x88,0xC8,0x40,0x03,0x20,0x06,0x88,0xE9,0xE2,0xE9,0xC0,0x04,0x9D,0xF9,0xE9,0x03,
+0xE6,0xE1,0xE8,0xF6,0x4C,0x74,0xC0,0x07,0x80,0x28,0x80,0xE6,0x84,0x40,0x84,0x00,
+0xD5,0x2B,0x40,0x14,0xC0,0x09,0x40,0x23,0x84,0xF7,0x40,0x04,0x80,0x13,0x42,0xF0,
+0x08,0x24,0x40,0x73,0xC0,0x08,0x40,0x53,0x40,0x09,0xFF,0xEF,0x80,0xA7,0x8A,0xEF,
+0xE2,0xA7,0xE8,0x05,0x9E,0x91,0x88,0xE9,0xE2,0xE9,0xE8,0xFD,0x40,0x13,0x84,0xF7,
+0x42,0x50,0x04,0x24,0x40,0x73,0xC0,0x08,0x96,0x31,0xFF,0xC7,0x80,0x07,0x9B,0xFD,
+0xE2,0x07,0xE8,0x05,0x9E,0x49,0x88,0xE9,0xE2,0xE9,0xE8,0xFD,0x40,0x21,0x40,0x08,
+0x98,0x91,0x42,0x01,0x20,0x69,0xFF,0x82,0x80,0x07,0x9B,0xF9,0xE2,0x07,0xC6,0x05,
+0x80,0x07,0x9F,0xF9,0xE9,0x03,0xE2,0x07,0xE8,0x0C,0x9E,0x91,0x88,0xC8,0x40,0x03,
+0x20,0x06,0x88,0xE9,0xE2,0xE9,0xC0,0x04,0x9D,0xF9,0xE9,0x03,0xE6,0xE1,0xE8,0xF6,
+0xE4,0x60,0xE9,0x07,0x81,0xE2,0x98,0x92,0xE2,0x4F,0x98,0xDB,0x88,0x6F,0x9F,0x21,
+0xFF,0xF7,0x58,0x01,0x00,0x01,0x40,0x01,0x1C,0x1A,0x80,0x23,0x4E,0x47,0x00,0x79,
+0x52,0x52,0x07,0xFF,0x4E,0x57,0x00,0x4A,0x50,0x00,0x04,0x00,0x5C,0xF0,0x04,0x00,
+0xE8,0x04,0x88,0x2F,0xE2,0x2F,0x88,0x8F,0x40,0x20,0x2C,0x09,0x96,0x94,0x9A,0x02,
+0x92,0x0B,0x40,0x20,0xD4,0x08,0xFE,0x17,0x94,0x49,0x92,0x2C,0x40,0x52,0x50,0x08,
+0xFE,0x6F,0x40,0x10,0xA8,0x04,0xFC,0xC2,0x40,0xF3,0x98,0x04,0xE8,0x1B,0x40,0xF3,
+0x7C,0x09,0x99,0xFF,0x88,0xEF,0x99,0xB6,0xCF,0x05,0x80,0xE6,0x84,0xC0,0x50,0x42,
+0x7F,0xE0,0x42,0x03,0x80,0x07,0x4E,0x02,0xFF,0x32,0x9B,0x20,0x52,0x20,0x00,0x20,
+0x40,0x23,0x08,0x0D,0x40,0x63,0x00,0x0C,0x40,0x73,0x80,0x0C,0xFF,0xD7,0x48,0xFF,
+0xFF,0x26,0xD3,0x07,0xCD,0x04,0x40,0xF4,0xA0,0x04,0xE8,0x07,0x80,0x2A,0xFC,0xC2,
+0x40,0x94,0xA0,0x04,0x4C,0x9E,0x3F,0xFC,0x84,0x00,0x44,0x18,0x00,0x00,0xFC,0xC2,
+0xFF,0xF7,0x4C,0x7E,0x7F,0xFB,0xD3,0xF9,0x84,0x00,0x46,0x17,0xFF,0x00,0x40,0x10,
+0xA8,0x04,0xFC,0xC2,0x40,0x94,0xA0,0x04,0x4C,0x9E,0x7F,0xF0,0x84,0x00,0xD5,0xE7,
+0x40,0xF4,0xA0,0x04,0xE8,0xF2,0x40,0xF4,0x7C,0x09,0x89,0x29,0x89,0x2F,0x89,0x08,
+0x4E,0x93,0x00,0x06,0x81,0x28,0x85,0x00,0x50,0x52,0xFF,0xE0,0x42,0x04,0x80,0x07,
+0x4E,0x02,0xFE,0xFB,0x9B,0x68,0x52,0x20,0x00,0x20,0x40,0x24,0x08,0x0D,0x40,0x84,
+0x00,0x0C,0x40,0x94,0x80,0x0C,0x40,0x94,0x88,0x04,0x48,0xFF,0xFE,0xEE,0x84,0xC0,
+0x52,0x32,0x00,0x01,0x5C,0xF1,0x80,0x20,0xE9,0x0A,0x80,0xC0,0x80,0x01,0x84,0x20,
+0x50,0x31,0xFF,0xE0,0xC0,0x04,0x5C,0xF1,0x80,0x20,0xE8,0x1A,0xC3,0x10,0x52,0x21,
+0x80,0x20,0x40,0x70,0x88,0x0C,0x40,0x50,0x08,0x0C,0x40,0x00,0x0C,0x0D,0x40,0x10,
+0x8C,0x0D,0xFE,0x3F,0xFF,0xAF,0xC6,0x03,0x58,0x00,0x00,0x01,0x50,0x00,0x04,0x00,
+0x5C,0xF0,0x04,0x00,0x88,0x2F,0x40,0x40,0xFC,0x09,0x48,0xFF,0xFF,0x6F,0x84,0x00,
+0xD5,0x9E,0x92,0x00,0x40,0x30,0xAC,0x08,0x40,0x40,0x54,0x09,0xFE,0xE7,0x46,0x48,
+0x00,0x00,0xFE,0xE7,0x95,0x09,0x92,0x95,0x52,0x22,0x04,0x1E,0xE4,0x40,0xE9,0x0C,
+0xFA,0x90,0xE2,0x44,0xE9,0x02,0x84,0x60,0x40,0x31,0x88,0x0D,0xE4,0x20,0xE8,0x02,
+0xFE,0xDA,0x80,0x03,0xDD,0x9E,0xC0,0x03,0x58,0x10,0x80,0x01,0x46,0x47,0xFF,0x00,
+0xE2,0x81,0xE8,0x04,0x46,0x08,0x00,0x00,0xDD,0x9E,0x84,0x1F,0xDD,0x9E,0x92,0x00,
+0x3A,0x6F,0x98,0x3C,0x84,0x20,0x80,0xA1,0x80,0x61,0x80,0x40,0xC2,0x10,0xE4,0x40,
+0xE8,0x07,0x46,0x58,0x00,0x00,0xFE,0x92,0xC1,0x03,0xFE,0x4A,0x8E,0x41,0x44,0x30,
+0x04,0x1E,0x42,0x41,0x00,0x07,0x9A,0xDC,0x40,0x21,0x10,0x0C,0x40,0x40,0xAC,0x09,
+0x40,0x61,0x54,0x08,0xFF,0x37,0x95,0x91,0x92,0xCC,0xFF,0x77,0x40,0x61,0xD0,0x08,
+0xFF,0x77,0x80,0x04,0x80,0x25,0x3A,0x6F,0x98,0x04,0xDD,0x9E,0x3A,0x6F,0x98,0x3C,
+0x84,0x20,0x80,0x61,0x80,0x40,0xC2,0x08,0x44,0x30,0x04,0x1E,0x42,0x51,0x00,0x07,
+0x9A,0xDD,0x40,0x21,0x14,0x0C,0x40,0x40,0xAC,0x09,0x40,0x61,0x54,0x08,0xFF,0x37,
+0x95,0x51,0x92,0xAC,0x40,0x61,0xD0,0x08,0xFF,0x77,0x80,0x04,0x80,0x25,0x3A,0x6F,
+0x98,0x04,0xDD,0x9E,0x49,0x00,0x07,0x54,0x49,0x00,0x2A,0x75,0x49,0x00,0x01,0xE6,
+0x46,0x08,0x00,0x20,0x04,0x10,0x03,0xC1,0x12,0x00,0x87,0xA0,0x02,0x00,0x07,0xA0,
+0x44,0x00,0x00,0x30,0x49,0x00,0x01,0xF7,0x49,0x00,0x03,0x4D,0x49,0x00,0x4E,0x82,
+0x3C,0x0D,0xFF,0x76,0x49,0x00,0x41,0xC9,0x2E,0x07,0xFF,0xA3,0x49,0x00,0x41,0xE7,
+0x44,0x20,0x05,0x10,0x49,0x00,0x4D,0xC3,0x3E,0x17,0xFE,0x64,0x49,0x00,0x41,0xB1,
+0x44,0x00,0x00,0xBB,0x49,0x00,0x41,0xE7,0x3E,0x07,0xFD,0x19,0x49,0x00,0x1B,0x8A,
+0x46,0x09,0x00,0x00,0x66,0x00,0x00,0xFF,0x49,0x00,0x4D,0xC0,0x3E,0x07,0xFE,0x86,
+0x2E,0x17,0xFE,0x64,0x44,0x00,0x00,0x64,0x58,0x00,0x06,0x58,0x04,0x00,0x03,0xC1,
+0x5E,0xF7,0x80,0x97,0x50,0x00,0x05,0x5A,0x46,0x0A,0x55,0xAA,0x3C,0x00,0x01,0x7E,
+0x02,0x3F,0x80,0x07,0x2E,0x07,0xFD,0x01,0x49,0x00,0x32,0x76,0x02,0x0F,0x80,0x07,
+0x04,0x50,0x03,0xF1,0x46,0x18,0x00,0x20,0x44,0x00,0xFF,0xFF,0x44,0x10,0x00,0x64,
+0x2E,0x07,0xFD,0x79,0x2E,0x00,0x01,0x2B,0x49,0x00,0x31,0xB9,0x3A,0x05,0x04,0x00,
+0x10,0x10,0x00,0x60,0x14,0x00,0x83,0xC1,0x40,0x11,0x05,0x04,0x12,0x10,0x00,0x1E,
+0x49,0x00,0x43,0xE6,0x49,0x00,0x49,0x08,0x2E,0x00,0x00,0xDF,0x3C,0x03,0xFF,0xC1,
+0x58,0x00,0x00,0x01,0x3A,0x0F,0x84,0x20,0x50,0x0F,0x80,0x0F,0x49,0x00,0x42,0x19,
+0x49,0x00,0x4E,0x58,0x2E,0x00,0x01,0x28,0x3C,0x0B,0xFE,0xD0,0x46,0x19,0x00,0x00,
+0x50,0x00,0x03,0x3A,0x2E,0x07,0xFD,0x48,0x2E,0x17,0xFE,0x60,0x2E,0x07,0xFD,0x19,
+0x46,0x19,0x00,0x20,0x2E,0x07,0xFE,0x61,0x2E,0x07,0xFD,0x29,0x3E,0x07,0xFE,0x65,
+0x10,0x10,0x00,0x8C,0x46,0x0A,0x33,0xAA,0x2E,0x07,0xFD,0x6E,0x49,0x00,0x43,0x0E,
+0x3E,0x07,0xFD,0x2A,0x3E,0x1F,0xFF,0xA0,0x02,0x50,0x00,0x00,0x49,0x00,0x1B,0x95,
+0x3C,0x3D,0xFF,0x95,0x49,0x00,0x0F,0x20,0x2E,0x07,0xFD,0x00,0x2E,0x07,0xFD,0x07,
+0x49,0x00,0x09,0x75,0x58,0x00,0x06,0x44,0x3E,0x07,0xFD,0x0D,0x54,0xC6,0x00,0xFF,
+0x2E,0x07,0xFD,0x0E,0x10,0x10,0x01,0x68,0x2E,0x07,0xFD,0x51,0x44,0x00,0x01,0xB0,
+0x42,0x10,0x84,0x0B,0x64,0x00,0x00,0x08,0x46,0x09,0x00,0x88,0x49,0x00,0x41,0x9A,
+0x3C,0x03,0xFF,0xC2,0x49,0x00,0x41,0xEC,0x10,0x10,0x00,0x44,0x58,0x00,0x00,0x98,
+0x04,0x50,0x03,0xC4,0x3C,0x0B,0xFE,0xC7,0x3C,0x0B,0xFE,0xCA,0x3E,0xF7,0xFD,0x01,
+0x58,0x21,0x0B,0x14,0x49,0x00,0x4F,0xF2,0x2E,0x07,0xFF,0xA4,0x2E,0x07,0xFF,0xA2,
+0x3B,0x00,0xC4,0x00,0x48,0x00,0x4D,0xA2,0x49,0x00,0x4E,0x34,0x40,0x00,0x00,0x09,
+0x66,0x10,0x80,0xFF,0x14,0x00,0x83,0xC4,0x58,0x10,0x8D,0x68,0x58,0x00,0x00,0x78,
+0x46,0x09,0x00,0x90,0x3E,0x10,0x01,0x29,0x10,0x10,0x02,0x38,0x3E,0x07,0xFD,0x4C,
+0x58,0x10,0x8B,0x14,0x3C,0x43,0xFE,0xD0,0x40,0x11,0x05,0x00,0x3E,0x17,0xFE,0x65,
+0x2E,0x17,0xFD,0x17,0x12,0x10,0x07,0xA0,0x49,0x00,0x44,0x65,0x40,0xF7,0x80,0x11,
+0x50,0x10,0x8F,0xFF,0x3C,0x23,0xFE,0xD0,0x02,0x0F,0x80,0x04,0x2E,0x07,0xFD,0x15,
+0x2E,0x27,0xFE,0x65,0x2E,0x07,0xFD,0x17,0x46,0xF1,0x00,0x01,0x49,0x00,0x18,0xA4,
+0x40,0x00,0x07,0x00,0x49,0x00,0x42,0x19,0x44,0x40,0xFF,0xFF,0x42,0x00,0x04,0x0B,
+0x42,0x10,0x94,0x0B,0x58,0x10,0x86,0x04,0x44,0x00,0x00,0xFF,0x49,0x00,0x43,0x8F,
+0x3E,0x07,0xFD,0x1E,0x3E,0x07,0xFD,0x67,0x10,0x04,0x80,0x00,0x2E,0x07,0xFD,0x1E,
+0x49,0x00,0x43,0x05,0x2E,0x17,0xFD,0x68,0x12,0x00,0x87,0xF4,0x2E,0x07,0xFD,0x65,
+0x3E,0x07,0xFD,0x23,0x3E,0x07,0xFD,0x26,0x02,0xF7,0x80,0x12,0x3C,0x13,0xFF,0xBE,
+0x49,0x00,0x42,0x24,0x38,0x11,0x0D,0x01,0x2E,0x07,0xFF,0xD2,0x3B,0x01,0x44,0x20,
+0x38,0x11,0x0D,0x09,0x3C,0x13,0xFF,0xB7,0x3C,0x30,0x01,0x7E,0x3C,0x13,0xFF,0xB8,
+0x42,0x00,0x08,0x0B,0x02,0x00,0x02,0xD4,0x49,0x00,0x43,0xE6,0x3C,0x2D,0xFF,0x95,
+0x3C,0x33,0xFE,0xCA,0x3E,0x2F,0xFC,0x08,0x3C,0x00,0x00,0xE3,0x3E,0x07,0xFD,0x34,
+0x49,0x00,0x12,0xA2,0x58,0x00,0x0A,0x98,0x3E,0x07,0xFD,0x36,0x2E,0x20,0x00,0x11,
+0x40,0xF0,0x3C,0x00,0x2E,0x00,0x01,0x29,0x40,0x00,0x20,0x08,0x44,0x00,0x05,0x10,
+0x58,0x10,0x80,0x02,0x3C,0x0B,0xFE,0xD2,0x44,0x60,0xFF,0xFF,0x58,0x00,0x01,0x48,
+0x49,0x00,0x10,0x96,0x3C,0x0C,0x00,0x49,0x46,0x29,0x00,0x00,0x02,0x10,0x07,0xA0,
+0x2E,0x17,0xFD,0x6E,0x3E,0x27,0xFE,0x65,0x38,0x30,0x89,0x09,0x38,0x13,0x08,0x00,
+0x49,0x00,0x18,0xD0,0x10,0x05,0x80,0x00,0x46,0x10,0xFF,0xFF,0x3E,0x07,0xFD,0x08,
+0x3E,0x07,0xFD,0x48,0x49,0x00,0x03,0x3F,0x2E,0x07,0xFD,0x05,0x44,0x40,0x00,0x30,
+0x44,0x20,0xFF,0xFF,0x3E,0x07,0xFD,0x02,0x3C,0x03,0xFE,0xCA,0x38,0x07,0x1C,0x00,
+0x14,0x10,0x01,0x5F,0x2E,0x17,0xFE,0x65,0x3C,0x0B,0xFE,0xE4,0x44,0x00,0x00,0xC6,
+0x44,0x00,0x03,0xE8,0x44,0x00,0x00,0xCB,0x2E,0x00,0x00,0x10,0x02,0x0F,0x80,0x01,
+0x02,0x0F,0x80,0x02,0x02,0x10,0x87,0xF4,0x3C,0x0B,0xFF,0xC2,0x3E,0x07,0xFD,0x0F,
+0x42,0x10,0xA8,0x0B,0x58,0x00,0x00,0x4C,0x3E,0x0F,0xFE,0xC4,0x40,0x01,0x00,0x40,
+0x2E,0x20,0x01,0x2B,0x49,0x00,0x3A,0x56,0x40,0x00,0x04,0x16,0x3C,0x1C,0x00,0x48,
+0x10,0x10,0x00,0x50,0x38,0x00,0x80,0x01,0x12,0x00,0x87,0x92,0x02,0x00,0x07,0x92,
+0x3C,0x03,0xFE,0xD0,0x44,0x70,0x00,0xFF,0x02,0x0F,0x80,0x05,0x2E,0x07,0xFD,0x58,
+0x2E,0x07,0xFD,0x16,0x40,0x00,0x40,0x08,0x44,0x10,0x35,0xCA,0x3B,0x00,0xC4,0x20,
+0x54,0xA0,0x00,0xFF,0x10,0x00,0x82,0xC0,0x44,0x20,0x00,0x30,0x00,0x03,0x00,0x92,
+0x42,0x31,0xC0,0x24,0x42,0x00,0x10,0x0B,0x12,0x10,0x02,0xB8,0x49,0x00,0x1B,0x8E,
+0x58,0x00,0x08,0x00,0x2E,0x17,0xFF,0xA4,0x2E,0x17,0xFF,0xA2,0x48,0x00,0x12,0xA1,
+0x49,0x00,0x1B,0xB7,0x3E,0x07,0xFD,0x65,0x3E,0x07,0xFD,0x64,0x58,0x00,0x02,0xC4,
+0x10,0x00,0x80,0x08,0x3E,0x07,0xFD,0x68,0x2E,0x17,0xFD,0x65,0x49,0x00,0x32,0x18,
+0x3C,0x03,0xFF,0xC0,0x10,0x60,0x00,0xA0,0x42,0x01,0x04,0x73,0x2E,0x07,0xFD,0x21,
+0x58,0x00,0x00,0x02,0x44,0x00,0xA5,0x5A,0x58,0x00,0x00,0x04,0x44,0x00,0x5A,0xA5,
+0x10,0x10,0x00,0x40,0x2E,0x07,0xFD,0x68,0x3C,0x13,0xFF,0xBF,0x49,0x00,0x3D,0xBE,
+0x44,0x60,0x00,0x55,0x3E,0x07,0xFD,0x20,0x42,0x13,0x00,0x73,0x00,0x20,0x00,0x08,
+0x02,0x20,0x00,0x1E,0x50,0x1F,0x81,0x90,0x49,0x00,0x34,0x88,0x66,0x00,0x00,0x02,
+0x49,0x00,0x0A,0xA8,0x42,0x10,0x80,0x03,0x3C,0x0B,0xFE,0xC4,0x2E,0x07,0xFD,0x2B,
+0x58,0x10,0x81,0x44,0x42,0x00,0x14,0x0B,0x46,0x61,0x00,0x02,0x14,0x10,0x00,0x0E,
+0x58,0x21,0x0D,0x08,0x02,0x00,0x02,0xD6,0x3C,0x30,0x01,0x7B,0x3C,0x30,0x01,0x7A,
+0x49,0x00,0x01,0xDE,0x49,0x00,0x4F,0xE2,0x3C,0x0D,0xFF,0x9A,0x46,0x11,0x00,0x03,
+0x2E,0x17,0xFD,0x79,0x58,0x63,0x01,0x44,0x49,0x00,0x15,0x5B,0x00,0x00,0x02,0x7C,
+0x2E,0x07,0xFD,0x30,0x3C,0x00,0x00,0xE2,0x00,0x10,0x00,0x40,0x49,0x00,0x35,0x6A,
+0x50,0x21,0x00,0xE8,0x3C,0x1D,0xFF,0x76,0x10,0x10,0x00,0x4C,0x3E,0x07,0xFD,0x31,
+0x58,0x10,0x80,0x78,0x58,0x10,0x80,0x04,0x14,0x10,0x01,0x6D,0x14,0x10,0x01,0x6E,
+0x46,0x09,0x00,0x80,0x42,0x10,0x90,0x0B,0x38,0xF1,0x06,0x02,0x58,0x21,0x0F,0xF4,
+0x38,0x06,0x82,0x02,0x2E,0x07,0xFD,0x3B,0x49,0x00,0x0F,0x14,0x64,0x12,0x00,0x43,
+0x3C,0x0D,0xFF,0x87,0x3E,0x07,0xFD,0x3D,0x3C,0x0C,0x00,0x48,0x64,0x03,0x00,0x03,
+0x3C,0x03,0xFF,0x40,0x3C,0x03,0xFF,0x41,0x3E,0x67,0xFD,0x0D,0x3E,0x2F,0xFF,0x00,
+0x2E,0x07,0xFD,0x3D,0x40,0x03,0x98,0x60,0x2E,0x10,0x00,0x14,0x2E,0x07,0xFD,0x3F,
+0x58,0x00,0x0B,0x68,0x49,0x00,0x4E,0x2F,0x40,0x00,0x82,0x00,0x2E,0x10,0x00,0x11,
+0x00,0x10,0x00,0x44,0x50,0x00,0x03,0x3C,0x44,0x00,0x00,0x3C,0x46,0x01,0x00,0x05,
+0x46,0x01,0x00,0x06,0x46,0x01,0x00,0x07,0x46,0x01,0x00,0x01,0x46,0x01,0x00,0x02,
+0x46,0x01,0x00,0x03,0x46,0x01,0x00,0x03,0x46,0x01,0x00,0x04,0x46,0x01,0x00,0x05,
+0x46,0x21,0x00,0x00,0x46,0x21,0x00,0x01,0x46,0x21,0x00,0x02,0x46,0x11,0x00,0x00,
+0x46,0x11,0x00,0x01,0x46,0x11,0x00,0x02,0x46,0x11,0x00,0x06,0x46,0x11,0x00,0x07,
+0x46,0x51,0x00,0x07,0x46,0x51,0x00,0x08,0x46,0x01,0x00,0x07,0x46,0x01,0x00,0x08,
+0x46,0x01,0x00,0x09,0x46,0x01,0x00,0x02,0x46,0x01,0x00,0x03,0x46,0x01,0x00,0x04,
+0x46,0x31,0x00,0x01,0x46,0x31,0x00,0x02,0x46,0x31,0x00,0x03,0x46,0x31,0x00,0x07,
+0x46,0x31,0x00,0x08,0x46,0x31,0x00,0x09,0x46,0x21,0x00,0x06,0x46,0x21,0x00,0x07,
+0x46,0x31,0x00,0x02,0x46,0x31,0x00,0x03,0x46,0x31,0x00,0x04,0x46,0x21,0x00,0x07,
+0x46,0x21,0x00,0x08,0x46,0x21,0x00,0x09,0x46,0x21,0x00,0x01,0x46,0x21,0x00,0x02,
+0x46,0x21,0x00,0x03,0x46,0x11,0x00,0x01,0x46,0x11,0x00,0x02,0x46,0x11,0x00,0x03,
+0x46,0x11,0x00,0x02,0x46,0x11,0x00,0x03,0x46,0x11,0x00,0x04,0x46,0x00,0x00,0x0D,
+0x46,0x00,0x00,0x0E,0x46,0x00,0x00,0x0F,0x46,0x01,0x00,0x00,0x46,0x01,0x00,0x01,
+0x46,0x01,0x00,0x02,0x46,0x11,0x00,0x07,0x46,0x11,0x00,0x08,0x46,0x11,0x00,0x09,
+0x00,0x01,0x02,0x00,0x01,0x02,0x01,0x00,0x00,0x02,0x02,0x01,0x02,0x02,0x01,0x01,
+0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x08,0x09,0x10,0x11,0x00,0x01,0x08,0x09,
+0x10,0x11,0x00,0x01,0x08,0x09,0x10,0x11,0x00,0x01,0x08,0x09,0x10,0x11,0x00,0x01,
+0x08,0x09,0x10,0x11,0x00,0x01,0x08,0x09,0x00,0xA1,0x28,0x04,0x00,0x0A,0x85,0x02,
+0x00,0x54,0x50,0x01,0x48,0x19,0x00,0x10,0x02,0x04,0x02,0x00,0x00,0x00,0x00,0x00,
+0x04,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x02,0x04,0x02,0x04,0x00,0x00,0x00,0x00,
+0x04,0x02,0x01,0x04,0x03,0x02,0x00,0x00,0x02,0x01,0x04,0x03,0x01,0x02,0x00,0x00,
+0x03,0x02,0x03,0x00,0x00,0x00,0x00,0x00,0x01,0x04,0x03,0x02,0x00,0x00,0x00,0x00,
+0x04,0x03,0x02,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
+0x04,0x03,0x01,0x02,0x00,0x00,0x00,0x00,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
+0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0xA2,0x82,0xA2,0x82,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0xA1,0x81,0xA1,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA2,0x82,0xA2,0x82,0xA2,0x0D,0x00,0x00,
+0x00,0x00,0x00,0x00,0xC1,0xA1,0xE1,0x81,0xA1,0x85,0xC5,0xA5,0xE5,0x0E,0x00,0x00,
+0xE5,0x85,0xC5,0xAA,0xC1,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0xC1,0xA2,0xC1,0x82,
+0xE1,0x2F,0x00,0x00,0x00,0x00,0x00,0x00,0xE3,0x83,0xC3,0xA3,0xE3,0x0C,0x00,0x00,
+0x00,0x00,0x00,0x00,0xC5,0xA5,0xE5,0x05,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0xEA,0xCA,0xEA,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC5,0xE5,0xC5,0x85,
+0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCA,0xEA,0xCA,0x09,0x01,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0xAA,0x8A,0x0A,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x8A,0xAA,0x1D,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEA,0xCA,0x2D,0x02,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCA,0xEA,0x3D,0x02,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x81,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0xA1,0x02,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC1,0x03,0x03,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE1,0x04,0x03,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0xA5,0x5A,0x08,0x04,0x06,0x02,0x09,0x52,0x44,0x4A,0x4E,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x46,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x41,0x72,0x69,0x6D,0x61,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x31,0x39,0x30,0x39,0x30,0x33,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x02,0x3F,0x82,0xC2,0x10,0x02,0x03,0x37,0x64,0x30,0x96,0xC8,0x3C,0xFF,0x0A,
+0x14,0x14,0x28,0x14,0x32,0x32,0x25,0x20,0x05,0x40,0x25,0x14,0x14,0x82,0x82,0x16,
+0x16,0x53,0x75,0x0A,0x78,0x46,0x64,0x3C,0x0F,0x0C,0x00,0x00,0x11,0x00,0x00,0x08,
+0x0F,0x0A,0x96,0x10,0x09,0x06,0x0A,0x04,0x14,0x64,0xFF,0x14,0x00,0x00,0x1E,0x8C,
+0x64,0x64,0x78,0x90,0x08,0x00,0x0F,0x06,0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x02,0x80,0x00,0x00,0x00,
+0x00,0x0C,0x00,0x00,0x00,0x1E,0x20,0x22,0x24,0x00,0x50,0x02,0x02,0x0A,0x02,0x05,
+0x24,0x12,0x0A,0x06,0xE5,0x00,0x08,0x70,0x04,0x38,0x00,0x7F,0x03,0x44,0x47,0x34,
+0x00,0x04,0x56,0x0D,0xD4,0x53,0x0F,0x00,0x00,0x7F,0x03,0x44,0x47,0x34,0x00,0x04,
+0x56,0x0D,0xD4,0x53,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x28,0x00,0x00,
+0x00,0x00,0x00,0x16,0x0A,0x14,0x0A,0x0A,0x14,0x64,0x14,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x0B,0x0C,0x1B,0x15,0x50,0x25,0x02,0x50,0x0F,0x03,0x00,0x28,0xB2,0x64,
+0x04,0x3C,0x35,0x1E,0x32,0x80,0x0E,0x07,0x23,0x0A,0xB4,0x78,0x96,0x5A,0x64,0x32,
+0x00,0x00,0x64,0x64,0x00,0x14,0x03,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,
+0x06,0x0A,0x0A,0x78,0x3C,0x96,0x32,0x00,0x00,0x00,0x00,0x88,0x30,0x00,0x00,0x00,
+0x00,0x0A,0x0A,0x50,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x06,0x00,0x00,0x00,
+0x1E,0x00,0x00,0x00,0x00,0x02,0xD0,0x05,0x00,0x0A,0x05,0xFF,0x0A,0x03,0xE8,0x03,
+0xE8,0x03,0x02,0x01,0xF4,0x00,0x00,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,
+0x14,0x14,0x0A,0x0A,0x1C,0x30,0x00,0x00,0x11,0x11,0x0A,0x05,0x3D,0x0A,0x1B,0x33,
+0x00,0x00,0x11,0x0A,0x05,0x85,0x14,0x15,0x14,0x10,0x15,0x14,0x00,0x00,0x00,0x01,
+0x00,0x00,0x00,0x00,0x00,0x10,0x0A,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x01,0x0A,0x06,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x6F,0x08,0x6F,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x5C,0x08,0x6F,0x08,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0xED,0x00,0x36,0x01,0xE2,0x02,0x2D,0x03,0x37,0x04,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEB,0x00,0x40,0x01,0xDF,0x02,
+0x34,0x03,0x37,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x08,0x70,0x14,0x00,0x00,0x08,0x70,0x14,0x00,0x00,0x04,0x38,0x0A,0x00,
+0x00,0x04,0x38,0x0A,0x64,0x0C,0x64,0xFF,0x96,0x96,0x64,0x3C,0xC8,0xFF,0xB4,0x5A,
+0x05,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,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,0x40,
+0x00,0x40,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x65,0x67,0x65,0x67,0x65,0x67,0x65,0x67,0x64,0x65,0x64,0x65,
+0x00,0x65,0x00,0x65,0x00,0x65,0x00,0x65,0x64,0x65,0x64,0x65,0x65,0x67,0x65,0x67,
+0x65,0x67,0x65,0x67,0x00,0x00,0x00,0x00,0x26,0x00,0x39,0x00,0x24,0x0C,0x36,0x0C,
+0xFF,0x34,0x00,0x45,0x00,0xFF,0x37,0x00,0x26,0x00,0xFF,0x36,0x00,0x24,0x00,0xFF,
+0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x05,0x02,0x00,0xFA,0x00,0xFA,0x01,0xC2,0x03,0x20,0x01,0x2C,0x19,0x20,0x00,0x4B,
+0x32,0x32,0x00,0x00,0x01,0xF4,0x00,0x96,0xC8,0x18,0x18,0x01,0xF4,0x20,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0xFE,0xF7,0x9B,0x3C,0xFF,0xFF,0x07,0x80,0x4B,0x00,0xEF,0x0F,0x0C,0x44,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA5,0x5A,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE3,0x64,
+0x00,0x00,0x00,0x00,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,0x07,0x1C,0x30,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,
+0xFF,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0x03,0x00,0xFF,0xFF,0xFD,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,
+0xFF,0x00,0x00,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0x07,0x0E,0x15,0x00,
+0x07,0x0E,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,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,0x00,
+0x0A,0xBA,0x90,0x00,0x20,0x00,0x00,0x00,0xDC,0x05,0x00,0x00,0xC9,0x00,0x00,0x00,
+0x80,0x61,0x00,0x00,0x0A,0x00,0x00,0x00,0x32,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
+0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x03,0x00,0x00,0x00,
+0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x81,0x02,0x20,0x47,0x81,0x02,
+0x85,0x0C,0x81,0x02,0x14,0x00,0xC8,0x00,0x5E,0x01,0x5E,0x01,0x64,0x00,0x14,0x00,
+0x00,0x00,0x00,0x00,0x78,0x02,0x00,0x00,0x03,0x5D,0x08,0x02,0x1F,0x06,0x11,0x1B,
+0x0C,0x11,0x1F,0x09,0x00,0x04,0x00,0x03,0x00,0x02,0x03,0x03,0x01,0x00,0x15,0x15,
+0x00,0x04,0x30,0x03,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+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,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,
+0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x07,0x1C,0x30,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,
+0xFF,0xFF,0xFD,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x00,0x00,0x30,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0x07,0x0E,0x15,0x00,0x07,0x0E,0x15,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+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,0x00,0x0A,0xBA,0x90,0x00,
+0x20,0x00,0x00,0x00,0xDC,0x05,0x00,0x00,0xC9,0x00,0x00,0x00,0x80,0x61,0x00,0x00,
+0x0A,0x00,0x00,0x00,0x32,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0xAA,0xAA,0xAA,0xAA,
+0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x03,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x04,0x81,0x02,0x20,0x47,0x81,0x02,0x85,0x0C,0x81,0x02,
+0x14,0x00,0xC8,0x00,0x5E,0x01,0x5E,0x01,0x64,0x00,0x14,0x00,0x00,0x00,0x00,0x00,
+0x78,0x02,0x00,0x00,0x03,0x5D,0x08,0x02,0x1F,0x06,0x11,0x1B,0x0C,0x11,0x1F,0x09,
+0x00,0x04,0x00,0x03,0x00,0x02,0x03,0x03,0x01,0x00,0x15,0x15,0x00,0x04,0x30,0x03,
+0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,
+0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,
+0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xFF,0xFD,0x37,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x00,0x00,0x30,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0x03,0x00,0x07,0x0E,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x00,0x22,0x9A,0x80,0x00,0x20,0x00,0x00,0x00,
+0xF0,0x04,0x00,0x00,0xC9,0x00,0x00,0x00,0x80,0x61,0x00,0x00,0x0A,0x00,0x00,0x00,
+0x32,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+0xAA,0xAA,0xAA,0xAA,0x03,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x00,0x03,0x00,0x00,
+0x00,0x04,0xA0,0x00,0x20,0x47,0xA0,0x00,0x20,0x08,0xA0,0x00,0x14,0x00,0xC8,0x00,
+0x5E,0x01,0x5E,0x01,0xC8,0x00,0x14,0x00,0x29,0x0E,0x5B,0x0E,0x97,0x00,0x00,0x00,
+0x04,0x5D,0x08,0x04,0x1F,0x06,0x10,0x1A,0x0B,0x10,0x15,0x09,0x00,0x03,0x02,0x03,
+0x00,0x02,0x03,0x03,0x01,0x00,0x15,0x15,0x00,0x04,0x30,0x03,0x02,0x00,0x03,0x03,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0x03,0x00,0xFF,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,
+0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xFF,0xFD,0x37,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0x03,0x00,0xFF,0x00,0x00,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,
+0x38,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x00,0x3A,0x9A,0x84,0x00,0x20,0x00,0x00,0x00,0xF4,0x01,0x00,0x00,
+0xC9,0x00,0x00,0x00,0x00,0x41,0x00,0x00,0x0A,0x00,0x00,0x00,0x32,0x00,0x00,0x00,
+0x14,0x00,0x00,0x00,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+0x02,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x04,0xA0,0x00,
+0x20,0x47,0xA0,0x00,0x20,0x08,0xA0,0x00,0x14,0x00,0xC8,0x00,0x5E,0x01,0x5E,0x01,
+0xC8,0x00,0x14,0x00,0xA4,0x38,0xD6,0x38,0x97,0x00,0x00,0x00,0x04,0x5D,0x08,0x04,
+0x1F,0x06,0x10,0x1A,0x0B,0x10,0x15,0x09,0x00,0x04,0x02,0x03,0x00,0x02,0x03,0x03,
+0x01,0x00,0x15,0x15,0x00,0x03,0x30,0x03,0x00,0x01,0x03,0x03,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,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,0x07,0x1C,0x30,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,
+0xFF,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0x03,0x00,0xFF,0xFF,0xFD,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,
+0xFF,0x00,0x00,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0x07,0x00,0x0E,0x00,
+0x15,0x00,0x31,0x00,0x1C,0x00,0x23,0x00,0x2A,0x00,0x31,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,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,0x00,
+0x22,0x9A,0x80,0x00,0x20,0x00,0x00,0x00,0xF0,0x04,0x00,0x00,0xC9,0x00,0x00,0x00,
+0x80,0x61,0x00,0x00,0x0A,0x00,0x00,0x00,0x32,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
+0xAA,0xAA,0xAA,0xA2,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x03,0x00,0x00,0x00,
+0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xA0,0x00,0x20,0x47,0xA0,0x00,
+0x20,0x08,0xA0,0x00,0x14,0x00,0xC8,0x00,0x5E,0x01,0x5E,0x01,0x64,0x00,0x14,0x00,
+0x00,0x00,0x00,0x00,0x97,0x00,0x00,0x00,0x04,0x05,0x08,0x04,0x1F,0x06,0x10,0x1A,
+0x0B,0x10,0x15,0x09,0x00,0x03,0x00,0x03,0x00,0x02,0x03,0x03,0x00,0x01,0x15,0x15,
+0x00,0x04,0x30,0x01,0x00,0x00,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+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,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,
+0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x07,0x1C,0x30,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,
+0xFF,0xFF,0xFD,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x00,0x00,0x30,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0x07,0x00,0x0E,0x00,0x15,0x00,0x31,0x00,
+0x1C,0x00,0x23,0x00,0x2A,0x00,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+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,0x00,0x3A,0xBA,0x84,0x00,
+0x20,0x00,0x00,0x00,0xF0,0x04,0x00,0x00,0xC9,0x00,0x00,0x00,0x80,0x61,0x00,0x00,
+0x0A,0x00,0x00,0x00,0x32,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0xAA,0xAA,0xAA,0xA2,
+0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x03,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x04,0xA0,0x00,0x20,0x47,0x64,0x00,0x34,0x08,0x64,0x00,
+0x14,0x00,0xC8,0x00,0x5E,0x01,0x5E,0x01,0x64,0x00,0x14,0x00,0x00,0x00,0x00,0x00,
+0x97,0x00,0x00,0x00,0x04,0x05,0x08,0x07,0x1F,0x08,0x11,0x18,0x0C,0x11,0x16,0x09,
+0x00,0x04,0x00,0x03,0x00,0x02,0x03,0x03,0x00,0x01,0x15,0x15,0x00,0x04,0x30,0x01,
+0x00,0x00,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,
+0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,
+0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xFF,0xFD,0x37,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x00,0x00,0x30,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+0xFF,0xFF,0x03,0x00,0x31,0x00,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x00,0x3A,0x9A,0x84,0x00,0x20,0x00,0x00,0x00,
+0xF0,0x04,0x00,0x00,0xC9,0x00,0x00,0x00,0x80,0x61,0x00,0x00,0x0A,0x00,0x00,0x00,
+0x32,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
+0xAA,0xAA,0xAA,0xAA,0x03,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x04,0xA0,0x00,0x20,0x47,0xA0,0x00,0x20,0x08,0xA0,0x00,0x14,0x00,0xC8,0x00,
+0x5E,0x01,0x5E,0x01,0x64,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x97,0x00,0x00,0x00,
+0x04,0x05,0x08,0x04,0x1F,0x06,0x10,0x1A,0x0B,0x10,0x15,0x09,0x00,0x04,0x07,0x03,
+0x00,0x02,0x03,0x03,0x00,0x01,0x15,0x15,0x00,0x04,0x30,0x01,0x00,0x00,0x03,0x03,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x65,0x02,0x66,0x02,0x67,0x02,0x68,0x02,0x69,0x02,0x6A,0x02,0x6B,0x02,0x6C,0x02,
+0x6D,0x02,0x6E,0x02,0x6F,0x02,0x70,0x02,0x71,0x02,0x72,0x02,0x73,0x02,0x74,0x02,
+0x75,0x02,0x76,0x02,0x77,0x02,0x78,0x02,0x79,0x02,0x7A,0x02,0x7B,0x02,0x7C,0x02,
+0x7D,0x02,0x7E,0x02,0x7F,0x02,0x80,0x02,0x81,0x02,0x82,0x02,0x83,0x02,0x84,0x02,
+0x85,0x02,0x86,0x02,0x87,0x02,0x88,0x02,0x41,0x02,0x42,0x02,0x43,0x02,0x44,0x02,
+0x45,0x02,0x46,0x02,0x47,0x02,0x48,0x02,0x49,0x02,0x4A,0x02,0x4B,0x02,0x4C,0x02,
+0x4D,0x02,0x4E,0x02,0x4F,0x02,0x50,0x02,0x51,0x02,0x52,0x02,0x53,0x02,0x54,0x02,
+0x55,0x02,0x56,0x02,0x57,0x02,0x58,0x02,0x59,0x02,0x5A,0x02,0x5B,0x02,0x5C,0x02,
+0x5D,0x02,0x5E,0x02,0x5F,0x02,0x60,0x02,0x61,0x02,0x62,0x02,0x63,0x02,0x64,0x02,
+0x1D,0x02,0x1E,0x02,0x1F,0x02,0x20,0x02,0x21,0x02,0x22,0x02,0x23,0x02,0x24,0x02,
+0x25,0x02,0x26,0x02,0x27,0x02,0x28,0x02,0x29,0x02,0x2A,0x02,0x2B,0x02,0x2C,0x02,
+0x2D,0x02,0x2E,0x02,0x2F,0x02,0x30,0x02,0x31,0x02,0x32,0x02,0x33,0x02,0x34,0x02,
+0x35,0x02,0x36,0x02,0x37,0x02,0x38,0x02,0x39,0x02,0x3A,0x02,0x3B,0x02,0x3C,0x02,
+0x3D,0x02,0x3E,0x02,0x3F,0x02,0x40,0x02,0xF9,0x01,0xFA,0x01,0xFB,0x01,0xFC,0x01,
+0xFD,0x01,0xFE,0x01,0xFF,0x01,0x00,0x02,0x01,0x02,0x02,0x02,0x03,0x02,0x04,0x02,
+0x05,0x02,0x06,0x02,0x07,0x02,0x08,0x02,0x09,0x02,0x0A,0x02,0x0B,0x02,0x0C,0x02,
+0x0D,0x02,0x0E,0x02,0x0F,0x02,0x10,0x02,0x11,0x02,0x12,0x02,0x13,0x02,0x14,0x02,
+0x15,0x02,0x16,0x02,0x17,0x02,0x18,0x02,0x19,0x02,0x1A,0x02,0x1B,0x02,0x1C,0x02,
+0xD5,0x01,0xD6,0x01,0xD7,0x01,0xD8,0x01,0xD9,0x01,0xDA,0x01,0xDB,0x01,0xDC,0x01,
+0xDD,0x01,0xDE,0x01,0xDF,0x01,0xE0,0x01,0xE1,0x01,0xE2,0x01,0xE3,0x01,0xE4,0x01,
+0xE5,0x01,0xE6,0x01,0xE7,0x01,0xE8,0x01,0xE9,0x01,0xEA,0x01,0xEB,0x01,0xEC,0x01,
+0xED,0x01,0xEE,0x01,0xEF,0x01,0xF0,0x01,0xF1,0x01,0xF2,0x01,0xF3,0x01,0xF4,0x01,
+0xF5,0x01,0xF6,0x01,0xF7,0x01,0xF8,0x01,0xB1,0x01,0xB2,0x01,0xB3,0x01,0xB4,0x01,
+0xB5,0x01,0xB6,0x01,0xB7,0x01,0xB8,0x01,0xB9,0x01,0xBA,0x01,0xBB,0x01,0xBC,0x01,
+0xBD,0x01,0xBE,0x01,0xBF,0x01,0xC0,0x01,0xC1,0x01,0xC2,0x01,0xC3,0x01,0xC4,0x01,
+0xC5,0x01,0xC6,0x01,0xC7,0x01,0xC8,0x01,0xC9,0x01,0xCA,0x01,0xCB,0x01,0xCC,0x01,
+0xCD,0x01,0xCE,0x01,0xCF,0x01,0xD0,0x01,0xD1,0x01,0xD2,0x01,0xD3,0x01,0xD4,0x01,
+0x8D,0x01,0x8E,0x01,0x8F,0x01,0x90,0x01,0x91,0x01,0x92,0x01,0x93,0x01,0x94,0x01,
+0x95,0x01,0x96,0x01,0x97,0x01,0x98,0x01,0x99,0x01,0x9A,0x01,0x9B,0x01,0x9C,0x01,
+0x9D,0x01,0x9E,0x01,0x9F,0x01,0xA0,0x01,0xA1,0x01,0xA2,0x01,0xA3,0x01,0xA4,0x01,
+0xA5,0x01,0xA6,0x01,0xA7,0x01,0xA8,0x01,0xA9,0x01,0xAA,0x01,0xAB,0x01,0xAC,0x01,
+0xAD,0x01,0xAE,0x01,0xAF,0x01,0xB0,0x01,0x69,0x01,0x6A,0x01,0x6B,0x01,0x6C,0x01,
+0x6D,0x01,0x6E,0x01,0x6F,0x01,0x70,0x01,0x71,0x01,0x72,0x01,0x73,0x01,0x74,0x01,
+0x75,0x01,0x76,0x01,0x77,0x01,0x78,0x01,0x79,0x01,0x7A,0x01,0x7B,0x01,0x7C,0x01,
+0x7D,0x01,0x7E,0x01,0x7F,0x01,0x80,0x01,0x81,0x01,0x82,0x01,0x83,0x01,0x84,0x01,
+0x85,0x01,0x86,0x01,0x87,0x01,0x88,0x01,0x89,0x01,0x8A,0x01,0x8B,0x01,0x8C,0x01,
+0x45,0x01,0x46,0x01,0x47,0x01,0x48,0x01,0x49,0x01,0x4A,0x01,0x4B,0x01,0x4C,0x01,
+0x4D,0x01,0x4E,0x01,0x4F,0x01,0x50,0x01,0x51,0x01,0x52,0x01,0x53,0x01,0x54,0x01,
+0x55,0x01,0x56,0x01,0x57,0x01,0x58,0x01,0x59,0x01,0x5A,0x01,0x5B,0x01,0x5C,0x01,
+0x5D,0x01,0x5E,0x01,0x5F,0x01,0x60,0x01,0x61,0x01,0x62,0x01,0x63,0x01,0x64,0x01,
+0x65,0x01,0x66,0x01,0x67,0x01,0x68,0x01,0x21,0x01,0x22,0x01,0x23,0x01,0x24,0x01,
+0x25,0x01,0x26,0x01,0x27,0x01,0x28,0x01,0x29,0x01,0x2A,0x01,0x2B,0x01,0x2C,0x01,
+0x2D,0x01,0x2E,0x01,0x2F,0x01,0x30,0x01,0x31,0x01,0x32,0x01,0x33,0x01,0x34,0x01,
+0x35,0x01,0x36,0x01,0x37,0x01,0x38,0x01,0x39,0x01,0x3A,0x01,0x3B,0x01,0x3C,0x01,
+0x3D,0x01,0x3E,0x01,0x3F,0x01,0x40,0x01,0x41,0x01,0x42,0x01,0x43,0x01,0x44,0x01,
+0xFD,0x00,0xFE,0x00,0xFF,0x00,0x00,0x01,0x01,0x01,0x02,0x01,0x03,0x01,0x04,0x01,
+0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0A,0x01,0x0B,0x01,0x0C,0x01,
+0x0D,0x01,0x0E,0x01,0x0F,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x13,0x01,0x14,0x01,
+0x15,0x01,0x16,0x01,0x17,0x01,0x18,0x01,0x19,0x01,0x1A,0x01,0x1B,0x01,0x1C,0x01,
+0x1D,0x01,0x1E,0x01,0x1F,0x01,0x20,0x01,0xD9,0x00,0xDA,0x00,0xDB,0x00,0xDC,0x00,
+0xDD,0x00,0xDE,0x00,0xDF,0x00,0xE0,0x00,0xE1,0x00,0xE2,0x00,0xE3,0x00,0xE4,0x00,
+0xE5,0x00,0xE6,0x00,0xE7,0x00,0xE8,0x00,0xE9,0x00,0xEA,0x00,0xEB,0x00,0xEC,0x00,
+0xED,0x00,0xEE,0x00,0xEF,0x00,0xF0,0x00,0xF1,0x00,0xF2,0x00,0xF3,0x00,0xF4,0x00,
+0xF5,0x00,0xF6,0x00,0xF7,0x00,0xF8,0x00,0xF9,0x00,0xFA,0x00,0xFB,0x00,0xFC,0x00,
+0xB5,0x00,0xB6,0x00,0xB7,0x00,0xB8,0x00,0xB9,0x00,0xBA,0x00,0xBB,0x00,0xBC,0x00,
+0xBD,0x00,0xBE,0x00,0xBF,0x00,0xC0,0x00,0xC1,0x00,0xC2,0x00,0xC3,0x00,0xC4,0x00,
+0xC5,0x00,0xC6,0x00,0xC7,0x00,0xC8,0x00,0xC9,0x00,0xCA,0x00,0xCB,0x00,0xCC,0x00,
+0xCD,0x00,0xCE,0x00,0xCF,0x00,0xD0,0x00,0xD1,0x00,0xD2,0x00,0xD3,0x00,0xD4,0x00,
+0xD5,0x00,0xD6,0x00,0xD7,0x00,0xD8,0x00,0x91,0x00,0x92,0x00,0x93,0x00,0x94,0x00,
+0x95,0x00,0x96,0x00,0x97,0x00,0x98,0x00,0x99,0x00,0x9A,0x00,0x9B,0x00,0x9C,0x00,
+0x9D,0x00,0x9E,0x00,0x9F,0x00,0xA0,0x00,0xA1,0x00,0xA2,0x00,0xA3,0x00,0xA4,0x00,
+0xA5,0x00,0xA6,0x00,0xA7,0x00,0xA8,0x00,0xA9,0x00,0xAA,0x00,0xAB,0x00,0xAC,0x00,
+0xAD,0x00,0xAE,0x00,0xAF,0x00,0xB0,0x00,0xB1,0x00,0xB2,0x00,0xB3,0x00,0xB4,0x00,
+0x6D,0x00,0x6E,0x00,0x6F,0x00,0x70,0x00,0x71,0x00,0x72,0x00,0x73,0x00,0x74,0x00,
+0x75,0x00,0x76,0x00,0x77,0x00,0x78,0x00,0x79,0x00,0x7A,0x00,0x7B,0x00,0x7C,0x00,
+0x7D,0x00,0x7E,0x00,0x7F,0x00,0x80,0x00,0x81,0x00,0x82,0x00,0x83,0x00,0x84,0x00,
+0x85,0x00,0x86,0x00,0x87,0x00,0x88,0x00,0x89,0x00,0x8A,0x00,0x8B,0x00,0x8C,0x00,
+0x8D,0x00,0x8E,0x00,0x8F,0x00,0x90,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,
+0x25,0x00,0x26,0x00,0x27,0x00,0x28,0x00,0x29,0x00,0x2A,0x00,0x2B,0x00,0x2C,0x00,
+0x2D,0x00,0x2E,0x00,0x2F,0x00,0x30,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x34,0x00,
+0x35,0x00,0x36,0x00,0x37,0x00,0x38,0x00,0x39,0x00,0x3A,0x00,0x3B,0x00,0x3C,0x00,
+0x3D,0x00,0x3E,0x00,0x3F,0x00,0x40,0x00,0x41,0x00,0x42,0x00,0x43,0x00,0x44,0x00,
+0x45,0x00,0x46,0x00,0x47,0x00,0x48,0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x04,0x00,
+0x05,0x00,0x06,0x00,0x07,0x00,0x08,0x00,0x09,0x00,0x0A,0x00,0x0B,0x00,0x0C,0x00,
+0x0D,0x00,0x0E,0x00,0x0F,0x00,0x10,0x00,0x11,0x00,0x12,0x00,0x13,0x00,0x14,0x00,
+0x15,0x00,0x16,0x00,0x17,0x00,0x18,0x00,0x19,0x00,0x1A,0x00,0x1B,0x00,0x1C,0x00,
+0x1D,0x00,0x1E,0x00,0x1F,0x00,0x20,0x00,0x21,0x00,0x22,0x00,0x23,0x00,0x24,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x03,0xB9,0x83,0x11,0x2B,0x01,0xBD,0x01,0x02,0xC2,0x08,0x70,
+0x01,0xBD,0x03,0x04,0xB2,0x04,0x38,0x08,0x70,0x01,0xBD,0x00,0x0A,0xB1,0xF8,0x27,
+0x27,0x00,0x00,0x0B,0x0E,0x0B,0x0E,0x33,0x02,0xD2,0x2D,0x2D,0x0B,0xB2,0x80,0x02,
+0x18,0x80,0x70,0x00,0x08,0x1C,0x08,0x11,0x05,0x01,0xE9,0xD1,0x02,0xB2,0x00,0x08,
+0x01,0xE9,0x00,0x01,0xBD,0x02,0x02,0xB2,0xB5,0x0A,0x01,0xBD,0x00,0x08,0xDD,0x00,
+0x00,0x08,0x1C,0x08,0x34,0x34,0x88,0x18,0xB4,0x65,0x6B,0x00,0x00,0xD0,0xD4,0x36,
+0xCF,0x06,0xCE,0x00,0xCE,0x00,0x00,0x00,0x07,0x00,0x2A,0x07,0x01,0x07,0x00,0x00,
+0x2A,0x01,0xBD,0x03,0x01,0xE9,0xC3,0x03,0xB4,0x01,0x67,0x2A,0x01,0xE9,0x00,0x01,
+0xBD,0x00,0x01,0xC1,0x01,0x01,0xBD,0x01,0x39,0xC1,0xFF,0xFB,0xF9,0xF6,0xF4,0xF1,
+0xEF,0xEA,0xE7,0xE5,0xE2,0xDF,0xDD,0xDA,0xD8,0xD5,0xD2,0xCF,0xCC,0xC5,0xBE,0xB7,
+0xB0,0xA8,0xA0,0x98,0x8E,0x85,0x7B,0x72,0x69,0x5E,0x53,0x48,0x3E,0x35,0x2B,0x22,
+0x17,0x0D,0x09,0x07,0x05,0x01,0x00,0x26,0xF0,0x86,0x25,0x6E,0xB6,0xDD,0xF3,0xD8,
+0xCC,0x9B,0x00,0x01,0xBD,0x02,0x39,0xC1,0xFF,0xFB,0xF9,0xF6,0xF4,0xF1,0xEF,0xEA,
+0xE7,0xE5,0xE2,0xDF,0xDD,0xDA,0xD8,0xD5,0xD2,0xCF,0xCC,0xC5,0xBE,0xB7,0xB0,0xA8,
+0xA0,0x98,0x8E,0x85,0x7B,0x72,0x69,0x5E,0x53,0x48,0x3E,0x35,0x2B,0x22,0x17,0x0D,
+0x09,0x07,0x05,0x01,0x00,0x26,0xF0,0x86,0x25,0x6E,0xB6,0xDD,0xF3,0xD8,0xCC,0x9B,
+0x00,0x01,0xBD,0x03,0x39,0xC1,0xFF,0xFB,0xF9,0xF6,0xF4,0xF1,0xEF,0xEA,0xE7,0xE5,
+0xE2,0xDF,0xDD,0xDA,0xD8,0xD5,0xD2,0xCF,0xCC,0xC5,0xBE,0xB7,0xB0,0xA8,0xA0,0x98,
+0x8E,0x85,0x7B,0x72,0x69,0x5E,0x53,0x48,0x3E,0x35,0x2B,0x22,0x17,0x0D,0x09,0x07,
+0x05,0x01,0x00,0x26,0xF0,0x86,0x25,0x6E,0xB6,0xDD,0xF3,0xD8,0xCC,0x9B,0x00,0x01,
+0xBD,0x00,0x01,0xC2,0xC8,0x01,0xCC,0x08,0x25,0xD3,0x81,0x00,0x00,0x00,0x00,0x01,
+0x00,0x04,0x00,0x01,0x13,0x40,0x04,0x09,0x09,0x0B,0x0B,0x32,0x10,0x08,0x00,0x08,
+0x32,0x10,0x08,0x00,0x08,0x32,0x10,0x08,0x00,0x08,0x00,0x00,0x0A,0x08,0x7B,0x01,
+0xE9,0xC5,0x01,0xC6,0xF7,0x01,0xE9,0x00,0x01,0xE9,0xD4,0x01,0xC6,0x6E,0x01,0xE9,
+0x00,0x01,0xE9,0xEF,0x01,0xD3,0x0C,0x01,0xE9,0x00,0x01,0xBD,0x01,0x01,0xE9,0xC8,
+0x01,0xD3,0xA1,0x01,0xE9,0x00,0x01,0xBD,0x00,0x38,0xD5,0x18,0x18,0x19,0x18,0x18,
+0x20,0x18,0x18,0x18,0x10,0x10,0x18,0x18,0x00,0x00,0x18,0x18,0x01,0x01,0x18,0x18,
+0x28,0x28,0x18,0x18,0x18,0x18,0x18,0x2F,0x2F,0x30,0x30,0x31,0x31,0x35,0x35,0x36,
+0x36,0x37,0x37,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFC,0xFC,0x00,0x00,0xFC,
+0xFC,0x00,0x00,0x30,0xD6,0x18,0x18,0x19,0x18,0x18,0x20,0x19,0x18,0x18,0x10,0x10,
+0x18,0x18,0x00,0x00,0x18,0x18,0x01,0x01,0x18,0x18,0x28,0x28,0x18,0x18,0x18,0x18,
+0x18,0x2F,0x2F,0x30,0x30,0x31,0x31,0x35,0x35,0x36,0x36,0x37,0x37,0x18,0x18,0x18,
+0x18,0x18,0x18,0x18,0x18,0x18,0xD8,0xAA,0xAA,0xAA,0xAF,0xEA,0xAA,0xAA,0xAA,0xAA,
+0xAF,0xEA,0xAA,0xAA,0xAA,0xAB,0xAF,0xEF,0xAA,0xAA,0xAA,0xAA,0xAF,0xEA,0xAA,0x01,
+0xBD,0x01,0x0C,0xD8,0xAA,0xAA,0xAB,0xAF,0xEA,0xAA,0xAA,0xAA,0xAE,0xAF,0xEA,0xAA,
+0x01,0xBD,0x02,0x0C,0xD8,0xAA,0xAA,0xAA,0xAF,0xEA,0xAA,0xAA,0xAA,0xAA,0xAF,0xEA,
+0xAA,0x01,0xBD,0x03,0x18,0xD8,0xBA,0xAA,0xAA,0xAF,0xEA,0xAA,0xAA,0xAA,0xAA,0xAF,
+0xEA,0xAA,0xBA,0xAA,0xAA,0xAF,0xEA,0xAA,0xAA,0xAA,0xAA,0xAF,0xEA,0xAA,0x01,0xBD,
+0x00,0x01,0xE9,0xE4,0x02,0xE7,0x17,0x69,0x01,0xE9,0x00,0x19,0xE7,0x09,0x09,0x00,
+0x07,0xE8,0x00,0x26,0x00,0x07,0x00,0x00,0xE8,0x32,0x00,0xE9,0x0A,0x0A,0x00,0x00,
+0x00,0x01,0x01,0x00,0x12,0x04,0x01,0xBD,0x01,0x09,0xE7,0x02,0x00,0x01,0x20,0x01,
+0x18,0x08,0xA8,0x09,0x01,0xBD,0x02,0x03,0xE7,0x20,0x20,0x00,0x01,0xBD,0x03,0x06,
+0xE7,0x00,0xDC,0x11,0x70,0x00,0x20,0x01,0xE9,0xC9,0x06,0xE7,0x2A,0xCE,0x02,0x70,
+0x01,0x04,0x01,0xE9,0x00,0x01,0xBD,0x00,0x01,0xD1,0x27,0x04,0xC9,0x04,0x0C,0x6D,
+0x01,0x00,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x03,0xB9,0x83,0x11,0x2B,0x01,0xBD,0x01,0x02,0xC2,0x08,0x70,
+0x01,0xBD,0x03,0x04,0xB2,0x04,0x38,0x08,0x70,0x01,0xBD,0x00,0x0A,0xB1,0xF8,0x27,
+0x27,0x00,0x00,0x0B,0x0E,0x0B,0x0E,0x33,0x02,0xD2,0x2D,0x2D,0x0B,0xB2,0x80,0x02,
+0x18,0x80,0x70,0x00,0x08,0x1C,0x08,0x11,0x05,0x01,0xE9,0xD1,0x02,0xB2,0x00,0x08,
+0x01,0xE9,0x00,0x01,0xBD,0x02,0x02,0xB2,0xB5,0x0A,0x01,0xBD,0x00,0x08,0xDD,0x00,
+0x00,0x08,0x1C,0x08,0x34,0x34,0x88,0x18,0xB4,0x65,0x6B,0x00,0x00,0xD0,0xD4,0x36,
+0xCF,0x06,0xCE,0x00,0xCE,0x00,0x00,0x00,0x07,0x00,0x2A,0x07,0x01,0x07,0x00,0x00,
+0x2A,0x01,0xBD,0x03,0x01,0xE9,0xC3,0x03,0xB4,0x01,0x67,0x2A,0x01,0xE9,0x00,0x01,
+0xBD,0x00,0x01,0xC1,0x01,0x01,0xBD,0x01,0x39,0xC1,0xFF,0xFB,0xF9,0xF6,0xF4,0xF1,
+0xEF,0xEA,0xE7,0xE5,0xE2,0xDF,0xDD,0xDA,0xD8,0xD5,0xD2,0xCF,0xCC,0xC5,0xBE,0xB7,
+0xB0,0xA8,0xA0,0x98,0x8E,0x85,0x7B,0x72,0x69,0x5E,0x53,0x48,0x3E,0x35,0x2B,0x22,
+0x17,0x0D,0x09,0x07,0x05,0x01,0x00,0x26,0xF0,0x86,0x25,0x6E,0xB6,0xDD,0xF3,0xD8,
+0xCC,0x9B,0x00,0x01,0xBD,0x02,0x39,0xC1,0xFF,0xFB,0xF9,0xF6,0xF4,0xF1,0xEF,0xEA,
+0xE7,0xE5,0xE2,0xDF,0xDD,0xDA,0xD8,0xD5,0xD2,0xCF,0xCC,0xC5,0xBE,0xB7,0xB0,0xA8,
+0xA0,0x98,0x8E,0x85,0x7B,0x72,0x69,0x5E,0x53,0x48,0x3E,0x35,0x2B,0x22,0x17,0x0D,
+0x09,0x07,0x05,0x01,0x00,0x26,0xF0,0x86,0x25,0x6E,0xB6,0xDD,0xF3,0xD8,0xCC,0x9B,
+0x00,0x01,0xBD,0x03,0x39,0xC1,0xFF,0xFB,0xF9,0xF6,0xF4,0xF1,0xEF,0xEA,0xE7,0xE5,
+0xE2,0xDF,0xDD,0xDA,0xD8,0xD5,0xD2,0xCF,0xCC,0xC5,0xBE,0xB7,0xB0,0xA8,0xA0,0x98,
+0x8E,0x85,0x7B,0x72,0x69,0x5E,0x53,0x48,0x3E,0x35,0x2B,0x22,0x17,0x0D,0x09,0x07,
+0x05,0x01,0x00,0x26,0xF0,0x86,0x25,0x6E,0xB6,0xDD,0xF3,0xD8,0xCC,0x9B,0x00,0x01,
+0xBD,0x00,0x01,0xC2,0xC8,0x01,0xCC,0x08,0x25,0xD3,0x81,0x00,0x00,0x00,0x00,0x01,
+0x00,0x04,0x00,0x01,0x13,0x40,0x04,0x09,0x09,0x0B,0x0B,0x32,0x10,0x08,0x00,0x08,
+0x32,0x10,0x08,0x00,0x08,0x32,0x10,0x08,0x00,0x08,0x00,0x00,0x0A,0x08,0x7B,0x01,
+0xE9,0xC5,0x01,0xC6,0xF7,0x01,0xE9,0x00,0x01,0xE9,0xD4,0x01,0xC6,0x6E,0x01,0xE9,
+0x00,0x01,0xE9,0xEF,0x01,0xD3,0x0C,0x01,0xE9,0x00,0x01,0xBD,0x01,0x01,0xE9,0xC8,
+0x01,0xD3,0xA1,0x01,0xE9,0x00,0x01,0xBD,0x00,0x38,0xD5,0x18,0x18,0x19,0x18,0x18,
+0x20,0x18,0x18,0x18,0x10,0x10,0x18,0x18,0x00,0x00,0x18,0x18,0x01,0x01,0x18,0x18,
+0x28,0x28,0x18,0x18,0x18,0x18,0x18,0x2F,0x2F,0x30,0x30,0x31,0x31,0x35,0x35,0x36,
+0x36,0x37,0x37,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFC,0xFC,0x00,0x00,0xFC,
+0xFC,0x00,0x00,0x30,0xD6,0x18,0x18,0x19,0x18,0x18,0x20,0x19,0x18,0x18,0x10,0x10,
+0x18,0x18,0x00,0x00,0x18,0x18,0x01,0x01,0x18,0x18,0x28,0x28,0x18,0x18,0x18,0x18,
+0x18,0x2F,0x2F,0x30,0x30,0x31,0x31,0x35,0x35,0x36,0x36,0x37,0x37,0x18,0x18,0x18,
+0x18,0x18,0x18,0x18,0x18,0x18,0xD8,0xAA,0xAA,0xAA,0xAF,0xEA,0xAA,0xAA,0xAA,0xAA,
+0xAF,0xEA,0xAA,0xAA,0xAA,0xAB,0xAF,0xEF,0xAA,0xAA,0xAA,0xAA,0xAF,0xEA,0xAA,0x01,
+0xBD,0x01,0x0C,0xD8,0xAA,0xAA,0xAB,0xAF,0xEA,0xAA,0xAA,0xAA,0xAE,0xAF,0xEA,0xAA,
+0x01,0xBD,0x02,0x0C,0xD8,0xAA,0xAA,0xAA,0xAF,0xEA,0xAA,0xAA,0xAA,0xAA,0xAF,0xEA,
+0xAA,0x01,0xBD,0x03,0x18,0xD8,0xBA,0xAA,0xAA,0xAF,0xEA,0xAA,0xAA,0xAA,0xAA,0xAF,
+0xEA,0xAA,0xBA,0xAA,0xAA,0xAF,0xEA,0xAA,0xAA,0xAA,0xAA,0xAF,0xEA,0xAA,0x01,0xBD,
+0x00,0x01,0xE9,0xE4,0x02,0xE7,0x17,0x69,0x01,0xE9,0x00,0x19,0xE7,0x09,0x09,0x00,
+0x07,0xE8,0x00,0x26,0x00,0x07,0x00,0x00,0xE8,0x32,0x00,0xE9,0x0A,0x0A,0x00,0x00,
+0x00,0x01,0x01,0x00,0x12,0x04,0x01,0xBD,0x01,0x09,0xE7,0x02,0x00,0x01,0x20,0x01,
+0x18,0x08,0xA8,0x09,0x01,0xBD,0x02,0x03,0xE7,0x20,0x20,0x00,0x01,0xBD,0x03,0x06,
+0xE7,0x00,0xDC,0x11,0x70,0x00,0x20,0x01,0xE9,0xC9,0x06,0xE7,0x2A,0xCE,0x02,0x70,
+0x01,0x04,0x01,0xE9,0x00,0x01,0xBD,0x00,0x01,0xD1,0x27,0x04,0xC9,0x04,0x0C,0x6D,
+0x01,0x00,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x30,0xC3,0x1B,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x08,0x78,0x56,0xE7,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x53,0x00,0x00,0x00,0x0C,0x2B,0xDF,0x15
diff --git a/drivers/input/touchscreen/hxchipset83112b/Kconfig b/drivers/input/touchscreen/hxchipset83112b/Kconfig
new file mode 100755
index 0000000..2efd9c3
--- /dev/null
+++ b/drivers/input/touchscreen/hxchipset83112b/Kconfig
@@ -0,0 +1,27 @@
+#
+# Himax Touchscreen driver configuration
+#
+
+config TOUCHSCREEN_HIMAX_I2C
+ tristate "HIMAX chipset i2c touchscreen"
+ depends on TOUCHSCREEN_HIMAX_CHIPSET
+ help
+ This enables support for HIMAX CHIPSET over I2C based touchscreens.
+
+config TOUCHSCREEN_HIMAX_DEBUG
+ tristate "HIMAX debug function"
+ depends on TOUCHSCREEN_HIMAX_I2C
+ help
+ This enables support for HIMAX debug function.
+
+config TOUCHSCREEN_HIMAX_ITO_TEST
+ tristate "HIMAX driver test over Dragon Board"
+ depends on TOUCHSCREEN_HIMAX_I2C
+ help
+ This enables support for HIMAX driver test over Dragon Board.
+
+config HMX_DB
+ tristate "HIMAX driver test over Dragon Board"
+ depends on TOUCHSCREEN_HIMAX_I2C
+ help
+ This enables support for HIMAX driver test over Dragon Board.
diff --git a/drivers/input/touchscreen/hxchipset83112b/Makefile b/drivers/input/touchscreen/hxchipset83112b/Makefile
new file mode 100755
index 0000000..522907a
--- /dev/null
+++ b/drivers/input/touchscreen/hxchipset83112b/Makefile
@@ -0,0 +1,4 @@
+# Makefile for the Himax touchscreen drivers.
+
+obj-$(CONFIG_TOUCHSCREEN_HIMAX_I2C) += himax_platform.o himax_ic.o himax_common.o himax_debug.o
+obj-$(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) += himax_ito_test.o
\ No newline at end of file
diff --git a/drivers/input/touchscreen/hxchipset83112b/himax_common.c b/drivers/input/touchscreen/hxchipset83112b/himax_common.c
new file mode 100755
index 0000000..5f1a98f
--- /dev/null
+++ b/drivers/input/touchscreen/hxchipset83112b/himax_common.c
@@ -0,0 +1,2398 @@
+/* Himax Android Driver Sample Code for common functions
+*
+* Copyright (C) 2017 Himax Corporation.
+*
+* 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 "himax_common.h"
+#include "himax_ic.h"
+
+#define SUPPORT_FINGER_DATA_CHECKSUM 0x0F
+#define TS_WAKE_LOCK_TIMEOUT (2 * HZ)
+#define FRAME_COUNT 5
+
+#ifdef HX_RST_PIN_FUNC
+extern void himax_ic_reset(uint8_t loadconfig,uint8_t int_off);
+#endif
+#if defined(HX_AUTO_UPDATE_FW)
+
+unsigned char i_CTPM_FW_HX83112A[]=
+{
+ 0
+};
+unsigned char i_CTPM_FW_HX83112B[]=
+{
+#include "FP_DJN_Arima_CID0804_D02_C14_20190903.i"
+};
+
+#endif
+
+static void himax_release_all_finger(void);
+
+#if defined(HX_SMART_WAKEUP)||defined(HX_HIGH_SENSE)||defined(HX_USB_DETECT_GLOBAL)
+extern void himax_resend_cmd_func(bool suspended);
+extern void himax_rst_cmd_recovery_func(bool suspended);
+#endif
+
+#ifdef HX_RST_PIN_FUNC
+int reset_flag =1;
+#endif
+
+struct himax_ts_data *private_ts;
+struct himax_ic_data *ic_data;
+struct himax_report_data *hx_touch_data;
+
+static int HX_TOUCH_INFO_POINT_CNT = 0;
+
+unsigned long FW_VER_MAJ_FLASH_ADDR;
+unsigned long FW_VER_MIN_FLASH_ADDR;
+unsigned long CFG_VER_MAJ_FLASH_ADDR;
+unsigned long CFG_VER_MIN_FLASH_ADDR;
+unsigned long CID_VER_MAJ_FLASH_ADDR;
+unsigned long CID_VER_MIN_FLASH_ADDR;
+//unsigned long PANEL_VERSION_ADDR;
+
+unsigned long FW_VER_MAJ_FLASH_LENG;
+unsigned long FW_VER_MIN_FLASH_LENG;
+unsigned long CFG_VER_MAJ_FLASH_LENG;
+unsigned long CFG_VER_MIN_FLASH_LENG;
+unsigned long CID_VER_MAJ_FLASH_LENG;
+unsigned long CID_VER_MIN_FLASH_LENG;
+//unsigned long PANEL_VERSION_LENG;
+
+unsigned long FW_CFG_VER_FLASH_ADDR;
+
+#ifdef HX_AUTO_UPDATE_FW
+int g_i_FW_VER = 0;
+int g_i_CFG_VER = 0;
+int g_i_CID_MAJ = 0; //GUEST ID
+int g_i_CID_MIN = 0; //VER for GUEST
+#endif
+
+unsigned char IC_TYPE = 11;
+unsigned char IC_CHECKSUM = 0;
+
+#ifdef HX_ESD_RECOVERY
+u8 HX_ESD_RESET_ACTIVATE = 0;
+int hx_EB_event_flag = 0;
+int hx_EC_event_flag = 0;
+int hx_ED_event_flag = 0;
+extern int g_zero_event_count;
+#endif
+u8 HX_HW_RESET_ACTIVATE = 0;
+
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
+extern int himax_touch_proc_init(void);
+extern void himax_touch_proc_deinit(void);
+//PROC-START
+#ifdef HX_TP_PROC_FLASH_DUMP
+extern void himax_ts_flash_func(void);
+extern void setFlashBuffer(void);
+extern bool getFlashDumpGoing(void);
+extern uint8_t getSysOperation(void);
+extern void setSysOperation(uint8_t operation);
+#endif
+#ifdef HX_TP_PROC_GUEST_INFO
+extern int himax_guest_info_get_status(void);
+extern void himax_guest_info_set_status(int setting);
+extern int himax_read_project_id(void);
+#endif
+
+#if defined(HX_PLATFOME_DEFINE_KEY)
+extern void himax_platform_key(void);
+#endif
+
+#ifdef HX_TP_PROC_DIAG
+extern void himax_ts_diag_func(void);
+
+extern int16_t *getMutualBuffer(void);
+extern int16_t *getMutualNewBuffer(void);
+extern int16_t *getMutualOldBuffer(void);
+extern int16_t *getSelfBuffer(void);
+extern uint8_t getXChannel(void);
+extern uint8_t getYChannel(void);
+extern uint8_t getDiagCommand(void);
+extern void setXChannel(uint8_t x);
+extern void setYChannel(uint8_t y);
+extern void setMutualBuffer(void);
+extern void setMutualNewBuffer(void);
+extern void setMutualOldBuffer(void);
+extern uint8_t diag_coor[128];
+extern int himax_set_diag_cmd(struct himax_ic_data *ic_data,struct himax_report_data *hx_touch_data);
+#ifdef HX_TP_PROC_2T2R
+extern bool Is_2T2R;
+extern int16_t *getMutualBuffer_2(void);
+extern uint8_t getXChannel_2(void);
+extern uint8_t getYChannel_2(void);
+extern void setXChannel_2(uint8_t x);
+extern void setYChannel_2(uint8_t y);
+extern void setMutualBuffer_2(void);
+#endif
+#endif
+//PROC-END
+#endif
+
+extern int himax_parse_dt(struct himax_ts_data *ts,
+ struct himax_i2c_platform_data *pdata);
+extern bool himax_calculateChecksum(struct i2c_client *client, bool change_iref);
+#if defined(HX_EN_SEL_BUTTON) || defined(HX_EN_MUT_BUTTON)
+static uint8_t vk_press = 0x00;
+#endif
+static uint8_t AA_press = 0x00;
+static uint8_t EN_NoiseFilter = 0x00;
+static uint8_t Last_EN_NoiseFilter = 0x00;
+static int hx_point_num = 0; // for himax_ts_work_func use
+static int p_point_num = 0xFFFF;
+static int tpd_key = 0x00;
+static int tpd_key_old = 0x00;
+static int probe_fail_flag = 0;
+#ifdef HX_USB_DETECT_GLOBAL
+//bool USB_detect_flag = 0;
+#endif
+
+#if defined(CONFIG_FB)
+int fb_notifier_callback(struct notifier_block *self,
+ unsigned long event, void *data);
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+static void himax_ts_early_suspend(struct early_suspend *h);
+static void himax_ts_late_resume(struct early_suspend *h);
+#endif
+
+#if defined(HX_PALM_REPORT)
+int himax_palm_detect(uint8_t *buf);
+#endif
+
+#ifdef HX_GESTURE_TRACK
+static int gest_pt_cnt;
+static int gest_pt_x[GEST_PT_MAX_NUM];
+static int gest_pt_y[GEST_PT_MAX_NUM];
+static int gest_start_x=0,gest_start_y=0,gest_end_x=0,gest_end_y=0;
+static int gest_width=0,gest_height=0,gest_mid_x=0,gest_mid_y=0;
+static int gn_gesture_coor[16];
+#endif
+
+#ifdef HX_CHIP_STATUS_MONITOR
+struct chip_monitor_data *g_chip_monitor_data;
+#endif
+
+#if defined(HX_TP_PROC_SELF_TEST)|| defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST)
+extern int g_self_test_entered;
+#endif
+
+int himax_report_data_init(void);
+extern int himax_get_touch_data_size(void);
+//void himax_HW_reset(uint8_t loadconfig,uint8_t int_off);
+extern void himax_log_touch_data(uint8_t *buf,struct himax_report_data *hx_touch_data);
+extern void himax_log_touch_event(int x,int y,int w,int loop_i,uint8_t EN_NoiseFilter,int touched);
+extern void himax_log_touch_event_detail(struct himax_ts_data *ts,int x,int y,int w,int loop_i,uint8_t EN_NoiseFilter,int touched,uint16_t old_finger);
+
+#if defined(HX_ESD_RECOVERY)
+extern void himax_esd_ic_reset(void);
+extern int himax_ic_esd_recovery(int hx_esd_event,int hx_zero_event,int length);
+#endif
+
+extern int himax_dev_set(struct himax_ts_data *ts);
+extern int himax_input_register_device(struct input_dev *input_dev);
+
+
+#ifdef HX_ZERO_FLASH
+extern void himax_0f_operation(struct work_struct *work);
+#endif
+
+int himax_input_register(struct himax_ts_data *ts)
+{
+ int ret = 0;
+
+ ret = himax_dev_set(ts);
+ if(ret < 0)
+ goto input_device_fail;
+
+ set_bit(EV_SYN, ts->input_dev->evbit);
+ set_bit(EV_ABS, ts->input_dev->evbit);
+ set_bit(EV_KEY, ts->input_dev->evbit);
+
+#if defined(HX_EN_SEL_BUTTON) || defined(HX_EN_MUT_BUTTON)
+#if defined(HX_PLATFOME_DEFINE_KEY)
+ himax_platform_key();
+#else
+ set_bit(KEY_BACK, ts->input_dev->keybit);
+ set_bit(KEY_HOME, ts->input_dev->keybit);
+ set_bit(KEY_MENU, ts->input_dev->keybit);
+ set_bit(KEY_SEARCH, ts->input_dev->keybit);
+ set_bit(KEY_APP_SWITCH, ts->input_dev->keybit);
+#endif
+#endif
+
+#if defined(HX_SMART_WAKEUP) || defined(HX_PALM_REPORT)
+ set_bit(KEY_POWER, ts->input_dev->keybit);
+#endif
+#if defined(HX_SMART_WAKEUP)
+ set_bit(KEY_CUST_01, ts->input_dev->keybit);
+ set_bit(KEY_CUST_02, ts->input_dev->keybit);
+ set_bit(KEY_CUST_03, ts->input_dev->keybit);
+ set_bit(KEY_CUST_04, ts->input_dev->keybit);
+ set_bit(KEY_CUST_05, ts->input_dev->keybit);
+ set_bit(KEY_CUST_06, ts->input_dev->keybit);
+ set_bit(KEY_CUST_07, ts->input_dev->keybit);
+ set_bit(KEY_CUST_08, ts->input_dev->keybit);
+ set_bit(KEY_CUST_09, ts->input_dev->keybit);
+ set_bit(KEY_CUST_10, ts->input_dev->keybit);
+ set_bit(KEY_CUST_11, ts->input_dev->keybit);
+ set_bit(KEY_CUST_12, ts->input_dev->keybit);
+ set_bit(KEY_CUST_13, ts->input_dev->keybit);
+ set_bit(KEY_CUST_14, ts->input_dev->keybit);
+ set_bit(KEY_CUST_15, ts->input_dev->keybit);
+#endif
+ set_bit(BTN_TOUCH, ts->input_dev->keybit);
+ set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit);
+
+#ifdef HX_PROTOCOL_A
+ //ts->input_dev->mtsize = ts->nFinger_support;
+ input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID,
+ 0, 3, 0, 0);
+#else
+ set_bit(MT_TOOL_FINGER, ts->input_dev->keybit);
+#if defined(HX_PROTOCOL_B_3PA)
+ input_mt_init_slots(ts->input_dev, ts->nFinger_support,0);
+#else
+ input_mt_init_slots(ts->input_dev, ts->nFinger_support);
+#endif
+#endif
+
+ I("input_set_abs_params: mix_x %d, max_x %d, min_y %d, max_y %d\n",
+ ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_y_min, ts->pdata->abs_y_max);
+
+ input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X,ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_x_fuzz, 0);
+ input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y,ts->pdata->abs_y_min, ts->pdata->abs_y_max, ts->pdata->abs_y_fuzz, 0);
+ input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR,ts->pdata->abs_pressure_min, ts->pdata->abs_pressure_max, ts->pdata->abs_pressure_fuzz, 0);
+#ifndef HX_PROTOCOL_A
+ input_set_abs_params(ts->input_dev, ABS_MT_PRESSURE,ts->pdata->abs_pressure_min, ts->pdata->abs_pressure_max, ts->pdata->abs_pressure_fuzz, 0);
+ input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR,ts->pdata->abs_width_min, ts->pdata->abs_width_max, ts->pdata->abs_pressure_fuzz, 0);
+#endif
+// input_set_abs_params(ts->input_dev, ABS_MT_AMPLITUDE, 0, ((ts->pdata->abs_pressure_max << 16) | ts->pdata->abs_width_max), 0, 0);
+// input_set_abs_params(ts->input_dev, ABS_MT_POSITION, 0, (BIT(31) | (ts->pdata->abs_x_max << 16) | ts->pdata->abs_y_max), 0, 0);
+
+
+ if(himax_input_register_device(ts->input_dev) == 0)
+ return NO_ERR;
+ else
+ ret = INPUT_REGISTER_FAIL;
+
+input_device_fail:
+ I("%s, input device register fail!\n",__func__);
+ return ret;
+}
+
+static void calcDataSize(uint8_t finger_num)
+{
+ struct himax_ts_data *ts_data = private_ts;
+ ts_data->coord_data_size = 4 * finger_num;
+ ts_data->area_data_size = ((finger_num / 4) + (finger_num % 4 ? 1 : 0)) * 4;
+ //printk("allenyu : area_data_size = %d \n",ts_data->area_data_size );
+ ts_data->coordInfoSize = ts_data->coord_data_size + ts_data->area_data_size + 4;
+ ts_data->raw_data_frame_size = 128 - ts_data->coord_data_size - ts_data->area_data_size - 4 - 4 - 1;
+ if(ts_data->raw_data_frame_size == 0)
+ {
+ E("%s: could NOT calculate! \n", __func__);
+ return;
+ }
+ ts_data->raw_data_nframes = ((uint32_t)ts_data->x_channel * ts_data->y_channel +
+ ts_data->x_channel + ts_data->y_channel) / ts_data->raw_data_frame_size +
+ (((uint32_t)ts_data->x_channel * ts_data->y_channel +
+ ts_data->x_channel + ts_data->y_channel) % ts_data->raw_data_frame_size)? 1 : 0;
+ I("%s: coord_data_size: %d, area_data_size:%d, raw_data_frame_size:%d, raw_data_nframes:%d", __func__, ts_data->coord_data_size, ts_data->area_data_size, ts_data->raw_data_frame_size, ts_data->raw_data_nframes);
+}
+
+void calculate_point_number(void)
+{
+ HX_TOUCH_INFO_POINT_CNT = ic_data->HX_MAX_PT * 4 ;
+
+ if ( (ic_data->HX_MAX_PT % 4) == 0)
+ HX_TOUCH_INFO_POINT_CNT += (ic_data->HX_MAX_PT / 4) * 4 ;
+ else
+ HX_TOUCH_INFO_POINT_CNT += ((ic_data->HX_MAX_PT / 4) +1) * 4 ;
+}
+
+#ifdef HX_AUTO_UPDATE_FW
+static int i_update_FW(void)
+{
+ int upgrade_times = 0;
+ //unsigned char* ImageBuffer = i_CTPM_FW;
+ //int fullFileLength = sizeof(i_CTPM_FW);
+ unsigned char* ImageBuffer = NULL;
+ int fullFileLength = 0;
+ uint8_t ret = 0, result = 0;
+
+if(IC_TYPE == HX_83112A_SERIES_PWON)
+ {
+ ImageBuffer = i_CTPM_FW_HX83112A;
+ fullFileLength = sizeof(i_CTPM_FW_HX83112A);
+ }
+ else/*HX_83112B_SERIES_PWON*/
+ {
+ //printk("%s: (%d)No upgrade 2nd source fw\n", __func__, __LINE__);
+ //return false;
+ ImageBuffer = i_CTPM_FW_HX83112B;
+ fullFileLength = sizeof(i_CTPM_FW_HX83112B);
+ }
+ I("%s: i_fullFileLength = %d\n", __func__,fullFileLength);
+
+ himax_int_enable(private_ts->client->irq,0);
+update_retry:
+ if(fullFileLength == FW_SIZE_32k)
+ {
+ ret = fts_ctpm_fw_upgrade_with_sys_fs_32k(private_ts->client,ImageBuffer,fullFileLength,false);
+ }
+ else if(fullFileLength == FW_SIZE_60k)
+ {
+ ret = fts_ctpm_fw_upgrade_with_sys_fs_60k(private_ts->client,ImageBuffer,fullFileLength,false);
+ }
+ else if (fullFileLength == FW_SIZE_64k)
+ {
+ ret = fts_ctpm_fw_upgrade_with_sys_fs_64k(private_ts->client,ImageBuffer,fullFileLength,false);
+ }
+ else if (fullFileLength == FW_SIZE_124k)
+ {
+ ret = fts_ctpm_fw_upgrade_with_sys_fs_124k(private_ts->client,ImageBuffer,fullFileLength,false);
+ }
+ else if (fullFileLength == FW_SIZE_128k)
+ {
+ ret = fts_ctpm_fw_upgrade_with_sys_fs_128k(private_ts->client,ImageBuffer,fullFileLength,false);
+ }
+ if(ret == 0)
+ {
+ upgrade_times++;
+ E("%s: TP upgrade error, upgrade_times = %d\n", __func__, upgrade_times);
+ if(upgrade_times < 3)
+ goto update_retry;
+ else
+ result = -1;//upgrade fail
+ }
+ else
+ {
+ ic_data->vendor_fw_ver = g_i_FW_VER;
+ ic_data->vendor_config_ver = g_i_CFG_VER;
+ result = 1;//upgrade success
+ I("%s: TP upgrade OK\n", __func__);
+ }
+#ifdef HX_RST_PIN_FUNC
+ himax_ic_reset(true,false);
+#endif
+ himax_int_enable(private_ts->client->irq,1);
+ return result;
+}
+#endif
+
+int himax_loadSensorConfig(struct i2c_client *client, struct himax_i2c_platform_data *pdata)
+{
+
+ if (!client)
+ {
+ E("%s: Necessary parameters client are null!\n", __func__);
+ return -1;
+ }
+
+ I("%s: initialization complete\n", __func__);
+
+ return NO_ERR;
+}
+
+#ifdef HX_ESD_RECOVERY
+void himax_esd_hw_reset(void)
+{
+ I("START_Himax TP: ESD - Reset\n");
+#if defined(HX_TP_PROC_SELF_TEST) || defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST)
+ if (g_self_test_entered == 1)
+ {
+ I("In self test ,not TP: ESD - Reset\n");
+ return;
+ }
+#endif
+ HX_ESD_RESET_ACTIVATE = 1;
+#if defined(HX_CHIP_STATUS_MONITOR)
+ g_chip_monitor_data->HX_CHIP_POLLING_COUNT=0;
+#endif
+ himax_esd_ic_reset();
+
+ I("END_Himax TP: ESD - Reset\n");
+}
+#endif
+
+#ifdef HX_CHIP_STATUS_MONITOR
+static void himax_chip_monitor_function(struct work_struct *work) //for ESD solution
+{
+ int ret=0;
+
+ I(" %s: POLLING_COUNT=%x, STATUS=%x\n", __func__,g_chip_monitor_data->HX_CHIP_POLLING_COUNT,ret);
+ if(g_chip_monitor_data->HX_CHIP_POLLING_COUNT >= (g_chip_monitor_data->HX_POLLING_TIMES-1))//POLLING TIME
+ {
+ g_chip_monitor_data->HX_ON_HAND_SHAKING=1;
+ ret = himax_hand_shaking(private_ts->client); //0:Running, 1:Stop, 2:I2C Fail
+ g_chip_monitor_data->HX_ON_HAND_SHAKING=0;
+ if(ret == 2)
+ {
+ I(" %s: I2C Fail \n", __func__);
+ himax_esd_hw_reset();
+ }
+ else if(ret == 1)
+ {
+ I(" %s: MCU Stop \n", __func__);
+ himax_esd_hw_reset();
+ }
+ g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0;//clear polling counter
+ }
+ else
+ g_chip_monitor_data->HX_CHIP_POLLING_COUNT++;
+
+
+ g_chip_monitor_data->HX_CHIP_MONITOR_EN = 1;
+ queue_delayed_work(private_ts->himax_chip_monitor_wq, &private_ts->himax_chip_monitor, g_chip_monitor_data->HX_POLLING_TIMER*HZ);
+
+ return;
+}
+#endif
+
+#ifdef HX_SMART_WAKEUP
+#ifdef HX_GESTURE_TRACK
+static void gest_pt_log_coordinate(int rx, int tx)
+{
+ //driver report x y with range 0 - 255 , we scale it up to x/y pixel
+ gest_pt_x[gest_pt_cnt] = rx*(ic_data->HX_X_RES)/255;
+ gest_pt_y[gest_pt_cnt] = tx*(ic_data->HX_Y_RES)/255;
+}
+#endif
+static int himax_parse_wake_event(struct himax_ts_data *ts)
+{
+ uint8_t *buf;
+#ifdef HX_GESTURE_TRACK
+ int tmp_max_x=0x00,tmp_min_x=0xFFFF,tmp_max_y=0x00,tmp_min_y=0xFFFF;
+ int gest_len;
+#endif
+ int i=0, check_FC = 0, gesture_flag = 0;
+
+ buf = kzalloc(hx_touch_data->event_size*sizeof(uint8_t),GFP_KERNEL);
+ memcpy(buf,hx_touch_data->hx_event_buf,hx_touch_data->event_size);
+
+ for(i=0; i<GEST_PTLG_ID_LEN; i++)
+ {
+ if (check_FC==0)
+ {
+ if((buf[0]!=0x00)&&((buf[0]<=0x0F)||(buf[0]==0x80)))
+ {
+ check_FC = 1;
+ gesture_flag = buf[i];
+ }
+ else
+ {
+ check_FC = 0;
+ I("ID START at %x , value = %x skip the event\n", i, buf[i]);
+ break;
+ }
+ }
+ else
+ {
+ if(buf[i]!=gesture_flag)
+ {
+ check_FC = 0;
+ I("ID NOT the same %x != %x So STOP parse event\n", buf[i], gesture_flag);
+ break;
+ }
+ }
+
+ I("0x%2.2X ", buf[i]);
+ if (i % 8 == 7)
+ I("\n");
+ }
+ I("Himax gesture_flag= %x\n",gesture_flag );
+ I("Himax check_FC is %d\n", check_FC);
+
+ if (check_FC == 0)
+ return 0;
+ if(buf[GEST_PTLG_ID_LEN] != GEST_PTLG_HDR_ID1 ||
+ buf[GEST_PTLG_ID_LEN+1] != GEST_PTLG_HDR_ID2)
+ return 0;
+
+#ifdef HX_GESTURE_TRACK
+ if(buf[GEST_PTLG_ID_LEN] == GEST_PTLG_HDR_ID1 &&
+ buf[GEST_PTLG_ID_LEN+1] == GEST_PTLG_HDR_ID2)
+ {
+ gest_len = buf[GEST_PTLG_ID_LEN+2];
+
+ I("gest_len = %d ",gest_len);
+
+ i = 0;
+ gest_pt_cnt = 0;
+ I("gest doornidate start \n %s",__func__);
+ while(i<(gest_len+1)/2)
+ {
+ gest_pt_log_coordinate(buf[GEST_PTLG_ID_LEN+4+i*2],buf[GEST_PTLG_ID_LEN+4+i*2+1]);
+ i++;
+
+ I("gest_pt_x[%d]=%d \n",gest_pt_cnt,gest_pt_x[gest_pt_cnt]);
+ I("gest_pt_y[%d]=%d \n",gest_pt_cnt,gest_pt_y[gest_pt_cnt]);
+
+ gest_pt_cnt +=1;
+ }
+ if(gest_pt_cnt)
+ {
+ for(i=0; i<gest_pt_cnt; i++)
+ {
+ if(tmp_max_x<gest_pt_x[i])
+ tmp_max_x=gest_pt_x[i];
+ if(tmp_min_x>gest_pt_x[i])
+ tmp_min_x=gest_pt_x[i];
+ if(tmp_max_y<gest_pt_y[i])
+ tmp_max_y=gest_pt_y[i];
+ if(tmp_min_y>gest_pt_y[i])
+ tmp_min_y=gest_pt_y[i];
+ }
+ I("gest_point x_min= %d, x_max= %d, y_min= %d, y_max= %d\n",tmp_min_x,tmp_max_x,tmp_min_y,tmp_max_y);
+ gest_start_x=gest_pt_x[0];
+ gn_gesture_coor[0] = gest_start_x;
+ gest_start_y=gest_pt_y[0];
+ gn_gesture_coor[1] = gest_start_y;
+ gest_end_x=gest_pt_x[gest_pt_cnt-1];
+ gn_gesture_coor[2] = gest_end_x;
+ gest_end_y=gest_pt_y[gest_pt_cnt-1];
+ gn_gesture_coor[3] = gest_end_y;
+ gest_width = tmp_max_x - tmp_min_x;
+ gn_gesture_coor[4] = gest_width;
+ gest_height = tmp_max_y - tmp_min_y;
+ gn_gesture_coor[5] = gest_height;
+ gest_mid_x = (tmp_max_x + tmp_min_x)/2;
+ gn_gesture_coor[6] = gest_mid_x;
+ gest_mid_y = (tmp_max_y + tmp_min_y)/2;
+ gn_gesture_coor[7] = gest_mid_y;
+ gn_gesture_coor[8] = gest_mid_x;//gest_up_x
+ gn_gesture_coor[9] = gest_mid_y-gest_height/2;//gest_up_y
+ gn_gesture_coor[10] = gest_mid_x;//gest_down_x
+ gn_gesture_coor[11] = gest_mid_y+gest_height/2; //gest_down_y
+ gn_gesture_coor[12] = gest_mid_x-gest_width/2; //gest_left_x
+ gn_gesture_coor[13] = gest_mid_y; //gest_left_y
+ gn_gesture_coor[14] = gest_mid_x+gest_width/2; //gest_right_x
+ gn_gesture_coor[15] = gest_mid_y; //gest_right_y
+
+ }
+
+ }
+#endif
+ if(gesture_flag != 0x80)
+ {
+ if(!ts->gesture_cust_en[gesture_flag])
+ {
+ I("%s NOT report customer key \n ",__func__);
+ return 0;//NOT report customer key
+ }
+ }
+ else
+ {
+ if(!ts->gesture_cust_en[0])
+ {
+ I("%s NOT report report double click \n",__func__);
+ return 0;//NOT report power key
+ }
+ }
+
+ if(gesture_flag == 0x80)
+ return EV_GESTURE_PWR;
+ else
+ return gesture_flag;
+}
+
+void himax_wake_check_func(void)
+{
+ int ret_event = 0, KEY_EVENT = 0;
+
+ ret_event = himax_parse_wake_event(private_ts);
+ switch (ret_event)
+ {
+ case EV_GESTURE_PWR:
+ KEY_EVENT = KEY_POWER;
+ break;
+ case EV_GESTURE_01:
+ KEY_EVENT = KEY_CUST_01;
+ break;
+ case EV_GESTURE_02:
+ KEY_EVENT = KEY_CUST_02;
+ break;
+ case EV_GESTURE_03:
+ KEY_EVENT = KEY_CUST_03;
+ break;
+ case EV_GESTURE_04:
+ KEY_EVENT = KEY_CUST_04;
+ break;
+ case EV_GESTURE_05:
+ KEY_EVENT = KEY_CUST_05;
+ break;
+ case EV_GESTURE_06:
+ KEY_EVENT = KEY_CUST_06;
+ break;
+ case EV_GESTURE_07:
+ KEY_EVENT = KEY_CUST_07;
+ break;
+ case EV_GESTURE_08:
+ KEY_EVENT = KEY_CUST_08;
+ break;
+ case EV_GESTURE_09:
+ KEY_EVENT = KEY_CUST_09;
+ break;
+ case EV_GESTURE_10:
+ KEY_EVENT = KEY_CUST_10;
+ break;
+ case EV_GESTURE_11:
+ KEY_EVENT = KEY_CUST_11;
+ break;
+ case EV_GESTURE_12:
+ KEY_EVENT = KEY_CUST_12;
+ break;
+ case EV_GESTURE_13:
+ KEY_EVENT = KEY_CUST_13;
+ break;
+ case EV_GESTURE_14:
+ KEY_EVENT = KEY_CUST_14;
+ break;
+ case EV_GESTURE_15:
+ KEY_EVENT = KEY_CUST_15;
+ break;
+ }
+ if(ret_event)
+ {
+ I(" %s SMART WAKEUP KEY event %x press\n",__func__,KEY_EVENT);
+ input_report_key(private_ts->input_dev, KEY_EVENT, 1);
+ input_sync(private_ts->input_dev);
+ //msleep(100);
+ I(" %s SMART WAKEUP KEY event %x release\n",__func__,KEY_EVENT);
+ input_report_key(private_ts->input_dev, KEY_EVENT, 0);
+ input_sync(private_ts->input_dev);
+ FAKE_POWER_KEY_SEND=true;
+#ifdef HX_GESTURE_TRACK
+ I("gest_start_x= %d, gest_start_y= %d, gest_end_x= %d, gest_end_y= %d\n",gest_start_x,gest_start_y,
+ gest_end_x,gest_end_y);
+ I("gest_width= %d, gest_height= %d, gest_mid_x= %d, gest_mid_y= %d\n",gest_width,gest_height,
+ gest_mid_x,gest_mid_y);
+ I("gest_up_x= %d, gest_up_y= %d, gest_down_x= %d, gest_down_y= %d\n",gn_gesture_coor[8],gn_gesture_coor[9],
+ gn_gesture_coor[10],gn_gesture_coor[11]);
+ I("gest_left_x= %d, gest_left_y= %d, gest_right_x= %d, gest_right_y= %d\n",gn_gesture_coor[12],gn_gesture_coor[13],
+ gn_gesture_coor[14],gn_gesture_coor[15]);
+#endif
+ }
+}
+
+#endif
+
+#if defined(HX_EN_SEL_BUTTON) || defined(HX_EN_MUT_BUTTON)
+static void himax_ts_button_func(int tp_key_index,struct himax_ts_data *ts)
+{
+ uint16_t x_position = 0, y_position = 0;
+ if ( tp_key_index != 0x00)
+ {
+ I("virtual key index =%x\n",tp_key_index);
+ if ( tp_key_index == 0x01)
+ {
+ vk_press = 1;
+ I("back key pressed\n");
+ if (ts->pdata->virtual_key)
+ {
+ if (ts->button[0].index)
+ {
+ x_position = (ts->button[0].x_range_min + ts->button[0].x_range_max) / 2;
+ y_position = (ts->button[0].y_range_min + ts->button[0].y_range_max) / 2;
+ }
+#ifdef HX_PROTOCOL_A
+ input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR,
+ 100);
+ input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 0);
+
+ input_report_abs(ts->input_dev, ABS_MT_POSITION_X,
+ x_position);
+ input_report_abs(ts->input_dev, ABS_MT_POSITION_Y,
+ y_position);
+ input_mt_sync(ts->input_dev);
+#else
+ input_mt_slot(ts->input_dev, 0);
+ input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER,
+ 1);
+ input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR,
+ 100);
+ input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR,
+ 100);
+ input_report_abs(ts->input_dev, ABS_MT_PRESSURE,
+ 100);
+ input_report_abs(ts->input_dev, ABS_MT_POSITION_X,
+ x_position);
+ input_report_abs(ts->input_dev, ABS_MT_POSITION_Y,
+ y_position);
+#endif
+ }
+ else
+ input_report_key(ts->input_dev, KEY_BACK, 1);
+ }
+ else if ( tp_key_index == 0x02)
+ {
+ vk_press = 1;
+ I("home key pressed\n");
+ if (ts->pdata->virtual_key)
+ {
+ if (ts->button[1].index)
+ {
+ x_position = (ts->button[1].x_range_min + ts->button[1].x_range_max) / 2;
+ y_position = (ts->button[1].y_range_min + ts->button[1].y_range_max) / 2;
+ }
+#ifdef HX_PROTOCOL_A
+ input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 0);
+ input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR,
+ 100);
+
+ input_report_abs(ts->input_dev, ABS_MT_POSITION_X,
+ x_position);
+ input_report_abs(ts->input_dev, ABS_MT_POSITION_Y,
+ y_position);
+ input_mt_sync(ts->input_dev);
+#else
+ input_mt_slot(ts->input_dev, 0);
+ input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER,
+ 1);
+ input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR,
+ 100);
+ input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR,
+ 100);
+ input_report_abs(ts->input_dev, ABS_MT_PRESSURE,
+ 100);
+ input_report_abs(ts->input_dev, ABS_MT_POSITION_X,
+ x_position);
+ input_report_abs(ts->input_dev, ABS_MT_POSITION_Y,
+ y_position);
+#endif
+ }
+ else
+ input_report_key(ts->input_dev, KEY_HOME, 1);
+ }
+ else if ( tp_key_index == 0x04)
+ {
+ vk_press = 1;
+ I("APP_switch key pressed\n");
+ if (ts->pdata->virtual_key)
+ {
+ if (ts->button[2].index)
+ {
+ x_position = (ts->button[2].x_range_min + ts->button[2].x_range_max) / 2;
+ y_position = (ts->button[2].y_range_min + ts->button[2].y_range_max) / 2;
+ }
+#ifdef HX_PROTOCOL_A
+ input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 0);
+
+ input_report_abs(ts->input_dev, ABS_MT_PRESSURE,
+ 100);
+ input_report_abs(ts->input_dev, ABS_MT_POSITION_X,
+ x_position);
+ input_report_abs(ts->input_dev, ABS_MT_POSITION_Y,
+ y_position);
+ input_mt_sync(ts->input_dev);
+#else
+ input_mt_slot(ts->input_dev, 0);
+ input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER,
+ 1);
+ input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR,
+ 100);
+ input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR,
+ 100);
+ input_report_abs(ts->input_dev, ABS_MT_PRESSURE,
+ 100);
+ input_report_abs(ts->input_dev, ABS_MT_POSITION_X,
+ x_position);
+ input_report_abs(ts->input_dev, ABS_MT_POSITION_Y,
+ y_position);
+#endif
+ }
+ else
+ input_report_key(ts->input_dev, KEY_APP_SWITCH, 1);
+ }
+ input_sync(ts->input_dev);
+ }
+ else/*tp_key_index =0x00*/
+ {
+ I("virtual key released\n");
+ vk_press = 0;
+#ifndef HX_PROTOCOL_A
+ input_mt_slot(ts->input_dev, 0);
+ input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0);
+#else
+ input_mt_sync(ts->input_dev);
+#endif
+ input_report_key(ts->input_dev, KEY_BACK, 0);
+ input_report_key(ts->input_dev, KEY_HOME, 0);
+ input_report_key(ts->input_dev, KEY_APP_SWITCH, 0);
+#ifndef HX_PROTOCOL_A
+ input_sync(ts->input_dev);
+#endif
+ }
+}
+
+void himax_report_key(struct himax_ts_data *ts)
+{
+ if(hx_point_num!=0)
+ {
+ //Touch KEY
+ if ((tpd_key_old != 0x00)&&(tpd_key == 0x00))
+ {
+ //temp_x[0] = 0xFFFF;
+ //temp_y[0] = 0xFFFF;
+ //temp_x[1] = 0xFFFF;
+ //temp_y[1] = 0xFFFF;
+ hx_touch_data->finger_on = 0;
+#ifdef HX_PROTOCOL_A
+ input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on);
+#endif
+ himax_ts_button_func(tpd_key,ts);
+ }
+#ifndef HX_PROTOCOL_A
+ input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on);
+#endif
+ input_sync(ts->input_dev);
+ }
+ else
+ {
+ if (tpd_key != 0x00)
+ {
+ hx_touch_data->finger_on = 1;
+#ifdef HX_PROTOCOL_A
+ input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on);
+#endif
+ himax_ts_button_func(tpd_key,ts);
+
+ }
+ else if ((tpd_key_old != 0x00)&&(tpd_key == 0x00))
+ {
+ hx_touch_data->finger_on = 0;
+#ifdef HX_PROTOCOL_A
+ input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on);
+#endif
+ himax_ts_button_func(tpd_key,ts);
+
+ }
+#ifndef HX_PROTOCOL_A
+ input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on);
+#endif
+ input_sync(ts->input_dev);
+ }
+ tpd_key_old = tpd_key;
+ Last_EN_NoiseFilter = EN_NoiseFilter;
+}
+#endif
+
+int himax_report_data_init(void)
+{
+ if(hx_touch_data->hx_coord_buf!=NULL)
+ {
+ kfree(hx_touch_data->hx_coord_buf);
+ }
+#ifdef HX_TP_PROC_DIAG
+ if(hx_touch_data->hx_rawdata_buf!=NULL)
+ {
+ kfree(hx_touch_data->hx_rawdata_buf);
+ }
+#endif
+
+#if defined(HX_SMART_WAKEUP)
+ hx_touch_data->event_size = himax_get_touch_data_size();
+ if(hx_touch_data->hx_event_buf!=NULL)
+ {
+ kfree(hx_touch_data->hx_event_buf);
+ }
+#endif
+
+ hx_touch_data->touch_all_size = himax_get_touch_data_size();
+ hx_touch_data->raw_cnt_max = ic_data->HX_MAX_PT/4;
+ hx_touch_data->raw_cnt_rmd = ic_data->HX_MAX_PT%4;
+
+ if (hx_touch_data->raw_cnt_rmd != 0x00) //more than 4 fingers
+ {
+ hx_touch_data->rawdata_size = cal_data_len(hx_touch_data->raw_cnt_rmd, ic_data->HX_MAX_PT, hx_touch_data->raw_cnt_max);
+ hx_touch_data->touch_info_size = (ic_data->HX_MAX_PT+hx_touch_data->raw_cnt_max+2)*4;
+ }
+ else //less than 4 fingers
+ {
+ hx_touch_data->rawdata_size = cal_data_len(hx_touch_data->raw_cnt_rmd, ic_data->HX_MAX_PT, hx_touch_data->raw_cnt_max);
+ hx_touch_data->touch_info_size = (ic_data->HX_MAX_PT+hx_touch_data->raw_cnt_max+1)*4;
+ }
+ if((ic_data->HX_TX_NUM * ic_data->HX_RX_NUM + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM) % hx_touch_data->rawdata_size == 0)
+ hx_touch_data->rawdata_frame_size = (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM) / hx_touch_data->rawdata_size;
+ else
+ hx_touch_data->rawdata_frame_size = (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM) / hx_touch_data->rawdata_size + 1;
+ I("%s: rawdata_frame_size = %d ",__func__,hx_touch_data->rawdata_frame_size);
+ I("%s: ic_data->HX_MAX_PT:%d,hx_raw_cnt_max:%d,hx_raw_cnt_rmd:%d,g_hx_rawdata_size:%d,hx_touch_data->touch_info_size:%d\n",__func__,ic_data->HX_MAX_PT,hx_touch_data->raw_cnt_max,hx_touch_data->raw_cnt_rmd,hx_touch_data->rawdata_size,hx_touch_data->touch_info_size);
+
+ hx_touch_data->hx_coord_buf = kzalloc(sizeof(uint8_t)*(hx_touch_data->touch_info_size),GFP_KERNEL);
+ if(hx_touch_data->hx_coord_buf == NULL)
+ goto mem_alloc_fail;
+#ifdef HX_TP_PROC_DIAG
+ hx_touch_data->hx_rawdata_buf = kzalloc(sizeof(uint8_t)*(hx_touch_data->touch_all_size - hx_touch_data->touch_info_size),GFP_KERNEL);
+ if(hx_touch_data->hx_rawdata_buf == NULL)
+ goto mem_alloc_fail;
+#endif
+
+#if defined(HX_SMART_WAKEUP)
+ hx_touch_data->hx_event_buf = kzalloc(sizeof(uint8_t)*(hx_touch_data->event_size),GFP_KERNEL);
+ if(hx_touch_data->hx_event_buf == NULL)
+ goto mem_alloc_fail;
+#endif
+
+ return NO_ERR;
+
+mem_alloc_fail:
+ kfree(hx_touch_data->hx_coord_buf);
+#if defined(HX_TP_PROC_DIAG)
+ kfree(hx_touch_data->hx_rawdata_buf);
+#endif
+#if defined(HX_SMART_WAKEUP)
+ kfree(hx_touch_data->hx_event_buf);
+#endif
+
+ I("%s: Memory allocate fail!\n",__func__);
+ return MEM_ALLOC_FAIL;
+
+}
+
+
+#if defined(HX_USB_DETECT_GLOBAL)
+void himax_read_file_func(char *pFilePath, u8 *pBuf, u16 nLength)
+{
+ struct file *pFile = NULL;
+ mm_segment_t old_fs;
+ ssize_t nReadBytes = 0;
+
+ old_fs = get_fs();
+ set_fs(get_ds());
+
+ pFile = filp_open(pFilePath, O_RDONLY, 0);
+
+ if (IS_ERR(pFile)) {
+ printk ( "[Tracy]Open file failed: %s\n", pFilePath);
+ return;
+ }
+
+ pFile->f_op->llseek(pFile, 0, SEEK_SET);
+ nReadBytes = pFile->f_op->read(pFile, pBuf, nLength, &pFile->f_pos);
+
+ set_fs(old_fs);
+
+ filp_close(pFile, NULL);
+
+}
+
+void himax_cable_detect_func(bool force_renew)
+{
+ struct himax_ts_data *ts;
+ u32 connect_status = 0;
+ u8 szChargerStatus[20] = {0};
+
+ ts = private_ts;
+
+ if (ts->suspended==false)
+ {
+ himax_read_file_func(POWER_SUPPLY_BATTERY_STATUS_PATCH, szChargerStatus, 20);
+ if (strstr(szChargerStatus, "Charging") != NULL || strstr(szChargerStatus, "Full") != NULL || strstr(szChargerStatus, "Fully charged") != NULL) // Charging
+ {
+ connect_status=1;
+ }
+ else
+ {
+ connect_status=0;
+ }
+ }
+
+ if (ts->cable_config)
+ {
+ if (((!!connect_status) != ts->usb_connected) || force_renew)
+ {
+ if (!!connect_status)
+ {
+ ts->cable_config[1] = 0x01;
+ ts->usb_connected = 0x01;
+ }
+ else
+ {
+ ts->cable_config[1] = 0x00;
+ ts->usb_connected = 0x00;
+ }
+ himax_usb_detect_set(ts->client,ts->cable_config);
+ printk("%s: Cable status change: 0x%2.2X\n", __func__, ts->usb_connected);
+ }
+ }
+}
+#endif
+
+
+void himax_report_points(struct himax_ts_data *ts)
+{
+ int x = 0;
+ int y = 0;
+ int w = 0;
+ int base = 0;
+ int32_t loop_i = 0;
+ uint16_t old_finger = 0;
+
+ //I("%s:Entering\n",__func__);
+
+ /* finger on/press */
+ if (hx_point_num != 0 )
+ {
+ old_finger = ts->pre_finger_mask;
+ ts->pre_finger_mask = 0;
+ hx_touch_data->finger_num = hx_touch_data->hx_coord_buf[ts->coordInfoSize - 4] & 0x0F;
+ hx_touch_data->finger_on = 1;
+ AA_press = 1;
+ for (loop_i = 0; loop_i < ts->nFinger_support; loop_i++)
+ {
+ base = loop_i * 4;
+ x = hx_touch_data->hx_coord_buf[base] << 8 | hx_touch_data->hx_coord_buf[base + 1];
+ y = (hx_touch_data->hx_coord_buf[base + 2] << 8 | hx_touch_data->hx_coord_buf[base + 3]);
+ w = hx_touch_data->hx_coord_buf[(ts->nFinger_support * 4) + loop_i];
+ //x = ic_data->HX_X_RES - x;
+ //y = ic_data->HX_Y_RES - y;
+ //printk("allenyu:abs_x_max = %d \n",ts->pdata->abs_x_max);
+ //printk("allenyu:abs_y_max = %d \n",ts->pdata->abs_y_max);
+ if(x >= 0 && x <= ts->pdata->abs_x_max && y >= 0 && y <= ts->pdata->abs_y_max)
+ {
+ //printk("allenyu_010\n");
+ hx_touch_data->finger_num--;
+ if ((ts->debug_log_level & BIT(3)) > 0)
+ {
+ himax_log_touch_event_detail(ts,x,y,w,loop_i,EN_NoiseFilter,HX_FINGER_ON,old_finger);
+ }
+#ifndef HX_PROTOCOL_A
+
+ input_mt_slot(ts->input_dev, loop_i);
+#endif
+ input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on);
+ input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, w);
+ input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, loop_i);
+#ifndef HX_PROTOCOL_A
+ input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w);
+ input_report_abs(ts->input_dev, ABS_MT_PRESSURE, w);
+#endif
+ input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x);
+ input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y);
+
+#ifndef HX_PROTOCOL_A
+ ts->last_slot = loop_i;
+ input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 1);
+#else
+ input_mt_sync(ts->input_dev);
+#endif
+
+ if (!ts->first_pressed)
+ {
+ ts->first_pressed = 1;
+ I("S1@%d, %d\n", x, y);
+ }
+
+ ts->pre_finger_data[loop_i][0] = x;
+ ts->pre_finger_data[loop_i][1] = y;
+ if (ts->debug_log_level & BIT(1))
+ himax_log_touch_event(x, y, w,loop_i,EN_NoiseFilter,HX_FINGER_ON);
+
+ ts->pre_finger_mask = ts->pre_finger_mask + (1 << loop_i);
+ }
+ /* report coordinates */
+ else
+ {
+ //printk("allenyu_020\n");
+#ifndef HX_PROTOCOL_A
+ input_mt_slot(ts->input_dev, loop_i);
+ input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0);
+#endif
+
+ if (loop_i == 0 && ts->first_pressed == 1)
+ {
+ ts->first_pressed = 2;
+ I("E1@%d, %d\n",
+ ts->pre_finger_data[0][0], ts->pre_finger_data[0][1]);
+ }
+ if ((ts->debug_log_level & BIT(3)) > 0)
+ {
+ himax_log_touch_event_detail(ts,x,y,w,loop_i,Last_EN_NoiseFilter,HX_FINGER_LEAVE,old_finger);
+ }
+ }
+ }
+#ifndef HX_PROTOCOL_A
+ input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on);
+#endif
+ input_sync(ts->input_dev);
+ }
+
+ /* finger leave/release */
+ else
+ {
+#if defined(HX_PALM_REPORT)
+ if(himax_palm_detect(hx_touch_data->hx_coord_buf) == NO_ERR)
+ {
+ I(" %s HX_PALM_REPORT KEY power event press\n",__func__);
+ input_report_key(ts->input_dev, KEY_POWER, 1);
+ input_sync(ts->input_dev);
+ msleep(100);
+ I(" %s HX_PALM_REPORT KEY power event release\n",__func__);
+ input_report_key(ts->input_dev, KEY_POWER, 0);
+ input_sync(ts->input_dev);
+ return;
+ }
+#endif
+ hx_touch_data->finger_on = 0;
+ AA_press = 0;
+#ifdef HX_PROTOCOL_A
+ input_mt_sync(ts->input_dev);
+#endif
+
+ for (loop_i = 0; loop_i < ts->nFinger_support; loop_i++)
+ {
+ if (((ts->pre_finger_mask >> loop_i) & 1) == 1)
+ {
+#ifndef HX_PROTOCOL_A
+ input_mt_slot(ts->input_dev, loop_i);
+ input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0);
+#endif
+ }
+ if(ts->pre_finger_mask > 0 && (ts->debug_log_level & BIT(3)) > 0)
+ {
+ if (((ts->pre_finger_mask >> loop_i) & 1) == 1)
+ {
+ if (ts->useScreenRes)
+ {
+ I("status:%X, Screen:F:%02d Up, X:%d, Y:%d, N:%d\n", 0, loop_i+1, ts->pre_finger_data[loop_i][0] * ts->widthFactor >> SHIFTBITS,
+ ts->pre_finger_data[loop_i][1] * ts->heightFactor >> SHIFTBITS, Last_EN_NoiseFilter);
+ }
+ else
+ {
+ I("status:%X, Raw:F:%02d Up, X:%d, Y:%d, N:%d\n",0, loop_i+1, ts->pre_finger_data[loop_i][0],ts->pre_finger_data[loop_i][1], Last_EN_NoiseFilter);
+ }
+ }
+ }
+ }
+ if (ts->pre_finger_mask > 0)
+ {
+ /*for (loop_i = 0; loop_i < ts->nFinger_support && (ts->debug_log_level & BIT(3)) > 0; loop_i++)
+ {
+ if (((ts->pre_finger_mask >> loop_i) & 1) == 1)
+ {
+ if (ts->useScreenRes)
+ {
+ I("status:%X, Screen:F:%02d Up, X:%d, Y:%d, N:%d\n", 0, loop_i+1, ts->pre_finger_data[loop_i][0] * ts->widthFactor >> SHIFTBITS,
+ ts->pre_finger_data[loop_i][1] * ts->heightFactor >> SHIFTBITS, Last_EN_NoiseFilter);
+ }
+ else
+ {
+ I("status:%X, Raw:F:%02d Up, X:%d, Y:%d, N:%d\n",0, loop_i+1, ts->pre_finger_data[loop_i][0],ts->pre_finger_data[loop_i][1], Last_EN_NoiseFilter);
+ }
+ }
+ }*/
+ ts->pre_finger_mask = 0;
+ }
+
+ if (ts->first_pressed == 1)
+ {
+ ts->first_pressed = 2;
+ I("E1@%d, %d\n",ts->pre_finger_data[0][0], ts->pre_finger_data[0][1]);
+ }
+
+ if (ts->debug_log_level & BIT(1))
+ himax_log_touch_event(x, y, w,loop_i,EN_NoiseFilter,HX_FINGER_LEAVE);
+
+ input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on);
+ input_sync(ts->input_dev);
+ }
+ Last_EN_NoiseFilter = EN_NoiseFilter;
+
+ //I("%s:End\n",__func__);
+}
+
+int himax_touch_get(struct himax_ts_data *ts,uint8_t *buf,int ts_status)
+{
+ int ret = 0;
+
+ switch(ts_status)
+ {
+ /*normal*/
+ case 1:
+#ifdef HX_TP_PROC_DIAG
+ hx_touch_data->diag_cmd = getDiagCommand();
+
+ if((hx_touch_data->diag_cmd)
+ || (HX_HW_RESET_ACTIVATE)
+#ifdef HX_ESD_RECOVERY
+ || (HX_ESD_RESET_ACTIVATE)
+#endif
+ )
+ {
+ ret = himax_read_event_stack(ts->client, buf, 128);
+ }
+ else
+ {
+ ret = himax_read_event_stack(ts->client, buf, hx_touch_data->touch_info_size);
+ }
+
+ if (!ret)
+#else
+ if(!himax_read_event_stack(ts->client, buf, hx_touch_data->touch_info_size))
+#endif
+ {
+ E("%s: can't read data from chip!\n", __func__);
+ goto err_workqueue_out;
+ }
+ break;
+#if defined(HX_SMART_WAKEUP)
+ /*SMWP*/
+ case 2:
+ himax_burst_enable(ts->client, 0);
+ if(!himax_read_event_stack(ts->client,buf,hx_touch_data->event_size))
+ {
+ E("%s: can't read data from chip!\n", __func__);
+ goto err_workqueue_out;
+ }
+ break;
+#endif
+ default:
+ break;
+ }
+ return NO_ERR;
+
+err_workqueue_out:
+ return I2C_FAIL;
+
+}
+
+int himax_checksum_cal(struct himax_ts_data *ts,uint8_t *buf,int ts_status)
+{
+#if defined(HX_ESD_RECOVERY)
+ int hx_EB_event = 0;
+ int hx_EC_event = 0;
+ int hx_ED_event = 0;
+ int hx_esd_event = 0;
+ int hx_zero_event = 0;
+ int shaking_ret = 0;
+#endif
+ uint16_t check_sum_cal = 0;
+ int32_t loop_i = 0;
+ int length = 0;
+
+ /* Normal */
+ if(ts_status == HX_REPORT_COORD)
+ length = hx_touch_data->touch_info_size;
+#if defined(HX_SMART_WAKEUP)
+ /* SMWP */
+ else if(ts_status == HX_REPORT_SMWP_EVENT)
+ length = (GEST_PTLG_ID_LEN+GEST_PTLG_HDR_LEN);
+#endif
+ else
+ {
+ I("%s, Neither Normal Nor SMWP error!\n",__func__);
+ }
+ //I("Now status=%d,length=%d\n",ts_status,length);
+ for (loop_i = 0; loop_i < length; loop_i++)
+ {
+ check_sum_cal+=buf[loop_i];
+
+ /*if (ts->debug_log_level & BIT(0))
+ {
+ I("P %d = 0x%2.2X ", loop_i, hx_touch_data->hx_coord_buf[loop_i]);
+ if (loop_i % 8 == 7)
+ I("\n");
+ }*/
+
+#ifdef HX_ESD_RECOVERY
+ if(ts_status == HX_REPORT_COORD)
+ {
+ /* case 1 ESD recovery flow */
+ if(buf[loop_i] == 0xEB)
+ hx_EB_event++;
+ else if(buf[loop_i] == 0xEC)
+ hx_EC_event++;
+ else if(buf[loop_i] == 0xED)
+ hx_ED_event++;
+ /* case 2 ESD recovery flow-Disable */
+ else if(buf[loop_i] == 0x00)
+ hx_zero_event++;
+ else
+ {
+ hx_EB_event = 0;
+ hx_EC_event = 0;
+ hx_ED_event = 0;
+ hx_zero_event = 0;
+ g_zero_event_count = 0;
+ }
+
+ if(hx_EB_event == length)
+ {
+ hx_esd_event = length;
+ hx_EB_event_flag ++;
+ I("[HIMAX TP MSG]: ESD event checked - ALL 0xEB.\n");
+ }
+ else if(hx_EC_event == length)
+ {
+ hx_esd_event = length;
+ hx_EC_event_flag ++;
+ I("[HIMAX TP MSG]: ESD event checked - ALL 0xEC.\n");
+ }
+ else if(hx_ED_event == length)
+ {
+ hx_esd_event = length;
+ hx_ED_event_flag ++;
+ I("[HIMAX TP MSG]: ESD event checked - ALL 0xED.\n");
+ }
+ else
+ {
+ hx_esd_event = 0;
+ }
+ }
+#endif
+ }
+
+ if(ts_status == HX_REPORT_COORD)
+ {
+#ifdef HX_ESD_RECOVERY
+ if ((hx_esd_event == length || hx_zero_event == length)
+ && (HX_HW_RESET_ACTIVATE == 0)
+ && (HX_ESD_RESET_ACTIVATE == 0)
+#if defined(HX_TP_PROC_DIAG)
+ && (hx_touch_data->diag_cmd == 0)
+#endif
+#if defined(HX_TP_PROC_SELF_TEST) || defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST)
+ && (g_self_test_entered == 0)
+#endif
+ )
+ {
+ shaking_ret = himax_ic_esd_recovery(hx_esd_event,hx_zero_event,length);
+ if(shaking_ret == CHECKSUM_FAIL)
+ {
+ himax_esd_hw_reset();
+ goto checksum_fail;
+ }
+ else if(shaking_ret == ERR_WORK_OUT)
+ goto err_workqueue_out;
+ else
+ {
+ //I("I2C running. Nothing to be done!\n");
+ goto workqueue_out;
+ }
+ }
+ else if (HX_ESD_RESET_ACTIVATE)
+ {
+#if defined(HX_SMART_WAKEUP)||defined(HX_HIGH_SENSE)||defined(HX_USB_DETECT_GLOBAL)
+#ifdef HX_RESUME_SEND_CMD
+#if 0
+ himax_resend_cmd_func(ts->suspended);
+#endif
+ himax_rst_cmd_recovery_func(ts->suspended);
+#endif
+#endif
+ /* drop 1st interrupts after chip reset */
+ HX_ESD_RESET_ACTIVATE = 0;
+ I("[HX_ESD_RESET_ACTIVATE]:%s: Back from reset, ready to serve.\n", __func__);
+ goto checksum_fail;
+ }
+
+ else if (HX_HW_RESET_ACTIVATE)
+#else
+ if (HX_HW_RESET_ACTIVATE)
+#endif
+ {
+#if defined(HX_SMART_WAKEUP)||defined(HX_HIGH_SENSE)||defined(HX_USB_DETECT_GLOBAL)
+#ifdef HX_RESUME_SEND_CMD
+#if 0
+ himax_resend_cmd_func(ts->suspended);
+#endif
+ himax_rst_cmd_recovery_func(ts->suspended);
+#endif
+#endif
+ /* drop 1st interrupts after chip reset */
+ HX_HW_RESET_ACTIVATE = 0;
+ I("[HX_HW_RESET_ACTIVATE]:%s: Back from reset, ready to serve.\n", __func__);
+ goto ready_to_serve;
+ }
+ }
+
+ if ((check_sum_cal % 0x100 != 0) )
+ {
+ I("[HIMAX TP MSG] checksum fail : check_sum_cal: 0x%02X\n", check_sum_cal);
+ goto checksum_fail;
+ }
+
+ /* I("%s:End\n",__func__); */
+ return NO_ERR;
+
+ready_to_serve:
+ return READY_TO_SERVE;
+checksum_fail:
+ return CHECKSUM_FAIL;
+#ifdef HX_ESD_RECOVERY
+err_workqueue_out:
+ return ERR_WORK_OUT;
+workqueue_out:
+ return WORK_OUT;
+#endif
+}
+
+int himax_ts_work_status(struct himax_ts_data *ts)
+{
+ /* 1: normal, 2:SMWP */
+ int result = HX_REPORT_COORD;
+ uint8_t diag_cmd = 0;
+
+#ifdef HX_TP_PROC_DIAG
+ diag_cmd = getDiagCommand();
+#endif
+
+#ifdef HX_SMART_WAKEUP
+ if (atomic_read(&ts->suspend_mode)&&(!FAKE_POWER_KEY_SEND)&&(ts->SMWP_enable)&&(!diag_cmd))
+ {
+ result = HX_REPORT_SMWP_EVENT;
+ }
+#endif
+ /* I("Now Status is %d\n",result); */
+ return result;
+}
+
+void himax_assign_touch_data(uint8_t *buf,int ts_status)
+{
+ uint8_t hx_state_info_pos = hx_touch_data->touch_info_size - 3;
+
+ if(ts_status == HX_REPORT_COORD)
+ {
+ memcpy(hx_touch_data->hx_coord_buf,&buf[0],hx_touch_data->touch_info_size);
+ if(buf[hx_state_info_pos] != 0xFF && buf[hx_state_info_pos + 1] != 0xFF )
+ memcpy(hx_touch_data->hx_state_info,&buf[hx_state_info_pos],2);
+ else
+ memset(hx_touch_data->hx_state_info, 0x00, sizeof(hx_touch_data->hx_state_info));
+ }
+#if defined(HX_SMART_WAKEUP)
+ else
+ memcpy(hx_touch_data->hx_event_buf,buf,hx_touch_data->event_size);
+#endif
+
+#ifdef HX_TP_PROC_DIAG
+ if((hx_touch_data->diag_cmd)
+ || (HX_HW_RESET_ACTIVATE)
+#ifdef HX_ESD_RECOVERY
+ || (HX_ESD_RESET_ACTIVATE)
+#endif
+ )
+ {
+ memcpy(hx_touch_data->hx_rawdata_buf,&buf[hx_touch_data->touch_info_size],hx_touch_data->touch_all_size - hx_touch_data->touch_info_size);
+ }
+#endif
+
+}
+
+void himax_coord_report(struct himax_ts_data *ts)
+{
+
+#if defined(HX_TP_PROC_DIAG)
+ //touch monitor raw data fetch
+ if(himax_set_diag_cmd(ic_data,hx_touch_data))
+ I("%s: coordinate dump fail and bypass with checksum err\n",__func__);
+#endif
+ EN_NoiseFilter = (hx_touch_data->hx_coord_buf[HX_TOUCH_INFO_POINT_CNT+2]>>3);
+ //I("EN_NoiseFilter=%d\n",EN_NoiseFilter);
+ EN_NoiseFilter = EN_NoiseFilter & 0x01;
+ //I("EN_NoiseFilter2=%d\n",EN_NoiseFilter);
+
+#if defined(HX_EN_SEL_BUTTON) || defined(HX_EN_MUT_BUTTON)
+ tpd_key = (hx_touch_data->hx_coord_buf[HX_TOUCH_INFO_POINT_CNT+2]>>4);
+ /* All (VK+AA)leave */
+ if (tpd_key == 0x0F)
+ {
+ tpd_key = 0x00;
+ }
+ //I("[DEBUG] tpd_key: %x\r\n", tpd_key);
+#else
+ tpd_key = 0x00;
+#endif
+
+ p_point_num = hx_point_num;
+
+ if (hx_touch_data->hx_coord_buf[HX_TOUCH_INFO_POINT_CNT] == 0xff)
+ hx_point_num = 0;
+ else
+ hx_point_num= hx_touch_data->hx_coord_buf[HX_TOUCH_INFO_POINT_CNT] & 0x0f;
+
+ /* Touch Point information */
+ if(!tpd_key && !tpd_key_old)
+ himax_report_points(ts);
+#if defined(HX_EN_SEL_BUTTON) || defined(HX_EN_MUT_BUTTON)
+ else
+ himax_report_key(ts);
+#endif
+ /* I("%s:END\n",__func__); */
+
+}
+
+void himax_ts_work(struct himax_ts_data *ts)
+{
+ uint8_t hw_reset_check[2];
+ uint8_t buf[128];
+ int check_sum_cal = 0;
+ //int loop_i = 0;
+ int ts_status = 0;
+#ifdef HX_CHIP_STATUS_MONITOR
+ int j=0;
+#endif
+
+#if defined(HX_USB_DETECT_GLOBAL)
+ himax_cable_detect_func(false);
+#endif
+
+#if defined(HX_CHIP_STATUS_MONITOR)
+ g_chip_monitor_data->HX_CHIP_POLLING_COUNT=0;
+ if(g_chip_monitor_data->HX_ON_HAND_SHAKING)//chip on hand shaking,wait hand shaking
+ {
+ for(j=0; j<100; j++)
+ {
+ if(g_chip_monitor_data->HX_ON_HAND_SHAKING==0)//chip on hand shaking end
+ {
+ I("%s:HX_ON_HAND_SHAKING OK check %d times\n",__func__,j);
+ break;
+ }
+ else
+ msleep(1);
+ }
+ if(j==100)
+ {
+ E("%s:HX_ON_HAND_SHAKING timeout reject interrupt\n",__func__);
+ return;
+ }
+ }
+#endif
+
+ ts_status = himax_ts_work_status(ts);
+ if(ts_status > HX_REPORT_SMWP_EVENT || ts_status < HX_REPORT_COORD)
+ goto neither_normal_nor_smwp;
+
+ memset(buf, 0x00, sizeof(buf));
+ memset(hw_reset_check, 0x00, sizeof(hw_reset_check));
+
+ //I("New Method for ts_work\n");
+
+ if(himax_touch_get(ts,buf,ts_status))
+ goto err_workqueue_out;
+
+ if (ts->debug_log_level & BIT(0))
+ {
+
+ himax_log_touch_data(buf,hx_touch_data);
+
+ }
+
+ check_sum_cal = himax_checksum_cal(ts,buf,ts_status);
+ if (check_sum_cal == CHECKSUM_FAIL)
+ goto checksum_fail;
+ else if (check_sum_cal == READY_TO_SERVE)
+ goto ready_to_serve;
+ else if (check_sum_cal == ERR_WORK_OUT)
+ goto err_workqueue_out;
+ else if (check_sum_cal == WORK_OUT)
+ goto workqueue_out;
+ /* checksum calculate pass and assign data to global touch data*/
+ else
+ himax_assign_touch_data(buf,ts_status);
+
+ if(ts_status == HX_REPORT_COORD)
+ himax_coord_report(ts);
+#if defined(HX_SMART_WAKEUP)
+ else
+ {
+ //wake_lock_timeout(&ts->ts_SMWP_wake_lock, TS_WAKE_LOCK_TIMEOUT);
+ __pm_wakeup_event(&ts->ts_SMWP_wake_lock, TS_WAKE_LOCK_TIMEOUT);
+ msleep(200);
+ himax_wake_check_func();
+ }
+#endif
+
+checksum_fail:
+workqueue_out:
+ready_to_serve:
+neither_normal_nor_smwp:
+ return;
+
+err_workqueue_out:
+ I("%s: Now reset the Touch chip.\n", __func__);
+
+#ifdef HX_RST_PIN_FUNC
+ himax_ic_reset(false,true);
+#endif
+
+ goto workqueue_out;
+}
+enum hrtimer_restart himax_ts_timer_func(struct hrtimer *timer)
+{
+ struct himax_ts_data *ts;
+
+ ts = container_of(timer, struct himax_ts_data, timer);
+ queue_work(ts->himax_wq, &ts->work);
+ hrtimer_start(&ts->timer, ktime_set(0, 12500000), HRTIMER_MODE_REL);
+ return HRTIMER_NORESTART;
+}
+
+#if defined( HX_USB_DETECT_CALLBACK)
+static void himax_cable_tp_status_handler_func(int connect_status)
+{
+ struct himax_ts_data *ts;
+ I("Touch: cable change to %d\n", connect_status);
+ ts = private_ts;
+ if (ts->cable_config)
+ {
+ if (!atomic_read(&ts->suspend_mode))
+ {
+ if ((!!connect_status) != ts->usb_connected)
+ {
+ if (!!connect_status)
+ {
+ ts->cable_config[1] = 0x01;
+ ts->usb_connected = 0x01;
+ }
+ else
+ {
+ ts->cable_config[1] = 0x00;
+ ts->usb_connected = 0x00;
+ }
+
+ i2c_himax_master_write(ts->client, ts->cable_config,
+ sizeof(ts->cable_config), DEFAULT_RETRY_CNT);
+
+ I("%s: Cable status change: 0x%2.2X\n", __func__, ts->cable_config[1]);
+ }
+ else
+ I("%s: Cable status is the same as previous one, ignore.\n", __func__);
+ }
+ else
+ {
+ if (connect_status)
+ ts->usb_connected = 0x01;
+ else
+ ts->usb_connected = 0x00;
+ I("%s: Cable status remembered: 0x%2.2X\n", __func__, ts->usb_connected);
+ }
+ }
+}
+
+static struct t_cable_status_notifier himax_cable_status_handler =
+{
+ .name = "usb_tp_connected",
+ .func = himax_cable_tp_status_handler_func,
+};
+
+#endif
+
+#ifdef HX_AUTO_UPDATE_FW
+static void himax_update_register(struct work_struct *work)
+{
+ I(" %s in", __func__);
+#if defined(HX_CHIP_STATUS_MONITOR)
+ I("Cancel Chip monitor during auto-updating!\n");
+ g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0;
+ g_chip_monitor_data->HX_CHIP_MONITOR_EN = 0;
+ cancel_delayed_work_sync(&private_ts->himax_chip_monitor);
+#endif
+ if(i_update_FW() == false)
+ I("NOT Have new FW=NOT UPDATE=\n");
+ else
+ I("Have new FW=UPDATE=\n");
+#ifdef HX_CHIP_STATUS_MONITOR
+ I("Auto-updating over, now chip monitor working!\n");
+ g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0;
+ g_chip_monitor_data->HX_CHIP_MONITOR_EN = 1;
+ queue_delayed_work(private_ts->himax_chip_monitor_wq, &private_ts->himax_chip_monitor, g_chip_monitor_data->HX_POLLING_TIMER*HZ);
+#endif
+}
+#endif
+
+#ifdef CONFIG_FB
+static void himax_fb_register(struct work_struct *work)
+{
+ int ret = 0;
+ struct himax_ts_data *ts = container_of(work, struct himax_ts_data,
+ work_att.work);
+ I(" %s in\n", __func__);
+
+ ts->fb_notif.notifier_call = fb_notifier_callback;
+//ParisKuong modified Mutex initialization +++
+ mutex_init(&ts->ops_lock);
+//ParisKuong modified Mutex initialization ---
+ ret = fb_register_client(&ts->fb_notif);
+ if (ret)
+ E(" Unable to register fb_notifier: %d\n", ret);
+}
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST)
+static void himax_ito_test_work(struct work_struct *work)
+{
+ I(" %s in\n", __func__);
+ himax_ito_test();
+}
+#endif
+
+#ifdef HX_TP_PROC_FLASH_DUMP
+static void himax_ts_flash_work_func(struct work_struct *work)
+{
+ himax_ts_flash_func();
+}
+#endif
+#ifdef HX_TP_PROC_GUEST_INFO
+static void himax_ts_guest_info_work_func(struct work_struct *work)
+{
+
+ himax_read_project_id();
+
+}
+#endif
+#ifdef HX_TP_PROC_DIAG
+static void himax_ts_diag_work_func(struct work_struct *work)
+{
+ himax_ts_diag_func();
+}
+#endif
+
+static void himax_release_all_finger(void)
+{
+ struct input_dev *input_dev = private_ts->input_dev;
+ u32 finger_count = 0;
+
+
+ I("%s: enter \n", __func__);
+ mutex_lock(&private_ts->report_mutex);
+ for (finger_count = 0; finger_count < private_ts->nFinger_support; finger_count++) {
+ input_mt_slot(input_dev, finger_count);
+ input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 0);
+ }
+ input_report_key(input_dev, BTN_TOUCH, 0);
+ input_sync(input_dev);
+ mutex_unlock(&private_ts->report_mutex);
+ I("%s: exit \n", __func__);
+}
+
+int himax_chip_common_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ int ret = 0, err = 0;
+ bool auto_update_flag = false;
+ struct himax_ts_data *ts;
+ struct himax_i2c_platform_data *pdata;
+
+ printk("himax probe enter \n");
+
+ //Check I2C functionality
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+ {
+ E("%s: i2c check functionality error\n", __func__);
+ err = -ENODEV;
+ goto err_check_functionality_failed;
+ }
+
+ ts = kzalloc(sizeof(struct himax_ts_data), GFP_KERNEL);
+ if (ts == NULL)
+ {
+ E("%s: allocate himax_ts_data failed\n", __func__);
+ err = -ENOMEM;
+ goto err_alloc_data_failed;
+ }
+
+ i2c_set_clientdata(client, ts);
+ ts->client = client;
+ ts->dev = &client->dev;
+ mutex_init(&ts->rw_lock);
+
+ pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+ if (pdata == NULL) /*Allocate Platform data space*/
+ {
+ err = -ENOMEM;
+ goto err_dt_platform_data_fail;
+ }
+
+ ic_data = kzalloc(sizeof(*ic_data), GFP_KERNEL);
+ if (ic_data == NULL) /*Allocate IC data space*/
+ {
+ err = -ENOMEM;
+ goto err_dt_ic_data_fail;
+ }
+
+ /* allocate report data */
+ hx_touch_data = kzalloc(sizeof(struct himax_report_data),GFP_KERNEL);
+ if(hx_touch_data == NULL)
+ {
+ err = -ENOMEM;
+ goto err_alloc_data_failed;
+ }
+
+ if (himax_parse_dt(ts, pdata) < 0)
+ {
+ I(" pdata is NULL for DT\n");
+ goto err_alloc_dt_pdata_failed;
+ }
+
+#ifdef HX_RST_PIN_FUNC
+ ts->rst_gpio = pdata->gpio_reset;
+#endif
+
+ himax_gpio_power_config(ts->client, pdata);
+
+#ifndef CONFIG_OF
+ if (pdata->power)
+ {
+ ret = pdata->power(1);
+ if (ret < 0)
+ {
+ E("%s: power on failed\n", __func__);
+ goto err_power_failed;
+ }
+ }
+#endif
+ private_ts = ts;
+
+ if (himax_ic_package_check(ts->client) == false)
+ {
+ E("Himax chip doesn NOT EXIST");
+ goto err_ic_package_failed;
+ }
+
+ if (pdata->virtual_key)
+ ts->button = pdata->virtual_key;
+#ifdef HX_TP_PROC_FLASH_DUMP
+ ts->flash_wq = create_singlethread_workqueue("himax_flash_wq");
+ if (!ts->flash_wq)
+ {
+ E("%s: create flash workqueue failed\n", __func__);
+ err = -ENOMEM;
+ goto err_create_wq_failed;
+ }
+
+ INIT_WORK(&ts->flash_work, himax_ts_flash_work_func);
+
+ setSysOperation(0);
+ setFlashBuffer();
+#endif
+#ifdef HX_TP_PROC_GUEST_INFO
+ ts->guest_info_wq = create_singlethread_workqueue("himax_guest_info_wq");
+ if (!ts->guest_info_wq)
+ {
+ E("%s: create guest info workqueue failed\n", __func__);
+ err = -ENOMEM;
+ goto err_create_guest_info_wq_failed;
+ }
+ INIT_WORK(&ts->guest_info_work, himax_ts_guest_info_work_func);
+#endif
+#ifdef HX_TP_PROC_DIAG
+ ts->himax_diag_wq = create_singlethread_workqueue("himax_diag");
+ if (!ts->himax_diag_wq)
+ {
+ E("%s: create diag workqueue failed\n", __func__);
+ err = -ENOMEM;
+ goto err_create_wq_failed;
+ }
+ INIT_DELAYED_WORK(&ts->himax_diag_delay_wrok, himax_ts_diag_work_func);
+#endif
+
+ himax_read_FW_ver(client);
+ auto_update_flag = !himax_calculateChecksum(client, false);
+#ifdef HX_AUTO_UPDATE_FW
+#if 0
+ auto_update_flag |= (( ic_data->vendor_fw_ver < g_i_FW_VER ) || ( ic_data->vendor_config_ver < g_i_CFG_VER ));
+ /* Not sure to do */
+ auto_update_flag |= ((ic_data->vendor_cid_maj_ver != g_i_CID_MAJ) || (ic_data->vendor_cid_min_ver < g_i_CID_MIN));
+ auto_update_flag |= (( ic_data->vendor_touch_cfg_ver < ((g_i_CFG_VER >> 8)&0xff) ) || ( ic_data->vendor_display_cfg_ver < ((g_i_CFG_VER)&0xff) ));
+#endif
+
+/*wrong FW in IC cases need to force FW upgrade*/
+ if (IC_TYPE == HX_83112A_SERIES_PWON)
+ {
+ if (ic_data->vendor_hx_ic_id == 0x51)
+ {
+ if (( ic_data->vendor_touch_cfg_ver < ((g_i_CFG_VER >> 8)&0xff) ) || ( ic_data->vendor_display_cfg_ver < ((g_i_CFG_VER)&0xff) ))
+ {
+ auto_update_flag |= true;
+ }
+ else
+ {
+ auto_update_flag |= false;
+ }
+ }
+ else
+ {
+ auto_update_flag |= true;
+ }
+ }
+ else if (IC_TYPE == HX_83112B_SERIES_PWON)
+ {
+ if (ic_data->vendor_hx_ic_id == 0x52)
+ {
+ if (( ic_data->vendor_touch_cfg_ver < ((g_i_CFG_VER >> 8)&0xff) ) || ( ic_data->vendor_display_cfg_ver < ((g_i_CFG_VER)&0xff) ))
+ {
+ auto_update_flag |= true;
+ }
+ else
+ {
+ auto_update_flag |= false;
+ }
+ }
+ else
+ {
+ auto_update_flag |= true;
+ }
+ }
+ if (auto_update_flag)
+ {
+ ts->himax_update_wq = create_singlethread_workqueue("HMX_update_reuqest");
+ if (!ts->himax_update_wq)
+ {
+ E(" allocate syn_update_wq failed\n");
+ err = -ENOMEM;
+ goto err_update_wq_failed;
+ }
+ INIT_DELAYED_WORK(&ts->work_update, himax_update_register);
+ queue_delayed_work(ts->himax_update_wq, &ts->work_update, msecs_to_jiffies(2000));
+ }
+#endif
+
+#ifdef HX_ZERO_FLASH
+ ts->himax_0f_update_wq = create_singlethread_workqueue("HMX_0f_update_reuqest");
+ INIT_DELAYED_WORK(&ts->work_0f_update, himax_0f_operation);
+ queue_delayed_work(ts->himax_0f_update_wq, &ts->work_0f_update, msecs_to_jiffies(2000));
+#endif
+ //Himax Power On and Load Config
+ if (himax_loadSensorConfig(client, pdata))
+ {
+ E("%s: Load Sesnsor configuration failed, unload driver.\n", __func__);
+ goto err_detect_failed;
+ }
+ himax_power_on_init(client);
+
+ calculate_point_number();
+#ifdef HX_TP_PROC_DIAG
+ setXChannel(ic_data->HX_RX_NUM); // X channel
+ setYChannel(ic_data->HX_TX_NUM); // Y channel
+
+ setMutualBuffer();
+ setMutualNewBuffer();
+ setMutualOldBuffer();
+ if (getMutualBuffer() == NULL)
+ {
+ E("%s: mutual buffer allocate fail failed\n", __func__);
+ return -1;
+ }
+#ifdef HX_TP_PROC_2T2R
+ if(Is_2T2R)
+ {
+ setXChannel_2(ic_data->HX_RX_NUM_2); // X channel
+ setYChannel_2(ic_data->HX_TX_NUM_2); // Y channel
+
+ setMutualBuffer_2();
+
+ if (getMutualBuffer_2() == NULL)
+ {
+ E("%s: mutual buffer 2 allocate fail failed\n", __func__);
+ return -1;
+ }
+ }
+#endif
+#endif
+#ifdef CONFIG_OF
+ ts->power = pdata->power;
+#endif
+ ts->pdata = pdata;
+
+ ts->x_channel = ic_data->HX_RX_NUM;
+ ts->y_channel = ic_data->HX_TX_NUM;
+ ts->nFinger_support = ic_data->HX_MAX_PT;
+ //calculate the i2c data size
+ calcDataSize(ts->nFinger_support);
+ I("%s: calcDataSize complete\n", __func__);
+#ifdef CONFIG_OF
+ ts->pdata->abs_pressure_min = 0;
+ ts->pdata->abs_pressure_max = 200;
+ ts->pdata->abs_width_min = 0;
+ ts->pdata->abs_width_max = 200;
+ pdata->cable_config[0] = 0xF0;
+ pdata->cable_config[1] = 0x00;
+#endif
+ ts->suspended = false;
+#if defined( HX_USB_DETECT_CALLBACK)||defined(HX_USB_DETECT_GLOBAL)
+ ts->usb_connected = 0x00;
+ ts->cable_config = pdata->cable_config;
+#endif
+#ifdef HX_PROTOCOL_A
+ ts->protocol_type = PROTOCOL_TYPE_A;
+#else
+ ts->protocol_type = PROTOCOL_TYPE_B;
+#endif
+ I("%s: Use Protocol Type %c\n", __func__,
+ ts->protocol_type == PROTOCOL_TYPE_A ? 'A' : 'B');
+
+ ret = himax_input_register(ts);
+ if (ret)
+ {
+ E("%s: Unable to register %s input device\n",
+ __func__, ts->input_dev->name);
+ goto err_input_register_device_failed;
+ }
+#ifdef CONFIG_FB
+ ts->himax_att_wq = create_singlethread_workqueue("HMX_ATT_reuqest");
+ if (!ts->himax_att_wq)
+ {
+ E(" allocate syn_att_wq failed\n");
+ err = -ENOMEM;
+ goto err_get_intr_bit_failed;
+ }
+ INIT_DELAYED_WORK(&ts->work_att, himax_fb_register);
+ queue_delayed_work(ts->himax_att_wq, &ts->work_att, msecs_to_jiffies(15000));
+#endif
+
+ mutex_init(&ts->report_mutex);
+
+#if defined(HX_CHIP_STATUS_MONITOR)//for ESD solution
+ I("Enter HX_CHIP_STATUS_MONITOR! \n");
+
+ g_chip_monitor_data = kzalloc(sizeof(struct chip_monitor_data),GFP_KERNEL);
+ if(g_chip_monitor_data == NULL)
+ {
+ err = -ENOMEM;
+ goto err_alloc_monitor_data;
+ }
+ g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0;
+ g_chip_monitor_data->HX_POLLING_TIMER = 5;//unit:sec
+ g_chip_monitor_data->HX_POLLING_TIMES = 2;//ex:5(timer)x2(times)=10sec(polling time)
+ g_chip_monitor_data->HX_ON_HAND_SHAKING = 0;//
+ g_chip_monitor_data->HX_CHIP_MONITOR_EN = 1;
+
+ ts->himax_chip_monitor_wq = create_singlethread_workqueue("himax_chip_monitor_wq");
+ if (!ts->himax_chip_monitor_wq)
+ {
+ E(" %s: create workqueue failed\n", __func__);
+ err = -ENOMEM;
+ goto err_create_chip_monitor_wq_failed;
+ }
+ g_chip_monitor_data->HX_CHIP_MONITOR_EN = 1;
+
+ INIT_DELAYED_WORK(&ts->himax_chip_monitor, himax_chip_monitor_function);
+
+ queue_delayed_work(ts->himax_chip_monitor_wq, &ts->himax_chip_monitor, g_chip_monitor_data->HX_POLLING_TIMER*HZ);
+
+#endif
+
+#ifdef HX_SMART_WAKEUP
+ ts->SMWP_enable=0;
+ //wake_lock_init(&ts->ts_SMWP_wake_lock, WAKE_LOCK_SUSPEND, HIMAX_common_NAME);
+ wakeup_source_init(&ts->ts_SMWP_wake_lock, HIMAX_common_NAME);
+#endif
+#ifdef HX_HIGH_SENSE
+ ts->HSEN_enable=0;
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST)
+ ts->ito_test_wq = create_singlethread_workqueue("himax_ito_test_wq");
+ if (!ts->ito_test_wq)
+ {
+ E("%s: ito test workqueue failed\n", __func__);
+ err = -ENOMEM;
+ goto err_ito_test_wq_failed;
+ }
+
+ INIT_WORK(&ts->ito_test_work, himax_ito_test_work);
+#endif
+
+ //touch data init
+ err=himax_report_data_init();
+ if(err)
+ goto err_report_data_init_failed;
+
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
+ himax_touch_proc_init();
+#endif
+
+#if defined( HX_USB_DETECT_CALLBACK)
+ if (ts->cable_config)
+ cable_detect_register_notifier(&himax_cable_status_handler);
+#endif
+
+ err = himax_ts_register_interrupt(ts->client);
+ if (err)
+ goto err_register_interrupt_failed;
+
+#if defined(HX_AUTO_UPDATE_FW) || defined(HX_ZERO_FLASH)
+ if (auto_update_flag)
+ {
+ himax_int_enable(client->irq,0);
+ }
+#endif
+
+ return 0;
+
+err_register_interrupt_failed:
+err_report_data_init_failed:
+
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST)
+err_ito_test_wq_failed:
+#endif
+#ifdef HX_SMART_WAKEUP
+ //wake_lock_destroy(&ts->ts_SMWP_wake_lock);
+ wakeup_source_trash(&ts->ts_SMWP_wake_lock);
+#endif
+#ifdef HX_CHIP_STATUS_MONITOR
+ g_chip_monitor_data->HX_CHIP_MONITOR_EN = 0;
+ cancel_delayed_work_sync(&ts->himax_chip_monitor);
+ destroy_workqueue(ts->himax_chip_monitor_wq);
+err_create_chip_monitor_wq_failed:
+err_alloc_monitor_data:
+ kfree(g_chip_monitor_data);
+#endif
+#ifdef CONFIG_FB
+err_get_intr_bit_failed:
+#endif
+err_input_register_device_failed:
+ input_free_device(ts->input_dev);
+err_detect_failed:
+#ifdef HX_AUTO_UPDATE_FW
+err_update_wq_failed:
+#endif
+#ifdef HX_TP_PROC_GUEST_INFO
+err_create_guest_info_wq_failed:
+#endif
+#ifdef HX_TP_PROC_FLASH_DUMP
+err_create_wq_failed:
+#endif
+err_ic_package_failed:
+
+ if (gpio_is_valid(pdata->gpio_irq))
+ gpio_free(pdata->gpio_irq);
+#ifdef HX_RST_PIN_FUNC
+ if (gpio_is_valid(pdata->gpio_reset))
+ gpio_free(pdata->gpio_reset);
+#endif
+
+err_alloc_dt_pdata_failed:
+#ifndef CONFIG_OF
+err_power_failed:
+#endif
+
+ kfree(ic_data);
+
+err_dt_ic_data_fail:
+ kfree(pdata);
+
+err_dt_platform_data_fail:
+ kfree(ts);
+
+err_alloc_data_failed:
+ kfree(hx_touch_data);
+
+err_check_functionality_failed:
+ probe_fail_flag = 1;
+ return err;
+
+}
+
+int himax_chip_common_remove(struct i2c_client *client)
+{
+ struct himax_ts_data *ts = i2c_get_clientdata(client);
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
+ himax_touch_proc_deinit();
+#endif
+#ifdef HX_CHIP_STATUS_MONITOR
+ g_chip_monitor_data->HX_CHIP_MONITOR_EN = 0;
+ cancel_delayed_work_sync(&ts->himax_chip_monitor);
+ destroy_workqueue(ts->himax_chip_monitor_wq);
+ kfree(g_chip_monitor_data);
+#endif
+#ifdef CONFIG_FB
+ if (fb_unregister_client(&ts->fb_notif))
+ dev_err(&client->dev, "Error occurred while unregistering fb_notifier.\n");
+#endif
+
+ if (!ts->use_irq)
+ hrtimer_cancel(&ts->timer);
+
+ destroy_workqueue(ts->himax_wq);
+
+#ifndef HX_PROTOCOL_A
+ input_mt_destroy_slots(ts->input_dev);
+#endif
+
+ input_unregister_device(ts->input_dev);
+
+#ifdef HX_SMART_WAKEUP
+ //wake_lock_destroy(&ts->ts_SMWP_wake_lock);
+ wakeup_source_trash(&ts->ts_SMWP_wake_lock);
+#endif
+ kfree(ts);
+
+ return 0;
+
+}
+
+int himax_chip_common_suspend(struct himax_ts_data *ts)
+{
+ int ret;
+#ifdef HX_CHIP_STATUS_MONITOR
+ int t = 0;
+#endif
+
+ if(ts->suspended)
+ {
+ I("%s: Already suspended. Skipped. \n", __func__);
+ return 0;
+ }
+ else
+ {
+ ts->suspended = true;
+ I("%s: enter \n", __func__);
+ }
+
+#ifdef HX_TP_PROC_FLASH_DUMP
+ if (getFlashDumpGoing())
+ {
+ I("[himax] %s: Flash dump is going, reject suspend\n",__func__);
+ return 0;
+ }
+#endif
+#ifdef HX_TP_PROC_GUEST_INFO
+ if (himax_guest_info_get_status())
+ {
+ I("[himax] %s: GUEST INFO dump is going, reject suspend\n",__func__);
+ return 0;
+ }
+#endif
+#ifdef HX_CHIP_STATUS_MONITOR
+ if(g_chip_monitor_data->HX_ON_HAND_SHAKING)//chip on hand shaking,wait hand shaking
+ {
+ for(t=0; t<100; t++)
+ {
+ if(g_chip_monitor_data->HX_ON_HAND_SHAKING==0)//chip on hand shaking end
+ {
+ I("%s:HX_ON_HAND_SHAKING OK check %d times\n",__func__,t);
+ break;
+ }
+ else
+ msleep(1);
+ }
+ if(t==100)
+ {
+ E("%s:HX_ON_HAND_SHAKING timeout reject suspend\n",__func__);
+ return 0;
+ }
+ }
+ g_chip_monitor_data->HX_CHIP_MONITOR_EN = 0;
+ g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0;
+ cancel_delayed_work_sync(&ts->himax_chip_monitor);
+#endif
+
+#if defined(HX_SMART_WAKEUP)||defined(HX_HIGH_SENSE)||defined(HX_USB_DETECT_GLOBAL)
+#ifndef HX_RESUME_SEND_CMD
+ himax_resend_cmd_func(ts->suspended);
+#endif
+#endif
+
+#ifdef HX_SMART_WAKEUP
+ if(ts->SMWP_enable)
+ {
+ atomic_set(&ts->suspend_mode, 1);
+ ts->pre_finger_mask = 0;
+ FAKE_POWER_KEY_SEND=false;
+ I("[himax] %s: SMART_WAKEUP enable, reject suspend\n",__func__);
+ return 0;
+ }
+#endif
+
+ himax_int_enable(ts->client->irq,0);
+#ifdef HX_RST_PIN_FUNC
+ reset_flag = 0;
+#endif
+ himax_suspend_ic_action(ts->client);
+
+ if (!ts->use_irq)
+ {
+ ret = cancel_work_sync(&ts->work);
+ if (ret)
+ himax_int_enable(ts->client->irq,1);
+ }
+
+ //ts->first_pressed = 0;
+ atomic_set(&ts->suspend_mode, 1);
+ ts->pre_finger_mask = 0;
+ if (ts->pdata->powerOff3V3 && ts->pdata->power)
+ ts->pdata->power(0);
+ I("%s: END \n", __func__);
+ return 0;
+}
+
+int himax_chip_common_resume(struct himax_ts_data *ts)
+{
+
+#ifdef HX_CHIP_STATUS_MONITOR
+ int t=0;
+#endif
+
+ I("%s: enter \n", __func__);
+ if(ts->suspended == false)
+ {
+ I("%s: It had entered resume,skip this step \n", __func__);
+ return 0;
+ }
+ else
+ ts->suspended = false;
+
+ atomic_set(&ts->suspend_mode, 0);
+
+ himax_release_all_finger();
+
+ if (ts->pdata->powerOff3V3 && ts->pdata->power)
+ ts->pdata->power(1);
+
+#ifdef HX_CHIP_STATUS_MONITOR
+ if(g_chip_monitor_data->HX_ON_HAND_SHAKING)//chip on hand shaking,wait hand shaking
+ {
+ for(t=0; t<100; t++)
+ {
+ if(g_chip_monitor_data->HX_ON_HAND_SHAKING == 0)//chip on hand shaking end
+ {
+ I("%s:HX_ON_HAND_SHAKING OK check %d times\n",__func__,t);
+ break;
+ }
+ else
+ msleep(1);
+ }
+ if(t==100)
+ {
+ E("%s:HX_ON_HAND_SHAKING timeout reject resume\n",__func__);
+ return 0;
+ }
+ }
+#endif
+
+#if defined(HX_SMART_WAKEUP)||defined(HX_HIGH_SENSE)||defined(HX_USB_DETECT_GLOBAL)
+#if defined(HX_RESUME_SEND_CMD)
+ himax_resend_cmd_func(ts->suspended);
+#endif
+#elif defined(HX_RESUME_HW_RESET)
+ himax_ic_reset(false,false);
+#endif
+
+ himax_resume_ic_action(ts->client);
+
+ himax_int_enable(ts->client->irq,1);
+#ifdef HX_RST_PIN_FUNC
+ reset_flag = 1;
+#endif
+#ifdef HX_CHIP_STATUS_MONITOR
+ g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0;
+ g_chip_monitor_data->HX_CHIP_MONITOR_EN = 1;
+ queue_delayed_work(ts->himax_chip_monitor_wq, &ts->himax_chip_monitor, g_chip_monitor_data->HX_POLLING_TIMER*HZ); //for ESD solution
+#endif
+ I("%s: END \n", __func__);
+ return 0;
+}
+
diff --git a/drivers/input/touchscreen/hxchipset83112b/himax_common.h b/drivers/input/touchscreen/hxchipset83112b/himax_common.h
new file mode 100755
index 0000000..5e12bc9
--- /dev/null
+++ b/drivers/input/touchscreen/hxchipset83112b/himax_common.h
@@ -0,0 +1,440 @@
+/* Himax Android Driver Sample Code for common functions
+*
+* Copyright (C) 2017 Himax Corporation.
+*
+* 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 HIMAX_COMMON_H
+#define HIMAX_COMMON_H
+
+#include <asm/segment.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/async.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/input/mt.h>
+#include <linux/firmware.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/buffer_head.h>
+//#include <linux/wakelock.h>
+#include <linux/pm_wakeup.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
+#include "himax_platform.h"
+#include <linux/file.h>
+#if defined(CONFIG_FB)
+#include <linux/notifier.h>
+#include <linux/fb.h>
+#include <linux/mutex.h>
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+#include <linux/earlysuspend.h>
+#endif
+
+#ifdef CONFIG_OF
+#include <linux/of_gpio.h>
+#endif
+//#define HIMAX_DRIVER_VER "0.1.95.0_ABCD1234_01"
+#define HIMAX_DRIVER_VER "1.2.2.69_ABCD1234_01"
+
+#define FLASH_DUMP_FILE "/sdcard/HX_Flash_Dump.bin"
+
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
+
+#define HX_TP_PROC_DIAG
+#define HX_TP_PROC_REGISTER
+#define HX_TP_PROC_DEBUG
+#define HX_TP_PROC_FLASH_DUMP
+#define HX_TP_PROC_SELF_TEST
+#define HX_TP_PROC_RESET
+#define HX_TP_PROC_SENSE_ON_OFF
+#define HX_TP_PROC_2T2R
+
+#ifdef HX_TP_PROC_SELF_TEST
+//#define HX_TP_SELF_TEST_DRIVER //if enable, selftest works in driver
+#endif
+
+int himax_touch_proc_init(void);
+void himax_touch_proc_deinit(void);
+#endif
+//===========Himax Option function=============
+#define HX_RST_PIN_FUNC
+#define HX_AUTO_UPDATE_FW
+//#define HX_ESD_RECOVERY
+//#define HX_CHIP_STATUS_MONITOR /*for ESD 2nd solution,it does not support incell,default off*/
+//#define HX_SMART_WAKEUP
+//#define HX_GESTURE_TRACK
+//#define HX_HIGH_SENSE
+//#define HX_PALM_REPORT
+#define HX_USB_DETECT_GLOBAL
+//#define HX_USB_DETECT_CALLBACK
+//#define HX_PROTOCOL_A /* for MTK special platform.If turning on,it will report to system by using specific format. */
+//#define HX_RESUME_HW_RESET
+//#define HX_RESUME_SEND_CMD
+#define HX_PROTOCOL_B_3PA
+#define HX_FIX_TOUCH_INFO /* if open, you need to change the touch info in the fix_touch_info*/
+//#define HX_EN_SEL_BUTTON /* Support Self Virtual key ,default is close*/
+//#define HX_EN_MUT_BUTTON /* Support Mutual Virtual Key ,default is close*/
+
+#if defined(HX_EN_SEL_BUTTON) || defined(HX_EN_MUT_BUTTON)
+//#define HX_PLATFOME_DEFINE_KEY /* for specfic platform to set key(button) */
+#endif
+
+#ifdef HX_USB_DETECT_GLOBAL
+#define POWER_SUPPLY_BATTERY_STATUS_PATCH "/sys/class/power_supply/battery/status"
+#endif
+
+#define HX_KEY_MAX_COUNT 4
+#define DEFAULT_RETRY_CNT 3
+
+#define HX_85XX_A_SERIES_PWON 1
+#define HX_85XX_B_SERIES_PWON 2
+#define HX_85XX_C_SERIES_PWON 3
+#define HX_85XX_D_SERIES_PWON 4
+#define HX_85XX_E_SERIES_PWON 5
+#define HX_85XX_ES_SERIES_PWON 6
+#define HX_85XX_F_SERIES_PWON 7
+#define HX_85XX_G_SERIES_PWON 8
+#define HX_85XX_H_SERIES_PWON 9
+#define HX_83100A_SERIES_PWON 10
+#define HX_83102A_SERIES_PWON 11
+#define HX_83102B_SERIES_PWON 12
+#define HX_83110A_SERIES_PWON 13
+#define HX_83110B_SERIES_PWON 14
+#define HX_83111B_SERIES_PWON 15
+#define HX_83112A_SERIES_PWON 16
+#define HX_83112B_SERIES_PWON 17
+
+#define HX_TP_BIN_CHECKSUM_SW 1
+#define HX_TP_BIN_CHECKSUM_HW 2
+#define HX_TP_BIN_CHECKSUM_CRC 3
+
+#define SHIFTBITS 5
+
+#define FW_SIZE_32k 32768
+#define FW_SIZE_60k 61440
+#define FW_SIZE_64k 65536
+#define FW_SIZE_124k 126976
+#define FW_SIZE_128k 131072
+
+#define NO_ERR 0
+#define READY_TO_SERVE 1
+#define WORK_OUT 2
+#define I2C_FAIL -1
+#define MEM_ALLOC_FAIL -2
+#define CHECKSUM_FAIL -3
+#define GESTURE_DETECT_FAIL -4
+#define INPUT_REGISTER_FAIL -5
+#define FW_NOT_READY -6
+#define LENGTH_FAIL -7
+#define OPEN_FILE_FAIL -8
+#define ERR_WORK_OUT -10
+
+#define HX_FINGER_ON 1
+#define HX_FINGER_LEAVE 2
+
+#define HX_REPORT_COORD 1
+#define HX_REPORT_SMWP_EVENT 2
+#ifdef HX_FIX_TOUCH_INFO
+enum fix_touch_info
+{
+ FIX_HX_RX_NUM = 30,
+ FIX_HX_TX_NUM = 18,
+ FIX_HX_BT_NUM = 0,
+ FIX_HX_X_RES = 1080,
+ FIX_HX_Y_RES = 2160,
+ FIX_HX_MAX_PT = 10,
+ FIX_HX_XY_REVERSE = true,
+ FIX_HX_INT_IS_EDGE = false,
+#ifdef HX_TP_PROC_2T2R
+ FIX_HX_RX_NUM_2 = 0,
+ FIX_HX_TX_NUM_2 = 0,
+#endif
+ SEC_FIX_HX_RX_NUM = 36,
+ SEC_FIX_HX_TX_NUM = 18,
+ SEC_FIX_HX_BT_NUM = 0,
+ SEC_FIX_HX_X_RES = 1080,
+ SEC_FIX_HX_Y_RES = 2160,
+ SEC_FIX_HX_MAX_PT = 10,
+ SEC_FIX_HX_XY_REVERSE = true,
+ SEC_FIX_HX_INT_IS_EDGE = false,
+#ifdef HX_TP_PROC_2T2R
+ SEC_FIX_HX_RX_NUM_2 = 0,
+ SEC_FIX_HX_TX_NUM_2 = 0
+#endif
+};
+#endif
+#ifdef HX_ZERO_FLASH
+#define HX_0F_DEBUG
+#endif
+
+struct himax_ic_data
+{
+ int vendor_fw_ver;
+ int vendor_config_ver;
+ int vendor_touch_cfg_ver;
+ int vendor_display_cfg_ver;
+ int vendor_cid_maj_ver;
+ int vendor_cid_min_ver;
+ int vendor_panel_ver;
+ int vendor_sensor_id;
+ int vendor_hx_ic_id;
+ int HX_RX_NUM;
+ int HX_TX_NUM;
+ int HX_BT_NUM;
+ int HX_X_RES;
+ int HX_Y_RES;
+ int HX_MAX_PT;
+ bool HX_XY_REVERSE;
+ bool HX_INT_IS_EDGE;
+#ifdef HX_TP_PROC_2T2R
+ int HX_RX_NUM_2;
+ int HX_TX_NUM_2;
+#endif
+};
+
+struct himax_virtual_key
+{
+ int index;
+ int keycode;
+ int x_range_min;
+ int x_range_max;
+ int y_range_min;
+ int y_range_max;
+};
+
+struct himax_report_data
+{
+ int touch_all_size;
+ int raw_cnt_max;
+ int raw_cnt_rmd;
+ int touch_info_size;
+ uint8_t finger_num;
+ uint8_t finger_on;
+ uint8_t *hx_coord_buf;
+ uint8_t hx_state_info[2];
+#if defined(HX_SMART_WAKEUP)
+ int event_size;
+ uint8_t *hx_event_buf;
+#endif
+#if defined(HX_TP_PROC_DIAG)
+ int rawdata_size;
+ uint8_t diag_cmd;
+ uint8_t *hx_rawdata_buf;
+ uint8_t rawdata_frame_size;
+#endif
+};
+
+struct himax_ts_data
+{
+ bool suspended;
+ atomic_t suspend_mode;
+ uint8_t x_channel;
+ uint8_t y_channel;
+ uint8_t useScreenRes;
+ uint8_t diag_command;
+
+ uint8_t protocol_type;
+ uint8_t first_pressed;
+ uint8_t coord_data_size;
+ uint8_t area_data_size;
+ uint8_t coordInfoSize;
+ uint8_t raw_data_frame_size;
+ uint8_t raw_data_nframes;
+ uint8_t nFinger_support;
+ uint8_t irq_enabled;
+ uint8_t diag_self[50];
+
+ uint16_t finger_pressed;
+ uint16_t last_slot;
+ uint16_t pre_finger_mask;
+
+ uint32_t debug_log_level;
+ uint32_t widthFactor;
+ uint32_t heightFactor;
+ uint32_t tw_x_min;
+ uint32_t tw_x_max;
+ uint32_t tw_y_min;
+ uint32_t tw_y_max;
+ uint32_t pl_x_min;
+ uint32_t pl_x_max;
+ uint32_t pl_y_min;
+ uint32_t pl_y_max;
+
+ int rst_gpio;
+ int use_irq;
+ int (*power)(int on);
+ int pre_finger_data[10][2];
+
+ struct device *dev;
+ struct workqueue_struct *himax_wq;
+ struct work_struct work;
+ struct input_dev *input_dev;
+ struct hrtimer timer;
+ struct i2c_client *client;
+ struct himax_i2c_platform_data *pdata;
+ struct himax_virtual_key *button;
+ struct mutex rw_lock;
+ struct mutex report_mutex;
+
+#if defined(CONFIG_FB)
+ struct notifier_block fb_notif;
+ struct workqueue_struct *himax_att_wq;
+ struct delayed_work work_att;
+ struct mutex ops_lock;
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+ struct early_suspend early_suspend;
+#endif
+#ifdef HX_CHIP_STATUS_MONITOR
+ struct workqueue_struct *himax_chip_monitor_wq;
+ struct delayed_work himax_chip_monitor;
+#endif
+#ifdef HX_TP_PROC_FLASH_DUMP
+ struct workqueue_struct *flash_wq;
+ struct work_struct flash_work;
+#endif
+
+#ifdef HX_AUTO_UPDATE_FW
+ struct workqueue_struct *himax_update_wq;
+ struct delayed_work work_update;
+#endif
+
+#ifdef HX_ZERO_FLASH
+ struct workqueue_struct *himax_0f_update_wq;
+ struct delayed_work work_0f_update;
+#endif
+
+#ifdef HX_TP_PROC_DIAG
+ struct workqueue_struct *himax_diag_wq;
+ struct delayed_work himax_diag_delay_wrok;
+#endif
+
+#ifdef HX_SMART_WAKEUP
+ uint8_t SMWP_enable;
+ uint8_t gesture_cust_en[16];
+ //struct wake_lock ts_SMWP_wake_lock;
+ struct wakeup_source ts_SMWP_wake_lock;
+#endif
+
+#ifdef HX_HIGH_SENSE
+ uint8_t HSEN_enable;
+#endif
+
+#if defined(HX_USB_DETECT_CALLBACK)||defined(HX_USB_DETECT_GLOBAL)
+ uint8_t usb_connected;
+ uint8_t *cable_config;
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST)
+ struct workqueue_struct *ito_test_wq;
+ struct work_struct ito_test_work;
+#endif
+
+};
+
+#ifdef HX_CHIP_STATUS_MONITOR
+struct chip_monitor_data
+{
+ int HX_CHIP_POLLING_COUNT;
+ int HX_POLLING_TIMER;//unit:sec
+ int HX_POLLING_TIMES;//ex:5(timer)x2(times)=10sec(polling time)
+ int HX_ON_HAND_SHAKING;//
+ int HX_CHIP_MONITOR_EN;
+};
+#endif
+
+
+enum input_protocol_type
+{
+ PROTOCOL_TYPE_A = 0x00,
+ PROTOCOL_TYPE_B = 0x01,
+};
+
+#ifdef HX_HIGH_SENSE
+void himax_set_HSEN_func(struct i2c_client *client,uint8_t HSEN_enable);
+#endif
+
+#ifdef HX_SMART_WAKEUP
+#define GEST_PTLG_ID_LEN (4)
+#define GEST_PTLG_HDR_LEN (4)
+#define GEST_PTLG_HDR_ID1 (0xCC)
+#define GEST_PTLG_HDR_ID2 (0x44)
+#define GEST_PT_MAX_NUM (128)
+
+void himax_set_SMWP_func(struct i2c_client *client,uint8_t SMWP_enable);
+extern bool FAKE_POWER_KEY_SEND;
+
+enum gesture_event_type
+{
+ EV_GESTURE_01 = 0x01,
+ EV_GESTURE_02,
+ EV_GESTURE_03,
+ EV_GESTURE_04,
+ EV_GESTURE_05,
+ EV_GESTURE_06,
+ EV_GESTURE_07,
+ EV_GESTURE_08,
+ EV_GESTURE_09,
+ EV_GESTURE_10,
+ EV_GESTURE_11,
+ EV_GESTURE_12,
+ EV_GESTURE_13,
+ EV_GESTURE_14,
+ EV_GESTURE_15,
+ EV_GESTURE_PWR = 0x80,
+};
+
+#define KEY_CUST_01 251
+#define KEY_CUST_02 252
+#define KEY_CUST_03 253
+#define KEY_CUST_04 254
+#define KEY_CUST_05 255
+#define KEY_CUST_06 256
+#define KEY_CUST_07 257
+#define KEY_CUST_08 258
+#define KEY_CUST_09 259
+#define KEY_CUST_10 260
+#define KEY_CUST_11 261
+#define KEY_CUST_12 262
+#define KEY_CUST_13 263
+#define KEY_CUST_14 264
+#define KEY_CUST_15 265
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST)
+extern uint8_t himax_ito_test(void);
+#endif
+
+extern int irq_enable_count;
+
+//void himax_HW_reset(uint8_t loadconfig,uint8_t int_off);
+
+#ifdef QCT
+irqreturn_t himax_ts_thread(int irq, void *ptr);
+int himax_input_register(struct himax_ts_data *ts);
+#endif
+
+extern int himax_chip_common_probe(struct i2c_client *client, const struct i2c_device_id *id);
+extern int himax_chip_common_remove(struct i2c_client *client);
+extern int himax_chip_common_suspend(struct himax_ts_data *ts);
+extern int himax_chip_common_resume(struct himax_ts_data *ts);
+
+#endif
+
diff --git a/drivers/input/touchscreen/hxchipset83112b/himax_debug.c b/drivers/input/touchscreen/hxchipset83112b/himax_debug.c
new file mode 100755
index 0000000..33e6a08
--- /dev/null
+++ b/drivers/input/touchscreen/hxchipset83112b/himax_debug.c
@@ -0,0 +1,3351 @@
+/* Himax Android Driver Sample Code for debug nodes
+*
+* Copyright (C) 2017 Himax Corporation.
+*
+* 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 "himax_debug.h"
+#include "himax_ic.h"
+
+//struct himax_debug_data* debug_data;
+
+extern struct himax_ic_data* ic_data;
+extern struct himax_ts_data *private_ts;
+extern unsigned char IC_TYPE;
+extern unsigned char IC_CHECKSUM;
+extern int himax_input_register(struct himax_ts_data *ts);
+#ifdef HX_CHIP_STATUS_MONITOR
+extern struct chip_monitor_data *g_chip_monitor_data;
+#endif
+
+#ifdef HX_RST_PIN_FUNC
+extern void himax_ic_reset(uint8_t loadconfig,uint8_t int_off);
+#endif
+
+#ifdef HX_TP_PROC_DIAG
+#ifdef HX_TP_PROC_2T2R
+extern bool Is_2T2R;
+int HX_RX_NUM_2 = 0;
+int HX_TX_NUM_2 = 0;
+#endif
+uint8_t g_diag_arr_num = 0;
+#endif
+
+#ifdef HX_SMART_WAKEUP
+bool FAKE_POWER_KEY_SEND;
+#endif
+
+int g_max_mutual = 0;
+int g_min_mutual = 255;
+int g_max_self = 0;
+int g_min_self = 255;
+
+#if defined(HX_TP_PROC_SELF_TEST) || defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST)
+int g_self_test_entered = 0;
+#endif
+
+struct timespec timeStart, timeEnd, timeDelta;
+int g_switch_mode = 0;
+extern void himax_idle_mode(struct i2c_client *client,int disable);
+extern int himax_switch_mode(struct i2c_client *client,int mode);
+extern void himax_return_event_stack(struct i2c_client *client);
+
+#ifdef HX_ZERO_FLASH
+extern void himax_0f_operation(struct work_struct *work);
+extern void himax_0f_operation_check(void);
+extern void himax_sys_reset(void);
+#endif
+
+//=============================================================================================================
+//
+// Segment : Himax PROC Debug Function
+//
+//=============================================================================================================
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
+
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST)
+
+static ssize_t himax_ito_test_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ ssize_t ret = 0;
+ uint8_t result = 0;
+ uint8_t status = 0;
+
+ if(!HX_PROC_SEND_FLAG)
+ {
+ status = ito_get_step_status();
+
+ switch(status)
+ {
+ case 0:
+ ret += sprintf(buf + ret, "Step : START_TEST\n");
+ break;
+ case 1:
+ ret += sprintf(buf + ret, "Step : RAW_DATA\n");
+ break;
+ case 2:
+ ret += sprintf(buf + ret, "Step : PERCENT_TEST\n");
+ break;
+ case 3:
+ ret += sprintf(buf + ret, "Step : DEV_TEST\n");
+ break;
+ case 4:
+ ret += sprintf(buf + ret, "Step : NOISE_TEST\n");
+ break;
+ case 9:
+ ret += sprintf(buf + ret, "Step : END_TEST\n");
+ break;
+ default:
+ ret += sprintf(buf + ret, "Step : Null\n");
+ }
+
+ result = ito_get_result_status();
+ if(result == 0xF)
+ ret += sprintf(buf + ret, "ITO test is On-going! \n");
+ else if(result == 0)
+ ret += sprintf(buf + ret, "ITO test is Pass! \n");
+ else if(result == 2)
+ ret += sprintf(buf + ret, "Open config file fail! \n");
+ else
+ ret += sprintf(buf + ret, "ITO test is Fail! \n");
+ HX_PROC_SEND_FLAG=1;
+ }
+ else
+ HX_PROC_SEND_FLAG=0;
+
+ return ret;
+}
+
+static ssize_t himax_ito_test_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+ struct himax_ts_data *ts = private_ts;
+ uint8_t result = 0;
+ char buf[80] = {0};
+
+ if (len >= 80)
+ {
+ I("%s: no command exceeds 80 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf, buff, len))
+ {
+ return -EFAULT;
+ }
+
+ result = ito_get_result_status();
+ I("%s: buf = %s, result = %d.\n", __func__, buf, result);
+
+ if(buf[0] == '1' && result != 0xF)
+ {
+ I("%s: buf[0] = %c.\n", __func__, buf[0]);
+ ito_set_step_status(0);
+ queue_work(ts->ito_test_wq, &ts->ito_test_work);
+ }
+
+ return len;
+}
+
+static struct file_operations himax_proc_ito_test_ops =
+{
+ .owner = THIS_MODULE,
+ .read = himax_ito_test_read,
+ .write = himax_ito_test_write,
+};
+#endif
+
+static ssize_t himax_CRC_test_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ ssize_t ret = 0;
+ uint8_t result = 0;
+ char *temp_buf;
+
+ temp_buf = kzalloc(len,GFP_KERNEL);
+
+ if(!HX_PROC_SEND_FLAG)
+ {
+ himax_sense_off(private_ts->client);
+ msleep(20);
+ result = himax_calculateChecksum(private_ts->client, false);
+ himax_sense_on(private_ts->client, 0x01);
+ if(result)
+ ret += sprintf(temp_buf + ret, "CRC test is Pass! \n");
+ else
+ ret += sprintf(temp_buf + ret, "CRC test is Fail! \n");
+ if(copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n",__func__,__LINE__);
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG=1;
+ }
+ else
+ HX_PROC_SEND_FLAG=0;
+
+ return ret;
+}
+
+static struct file_operations himax_proc_CRC_test_ops =
+{
+ .owner = THIS_MODULE,
+ .read = himax_CRC_test_read,
+};
+
+static ssize_t himax_vendor_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ ssize_t count = 0;
+ char *temp_buf;
+
+ temp_buf = kzalloc(len,GFP_KERNEL);
+
+ if(!HX_PROC_SEND_FLAG)
+ {
+#if 1
+ if((IC_TYPE >= 8)&&(ic_data->vendor_cid_maj_ver >= 0 || ic_data->vendor_cid_min_ver >= 0))
+ {
+ if(IC_TYPE == HX_83112A_SERIES_PWON)
+ {
+ count += sprintf(temp_buf + count, "Truly Himax CID0%2.2X_D%2.2X_C%2.2X \n",(ic_data->vendor_cid_maj_ver << 8 | ic_data->vendor_cid_min_ver),ic_data->vendor_display_cfg_ver,ic_data->vendor_touch_cfg_ver);
+ }
+ else
+ {
+ count += sprintf(temp_buf + count, "DJN Himax CID0%2.2X_D%2.2X_C%2.2X \n",(ic_data->vendor_cid_maj_ver << 8 | ic_data->vendor_cid_min_ver),ic_data->vendor_display_cfg_ver,ic_data->vendor_touch_cfg_ver);
+ }
+ }
+ else
+ {
+ count += sprintf(temp_buf + count, "Himax null\n");
+ }
+#else
+ count += sprintf(temp_buf + count, "FW_VER = 0x%2.2X \n",ic_data->vendor_fw_ver);
+
+ if(IC_TYPE < 8)
+ count += sprintf(temp_buf + count, "CONFIG_VER = 0x%2.2X \n",ic_data->vendor_config_ver);
+ else
+ {
+ count += sprintf(temp_buf + count, "TOUCH_VER = 0x%2.2X \n",ic_data->vendor_touch_cfg_ver);
+ count += sprintf(temp_buf + count, "DISPLAY_VER = 0x%2.2X \n",ic_data->vendor_display_cfg_ver);
+ }
+ if(ic_data->vendor_cid_maj_ver < 0 && ic_data->vendor_cid_min_ver < 0)
+ count += sprintf(temp_buf + count, "CID_VER = NULL\n");
+ else
+ count += sprintf(temp_buf + count, "CID_VER = 0x%2.2X \n",(ic_data->vendor_cid_maj_ver << 8 | ic_data->vendor_cid_min_ver));
+
+ if(ic_data->vendor_panel_ver < 0)
+ count += sprintf(temp_buf + count, "PANEL_VER = NULL\n");
+ else
+ count += sprintf(temp_buf + count, "PANEL_VER = 0x%2.2X \n",ic_data->vendor_panel_ver);
+
+ count += sprintf(temp_buf + count, "\n");
+
+ count += sprintf(temp_buf + count, "Himax Touch Driver Version:\n");
+ count += sprintf(temp_buf + count, "%s \n", HIMAX_DRIVER_VER);
+#endif
+ HX_PROC_SEND_FLAG=1;
+ if(copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n",__func__,__LINE__);
+ kfree(temp_buf);
+ }
+ else
+ HX_PROC_SEND_FLAG=0;
+
+ return count;
+}
+
+static struct file_operations himax_proc_vendor_ops =
+{
+ .owner = THIS_MODULE,
+ .read = himax_vendor_read,
+};
+
+static ssize_t himax_attn_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ ssize_t ret = 0;
+ struct himax_ts_data *ts_data;
+ char *temp_buf;
+
+ temp_buf = kzalloc(len,GFP_KERNEL);
+ ts_data = private_ts;
+
+ if(!HX_PROC_SEND_FLAG)
+ {
+ ret += sprintf(temp_buf, "attn = %x\n", himax_int_gpio_read(ts_data->pdata->gpio_irq));
+ if(copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n",__func__,__LINE__);
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG=1;
+ }
+ else
+ HX_PROC_SEND_FLAG=0;
+
+ return ret;
+}
+
+
+static struct file_operations himax_proc_attn_ops =
+{
+ .owner = THIS_MODULE,
+ .read = himax_attn_read,
+};
+
+static ssize_t himax_int_en_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ struct himax_ts_data *ts = private_ts;
+ size_t count = 0;
+ char *temp_buf;
+
+ temp_buf = kzalloc(len,GFP_KERNEL);
+
+ if(!HX_PROC_SEND_FLAG)
+ {
+ count += sprintf(temp_buf + count, "%d ", ts->irq_enabled);
+ count += sprintf(temp_buf + count, "\n");
+ if(copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n",__func__,__LINE__);
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG=1;
+ }
+ else
+ HX_PROC_SEND_FLAG=0;
+ return count;
+}
+
+static ssize_t himax_int_en_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+ struct himax_ts_data *ts = private_ts;
+ char buf_tmp[12]= {0};
+ int value, ret=0;
+
+ if (len >= 12)
+ {
+ I("%s: no command exceeds 12 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf_tmp, buff, len))
+ {
+ return -EFAULT;
+ }
+
+ if (buf_tmp[0] == '0')
+ value = false;
+ else if (buf_tmp[0] == '1')
+ value = true;
+ else
+ return -EINVAL;
+
+ if (value)
+ {
+ ret = himax_int_en_set(ts->client);
+ if (ret == 0)
+ {
+ ts->irq_enabled = 1;
+ irq_enable_count = 1;
+ }
+ }
+ else
+ {
+ himax_int_enable(ts->client->irq,0);
+ free_irq(ts->client->irq, ts);
+ ts->irq_enabled = 0;
+ }
+
+ return len;
+}
+
+static struct file_operations himax_proc_int_en_ops =
+{
+ .owner = THIS_MODULE,
+ .read = himax_int_en_read,
+ .write = himax_int_en_write,
+};
+
+static ssize_t himax_layout_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ struct himax_ts_data *ts = private_ts;
+ size_t count = 0;
+ char *temp_buf;
+
+ temp_buf = kzalloc(len,GFP_KERNEL);
+
+ if(!HX_PROC_SEND_FLAG)
+ {
+ count += sprintf(temp_buf + count, "%d ", ts->pdata->abs_x_min);
+ count += sprintf(temp_buf + count, "%d ", ts->pdata->abs_x_max);
+ count += sprintf(temp_buf + count, "%d ", ts->pdata->abs_y_min);
+ count += sprintf(temp_buf + count, "%d ", ts->pdata->abs_y_max);
+ count += sprintf(temp_buf + count, "\n");
+ if(copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n",__func__,__LINE__);
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG=1;
+ }
+ else
+ HX_PROC_SEND_FLAG=0;
+
+ return count;
+}
+
+static ssize_t himax_layout_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+ struct himax_ts_data *ts = private_ts;
+ char buf_tmp[5];
+ int i = 0, j = 0, k = 0, ret;
+ unsigned long value;
+ int layout[4] = {0};
+ char buf[80] = {0};
+
+ if (len >= 80)
+ {
+ I("%s: no command exceeds 80 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf, buff, len))
+ {
+ return -EFAULT;
+ }
+
+ for (i = 0; i < 20; i++)
+ {
+ if (buf[i] == ',' || buf[i] == '\n')
+ {
+ memset(buf_tmp, 0x0, sizeof(buf_tmp));
+ if (i - j <= 5)
+ memcpy(buf_tmp, buf + j, i - j);
+ else
+ {
+ I("buffer size is over 5 char\n");
+ return len;
+ }
+ j = i + 1;
+ if (k < 4)
+ {
+ ret = kstrtoul(buf_tmp, 10, &value);
+ layout[k++] = value;
+ }
+ }
+ }
+ if (k == 4)
+ {
+ ts->pdata->abs_x_min=layout[0];
+ ts->pdata->abs_x_max=layout[1];
+ ts->pdata->abs_y_min=layout[2];
+ ts->pdata->abs_y_max=layout[3];
+ I("%d, %d, %d, %d\n",
+ ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_y_min, ts->pdata->abs_y_max);
+ input_unregister_device(ts->input_dev);
+ himax_input_register(ts);
+ }
+ else
+ I("ERR@%d, %d, %d, %d\n",
+ ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_y_min, ts->pdata->abs_y_max);
+ return len;
+}
+
+static struct file_operations himax_proc_layout_ops =
+{
+ .owner = THIS_MODULE,
+ .read = himax_layout_read,
+ .write = himax_layout_write,
+};
+
+static ssize_t himax_debug_level_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ struct himax_ts_data *ts_data;
+ size_t count = 0;
+ char *temp_buf;
+
+ temp_buf = kzalloc(len,GFP_KERNEL);
+ ts_data = private_ts;
+
+ if(!HX_PROC_SEND_FLAG)
+ {
+ count += sprintf(temp_buf, "%d\n", ts_data->debug_log_level);
+ if(copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n",__func__,__LINE__);
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG = 1;
+ }
+ else
+ HX_PROC_SEND_FLAG=0;
+
+ return count;
+}
+
+static ssize_t himax_debug_level_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+ struct himax_ts_data *ts;
+ char buf_tmp[11];
+ int i;
+ ts = private_ts;
+
+ if (len >= 12)
+ {
+ I("%s: no command exceeds 12 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf_tmp, buff, len))
+ {
+ return -EFAULT;
+ }
+
+ ts->debug_log_level = 0;
+ for(i=0; i<len-1; i++)
+ {
+ if( buf_tmp[i]>='0' && buf_tmp[i]<='9' )
+ ts->debug_log_level |= (buf_tmp[i]-'0');
+ else if( buf_tmp[i]>='A' && buf_tmp[i]<='F' )
+ ts->debug_log_level |= (buf_tmp[i]-'A'+10);
+ else if( buf_tmp[i]>='a' && buf_tmp[i]<='f' )
+ ts->debug_log_level |= (buf_tmp[i]-'a'+10);
+
+ if(i!=len-2)
+ ts->debug_log_level <<= 4;
+ }
+
+ if (ts->debug_log_level & BIT(3))
+ {
+ if (ts->pdata->screenWidth > 0 && ts->pdata->screenHeight > 0 &&
+ (ts->pdata->abs_x_max - ts->pdata->abs_x_min) > 0 &&
+ (ts->pdata->abs_y_max - ts->pdata->abs_y_min) > 0)
+ {
+ ts->widthFactor = (ts->pdata->screenWidth << SHIFTBITS)/(ts->pdata->abs_x_max - ts->pdata->abs_x_min);
+ ts->heightFactor = (ts->pdata->screenHeight << SHIFTBITS)/(ts->pdata->abs_y_max - ts->pdata->abs_y_min);
+ if (ts->widthFactor > 0 && ts->heightFactor > 0)
+ ts->useScreenRes = 1;
+ else
+ {
+ ts->heightFactor = 0;
+ ts->widthFactor = 0;
+ ts->useScreenRes = 0;
+ }
+ }
+ else
+ I("Enable finger debug with raw position mode!\n");
+ }
+ else
+ {
+ ts->useScreenRes = 0;
+ ts->widthFactor = 0;
+ ts->heightFactor = 0;
+ }
+
+ return len;
+}
+
+static struct file_operations himax_proc_debug_level_ops =
+{
+ .owner = THIS_MODULE,
+ .read = himax_debug_level_read,
+ .write = himax_debug_level_write,
+};
+
+#ifdef HX_TP_PROC_REGISTER
+static ssize_t himax_proc_register_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ int ret = 0;
+ uint16_t loop_i;
+ uint8_t data[128];
+ char *temp_buf;
+
+ temp_buf = kzalloc(len,GFP_KERNEL);
+ memset(data, 0x00, sizeof(data));
+
+ if(!HX_PROC_SEND_FLAG)
+ {
+ I("himax_register_show: %02X,%02X,%02X,%02X\n", register_command[3],register_command[2],register_command[1],register_command[0]);
+ himax_register_read(private_ts->client, register_command, 128, data, cfg_flag);
+
+ ret += sprintf(temp_buf, "command: %02X,%02X,%02X,%02X\n", register_command[3],register_command[2],register_command[1],register_command[0]);
+
+ for (loop_i = 0; loop_i < 128; loop_i++)
+ {
+ ret += sprintf(temp_buf + ret, "0x%2.2X ", data[loop_i]);
+ if ((loop_i % 16) == 15)
+ ret += sprintf(temp_buf + ret, "\n");
+ }
+ ret += sprintf(temp_buf + ret, "\n");
+ if(copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n",__func__,__LINE__);
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG=1;
+ }
+ else
+ HX_PROC_SEND_FLAG=0;
+ return ret;
+}
+
+static ssize_t himax_proc_register_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+ char buf[80] = {0};
+ char buf_tmp[16];
+ uint8_t length = 0;
+ unsigned long result = 0;
+ uint8_t loop_i = 0;
+ uint16_t base = 2;
+ char *data_str = NULL;
+ uint8_t w_data[20];
+ uint8_t x_pos[20];
+ uint8_t count = 0;
+
+ if (len >= 80)
+ {
+ I("%s: no command exceeds 80 chars.\n", __func__);
+ return -EFAULT;
+ }
+
+ if (copy_from_user(buf, buff, len))
+ {
+ return -EFAULT;
+ }
+
+ memset(buf_tmp, 0x0, sizeof(buf_tmp));
+ memset(w_data, 0x0, sizeof(w_data));
+ memset(x_pos, 0x0, sizeof(x_pos));
+
+ I("himax %s \n",buf);
+
+ if ((buf[0] == 'r' || buf[0] == 'w') && buf[1] == ':' && buf[2] == 'x')
+ {
+
+ length = strlen(buf);
+
+ //I("%s: length = %d.\n", __func__,length);
+ for (loop_i = 0; loop_i < length; loop_i++) //find postion of 'x'
+ {
+ if(buf[loop_i] == 'x')
+ {
+ x_pos[count] = loop_i;
+ count++;
+ }
+ }
+
+ data_str = strrchr(buf, 'x');
+ I("%s: %s.\n", __func__,data_str);
+ length = strlen(data_str+1) - 1;
+
+ if (buf[0] == 'r')
+ {
+ if (buf[3] == 'F' && buf[4] == 'E' && length == 4)
+ {
+ length = length - base;
+ cfg_flag = true;
+ memcpy(buf_tmp, data_str + base +1, length);
+ }
+ else
+ {
+ cfg_flag = false;
+ memcpy(buf_tmp, data_str + 1, length);
+ }
+
+ byte_length = length/2;
+ if (!kstrtoul(buf_tmp, 16, &result))
+ {
+ for (loop_i = 0 ; loop_i < byte_length ; loop_i++)
+ {
+ register_command[loop_i] = (uint8_t)(result >> loop_i*8);
+ }
+ }
+ }
+ else if (buf[0] == 'w')
+ {
+ if (buf[3] == 'F' && buf[4] == 'E')
+ {
+ cfg_flag = true;
+ memcpy(buf_tmp, buf + base + 3, length);
+ }
+ else
+ {
+ cfg_flag = false;
+ memcpy(buf_tmp, buf + 3, length);
+ }
+ if(count < 3)
+ {
+ byte_length = length/2;
+ if (!kstrtoul(buf_tmp, 16, &result)) //command
+ {
+ for (loop_i = 0 ; loop_i < byte_length ; loop_i++)
+ {
+ register_command[loop_i] = (uint8_t)(result >> loop_i*8);
+ }
+ }
+ if (!kstrtoul(data_str+1, 16, &result)) //data
+ {
+ for (loop_i = 0 ; loop_i < byte_length ; loop_i++)
+ {
+ w_data[loop_i] = (uint8_t)(result >> loop_i*8);
+ }
+ }
+ himax_register_write(private_ts->client, register_command, byte_length, w_data, cfg_flag);
+ }
+ else
+ {
+ byte_length = x_pos[1] - x_pos[0] - 2;
+ for (loop_i = 0; loop_i < count; loop_i++) //parsing addr after 'x'
+ {
+ memcpy(buf_tmp, buf + x_pos[loop_i] + 1, byte_length);
+ //I("%s: buf_tmp = %s\n", __func__,buf_tmp);
+ if (!kstrtoul(buf_tmp, 16, &result))
+ {
+ if(loop_i == 0)
+ {
+ register_command[loop_i] = (uint8_t)(result);
+ //I("%s: register_command = %X\n", __func__,register_command[0]);
+ }
+ else
+ {
+ w_data[loop_i - 1] = (uint8_t)(result);
+ //I("%s: w_data[%d] = %2X\n", __func__,loop_i - 1,w_data[loop_i - 1]);
+ }
+ }
+ }
+
+ byte_length = count - 1;
+ himax_register_write(private_ts->client, register_command, byte_length, &w_data[0], cfg_flag);
+ }
+ }
+ else
+ return len;
+
+ }
+ return len;
+}
+
+static struct file_operations himax_proc_register_ops =
+{
+ .owner = THIS_MODULE,
+ .read = himax_proc_register_read,
+ .write = himax_proc_register_write,
+};
+#endif
+
+#ifdef HX_TP_PROC_DIAG
+int32_t *getMutualBuffer(void)
+{
+ return diag_mutual;
+}
+int32_t *getMutualNewBuffer(void)
+{
+ return diag_mutual_new;
+}
+int32_t *getMutualOldBuffer(void)
+{
+ return diag_mutual_old;
+}
+int32_t *getSelfBuffer(void)
+{
+ return &diag_self[0];
+}
+uint8_t getXChannel(void)
+{
+ return x_channel;
+}
+uint8_t getYChannel(void)
+{
+ return y_channel;
+}
+uint8_t getDiagCommand(void)
+{
+ return g_diag_command;
+}
+void setXChannel(uint8_t x)
+{
+ x_channel = x;
+}
+void setYChannel(uint8_t y)
+{
+ y_channel = y;
+}
+void setMutualBuffer(void)
+{
+ diag_mutual = kzalloc(x_channel * y_channel * sizeof(int32_t), GFP_KERNEL);
+}
+void setMutualNewBuffer(void)
+{
+ diag_mutual_new = kzalloc(x_channel * y_channel * sizeof(int32_t), GFP_KERNEL);
+}
+void setMutualOldBuffer(void)
+{
+ diag_mutual_old = kzalloc(x_channel * y_channel * sizeof(int32_t), GFP_KERNEL);
+}
+
+#ifdef HX_TP_PROC_2T2R
+int32_t *getMutualBuffer_2(void)
+{
+ return diag_mutual_2;
+}
+uint8_t getXChannel_2(void)
+{
+ return x_channel_2;
+}
+uint8_t getYChannel_2(void)
+{
+ return y_channel_2;
+}
+void setXChannel_2(uint8_t x)
+{
+ x_channel_2 = x;
+}
+void setYChannel_2(uint8_t y)
+{
+ y_channel_2 = y;
+}
+void setMutualBuffer_2(void)
+{
+ diag_mutual_2 = kzalloc(x_channel_2 * y_channel_2 * sizeof(int32_t), GFP_KERNEL);
+}
+#endif
+
+#ifdef HX_TP_PROC_DIAG
+int himax_set_diag_cmd(struct himax_ic_data *ic_data,struct himax_report_data *hx_touch_data)
+{
+ int32_t *mutual_data;
+ int32_t *self_data;
+ int mul_num;
+ int self_num;
+ //int RawDataLen = 0;
+
+ hx_touch_data->diag_cmd = getDiagCommand();
+ if (hx_touch_data->diag_cmd >= 1 && hx_touch_data->diag_cmd <= 7)
+ {
+ //Check event stack CRC
+ if(!diag_check_sum(hx_touch_data))
+ {
+ goto bypass_checksum_failed_packet;
+ }
+#ifdef HX_TP_PROC_2T2R
+ if(Is_2T2R && (hx_touch_data->diag_cmd >= 4 && hx_touch_data->diag_cmd <= 6))
+ {
+ mutual_data = getMutualBuffer_2();
+ self_data = getSelfBuffer();
+
+ // initiallize the block number of mutual and self
+ mul_num = getXChannel_2() * getYChannel_2();
+
+#ifdef HX_EN_SEL_BUTTON
+ self_num = getXChannel_2() + getYChannel_2() + ic_data->HX_BT_NUM;
+#else
+ self_num = getXChannel_2() + getYChannel_2();
+#endif
+ }
+ else
+#endif
+ {
+ mutual_data = getMutualBuffer();
+ self_data = getSelfBuffer();
+
+ // initiallize the block number of mutual and self
+ mul_num = getXChannel() * getYChannel();
+
+#ifdef HX_EN_SEL_BUTTON
+ self_num = getXChannel() + getYChannel() + ic_data->HX_BT_NUM;
+#else
+ self_num = getXChannel() + getYChannel();
+#endif
+ }
+
+ diag_parse_raw_data(hx_touch_data,mul_num, self_num,hx_touch_data->diag_cmd, mutual_data,self_data);
+
+ }
+ else if (hx_touch_data->diag_cmd == 8)
+ {
+ memset(diag_coor, 0x00, sizeof(diag_coor));
+ memcpy(&(diag_coor[0]), &hx_touch_data->hx_coord_buf[0], hx_touch_data->touch_info_size);
+ }
+ //assign state info data
+ memcpy(&(hx_state_info[0]), &hx_touch_data->hx_state_info[0], 2);
+
+ return NO_ERR;
+
+bypass_checksum_failed_packet:
+ return 1;
+}
+#endif
+//#if defined(HX_DEBUG_LEVEL)
+void himax_log_touch_data(uint8_t *buf,struct himax_report_data *hx_touch_data)
+{
+ int loop_i = 0;
+ int print_size = 0;
+
+ if(!hx_touch_data->diag_cmd)
+ print_size = hx_touch_data->touch_info_size;
+ else
+ print_size = hx_touch_data->touch_all_size;
+
+ for (loop_i = 0; loop_i < print_size; loop_i+=8)
+ {
+ if((loop_i + 7) >= print_size)
+ {
+ I("%s: over flow\n",__func__);
+ break;
+ }
+ I("P %2d = 0x%2.2X P %2d = 0x%2.2X ", loop_i, buf[loop_i], loop_i + 1, buf[loop_i + 1]);
+ I("P %2d = 0x%2.2X P %2d = 0x%2.2X ", loop_i + 2, buf[loop_i + 2], loop_i + 3, buf[loop_i + 3]);
+ I("P %2d = 0x%2.2X P %2d = 0x%2.2X ", loop_i + 4, buf[loop_i + 4], loop_i + 5, buf[loop_i + 5]);
+ I("P %2d = 0x%2.2X P %2d = 0x%2.2X ", loop_i + 6, buf[loop_i + 6], loop_i + 7, buf[loop_i + 7]);
+ I("\n");
+ }
+}
+void himax_log_touch_event(int x,int y,int w,int loop_i,uint8_t EN_NoiseFilter,int touched)
+{
+ if(touched == HX_FINGER_ON)
+ I("Finger %d=> X:%d, Y:%d W:%d, Z:%d, F:%d, N:%d\n",loop_i + 1, x, y, w, w, loop_i + 1, EN_NoiseFilter);
+ else if(touched == HX_FINGER_LEAVE)
+ I("All Finger leave\n");
+ else
+ I("%s : wrong input!\n",__func__);
+}
+void himax_log_touch_int_devation(int touched)
+{
+
+
+ if(touched == HX_FINGER_ON)
+ {
+ getnstimeofday(&timeStart);
+ /* I(" Irq start time = %ld.%06ld s\n",
+ timeStart.tv_sec, timeStart.tv_nsec/1000); */
+ }
+ else if(touched == HX_FINGER_LEAVE)
+ {
+ getnstimeofday(&timeEnd);
+ timeDelta.tv_nsec = (timeEnd.tv_sec*1000000000+timeEnd.tv_nsec) - (timeStart.tv_sec*1000000000+timeStart.tv_nsec);
+ /*I("Irq finish time = %ld.%06ld s\n",
+ timeEnd.tv_sec, timeEnd.tv_nsec/1000);*/
+ I("Touch latency = %ld us\n", timeDelta.tv_nsec/1000);
+ }
+ else
+ I("%s : wrong input!\n",__func__);
+}
+void himax_log_touch_event_detail(struct himax_ts_data *ts,int x,int y,int w,int loop_i,uint8_t EN_NoiseFilter,int touched,uint16_t old_finger)
+{
+
+ if (touched == HX_FINGER_ON)
+ {
+ if (old_finger >> loop_i == 0)
+ {
+ if (ts->useScreenRes)
+ {
+ I("status: Screen:F:%02d Down, X:%d, Y:%d, W:%d, N:%d\n",
+ loop_i+1, x * ts->widthFactor >> SHIFTBITS,
+ y * ts->heightFactor >> SHIFTBITS, w, EN_NoiseFilter);
+ }
+ else
+ {
+ I("status: Raw:F:%02d Down, X:%d, Y:%d, W:%d, N:%d\n",
+ loop_i+1, x, y, w, EN_NoiseFilter);
+ }
+ }
+ }
+ else if(touched == HX_FINGER_LEAVE)//if (old_finger >> loop_i == 1)
+ {
+ if (old_finger >> loop_i == 1)
+ {
+ if (ts->useScreenRes)
+ {
+ I("status: Screen:F:%02d Up, X:%d, Y:%d, N:%d\n",
+ loop_i+1, ts->pre_finger_data[loop_i][0] * ts->widthFactor >> SHIFTBITS,
+ ts->pre_finger_data[loop_i][1] * ts->heightFactor >> SHIFTBITS, EN_NoiseFilter); //Last_EN_NoiseFilter
+ }
+ else
+ {
+ I("status: Raw:F:%02d Up, X:%d, Y:%d, N:%d\n",
+ loop_i+1, ts->pre_finger_data[loop_i][0],
+ ts->pre_finger_data[loop_i][1], EN_NoiseFilter); //Last_EN_NoiseFilter
+ }
+ }
+ }
+ else
+ {
+ I("%s : wrong input!\n",__func__);
+ }
+}
+//#endif
+static ssize_t himax_diag_arrange_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+
+ char buf[80] = {0};
+
+ if (len >= 80)
+ {
+ I("%s: no command exceeds 80 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf, buff, len))
+ {
+ return -EFAULT;
+ }
+
+ g_diag_arr_num = buf[0] - '0';
+ I("%s: g_diag_arr_num = %d \n", __func__,g_diag_arr_num);
+
+ return len;
+}
+
+void himax_get_mutual_edge(void)
+{
+ int i = 0;
+ for(i = 0; i < (x_channel * y_channel); i++)
+ {
+ if(diag_mutual[i] > g_max_mutual)
+ g_max_mutual = diag_mutual[i];
+ if(diag_mutual[i] < g_min_mutual)
+ g_min_mutual = diag_mutual[i];
+ }
+}
+
+void himax_get_self_edge(void)
+{
+ int i = 0;
+ for(i = 0; i < (x_channel + y_channel); i++)
+ {
+ if(diag_self[i] > g_max_self)
+ g_max_self = diag_self[i];
+ if(diag_self[i] < g_min_self)
+ g_min_self = diag_self[i];
+ }
+}
+
+/* print first step which is row */
+static struct file_operations himax_proc_diag_arrange_ops =
+{
+ .owner = THIS_MODULE,
+ .write = himax_diag_arrange_write,
+};
+static void print_state_info(struct seq_file *s)
+{
+ //seq_printf(s, "State_info_2bytes:%3d, %3d\n",hx_state_info[0],hx_state_info[1]);
+ seq_printf(s, "ReCal = %d\t",hx_state_info[0] & 0x01);
+ seq_printf(s, "Palm = %d\t",hx_state_info[0]>>1 & 0x01);
+ seq_printf(s, "AC mode = %d\t",hx_state_info[0]>>2 & 0x01);
+ seq_printf(s, "Water = %d\n",hx_state_info[0]>>3 & 0x01);
+ seq_printf(s, "Glove = %d\t",hx_state_info[0]>>4 & 0x01);
+ seq_printf(s, "TX Hop = %d\t",hx_state_info[0]>>5 & 0x01 );
+ seq_printf(s, "Base Line = %d\t",hx_state_info[0]>>6 & 0x01);
+ seq_printf(s, "OSR Hop = %d\t",hx_state_info[1]>>3 & 0x01);
+ seq_printf(s, "KEY = %d\n",hx_state_info[1]>>4 & 0x0F);
+}
+
+static void himax_diag_arrange_print(struct seq_file *s, int i, int j, int transpose)
+{
+
+ if(transpose)
+ seq_printf(s, "%6d", diag_mutual[ j + i*x_channel]);
+ else
+ seq_printf(s, "%6d", diag_mutual[ i + j*x_channel]);
+}
+
+/* ready to print second step which is column*/
+static void himax_diag_arrange_inloop(struct seq_file *s, int in_init,int out_init,bool transpose, int j)
+{
+ int i;
+ int in_max = 0;
+
+ if(transpose)
+ in_max = y_channel;
+ else
+ in_max = x_channel;
+
+ if (in_init > 0) //bit0 = 1
+ {
+ for(i = in_init-1; i >= 0; i--)
+ {
+ himax_diag_arrange_print(s, i, j, transpose);
+ }
+ if(transpose)
+ {
+ if(out_init > 0)
+ seq_printf(s, " %5d\n", diag_self[j]);
+ else
+ seq_printf(s, " %5d\n", diag_self[x_channel - j - 1]);
+ }
+ }
+ else //bit0 = 0
+ {
+ for (i = 0; i < in_max; i++)
+ {
+ himax_diag_arrange_print(s, i, j, transpose);
+ }
+ if(transpose)
+ {
+ if(out_init > 0)
+ seq_printf(s, " %5d\n", diag_self[x_channel - j - 1]);
+ else
+ seq_printf(s, " %5d\n", diag_self[j]);
+ }
+ }
+}
+
+/* print first step which is row */
+static void himax_diag_arrange_outloop(struct seq_file *s, int transpose, int out_init, int in_init)
+{
+ int j;
+ int out_max = 0;
+ int self_cnt = 0;
+
+ if(transpose)
+ out_max = x_channel;
+ else
+ out_max = y_channel;
+
+ if(out_init > 0) //bit1 = 1
+ {
+ self_cnt = 1;
+ for(j = out_init-1; j >= 0; j--)
+ {
+ seq_printf(s, "%3c%02d%c",'[', j + 1,']');
+ himax_diag_arrange_inloop(s, in_init, out_init, transpose, j);
+ if(!transpose)
+ {
+ seq_printf(s, " %5d\n", diag_self[y_channel + x_channel - self_cnt]);
+ self_cnt++;
+ }
+ }
+ }
+ else //bit1 = 0
+ {
+ //self_cnt = x_channel;
+ for(j = 0; j < out_max; j++)
+ {
+ seq_printf(s, "%3c%02d%c",'[', j + 1,']');
+ himax_diag_arrange_inloop(s, in_init, out_init, transpose, j);
+ if(!transpose)
+ {
+ seq_printf(s, " %5d\n", diag_self[j + x_channel]);
+ }
+ }
+ }
+}
+
+/* determin the output format of diag */
+static void himax_diag_arrange(struct seq_file *s)
+{
+ int bit2,bit1,bit0;
+ int i;
+
+ /* rotate bit */
+ bit2 = g_diag_arr_num >> 2;
+ /* reverse Y */
+ bit1 = g_diag_arr_num >> 1 & 0x1;
+ /* reverse X */
+ bit0 = g_diag_arr_num & 0x1;
+
+ if (g_diag_arr_num < 4)
+ {
+ for (i = 0 ; i <= x_channel; i++)
+ seq_printf(s, "%3c%02d%c",'[', i,']');
+ seq_printf(s,"\n");
+ himax_diag_arrange_outloop(s, bit2, bit1 * y_channel, bit0 * x_channel);
+ seq_printf(s, "%6c",' ');
+ if(bit0 == 1)
+ {
+ for (i = x_channel - 1; i >= 0; i--)
+ seq_printf(s, "%6d", diag_self[i]);
+ }
+ else
+ {
+ for (i = 0; i < x_channel; i++)
+ seq_printf(s, "%6d", diag_self[i]);
+ }
+ }
+ else
+ {
+ for (i = 0 ; i <= y_channel; i++)
+ seq_printf(s, "%3c%02d%c",'[', i,']');
+ seq_printf(s,"\n");
+ himax_diag_arrange_outloop(s, bit2, bit1 * x_channel, bit0 * y_channel);
+ seq_printf(s, "%6c",' ');
+ if(bit1 == 1)
+ {
+ for (i = x_channel + y_channel - 1; i >= x_channel; i--)
+ {
+ seq_printf(s, "%6d", diag_self[i]);
+ }
+ }
+ else
+ {
+ for (i = x_channel; i < x_channel + y_channel; i++)
+ {
+ seq_printf(s, "%6d", diag_self[i]);
+ }
+ }
+ }
+}
+
+static void *himax_diag_seq_start(struct seq_file *s, loff_t *pos)
+{
+ if (*pos>=1) return NULL;
+ return (void *)((unsigned long) *pos+1);
+}
+
+static void *himax_diag_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+ return NULL;
+}
+static void himax_diag_seq_stop(struct seq_file *s, void *v)
+{
+}
+static int himax_diag_seq_read(struct seq_file *s, void *v)
+{
+ size_t count = 0;
+ uint32_t loop_i;
+ uint16_t mutual_num, self_num, width;
+ int dsram_type = 0;
+
+ dsram_type = g_diag_command/10;
+
+#ifdef HX_TP_PROC_2T2R
+ if(Is_2T2R &&(g_diag_command >= 4 && g_diag_command <= 6))
+ {
+ mutual_num = x_channel_2 * y_channel_2;
+ self_num = x_channel_2 + y_channel_2; //don't add KEY_COUNT
+ width = x_channel_2;
+ seq_printf(s, "ChannelStart: %4d, %4d\n\n", x_channel_2, y_channel_2);
+ }
+ else
+#endif
+ {
+ mutual_num = x_channel * y_channel;
+ self_num = x_channel + y_channel; //don't add KEY_COUNT
+ width = x_channel;
+ seq_printf(s, "ChannelStart: %4d, %4d\n\n", x_channel, y_channel);
+ }
+
+ // start to show out the raw data in adb shell
+ if ((g_diag_command >= 1 && g_diag_command <= 3) || (g_diag_command == 7))
+ {
+ himax_diag_arrange(s);
+ seq_printf(s, "\n");
+#ifdef HX_EN_SEL_BUTTON
+ seq_printf(s, "\n");
+ for (loop_i = 0; loop_i < ic_data->HX_BT_NUM; loop_i++)
+ seq_printf(s, "%6d", diag_self[ic_data->HX_RX_NUM + ic_data->HX_TX_NUM + loop_i]);
+#endif
+ seq_printf(s, "ChannelEnd");
+ seq_printf(s, "\n");
+ }
+#ifdef HX_TP_PROC_2T2R
+ else if(Is_2T2R && g_diag_command >= 4 && g_diag_command <= 6)
+ {
+ for (loop_i = 0; loop_i < mutual_num; loop_i++)
+ {
+ seq_printf(s, "%4d", diag_mutual_2[loop_i]);
+ if ((loop_i % width) == (width - 1))
+ seq_printf(s, " %4d\n", diag_self[width + loop_i/width]);
+ }
+ seq_printf(s, "\n");
+ for (loop_i = 0; loop_i < width; loop_i++)
+ {
+ seq_printf(s, "%4d", diag_self[loop_i]);
+ if (((loop_i) % width) == (width - 1))
+ seq_printf(s, "\n");
+ }
+
+#ifdef HX_EN_SEL_BUTTON
+ seq_printf(s, "\n");
+ for (loop_i = 0; loop_i < HX_BT_NUM; loop_i++)
+ seq_printf(s, "%4d", diag_self[ic_data->HX_RX_NUM_2 + ic_data->HX_TX_NUM_2 + loop_i]);
+#endif
+ seq_printf(s, "ChannelEnd");
+ seq_printf(s, "\n");
+ }
+#endif
+ else if (g_diag_command == 8)
+ {
+ for (loop_i = 0; loop_i < 128 ; loop_i++)
+ {
+ if ((loop_i % 16) == 0)
+ seq_printf(s, "LineStart:");
+ seq_printf(s, "%4x", diag_coor[loop_i]);
+ if ((loop_i % 16) == 15)
+ seq_printf(s, "\n");
+ }
+ }
+ else if (dsram_type > 0 && dsram_type <= 8)
+ {
+ himax_diag_arrange(s);
+ seq_printf(s, "ChannelEnd");
+ seq_printf(s, "\n");
+ }
+ if((g_diag_command >= 1 && g_diag_command <= 7) || dsram_type > 0)
+ {
+ /* print Mutual/Slef Maximum and Minimum */
+ himax_get_mutual_edge();
+ himax_get_self_edge();
+ seq_printf(s, "Mutual Max:%3d, Min:%3d\n",g_max_mutual,g_min_mutual);
+ seq_printf(s, "Self Max:%3d, Min:%3d\n",g_max_self,g_min_self);
+
+ /* recovery status after print*/
+ g_max_mutual = 0;
+ g_min_mutual = 255;
+ g_max_self = 0;
+ g_min_self = 255;
+ }
+ /*pring state info*/
+ print_state_info(s);
+ return count;
+}
+static struct seq_operations himax_diag_seq_ops =
+{
+ .start = himax_diag_seq_start,
+ .next = himax_diag_seq_next,
+ .stop = himax_diag_seq_stop,
+ .show = himax_diag_seq_read,
+};
+static int himax_diag_proc_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &himax_diag_seq_ops);
+};
+bool DSRAM_Flag = false;
+
+//DSRAM thread
+void himax_ts_diag_func(void)
+{
+ int i=0, j=0;
+ unsigned int index = 0;
+ int total_size = ic_data->HX_TX_NUM * ic_data->HX_RX_NUM * 2;
+ uint8_t info_data[total_size];
+ int32_t *mutual_data;
+ int32_t *mutual_data_new;
+ int32_t *mutual_data_old;
+ int32_t new_data;
+ /* 1:common dsram,2:100 frame Max,3:N-(N-1)frame */
+ int dsram_type = 0;
+ char temp_buf[20];
+ char write_buf[total_size*3];
+
+ mutual_data = NULL;
+ mutual_data_new = NULL;
+ mutual_data_old = NULL;
+ memset(write_buf, '\0', sizeof(write_buf));
+
+ dsram_type = g_diag_command/10;
+
+ I("%s:Entering g_diag_command=%d\n!",__func__,g_diag_command);
+
+ if(dsram_type == 8)
+ {
+ dsram_type = 1;
+ I("%s Sorting Mode run sram type1 ! \n",__func__);
+ }
+
+ himax_burst_enable(private_ts->client, 1);
+ if(dsram_type == 1 || dsram_type == 2 || dsram_type == 4)
+ {
+ mutual_data = getMutualBuffer();
+ }
+ else if(dsram_type == 3)
+ {
+ mutual_data = getMutualBuffer();
+ mutual_data_new = getMutualNewBuffer();
+ mutual_data_old = getMutualOldBuffer();
+ }
+ himax_get_DSRAM_data(private_ts->client, info_data);
+
+ index = 0;
+ for (i = 0; i < ic_data->HX_TX_NUM; i++)
+ {
+ for (j = 0; j < ic_data->HX_RX_NUM; j++)
+ {
+ new_data = (info_data[index + 1] << 8 | info_data[index]);
+ if(dsram_type == 1 || dsram_type == 4)
+ {
+ mutual_data[i*ic_data->HX_RX_NUM+j] = new_data;
+ }
+ else if(dsram_type == 2)
+ {
+ //Keep max data for 100 frame
+ if(mutual_data[i * ic_data->HX_RX_NUM + j] < new_data)
+ mutual_data[i * ic_data->HX_RX_NUM + j] = new_data;
+ }
+ else if(dsram_type == 3)
+ {
+ //Cal data for [N]-[N-1] frame
+ mutual_data_new[i * ic_data->HX_RX_NUM + j] = new_data;
+ mutual_data[i * ic_data->HX_RX_NUM + j] = mutual_data_new[i * ic_data->HX_RX_NUM + j] - mutual_data_old[i * ic_data->HX_RX_NUM + j];
+ }
+ index += 2;
+ }
+ }
+ if(dsram_type == 3)
+ {
+ memcpy(mutual_data_old,mutual_data_new,x_channel * y_channel * sizeof(int16_t)); //copy N data to N-1 array
+ }
+ diag_max_cnt++;
+ if(dsram_type == 1 || dsram_type == 3 )
+ {
+ queue_delayed_work(private_ts->himax_diag_wq, &private_ts->himax_diag_delay_wrok, 1/10*HZ);
+ }
+ else if(dsram_type == 4)
+ {
+ for(i = 0; i < x_channel * y_channel; i++)
+ {
+ memset(temp_buf, '\0', sizeof(temp_buf));
+ if(i == (x_channel * y_channel - 1))
+ snprintf(temp_buf, sizeof(temp_buf), "%4d\n\n", mutual_data[i]);
+ //I("%s :temp_buf = %s\n",__func__,temp_buf);
+ else if(i % x_channel == (x_channel - 1))
+ snprintf(temp_buf, sizeof(temp_buf), "%4d\n", mutual_data[i]);
+ else
+ snprintf(temp_buf, sizeof(temp_buf), "%4d\t", mutual_data[i]);
+ //I("%s :mutual_data[%d] = %d, temp_buf = %s\n",__func__, i, mutual_data[i], temp_buf);
+ strcat(write_buf, temp_buf);
+ }
+
+ //save raw data in file
+ if (!IS_ERR(diag_sram_fn))
+ {
+ I("%s create file and ready to write\n",__func__);
+ diag_sram_fn->f_op->write(diag_sram_fn, write_buf, sizeof(write_buf), &diag_sram_fn->f_pos);
+ write_counter++;
+ if(write_counter < write_max_count)
+ queue_delayed_work(private_ts->himax_diag_wq, &private_ts->himax_diag_delay_wrok, 1/10*HZ);
+ else
+ {
+ filp_close(diag_sram_fn,NULL);
+ write_counter = 0;
+ }
+ }
+ }
+ else if(dsram_type == 2)
+ {
+ if(diag_max_cnt > 100) //count for 100 frame
+ {
+ //Clear DSRAM flag
+ DSRAM_Flag = false;
+
+ //Enable ISR
+ himax_int_enable(private_ts->client->irq,1);
+
+ //=====================================
+ // test result command : 0x8002_0324 ==> 0x00
+ //=====================================
+ himax_diag_register_set(private_ts->client, 0x00);
+ }
+ else
+ {
+ queue_delayed_work(private_ts->himax_diag_wq, &private_ts->himax_diag_delay_wrok, 1/10*HZ);
+ }
+ }
+}
+
+static ssize_t himax_diag_write(struct file *filp, const char __user *buff, size_t len, loff_t *data)
+{
+ char messages[80] = {0};
+
+ uint8_t command[2] = {0x00, 0x00};
+ uint8_t receive[1];
+
+ /* 0: common , other: dsram*/
+ int storage_type = 0;
+ /* 1:IIR,2:DC,3:Bank,4:IIR2,5:IIR2_N,6:FIR2,7:Baseline,8:dump coord */
+ int rawdata_type = 0;
+
+ memset(receive, 0x00, sizeof(receive));
+
+ if (len >= 80)
+ {
+ I("%s: no command exceeds 80 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(messages, buff, len))
+ {
+ return -EFAULT;
+ }
+
+ I("%s:g_switch_mode = %d\n",__func__,g_switch_mode);
+
+ if (messages[1] == 0x0A)
+ {
+ g_diag_command =messages[0] - '0';
+ }
+ else
+ {
+ g_diag_command =(messages[0] - '0')*10 + (messages[1] - '0');
+ }
+
+ storage_type = himax_determin_diag_storage(g_diag_command);
+ rawdata_type = himax_determin_diag_rawdata(g_diag_command);
+
+ if(g_diag_command > 0 && rawdata_type == 0)
+ {
+ I("[Himax]g_diag_command=0x%x ,storage_type=%d, rawdata_type=%d! Maybe no support!\n"
+ ,g_diag_command,storage_type,rawdata_type);
+ g_diag_command = 0x00;
+ }
+ else
+ I("[Himax]g_diag_command=0x%x ,storage_type=%d, rawdata_type=%d\n",g_diag_command,storage_type,rawdata_type);
+
+ if (storage_type == 0 && rawdata_type > 0 && rawdata_type < 8)
+ {
+ I("%s,common\n",__func__);
+ if(DSRAM_Flag)
+ {
+ //1. Clear DSRAM flag
+ DSRAM_Flag = false;
+ //2. Stop DSRAM thread
+ cancel_delayed_work(&private_ts->himax_diag_delay_wrok);
+ //3. Enable ISR
+ himax_int_enable(private_ts->client->irq,1);
+
+ /*(4) FW leave sram and return to event stack*/
+ himax_return_event_stack(private_ts->client);
+ }
+
+ if(g_switch_mode == 2)
+ {
+ himax_idle_mode(private_ts->client,0);
+ g_switch_mode = himax_switch_mode(private_ts->client,0);
+ }
+
+ if(g_diag_command == 0x04)
+ {
+#if defined(HX_TP_PROC_2T2R)
+ command[0] = g_diag_command;
+#else
+ g_diag_command = 0x00;
+ command[0] = 0x00;
+#endif
+ }
+ else
+ command[0] = g_diag_command;
+ himax_diag_register_set(private_ts->client, command[0]);
+ }
+ else if (storage_type > 0 && storage_type < 8 && rawdata_type > 0 && rawdata_type < 8)
+ {
+ I("%s,dsram\n",__func__);
+
+ diag_max_cnt = 0;
+ memset(diag_mutual, 0x00, x_channel * y_channel * sizeof(int32_t)); //Set data 0 everytime
+
+ //0. set diag flag
+ if(DSRAM_Flag)
+ {
+ //(1) Clear DSRAM flag
+ DSRAM_Flag = false;
+
+ //(2) Stop DSRAM thread
+ cancel_delayed_work(&private_ts->himax_diag_delay_wrok);
+ //(3) Enable ISR
+ himax_int_enable(private_ts->client->irq,1);
+
+ /*(4) FW leave sram and return to event stack*/
+ himax_return_event_stack(private_ts->client);
+ }
+ /* close sorting if turn on*/
+ if(g_switch_mode == 2)
+ {
+ himax_idle_mode(private_ts->client,0);
+ g_switch_mode = himax_switch_mode(private_ts->client,0);
+ }
+
+ switch(rawdata_type)
+ {
+ case 1:
+ command[0] = 0x09; //IIR
+ break;
+ case 2:
+ command[0] = 0x0A; //RAWDATA
+ break;
+ case 7:
+ command[0] = 0x0B; //DC
+ break;
+ default:
+ command[0] = 0x00;
+ E("%s: Sram no support this type !\n",__func__);
+ break;
+ }
+ himax_diag_register_set(private_ts->client, command[0]);
+
+ //1. Disable ISR
+ himax_int_enable(private_ts->client->irq,0);
+
+ //Open file for save raw data log
+ if (storage_type == 4)
+ {
+ switch (rawdata_type)
+ {
+ case 1:
+ diag_sram_fn = filp_open(IIR_DUMP_FILE,O_CREAT | O_WRONLY,0);
+ break;
+ case 2:
+ diag_sram_fn = filp_open(DC_DUMP_FILE,O_CREAT | O_WRONLY,0);
+ break;
+ case 3:
+ diag_sram_fn = filp_open(BANK_DUMP_FILE,O_CREAT | O_WRONLY,0);
+ break;
+ default:
+ I("%s raw data type is not true. raw data type is %d \n",__func__, rawdata_type);
+ }
+ }
+
+ //2. Start DSRAM thread
+ queue_delayed_work(private_ts->himax_diag_wq, &private_ts->himax_diag_delay_wrok, 2*HZ/100);
+
+ I("%s: Start get raw data in DSRAM\n", __func__);
+ if (storage_type == 4)
+ msleep(6000);
+ //3. Set DSRAM flag
+ DSRAM_Flag = true;
+
+
+ }
+ else if(storage_type == 8)
+ {
+ I("Soritng mode!\n");
+
+ if(DSRAM_Flag)
+ {
+ //1. Clear DSRAM flag
+ DSRAM_Flag = false;
+ //2. Stop DSRAM thread
+ cancel_delayed_work(&private_ts->himax_diag_delay_wrok);
+ //3. Enable ISR
+ himax_int_enable(private_ts->client->irq,1);
+
+ /*(4) FW leave sram and return to event stack*/
+ himax_return_event_stack(private_ts->client);
+ }
+
+ himax_idle_mode(private_ts->client,1);
+ g_switch_mode = himax_switch_mode(private_ts->client,1);
+ if(g_switch_mode == 2)
+ {
+ if(rawdata_type == 1)
+ command[0] = 0x09; //IIR
+ else if(rawdata_type == 2)
+ command[0] = 0x0A; //DC
+ else if(rawdata_type == 7)
+ command[0] = 0x08; //BASLINE
+ else
+ {
+ command[0] = 0x00;
+ E("%s: Now Sorting Mode does not support this command=%d\n",__func__,g_diag_command);
+ }
+ himax_diag_register_set(private_ts->client, command[0]);
+ }
+
+ queue_delayed_work(private_ts->himax_diag_wq, &private_ts->himax_diag_delay_wrok, 2*HZ/100);
+ DSRAM_Flag = true;
+
+ }
+ else
+ {
+ //set diag flag
+ if(DSRAM_Flag)
+ {
+ I("return and cancel sram thread!\n");
+ //(1) Clear DSRAM flag
+ DSRAM_Flag = false;
+
+ //(2) Stop DSRAM thread
+ cancel_delayed_work(&private_ts->himax_diag_delay_wrok);
+ //(3) Enable ISR
+ himax_int_enable(private_ts->client->irq,1);
+
+ /*(4) FW leave sram and return to event stack*/
+ himax_return_event_stack(private_ts->client);
+ }
+
+ if(g_switch_mode == 2)
+ {
+ himax_idle_mode(private_ts->client,0);
+ g_switch_mode = himax_switch_mode(private_ts->client,0);
+ }
+
+ if(g_diag_command != 0x00)
+ {
+
+ E("[Himax]g_diag_command error!diag_command=0x%x so reset\n",g_diag_command);
+ command[0] = 0x00;
+ if(g_diag_command != 0x08)
+ g_diag_command = 0x00;
+ himax_diag_register_set(private_ts->client, command[0]);
+ }
+ else
+ {
+ command[0] = 0x00;
+ g_diag_command = 0x00;
+ himax_diag_register_set(private_ts->client, command[0]);
+ I("return to normal g_diag_command=0x%x\n",g_diag_command);
+ }
+ }
+ return len;
+}
+
+static struct file_operations himax_proc_diag_ops =
+{
+ .owner = THIS_MODULE,
+ .open = himax_diag_proc_open,
+ .read = seq_read,
+ .write = himax_diag_write,
+};
+#endif
+
+#ifdef HX_TP_PROC_RESET
+static ssize_t himax_reset_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+ char buf_tmp[12];
+
+ if (len >= 12)
+ {
+ I("%s: no command exceeds 12 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf_tmp, buff, len))
+ {
+ return -EFAULT;
+ }
+#ifdef HX_RST_PIN_FUNC
+ if (buf_tmp[0] == '1')
+ himax_ic_reset(false,false);
+ else if (buf_tmp[0] == '2')
+ himax_ic_reset(false,true);
+ else if (buf_tmp[0] == '3')
+ himax_ic_reset(true,false);
+ else if (buf_tmp[0] == '4')
+ himax_ic_reset(true,true);
+ //else if (buf_tmp[0] == '5')
+ // ESD_HW_REST();
+#endif
+ return len;
+}
+
+static struct file_operations himax_proc_reset_ops =
+{
+ .owner = THIS_MODULE,
+ .write = himax_reset_write,
+};
+#endif
+
+#ifdef HX_TP_PROC_DEBUG
+static ssize_t himax_debug_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ size_t count = 0;
+ char *temp_buf;
+
+ temp_buf = kzalloc(len,GFP_KERNEL);
+
+ if(!HX_PROC_SEND_FLAG)
+ {
+ if (debug_level_cmd == 't')
+ {
+ if (fw_update_complete)
+ {
+ count += sprintf(temp_buf, "FW Update Complete ");
+ }
+ else
+ {
+ count += sprintf(temp_buf, "FW Update Fail ");
+ }
+ }
+ else if (debug_level_cmd == 'h')
+ {
+ if (handshaking_result == 0)
+ {
+ count += sprintf(temp_buf, "Handshaking Result = %d (MCU Running)\n",handshaking_result);
+ }
+ else if (handshaking_result == 1)
+ {
+ count += sprintf(temp_buf, "Handshaking Result = %d (MCU Stop)\n",handshaking_result);
+ }
+ else if (handshaking_result == 2)
+ {
+ count += sprintf(temp_buf, "Handshaking Result = %d (I2C Error)\n",handshaking_result);
+ }
+ else
+ {
+ count += sprintf(temp_buf, "Handshaking Result = error \n");
+ }
+ }
+ else if (debug_level_cmd == 'v')
+ {
+ count += sprintf(temp_buf + count, "FW_VER = 0x%2.2X \n",ic_data->vendor_fw_ver);
+
+ if(IC_TYPE < 8)
+ count += sprintf(temp_buf + count, "CONFIG_VER = 0x%2.2X \n",ic_data->vendor_config_ver);
+ else
+ {
+ count += sprintf(temp_buf + count, "TOUCH_VER = 0x%2.2X \n",ic_data->vendor_touch_cfg_ver);
+ count += sprintf(temp_buf + count, "DISPLAY_VER = 0x%2.2X \n",ic_data->vendor_display_cfg_ver);
+ }
+ if(ic_data->vendor_cid_maj_ver < 0 && ic_data->vendor_cid_min_ver < 0)
+ count += sprintf(temp_buf + count, "CID_VER = NULL\n");
+ else
+ count += sprintf(temp_buf + count, "CID_VER = 0x%2.2X \n",(ic_data->vendor_cid_maj_ver << 8 | ic_data->vendor_cid_min_ver));
+
+ if(ic_data->vendor_panel_ver < 0)
+ count += sprintf(temp_buf + count, "PANEL_VER = NULL\n");
+ else
+ count += sprintf(temp_buf + count, "PANEL_VER = 0x%2.2X \n",ic_data->vendor_panel_ver);
+
+ count += sprintf(temp_buf + count, "\n");
+
+ count += sprintf(temp_buf + count, "Himax Touch Driver Version:\n");
+ count += sprintf(temp_buf + count, "%s \n", HIMAX_DRIVER_VER);
+ }
+ else if (debug_level_cmd == 'd')
+ {
+ count += sprintf(temp_buf + count, "Himax Touch IC Information :\n");
+ switch(IC_TYPE)
+ {
+ case HX_85XX_D_SERIES_PWON:
+ count += sprintf(temp_buf + count, "IC Type : HX852xD\n");
+ break;
+ case HX_85XX_E_SERIES_PWON:
+ count += sprintf(temp_buf + count, "IC Type : HX852xE\n");
+ break;
+ case HX_85XX_ES_SERIES_PWON:
+ count += sprintf(temp_buf + count, "IC Type : HX852xES\n");
+ break;
+ case HX_85XX_F_SERIES_PWON:
+ count += sprintf(temp_buf + count, "IC Type : HX852xF\n");
+ break;
+ case HX_83100A_SERIES_PWON:
+ count += sprintf(temp_buf + count, "IC Type : HX83100A\n");
+ break;
+ case HX_83102A_SERIES_PWON:
+ count += sprintf(temp_buf + count, "IC Type : HX83102A\n");
+ break;
+ case HX_83102B_SERIES_PWON:
+ count += sprintf(temp_buf + count, "IC Type : HX83102B\n");
+ break;
+ case HX_83110A_SERIES_PWON:
+ count += sprintf(temp_buf + count, "IC Type : HX83110A\n");
+ break;
+ case HX_83110B_SERIES_PWON:
+ count += sprintf(temp_buf + count, "IC Type : HX83110B\n");
+ break;
+ case HX_83111B_SERIES_PWON:
+ count += sprintf(temp_buf + count, "IC Type : HX83111B\n");
+ break;
+ case HX_83112A_SERIES_PWON:
+ count += sprintf(temp_buf + count, "IC Type : HX83112A\n");
+ break;
+ case HX_83112B_SERIES_PWON:
+ count += sprintf(temp_buf + count, "IC Type : HX83112B\n");
+ break;
+ default:
+ count += sprintf(temp_buf + count, "IC Type error.\n");
+ }
+ switch(IC_CHECKSUM)
+ {
+ case HX_TP_BIN_CHECKSUM_SW:
+ count += sprintf(temp_buf + count, "IC Checksum : SW\n");
+ break;
+ case HX_TP_BIN_CHECKSUM_HW:
+ count += sprintf(temp_buf + count, "IC Checksum : HW\n");
+ break;
+ case HX_TP_BIN_CHECKSUM_CRC:
+ count += sprintf(temp_buf + count, "IC Checksum : CRC\n");
+ break;
+ default:
+ count += sprintf(temp_buf + count, "IC Checksum error.\n");
+ }
+
+ if (ic_data->HX_INT_IS_EDGE)
+ {
+ count += sprintf(temp_buf + count, "Driver register Interrupt : EDGE TIRGGER\n");
+ }
+ else
+ {
+ count += sprintf(temp_buf + count, "Driver register Interrupt : LEVEL TRIGGER\n");
+ }
+ if (private_ts->protocol_type == PROTOCOL_TYPE_A)
+ {
+ count += sprintf(temp_buf + count, "Protocol : TYPE_A\n");
+ }
+ else
+ {
+ count += sprintf(temp_buf + count, "Protocol : TYPE_B\n");
+ }
+ count += sprintf(temp_buf + count, "RX Num : %d\n",ic_data->HX_RX_NUM);
+ count += sprintf(temp_buf + count, "TX Num : %d\n",ic_data->HX_TX_NUM);
+ count += sprintf(temp_buf + count, "BT Num : %d\n",ic_data->HX_BT_NUM);
+ count += sprintf(temp_buf + count, "X Resolution : %d\n",ic_data->HX_X_RES);
+ count += sprintf(temp_buf + count, "Y Resolution : %d\n",ic_data->HX_Y_RES);
+ count += sprintf(temp_buf + count, "Max Point : %d\n",ic_data->HX_MAX_PT);
+ count += sprintf(temp_buf + count, "XY reverse : %d\n",ic_data->HX_XY_REVERSE);
+#ifdef HX_TP_PROC_2T2R
+ if(Is_2T2R)
+ {
+ count += sprintf(temp_buf + count, "2T2R panel\n");
+ count += sprintf(temp_buf + count, "RX Num_2 : %d\n",HX_RX_NUM_2);
+ count += sprintf(temp_buf + count, "TX Num_2 : %d\n",HX_TX_NUM_2);
+ }
+#endif
+ }
+ else if (debug_level_cmd == 'i')
+ {
+ if(himax_read_i2c_status(private_ts->client))
+ count += sprintf(temp_buf + count, "I2C communication is bad.\n");
+ else
+ count += sprintf(temp_buf + count, "I2C communication is good.\n");
+ }
+ else if (debug_level_cmd == 'n')
+ {
+ if(himax_read_ic_trigger_type(private_ts->client) == 1) //Edgd = 1, Level = 0
+ count += sprintf(temp_buf + count, "IC Interrupt type is edge trigger.\n");
+ else if(himax_read_ic_trigger_type(private_ts->client) == 0)
+ count += sprintf(temp_buf + count, "IC Interrupt type is level trigger.\n");
+ else
+ count += sprintf(temp_buf + count, "Unkown IC trigger type.\n");
+ if (ic_data->HX_INT_IS_EDGE)
+ count += sprintf(temp_buf + count, "Driver register Interrupt : EDGE TIRGGER\n");
+ else
+ count += sprintf(temp_buf + count, "Driver register Interrupt : LEVEL TRIGGER\n");
+ }
+#if defined(HX_CHIP_STATUS_MONITOR)
+ else if(debug_level_cmd=='c')
+ {
+ count += sprintf(temp_buf + count, "chip_monitor :%d\n", g_chip_monitor_data->HX_CHIP_MONITOR_EN);
+ }
+#endif
+ if(copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n",__func__,__LINE__);
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG=1;
+ }
+ else
+ HX_PROC_SEND_FLAG=0;
+ return count;
+}
+
+static ssize_t himax_debug_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+ struct file* filp = NULL;
+ mm_segment_t oldfs;
+ int result = 0;
+ char fileName[128];
+ char buf[80] = {0};
+ int fw_type = 0;
+ struct inode *inode;
+ loff_t file_len = 0;
+
+ if (len >= 80)
+ {
+ I("%s: no command exceeds 80 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf, buff, len))
+ {
+ return -EFAULT;
+ }
+
+ if ( buf[0] == 'h') //handshaking
+ {
+ debug_level_cmd = buf[0];
+
+ himax_int_enable(private_ts->client->irq,0);
+
+ handshaking_result = himax_hand_shaking(private_ts->client); //0:Running, 1:Stop, 2:I2C Fail
+
+ himax_int_enable(private_ts->client->irq,1);
+
+ return len;
+ }
+
+ else if ( buf[0] == 'v') //firmware version
+ {
+ himax_int_enable(private_ts->client->irq,0);
+#ifdef HX_RST_PIN_FUNC
+ himax_ic_reset(false,false);
+#endif
+ debug_level_cmd = buf[0];
+ himax_read_FW_ver(private_ts->client);
+#ifdef HX_RST_PIN_FUNC
+ himax_ic_reset(true,false);
+#endif
+ himax_int_enable(private_ts->client->irq,1);
+ //himax_check_chip_version();
+ return len;
+ }
+
+ else if ( buf[0] == 'd') //ic information
+ {
+ debug_level_cmd = buf[0];
+ return len;
+ }
+
+ else if (buf[0] == 't')
+ {
+
+ himax_int_enable(private_ts->client->irq,0);
+
+#ifdef HX_CHIP_STATUS_MONITOR
+ g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0;
+ g_chip_monitor_data->HX_CHIP_MONITOR_EN = 0;
+ cancel_delayed_work_sync(&private_ts->himax_chip_monitor);
+#endif
+
+ debug_level_cmd = buf[0];
+ fw_update_complete = false;
+
+ memset(fileName, 0, 128);
+ // parse the file name
+ snprintf(fileName, len-2, "%s", &buf[2]);
+ I("%s: upgrade from file(%s) start!\n", __func__, fileName);
+ // open file
+ filp = filp_open(fileName, O_RDONLY, 0);
+ if (IS_ERR(filp))
+ {
+ E("%s: open firmware file failed\n", __func__);
+ goto firmware_upgrade_done;
+ //return len;
+ }
+ inode = filp->f_inode;
+ file_len = inode->i_size;
+ oldfs = get_fs();
+ set_fs(get_ds());
+
+ // read the latest firmware binary file
+ result=vfs_read(filp,upgrade_fw,file_len, &filp->f_pos);
+ if (result < 0)
+ {
+ E("%s: read firmware file failed\n", __func__);
+ goto firmware_upgrade_done;
+ //return len;
+ }
+
+ set_fs(oldfs);
+ filp_close(filp, NULL);
+
+ I("%s: FW image,len %d: %02X, %02X, %02X, %02X\n", __func__, result, upgrade_fw[0], upgrade_fw[1], upgrade_fw[2], upgrade_fw[3]);
+
+ if (result > 0)
+ {
+ fw_type = result/1024;
+ // start to upgrade
+ himax_int_enable(private_ts->client->irq,0);
+ I("Now FW size is : %dk\n",fw_type);
+ switch(fw_type)
+ {
+ case 32:
+ if (fts_ctpm_fw_upgrade_with_sys_fs_32k(private_ts->client,upgrade_fw, result, false) == 0)
+ {
+ E("%s: TP upgrade error, line: %d\n", __func__, __LINE__);
+ fw_update_complete = false;
+ }
+ else
+ {
+ I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__);
+ fw_update_complete = true;
+ }
+ break;
+ case 60:
+ if (fts_ctpm_fw_upgrade_with_sys_fs_60k(private_ts->client,upgrade_fw, result, false) == 0)
+ {
+ E("%s: TP upgrade error, line: %d\n", __func__, __LINE__);
+ fw_update_complete = false;
+ }
+ else
+ {
+ I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__);
+ fw_update_complete = true;
+ }
+ break;
+ case 64:
+ if (fts_ctpm_fw_upgrade_with_sys_fs_64k(private_ts->client,upgrade_fw, result, false) == 0)
+ {
+ E("%s: TP upgrade error, line: %d\n", __func__, __LINE__);
+ fw_update_complete = false;
+ }
+ else
+ {
+ I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__);
+ fw_update_complete = true;
+ }
+ break;
+ case 124:
+ if (fts_ctpm_fw_upgrade_with_sys_fs_124k(private_ts->client,upgrade_fw, result, false) == 0)
+ {
+ E("%s: TP upgrade error, line: %d\n", __func__, __LINE__);
+ fw_update_complete = false;
+ }
+ else
+ {
+ I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__);
+ fw_update_complete = true;
+ }
+ break;
+ case 128:
+ if (fts_ctpm_fw_upgrade_with_sys_fs_128k(private_ts->client,upgrade_fw, result, false) == 0)
+ {
+ E("%s: TP upgrade error, line: %d\n", __func__, __LINE__);
+ fw_update_complete = false;
+ }
+ else
+ {
+ I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__);
+ fw_update_complete = true;
+ }
+ break;
+ default:
+ E("%s: Flash command fail: %d\n", __func__, __LINE__);
+ fw_update_complete = false;
+ break;
+ }
+ goto firmware_upgrade_done;
+ //return count;
+ }
+ }
+ else if (buf[0] == 'i' && buf[1] == '2' && buf[2] == 'c') //i2c commutation
+ {
+ debug_level_cmd = 'i';
+ return len;
+ }
+
+ else if (buf[0] == 'i' && buf[1] == 'n' && buf[2] == 't') //INT trigger
+ {
+ debug_level_cmd = 'n';
+ return len;
+ }
+#if defined(HX_CHIP_STATUS_MONITOR)
+ else if(buf[0] == 'c')
+ {
+ debug_level_cmd = buf[0];
+ g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0;
+ g_chip_monitor_data->HX_CHIP_MONITOR_EN = 0;
+ cancel_delayed_work_sync(&private_ts->himax_chip_monitor);
+ return len;
+ }
+#endif
+#ifdef HX_ZERO_FLASH
+ else if(buf[0] == 'z')
+ {
+ himax_0f_operation_check();
+ return len;
+ }
+ else if(buf[0] == 'p')
+ {
+ I("NOW debug echo r!\n");
+ //himax_program_sram();
+ private_ts->himax_0f_update_wq = create_singlethread_workqueue("HMX_update_0f_reuqest_write");
+ if (!private_ts->himax_0f_update_wq)
+ E(" allocate syn_update_wq failed\n");
+
+ INIT_DELAYED_WORK(&private_ts->work_0f_update, himax_0f_operation);
+ queue_delayed_work(private_ts->himax_0f_update_wq, &private_ts->work_0f_update, msecs_to_jiffies(100));
+ return len;
+ }
+ else if(buf[0] == 'x')
+ {
+ himax_sys_reset();
+ return len;
+ }
+#endif
+ /* others,do nothing */
+ else
+ {
+ debug_level_cmd = 0;
+ return len;
+ }
+
+firmware_upgrade_done:
+
+#ifdef HX_RST_PIN_FUNC
+ himax_ic_reset(true,false);
+#endif
+ himax_int_enable(private_ts->client->irq,1);
+
+#ifdef HX_CHIP_STATUS_MONITOR
+ g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0;
+ g_chip_monitor_data->HX_CHIP_MONITOR_EN = 1;
+ queue_delayed_work(private_ts->himax_chip_monitor_wq, &private_ts->himax_chip_monitor, g_chip_monitor_data->HX_POLLING_TIMES*HZ);
+#endif
+
+ //todo himax_chip->tp_firmware_upgrade_proceed = 0;
+ //todo himax_chip->suspend_state = 0;
+ //todo enable_irq(himax_chip->irq);
+ return len;
+}
+
+static struct file_operations himax_proc_debug_ops =
+{
+ .owner = THIS_MODULE,
+ .read = himax_debug_read,
+ .write = himax_debug_write,
+};
+
+static ssize_t himax_proc_FW_debug_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ int ret = 0;
+ uint8_t loop_i = 0;
+ uint8_t tmp_data[64];
+ char *temp_buf;
+
+ temp_buf = kzalloc(len,GFP_KERNEL);
+
+ if(!HX_PROC_SEND_FLAG)
+ {
+ cmd_set[0] = 0x01;
+ if(himax_read_FW_status(cmd_set, tmp_data) == NO_ERR)
+ {
+ ret += sprintf(temp_buf + ret, "0x%02X%02X%02X%02X :\t",cmd_set[5],cmd_set[4],cmd_set[3],cmd_set[2]);
+ for (loop_i = 0; loop_i < cmd_set[1]; loop_i++)
+ {
+ ret += sprintf(temp_buf+ ret, "%5d\t", tmp_data[loop_i]);
+ }
+ ret += sprintf(temp_buf + ret, "\n");
+ }
+ cmd_set[0] = 0x02;
+ if(himax_read_FW_status(cmd_set, tmp_data) == NO_ERR)
+ {
+ for (loop_i = 0; loop_i < cmd_set[1]; loop_i = loop_i + 2)
+ {
+ if ((loop_i % 16) == 0)
+ ret += sprintf(temp_buf + ret, "0x%02X%02X%02X%02X :\t",
+ cmd_set[5],cmd_set[4],cmd_set[3]+(((cmd_set[2]+ loop_i)>>8)&0xFF), (cmd_set[2] + loop_i)&0xFF);
+ ret += sprintf(temp_buf + ret, "%5d\t", tmp_data[loop_i] + (tmp_data[loop_i + 1] << 8));
+ if ((loop_i % 16) == 14)
+ ret += sprintf(temp_buf + ret, "\n");
+ }
+
+ }
+ ret += sprintf(temp_buf + ret, "\n");
+ if(copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n",__func__,__LINE__);
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG=1;
+ }
+ else
+ HX_PROC_SEND_FLAG=0;
+ return ret;
+}
+
+static struct file_operations himax_proc_fw_debug_ops =
+{
+ .owner = THIS_MODULE,
+ .read = himax_proc_FW_debug_read,
+};
+
+static ssize_t himax_proc_DD_debug_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ int ret = 0;
+ uint8_t tmp_data[64];
+ uint8_t loop_i = 0;
+ char *temp_buf;
+
+ temp_buf = kzalloc(len,GFP_KERNEL);
+
+ if(!HX_PROC_SEND_FLAG)
+ {
+ if(mutual_set_flag == 1)
+ {
+ if(himax_read_DD_status(cmd_set, tmp_data) == NO_ERR)
+ {
+ for (loop_i = 0; loop_i < cmd_set[0]; loop_i++)
+ {
+ if ((loop_i % 8) == 0)
+ ret += sprintf(temp_buf + ret, "0x%02X : ", loop_i);
+ ret += sprintf(temp_buf + ret, "0x%02X ", tmp_data[loop_i]);
+ if ((loop_i % 8) == 7)
+ ret += sprintf(temp_buf + ret, "\n");
+ }
+ }
+ }
+ //else
+ ret += sprintf(temp_buf + ret, "\n");
+ if(copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n",__func__,__LINE__);
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG=1;
+ }
+ else
+ HX_PROC_SEND_FLAG=0;
+ return ret;
+}
+
+static ssize_t himax_proc_DD_debug_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+ uint8_t i = 0;
+ uint8_t cnt = 2;
+ unsigned long result = 0;
+ char buf_tmp[20];
+ char buf_tmp2[4];
+
+ if (len >= 20)
+ {
+ I("%s: no command exceeds 20 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf_tmp, buff, len))
+ {
+ return -EFAULT;
+ }
+ memset(buf_tmp2, 0x0, sizeof(buf_tmp2));
+
+ if (buf_tmp[2] == 'x' && buf_tmp[6] == 'x' && buf_tmp[10] == 'x')
+ {
+ mutual_set_flag = 1;
+ for (i = 3; i < 12; i = i + 4)
+ {
+ memcpy(buf_tmp2, buf_tmp + i, 2);
+ if (!kstrtoul(buf_tmp2, 16, &result))
+ cmd_set[cnt] = (uint8_t)result;
+ else
+ I("String to oul is fail in cnt = %d, buf_tmp2 = %s",cnt, buf_tmp2);
+ cnt--;
+ }
+ I("cmd_set[2] = %02X, cmd_set[1] = %02X, cmd_set[0] = %02X\n",cmd_set[2],cmd_set[1],cmd_set[0]);
+ }
+ else
+ mutual_set_flag = 0;
+
+ return len;
+}
+
+static struct file_operations himax_proc_dd_debug_ops =
+{
+ .owner = THIS_MODULE,
+ .read = himax_proc_DD_debug_read,
+ .write = himax_proc_DD_debug_write,
+};
+
+#endif
+
+#ifdef HX_TP_PROC_FLASH_DUMP
+
+uint8_t getFlashCommand(void)
+{
+ return flash_command;
+}
+
+static uint8_t getFlashDumpProgress(void)
+{
+ return flash_progress;
+}
+
+static uint8_t getFlashDumpComplete(void)
+{
+ return flash_dump_complete;
+}
+
+static uint8_t getFlashDumpFail(void)
+{
+ return flash_dump_fail;
+}
+
+uint8_t getSysOperation(void)
+{
+ return sys_operation;
+}
+
+static uint8_t getFlashReadStep(void)
+{
+ return flash_read_step;
+}
+
+bool getFlashDumpGoing(void)
+{
+ return flash_dump_going;
+}
+
+void setFlashBuffer(void)
+{
+ flash_buffer = kzalloc(Flash_Size * sizeof(uint8_t), GFP_KERNEL);
+ memset(flash_buffer,0x00,Flash_Size);
+}
+
+void setSysOperation(uint8_t operation)
+{
+ sys_operation = operation;
+}
+
+void setFlashDumpProgress(uint8_t progress)
+{
+ flash_progress = progress;
+ //I("setFlashDumpProgress : progress = %d ,flash_progress = %d \n",progress,flash_progress);
+}
+
+void setFlashDumpComplete(uint8_t status)
+{
+ flash_dump_complete = status;
+}
+
+void setFlashDumpFail(uint8_t fail)
+{
+ flash_dump_fail = fail;
+}
+
+static void setFlashCommand(uint8_t command)
+{
+ flash_command = command;
+}
+
+static void setFlashReadStep(uint8_t step)
+{
+ flash_read_step = step;
+}
+
+void setFlashDumpGoing(bool going)
+{
+ flash_dump_going = going;
+}
+
+static ssize_t himax_proc_flash_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ int ret = 0;
+ int loop_i;
+ uint8_t local_flash_read_step=0;
+ uint8_t local_flash_complete = 0;
+ uint8_t local_flash_progress = 0;
+ uint8_t local_flash_command = 0;
+ uint8_t local_flash_fail = 0;
+ char *temp_buf;
+
+ temp_buf = kzalloc(len,GFP_KERNEL);
+
+ local_flash_complete = getFlashDumpComplete();
+ local_flash_progress = getFlashDumpProgress();
+ local_flash_command = getFlashCommand();
+ local_flash_fail = getFlashDumpFail();
+
+ I("flash_progress = %d \n",local_flash_progress);
+ if(!HX_PROC_SEND_FLAG)
+ {
+ if (local_flash_fail)
+ {
+ ret += sprintf(temp_buf + ret, "FlashStart:Fail \n");
+ ret += sprintf(temp_buf + ret, "FlashEnd");
+ ret += sprintf(temp_buf + ret, "\n");
+ if(copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n",__func__,__LINE__);
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG=1;
+ return ret;
+ }
+
+ if (!local_flash_complete)
+ {
+ ret += sprintf(temp_buf + ret, "FlashStart:Ongoing:0x%2.2x \n",flash_progress);
+ ret += sprintf(temp_buf + ret, "FlashEnd");
+ ret += sprintf(temp_buf + ret, "\n");
+ if(copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n",__func__,__LINE__);
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG=1;
+ return ret;
+ }
+
+ if (local_flash_command == 1 && local_flash_complete)
+ {
+ ret += sprintf(temp_buf + ret, "FlashStart:Complete \n");
+ ret += sprintf(temp_buf + ret, "FlashEnd");
+ ret += sprintf(temp_buf + ret, "\n");
+ if(copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n",__func__,__LINE__);
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG=1;
+ return ret;
+ }
+
+ if (local_flash_command == 3 && local_flash_complete)
+ {
+ ret += sprintf(temp_buf + ret, "FlashStart: \n");
+ for(loop_i = 0; loop_i < 128; loop_i++)
+ {
+ ret += sprintf(temp_buf + ret, "x%2.2x", flash_buffer[loop_i]);
+ if ((loop_i % 16) == 15)
+ {
+ ret += sprintf(temp_buf + ret, "\n");
+ }
+ }
+ ret += sprintf(temp_buf + ret, "FlashEnd");
+ ret += sprintf(temp_buf + ret, "\n");
+ if(copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n",__func__,__LINE__);
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG=1;
+ return ret;
+ }
+
+ //flash command == 0 , report the data
+ local_flash_read_step = getFlashReadStep();
+
+ ret += sprintf(temp_buf + ret, "FlashStart:%2.2x \n",local_flash_read_step);
+
+ for (loop_i = 0; loop_i < 1024; loop_i++)
+ {
+ ret += sprintf(temp_buf + ret, "x%2.2X", flash_buffer[local_flash_read_step*1024 + loop_i]);
+
+ if ((loop_i % 16) == 15)
+ {
+ ret += sprintf(temp_buf + ret, "\n");
+ }
+ }
+
+ ret += sprintf(temp_buf + ret, "FlashEnd");
+ ret += sprintf(temp_buf + ret, "\n");
+ if(copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n",__func__,__LINE__);
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG=1;
+ }
+ else
+ HX_PROC_SEND_FLAG=0;
+ return ret;
+}
+
+static ssize_t himax_proc_flash_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+ char buf_tmp[6];
+ unsigned long result = 0;
+ char buf[80] = {0};
+
+ if (len >= 80)
+ {
+ I("%s: no command exceeds 80 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf, buff, len))
+ {
+ return -EFAULT;
+ }
+ memset(buf_tmp, 0x0, sizeof(buf_tmp));
+
+ I("%s: buf = %s\n", __func__, buf);
+
+ if (getSysOperation() == 1)
+ {
+ E("%s: PROC is busy , return!\n", __func__);
+ return len;
+ }
+
+ if (buf[0] == '0')
+ {
+ setFlashCommand(0);
+ if (buf[1] == ':' && buf[2] == 'x')
+ {
+ memcpy(buf_tmp, buf + 3, 2);
+ I("%s: read_Step = %s\n", __func__, buf_tmp);
+ if (!kstrtoul(buf_tmp, 16, &result))
+ {
+ I("%s: read_Step = %lu \n", __func__, result);
+ setFlashReadStep(result);
+ }
+ }
+ }
+ else if (buf[0] == '1')// 1_32,1_60,1_64,1_24,1_28 for flash size 32k,60k,64k,124k,128k
+ {
+ setSysOperation(1);
+ setFlashCommand(1);
+ setFlashDumpProgress(0);
+ setFlashDumpComplete(0);
+ setFlashDumpFail(0);
+ if ((buf[1] == '_' ) && (buf[2] == '3' ) && (buf[3] == '2' ))
+ {
+ Flash_Size = FW_SIZE_32k;
+ }
+ else if ((buf[1] == '_' ) && (buf[2] == '6' ))
+ {
+ if (buf[3] == '0')
+ {
+ Flash_Size = FW_SIZE_60k;
+ }
+ else if (buf[3] == '4')
+ {
+ Flash_Size = FW_SIZE_64k;
+ }
+ }
+ else if ((buf[1] == '_' ) && (buf[2] == '2' ))
+ {
+ if (buf[3] == '4')
+ {
+ Flash_Size = FW_SIZE_124k;
+ }
+ else if (buf[3] == '8')
+ {
+ Flash_Size = FW_SIZE_128k;
+ }
+ }
+ queue_work(private_ts->flash_wq, &private_ts->flash_work);
+ }
+ else if (buf[0] == '2') // 2_32,2_60,2_64,2_24,2_28 for flash size 32k,60k,64k,124k,128k
+ {
+ setSysOperation(1);
+ setFlashCommand(2);
+ setFlashDumpProgress(0);
+ setFlashDumpComplete(0);
+ setFlashDumpFail(0);
+ if ((buf[1] == '_' ) && (buf[2] == '3' ) && (buf[3] == '2' ))
+ {
+ Flash_Size = FW_SIZE_32k;
+ }
+ else if ((buf[1] == '_' ) && (buf[2] == '6' ))
+ {
+ if (buf[3] == '0')
+ {
+ Flash_Size = FW_SIZE_60k;
+ }
+ else if (buf[3] == '4')
+ {
+ Flash_Size = FW_SIZE_64k;
+ }
+ }
+ else if ((buf[1] == '_' ) && (buf[2] == '2' ))
+ {
+ if (buf[3] == '4')
+ {
+ Flash_Size = FW_SIZE_124k;
+ }
+ else if (buf[3] == '8')
+ {
+ Flash_Size = FW_SIZE_128k;
+ }
+ }
+ queue_work(private_ts->flash_wq, &private_ts->flash_work);
+ }
+ return len;
+}
+
+static struct file_operations himax_proc_flash_ops =
+{
+ .owner = THIS_MODULE,
+ .read = himax_proc_flash_read,
+ .write = himax_proc_flash_write,
+};
+
+void himax_ts_flash_func(void)
+{
+ uint8_t local_flash_command = 0;
+
+ himax_int_enable(private_ts->client->irq,0);
+ setFlashDumpGoing(true);
+
+ //sector = getFlashDumpSector();
+ //page = getFlashDumpPage();
+
+ local_flash_command = getFlashCommand();
+
+ msleep(100);
+
+ I("%s: local_flash_command = %d enter.\n", __func__,local_flash_command);
+
+ if ((local_flash_command == 1 || local_flash_command == 2)|| (local_flash_command==0x0F))
+ {
+ himax_flash_dump_func(private_ts->client, local_flash_command,Flash_Size, flash_buffer);
+ }
+
+ I("Complete~~~~~~~~~~~~~~~~~~~~~~~\n");
+
+ if (local_flash_command == 2)
+ {
+ struct file *fn;
+
+ fn = filp_open(FLASH_DUMP_FILE,O_CREAT | O_WRONLY,0);
+ if (!IS_ERR(fn))
+ {
+ I("%s create file and ready to write\n",__func__);
+ fn->f_op->write(fn,flash_buffer,Flash_Size*sizeof(uint8_t),&fn->f_pos);
+ filp_close(fn,NULL);
+ }
+ }
+
+ himax_int_enable(private_ts->client->irq,1);
+ setFlashDumpGoing(false);
+
+ setFlashDumpComplete(1);
+ setSysOperation(0);
+ return;
+
+ /* Flash_Dump_i2c_transfer_error:
+
+ himax_int_enable(private_ts->client->irq,1);
+ setFlashDumpGoing(false);
+ setFlashDumpComplete(0);
+ setFlashDumpFail(1);
+ setSysOperation(0);
+ return;
+ */
+}
+
+#endif
+
+#ifdef HX_TP_PROC_SELF_TEST
+static ssize_t himax_self_test_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ int val=0x00;
+ int ret = 0;
+ char *temp_buf;
+
+ temp_buf = kzalloc(len,GFP_KERNEL);
+ I("%s: enter, %d \n", __func__, __LINE__);
+ if(!HX_PROC_SEND_FLAG)
+ {
+ himax_int_enable(private_ts->client->irq,0);//disable irq
+ g_self_test_entered = 1;
+ val = himax_chip_self_test(private_ts->client);
+#ifdef HX_ESD_RECOVERY
+ HX_ESD_RESET_ACTIVATE = 1;
+#endif
+ himax_int_enable(private_ts->client->irq,1);//enable irq
+
+ if (val == 0x01)
+ {
+ ret += sprintf(temp_buf + ret, "Self_Test Pass\n");
+ }
+ else
+ {
+ ret += sprintf(temp_buf + ret, "Self_Test Fail\n");
+ }
+ g_self_test_entered = 0;
+ if(copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n",__func__,__LINE__);
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG=1;
+ }
+ else
+ HX_PROC_SEND_FLAG=0;
+ return ret;
+}
+
+/*
+static ssize_t himax_chip_self_test_store(struct device *dev,struct device_attribute *attr, const char *buf, size_t count)
+{
+ char buf_tmp[2];
+ unsigned long result = 0;
+
+ memset(buf_tmp, 0x0, sizeof(buf_tmp));
+ memcpy(buf_tmp, buf, 2);
+ if(!kstrtoul(buf_tmp, 16, &result))
+ {
+ sel_type = (uint8_t)result;
+ }
+ I("sel_type = %x \r\n", sel_type);
+ return count;
+}
+*/
+
+static struct file_operations himax_proc_self_test_ops =
+{
+ .owner = THIS_MODULE,
+ .read = himax_self_test_read,
+};
+#endif
+
+#ifdef HX_TP_PROC_SENSE_ON_OFF
+static ssize_t himax_sense_on_off_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+ char buf[80] = {0};
+
+ if (len >= 80)
+ {
+ I("%s: no command exceeds 80 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf, buff, len))
+ {
+ return -EFAULT;
+ }
+
+ if(buf[0] == '0')
+ {
+ himax_sense_off(private_ts->client);
+ I("Sense off \n");
+ }
+ else if(buf[0] == '1')
+ {
+ if(buf[1] == 's')
+ {
+ himax_sense_on(private_ts->client, 0x00);
+ I("Sense on re-map on, run sram \n");
+ }
+ else
+ {
+ himax_sense_on(private_ts->client, 0x01);
+ I("Sense on re-map off, run flash \n");
+ }
+ }
+ else
+ {
+ I("Do nothing \n");
+ }
+ return len;
+}
+
+static struct file_operations himax_proc_sense_on_off_ops =
+{
+ .owner = THIS_MODULE,
+ .write = himax_sense_on_off_write,
+};
+#endif
+
+#ifdef HX_HIGH_SENSE
+static ssize_t himax_HSEN_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ struct himax_ts_data *ts = private_ts;
+ size_t count = 0;
+ char *temp_buf;
+
+ temp_buf = kzalloc(len,GFP_KERNEL);
+
+ if(!HX_PROC_SEND_FLAG)
+ {
+ count = snprintf(temp_buf, PAGE_SIZE, "%d\n", ts->HSEN_enable);
+ if(copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n",__func__,__LINE__);
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG=1;
+ }
+ else
+ HX_PROC_SEND_FLAG=0;
+ return count;
+}
+
+static ssize_t himax_HSEN_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+ struct himax_ts_data *ts = private_ts;
+ char buf[80] = {0};
+
+
+ if (len >= 80)
+ {
+ I("%s: no command exceeds 80 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf, buff, len))
+ {
+ return -EFAULT;
+ }
+
+ if (buf[0] == '0')
+ {
+ ts->HSEN_enable = 0;
+ }
+ else if (buf[0] == '1')
+ {
+ ts->HSEN_enable = 1;
+ }
+ else
+ return -EINVAL;
+
+ himax_set_HSEN_enable(ts->client, ts->HSEN_enable, ts->suspended);
+
+ I("%s: HSEN_enable = %d.\n", __func__, ts->HSEN_enable);
+
+ return len;
+}
+
+static struct file_operations himax_proc_HSEN_ops =
+{
+ .owner = THIS_MODULE,
+ .read = himax_HSEN_read,
+ .write = himax_HSEN_write,
+};
+#endif
+
+#ifdef HX_SMART_WAKEUP
+static ssize_t himax_SMWP_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ size_t count = 0;
+ struct himax_ts_data *ts = private_ts;
+
+ char *temp_buf;
+
+ temp_buf = kzalloc(len,GFP_KERNEL);
+
+ if(!HX_PROC_SEND_FLAG)
+ {
+ count = snprintf(temp_buf, PAGE_SIZE, "%d\n", ts->SMWP_enable);
+ if(copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n",__func__,__LINE__);
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG=1;
+ }
+ else
+ HX_PROC_SEND_FLAG=0;
+
+ return count;
+}
+
+static ssize_t himax_SMWP_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+ struct himax_ts_data *ts = private_ts;
+ char buf[80] = {0};
+
+ if (len >= 80)
+ {
+ I("%s: no command exceeds 80 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf, buff, len))
+ {
+ return -EFAULT;
+ }
+
+
+ if (buf[0] == '0')
+ {
+ ts->SMWP_enable = 0;
+ }
+ else if (buf[0] == '1')
+ {
+ ts->SMWP_enable = 1;
+ }
+ else
+ return -EINVAL;
+
+ himax_set_SMWP_enable(ts->client, ts->SMWP_enable, ts->suspended);
+
+ HX_SMWP_EN = ts->SMWP_enable;
+ I("%s: SMART_WAKEUP_enable = %d.\n", __func__, HX_SMWP_EN);
+
+ return len;
+}
+
+static struct file_operations himax_proc_SMWP_ops =
+{
+ .owner = THIS_MODULE,
+ .read = himax_SMWP_read,
+ .write = himax_SMWP_write,
+};
+
+static ssize_t himax_GESTURE_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ struct himax_ts_data *ts = private_ts;
+ int i =0;
+ int ret = 0;
+ char *temp_buf;
+
+ temp_buf = kzalloc(len,GFP_KERNEL);
+ if(!HX_PROC_SEND_FLAG)
+ {
+ for(i=0; i<16; i++)
+ ret += sprintf(temp_buf + ret, "ges_en[%d]=%d \n",i,ts->gesture_cust_en[i]);
+ if(copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n",__func__,__LINE__);
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG = 1;
+ }
+ else
+ {
+ HX_PROC_SEND_FLAG = 0;
+ ret = 0;
+ }
+ return ret;
+}
+
+static ssize_t himax_GESTURE_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+ struct himax_ts_data *ts = private_ts;
+ int i =0;
+ char buf[80] = {0};
+
+ if (len >= 80)
+ {
+ I("%s: no command exceeds 80 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf, buff, len))
+ {
+ return -EFAULT;
+ }
+
+ I("himax_GESTURE_store= %s \n",buf);
+ for (i=0; i<16; i++)
+ {
+ if (buf[i] == '0')
+ ts->gesture_cust_en[i]= 0;
+ else if (buf[i] == '1')
+ ts->gesture_cust_en[i]= 1;
+ else
+ ts->gesture_cust_en[i]= 0;
+ I("gesture en[%d]=%d \n", i, ts->gesture_cust_en[i]);
+ }
+ return len;
+}
+
+static struct file_operations himax_proc_Gesture_ops =
+{
+ .owner = THIS_MODULE,
+ .read = himax_GESTURE_read,
+ .write = himax_GESTURE_write,
+};
+#endif
+
+#ifdef HX_ESD_RECOVERY
+static ssize_t himax_esd_cnt_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ int ret = 0;
+ char *temp_buf;
+
+ temp_buf = kzalloc(len,GFP_KERNEL);
+
+ I("%s: enter, %d \n", __func__, __LINE__);
+ if(!HX_PROC_SEND_FLAG)
+ {
+ ret += sprintf(temp_buf + ret, "EB_cnt = %d, EC_cnt = %d, ED_cnt = %d\n",hx_EB_event_flag, hx_EC_event_flag, hx_ED_event_flag);
+ if(copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n",__func__,__LINE__);
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG=1;
+ }
+ else
+ HX_PROC_SEND_FLAG=0;
+ return ret;
+}
+
+static ssize_t himax_esd_cnt_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+ int i =0;
+ char buf[12] = {0};
+
+ if (len >= 12)
+ {
+ I("%s: no command exceeds 80 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf, buff, len))
+ {
+ return -EFAULT;
+ }
+
+ I("Clear ESD Flag \n");
+ if (buf[i] == '0')
+ {
+ hx_EB_event_flag = 0;
+ hx_EC_event_flag = 0;
+ hx_ED_event_flag = 0;
+ }
+
+ return len;
+}
+
+static struct file_operations himax_proc_esd_cnt_ops =
+{
+ .owner = THIS_MODULE,
+ .read = himax_esd_cnt_read,
+ .write = himax_esd_cnt_write,
+};
+#endif
+
+int himax_touch_proc_init(void)
+{
+ himax_touch_proc_dir = proc_mkdir( HIMAX_PROC_TOUCH_FOLDER, NULL);
+ if (himax_touch_proc_dir == NULL)
+ {
+ E(" %s: himax_touch_proc_dir file create failed!\n", __func__);
+ return -ENOMEM;
+ }
+
+ himax_proc_debug_level_file = proc_create(HIMAX_PROC_DEBUG_LEVEL_FILE, (S_IWUSR|S_IRUGO),
+ himax_touch_proc_dir, &himax_proc_debug_level_ops);
+ if (himax_proc_debug_level_file == NULL)
+ {
+ E(" %s: proc debug_level file create failed!\n", __func__);
+ goto fail_1;
+ }
+
+ himax_proc_vendor_file = proc_create(HIMAX_PROC_VENDOR_FILE, (S_IRUGO),
+ himax_touch_proc_dir, &himax_proc_vendor_ops);
+ if(himax_proc_vendor_file == NULL)
+ {
+ E(" %s: proc vendor file create failed!\n", __func__);
+ goto fail_2;
+ }
+
+ himax_proc_attn_file = proc_create(HIMAX_PROC_ATTN_FILE, (S_IRUGO),
+ himax_touch_proc_dir, &himax_proc_attn_ops);
+ if(himax_proc_attn_file == NULL)
+ {
+ E(" %s: proc attn file create failed!\n", __func__);
+ goto fail_3;
+ }
+
+ himax_proc_int_en_file = proc_create(HIMAX_PROC_INT_EN_FILE, (S_IWUSR|S_IRUGO),
+ himax_touch_proc_dir, &himax_proc_int_en_ops);
+ if(himax_proc_int_en_file == NULL)
+ {
+ E(" %s: proc int en file create failed!\n", __func__);
+ goto fail_4;
+ }
+
+ himax_proc_layout_file = proc_create(HIMAX_PROC_LAYOUT_FILE, (S_IWUSR|S_IRUGO),
+ himax_touch_proc_dir, &himax_proc_layout_ops);
+ if(himax_proc_layout_file == NULL)
+ {
+ E(" %s: proc layout file create failed!\n", __func__);
+ goto fail_5;
+ }
+
+#ifdef HX_TP_PROC_RESET
+ himax_proc_reset_file = proc_create(HIMAX_PROC_RESET_FILE, (S_IWUSR),
+ himax_touch_proc_dir, &himax_proc_reset_ops);
+ if(himax_proc_reset_file == NULL)
+ {
+ E(" %s: proc reset file create failed!\n", __func__);
+ goto fail_6;
+ }
+#endif
+
+#ifdef HX_TP_PROC_DIAG
+ himax_proc_diag_file = proc_create(HIMAX_PROC_DIAG_FILE, (S_IWUSR|S_IRUGO),
+ himax_touch_proc_dir, &himax_proc_diag_ops);
+ if(himax_proc_diag_file == NULL)
+ {
+ E(" %s: proc diag file create failed!\n", __func__);
+ goto fail_7;
+ }
+ himax_proc_diag_arrange_file = proc_create(HIMAX_PROC_DIAG_ARR_FILE, (S_IWUSR|S_IRUGO),
+ himax_touch_proc_dir, &himax_proc_diag_arrange_ops);
+ if(himax_proc_diag_arrange_file == NULL)
+ {
+ E(" %s: proc diag file create failed!\n", __func__);
+ goto fail_7_1;
+ }
+#endif
+
+#ifdef HX_TP_PROC_REGISTER
+ himax_proc_register_file = proc_create(HIMAX_PROC_REGISTER_FILE, (S_IWUSR|S_IRUGO),
+ himax_touch_proc_dir, &himax_proc_register_ops);
+ if(himax_proc_register_file == NULL)
+ {
+ E(" %s: proc register file create failed!\n", __func__);
+ goto fail_8;
+ }
+#endif
+
+#ifdef HX_TP_PROC_DEBUG
+ himax_proc_debug_file = proc_create(HIMAX_PROC_DEBUG_FILE, (S_IWUSR|S_IRUGO),
+ himax_touch_proc_dir, &himax_proc_debug_ops);
+ if(himax_proc_debug_file == NULL)
+ {
+ E(" %s: proc debug file create failed!\n", __func__);
+ goto fail_9;
+ }
+
+ himax_proc_fw_debug_file = proc_create(HIMAX_PROC_FW_DEBUG_FILE, (S_IWUSR|S_IRUGO),
+ himax_touch_proc_dir, &himax_proc_fw_debug_ops);
+ if(himax_proc_fw_debug_file == NULL)
+ {
+ E(" %s: proc fw debug file create failed!\n", __func__);
+ goto fail_9_1;
+ }
+
+ himax_proc_dd_debug_file = proc_create(HIMAX_PROC_DD_DEBUG_FILE, (S_IWUSR|S_IRUGO),
+ himax_touch_proc_dir, &himax_proc_dd_debug_ops);
+ if(himax_proc_dd_debug_file == NULL)
+ {
+ E(" %s: proc DD debug file create failed!\n", __func__);
+ goto fail_9_2;
+ }
+#endif
+
+#ifdef HX_TP_PROC_FLASH_DUMP
+ himax_proc_flash_dump_file = proc_create(HIMAX_PROC_FLASH_DUMP_FILE, (S_IWUSR|S_IRUGO),
+ himax_touch_proc_dir, &himax_proc_flash_ops);
+ if(himax_proc_flash_dump_file == NULL)
+ {
+ E(" %s: proc flash dump file create failed!\n", __func__);
+ goto fail_10;
+ }
+#endif
+
+#ifdef HX_TP_PROC_SELF_TEST
+ himax_proc_self_test_file = proc_create(HIMAX_PROC_SELF_TEST_FILE, (S_IRUGO),
+ himax_touch_proc_dir, &himax_proc_self_test_ops);
+ if(himax_proc_self_test_file == NULL)
+ {
+ E(" %s: proc self_test file create failed!\n", __func__);
+ goto fail_11;
+ }
+#endif
+
+#ifdef HX_HIGH_SENSE
+ himax_proc_HSEN_file = proc_create(HIMAX_PROC_HSEN_FILE, (S_IWUSR|S_IRUGO|S_IWUGO),
+ himax_touch_proc_dir, &himax_proc_HSEN_ops);
+ if(himax_proc_HSEN_file == NULL)
+ {
+ E(" %s: proc HSEN file create failed!\n", __func__);
+ goto fail_13;
+ }
+#endif
+
+#ifdef HX_SMART_WAKEUP
+ himax_proc_SMWP_file = proc_create(HIMAX_PROC_SMWP_FILE, (S_IWUSR|S_IRUGO|S_IWUGO),
+ himax_touch_proc_dir, &himax_proc_SMWP_ops);
+ if(himax_proc_SMWP_file == NULL)
+ {
+ E(" %s: proc SMWP file create failed!\n", __func__);
+ goto fail_14;
+ }
+ himax_proc_GESTURE_file = proc_create(HIMAX_PROC_GESTURE_FILE, (S_IWUSR|S_IRUGO|S_IWUGO),
+ himax_touch_proc_dir, &himax_proc_Gesture_ops);
+ if(himax_proc_GESTURE_file == NULL)
+ {
+ E(" %s: proc GESTURE file create failed!\n", __func__);
+ goto fail_15;
+ }
+#endif
+
+#ifdef HX_TP_PROC_SENSE_ON_OFF
+ himax_proc_SENSE_ON_OFF_file = proc_create(HIMAX_PROC_SENSE_ON_OFF_FILE, (S_IWUSR|S_IRUGO|S_IWUGO),
+ himax_touch_proc_dir, &himax_proc_sense_on_off_ops);
+ if(himax_proc_SENSE_ON_OFF_file == NULL)
+ {
+ E(" %s: proc SENSE_ON_OFF file create failed!\n", __func__);
+ goto fail_16;
+ }
+#endif
+#ifdef HX_ESD_RECOVERY
+ himax_proc_ESD_cnt_file = proc_create(HIMAX_PROC_ESD_CNT_FILE, (S_IWUSR|S_IRUGO|S_IWUGO),
+ himax_touch_proc_dir, &himax_proc_esd_cnt_ops);
+ if(himax_proc_ESD_cnt_file == NULL)
+ {
+ E(" %s: proc ESD cnt file create failed!\n", __func__);
+ goto fail_17;
+ }
+#endif
+ himax_proc_CRC_test_file = proc_create(HIMAX_PROC_CRC_TEST_FILE, (S_IWUSR|S_IRUGO|S_IWUGO),
+ himax_touch_proc_dir, &himax_proc_CRC_test_ops);
+ if(himax_proc_CRC_test_file == NULL)
+ {
+ E(" %s: proc CRC test file create failed!\n", __func__);
+ goto fail_18;
+ }
+ return 0 ;
+
+fail_18:
+#ifdef HX_ESD_RECOVERY
+ remove_proc_entry( HIMAX_PROC_ESD_CNT_FILE, himax_touch_proc_dir );
+fail_17:
+#endif
+#ifdef HX_TP_PROC_SENSE_ON_OFF
+ remove_proc_entry( HIMAX_PROC_SENSE_ON_OFF_FILE, himax_touch_proc_dir );
+fail_16:
+#endif
+#ifdef HX_SMART_WAKEUP
+ remove_proc_entry( HIMAX_PROC_GESTURE_FILE, himax_touch_proc_dir );
+fail_15:
+ remove_proc_entry( HIMAX_PROC_SMWP_FILE, himax_touch_proc_dir );
+fail_14:
+#endif
+#ifdef HX_HIGH_SENSE
+ remove_proc_entry( HIMAX_PROC_HSEN_FILE, himax_touch_proc_dir );
+fail_13:
+#endif
+#ifdef HX_TP_PROC_SELF_TEST
+ remove_proc_entry( HIMAX_PROC_SELF_TEST_FILE, himax_touch_proc_dir );
+fail_11:
+#endif
+#ifdef HX_TP_PROC_FLASH_DUMP
+ remove_proc_entry( HIMAX_PROC_FLASH_DUMP_FILE, himax_touch_proc_dir );
+fail_10:
+#endif
+#ifdef HX_TP_PROC_DEBUG
+ remove_proc_entry( HIMAX_PROC_DEBUG_FILE, himax_touch_proc_dir );
+fail_9:
+ remove_proc_entry( HIMAX_PROC_FW_DEBUG_FILE, himax_touch_proc_dir );
+fail_9_1:
+ remove_proc_entry( HIMAX_PROC_DD_DEBUG_FILE, himax_touch_proc_dir );
+fail_9_2:
+#endif
+#ifdef HX_TP_PROC_REGISTER
+ remove_proc_entry( HIMAX_PROC_REGISTER_FILE, himax_touch_proc_dir );
+fail_8:
+#endif
+#ifdef HX_TP_PROC_DIAG
+ remove_proc_entry( HIMAX_PROC_DIAG_FILE, himax_touch_proc_dir );
+fail_7:
+ remove_proc_entry( HIMAX_PROC_DIAG_ARR_FILE, himax_touch_proc_dir );
+fail_7_1:
+#endif
+#ifdef HX_TP_PROC_RESET
+ remove_proc_entry( HIMAX_PROC_RESET_FILE, himax_touch_proc_dir );
+fail_6:
+#endif
+ remove_proc_entry( HIMAX_PROC_LAYOUT_FILE, himax_touch_proc_dir );
+fail_5:
+ remove_proc_entry( HIMAX_PROC_INT_EN_FILE, himax_touch_proc_dir );
+fail_4:
+ remove_proc_entry( HIMAX_PROC_ATTN_FILE, himax_touch_proc_dir );
+fail_3:
+ remove_proc_entry( HIMAX_PROC_VENDOR_FILE, himax_touch_proc_dir );
+fail_2:
+ remove_proc_entry( HIMAX_PROC_DEBUG_LEVEL_FILE, himax_touch_proc_dir );
+fail_1:
+ remove_proc_entry( HIMAX_PROC_TOUCH_FOLDER, NULL );
+ return -ENOMEM;
+}
+
+void himax_touch_proc_deinit(void)
+{
+ remove_proc_entry( HIMAX_PROC_CRC_TEST_FILE, himax_touch_proc_dir );
+#ifdef HX_ESD_RECOVERY
+ remove_proc_entry( HIMAX_PROC_ESD_CNT_FILE, himax_touch_proc_dir );
+#endif
+#ifdef HX_TP_PROC_SENSE_ON_OFF
+ remove_proc_entry( HIMAX_PROC_SENSE_ON_OFF_FILE, himax_touch_proc_dir );
+#endif
+#ifdef HX_SMART_WAKEUP
+ remove_proc_entry( HIMAX_PROC_GESTURE_FILE, himax_touch_proc_dir );
+ remove_proc_entry( HIMAX_PROC_SMWP_FILE, himax_touch_proc_dir );
+#endif
+#ifdef HX_DOT_VIEW
+ remove_proc_entry( HIMAX_PROC_HSEN_FILE, himax_touch_proc_dir );
+#endif
+#ifdef HX_TP_PROC_SELF_TEST
+ remove_proc_entry(HIMAX_PROC_SELF_TEST_FILE, himax_touch_proc_dir);
+#endif
+#ifdef HX_TP_PROC_FLASH_DUMP
+ remove_proc_entry(HIMAX_PROC_FLASH_DUMP_FILE, himax_touch_proc_dir);
+#endif
+#ifdef HX_TP_PROC_DEBUG
+ remove_proc_entry( HIMAX_PROC_DEBUG_FILE, himax_touch_proc_dir );
+ remove_proc_entry( HIMAX_PROC_FW_DEBUG_FILE, himax_touch_proc_dir );
+ remove_proc_entry( HIMAX_PROC_DD_DEBUG_FILE, himax_touch_proc_dir );
+#endif
+#ifdef HX_TP_PROC_REGISTER
+ remove_proc_entry(HIMAX_PROC_REGISTER_FILE, himax_touch_proc_dir);
+#endif
+#ifdef HX_TP_PROC_DIAG
+ remove_proc_entry(HIMAX_PROC_DIAG_FILE, himax_touch_proc_dir);
+#endif
+#ifdef HX_TP_PROC_RESET
+ remove_proc_entry( HIMAX_PROC_RESET_FILE, himax_touch_proc_dir );
+#endif
+ remove_proc_entry( HIMAX_PROC_LAYOUT_FILE, himax_touch_proc_dir );
+ remove_proc_entry( HIMAX_PROC_INT_EN_FILE, himax_touch_proc_dir );
+ remove_proc_entry( HIMAX_PROC_ATTN_FILE, himax_touch_proc_dir );
+ remove_proc_entry( HIMAX_PROC_VENDOR_FILE, himax_touch_proc_dir );
+ remove_proc_entry( HIMAX_PROC_DEBUG_LEVEL_FILE, himax_touch_proc_dir );
+ remove_proc_entry( HIMAX_PROC_TOUCH_FOLDER, NULL );
+}
+#endif
diff --git a/drivers/input/touchscreen/hxchipset83112b/himax_debug.h b/drivers/input/touchscreen/hxchipset83112b/himax_debug.h
new file mode 100755
index 0000000..925d5e0
--- /dev/null
+++ b/drivers/input/touchscreen/hxchipset83112b/himax_debug.h
@@ -0,0 +1,213 @@
+/* Himax Android Driver Sample Code for debug nodes
+*
+* Copyright (C) 2017 Himax Corporation.
+*
+* 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 H_HIMAX_DEBUG
+#define H_HIMAX_DEBUG
+
+#include "himax_platform.h"
+#include "himax_common.h"
+
+
+#ifdef HX_ESD_RECOVERY
+extern u8 HX_ESD_RESET_ACTIVATE;
+extern int hx_EB_event_flag;
+extern int hx_EC_event_flag;
+extern int hx_ED_event_flag;
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
+#define HIMAX_PROC_TOUCH_FOLDER "android_touch"
+#define HIMAX_PROC_DEBUG_LEVEL_FILE "debug_level"
+#define HIMAX_PROC_VENDOR_FILE "vendor"
+#define HIMAX_PROC_ATTN_FILE "attn"
+#define HIMAX_PROC_INT_EN_FILE "int_en"
+#define HIMAX_PROC_LAYOUT_FILE "layout"
+#define HIMAX_PROC_CRC_TEST_FILE "CRC_test"
+
+static struct proc_dir_entry *himax_touch_proc_dir = NULL;
+static struct proc_dir_entry *himax_proc_debug_level_file = NULL;
+static struct proc_dir_entry *himax_proc_vendor_file = NULL;
+static struct proc_dir_entry *himax_proc_attn_file = NULL;
+static struct proc_dir_entry *himax_proc_int_en_file = NULL;
+static struct proc_dir_entry *himax_proc_layout_file = NULL;
+static struct proc_dir_entry *himax_proc_CRC_test_file = NULL;
+
+uint8_t HX_PROC_SEND_FLAG;
+
+extern int himax_touch_proc_init(void);
+extern void himax_touch_proc_deinit(void);
+bool getFlashDumpGoing(void);
+
+extern int himax_int_en_set(struct i2c_client *client);
+
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST)
+#define HIMAX_PROC_ITO_TEST_FILE "ITO_test"
+static struct proc_dir_entry *himax_proc_ito_test_file = NULL;
+
+extern void ito_set_step_status(uint8_t status);
+extern uint8_t ito_get_step_status(void);
+extern void ito_set_result_status(uint8_t status);
+extern uint8_t ito_get_result_status(void);
+
+#endif
+
+#ifdef HX_TP_PROC_REGISTER
+#define HIMAX_PROC_REGISTER_FILE "register"
+struct proc_dir_entry *himax_proc_register_file = NULL;
+uint8_t byte_length = 0;
+uint8_t register_command[4];
+bool cfg_flag = false;
+#endif
+
+#ifdef HX_TP_PROC_DIAG
+#define HIMAX_PROC_DIAG_FILE "diag"
+struct proc_dir_entry *himax_proc_diag_file = NULL;
+#define HIMAX_PROC_DIAG_ARR_FILE "diag_arr"
+struct proc_dir_entry *himax_proc_diag_arrange_file = NULL;
+struct file *diag_sram_fn;
+uint8_t write_counter = 0;
+uint8_t write_max_count = 30;
+#define IIR_DUMP_FILE "/sdcard/HX_IIR_Dump.txt"
+#define DC_DUMP_FILE "/sdcard/HX_DC_Dump.txt"
+#define BANK_DUMP_FILE "/sdcard/HX_BANK_Dump.txt"
+
+#ifdef HX_TP_PROC_2T2R
+static uint8_t x_channel_2 = 0;
+static uint8_t y_channel_2 = 0;
+static uint32_t *diag_mutual_2 = NULL;
+
+int32_t *getMutualBuffer_2(void);
+uint8_t getXChannel_2(void);
+uint8_t getYChannel_2(void);
+
+void setMutualBuffer_2(void);
+void setXChannel_2(uint8_t x);
+void setYChannel_2(uint8_t y);
+#endif
+uint8_t x_channel = 0;
+uint8_t y_channel = 0;
+ int32_t *diag_mutual = NULL;
+ int32_t *diag_mutual_new = NULL;
+ int32_t *diag_mutual_old = NULL;
+uint8_t diag_max_cnt = 0;
+uint8_t hx_state_info[2] = {0};
+
+int g_diag_command = 0;
+uint8_t diag_coor[128];// = {0xFF};
+ int32_t diag_self[100] = {0};
+
+ int32_t *getMutualBuffer(void);
+ int32_t *getMutualNewBuffer(void);
+ int32_t *getMutualOldBuffer(void);
+ int32_t *getSelfBuffer(void);
+uint8_t getDiagCommand(void);
+uint8_t getXChannel(void);
+uint8_t getYChannel(void);
+
+void setMutualBuffer(void);
+void setMutualNewBuffer(void);
+void setMutualOldBuffer(void);
+void setXChannel(uint8_t x);
+void setYChannel(uint8_t y);
+#endif
+
+#ifdef HX_TP_PROC_DEBUG
+#define HIMAX_PROC_DEBUG_FILE "debug"
+struct proc_dir_entry *himax_proc_debug_file = NULL;
+#define HIMAX_PROC_FW_DEBUG_FILE "FW_debug"
+struct proc_dir_entry *himax_proc_fw_debug_file = NULL;
+#define HIMAX_PROC_DD_DEBUG_FILE "DD_debug"
+struct proc_dir_entry *himax_proc_dd_debug_file = NULL;
+
+bool fw_update_complete = false;
+int handshaking_result = 0;
+unsigned char debug_level_cmd = 0;
+unsigned char upgrade_fw[128*1024];
+uint8_t cmd_set[8];
+uint8_t mutual_set_flag = 0;
+#endif
+
+#ifdef HX_TP_PROC_FLASH_DUMP
+#define HIMAX_PROC_FLASH_DUMP_FILE "flash_dump"
+struct proc_dir_entry *himax_proc_flash_dump_file = NULL;
+
+static int Flash_Size = 131072;
+static uint8_t *flash_buffer = NULL;
+static uint8_t flash_command = 0;
+static uint8_t flash_read_step = 0;
+static uint8_t flash_progress = 0;
+static uint8_t flash_dump_complete = 0;
+static uint8_t flash_dump_fail = 0;
+static uint8_t sys_operation = 0;
+static bool flash_dump_going = false;
+
+static uint8_t getFlashDumpComplete(void);
+static uint8_t getFlashDumpFail(void);
+static uint8_t getFlashDumpProgress(void);
+static uint8_t getFlashReadStep(void);
+uint8_t getFlashCommand(void);
+uint8_t getSysOperation(void);
+
+static void setFlashCommand(uint8_t command);
+static void setFlashReadStep(uint8_t step);
+
+void setFlashBuffer(void);
+void setFlashDumpComplete(uint8_t complete);
+void setFlashDumpFail(uint8_t fail);
+void setFlashDumpProgress(uint8_t progress);
+void setSysOperation(uint8_t operation);
+void setFlashDumpGoing(bool going);
+
+#endif
+
+#ifdef HX_TP_PROC_SELF_TEST
+#define HIMAX_PROC_SELF_TEST_FILE "self_test"
+struct proc_dir_entry *himax_proc_self_test_file = NULL;
+uint32_t **raw_data_array;
+uint8_t X_NUM = 0, Y_NUM = 0;
+uint8_t sel_type = 0x0D;
+#endif
+
+#ifdef HX_TP_PROC_RESET
+#define HIMAX_PROC_RESET_FILE "reset"
+struct proc_dir_entry *himax_proc_reset_file = NULL;
+#endif
+
+#ifdef HX_HIGH_SENSE
+#define HIMAX_PROC_HSEN_FILE "HSEN"
+struct proc_dir_entry *himax_proc_HSEN_file = NULL;
+#endif
+
+#ifdef HX_TP_PROC_SENSE_ON_OFF
+#define HIMAX_PROC_SENSE_ON_OFF_FILE "SenseOnOff"
+struct proc_dir_entry *himax_proc_SENSE_ON_OFF_file = NULL;
+#endif
+
+#ifdef HX_SMART_WAKEUP
+#define HIMAX_PROC_SMWP_FILE "SMWP"
+struct proc_dir_entry *himax_proc_SMWP_file = NULL;
+#define HIMAX_PROC_GESTURE_FILE "GESTURE"
+struct proc_dir_entry *himax_proc_GESTURE_file = NULL;
+uint8_t HX_SMWP_EN = 0;
+//extern bool FAKE_POWER_KEY_SEND;
+#endif
+
+#ifdef HX_ESD_RECOVERY
+#define HIMAX_PROC_ESD_CNT_FILE "ESD_cnt"
+struct proc_dir_entry *himax_proc_ESD_cnt_file = NULL;
+#endif
+
+#endif
+
+#endif
diff --git a/drivers/input/touchscreen/hxchipset83112b/himax_ic.c b/drivers/input/touchscreen/hxchipset83112b/himax_ic.c
new file mode 100755
index 0000000..e0922d7
--- /dev/null
+++ b/drivers/input/touchscreen/hxchipset83112b/himax_ic.c
@@ -0,0 +1,3224 @@
+/* Himax Android Driver Sample Code for HX83112 chipset
+*
+* Copyright (C) 2017 Himax Corporation.
+*
+* 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 "himax_ic.h"
+#include "himax_common.h"
+
+extern int i2c_error_count;
+extern int reset_flag;
+
+extern unsigned long FW_VER_MAJ_FLASH_ADDR;
+extern unsigned long FW_VER_MIN_FLASH_ADDR;
+extern unsigned long CFG_VER_MAJ_FLASH_ADDR;
+extern unsigned long CFG_VER_MIN_FLASH_ADDR;
+extern unsigned long CID_VER_MAJ_FLASH_ADDR;
+extern unsigned long CID_VER_MIN_FLASH_ADDR;
+
+extern unsigned long FW_VER_MAJ_FLASH_LENG;
+extern unsigned long FW_VER_MIN_FLASH_LENG;
+extern unsigned long CFG_VER_MAJ_FLASH_LENG;
+extern unsigned long CFG_VER_MIN_FLASH_LENG;
+extern unsigned long CID_VER_MAJ_FLASH_LENG;
+extern unsigned long CID_VER_MIN_FLASH_LENG;
+
+#ifdef HX_AUTO_UPDATE_FW
+extern int g_i_FW_VER;
+extern int g_i_CFG_VER;
+extern int g_i_CID_MAJ;
+extern int g_i_CID_MIN;
+//extern unsigned char i_CTPM_FW[];
+extern unsigned char i_CTPM_FW_HX83112A[];
+extern unsigned char i_CTPM_FW_HX83112B[];
+#endif
+
+extern unsigned char IC_TYPE;
+extern unsigned char IC_CHECKSUM;
+
+extern bool DSRAM_Flag;
+
+extern struct himax_ic_data* ic_data;
+extern struct himax_ts_data *private_ts;
+
+int himax_touch_data_size = 128;
+
+#ifdef HX_TP_PROC_2T2R
+bool Is_2T2R = false;
+#endif
+
+#ifdef HX_USB_DETECT_GLOBAL
+//extern kal_bool upmu_is_chr_det(void);
+extern void himax_cable_detect_func(bool force_renew);
+#endif
+
+int himax_get_touch_data_size(void)
+{
+ return himax_touch_data_size;
+}
+
+#ifdef HX_RST_PIN_FUNC
+extern void himax_rst_gpio_set(int pinnum, uint8_t value);
+extern int himax_report_data_init(void);
+extern u8 HX_HW_RESET_ACTIVATE;
+
+void himax_pin_reset(void)
+{
+ I("%s: Now reset the Touch chip.\n", __func__);
+ himax_rst_gpio_set(private_ts->rst_gpio, 0);
+ msleep(20);
+ himax_rst_gpio_set(private_ts->rst_gpio, 1);
+#if 0
+ msleep(20);
+#endif
+}
+
+void himax_reload_config(void)
+{
+ if(himax_report_data_init())
+ E("%s: allocate data fail\n",__func__);
+
+ himax_sense_on(private_ts->client, 0x00);
+}
+
+void himax_irq_switch(int switch_on)
+{
+ int ret = 0;
+ if(switch_on)
+ {
+
+ if (private_ts->use_irq)
+ himax_int_enable(private_ts->client->irq,switch_on);
+ else
+ hrtimer_start(&private_ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
+ }
+ else
+ {
+ if (private_ts->use_irq)
+ himax_int_enable(private_ts->client->irq,switch_on);
+ else
+ {
+ hrtimer_cancel(&private_ts->timer);
+ ret = cancel_work_sync(&private_ts->work);
+ }
+ }
+}
+
+void himax_ic_reset(uint8_t loadconfig,uint8_t int_off)
+{
+#ifdef HX_RST_PIN_FUNC
+if (reset_flag ==1){
+ struct himax_ts_data *ts = private_ts;
+
+ HX_HW_RESET_ACTIVATE = 1;
+
+ I("%s,status: loadconfig=%d,int_off=%d\n",__func__,loadconfig,int_off);
+
+ if (ts->rst_gpio)
+ {
+ if(int_off)
+ {
+ himax_irq_switch(0);
+ }
+
+ himax_pin_reset();
+ if(loadconfig)
+ {
+ himax_reload_config();
+ }
+ if(int_off)
+ {
+ himax_irq_switch(1);
+ }
+ }
+}
+#endif
+}
+#endif
+
+#if defined(HX_ESD_RECOVERY)
+int g_zero_event_count = 0;
+int himax_ic_esd_recovery(int hx_esd_event,int hx_zero_event,int length)
+{
+ if(g_zero_event_count > 5)
+ {
+ g_zero_event_count = 0;
+ I("[HIMAX TP MSG]: ESD event checked - ALL Zero.\n");
+ goto checksum_fail;
+ }
+
+ if(hx_esd_event == length)
+ {
+ g_zero_event_count = 0;
+ goto checksum_fail;
+ }
+ else if(hx_zero_event == length)
+ {
+ g_zero_event_count++;
+ I("[HIMAX TP MSG]: ALL Zero event is %d times.\n",g_zero_event_count);
+ goto err_workqueue_out;
+ }
+
+checksum_fail:
+ return CHECKSUM_FAIL;
+err_workqueue_out:
+ return WORK_OUT;
+}
+void himax_esd_ic_reset(void)
+{
+ /*Nothing to do in incell,need to follow display reset*/
+}
+#endif
+
+int himax_hand_shaking(struct i2c_client *client) //0:Running, 1:Stop, 2:I2C Fail
+{
+ int result = 0;
+
+ return result;
+}
+
+void himax_idle_mode(struct i2c_client *client,int disable)
+{
+ int retry = 20;
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+ uint8_t switch_cmd = 0x00;
+
+ I("%s:entering\n",__func__);
+ do
+ {
+
+ I("%s,now %d times\n!",__func__,retry);
+
+ tmp_addr[3] = 0x10;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x70;
+ tmp_addr[0] = 0x88;
+ himax_register_read(client, tmp_addr, 4, tmp_data, false);
+
+ if(disable)
+ switch_cmd = 0x17;
+ else
+ switch_cmd = 0x1F;
+
+ tmp_data[0] = switch_cmd;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ himax_register_read(client, tmp_addr, 4, tmp_data, false);
+ I("%s:After turn ON/OFF IDLE Mode [0] = 0x%02X,[1] = 0x%02X,[2] = 0x%02X,[3] = 0x%02X\n", __func__,tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3]);
+
+ retry--;
+ msleep(10);
+
+ }
+ while((tmp_data[0] != switch_cmd) && retry > 0);
+
+ I("%s: setting OK!\n",__func__);
+
+}
+
+int himax_write_read_reg(struct i2c_client *client,uint8_t *tmp_addr,uint8_t *tmp_data,uint8_t hb,uint8_t lb)
+{
+ int cnt = 0;
+
+ do
+ {
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ msleep(10);
+ himax_register_read(client, tmp_addr, 4, tmp_data, false);
+ //I("%s:Now tmp_data[0]=0x%02X,[1]=0x%02X,[2]=0x%02X,[3]=0x%02X\n",__func__,tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3]);
+ }
+ while((tmp_data[1] != hb && tmp_data[0] != lb) && cnt++ < 100);
+
+ if(cnt == 99)
+ return -1;
+
+ I("Now register 0x%08X : high byte=0x%02X,low byte=0x%02X\n",tmp_addr[3],tmp_data[1],tmp_data[0]);
+ return NO_ERR;
+}
+
+int himax_determin_diag_rawdata(int diag_command)
+{
+ return diag_command%10;
+}
+
+int himax_determin_diag_storage(int diag_command)
+{
+ return diag_command/10;
+}
+
+void himax_reload_disable(struct i2c_client *client)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+
+ I("%s:entering\n",__func__);
+
+ tmp_addr[3] = 0x10; tmp_addr[2] = 0x00; tmp_addr[1] = 0x7F; tmp_addr[0] = 0x00;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0xA5; tmp_data[0] = 0x5A;
+
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ I("%s: setting OK!\n",__func__);
+}
+
+int himax_switch_mode(struct i2c_client *client,int mode)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+ uint8_t mode_wirte_cmd;
+ uint8_t mode_read_cmd;
+ int result = -1;
+ int retry = 200;
+
+ I("%s: Entering\n",__func__);
+
+ if(mode == 0) /*normal mode*/
+ {
+ mode_wirte_cmd = 0x00;
+ mode_read_cmd = 0x99;
+ }
+ else /*sorting mode*/
+ {
+ mode_wirte_cmd = 0xAA;
+ mode_read_cmd = 0xCC;
+ }
+
+ himax_sense_off(client);
+
+ //himax_interface_on(client);
+
+ /* */
+
+ /* clean up FW status */
+ tmp_addr[3] = 0x10;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x00;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+ //msleep(30);
+
+ tmp_addr[3] = 0x10;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x7F;
+ tmp_addr[0] = 0x04;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = mode_wirte_cmd;
+ tmp_data[0] = mode_wirte_cmd;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+ //msleep(30);
+
+ himax_idle_mode(client,1);
+ himax_reload_disable(client);
+
+ // To stable the sorting //skip frames
+ if(mode)
+ {
+ tmp_addr[3] = 0x10;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x70;
+ tmp_addr[0] = 0xF4;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x08;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+ }
+ else
+ {
+ tmp_addr[3] = 0x10;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x72;
+ tmp_addr[0] = 0x94;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x50;/*0x50 normal mode 80 frame*/
+ /* N Frame Sorting*/
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ tmp_addr[3] = 0x10;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x70;
+ tmp_addr[0] = 0xF4;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x14;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+ }
+
+ himax_sense_on(client,0x01);
+ I("mode_wirte_cmd(0)=0x%2.2X,mode_wirte_cmd(1)=0x%2.2X\n",tmp_data[0],tmp_data[1]);
+ while(retry!=0)
+ {
+ I("[%d]Read 10007F04!\n",retry);
+ tmp_addr[3] = 0x10;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x7F;
+ tmp_addr[0] = 0x04;
+ himax_register_read(client, tmp_addr, 4, tmp_data, false);
+ msleep(100);
+ I("mode_read_cmd(0)=0x%2.2X,mode_read_cmd(1)=0x%2.2X\n",tmp_data[0],tmp_data[1]);
+ if(tmp_data[0] == mode_read_cmd && tmp_data[1] == mode_read_cmd)
+ {
+ I("Read OK!\n");
+ result = 0;
+ break;
+ }
+ tmp_addr[3] = 0x90;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0xA8;
+ himax_register_read(client, tmp_addr, 4, tmp_data, false);
+ if(tmp_data[0] == 0x00 && tmp_data[1] == 0x00 && tmp_data[2] == 0x00 && tmp_data[3] == 0x00)
+ {
+ E("%s,: FW Stop!\n",__func__);
+ break;
+ }
+ retry--;
+ }
+
+ if(result == 0)
+ {
+ if(mode == 0)
+ return 1; //normal mode
+ else
+ return 2; //sorting mode
+ }
+ else
+ return -1; //change mode fail
+}
+
+void himax_return_event_stack(struct i2c_client *client)
+{
+ int retry = 20;
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+
+ I("%s:entering\n",__func__);
+ do
+ {
+
+ I("%s,now %d times\n!",__func__,retry);
+ tmp_addr[3] = 0x10;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x00;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ himax_register_read(client, tmp_addr, 4, tmp_data, false);
+ retry--;
+ msleep(10);
+
+ }
+ while((tmp_data[1] != 0x00 && tmp_data[0] != 0x00) && retry > 0);
+
+ I("%s: End of setting!\n",__func__);
+
+}
+
+void himax_diag_register_set(struct i2c_client *client, uint8_t diag_command)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+
+ I("diag_command = %d\n", diag_command );
+
+ himax_interface_on(client);
+
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x02;
+ tmp_addr[1] = 0x04;
+ tmp_addr[0] = 0xB4;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = diag_command;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ himax_register_read(client, tmp_addr, 4, tmp_data, false);
+ I("%s: tmp_data[3]=0x%02X,tmp_data[2]=0x%02X,tmp_data[1]=0x%02X,tmp_data[0]=0x%02X!\n",
+ __func__,tmp_data[3],tmp_data[2],tmp_data[1],tmp_data[0]);
+
+}
+
+void himax_init_psl(struct i2c_client *client) //power saving level
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+
+ //==============================================================
+ // SCU_Power_State_PW : 0x9000_00A0 ==> 0x0000_0000 (Reset PSL)
+ //==============================================================
+ tmp_addr[3] = 0x90;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0xA0;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x00;
+ himax_register_write(client, tmp_addr, 4, tmp_data, false);
+
+ I("%s: power saving level reset OK!\n",__func__);
+}
+
+void himax_flash_dump_func(struct i2c_client *client, uint8_t local_flash_command, int Flash_Size, uint8_t *flash_buffer)
+{
+ uint8_t tmp_addr[4];
+ uint8_t buffer[256];
+ int page_prog_start = 0;
+
+ himax_sense_off(client);
+ himax_burst_enable(client, 1);
+
+ for (page_prog_start = 0; page_prog_start < Flash_Size; page_prog_start = page_prog_start + 128)
+ {
+
+ tmp_addr[0] = page_prog_start % 0x100;
+ tmp_addr[1] = (page_prog_start >> 8) % 0x100;
+ tmp_addr[2] = (page_prog_start >> 16) % 0x100;
+ tmp_addr[3] = page_prog_start / 0x1000000;
+ himax_register_read(client, tmp_addr,128,buffer,false);
+ memcpy(&flash_buffer[page_prog_start],buffer,128);
+ }
+
+ himax_burst_enable(client, 0);
+ himax_sense_on(client, 0x01);
+
+ return;
+
+}
+
+int himax_chip_self_test(struct i2c_client *client)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[128];
+ uint8_t self_test_info[24];
+ int pf_value=0x00;
+ uint8_t test_result_id = 0;
+ int i;
+
+ memset(tmp_addr, 0x00, sizeof(tmp_addr));
+ memset(tmp_data, 0x00, sizeof(tmp_data));
+
+ himax_interface_on(client);
+ himax_sense_off(client);
+
+
+ himax_burst_enable(client, 1);
+
+ // 0x10007f18 -> 0x00006AA6
+ tmp_addr[3] = 0x10;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x7F;
+ tmp_addr[0] = 0x18;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x6A;
+ tmp_data[0] = 0xA6;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+ //Set criteria 0x10007F1C [0,1]=aa/up,down=, [2-3]=key/up,down, [4-5]=avg/up,down
+ tmp_addr[3] = 0x10;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x7F;
+ tmp_addr[0] = 0x1C;
+ if(IC_TYPE == HX_83112A_SERIES_PWON)
+ {
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x64;
+ tmp_data[1] = 0x08;
+ tmp_data[0] = 0x32;
+ tmp_data[7] = 0x00;
+ tmp_data[6] = 0x00;
+ tmp_data[5] = 0x00;
+ tmp_data[4] = 0x64;
+ }
+ else/*HX_83112B_SERIES_PWON*/
+ {
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x64;
+ tmp_data[1] = 0x0F;
+ tmp_data[0] = 0x46;
+ tmp_data[7] = 0x00;
+ tmp_data[6] = 0x00;
+ tmp_data[5] = 0x00;
+ tmp_data[4] = 0x64;
+ }
+ himax_flash_write_burst_lenth(client, tmp_addr, tmp_data, 8);
+ // 0x10007294 -> 0x0000190 //SET IIR_MAX FRAMES
+ tmp_addr[3] = 0x10;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x7F;
+ tmp_addr[0] = 0x00;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x01;
+ tmp_data[0] = 0x90;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ //Disable IDLE Mode
+ himax_idle_mode(client,1);
+
+ // 0x10007f00 -> 0x0000A55A //Diable Flash Reload
+ tmp_addr[3] = 0x10;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x7F;
+ tmp_addr[0] = 0x00;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0xA5;
+ tmp_data[0] = 0x5A;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+
+ //start selftest // leave safe mode
+ himax_sense_on(client, 1);
+
+ //Hand shaking -> 0x100007f8 waiting 0xA66A
+ for(i = 0; i < 1000; i++)
+ {
+ tmp_addr[3] = 0x10;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x7F;
+ tmp_addr[0] = 0x18;
+ himax_register_read(client, tmp_addr, 4, tmp_data, false);
+ I("%s: tmp_data[0] = 0x%02X,tmp_data[1] = 0x%02X,tmp_data[2] = 0x%02X,tmp_data[3] = 0x%02X, cnt=%d\n", __func__,tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3],i);
+ msleep(10);
+ if(tmp_data[1] == 0xA6 && tmp_data[0] == 0x6A )
+ {
+ I("%s Data ready goto moving data\n", __func__);
+ break;
+ }
+ }
+
+ himax_sense_off(client);
+ msleep(20);
+
+ //=====================================
+ // Read test result ID : 0x10007f24 ==> bit[2][1][0] = [key][AA][avg] => 0xF = PASS
+ //=====================================
+ tmp_addr[3] = 0x10;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x7F;
+ tmp_addr[0] = 0x24;
+ himax_register_read(client, tmp_addr, 24, self_test_info, false);
+
+ test_result_id = self_test_info[0];
+
+ I("%s: check test result, test_result_id=%x, test_result=%x\n", __func__
+ ,test_result_id,self_test_info[0]);
+
+ I("raw top 1 = %d\n",self_test_info[3]*256+self_test_info[2]);
+ I("raw top 2 = %d\n",self_test_info[5]*256+self_test_info[4]);
+ I("raw top 3 = %d\n",self_test_info[7]*256+self_test_info[6]);
+
+ I("raw last 1 = %d\n",self_test_info[9]*256+self_test_info[8]);
+ I("raw last 2 = %d\n",self_test_info[11]*256+self_test_info[10]);
+ I("raw last 3 = %d\n",self_test_info[13]*256+self_test_info[12]);
+
+ I("raw key 1 = %d\n",self_test_info[15]*256+self_test_info[14]);
+ I("raw key 2 = %d\n",self_test_info[17]*256+self_test_info[16]);
+ I("raw key 3 = %d\n",self_test_info[19]*256+self_test_info[18]);
+
+ if (test_result_id==0xAA)
+ {
+ I("[Himax]: self-test pass\n");
+ pf_value = 0x1;
+ }
+ else
+ {
+ E("[Himax]: self-test fail\n");
+ /* E("[Himax]: bank_avg = %d, bank_max = %d,%d,%d, bank_min = %d,%d,%d, key = %d,%d,%d\n",
+ tmp_data[1],tmp_data[2],tmp_data[3],tmp_data[4],tmp_data[5],tmp_data[6],tmp_data[7],
+ tmp_data[8],tmp_data[9],tmp_data[10]); */
+ pf_value = 0x0;
+ }
+
+ //Enable IDLE Mode
+ himax_idle_mode(client,0);
+
+ // 0x10007f00 -> 0x00000000 //Enable Flash Reload //recovery
+ tmp_addr[3] = 0x10;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x7F;
+ tmp_addr[0] = 0x00;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ himax_sense_on(client, 0);
+ msleep(120);
+
+ return pf_value;
+}
+
+void himax_set_HSEN_enable(struct i2c_client *client, uint8_t HSEN_enable, bool suspended)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+ uint8_t back_data[4];
+ uint8_t retry_cnt = 0;
+
+ himax_sense_off(client);
+
+ //Enable:0x10007F14 = 0xA55AA55A
+ do
+ {
+ if(HSEN_enable)
+ {
+ tmp_addr[3] = 0x10;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x7F;
+ tmp_addr[0] = 0x14;
+ tmp_data[3] = 0xA5;
+ tmp_data[2] = 0x5A;
+ tmp_data[1] = 0xA5;
+ tmp_data[0] = 0x5A;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+ back_data[3] = 0XA5;
+ back_data[2] = 0X5A;
+ back_data[1] = 0XA5;
+ back_data[0] = 0X5A;
+ }
+ else
+ {
+ tmp_addr[3] = 0x10;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x7F;
+ tmp_addr[0] = 0x14;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+ back_data[3] = 0X00;
+ back_data[2] = 0X00;
+ back_data[1] = 0X00;
+ back_data[0] = 0x00;
+ }
+ himax_register_read(client, tmp_addr, 4, tmp_data, false);
+ //I("%s: tmp_data[0]=%d, HSEN_enable=%d, retry_cnt=%d \n", __func__, tmp_data[0],HSEN_enable,retry_cnt);
+ retry_cnt++;
+ }
+ while((tmp_data[3] != back_data[3] || tmp_data[2] != back_data[2] || tmp_data[1] != back_data[1] || tmp_data[0] != back_data[0] ) && retry_cnt < HIMAX_REG_RETRY_TIMES);
+
+ himax_sense_on(client,0);
+}
+
+int himax_palm_detect(uint8_t *buf)
+{
+
+ return GESTURE_DETECT_FAIL;
+
+}
+
+void himax_set_SMWP_enable(struct i2c_client *client, uint8_t SMWP_enable, bool suspended)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+ uint8_t back_data[4];
+ uint8_t retry_cnt = 0;
+
+ himax_sense_off(client);
+
+ //Enable:0x10007F10 = 0xA55AA55A
+ do
+ {
+ if(SMWP_enable)
+ {
+ tmp_addr[3] = 0x10;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x7F;
+ tmp_addr[0] = 0x10;
+ tmp_data[3] = 0xA5;
+ tmp_data[2] = 0x5A;
+ tmp_data[1] = 0xA5;
+ tmp_data[0] = 0x5A;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+ back_data[3] = 0XA5;
+ back_data[2] = 0X5A;
+ back_data[1] = 0XA5;
+ back_data[0] = 0X5A;
+ }
+ else
+ {
+ tmp_addr[3] = 0x10;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x7F;
+ tmp_addr[0] = 0x10;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+ back_data[3] = 0X00;
+ back_data[2] = 0X00;
+ back_data[1] = 0X00;
+ back_data[0] = 0x00;
+ }
+ himax_register_read(client, tmp_addr, 4, tmp_data, false);
+ //I("%s: tmp_data[0]=%d, SMWP_enable=%d, retry_cnt=%d \n", __func__, tmp_data[0],SMWP_enable,retry_cnt);
+ retry_cnt++;
+ }
+ while((tmp_data[3] != back_data[3] || tmp_data[2] != back_data[2] || tmp_data[1] != back_data[1] || tmp_data[0] != back_data[0] ) && retry_cnt < HIMAX_REG_RETRY_TIMES);
+
+ himax_sense_on(client,0);
+
+}
+
+void himax_usb_detect_set(struct i2c_client *client,uint8_t *cable_config)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+
+ //Enable:0x10007F38 = 0xA55AA55A
+
+ if(cable_config[1] == 0x01)
+ {
+ tmp_addr[3] = 0x10;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x7F;
+ tmp_addr[0] = 0x38;
+ tmp_data[3] = 0xA5;
+ tmp_data[2] = 0x5A;
+ tmp_data[1] = 0xA5;
+ tmp_data[0] = 0x5A;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+ }
+ else
+ {
+ tmp_addr[3] = 0x10;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x7F;
+ tmp_addr[0] = 0x38;
+ tmp_data[3] = 0x77;
+ tmp_data[2] = 0x88;
+ tmp_data[1] = 0x77;
+ tmp_data[0] = 0x88;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+ }
+}
+
+void himax_burst_enable(struct i2c_client *client, uint8_t auto_add_4_byte)
+{
+ uint8_t tmp_data[4];
+
+ tmp_data[0] = 0x31;
+ if ( i2c_himax_write(client, 0x13,tmp_data, 1, DEFAULT_RETRY_CNT) < 0)
+ {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ tmp_data[0] = (0x10 | auto_add_4_byte);
+ if ( i2c_himax_write(client, 0x0D,tmp_data, 1, DEFAULT_RETRY_CNT) < 0)
+ {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ //isBusrtOn = true;
+}
+
+void himax_register_read(struct i2c_client *client, uint8_t *read_addr, int read_length, uint8_t *read_data, bool cfg_flag)
+{
+ uint8_t tmp_data[4];
+ int i = 0;
+ int address = 0;
+ if(cfg_flag == false)
+ {
+ if(read_length>256)
+ {
+ E("%s: read len over 256!\n", __func__);
+ return;
+ }
+ if (read_length > 4)
+ himax_burst_enable(client, 1);
+ else
+ himax_burst_enable(client, 0);
+
+ address = (read_addr[3] << 24) + (read_addr[2] << 16) + (read_addr[1] << 8) + read_addr[0];
+ i = address;
+ tmp_data[0] = (uint8_t)i;
+ tmp_data[1] = (uint8_t)(i >> 8);
+ tmp_data[2] = (uint8_t)(i >> 16);
+ tmp_data[3] = (uint8_t)(i >> 24);
+ if ( i2c_himax_write(client, 0x00,tmp_data, 4, DEFAULT_RETRY_CNT) < 0)
+ {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+ tmp_data[0] = 0x00;
+ if ( i2c_himax_write(client, 0x0C,tmp_data, 1, DEFAULT_RETRY_CNT) < 0)
+ {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ if ( i2c_himax_read(client, 0x08,read_data, read_length, DEFAULT_RETRY_CNT) < 0)
+ {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+ if (read_length > 4)
+ himax_burst_enable(client, 0);
+ }
+ else if(cfg_flag == true)
+ {
+ if(i2c_himax_read(client, read_addr[0], read_data,read_length,DEFAULT_RETRY_CNT) < 0)
+ {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+ }
+ else
+ {
+ E("%s: cfg_flag = %d, value is wrong!\n", __func__,cfg_flag);
+ return;
+ }
+}
+
+void himax_flash_write_burst(struct i2c_client *client, uint8_t * reg_byte, uint8_t * write_data)
+{
+ uint8_t data_byte[8];
+ int i = 0, j = 0;
+
+ for (i = 0; i < 4; i++)
+ {
+ data_byte[i] = reg_byte[i];
+ }
+ for (j = 4; j < 8; j++)
+ {
+ data_byte[j] = write_data[j-4];
+ }
+
+ if ( i2c_himax_write(client, 0x00,data_byte, 8, DEFAULT_RETRY_CNT) < 0)
+ {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+}
+
+void himax_flash_write_burst_lenth(struct i2c_client *client, uint8_t *reg_byte, uint8_t *write_data, int length)
+{
+ uint8_t data_byte[256];
+ int i = 0, j = 0;
+
+ for (i = 0; i < 4; i++)
+ {
+ data_byte[i] = reg_byte[i];
+ }
+ for (j = 4; j < length + 4; j++)
+ {
+ data_byte[j] = write_data[j - 4];
+ }
+
+ if ( i2c_himax_write(client, 0x00,data_byte, length + 4, DEFAULT_RETRY_CNT) < 0)
+ {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+}
+
+void himax_register_write(struct i2c_client *client, uint8_t *write_addr, int write_length, uint8_t *write_data, bool cfg_flag)
+{
+ int i =0, address = 0;
+ if(cfg_flag == false)
+ {
+ address = (write_addr[3] << 24) + (write_addr[2] << 16) + (write_addr[1] << 8) + write_addr[0];
+
+ for (i = address; i < address + write_length; i++)
+ {
+ if (write_length > 4)
+ {
+ himax_burst_enable(client, 1);
+ }
+ else
+ {
+ himax_burst_enable(client, 0);
+ }
+ himax_flash_write_burst_lenth(client, write_addr, write_data, write_length);
+ }
+ }
+ else if(cfg_flag == true)
+ {
+ if(i2c_himax_write(client, write_addr[0], write_data,write_length,DEFAULT_RETRY_CNT) < 0)
+ {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+ }
+ else
+ {
+ E("%s: cfg_flag = %d, value is wrong!\n", __func__,cfg_flag);
+ return;
+ }
+}
+
+bool himax_sense_off(struct i2c_client *client)
+{
+ uint8_t cnt = 0;
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+ /*1225 for power on test*/
+ //=====================================
+ // FW ISR=0
+ //=====================================
+ tmp_addr[3] = 0x90;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x5C;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0xA5;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+ msleep(20);
+ /*1225 for power on test*/
+ do
+ {
+ //===========================================
+ // 0x31 ==> 0x27
+ //===========================================
+ tmp_data[0] = 0x27;
+ if ( i2c_himax_write(client, 0x31,tmp_data, 1, DEFAULT_RETRY_CNT) < 0)
+ {
+ E("%s: i2c access fail!\n", __func__);
+ return false;
+ }
+ //===========================================
+ // 0x32 ==> 0x95
+ //===========================================
+ tmp_data[0] = 0x95;
+ if ( i2c_himax_write(client, 0x32,tmp_data, 1, DEFAULT_RETRY_CNT) < 0)
+ {
+ E("%s: i2c access fail!\n", __func__);
+ return false;
+ }
+
+ // ======================
+ // Check enter_save_mode
+ // ======================
+ tmp_addr[3] = 0x90;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0xA8;
+ himax_register_read(client, tmp_addr, 4, tmp_data, false);
+
+ I("%s: Check enter_save_mode data[0]=%X \n", __func__,tmp_data[0]);
+
+ if (tmp_data[0] == 0x0C)
+ {
+ //=====================================
+ // Reset TCON
+ //=====================================
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x02;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+ msleep(1);
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x01;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ //=====================================
+ // Reset ADC
+ //=====================================
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x02;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x94;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+ msleep(1);
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x01;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+ return true;
+ }
+ else
+ {
+ msleep(10);
+#ifdef HX_RST_PIN_FUNC
+ himax_ic_reset(false,false);
+#endif
+ }
+ }
+ while (cnt++ < 15);
+
+ return false;
+}
+bool himax_enter_safe_mode(struct i2c_client *client)
+{
+ uint8_t cnt = 0;
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+
+ do
+ {
+ //===========================================
+ // 0x31 ==> 0x27
+ //===========================================
+ tmp_data[0] = 0x27;
+ if ( i2c_himax_write(client, 0x31,tmp_data, 1, DEFAULT_RETRY_CNT) < 0)
+ {
+ E("%s: i2c access fail!\n", __func__);
+ return false;
+ }
+ //===========================================
+ // 0x32 ==> 0x95
+ //===========================================
+ tmp_data[0] = 0x95;
+ if ( i2c_himax_write(client, 0x32,tmp_data, 1, DEFAULT_RETRY_CNT) < 0)
+ {
+ E("%s: i2c access fail!\n", __func__);
+ return false;
+ }
+
+ //===========================================
+ // 0x31 ==> 0x00
+ //===========================================
+ tmp_data[0] = 0x00;
+ if ( i2c_himax_write(client, 0x31,tmp_data, 1, DEFAULT_RETRY_CNT) < 0)
+ {
+ E("%s: i2c access fail!\n", __func__);
+ return false;
+ }
+ msleep(10);
+ //===========================================
+ // 0x31 ==> 0x27
+ //===========================================
+ tmp_data[0] = 0x27;
+ if ( i2c_himax_write(client, 0x31,tmp_data, 1, DEFAULT_RETRY_CNT) < 0)
+ {
+ E("%s: i2c access fail!\n", __func__);
+ return false;
+ }
+ //===========================================
+ // 0x32 ==> 0x95
+ //===========================================
+ tmp_data[0] = 0x95;
+ if ( i2c_himax_write(client, 0x32,tmp_data, 1, DEFAULT_RETRY_CNT) < 0)
+ {
+ E("%s: i2c access fail!\n", __func__);
+ return false;
+ }
+
+ // ======================
+ // Check enter_save_mode
+ // ======================
+ tmp_addr[3] = 0x90;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0xA8;
+ himax_register_read(client, tmp_addr, 4, tmp_data, false);
+
+ I("%s: Check enter_save_mode data[0]=%X \n", __func__,tmp_data[0]);
+
+ if (tmp_data[0] == 0x0C)
+ {
+ //=====================================
+ // Reset TCON
+ //=====================================
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x02;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+ msleep(1);
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x01;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ //=====================================
+ // Reset ADC
+ //=====================================
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x02;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x94;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+ msleep(1);
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x01;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+ return true;
+ }
+ else
+ {
+ msleep(10);
+#ifdef HX_RST_PIN_FUNC
+ himax_ic_reset(false,false);
+#endif
+ }
+ }
+ while (cnt++ < 15);
+
+ return false;
+}
+void himax_interface_on(struct i2c_client *client)
+{
+ uint8_t tmp_data[5];
+ uint8_t tmp_data2[2];
+ int cnt = 0;
+
+ //Read a dummy register to wake up I2C.
+ if ( i2c_himax_read(client, 0x08, tmp_data,4,DEFAULT_RETRY_CNT) < 0) // to knock I2C
+ {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ do
+ {
+ //===========================================
+ // Enable continuous burst mode : 0x13 ==> 0x31
+ //===========================================
+ tmp_data[0] = 0x31;
+ if ( i2c_himax_write(client, 0x13,tmp_data, 1, DEFAULT_RETRY_CNT) < 0)
+ {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+ //===========================================
+ // AHB address auto +4 : 0x0D ==> 0x11
+ // Do not AHB address auto +4 : 0x0D ==> 0x10
+ //===========================================
+ tmp_data[0] = (0x10);
+ if ( i2c_himax_write(client, 0x0D,tmp_data, 1, DEFAULT_RETRY_CNT) < 0)
+ {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ // Check cmd
+ i2c_himax_read(client, 0x13, tmp_data,1,DEFAULT_RETRY_CNT);
+ i2c_himax_read(client, 0x0D, tmp_data2,1,DEFAULT_RETRY_CNT);
+
+ if (tmp_data[0] == 0x31 && tmp_data2[0] == 0x10)
+ {
+ //isBusrtOn = true;
+ break;
+ }
+ msleep(1);
+ }
+ while (++cnt < 10);
+
+ if (cnt > 0)
+ I("%s:Polling burst mode: %d times", __func__,cnt);
+
+}
+
+bool wait_wip(struct i2c_client *client, int Timing)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+ uint8_t in_buffer[10];
+ //uint8_t out_buffer[20];
+ int retry_cnt = 0;
+
+ //=====================================
+ // SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
+ //=====================================
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x10;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x02;
+ tmp_data[1] = 0x07;
+ tmp_data[0] = 0x80;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ in_buffer[0] = 0x01;
+
+ do
+ {
+ //=====================================
+ // SPI Transfer Control : 0x8000_0020 ==> 0x4200_0003
+ //=====================================
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x42;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x03;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ //=====================================
+ // SPI Command : 0x8000_0024 ==> 0x0000_0005
+ // read 0x8000_002C for 0x01, means wait success
+ //=====================================
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x05;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ in_buffer[0] = in_buffer[1] = in_buffer[2] = in_buffer[3] = 0xFF;
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x2C;
+ himax_register_read(client, tmp_addr, 4, in_buffer, false);
+
+ if ((in_buffer[0] & 0x01) == 0x00)
+ return true;
+
+ retry_cnt++;
+
+ if (in_buffer[0] != 0x00 || in_buffer[1] != 0x00 || in_buffer[2] != 0x00 || in_buffer[3] != 0x00)
+ I("%s:Wait wip retry_cnt:%d, buffer[0]=%d, buffer[1]=%d, buffer[2]=%d, buffer[3]=%d \n", __func__,
+ retry_cnt,in_buffer[0],in_buffer[1],in_buffer[2],in_buffer[3]);
+
+ if (retry_cnt > 100)
+ {
+ E("%s: Wait wip error!\n", __func__);
+ return false;
+ }
+ msleep(Timing);
+ }
+ while ((in_buffer[0] & 0x01) == 0x01);
+ return true;
+}
+
+void himax_sense_on(struct i2c_client *client, uint8_t FlashMode)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+ int retry = 0;
+
+ I("Enter %s \n", __func__);
+
+ himax_interface_on(client);
+
+ if(!FlashMode)
+ {
+#ifdef HX_RST_PIN_FUNC
+ himax_ic_reset(false,false);
+#else
+ //===AHBI2C_SystemReset==========
+ tmp_addr[3] = 0x90;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x18;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x55;
+ himax_register_write(client, tmp_addr, 4, tmp_data, false);
+#endif
+ }
+ else
+ {
+ do
+ {
+ tmp_addr[3] = 0x90;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x98;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x53;
+ himax_register_write(client, tmp_addr, 4, tmp_data, false);
+
+ tmp_addr[0] = 0xE4;
+ himax_register_read(client, tmp_addr, 4, tmp_data, false);
+
+ I("%s:Read status from IC = %X,%X\n", __func__, tmp_data[0],tmp_data[1]);
+
+ }
+ while((tmp_data[1] != 0x01 || tmp_data[0] != 0x00) && retry++ < 5);
+
+ if(retry >= 5)
+ {
+ E("%s: Fail:\n", __func__);
+#ifdef HX_RST_PIN_FUNC
+ himax_ic_reset(false,false);
+#else
+ //===AHBI2C_SystemReset==========
+ tmp_addr[3] = 0x90;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x18;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x55;
+ himax_register_write(client, tmp_addr, 4, tmp_data, false);
+#endif
+ }
+ else
+ {
+ I("%s:OK and Read status from IC = %X,%X\n", __func__, tmp_data[0],tmp_data[1]);
+
+ /* reset code*/
+ tmp_data[0] = 0x00;
+ if ( i2c_himax_write(client, 0x31,tmp_data, 1, DEFAULT_RETRY_CNT) < 0)
+ {
+ E("%s: i2c access fail!\n", __func__);
+ }
+ if ( i2c_himax_write(client, 0x32,tmp_data, 1, DEFAULT_RETRY_CNT) < 0)
+ {
+ E("%s: i2c access fail!\n", __func__);
+ }
+
+ tmp_addr[3] = 0x90;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x98;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x00;
+ himax_register_write(client, tmp_addr, 4, tmp_data, false);
+ }
+ }
+}
+
+void himax_chip_erase(struct i2c_client *client)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+
+ himax_interface_on(client);
+
+ /* init psl */
+ himax_init_psl(client);
+
+ //=====================================
+ // SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
+ //=====================================
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x10;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x02;
+ tmp_data[1] = 0x07;
+ tmp_data[0] = 0x80;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ //=====================================
+ // Chip Erase
+ // Write Enable : 1. 0x8000_0020 ==> 0x4700_0000
+ // 2. 0x8000_0024 ==> 0x0000_0006
+ //=====================================
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x47;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x06;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ //=====================================
+ // Chip Erase
+ // Erase Command : 0x8000_0024 ==> 0x0000_00C7
+ //=====================================
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0xC7;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ msleep(2000);
+
+ if (!wait_wip(client, 100))
+ E("%s:83112_Chip_Erase Fail\n", __func__);
+
+}
+
+bool himax_block_erase(struct i2c_client *client)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+
+ himax_burst_enable(client, 0);
+
+ //=====================================
+ // SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
+ //=====================================
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x10;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x02;
+ tmp_data[1] = 0x07;
+ tmp_data[0] = 0x80;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ //=====================================
+ // Chip Erase
+ // Write Enable : 1. 0x8000_0020 ==> 0x4700_0000
+ // 2. 0x8000_0024 ==> 0x0000_0006
+ //=====================================
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x47;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x06;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ //=====================================
+ // Block Erase
+ // Erase Command : 0x8000_0028 ==> 0x0000_0000 //SPI addr
+ // 0x8000_0020 ==> 0x6700_0000 //control
+ // 0x8000_0024 ==> 0x0000_0052 //BE
+ //=====================================
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x28;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x67;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x52;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ msleep(1000);
+
+ if (!wait_wip(client, 100))
+ {
+ E("%s:83112_Erase Fail\n", __func__);
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+
+}
+
+bool himax_sector_erase(struct i2c_client *client, int start_addr)
+{
+ return true;
+}
+
+void himax_sram_write(struct i2c_client *client, uint8_t *FW_content)
+{
+
+}
+
+bool himax_sram_verify(struct i2c_client *client, uint8_t *FW_File, int FW_Size)
+{
+ return true;
+}
+
+void himax_flash_programming(struct i2c_client *client, uint8_t *FW_content, int FW_Size)
+{
+ int page_prog_start = 0;
+ int program_length = 48;
+ int i = 0, j = 0, k = 0;
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+ uint8_t buring_data[256]; // Read for flash data, 128K
+ // 4 bytes for 0x80002C padding
+
+ himax_interface_on(client);
+
+ //=====================================
+ // SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
+ //=====================================
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x10;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x02;
+ tmp_data[1] = 0x07;
+ tmp_data[0] = 0x80;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ for (page_prog_start = 0; page_prog_start < FW_Size; page_prog_start = page_prog_start + 256)
+ {
+ //msleep(5);
+ //=====================================
+ // Write Enable : 1. 0x8000_0020 ==> 0x4700_0000
+ // 2. 0x8000_0024 ==> 0x0000_0006
+ //=====================================
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x47;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x06;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ //=================================
+ // SPI Transfer Control
+ // Set 256 bytes page write : 0x8000_0020 ==> 0x610F_F000
+ // Set read start address : 0x8000_0028 ==> 0x0000_0000
+ //=================================
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x61;
+ tmp_data[2] = 0x0F;
+ tmp_data[1] = 0xF0;
+ tmp_data[0] = 0x00;
+ // data bytes should be 0x6100_0000 + ((word_number)*4-1)*4096 = 0x6100_0000 + 0xFF000 = 0x610F_F000
+ // Programmable size = 1 page = 256 bytes, word_number = 256 byte / 4 = 64
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x28;
+ //tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00; // Flash start address 1st : 0x0000_0000
+
+ if (page_prog_start < 0x100)
+ {
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = (uint8_t)page_prog_start;
+ }
+ else if (page_prog_start >= 0x100 && page_prog_start < 0x10000)
+ {
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = (uint8_t)(page_prog_start >> 8);
+ tmp_data[0] = (uint8_t)page_prog_start;
+ }
+ else if (page_prog_start >= 0x10000 && page_prog_start < 0x1000000)
+ {
+ tmp_data[3] = 0x00;
+ tmp_data[2] = (uint8_t)(page_prog_start >> 16);
+ tmp_data[1] = (uint8_t)(page_prog_start >> 8);
+ tmp_data[0] = (uint8_t)page_prog_start;
+ }
+
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+
+ //=================================
+ // Send 16 bytes data : 0x8000_002C ==> 16 bytes data
+ //=================================
+ buring_data[0] = 0x2C;
+ buring_data[1] = 0x00;
+ buring_data[2] = 0x00;
+ buring_data[3] = 0x80;
+
+ for (i = /*0*/page_prog_start, j = 0; i < 16 + page_prog_start/**/; i++, j++) /// <------ bin file
+ {
+ buring_data[j + 4] = FW_content[i];
+ }
+
+
+ if ( i2c_himax_write(client, 0x00,buring_data, 20, DEFAULT_RETRY_CNT) < 0)
+ {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+ //=================================
+ // Write command : 0x8000_0024 ==> 0x0000_0002
+ //=================================
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x02;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ //=================================
+ // Send 240 bytes data : 0x8000_002C ==> 240 bytes data
+ //=================================
+
+ for (j = 0; j < 5; j++)
+ {
+ for (i = (page_prog_start + 16 + (j * 48)), k = 0; i < (page_prog_start + 16 + (j * 48)) + program_length; i++, k++) /// <------ bin file
+ {
+ buring_data[k+4] = FW_content[i];//(byte)i;
+ }
+
+ if ( i2c_himax_write(client, 0x00,buring_data, program_length+4, DEFAULT_RETRY_CNT) < 0)
+ {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ }
+
+ if (!wait_wip(client, 1))
+ E("%s:83112_Flash_Programming Fail\n", __func__);
+ }
+}
+
+
+bool himax_check_chip_version(struct i2c_client *client)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+ uint8_t ret_data = false;
+ int i = 0;
+
+ for (i = 0; i < 5; i++)
+ {
+ // Product ID
+ // Touch
+ tmp_addr[3] = 0x90;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0xD0;
+ himax_register_read(client, tmp_addr, 4, tmp_data, false);
+
+ I("%s:Read driver IC ID = %X,%X,%X\n", __func__, tmp_data[3],tmp_data[2],tmp_data[1]);
+ if ((tmp_data[3] == 0x83) && (tmp_data[2] == 0x11) && (tmp_data[1] == 0x2a))
+ {
+ IC_TYPE = HX_83112A_SERIES_PWON;
+ ret_data = true;
+ break;
+ }
+ else if ((tmp_data[3] == 0x83) && (tmp_data[2] == 0x11) && (tmp_data[1] == 0x2b))
+ {
+ IC_TYPE = HX_83112B_SERIES_PWON;
+ ret_data = true;
+ break;
+ }
+ else
+ {
+ ret_data = false;
+ E("%s:Read driver ID register Fail:\n", __func__);
+ }
+ }
+
+ return ret_data;
+}
+
+bool Calculate_CRC_with_AP(unsigned char *FW_content, int CRC_from_FW, int mode)
+{
+ return true;
+}
+
+uint32_t himax_hw_check_CRC(struct i2c_client *client, uint8_t *start_addr, int reload_length)
+{
+ uint32_t result = 0;
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+ int cnt = 0;
+ int length = reload_length / 4;
+
+ //CRC4 // 0x8005_0020 <= from, 0x8005_0028 <= 0x0099_length
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x05;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x20;
+ //tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0xFB; tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, start_addr);
+
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x05;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x28;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x99;
+ tmp_data[1] = (length >> 8);
+ tmp_data[0] = length;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ cnt = 0;
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x05;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x00;
+ do
+ {
+ himax_register_read(client, tmp_addr, 4, tmp_data, false);
+
+ if ((tmp_data[0] & 0x01) != 0x01)
+ {
+ tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x05;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x18;
+ himax_register_read(client, tmp_addr, 4, tmp_data, false);
+ I("%s: tmp_data[3]=%X, tmp_data[2]=%X, tmp_data[1]=%X, tmp_data[0]=%X \n", __func__, tmp_data[3], tmp_data[2], tmp_data[1], tmp_data[0]);
+ result = ((tmp_data[3] << 24) + (tmp_data[2] << 16) + (tmp_data[1] << 8) + tmp_data[0]);
+ break;
+ }
+ }
+ while (cnt++ < 100);
+
+ return result;
+}
+
+void himax_flash_page_write(struct i2c_client *client, uint8_t *write_addr, uint8_t *write_data)
+{
+
+}
+
+void himax_set_reload_cmd(uint8_t *write_data, int idx, uint32_t cmd_from, uint32_t cmd_to, uint32_t cmd_beat)
+{
+ int index = idx * 12;
+ int i;
+ for (i = 3; i >= 0; i--)
+ {
+ write_data[index + i] = (cmd_from >> (8 * i));
+ write_data[index + 4 + i] = (cmd_to >> (8 * i));
+ write_data[index + 8 + i] = (cmd_beat >> (8 * i));
+ }
+}
+
+bool himax_program_reload(struct i2c_client *client)
+{
+ return true;
+}
+
+int fts_ctpm_fw_upgrade_with_sys_fs_32k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref)
+{
+ /* Not use */
+ return 0;
+}
+
+int fts_ctpm_fw_upgrade_with_sys_fs_60k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref)
+{
+ /* Not use */
+ return 0;
+}
+
+int fts_ctpm_fw_upgrade_with_sys_fs_64k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref) //Alice - Un
+{
+
+ //int CRC_from_FW = 0;
+ int burnFW_success = 0;
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+
+ if (len != FW_SIZE_64k) //64k
+ {
+ E("%s: The file size is not 64K bytes\n", __func__);
+ return false;
+ }
+
+#ifdef HX_RST_PIN_FUNC
+ himax_ic_reset(false,false);
+#else
+ //===AHBI2C_SystemReset==========
+ tmp_addr[3] = 0x90;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x18;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x55;
+ himax_register_write(client, tmp_addr, 4, tmp_data, false);
+#endif
+
+ himax_enter_safe_mode(client);
+ himax_chip_erase(client);
+ himax_flash_programming(client, fw, FW_SIZE_64k);
+
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x00;
+
+ if(himax_hw_check_CRC(client,tmp_data, FW_SIZE_64k) == 0)
+ {
+ burnFW_success = 1;
+ }
+ else
+ {
+ burnFW_success = 0;
+ }
+ /*RawOut select initial*/
+ tmp_addr[3] = 0x80;tmp_addr[2] = 0x02;tmp_addr[1] = 0x04;tmp_addr[0] = 0xB4;
+ tmp_data[3] = 0x00;tmp_data[2] = 0x00;tmp_data[1] = 0x00;tmp_data[0] = 0x00;
+ himax_register_write(client,tmp_addr, 4, tmp_data, false);
+
+ /*DSRAM func initial*/
+ tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x07;tmp_addr[0] = 0xFC;
+ tmp_data[3] = 0x00;tmp_data[2] = 0x00;tmp_data[1] = 0x00;tmp_data[0] = 0x00;
+ himax_register_write(client,tmp_addr, 4, tmp_data, false);
+
+#ifdef HX_RST_PIN_FUNC
+ himax_ic_reset(true,false);
+#else
+ //===AHBI2C_SystemReset==========
+ tmp_addr[3] = 0x90;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x18;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x55;
+ himax_register_write(client, tmp_addr, 4, tmp_data, false);
+#endif
+ msleep(800);
+ himax_read_FW_ver(private_ts->client);
+ return burnFW_success;
+
+}
+
+int fts_ctpm_fw_upgrade_with_sys_fs_124k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref)
+{
+ /* Not use */
+ return 0;
+}
+
+int fts_ctpm_fw_upgrade_with_sys_fs_128k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref)
+{
+ /* Not use */
+ return 0;
+}
+
+void himax_touch_information(struct i2c_client *client)
+{
+#ifndef HX_FIX_TOUCH_INFO
+ uint8_t cmd[4];
+ char data[12] = {0};
+
+ I("%s:IC_TYPE =%d\n", __func__,IC_TYPE);
+
+ //if(IC_TYPE == HX_83112A_SERIES_PWON)
+ if((IC_TYPE == HX_83112A_SERIES_PWON)||(IC_TYPE == HX_83112B_SERIES_PWON))
+ {
+ cmd[3] = 0x10;
+ cmd[2] = 0x00;
+ cmd[1] = 0x70;
+ cmd[0] = 0xF4;
+ himax_register_read(client, cmd, 8, data, false);
+ ic_data->HX_RX_NUM = data[2];
+ ic_data->HX_TX_NUM = data[3];
+ ic_data->HX_MAX_PT = data[4];
+ //I("%s : HX_RX_NUM=%d,ic_data->HX_TX_NUM=%d,ic_data->HX_MAX_PT=%d\n",__func__,ic_data->HX_RX_NUM,ic_data->HX_TX_NUM,ic_data->HX_MAX_PT);
+
+ cmd[3] = 0x10;
+ cmd[2] = 0x00;
+ cmd[1] = 0x70;
+ cmd[0] = 0xFA;
+ himax_register_read(client, cmd, 4, data, false);
+ //I("%s : c_data->HX_XY_REVERSE=0x%2.2X\n",__func__,data[1]);
+ if((data[1] & 0x04) == 0x04)
+ {
+ ic_data->HX_XY_REVERSE = true;
+ }
+ else
+ {
+ ic_data->HX_XY_REVERSE = false;
+ }
+
+ cmd[3] = 0x10;
+ cmd[2] = 0x00;
+ cmd[1] = 0x70;
+ cmd[0] = 0xFC;
+ himax_register_read(client, cmd, 4, data, false);
+ ic_data->HX_Y_RES = data[0]*256;
+ ic_data->HX_Y_RES = ic_data->HX_Y_RES + data[1];
+ ic_data->HX_X_RES = data[2]*256 + data[3];
+ //I("%s : ic_data->HX_Y_RES=%d,ic_data->HX_X_RES=%d \n",__func__,ic_data->HX_Y_RES,ic_data->HX_X_RES);
+
+ cmd[3] = 0x10;
+ cmd[2] = 0x00;
+ cmd[1] = 0x70;
+ cmd[0] = 0x89;
+ himax_register_read(client, cmd, 4, data, false);
+ //I("%s : data[0]=0x%2.2X,data[1]=0x%2.2X,data[2]=0x%2.2X,data[3]=0x%2.2X\n",__func__,data[0],data[1],data[2],data[3]);
+ //I("data[0] & 0x01 = %d\n",(data[0] & 0x01));
+ if((data[0] & 0x01) == 1)
+ {
+ ic_data->HX_INT_IS_EDGE = true;
+ }
+ else
+ {
+ ic_data->HX_INT_IS_EDGE = false;
+ }
+
+ if (ic_data->HX_RX_NUM > 40)
+ ic_data->HX_RX_NUM = 32;
+ if (ic_data->HX_TX_NUM > 20)
+ ic_data->HX_TX_NUM = 18;
+ if (ic_data->HX_MAX_PT > 10)
+ ic_data->HX_MAX_PT = 10;
+ if (ic_data->HX_Y_RES > 2000)
+ ic_data->HX_Y_RES = 1280;
+ if (ic_data->HX_X_RES > 2000)
+ ic_data->HX_X_RES = 720;
+
+ /*Read number of MKey R100070E8H*/
+ cmd[3] = 0x10;
+ cmd[2] = 0x00;
+ cmd[1] = 0x70;
+ cmd[0] = 0xE8;
+ himax_register_read(client, cmd, 4,data, false);
+ //I("%s: data[0] = 0x%02X,data[1] = 0x%02X,data[2] = 0x%02X,data[3] = 0x%02X\n", __func__,data[0],data[1],data[2],data[3]);
+ ic_data->HX_BT_NUM = data[0] & 0x03;
+ }
+ else
+ {
+ ic_data->HX_RX_NUM = 0;
+ ic_data->HX_TX_NUM = 0;
+ ic_data->HX_BT_NUM = 0;
+ ic_data->HX_X_RES = 0;
+ ic_data->HX_Y_RES = 0;
+ ic_data->HX_MAX_PT = 0;
+ ic_data->HX_XY_REVERSE = false;
+ ic_data->HX_INT_IS_EDGE = false;
+ }
+#else
+ if(IC_TYPE == HX_83112A_SERIES_PWON) {
+ ic_data->HX_RX_NUM = FIX_HX_RX_NUM;
+ ic_data->HX_TX_NUM = FIX_HX_TX_NUM;
+ ic_data->HX_BT_NUM = FIX_HX_BT_NUM;
+ ic_data->HX_X_RES = FIX_HX_X_RES;
+ ic_data->HX_Y_RES = FIX_HX_Y_RES;
+ ic_data->HX_MAX_PT = FIX_HX_MAX_PT;
+ ic_data->HX_XY_REVERSE = FIX_HX_XY_REVERSE;
+ ic_data->HX_INT_IS_EDGE = FIX_HX_INT_IS_EDGE;
+ }
+ else {
+ ic_data->HX_RX_NUM = SEC_FIX_HX_RX_NUM;
+ ic_data->HX_TX_NUM = SEC_FIX_HX_TX_NUM;
+ ic_data->HX_BT_NUM = SEC_FIX_HX_BT_NUM;
+ ic_data->HX_X_RES = SEC_FIX_HX_X_RES;
+ ic_data->HX_Y_RES = SEC_FIX_HX_Y_RES;
+ ic_data->HX_MAX_PT = SEC_FIX_HX_MAX_PT;
+ ic_data->HX_XY_REVERSE = SEC_FIX_HX_XY_REVERSE;
+ ic_data->HX_INT_IS_EDGE = SEC_FIX_HX_INT_IS_EDGE;
+ }
+#endif
+ I("%s:HX_RX_NUM =%d,HX_TX_NUM =%d,HX_MAX_PT=%d \n", __func__,ic_data->HX_RX_NUM,ic_data->HX_TX_NUM,ic_data->HX_MAX_PT);
+ I("%s:HX_XY_REVERSE =%d,HX_Y_RES =%d,HX_X_RES=%d \n", __func__,ic_data->HX_XY_REVERSE,ic_data->HX_Y_RES,ic_data->HX_X_RES);
+ I("%s:HX_INT_IS_EDGE =%d \n", __func__,ic_data->HX_INT_IS_EDGE);
+}
+
+int himax_read_i2c_status(struct i2c_client *client)
+{
+ return i2c_error_count; //
+}
+
+int himax_read_ic_trigger_type(struct i2c_client *client)
+{
+ uint8_t cmd[4];
+ char data[12] = {0};
+ int trigger_type = false;
+
+ cmd[3] = 0x10;
+ cmd[2] = 0x00;
+ cmd[1] = 0x70;
+ cmd[0] = 0x89;
+ himax_register_read(client, cmd, 4, data, false);
+ if((data[0] & 0x01) == 1)
+ {
+ trigger_type = true;
+ }
+ else
+ {
+ trigger_type = false;
+ }
+
+ return trigger_type;
+}
+
+void himax_read_FW_ver(struct i2c_client *client)
+{
+ uint8_t cmd[4];
+ uint8_t data[64];
+ uint8_t cmd_2[4];
+ uint8_t data_2[64];
+ int retry = 20;
+ int reload_status = 0;
+ while(reload_status == 0)
+ {
+ cmd[3] = 0x10;
+ cmd[2] = 0x00;
+ cmd[1] = 0x7f;
+ cmd[0] = 0x00;
+ himax_register_read(client, cmd, 4, data, false);
+
+ cmd_2[3] = 0x10;
+ cmd_2[2] = 0x00;
+ cmd_2[1] = 0x72;
+ cmd_2[0] = 0xc0;
+ himax_register_read(client, cmd_2, 4, data_2, false);
+
+ if((data[3]==0x00 && data[2]==0x00 && data[1]==0x3A && data[0]==0xA3 )
+ ||(data_2[3]==0x00 && data_2[2]==0x00 && data_2[1]==0x72 && data_2[0]==0xC0 ))
+ {
+ I("reload OK! \n");
+ reload_status = 1;
+ break;
+ }
+ else if(retry == 0)
+ {
+ E("reload 20 times! fail \n");
+ ic_data->vendor_panel_ver = 0;
+ ic_data->vendor_fw_ver = 0;
+ ic_data->vendor_config_ver = 0;
+ ic_data->vendor_touch_cfg_ver = 0;
+ ic_data->vendor_display_cfg_ver = 0;
+ ic_data->vendor_cid_maj_ver = 0;
+ ic_data->vendor_cid_min_ver = 0;
+ return;
+ }
+ else
+ {
+ I("%s: 0x10007f00, data[0]=%x,data[1]=%x,data[2]=%x,data[3]=%x \n", __func__, data[0],data[1],data[2],data[3]);
+ I("%s: 0x100072c0, data[0]=%x,data[1]=%x,data[2]=%x,data[3]=%x \n", __func__, data_2[0],data_2[1],data_2[2],data_2[3]);
+
+ cmd[3] = 0x90; cmd[2] = 0x00; cmd[1] = 0x00; cmd[0] = 0xA8;
+ himax_register_read(client, cmd, 4, data, false);
+ I("%s: 0x900000A8, data[0]=%x,data[1]=%x,data[2]=%x,data[3]=%x \n", __func__, data[0],data[1],data[2],data[3]);
+
+ cmd[3] = 0x90; cmd[2] = 0x00; cmd[1] = 0x00; cmd[0] = 0xE4;
+ himax_register_read(client, cmd, 4, data, false);
+ I("%s: 0x900000E4, data[0]=%x,data[1]=%x,data[2]=%x,data[3]=%x \n", __func__, data[0],data[1],data[2],data[3]);
+
+ cmd[3] = 0x10; cmd[2] = 0x00; cmd[1] = 0x7F; cmd[0] = 0x40;
+ himax_register_read(client, cmd, 4, data, false);
+ I("%s: 0x10007F40, data[0]=%x,data[1]=%x,data[2]=%x,data[3]=%x \n", __func__, data[0],data[1],data[2],data[3]);
+
+ retry --;
+ msleep(10);
+ I("reload fail ,delay 10ms retry=%d\n",retry);
+ }
+ }
+ I("%s : data[0]=0x%2.2X,data[1]=0x%2.2X,data[2]=0x%2.2X,data[3]=0x%2.2X\n",__func__,data[0],data[1],data[2],data[3]);
+ I("reload_status=%d\n",reload_status);
+
+ himax_sense_off(client);
+
+ //=====================================
+ // Read FW version : 0x1000_7004 but 05,06 are the real addr for FW Version
+ //=====================================
+
+ cmd[3] = 0x10;
+ cmd[2] = 0x00;
+ cmd[1] = 0x70;
+ cmd[0] = 0x04;
+ himax_register_read(client, cmd, 4, data, false);
+
+ ic_data->vendor_panel_ver = data[0];
+ ic_data->vendor_fw_ver = data[1] << 8 | data[2];
+ ic_data->vendor_hx_ic_id = data[3];
+
+ I("PANEL_VER : %X \n",ic_data->vendor_panel_ver);
+ I("FW_VER : %X \n",ic_data->vendor_fw_ver);
+ I("IC_ID : %X \n",ic_data->vendor_hx_ic_id);
+
+ cmd[3] = 0x10;
+ cmd[2] = 0x00;
+ cmd[1] = 0x70;
+ cmd[0] = 0x84;
+ himax_register_read(client, cmd, 4, data, false);
+
+ ic_data->vendor_config_ver = data[2] << 8 | data[3];
+ //I("CFG_VER : %X \n",ic_data->vendor_config_ver);
+ ic_data->vendor_touch_cfg_ver = data[2];
+ I("TOUCH_VER : %X \n",ic_data->vendor_touch_cfg_ver);
+ ic_data->vendor_display_cfg_ver = data[3];
+ I("DISPLAY_VER : %X \n",ic_data->vendor_display_cfg_ver);
+
+
+ cmd[3] = 0x10;
+ cmd[2] = 0x00;
+ cmd[1] = 0x70;
+ cmd[0] = 0x00;
+ himax_register_read(client, cmd, 4, data, false);
+
+ ic_data->vendor_cid_maj_ver = data[2] ;
+ ic_data->vendor_cid_min_ver = data[3];
+
+ I("CID_VER : %X \n",(ic_data->vendor_cid_maj_ver << 8 | ic_data->vendor_cid_min_ver));
+ return;
+}
+
+bool himax_ic_package_check(struct i2c_client *client)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+ uint8_t ret_data = 0x00;
+ int i = 0;
+
+ himax_enter_safe_mode(client);
+ for (i = 0; i < 5; i++)
+ {
+// Product ID
+ // Touch
+ tmp_addr[3] = 0x90;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0xD0;
+ himax_register_read(client, tmp_addr, 4, tmp_data, false);
+
+ I("%s:Read driver IC ID = %X,%X,%X\n", __func__, tmp_data[3],tmp_data[2],tmp_data[1]);
+ if ((tmp_data[3] == 0x83) && (tmp_data[2] == 0x11) && ((tmp_data[1] == 0x2a)||(tmp_data[1] == 0x2b)))
+ {
+ IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC;
+ //Himax: Set FW and CFG Flash Address
+ FW_VER_MAJ_FLASH_ADDR = 49157; //0x00C005
+ FW_VER_MAJ_FLASH_LENG = 1;
+ FW_VER_MIN_FLASH_ADDR = 49158; //0x00C006
+ FW_VER_MIN_FLASH_LENG = 1;
+ CFG_VER_MAJ_FLASH_ADDR = 49408; //0x00C100
+ CFG_VER_MAJ_FLASH_LENG = 1;
+ CFG_VER_MIN_FLASH_ADDR = 49409; //0x00C101
+ CFG_VER_MIN_FLASH_LENG = 1;
+ CID_VER_MAJ_FLASH_ADDR = 49154; //0x00C002
+ CID_VER_MAJ_FLASH_LENG = 1;
+ CID_VER_MIN_FLASH_ADDR = 49155; //0x00C003
+ CID_VER_MIN_FLASH_LENG = 1;
+ //PANEL_VERSION_ADDR = 49156; //0x00C004
+ //PANEL_VERSION_LENG = 1;
+ if ((tmp_data[3] == 0x83) && (tmp_data[2] == 0x11) && (tmp_data[1] == 0x2a))
+ {
+ IC_TYPE = HX_83112A_SERIES_PWON;
+#ifdef HX_AUTO_UPDATE_FW
+ g_i_FW_VER = i_CTPM_FW_HX83112A[FW_VER_MAJ_FLASH_ADDR]<<8 |i_CTPM_FW_HX83112A[FW_VER_MIN_FLASH_ADDR];
+ g_i_CFG_VER = i_CTPM_FW_HX83112A[CFG_VER_MAJ_FLASH_ADDR]<<8 |i_CTPM_FW_HX83112A[CFG_VER_MIN_FLASH_ADDR];
+ g_i_CID_MAJ = i_CTPM_FW_HX83112A[CID_VER_MAJ_FLASH_ADDR];
+ g_i_CID_MIN = i_CTPM_FW_HX83112A[CID_VER_MIN_FLASH_ADDR];
+#endif
+ }
+ else
+ {
+ IC_TYPE = HX_83112B_SERIES_PWON;
+#ifdef HX_AUTO_UPDATE_FW
+ printk("%s: (%d)No need check 2nd ic package\n", __func__, __LINE__);
+ g_i_FW_VER = i_CTPM_FW_HX83112B[FW_VER_MAJ_FLASH_ADDR]<<8 |i_CTPM_FW_HX83112B[FW_VER_MIN_FLASH_ADDR];
+ g_i_CFG_VER = i_CTPM_FW_HX83112B[CFG_VER_MAJ_FLASH_ADDR]<<8 |i_CTPM_FW_HX83112B[CFG_VER_MIN_FLASH_ADDR];
+ g_i_CID_MAJ = i_CTPM_FW_HX83112B[CID_VER_MAJ_FLASH_ADDR];
+ g_i_CID_MIN = i_CTPM_FW_HX83112B[CID_VER_MIN_FLASH_ADDR];
+#endif
+ }
+#if 0
+ IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC;
+ //Himax: Set FW and CFG Flash Address
+ FW_VER_MAJ_FLASH_ADDR = 49157; //0x00C005
+ FW_VER_MAJ_FLASH_LENG = 1;
+ FW_VER_MIN_FLASH_ADDR = 49158; //0x00C006
+ FW_VER_MIN_FLASH_LENG = 1;
+ CFG_VER_MAJ_FLASH_ADDR = 49408; //0x00C100
+ CFG_VER_MAJ_FLASH_LENG = 1;
+ CFG_VER_MIN_FLASH_ADDR = 49409; //0x00C101
+ CFG_VER_MIN_FLASH_LENG = 1;
+ CID_VER_MAJ_FLASH_ADDR = 49154; //0x00C002
+ CID_VER_MAJ_FLASH_LENG = 1;
+ CID_VER_MIN_FLASH_ADDR = 49155; //0x00C003
+ CID_VER_MIN_FLASH_LENG = 1;
+ //PANEL_VERSION_ADDR = 49156; //0x00C004
+ //PANEL_VERSION_LENG = 1;
+#endif
+#if 0
+ g_i_FW_VER = i_CTPM_FW[FW_VER_MAJ_FLASH_ADDR]<<8 |i_CTPM_FW[FW_VER_MIN_FLASH_ADDR];
+ g_i_CFG_VER = i_CTPM_FW[CFG_VER_MAJ_FLASH_ADDR]<<8 |i_CTPM_FW[CFG_VER_MIN_FLASH_ADDR];
+ g_i_CID_MAJ = i_CTPM_FW[CID_VER_MAJ_FLASH_ADDR];
+ g_i_CID_MIN = i_CTPM_FW[CID_VER_MIN_FLASH_ADDR];
+#endif
+ I("Himax IC package 83112_in\n");
+ ret_data = true;
+ himax_sense_on(client, 0);
+ break;
+ }
+ else
+ {
+ ret_data = false;
+ E("%s:Read driver ID register Fail:\n", __func__);
+ }
+ }
+
+ return ret_data;
+}
+
+void himax_power_on_init(struct i2c_client *client)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+
+ I("%s:\n", __func__);
+ himax_touch_information(client);
+
+ /*RawOut select initial*/
+ tmp_addr[3] = 0x80;tmp_addr[2] = 0x02;tmp_addr[1] = 0x04;tmp_addr[0] = 0xB4;
+ tmp_data[3] = 0x00;tmp_data[2] = 0x00;tmp_data[1] = 0x00;tmp_data[0] = 0x00;
+ himax_register_write(client,tmp_addr, 4, tmp_data, false);
+
+ /*DSRAM func initial*/
+ tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x07;tmp_addr[0] = 0xFC;
+ tmp_data[3] = 0x00;tmp_data[2] = 0x00;tmp_data[1] = 0x00;tmp_data[0] = 0x00;
+ himax_register_write(client,tmp_addr, 4, tmp_data, false);
+
+ himax_sense_on(client, 0x00);
+}
+
+bool himax_read_event_stack(struct i2c_client *client, uint8_t *buf, uint8_t length) //Alice - Un
+{
+ uint8_t cmd[4];
+
+ // AHB_I2C Burst Read Off
+ cmd[0] = 0x00;
+ if ( i2c_himax_write(client, 0x11,cmd, 1, DEFAULT_RETRY_CNT) < 0)
+ {
+ E("%s: i2c access fail!\n", __func__);
+ return 0;
+ }
+
+ i2c_himax_read(client, 0x30, buf, length,DEFAULT_RETRY_CNT);
+
+ // AHB_I2C Burst Read On
+ cmd[0] = 0x01;
+ if ( i2c_himax_write(client, 0x11,cmd, 1, 3) < 0)
+ {
+ E("%s: i2c access fail!\n", __func__);
+ return 0;
+ }
+ return 1;
+}
+
+void himax_get_DSRAM_data(struct i2c_client *client, uint8_t *info_data)
+{
+ int i = 0;
+ //int cnt = 0;
+ unsigned char tmp_addr[4];
+ unsigned char tmp_data[4];
+ uint8_t max_i2c_size = 128;
+ uint8_t x_num = ic_data->HX_RX_NUM;
+ uint8_t y_num = ic_data->HX_TX_NUM;
+ int m_key_num = 0;
+ int total_size = (x_num * y_num + x_num + y_num) * 2 + 4;
+ int total_size_temp;
+ int mutual_data_size = x_num * y_num * 2;
+ int total_read_times = 0;
+ int address = 0;
+ uint8_t *temp_info_data; //max mkey size = 8
+ uint16_t check_sum_cal = 0;
+ int fw_run_flag = -1;
+ //uint16_t temp_check_sum_cal = 0;
+
+ temp_info_data = kzalloc(sizeof(uint8_t)*(total_size + 8),GFP_KERNEL);
+
+ /*1. Read number of MKey R100070E8H to determin data size*/
+ m_key_num = ic_data->HX_BT_NUM;
+ //I("%s,m_key_num=%d\n",__func__,m_key_num);
+ total_size += m_key_num*2;
+
+ /* 2. Start DSRAM Rawdata and Wait Data Ready */
+ tmp_addr[3] = 0x10;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x00;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x5A;
+ tmp_data[0] = 0xA5;
+ fw_run_flag = himax_write_read_reg(client,tmp_addr,tmp_data,0xA5,0x5A);
+
+ if(fw_run_flag < 0)
+ {
+ I("%s Data NOT ready => bypass \n", __func__);
+ kfree(temp_info_data);
+ return;
+ }
+
+ /* 3. Read RawData */
+ total_size_temp = total_size;
+ tmp_addr[3] = 0x10;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x00;
+
+ if (total_size % max_i2c_size == 0)
+ {
+ total_read_times = total_size / max_i2c_size;
+ }
+ else
+ {
+ total_read_times = total_size / max_i2c_size + 1;
+ }
+
+ for (i = 0; i < (total_read_times); i++)
+ {
+ if ( total_size_temp >= max_i2c_size)
+ {
+ himax_register_read(client, tmp_addr, max_i2c_size, &temp_info_data[i*max_i2c_size], false);
+ total_size_temp = total_size_temp - max_i2c_size;
+ }
+ else
+ {
+ //I("last total_size_temp=%d\n",total_size_temp);
+ himax_register_read(client, tmp_addr, total_size_temp % max_i2c_size, &temp_info_data[i*max_i2c_size], false);
+ }
+
+ address = ((i+1)*max_i2c_size);
+ tmp_addr[1] = (uint8_t)((address>>8)&0x00FF);
+ tmp_addr[0] = (uint8_t)((address)&0x00FF);
+ }
+
+ /* 4. FW stop outputing */
+ //I("DSRAM_Flag=%d\n",DSRAM_Flag);
+ if(DSRAM_Flag == false)
+ {
+ //I("Return to Event Stack!\n");
+ tmp_addr[3] = 0x10;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x00;
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+ }
+ else
+ {
+ //I("Continue to SRAM!\n");
+ tmp_addr[3] = 0x10;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = 0x00;
+ tmp_data[3] = 0x11;
+ tmp_data[2] = 0x22;
+ tmp_data[1] = 0x33;
+ tmp_data[0] = 0x44;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+ }
+
+ /* 5. Data Checksum Check */
+ for (i = 2; i < total_size; i=i+2)/* 2:PASSWORD NOT included */
+ {
+ check_sum_cal += (temp_info_data[i+1]*256 + temp_info_data[i]);
+ }
+
+ if (check_sum_cal % 0x10000 != 0)
+ {
+ I("%s check_sum_cal fail=%2X \n", __func__, check_sum_cal);
+ kfree(temp_info_data);
+ return;
+ }
+ else
+ {
+ memcpy(info_data, &temp_info_data[4], mutual_data_size * sizeof(uint8_t));
+ //I("%s checksum PASS \n", __func__);
+ }
+ kfree(temp_info_data);
+}
+
+bool himax_calculateChecksum(struct i2c_client *client, bool change_iref)
+{
+ uint8_t CRC_result = 0;
+ uint8_t tmp_data[4];
+
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = 0x00;
+
+ CRC_result = himax_hw_check_CRC(client,tmp_data, FW_SIZE_64k);
+
+ msleep(50);
+
+ return !CRC_result;
+}
+
+//ts_work
+int cal_data_len(int raw_cnt_rmd, int HX_MAX_PT, int raw_cnt_max)
+{
+ int RawDataLen;
+ if (raw_cnt_rmd != 0x00)
+ {
+ RawDataLen = 128 - ((HX_MAX_PT+raw_cnt_max+3)*4) - 1;
+ }
+ else
+ {
+ RawDataLen = 128 - ((HX_MAX_PT+raw_cnt_max+2)*4) - 1;
+ }
+ return RawDataLen;
+}
+
+bool diag_check_sum( struct himax_report_data *hx_touch_data ) //return checksum value
+{
+ uint16_t check_sum_cal = 0;
+ int i;
+
+ //Check 128th byte CRC
+ for (i = 0, check_sum_cal = 0; i < (hx_touch_data->touch_all_size - hx_touch_data->touch_info_size); i=i+2)
+ {
+ check_sum_cal += (hx_touch_data->hx_rawdata_buf[i+1]*256 + hx_touch_data->hx_rawdata_buf[i]);
+ }
+ if (check_sum_cal % 0x10000 != 0)
+ {
+ I("%s fail=%2X \n", __func__, check_sum_cal);
+ return 0;
+ //goto bypass_checksum_failed_packet;
+ }
+
+ return 1;
+}
+
+
+void diag_parse_raw_data(struct himax_report_data *hx_touch_data,int mul_num, int self_num,uint8_t diag_cmd, int32_t *mutual_data, int32_t *self_data)
+{
+ int RawDataLen_word;
+ int index = 0;
+ int temp1, temp2,i;
+
+ if (hx_touch_data->hx_rawdata_buf[0] == 0x3A
+ && hx_touch_data->hx_rawdata_buf[1] == 0xA3
+ && hx_touch_data->hx_rawdata_buf[2] > 0
+ && hx_touch_data->hx_rawdata_buf[3] == diag_cmd )
+ {
+ RawDataLen_word = hx_touch_data->rawdata_size/2;
+ index = (hx_touch_data->hx_rawdata_buf[2] - 1) * RawDataLen_word;
+ //I("Header[%d]: %x, %x, %x, %x, mutual: %d, self: %d\n", index, buf[56], buf[57], buf[58], buf[59], mul_num, self_num);
+ //I("RawDataLen=%d , RawDataLen_word=%d , hx_touch_info_size=%d\n", RawDataLen, RawDataLen_word, hx_touch_info_size);
+ for (i = 0; i < RawDataLen_word; i++)
+ {
+ temp1 = index + i;
+
+ if (temp1 < mul_num)
+ {
+ //mutual
+ mutual_data[index + i] = hx_touch_data->hx_rawdata_buf[i*2 + 4 + 1]*256 + hx_touch_data->hx_rawdata_buf[i*2 + 4]; //4: RawData Header, 1:HSB
+ }
+ else
+ {
+ //self
+ temp1 = i + index;
+ temp2 = self_num + mul_num;
+
+ if (temp1 >= temp2)
+ {
+ break;
+ }
+ self_data[i+index-mul_num] = hx_touch_data->hx_rawdata_buf[i*2 + 4]; //4: RawData Header
+ self_data[i+index-mul_num+1] = hx_touch_data->hx_rawdata_buf[i*2 + 4 + 1];
+ }
+ }
+ }
+
+}
+uint8_t himax_read_DD_status(uint8_t *cmd_set, uint8_t *tmp_data)
+{
+ int cnt = 0;
+ uint8_t req_size = cmd_set[0];
+ uint8_t cmd_addr[4] = {0xFC, 0x00, 0x00, 0x90}; //0x900000FC -> cmd and hand shaking
+ uint8_t tmp_addr[4] = {0x80, 0x7F, 0x00, 0x10}; //0x10007F80 -> data space
+
+ cmd_set[3] = 0xAA;
+ himax_register_write(private_ts->client, cmd_addr, 4, cmd_set, 0);
+
+ I("%s: cmd_set[0] = 0x%02X,cmd_set[1] = 0x%02X,cmd_set[2] = 0x%02X,cmd_set[3] = 0x%02X\n", __func__,cmd_set[0],cmd_set[1],cmd_set[2],cmd_set[3]);
+
+ for (cnt = 0; cnt < 100; cnt++) //doing hand shaking 0xAA -> 0xBB
+ {
+ himax_register_read(private_ts->client, cmd_addr, 4, tmp_data, false);
+ //I("%s: tmp_data[0] = 0x%02X,tmp_data[1] = 0x%02X,tmp_data[2] = 0x%02X,tmp_data[3] = 0x%02X, cnt=%d\n", __func__,tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3],cnt);
+ msleep(10);
+ if(tmp_data[3] == 0xBB)
+ {
+ I("%s Data ready goto moving data\n", __func__);
+ break;
+ }
+ else if(cnt >= 99)
+ {
+ I("%s Data not ready in FW \n", __func__);
+ return FW_NOT_READY;
+ }
+ }
+ himax_register_read(private_ts->client, tmp_addr, req_size, tmp_data, false);
+ return NO_ERR;
+}
+
+int himax_read_FW_status(uint8_t *state_addr, uint8_t *tmp_addr)
+{
+ uint8_t req_size = 0;
+ uint8_t status_addr[4] = {0x44, 0x7F, 0x00, 0x10}; //0x10007F44
+ uint8_t cmd_addr[4] = {0xF8, 0x00, 0x00, 0x90}; //0x900000F8
+
+ if(state_addr[0]==0x01)
+ {
+ state_addr[1]= 0x04;
+ state_addr[2]= status_addr[0];state_addr[3]= status_addr[1];state_addr[4]= status_addr[2];state_addr[5]= status_addr[3];
+ req_size = 0x04;
+ himax_sense_off(private_ts->client);
+ himax_register_read(private_ts->client, status_addr, req_size, tmp_addr, false);
+ himax_sense_on(private_ts->client,1);
+ }
+ else if(state_addr[0]==0x02)
+ {
+ state_addr[1]= 0x30;
+ state_addr[2]= cmd_addr[0];state_addr[3]= cmd_addr[1];state_addr[4]= cmd_addr[2];state_addr[5]= cmd_addr[3];
+ req_size = 0x30;
+ himax_register_read(private_ts->client, cmd_addr, req_size, tmp_addr, false);
+ }
+
+ return NO_ERR;
+}
+
+#if defined(HX_SMART_WAKEUP)||defined(HX_HIGH_SENSE)||defined(HX_USB_DETECT_GLOBAL)
+void himax_resend_cmd_func(bool suspended)
+{
+ struct himax_ts_data *ts;
+
+ ts = private_ts;
+
+#ifdef HX_SMART_WAKEUP
+ himax_set_SMWP_enable(ts->client,ts->SMWP_enable,suspended);
+#endif
+#ifdef HX_HIGH_SENSE
+ himax_set_HSEN_enable(ts->client,ts->HSEN_enable,suspended);
+#endif
+#ifdef HX_USB_DETECT_GLOBAL
+ himax_cable_detect_func(true);
+#endif
+}
+#endif
+
+void himax_resume_ic_action(struct i2c_client *client)
+{
+ return;
+}
+
+void himax_suspend_ic_action(struct i2c_client *client)
+{
+ return;
+}
+
+#ifdef HX_ZERO_FLASH
+int G_POWERONOF = 1;
+void himax_sys_reset(void)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+
+ // 0x10007f00 -> 0x0000A55A //Diable Flash Reload
+ tmp_addr[3] = 0x10; tmp_addr[2] = 0x00; tmp_addr[1] = 0x7F; tmp_addr[0] = 0x00;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x9A; tmp_data[0] = 0xA9;
+ himax_flash_write_burst(private_ts->client,tmp_addr, tmp_data);
+
+ msleep(100);
+
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x18;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x55;
+ himax_register_write(private_ts->client,tmp_addr, 4, tmp_data, false);
+}
+void himax_clean_sram_0f(uint8_t *addr,int write_len,int type)
+{
+ int total_read_times = 0;
+ int max_bus_size = 128;
+ int total_size_temp = 0;
+ int total_size = 0;
+ int address = 0;
+ int i = 0;
+
+ uint8_t fix_data = 0x00;
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[128]={0};
+
+ I("%s,Entering \n",__func__);
+
+ total_size = write_len;
+
+ total_size_temp = write_len;
+
+ I("[log]enable start!\n");
+ himax_burst_enable(private_ts->client,1);
+ I("[log]enable end!\n");
+
+ tmp_addr[3] = addr[3]; tmp_addr[2] = addr[2]; tmp_addr[1] = addr[1]; tmp_addr[0] = addr[0];
+ I("%s, write addr tmp_addr[3]=0x%2.2X, tmp_addr[2]=0x%2.2X, tmp_addr[1]=0x%2.2X, tmp_addr[0]=0x%2.2X\n",__func__,tmp_addr[3],tmp_addr[2],tmp_addr[1],tmp_addr[0]);
+
+
+ switch(type)
+ {
+ case 0:
+ fix_data = 0x00;
+ break;
+ case 1:
+ fix_data = 0xAA;
+ break;
+ case 2:
+ fix_data = 0xBB;
+ break;
+ }
+
+ for(i = 0;i<128;i++)
+ {
+ tmp_data[i] = fix_data;
+ }
+
+
+ I("%s, total size=%d\n",__func__,total_size);
+
+ if (total_size_temp % max_bus_size == 0)
+ {
+ total_read_times = total_size_temp / max_bus_size;
+ }
+ else
+ {
+ total_read_times = total_size_temp / max_bus_size + 1;
+ }
+
+ for (i = 0; i < (total_read_times); i++)
+ {
+ I("[log]write %d time start!\n",i);
+ if ( total_size_temp >= max_bus_size)
+ {
+ himax_flash_write_burst_lenth(private_ts->client,tmp_addr,tmp_data, max_bus_size);
+ total_size_temp = total_size_temp - max_bus_size;
+ }
+ else
+ {
+ I("last total_size_temp=%d\n",total_size_temp);
+ himax_flash_write_burst_lenth(private_ts->client,tmp_addr,tmp_data, total_size_temp % max_bus_size);
+ }
+ address = ((i+1)*max_bus_size);
+ tmp_addr[1] = addr[1] + (uint8_t)((address>>8)&0x00FF);
+ tmp_addr[0] = addr[0] + (uint8_t)((address)&0x00FF);
+
+ msleep(10);
+ }
+
+ I("%s,END \n",__func__);
+}
+
+void himax_write_sram_0f(const struct firmware *fw_entry,uint8_t *addr,int start_index,int write_len)
+{
+ int total_read_times = 0;
+ int max_bus_size = 128;
+ int total_size_temp = 0;
+ int total_size = 0;
+ int address = 0;
+ int i = 0;
+
+ uint8_t tmp_addr[4];
+ uint8_t *tmp_data;
+ uint32_t now_addr;
+
+ I("%s,Entering \n",__func__);
+
+ total_size = 65536;
+
+ total_size_temp = write_len;
+
+ I("[log]enable start!\n");
+ himax_burst_enable(private_ts->client,1);
+ I("[log]enable end!\n");
+
+ tmp_addr[3] = addr[3]; tmp_addr[2] = addr[2]; tmp_addr[1] = addr[1]; tmp_addr[0] = addr[0];
+ I("%s, write addr tmp_addr[3]=0x%2.2X, tmp_addr[2]=0x%2.2X, tmp_addr[1]=0x%2.2X, tmp_addr[0]=0x%2.2X\n",__func__,tmp_addr[3],tmp_addr[2],tmp_addr[1],tmp_addr[0]);
+ now_addr = (addr[3] << 24) + (addr[2] << 16) + (addr[1] << 8) + addr[0];
+ I("now addr= 0x%08X\n",now_addr);
+
+ I("%s, total size=%d\n",__func__,total_size);
+
+ //I("[log]locate start!\n");
+ tmp_data = kzalloc(sizeof(uint8_t)*total_size,GFP_KERNEL);
+ //I("[log]enable end!\n");
+ //I("[log]memcpy start!\n");
+ memcpy(tmp_data,fw_entry->data,total_size);
+ //I("[log]memcpy end!\n");
+
+ I("tmp_data size=%d\n",(int)sizeof(tmp_data));
+
+ for(i = 0;i<10;i++)
+ {
+ I("[%d] 0x%2.2X",i,tmp_data[i]);
+ }
+ I("\n");
+ if (total_size_temp % max_bus_size == 0)
+ {
+ total_read_times = total_size_temp / max_bus_size;
+ }
+ else
+ {
+ total_read_times = total_size_temp / max_bus_size + 1;
+ }
+
+ for (i = 0; i < (total_read_times); i++)
+ {
+ I("[log]write %d time start!\n",i);
+ if ( total_size_temp >= max_bus_size)
+ {
+ himax_flash_write_burst_lenth(private_ts->client,tmp_addr,&(tmp_data[start_index+i*max_bus_size]), max_bus_size);
+ total_size_temp = total_size_temp - max_bus_size;
+ }
+ else
+ {
+ I("last total_size_temp=%d\n",total_size_temp);
+ himax_flash_write_burst_lenth(private_ts->client,tmp_addr,&(tmp_data[start_index+i*max_bus_size]), total_size_temp % max_bus_size);
+ }
+ I("[log]write %d time end!\n",i);
+ address = ((i+1)*max_bus_size);
+ tmp_addr[0] = addr[0] + (uint8_t)((address)&0x00FF);
+ if(tmp_addr[0] < addr[0])
+ tmp_addr[1] = addr[1] + (uint8_t)((address>>8)&0x00FF) + 1;
+ else
+ tmp_addr[1] = addr[1] + (uint8_t)((address>>8)&0x00FF);
+
+
+ msleep(10);
+ }
+ I("%s,END \n",__func__);
+ kfree(tmp_data);
+}
+
+void himax_firmware_update_0f(const struct firmware *fw_entry)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+
+ I("%s,Entering \n",__func__);
+
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x18;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x55;
+ himax_register_write(private_ts->client,tmp_addr, 4, tmp_data, false);
+
+ himax_sense_off(private_ts->client);
+
+ himax_chip_erase(private_ts->client);
+
+ /* first 48K */
+ tmp_addr[3] = 0x08;tmp_addr[2] = 0x00;tmp_addr[1] = 0x00;tmp_addr[0] = 0x00;
+ himax_write_sram_0f(fw_entry,tmp_addr,0,0xC000);
+
+
+ /* clean */
+ if(G_POWERONOF == 1)
+ {
+ tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x00;tmp_addr[0] = 0x00;
+ himax_clean_sram_0f(tmp_addr,32768,0);
+ }
+
+ /*last 16k*/
+ /*config info*/
+ tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x70;tmp_addr[0] = 0x00;
+ if(G_POWERONOF == 1)
+ himax_write_sram_0f(fw_entry,tmp_addr,0xC000,132);
+ else
+ himax_clean_sram_0f(tmp_addr,132,2);
+ /*FW config*/
+ tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x70;tmp_addr[0] = 0x84;
+ if(G_POWERONOF == 1)
+ himax_write_sram_0f(fw_entry,tmp_addr,0xC0FE,512); //0xc100-2
+ else
+ himax_clean_sram_0f(tmp_addr,512,1);
+ /*ADC config*/
+ tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x78;tmp_addr[0] = 0x00;
+ if(G_POWERONOF == 1)
+ himax_write_sram_0f(fw_entry,tmp_addr,0xD000,376);
+ else
+ himax_clean_sram_0f(tmp_addr,376,2);
+
+ tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x79;tmp_addr[0] = 0x78;
+ if(G_POWERONOF == 1)
+ himax_write_sram_0f(fw_entry,tmp_addr,0xD178,376);
+ else
+ himax_clean_sram_0f(tmp_addr,376,2);
+
+ tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x7A;tmp_addr[0] = 0xF0;
+ if(G_POWERONOF == 1)
+ himax_write_sram_0f(fw_entry,tmp_addr,0xD000,376);
+ else
+ himax_clean_sram_0f(tmp_addr,376,2);
+
+ //G_POWERONOF = 0;
+
+ I("%s,END \n",__func__);
+}
+void himax_0f_operation(struct work_struct *work)
+{
+ int err = NO_ERR;
+ const struct firmware *fw_entry = NULL;
+ char *firmware_name = "himax.bin";
+ uint8_t tmp_data[4];
+
+ I("%s,Entering \n",__func__);
+ I("file name = %s\n",firmware_name);
+ err = request_firmware(&fw_entry, firmware_name, private_ts->dev);
+ if (err < 0) {
+ E("%s,fail in line%d error code=%d\n",__func__,__LINE__,err);
+ //goto err_request_firmware;
+ return ;
+ }
+ himax_firmware_update_0f(fw_entry);
+ release_firmware(fw_entry);
+
+ tmp_data[0] = 0x00;tmp_data[1] = 0x00;tmp_data[2] = 0x00;tmp_data[3] = 0x08;
+ if(himax_hw_check_CRC(private_ts->client,tmp_data, 0xC000) == 0)
+ {
+ I("%s,HW CRC OK!\n",__func__);
+ }
+ else
+ {
+ E("%s,HW CRC FAIL!\n",__func__);
+ }
+
+ msleep(100);
+ himax_sys_reset();
+ msleep(100);
+ himax_int_enable(private_ts->client->irq,1);
+
+ I("%s,END \n",__func__);
+ return ;
+}
+
+#ifdef HX_0F_DEBUG
+void himax_read_sram_0f(const struct firmware *fw_entry,uint8_t *addr,int start_index,int read_len)
+{
+ int total_read_times = 0;
+ int max_i2c_size = 128;
+ int total_size_temp = 0;
+ int total_size = 0;
+ int address = 0;
+ int i = 0,j = 0;
+ int not_same = 0;
+
+ uint8_t tmp_addr[4];
+ uint8_t *temp_info_data;
+ int *not_same_buff;
+
+ I("%s,Entering \n",__func__);
+
+ himax_burst_enable(private_ts->client,1);
+
+ total_size = read_len;
+
+ total_size_temp = read_len;
+
+ temp_info_data = kzalloc(sizeof(uint8_t)*total_size,GFP_KERNEL);
+ not_same_buff = kzalloc(sizeof(int)*total_size,GFP_KERNEL);
+
+
+ tmp_addr[3] = addr[3]; tmp_addr[2] = addr[2]; tmp_addr[1] = addr[1]; tmp_addr[0] = addr[0];
+ I("%s, read addr tmp_addr[3]=0x%2.2X, tmp_addr[2]=0x%2.2X, tmp_addr[1]=0x%2.2X, tmp_addr[0]=0x%2.2X\n",__func__,tmp_addr[3],tmp_addr[2],tmp_addr[1],tmp_addr[0]);
+
+ I("%s, total size=%d\n",__func__,total_size);
+
+ himax_burst_enable(private_ts->client,1);
+
+ if (total_size % max_i2c_size == 0)
+ {
+ total_read_times = total_size / max_i2c_size;
+ }
+ else
+ {
+ total_read_times = total_size / max_i2c_size + 1;
+ }
+
+ for (i = 0; i < (total_read_times); i++)
+ {
+ if ( total_size_temp >= max_i2c_size)
+ {
+ himax_register_read(private_ts->client,tmp_addr, max_i2c_size, &temp_info_data[i*max_i2c_size], false);
+ total_size_temp = total_size_temp - max_i2c_size;
+ }
+ else
+ {
+ //I("last total_size_temp=%d\n",total_size_temp);
+ himax_register_read(private_ts->client,tmp_addr, total_size_temp % max_i2c_size, &temp_info_data[i*max_i2c_size], false);
+ }
+
+ address = ((i+1)*max_i2c_size);
+ tmp_addr[0] = addr[0] + (uint8_t)((address)&0x00FF);
+ if(tmp_addr[0] < addr[0])
+ tmp_addr[1] = addr[1] + (uint8_t)((address>>8)&0x00FF) + 1;
+ else
+ tmp_addr[1] = addr[1] + (uint8_t)((address>>8)&0x00FF);
+
+ msleep(10);
+ }
+ I("%s,READ Start \n",__func__);
+ I("%s,start_index = %d \n",__func__,start_index);
+ j = start_index;
+ for(i = 0;i < read_len;i++,j++)
+ {
+ if(fw_entry->data[j] != temp_info_data[i])
+ {
+ not_same++;
+ not_same_buff[i] = 1;
+ }
+
+
+
+
+ I("0x%2.2X,",temp_info_data[i]);
+
+ if (i > 0 && i%16 == 15)
+ printk("\n");
+ }
+ I("%s,READ END \n",__func__);
+ I("%s,Not Same count=%d\n",__func__,not_same);
+ if(not_same != 0)
+ {
+ j = start_index;
+ for(i = 0;i<read_len;i++,j++)
+ {
+ if(not_same_buff[i] == 1)
+ I("bin = [%d] 0x%2.2X\n",i,fw_entry->data[j]);
+ }
+ for(i = 0;i<read_len;i++,j++)
+ {
+ if(not_same_buff[i] == 1)
+ I("sram = [%d] 0x%2.2X \n",i,temp_info_data[i]);
+ }
+ }
+ I("%s,END \n",__func__);
+
+ kfree(temp_info_data);
+}
+
+void himax_read_all_sram(uint8_t *addr,int read_len)
+{
+ int total_read_times = 0;
+ int max_bus_size = 128;
+ int total_size_temp = 0;
+ int total_size = 0;
+ int address = 0;
+ int i = 0;
+ struct file *fn;
+
+ uint8_t tmp_addr[4];
+ uint8_t *temp_info_data;
+
+ I("%s,Entering \n",__func__);
+
+ himax_burst_enable(private_ts->client,1);
+
+ total_size = read_len;
+
+ total_size_temp = read_len;
+
+ temp_info_data = kzalloc(sizeof(uint8_t)*total_size,GFP_KERNEL);
+
+
+ tmp_addr[3] = addr[3]; tmp_addr[2] = addr[2]; tmp_addr[1] = addr[1]; tmp_addr[0] = addr[0];
+ I("%s, read addr tmp_addr[3]=0x%2.2X, tmp_addr[2]=0x%2.2X, tmp_addr[1]=0x%2.2X, tmp_addr[0]=0x%2.2X\n",__func__,tmp_addr[3],tmp_addr[2],tmp_addr[1],tmp_addr[0]);
+
+ I("%s, total size=%d\n",__func__,total_size);
+
+ if (total_size % max_bus_size == 0)
+ {
+ total_read_times = total_size / max_bus_size;
+ }
+ else
+ {
+ total_read_times = total_size / max_bus_size + 1;
+ }
+
+ for (i = 0; i < (total_read_times); i++)
+ {
+ if ( total_size_temp >= max_bus_size)
+ {
+ himax_register_read(private_ts->client,tmp_addr, max_bus_size, &temp_info_data[i*max_bus_size], false);
+ total_size_temp = total_size_temp - max_bus_size;
+ }
+ else
+ {
+ //I("last total_size_temp=%d\n",total_size_temp);
+ himax_register_read(private_ts->client,tmp_addr, total_size_temp % max_bus_size, &temp_info_data[i*max_bus_size], false);
+ }
+
+ address = ((i+1)*max_bus_size);
+ tmp_addr[1] = addr[1] + (uint8_t)((address>>8)&0x00FF);
+ tmp_addr[0] = addr[0] + (uint8_t)((address)&0x00FF);
+
+ msleep(10);
+ }
+ I("%s, NOW addr tmp_addr[3]=0x%2.2X, tmp_addr[2]=0x%2.2X, tmp_addr[1]=0x%2.2X, tmp_addr[0]=0x%2.2X\n",__func__,tmp_addr[3],tmp_addr[2],tmp_addr[1],tmp_addr[0]);
+ /*for(i = 0;i<read_len;i++)
+ {
+ I("0x%2.2X,",temp_info_data[i]);
+
+ if (i > 0 && i%16 == 15)
+ printk("\n");
+ }*/
+
+
+ I("Now Write File start!\n");
+ fn = filp_open("/sdcard/dump_dsram.txt",O_CREAT | O_WRONLY ,0);
+ if (!IS_ERR(fn))
+ {
+ I("%s create file and ready to write\n",__func__);
+ fn->f_op->write(fn,temp_info_data,read_len*sizeof(uint8_t),&fn->f_pos);
+ filp_close(fn,NULL);
+ }
+ I("Now Write File End!\n");
+
+
+ I("%s,END \n",__func__);
+
+ kfree(temp_info_data);
+}
+
+void himax_firmware_read_0f(const struct firmware *fw_entry)
+{
+ uint8_t tmp_addr[4];
+
+ I("%s,Entering \n",__func__);
+ /* first 48K */
+ tmp_addr[3] = 0x08;tmp_addr[2] = 0x00;tmp_addr[1] = 0x00;tmp_addr[0] = 0x00;
+ himax_read_sram_0f(fw_entry,tmp_addr,0,0xC000);
+
+ /*last 16k*/
+ tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x70;tmp_addr[0] = 0x00;
+ himax_read_sram_0f(fw_entry,tmp_addr,0xC000,132);
+ tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x70;tmp_addr[0] = 0x84;
+ himax_read_sram_0f(fw_entry,tmp_addr,0xC0FE,512);//0xc100-2
+ tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x78;tmp_addr[0] = 0x00;
+ himax_read_sram_0f(fw_entry,tmp_addr,0xD000,376);
+ tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x79;tmp_addr[0] = 0x78;
+ himax_read_sram_0f(fw_entry,tmp_addr,0xD178,376);
+ tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x7A;tmp_addr[0] = 0xF0;
+ himax_read_sram_0f(fw_entry,tmp_addr,0xD000,376);
+
+ tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x00;tmp_addr[0] = 0x00;
+ himax_read_all_sram(tmp_addr,32768);
+ I("%s,END \n",__func__);
+}
+
+void himax_0f_operation_check(void)
+{
+ int err = NO_ERR;
+ const struct firmware *fw_entry = NULL;
+ char *firmware_name = "himax.bin";
+
+
+ I("%s,Entering \n",__func__);
+ I("file name = %s\n",firmware_name);
+
+ err = request_firmware(&fw_entry, firmware_name, private_ts->dev);
+ if (err < 0) {
+ E("%s,fail in line%d error code=%d\n",__func__,__LINE__,err);
+ //goto err_request_firmware;
+ return ;
+ }
+
+ I("first 4 bytes 0x%2X,0x%2X,0x%2X,0x%2X !\n",fw_entry->data[0],fw_entry->data[1],fw_entry->data[2],fw_entry->data[3]);
+ I("next 4 bytes 0x%2X,0x%2X,0x%2X,0x%2X !\n",fw_entry->data[4],fw_entry->data[5],fw_entry->data[6],fw_entry->data[7]);
+ I("and next 4 bytes 0x%2X,0x%2X,0x%2X,0x%2X !\n",fw_entry->data[8],fw_entry->data[9],fw_entry->data[10],fw_entry->data[11]);
+
+ himax_firmware_read_0f(fw_entry);
+
+ release_firmware(fw_entry);
+ I("%s,END \n",__func__);
+ return ;
+}
+#endif
+
+#endif
diff --git a/drivers/input/touchscreen/hxchipset83112b/himax_ic.h b/drivers/input/touchscreen/hxchipset83112b/himax_ic.h
new file mode 100755
index 0000000..2654ac26
--- /dev/null
+++ b/drivers/input/touchscreen/hxchipset83112b/himax_ic.h
@@ -0,0 +1,80 @@
+/* Himax Android Driver Sample Code for HX83112 chipset
+*
+* Copyright (C) 2017 Himax Corporation.
+*
+* 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 "himax_platform.h"
+#include "himax_common.h"
+#include <linux/slab.h>
+
+#define HIMAX_REG_RETRY_TIMES 5
+
+enum fw_image_type
+{
+ fw_image_32k = 0x01,
+ fw_image_48k,
+ fw_image_60k,
+ fw_image_64k,
+ fw_image_124k,
+ fw_image_128k,
+};
+
+int himax_hand_shaking(struct i2c_client *client);
+void himax_set_SMWP_enable(struct i2c_client *client,uint8_t SMWP_enable, bool suspended);
+void himax_set_HSEN_enable(struct i2c_client *client,uint8_t HSEN_enable, bool suspended);
+void himax_usb_detect_set(struct i2c_client *client,uint8_t *cable_config);
+int himax_determin_diag_rawdata(int diag_command);
+int himax_determin_diag_storage(int diag_command);
+void himax_diag_register_set(struct i2c_client *client, uint8_t diag_command);
+void himax_flash_dump_func(struct i2c_client *client, uint8_t local_flash_command, int Flash_Size, uint8_t *flash_buffer);
+int himax_chip_self_test(struct i2c_client *client);
+void himax_burst_enable(struct i2c_client *client, uint8_t auto_add_4_byte); ////himax_83110_BURST_INC0_EN
+void himax_register_read(struct i2c_client *client, uint8_t *read_addr, int read_length, uint8_t *read_data, bool cfg_flag); ////RegisterRead83110
+void himax_flash_read(struct i2c_client *client, uint8_t *reg_byte, uint8_t *read_data); ////himax_83110_Flash_Read
+void himax_flash_write_burst(struct i2c_client *client, uint8_t * reg_byte, uint8_t * write_data); ////himax_83110_Flash_Write_Burst
+void himax_flash_write_burst_lenth(struct i2c_client *client, uint8_t *reg_byte, uint8_t *write_data, int length); ////himax_83110_Flash_Write_Burst_lenth
+void himax_register_write(struct i2c_client *client, uint8_t *write_addr, int write_length, uint8_t *write_data, bool cfg_flag); ////RegisterWrite83110
+bool himax_sense_off(struct i2c_client *client); ////himax_83110_SenseOff
+bool himax_enter_safe_mode(struct i2c_client *client);
+void himax_interface_on(struct i2c_client *client); ////himax_83110_Interface_on
+bool wait_wip(struct i2c_client *client, int Timing);
+void himax_sense_on(struct i2c_client *client, uint8_t FlashMode); ////himax_83110_SenseOn
+void himax_chip_erase(struct i2c_client *client); ////himax_83110_Chip_Erase
+bool himax_block_erase(struct i2c_client *client); ////himax_83110_Block_Erase
+void himax_flash_programming(struct i2c_client *client, uint8_t *FW_content, int FW_Size); ////himax_83110_Flash_Programming
+bool himax_check_chip_version(struct i2c_client *client); ////himax_83110_CheckChipVersion
+int himax_check_CRC(struct i2c_client *client, int mode); ////himax_83110_Check_CRC
+int fts_ctpm_fw_upgrade_with_sys_fs_32k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref);
+int fts_ctpm_fw_upgrade_with_sys_fs_60k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref);
+int fts_ctpm_fw_upgrade_with_sys_fs_64k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref);
+int fts_ctpm_fw_upgrade_with_sys_fs_124k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref);
+int fts_ctpm_fw_upgrade_with_sys_fs_128k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref);
+void himax_touch_information(struct i2c_client *client);
+int himax_read_i2c_status(struct i2c_client *client);
+int himax_read_ic_trigger_type(struct i2c_client *client);
+void himax_read_FW_ver(struct i2c_client *client);
+bool himax_ic_package_check(struct i2c_client *client);
+void himax_power_on_init(struct i2c_client *client);
+bool himax_read_event_stack(struct i2c_client *client, uint8_t *buf, uint8_t length);
+void himax_get_DSRAM_data(struct i2c_client *client, uint8_t *info_data);
+bool himax_calculateChecksum(struct i2c_client *client, bool change_iref);
+bool himax_program_reload(struct i2c_client *client);//5442 Program_Reload
+uint8_t himax_read_DD_status(uint8_t *cmd_set, uint8_t *tmp_data);
+int himax_read_FW_status(uint8_t *state_addr, uint8_t *tmp_addr);
+void himax_resume_ic_action(struct i2c_client *client);
+void himax_suspend_ic_action(struct i2c_client *client);
+
+//ts_work
+int cal_data_len(int raw_cnt_rmd, int HX_MAX_PT, int raw_cnt_max);
+bool diag_check_sum(struct himax_report_data *hx_touch_data); //return checksum value
+void diag_parse_raw_data(struct himax_report_data *hx_touch_data,int mul_num, int self_num,uint8_t diag_cmd, int32_t *mutual_data, int32_t *self_data);
diff --git a/drivers/input/touchscreen/hxchipset83112b/himax_platform.c b/drivers/input/touchscreen/hxchipset83112b/himax_platform.c
new file mode 100755
index 0000000..38e19ea
--- /dev/null
+++ b/drivers/input/touchscreen/hxchipset83112b/himax_platform.c
@@ -0,0 +1,813 @@
+/* Himax Android Driver Sample Code for QCT platform
+*
+* Copyright (C) 2017 Himax Corporation.
+*
+* 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 "himax_platform.h"
+#include "himax_common.h"
+#include "himax_ic.h"
+
+int i2c_error_count = 0;
+int irq_enable_count = 0;
+
+extern struct himax_ic_data* ic_data;
+extern struct himax_ts_data *private_ts;
+extern void himax_ts_work(struct himax_ts_data *ts);
+extern enum hrtimer_restart himax_ts_timer_func(struct hrtimer *timer);
+
+#ifdef HX_TP_PROC_DIAG
+extern uint8_t getDiagCommand(void);
+#endif
+
+extern void himax_log_touch_int_devation(int touched);
+
+
+int himax_dev_set(struct himax_ts_data *ts)
+{
+ int ret = 0;
+
+ ts->input_dev = input_allocate_device();
+ if (ts->input_dev == NULL)
+ {
+ ret = -ENOMEM;
+ E("%s: Failed to allocate input device\n", __func__);
+ return ret;
+ }
+ ts->input_dev->name = "himax-touchscreen";
+
+ return ret;
+}
+int himax_input_register_device(struct input_dev *input_dev)
+{
+ return input_register_device(input_dev);
+}
+
+#if defined(HX_PLATFOME_DEFINE_KEY)
+void himax_platform_key(void)
+{
+ I("Nothing to be done! Plz cancel it!\n");
+}
+#endif
+
+void himax_vk_parser(struct device_node *dt,
+ struct himax_i2c_platform_data *pdata)
+{
+ u32 data = 0;
+ uint8_t cnt = 0, i = 0;
+ uint32_t coords[4] = {0};
+ struct device_node *node, *pp = NULL;
+ struct himax_virtual_key *vk;
+
+ node = of_parse_phandle(dt, "virtualkey", 0);
+ if (node == NULL)
+ {
+ I(" DT-No vk info in DT");
+ return;
+ }
+ else
+ {
+ while ((pp = of_get_next_child(node, pp)))
+ cnt++;
+ if (!cnt)
+ return;
+
+ vk = kzalloc(cnt * (sizeof *vk), GFP_KERNEL);
+ pp = NULL;
+ while ((pp = of_get_next_child(node, pp)))
+ {
+ if (of_property_read_u32(pp, "idx", &data) == 0)
+ vk[i].index = data;
+ if (of_property_read_u32_array(pp, "range", coords, 4) == 0)
+ {
+ vk[i].x_range_min = coords[0], vk[i].x_range_max = coords[1];
+ vk[i].y_range_min = coords[2], vk[i].y_range_max = coords[3];
+ }
+ else
+ I(" range faile");
+ i++;
+ }
+ pdata->virtual_key = vk;
+ for (i = 0; i < cnt; i++)
+ I(" vk[%d] idx:%d x_min:%d, y_max:%d", i,pdata->virtual_key[i].index,
+ pdata->virtual_key[i].x_range_min, pdata->virtual_key[i].y_range_max);
+ }
+}
+
+int himax_parse_dt(struct himax_ts_data *ts,
+ struct himax_i2c_platform_data *pdata)
+{
+ int rc, coords_size = 0;
+ uint32_t coords[4] = {0};
+ struct property *prop;
+ struct device_node *dt = ts->client->dev.of_node;
+ u32 data = 0;
+ //printk("AllenYu_7-1\n");
+ prop = of_find_property(dt, "himax,panel-coords", NULL);
+ if (prop)
+ {
+ coords_size = prop->length / sizeof(u32);
+ if (coords_size != 4)
+ D(" %s:Invalid panel coords size %d", __func__, coords_size);
+ }
+ //printk("AllenYu_7-2\n");
+ if (of_property_read_u32_array(dt, "himax,panel-coords", coords, coords_size) == 0)
+ {
+ pdata->abs_x_min = coords[0], pdata->abs_x_max = coords[1];
+ pdata->abs_y_min = coords[2], pdata->abs_y_max = coords[3];
+ I(" DT-%s:panel-coords = %d, %d, %d, %d\n", __func__, pdata->abs_x_min,
+ pdata->abs_x_max, pdata->abs_y_min, pdata->abs_y_max);
+ }
+ //printk("AllenYu_7-3\n");
+ prop = of_find_property(dt, "himax,display-coords", NULL);
+ if (prop)
+ {
+ coords_size = prop->length / sizeof(u32);
+ if (coords_size != 4)
+ D(" %s:Invalid display coords size %d", __func__, coords_size);
+ }
+ //printk("AllenYu_7-4\n");
+ rc = of_property_read_u32_array(dt, "himax,display-coords", coords, coords_size);
+ if (rc && (rc != -EINVAL))
+ {
+ D(" %s:Fail to read display-coords %d\n", __func__, rc);
+ return rc;
+ }
+ //printk("AllenYu_7-5\n");
+ pdata->screenWidth = coords[1];
+ pdata->screenHeight = coords[3];
+ I(" DT-%s:display-coords = (%d, %d)", __func__, pdata->screenWidth,
+ pdata->screenHeight);
+ //printk("AllenYu_7-6\n");
+ pdata->gpio_irq = of_get_named_gpio(dt, "himax,irq-gpio", 0);
+ if (!gpio_is_valid(pdata->gpio_irq))
+ {
+ I(" DT:gpio_irq value is not valid\n");
+ }
+ //printk("AllenYu_7-7\n");
+ pdata->gpio_reset = of_get_named_gpio(dt, "himax,rst-gpio", 0);
+ if (!gpio_is_valid(pdata->gpio_reset))
+ {
+ I(" DT:gpio_rst value is not valid\n");
+ }
+ //printk("AllenYu_7-8\n");
+ pdata->gpio_3v3_en = of_get_named_gpio(dt, "himax,3v3-gpio", 0);
+ if (!gpio_is_valid(pdata->gpio_3v3_en))
+ {
+ I(" DT:gpio_3v3_en value is not valid\n");
+ }
+ I(" DT:gpio_irq=%d, gpio_rst=%d, gpio_3v3_en=%d", pdata->gpio_irq, pdata->gpio_reset, pdata->gpio_3v3_en);
+
+ if (of_property_read_u32(dt, "report_type", &data) == 0)
+ {
+ pdata->protocol_type = data;
+ I(" DT:protocol_type=%d", pdata->protocol_type);
+ }
+ //printk("AllenYu_7-9\n");
+ himax_vk_parser(dt, pdata);
+
+ return 0;
+}
+
+int i2c_himax_read(struct i2c_client *client, uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry)
+{
+ int retry;
+ struct i2c_msg msg[] =
+ {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = &command,
+ },
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = length,
+ .buf = data,
+ }
+ };
+
+ mutex_lock(&private_ts->rw_lock);
+ for (retry = 0; retry < toRetry; retry++)
+ {
+ if (i2c_transfer(client->adapter, msg, 2) == 2)
+ break;
+ msleep(20);
+ }
+ if (retry == toRetry)
+ {
+ E("%s: i2c_read_block retry over %d\n",
+ __func__, toRetry);
+ i2c_error_count = toRetry;
+ mutex_unlock(&private_ts->rw_lock);
+ return -EIO;
+ }
+ mutex_unlock(&private_ts->rw_lock);
+ return 0;
+
+}
+
+int i2c_himax_write(struct i2c_client *client, uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry)
+{
+ int retry/*, loop_i*/;
+ uint8_t buf[length + 1];
+
+ struct i2c_msg msg[] =
+ {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = length + 1,
+ .buf = buf,
+ }
+ };
+
+ mutex_lock(&private_ts->rw_lock);
+ buf[0] = command;
+ memcpy(buf+1, data, length);
+
+ for (retry = 0; retry < toRetry; retry++)
+ {
+ if (i2c_transfer(client->adapter, msg, 1) == 1)
+ break;
+ msleep(20);
+ }
+
+ if (retry == toRetry)
+ {
+ E("%s: i2c_write_block retry over %d\n",
+ __func__, toRetry);
+ i2c_error_count = toRetry;
+ mutex_unlock(&private_ts->rw_lock);
+ return -EIO;
+ }
+ mutex_unlock(&private_ts->rw_lock);
+ return 0;
+
+}
+
+int i2c_himax_write_command(struct i2c_client *client, uint8_t command, uint8_t toRetry)
+{
+ return i2c_himax_write(client, command, NULL, 0, toRetry);
+}
+
+int i2c_himax_master_write(struct i2c_client *client, uint8_t *data, uint8_t length, uint8_t toRetry)
+{
+ int retry/*, loop_i*/;
+ uint8_t buf[length];
+
+ struct i2c_msg msg[] =
+ {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = length,
+ .buf = buf,
+ }
+ };
+ mutex_lock(&private_ts->rw_lock);
+ memcpy(buf, data, length);
+
+ for (retry = 0; retry < toRetry; retry++)
+ {
+ if (i2c_transfer(client->adapter, msg, 1) == 1)
+ break;
+ msleep(20);
+ }
+
+ if (retry == toRetry)
+ {
+ E("%s: i2c_write_block retry over %d\n",
+ __func__, toRetry);
+ i2c_error_count = toRetry;
+ mutex_unlock(&private_ts->rw_lock);
+ return -EIO;
+ }
+ mutex_unlock(&private_ts->rw_lock);
+ return 0;
+}
+
+void himax_int_enable(int irqnum, int enable)
+{
+ if (enable == 1 && irq_enable_count == 0)
+ {
+ enable_irq(irqnum);
+ irq_enable_count++;
+ private_ts->irq_enabled = 1;
+ }
+ else if (enable == 0 && irq_enable_count == 1)
+ {
+ disable_irq_nosync(irqnum);
+ irq_enable_count--;
+ private_ts->irq_enabled = 0;
+ }
+ I("irq_enable_count = %d", irq_enable_count);
+}
+
+#ifdef HX_RST_PIN_FUNC
+void himax_rst_gpio_set(int pinnum, uint8_t value)
+{
+ // gpio_direction_output(pinnum, value); // old
+ gpio_set_value(pinnum, value);
+}
+#endif
+
+uint8_t himax_int_gpio_read(int pinnum)
+{
+ return gpio_get_value(pinnum);
+}
+
+#if defined(CONFIG_HMX_DB)
+static int himax_regulator_configure(struct i2c_client *client,struct himax_i2c_platform_data *pdata)
+{
+ int retval;
+ pdata->vcc_dig = regulator_get(&client->dev,
+ "vdd");
+ if (IS_ERR(pdata->vcc_dig))
+ {
+ E("%s: Failed to get regulator vdd\n",
+ __func__);
+ retval = PTR_ERR(pdata->vcc_dig);
+ return retval;
+ }
+ pdata->vcc_ana = regulator_get(&client->dev,
+ "avdd");
+ if (IS_ERR(pdata->vcc_ana))
+ {
+ E("%s: Failed to get regulator avdd\n",
+ __func__);
+ retval = PTR_ERR(pdata->vcc_ana);
+ regulator_put(pdata->vcc_ana);
+ return retval;
+ }
+
+ return 0;
+};
+
+static int himax_power_on(struct himax_i2c_platform_data *pdata, bool on)
+{
+ int retval;
+
+ if (on)
+ {
+ retval = regulator_enable(pdata->vcc_dig);
+ if (retval)
+ {
+ E("%s: Failed to enable regulator vdd\n",
+ __func__);
+ return retval;
+ }
+ msleep(100);
+ retval = regulator_enable(pdata->vcc_ana);
+ if (retval)
+ {
+ E("%s: Failed to enable regulator avdd\n",
+ __func__);
+ regulator_disable(pdata->vcc_dig);
+ return retval;
+ }
+ }
+ else
+ {
+ regulator_disable(pdata->vcc_dig);
+ regulator_disable(pdata->vcc_ana);
+ }
+
+ return 0;
+}
+
+int himax_gpio_power_config(struct i2c_client *client,struct himax_i2c_platform_data *pdata)
+{
+ int error;
+
+ error = himax_regulator_configure(client, pdata);
+ if (error)
+ {
+ E("Failed to intialize hardware\n");
+ goto err_regulator_not_on;
+ }
+
+#ifdef HX_RST_PIN_FUNC
+ if (gpio_is_valid(pdata->gpio_reset))
+ {
+ /* configure touchscreen reset out gpio */
+ error = gpio_request(pdata->gpio_reset, "hmx_reset_gpio");
+ if (error)
+ {
+ E("unable to request gpio [%d]\n",
+ pdata->gpio_reset);
+ goto err_regulator_on;
+ }
+
+ error = gpio_direction_output(pdata->gpio_reset, 0);
+ if (error)
+ {
+ E("unable to set direction for gpio [%d]\n",
+ pdata->gpio_reset);
+ goto err_gpio_reset_req;
+ }
+ }
+#endif
+
+ error = himax_power_on(pdata, true);
+ if (error)
+ {
+ E("Failed to power on hardware\n");
+ goto err_gpio_reset_req;
+ }
+
+ if (gpio_is_valid(pdata->gpio_irq))
+ {
+ /* configure touchscreen irq gpio */
+ error = gpio_request(pdata->gpio_irq, "hmx_gpio_irq");
+ if (error)
+ {
+ E("unable to request gpio [%d]\n",
+ pdata->gpio_irq);
+ goto err_power_on;
+ }
+ error = gpio_direction_input(pdata->gpio_irq);
+ if (error)
+ {
+ E("unable to set direction for gpio [%d]\n",
+ pdata->gpio_irq);
+ goto err_gpio_irq_req;
+ }
+ client->irq = gpio_to_irq(pdata->gpio_irq);
+ }
+ else
+ {
+ E("irq gpio not provided\n");
+ goto err_power_on;
+ }
+
+ msleep(20);
+#ifdef HX_RST_PIN_FUNC
+ if (gpio_is_valid(pdata->gpio_reset))
+ {
+ error = gpio_direction_output(pdata->gpio_reset, 1);
+ if (error)
+ {
+ E("unable to set direction for gpio [%d]\n",
+ pdata->gpio_reset);
+ goto err_gpio_irq_req;
+ }
+ }
+#endif
+ return 0;
+
+err_gpio_irq_req:
+ if (gpio_is_valid(pdata->gpio_irq))
+ gpio_free(pdata->gpio_irq);
+err_power_on:
+ himax_power_on(pdata, false);
+err_gpio_reset_req:
+#ifdef HX_RST_PIN_FUNC
+ if (gpio_is_valid(pdata->gpio_reset))
+ gpio_free(pdata->gpio_reset);
+err_regulator_on:
+#endif
+err_regulator_not_on:
+
+ return error;
+}
+
+#else
+int himax_gpio_power_config(struct i2c_client *client,struct himax_i2c_platform_data *pdata)
+{
+ int error=0;
+
+#ifdef HX_RST_PIN_FUNC
+ if (pdata->gpio_reset >= 0)
+ {
+ error = gpio_request(pdata->gpio_reset, "himax-reset");
+ if (error < 0)
+ {
+ E("%s: request reset pin failed\n", __func__);
+ return error;
+ }
+ error = gpio_direction_output(pdata->gpio_reset, 0);
+ if (error)
+ {
+ E("unable to set direction for gpio [%d]\n",
+ pdata->gpio_reset);
+ return error;
+ }
+ }
+#endif
+ if (pdata->gpio_3v3_en >= 0)
+ {
+ error = gpio_request(pdata->gpio_3v3_en, "himax-3v3_en");
+ if (error < 0)
+ {
+ E("%s: request 3v3_en pin failed\n", __func__);
+ return error;
+ }
+ gpio_direction_output(pdata->gpio_3v3_en, 1);
+ I("3v3_en pin =%d\n", gpio_get_value(pdata->gpio_3v3_en));
+ }
+ if (gpio_is_valid(pdata->gpio_irq))
+ {
+ /* configure touchscreen irq gpio */
+ error = gpio_request(pdata->gpio_irq, "himax_gpio_irq");
+ if (error)
+ {
+ E("unable to request gpio [%d]\n",pdata->gpio_irq);
+ return error;
+ }
+ error = gpio_direction_input(pdata->gpio_irq);
+ if (error)
+ {
+ E("unable to set direction for gpio [%d]\n",pdata->gpio_irq);
+ return error;
+ }
+ client->irq = gpio_to_irq(pdata->gpio_irq);
+ }
+ else
+ {
+ E("irq gpio not provided\n");
+ return error;
+ }
+ msleep(20);
+
+#ifdef HX_RST_PIN_FUNC
+ if (pdata->gpio_reset >= 0)
+ {
+ error = gpio_direction_output(pdata->gpio_reset, 1);
+ if (error)
+ {
+ E("unable to set direction for gpio [%d]\n",
+ pdata->gpio_reset);
+ return error;
+ }
+ }
+#if 0
+ msleep(20);
+#endif
+#endif
+
+ return error;
+}
+
+#endif
+
+static void himax_ts_isr_func(struct himax_ts_data *ts)
+{
+ himax_ts_work(ts);
+}
+
+irqreturn_t himax_ts_thread(int irq, void *ptr)
+{
+ struct himax_ts_data *ts = ptr;
+
+ if (ts->debug_log_level & BIT(2))
+ {
+ himax_log_touch_int_devation(HX_FINGER_ON);
+ }
+
+ himax_ts_isr_func((struct himax_ts_data *)ptr);
+
+ if(ts->debug_log_level & BIT(2))
+ {
+ himax_log_touch_int_devation(HX_FINGER_LEAVE);
+ }
+ return IRQ_HANDLED;
+}
+
+static void himax_ts_work_func(struct work_struct *work)
+{
+ struct himax_ts_data *ts = container_of(work, struct himax_ts_data, work);
+ himax_ts_work(ts);
+}
+
+int himax_int_register_trigger(struct i2c_client *client)
+{
+ int ret = 0;
+ struct himax_ts_data *ts = i2c_get_clientdata(client);
+
+ if(ic_data->HX_INT_IS_EDGE)
+ {
+ I("%s edge triiger falling\n ",__func__);
+ ret = request_threaded_irq(client->irq, NULL, himax_ts_thread,IRQF_TRIGGER_FALLING | IRQF_ONESHOT, client->name, ts);
+ }
+ else
+ {
+ I("%s level trigger low\n ",__func__);
+ ret = request_threaded_irq(client->irq, NULL, himax_ts_thread,IRQF_TRIGGER_LOW | IRQF_ONESHOT, client->name, ts);
+ }
+ return ret;
+}
+
+int himax_int_en_set(struct i2c_client *client)
+{
+ int ret = NO_ERR;
+ ret = himax_int_register_trigger(client);
+ return ret;
+}
+
+int himax_ts_register_interrupt(struct i2c_client *client)
+{
+ struct himax_ts_data *ts = i2c_get_clientdata(client);
+ int ret = 0;
+
+ ts->irq_enabled = 0;
+ //Work functon
+ if (client->irq) /*INT mode*/
+ {
+ ts->use_irq = 1;
+ ret = himax_int_register_trigger(client);
+ if (ret == 0)
+ {
+ ts->irq_enabled = 1;
+ irq_enable_count = 1;
+ I("%s: irq enabled at qpio: %d\n", __func__, client->irq);
+#ifdef HX_SMART_WAKEUP
+ irq_set_irq_wake(client->irq, 1);
+#endif
+ }
+ else
+ {
+ ts->use_irq = 0;
+ E("%s: request_irq failed\n", __func__);
+ }
+ }
+ else
+ {
+ I("%s: client->irq is empty, use polling mode.\n", __func__);
+ }
+
+ if (!ts->use_irq) /*if use polling mode need to disable HX_ESD_RECOVERY function*/
+ {
+ ts->himax_wq = create_singlethread_workqueue("himax_touch");
+
+ INIT_WORK(&ts->work, himax_ts_work_func);
+
+ hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ ts->timer.function = himax_ts_timer_func;
+ hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
+ I("%s: polling mode enabled\n", __func__);
+ }
+ return ret;
+}
+
+static int himax_common_suspend(struct device *dev)
+{
+ struct himax_ts_data *ts = dev_get_drvdata(dev);
+
+ I("%s: enter \n", __func__);
+
+ himax_chip_common_suspend(ts);
+ return 0;
+}
+
+static int himax_common_resume(struct device *dev)
+{
+ struct himax_ts_data *ts = dev_get_drvdata(dev);
+
+ I("%s: enter \n", __func__);
+
+ himax_chip_common_resume(ts);
+ return 0;
+}
+
+#if defined(CONFIG_FB)
+int fb_notifier_callback(struct notifier_block *self,
+ unsigned long event, void *data)
+{
+ struct fb_event *evdata = data;
+ int *blank;
+ struct himax_ts_data *ts;
+ if (event != FB_EVENT_BLANK)
+ return 0;
+
+ ts=container_of(self, struct himax_ts_data, fb_notif);
+//ParisKuong modified Mutex initialization +++
+#if 0
+ mutex_init(&ts->ops_lock);
+#endif
+//ParisKuong modified Mutex initialization ---
+ mutex_lock(&ts->ops_lock);
+
+ if(evdata == NULL)
+ {
+ E("%s(%d) evdata is NULL\n",__func__, __LINE__);
+ }
+ //I(" %s(%d)\n", __func__, __LINE__);
+ if (evdata && evdata->data && event == FB_EVENT_BLANK && ts && ts->client)
+ {
+ //I(" %s(%d)\n", __func__, __LINE__);
+ blank = evdata->data;
+ if(blank == NULL)
+ {
+ E("%s(%d) blank is NULL\n",__func__, __LINE__);
+ }
+//I("blank = %d %s(%d)\n", *blank, __func__, __LINE__);
+ switch (*blank)
+ {
+ case FB_BLANK_UNBLANK:
+ case FB_BLANK_NORMAL:
+ himax_common_resume(&ts->client->dev);
+ break;
+
+ case FB_BLANK_POWERDOWN:
+ case FB_BLANK_HSYNC_SUSPEND:
+ case FB_BLANK_VSYNC_SUSPEND:
+#if 0
+ case FB_BLANK_NORMAL:
+#endif
+ himax_common_suspend(&ts->client->dev);
+ break;
+ }
+ }
+ mutex_unlock(&ts->ops_lock);
+ return 0;
+}
+#endif
+
+static const struct i2c_device_id himax_common_ts_id[] =
+{
+ {HIMAX_common_NAME, 0 },
+ {}
+};
+
+static const struct dev_pm_ops himax_common_pm_ops =
+{
+#if (!defined(CONFIG_FB))
+ .suspend = himax_common_suspend,
+ .resume = himax_common_resume,
+#endif
+};
+
+//#ifdef CONFIG_OF
+#if 1
+static struct of_device_id himax_match_table[] =
+{
+ {.compatible = "himax,hxcommon", },
+ {},
+};
+#else
+#define himax_match_table NULL
+#endif
+
+static struct i2c_driver himax_common_driver = {
+ //.id_table = himax_common_ts_id,
+ .probe = himax_chip_common_probe,
+ .remove = himax_chip_common_remove,
+ .driver = {
+ .name = HIMAX_common_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = himax_match_table,
+#ifdef CONFIG_PM
+ .pm = &himax_common_pm_ops,
+#endif
+ },
+ .id_table = himax_common_ts_id,
+};
+
+//static void __init himax_common_init_async(void *unused, async_cookie_t cookie)
+//{
+// I("%s:Enter \n", __func__);
+// i2c_add_driver(&himax_common_driver);
+//}
+
+static int __init himax_common_init(void)
+{
+ int ret = -1;
+ I("Enter Himax common touch panel driver init 83112-B\n");
+
+
+ ret = i2c_add_driver(&himax_common_driver);
+ printk("Himax ret : %d \n",ret);
+
+ if ( ret != 0 ) {
+ printk("Himax ret : %d \n",ret);
+ I("Focaltech touch screen driver init failed!");
+ }
+ //async_schedule(himax_common_init_async, NULL);
+
+ I("Exit Himax common touch panel driver init 83112-B\n");
+ //return i2c_add_driver(&himax_common_driver);
+ return ret;
+}
+
+static void __exit himax_common_exit(void)
+{
+ i2c_del_driver(&himax_common_driver);
+}
+
+module_init(himax_common_init);
+module_exit(himax_common_exit);
+
+MODULE_DESCRIPTION("Himax_common driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/input/touchscreen/hxchipset83112b/himax_platform.h b/drivers/input/touchscreen/hxchipset83112b/himax_platform.h
new file mode 100755
index 0000000..70def61
--- /dev/null
+++ b/drivers/input/touchscreen/hxchipset83112b/himax_platform.h
@@ -0,0 +1,130 @@
+/* Himax Android Driver Sample Code for QCT platform
+*
+* Copyright (C) 2017 Himax Corporation.
+*
+* 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 HIMAX_PLATFORM_H
+#define HIMAX_PLATFORM_H
+
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/gpio.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#if defined(CONFIG_HMX_DB)
+#include <linux/regulator/consumer.h>
+#endif
+
+#define QCT
+
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
+#define D(x...) printk("[HXTP] " x)
+#define I(x...) printk("[HXTP] " x)
+#define W(x...) printk("[HXTP][WARNING] " x)
+#define E(x...) printk("[HXTP][ERROR] " x)
+#define DIF(x...) \
+ if (debug_flag) \
+ printk("[HXTP][DEBUG] " x) \
+} while(0)
+#else
+#define D(x...)
+#define I(x...)
+#define W(x...)
+#define E(x...)
+#define DIF(x...)
+#endif
+
+#if defined(CONFIG_HMX_DB)
+/* Analog voltage @2.7 V */
+#define HX_VTG_MIN_UV 2700000
+#define HX_VTG_MAX_UV 3300000
+#define HX_ACTIVE_LOAD_UA 15000
+#define HX_LPM_LOAD_UA 10
+/* Digital voltage @1.8 V */
+#define HX_VTG_DIG_MIN_UV 1800000
+#define HX_VTG_DIG_MAX_UV 1800000
+#define HX_ACTIVE_LOAD_DIG_UA 10000
+#define HX_LPM_LOAD_DIG_UA 10
+
+#define HX_I2C_VTG_MIN_UV 1800000
+#define HX_I2C_VTG_MAX_UV 1800000
+#define HX_I2C_LOAD_UA 10000
+#define HX_I2C_LPM_LOAD_UA 10
+#endif
+
+#define HIMAX_common_NAME "himax_tp"
+#define HIMAX_I2C_ADDR 0x48
+#define INPUT_DEV_NAME "himax-touchscreen"
+
+struct himax_i2c_platform_data
+{
+ int abs_x_min;
+ int abs_x_max;
+ int abs_x_fuzz;
+ int abs_y_min;
+ int abs_y_max;
+ int abs_y_fuzz;
+ int abs_pressure_min;
+ int abs_pressure_max;
+ int abs_pressure_fuzz;
+ int abs_width_min;
+ int abs_width_max;
+ int screenWidth;
+ int screenHeight;
+ uint8_t fw_version;
+ uint8_t tw_id;
+ uint8_t powerOff3V3;
+ uint8_t cable_config[2];
+ uint8_t protocol_type;
+ int gpio_irq;
+ int gpio_reset;
+ int gpio_3v3_en;
+ int (*power)(int on);
+ void (*reset)(void);
+ struct himax_virtual_key *virtual_key;
+ struct kobject *vk_obj;
+ struct kobj_attribute *vk2Use;
+
+ int hx_config_size;
+#if defined(CONFIG_HMX_DB)
+ bool i2c_pull_up;
+ bool digital_pwr_regulator;
+ int reset_gpio;
+ u32 reset_gpio_flags;
+ int irq_gpio;
+ u32 irq_gpio_flags;
+
+ struct regulator *vcc_ana; //For Dragon Board
+ struct regulator *vcc_dig; //For Dragon Board
+ struct regulator *vcc_i2c; //For Dragon Board
+#endif
+};
+
+
+extern int irq_enable_count;
+extern int i2c_himax_read(struct i2c_client *client, uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry);
+extern int i2c_himax_write(struct i2c_client *client, uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry);
+extern int i2c_himax_write_command(struct i2c_client *client, uint8_t command, uint8_t toRetry);
+extern int i2c_himax_master_write(struct i2c_client *client, uint8_t *data, uint8_t length, uint8_t toRetry);
+extern void himax_int_enable(int irqnum, int enable);
+extern int himax_ts_register_interrupt(struct i2c_client *client);
+extern uint8_t himax_int_gpio_read(int pinnum);
+
+extern int himax_gpio_power_config(struct i2c_client *client,struct himax_i2c_platform_data *pdata);
+
+#if defined(CONFIG_FB)
+extern int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data);
+#endif
+
+#endif
diff --git a/drivers/leds/leds-qti-tri-led.c b/drivers/leds/leds-qti-tri-led.c
index c494655..4f3de34 100644
--- a/drivers/leds/leds-qti-tri-led.c
+++ b/drivers/leds/leds-qti-tri-led.c
@@ -475,6 +475,19 @@
of_get_property(child_node, "label", NULL) ? :
child_node->name;
+ led->pwm_setting.pre_period_ns = 0;
+ led->pwm_setting.period_ns = 0;
+ led->pwm_setting.duty_ns = 0;
+
+ led->led_setting.on_ms = 0;
+ led->led_setting.off_ms = 0;
+ led->led_setting.brightness = LED_OFF;
+ led->led_setting.blink = false;
+ led->led_setting.breath = false;
+
+ led->blinking = false;
+ led->breathing = false;
+
led->pwm_dev =
devm_of_pwm_get(chip->dev, child_node, NULL);
if (IS_ERR(led->pwm_dev)) {
diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
index f15f219..8f64487 100644
--- a/drivers/md/dm-verity-target.c
+++ b/drivers/md/dm-verity-target.c
@@ -67,6 +67,14 @@
struct buffer_aux {
int hash_verified;
};
+/*
+ * While system shutdown, skip verity work for I/O error.
+ */
+static inline bool verity_is_system_shutting_down(void)
+{
+ return system_state == SYSTEM_HALT || system_state == SYSTEM_POWER_OFF
+ || system_state == SYSTEM_RESTART;
+}
/*
* Initialize struct buffer_aux for a freshly created buffer.
@@ -513,7 +521,8 @@
{
struct dm_verity_io *io = bio->bi_private;
- if (bio->bi_error && !verity_fec_is_enabled(io->v)) {
+ if (bio->bi_error &&
+ (!verity_fec_is_enabled(io->v) || verity_is_system_shutting_down())) {
verity_finish_io(io, bio->bi_error);
return;
}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
old mode 100644
new mode 100755
index 2806132..d3d72ab
--- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
@@ -31,6 +31,9 @@
#define PARK_LENS_SMALL_STEP 3
#define MAX_QVALUE 4096
+extern int nActuatorAK7374;
+extern int nActuatorDW9800;
+
static struct v4l2_file_operations msm_actuator_v4l2_subdev_fops;
static int32_t msm_actuator_power_up(struct msm_actuator_ctrl_t *a_ctrl);
static int32_t msm_actuator_power_down(struct msm_actuator_ctrl_t *a_ctrl);
@@ -118,7 +121,8 @@
write_arr[i].data_shift) |
((hw_dword & write_arr[i].hw_mask) >>
write_arr[i].hw_shift);
-
+ if(nActuatorAK7374 == 0 && nActuatorDW9800 == 0)
+ value = abs(1023-value);
if (write_arr[i].reg_addr != 0xFFFF) {
i2c_byte1 = write_arr[i].reg_addr;
i2c_byte2 = value;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c
index a33436e..26dc662 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c
@@ -26,6 +26,13 @@
#undef CDBG
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
+/* enable multi-camera on/off code */
+#define MULTI_CAMERA_POWER_ON
+
+#if defined (MULTI_CAMERA_POWER_ON)
+int iovdd_count = 0;
+#endif
+
int msm_camera_fill_vreg_params(struct camera_vreg_t *cam_vreg,
int num_vreg, struct msm_sensor_power_setting *power_setting,
uint16_t power_setting_size)
@@ -1512,10 +1519,26 @@
CDBG("%s:%d gpio set val %d\n", __func__, __LINE__,
ctrl->gpio_conf->gpio_num_info->gpio_num
[power_setting->seq_val]);
+ #if defined (MULTI_CAMERA_POWER_ON)
+ if (power_setting->seq_val == SENSOR_GPIO_VIO) {
+ CDBG("[%s][Arima] 1.Set common gpio. Loop %d\n", __func__, iovdd_count);
+ if (iovdd_count == 0) {
+ gpio_set_value_cansleep(
+ ctrl->gpio_conf->gpio_num_info->gpio_num[power_setting->seq_val],
+ (int) power_setting->config_val );
+ }
+ iovdd_count++;
+ } else {
+ gpio_set_value_cansleep(
+ ctrl->gpio_conf->gpio_num_info->gpio_num[power_setting->seq_val],
+ (int) power_setting->config_val);
+ }
+ #else
gpio_set_value_cansleep(
ctrl->gpio_conf->gpio_num_info->gpio_num
[power_setting->seq_val],
(int) power_setting->config_val);
+ #endif /* (MULTI_CAMERA_POWER_ON) */
break;
case SENSOR_VREG:
if (power_setting->seq_val == INVALID_VREG)
@@ -1588,9 +1611,25 @@
if (!ctrl->gpio_conf->gpio_num_info->valid
[power_setting->seq_val])
continue;
+ #if defined (MULTI_CAMERA_POWER_ON)
+ if (power_setting->seq_val == SENSOR_GPIO_VIO) {
+ iovdd_count --;
+ if (iovdd_count == 0) {
+ gpio_set_value_cansleep(
+ ctrl->gpio_conf->gpio_num_info->gpio_num[power_setting->seq_val],
+ GPIOF_OUT_INIT_LOW );
+ }
+ CDBG("[%s][Arima] 2.Set common gpio. Loop %d\n", __func__, iovdd_count);
+ } else {
+ gpio_set_value_cansleep(
+ ctrl->gpio_conf->gpio_num_info->gpio_num
+ [power_setting->seq_val], GPIOF_OUT_INIT_LOW);
+ }
+ #else
gpio_set_value_cansleep(
ctrl->gpio_conf->gpio_num_info->gpio_num
[power_setting->seq_val], GPIOF_OUT_INIT_LOW);
+ #endif /* (MULTI_CAMERA_POWER_ON) */
break;
case SENSOR_VREG:
if (power_setting->seq_val < ctrl->num_vreg)
@@ -1715,10 +1754,26 @@
if (!ctrl->gpio_conf->gpio_num_info->valid
[pd->seq_val])
continue;
+ #if defined (MULTI_CAMERA_POWER_ON)
+ if (pd->seq_val == SENSOR_GPIO_VIO) {
+ iovdd_count --;
+ if (iovdd_count == 0) {
+ gpio_set_value_cansleep(
+ ctrl->gpio_conf->gpio_num_info->gpio_num[pd->seq_val],
+ (int) pd->config_val );
+ }
+ CDBG("[%s][Arima] 3.Set common gpio. Loop %d\n", __func__, iovdd_count);
+ } else {
+ gpio_set_value_cansleep(
+ ctrl->gpio_conf->gpio_num_info->gpio_num[pd->seq_val],
+ (int) pd->config_val );
+ }
+ #else
gpio_set_value_cansleep(
ctrl->gpio_conf->gpio_num_info->gpio_num
[pd->seq_val],
(int) pd->config_val);
+ #endif /* (MULTI_CAMERA_POWER_ON) */
break;
case SENSOR_VREG:
if (pd->seq_val == INVALID_VREG)
diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
old mode 100644
new mode 100755
index 4bc13d0..3820844
--- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
@@ -25,6 +25,9 @@
#define SENSOR_MAX_MOUNTANGLE (360)
+int nActuatorAK7374 = 0;
+int nActuatorDW9800 = 0;
+
static struct v4l2_file_operations msm_sensor_v4l2_subdev_fops;
static int32_t msm_sensor_driver_platform_probe(struct platform_device *pdev);
@@ -1136,6 +1139,21 @@
goto free_camera_info;
}
+ pr_err("%s:%d s_ctrl->sensordata->actuator_name: %s\n",
+ __func__, __LINE__,
+ s_ctrl->sensordata->actuator_name);
+ if (strcmp(s_ctrl->sensordata->actuator_name, "ak7374") == 0) {
+ nActuatorAK7374 = 1;
+ pr_err("%s:%d nActuatorAK7374: %d\n",
+ __func__, __LINE__,
+ nActuatorAK7374);
+ } else if (strcmp(s_ctrl->sensordata->actuator_name, "dw9800") == 0) {
+ nActuatorDW9800 = 1;
+ pr_err("%s:%d nActuatorDW9800: %d\n",
+ __func__, __LINE__,
+ nActuatorDW9800);
+ }
+
pr_err("%s probe succeeded", slave_info->sensor_name);
s_ctrl->bypass_video_node_creation =
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
index 84ba012..d01c9dfd 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2021, 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
@@ -1094,7 +1094,8 @@
if (rc_mode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR ||
rc_mode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR ||
rc_mode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_CFR ||
- rc_mode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_VFR)
+ rc_mode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_VFR ||
+ rc_mode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF)
pdata.video_work_mode = VIDC_WORK_MODE_2;
} else {
return -EINVAL;
diff --git a/drivers/media/platform/msm/vidc_3x/msm_v4l2_vidc.c b/drivers/media/platform/msm/vidc_3x/msm_v4l2_vidc.c
index 9d05086..1c27e08 100644
--- a/drivers/media/platform/msm/vidc_3x/msm_v4l2_vidc.c
+++ b/drivers/media/platform/msm/vidc_3x/msm_v4l2_vidc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, 2021 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
@@ -627,6 +627,8 @@
vidc_driver->capability_version =
msm_vidc_read_efuse_version(
pdev, core->resources.pf_cap_tbl, "efuse2");
+ if (vidc_driver->capability_version)
+ core->resources.target_version = 1;
rc = call_hfi_op(core->device, core_early_init,
core->device->hfi_device_data);
diff --git a/drivers/media/platform/msm/vidc_3x/msm_vidc_common.c b/drivers/media/platform/msm/vidc_3x/msm_vidc_common.c
index c0efc3b..410482a 100644
--- a/drivers/media/platform/msm/vidc_3x/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc_3x/msm_vidc_common.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, 2021 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
@@ -672,7 +672,7 @@
struct msm_vidc_cb_cmd_done *response = data;
struct msm_vidc_core *core;
struct vidc_hal_sys_init_done *sys_init_msg;
- u32 index;
+ u32 index, i;
if (!IS_HAL_SYS_CMD(cmd)) {
dprintk(VIDC_ERR, "%s - invalid cmd\n", __func__);
@@ -718,6 +718,20 @@
memcpy(core->capabilities, sys_init_msg->capabilities,
sys_init_msg->codec_count * sizeof(struct msm_vidc_capability));
+ /* override capabilities for sdm450 */
+ if (core->resources.target_version == 1) {
+ for (i = 0; i < VIDC_MAX_SESSIONS; i++) {
+ if (core->capabilities[i].width.max > HD_WIDTH)
+ core->capabilities[i].width.max = HD_WIDTH;
+ if (core->capabilities[i].height.max > HD_WIDTH)
+ core->capabilities[i].height.max = HD_WIDTH;
+
+ core->capabilities[i].mbs_per_frame.max =
+ NUM_MBS_PER_FRAME(HD_WIDTH, HD_HEIGHT);
+ core->resources.max_inst_count =
+ MAX_SUPPORTED_INSTANCES;
+ }
+ }
dprintk(VIDC_DBG,
"%s: supported_codecs[%d]: enc = %#x, dec = %#x\n",
__func__, core->codec_count, core->enc_codec_supported,
diff --git a/drivers/media/platform/msm/vidc_3x/msm_vidc_internal.h b/drivers/media/platform/msm/vidc_3x/msm_vidc_internal.h
index 7d711aa..9ecad40 100644
--- a/drivers/media/platform/msm/vidc_3x/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc_3x/msm_vidc_internal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, 2020, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, 2020,2021 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
@@ -45,6 +45,8 @@
#define MIN_SUPPORTED_WIDTH 32
#define MIN_SUPPORTED_HEIGHT 32
#define DEFAULT_FPS 15
+#define HD_WIDTH 1920
+#define HD_HEIGHT 1088
/* Maintains the number of FTB's between each FBD over a window */
#define DCVS_FTB_WINDOW 32
diff --git a/drivers/media/platform/msm/vidc_3x/msm_vidc_resources.h b/drivers/media/platform/msm/vidc_3x/msm_vidc_resources.h
index 383aeda..eb47242 100644
--- a/drivers/media/platform/msm/vidc_3x/msm_vidc_resources.h
+++ b/drivers/media/platform/msm/vidc_3x/msm_vidc_resources.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2018, 2021 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
@@ -174,6 +174,7 @@
uint32_t imem_size;
enum imem_type imem_type;
uint32_t max_load;
+ uint32_t target_version;
struct platform_device *pdev;
struct regulator_set regulator_set;
struct clock_set clock_set;
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 0831456..80acd1c 100755
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -15,6 +15,7 @@
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/pm_runtime.h>
+#include <linux/seq_file.h>
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
@@ -27,10 +28,13 @@
#include "bus.h"
#include "mmc_ops.h"
#include "sd_ops.h"
+#include <linux/proc_fs.h>
#define DEFAULT_CMD6_TIMEOUT_MS 500
#define MIN_CACHE_EN_TIMEOUT_MS 1600
+static u32 memory_cid = 0x0;
+
static const unsigned int tran_exp[] = {
10000, 100000, 1000000, 10000000,
0, 0, 0, 0
@@ -3156,6 +3160,29 @@
.post_hibernate = mmc_post_hibernate
};
+static int proc_memory_vendor_show(struct seq_file *m, void *v)
+{
+ if (memory_cid==0x15010052) {
+ seq_printf(m, "Samsung_2nd\n");
+ }
+ else {
+ seq_printf(m, "Samsung_Main\n");
+ }
+ return 0;
+}
+
+static int proc_memory_vendor_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, proc_memory_vendor_show, NULL);
+}
+
+static const struct file_operations proc_memory_vendor_fops = {
+ .open = proc_memory_vendor_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
/*
* Starting point for MMC card init.
*/
@@ -3219,6 +3246,11 @@
register_reboot_notifier(&host->card->reboot_notify);
+ proc_create("memory_vendor", 0, NULL, &proc_memory_vendor_fops);
+ if (host->card->type == MMC_TYPE_MMC) {
+ memory_cid=host->card->raw_cid[0];
+ }
+
return 0;
remove_card:
diff --git a/drivers/nfc/nq-nci.c b/drivers/nfc/nq-nci.c
old mode 100644
new mode 100755
index bae7f5b..15a6c53
--- a/drivers/nfc/nq-nci.c
+++ b/drivers/nfc/nq-nci.c
@@ -29,6 +29,10 @@
#include <linux/compat.h>
#endif
+#define PFX "[NFC][NQ]"
+/* To avoid from recovery fail and then NFC always in download mode */
+#define NFC_FW_DOWNLOAD_MODE
+
struct nqx_platform_data {
unsigned int irq_gpio;
unsigned int en_gpio;
@@ -476,7 +480,9 @@
* interrupts to avoid spurious notifications to upper
* layers.
*/
+ #if !defined( NFC_FW_DOWNLOAD_MODE )
nqx_disable_irq(nqx_dev);
+ #endif /* ( NFC_FW_DOWNLOAD_MODE ) */
dev_dbg(&nqx_dev->client->dev,
"gpio_set_value disable: %s: info: %p\n",
__func__, nqx_dev);
@@ -533,6 +539,11 @@
return -EBUSY; /* Device or resource busy */
}
}
+ #if defined( NFC_FW_DOWNLOAD_MODE )
+ /* Enable IRQ while upgrade FW. To avoid from recovery fail and then NFC
+ * always in download mode */
+ nqx_enable_irq( nqx_dev );
+ #endif /* ( NFC_FW_DOWNLOAD_MODE ) */
gpio_set_value(nqx_dev->en_gpio, 1);
usleep_range(10000, 10100);
if (gpio_is_valid(nqx_dev->firm_gpio)) {
@@ -1187,8 +1198,12 @@
if (r) {
/* make sure NFCC is not enabled */
gpio_set_value(platform_data->en_gpio, 0);
+ #if !defined( NFC_FW_DOWNLOAD_MODE ) /* Qualcomm default */
/* We don't think there is hardware switch NFC OFF */
goto err_request_hw_check_failed;
+ #else
+ dev_err(&client->dev, "[%s]nfcc_hw_check() error !!\n", __func__ );
+ #endif /* ( NFC_FW_DOWNLOAD_MODE ) */
}
/* Register reboot notifier here */
diff --git a/drivers/power/supply/qcom/qpnp-smb5.c b/drivers/power/supply/qcom/qpnp-smb5.c
old mode 100644
new mode 100755
index 7505c49..27e06740
--- a/drivers/power/supply/qcom/qpnp-smb5.c
+++ b/drivers/power/supply/qcom/qpnp-smb5.c
@@ -1684,7 +1684,7 @@
static int smb5_configure_typec(struct smb_charger *chg)
{
int rc;
- u8 val = 0;
+ u8 val = 0, rid_int_src = 0;
rc = smblib_read(chg, LEGACY_CABLE_STATUS_REG, &val);
if (rc < 0) {
@@ -1750,6 +1750,16 @@
rc);
return rc;
}
+
+ /* Enable Water detection rid source interrupt */
+ rid_int_src |= TYPEC_WATER_DETECTION_INT_EN_BIT;
+ }
+
+ /* Disable rid source interrupts which are not required. */
+ rc = smblib_write(chg, TYPE_C_INTERRUPT_EN_CFG_2_REG, rid_int_src);
+ if (rc < 0) {
+ dev_err(chg->dev, "Couldn't configure Type-C interrupts rc=%d\n", rc);
+ return rc;
}
/* Disable TypeC and RID change source interrupts */
@@ -2092,6 +2102,14 @@
}
}
+ /* AICL PERIODIC RERUN ENABLE*/
+ rc = smblib_write(chg, USBIN_AICL_OPTIONS_CFG_REG, 0xD4);
+ if (rc < 0) {
+ dev_err(chg->dev,
+ "Couldn't config RERUN AICL ENABLE rc=%d\n", rc);
+ return rc;
+ }
+
/* enable the charging path */
rc = vote(chg->chg_disable_votable, DEFAULT_VOTER, false, 0);
if (rc < 0) {
diff --git a/drivers/power/supply/qcom/smb5-lib.c b/drivers/power/supply/qcom/smb5-lib.c
old mode 100644
new mode 100755
index 1fae678..7670e5d
--- a/drivers/power/supply/qcom/smb5-lib.c
+++ b/drivers/power/supply/qcom/smb5-lib.c
@@ -1236,6 +1236,36 @@
return 0;
}
+static int smblib_jeita_rechg_voltage_vote_callback(struct votable *votable, void *data,
+ int voltage, const char *client)
+{
+ struct smb_charger *chg = data;
+ int rc = 0;
+ u32 temp = VBAT_TO_VRAW_ADC((voltage/1000));
+
+ temp = ((temp & 0xFF00) >> 8) | ((temp & 0xFF) << 8);
+ rc = smblib_batch_write(chg,
+ CHGR_ADC_RECHARGE_THRESHOLD_MSB_REG, (u8 *)&temp, 2);
+ if (rc < 0) {
+ dev_err(chg->dev, "Couldn't configure ADC_RECHARGE_THRESHOLD REG rc=%d\n",
+ rc);
+ return rc;
+ }
+ /* Program the sample count for VBAT based recharge to 3 */
+ rc = smblib_masked_write(chg, CHGR_NO_SAMPLE_TERM_RCHG_CFG_REG,
+ NO_OF_SAMPLE_FOR_RCHG,
+ 2 << NO_OF_SAMPLE_FOR_RCHG_SHIFT);
+ if (rc < 0) {
+ dev_err(chg->dev, "Couldn't configure CHGR_NO_SAMPLE_FOR_TERM_RCHG_CFG rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ dev_err(chg->dev, "jeita_rechg_voltage =%d\n", voltage);
+
+ return rc;
+}
+
/*******************
* VCONN REGULATOR *
* *****************/
@@ -4521,6 +4551,14 @@
return rc;
}
+ chg->rechg_vol_votable = create_votable("RECHG_VOL", VOTE_MIN,
+ smblib_jeita_rechg_voltage_vote_callback,
+ chg);
+ if (IS_ERR(chg->rechg_vol_votable)) {
+ rc = PTR_ERR(chg->rechg_vol_votable);
+ return rc;
+ }
+
return rc;
}
diff --git a/drivers/power/supply/qcom/smb5-lib.h b/drivers/power/supply/qcom/smb5-lib.h
old mode 100644
new mode 100755
index 4911047..e7dd8be
--- a/drivers/power/supply/qcom/smb5-lib.h
+++ b/drivers/power/supply/qcom/smb5-lib.h
@@ -347,6 +347,7 @@
struct votable *chg_disable_votable;
struct votable *pl_enable_votable_indirect;
struct votable *usb_irq_enable_votable;
+ struct votable *rechg_vol_votable;
/* work */
struct work_struct bms_update_work;
diff --git a/drivers/power/supply/qcom/step-chg-jeita.c b/drivers/power/supply/qcom/step-chg-jeita.c
old mode 100644
new mode 100755
index 3e8b46b..5f61803
--- a/drivers/power/supply/qcom/step-chg-jeita.c
+++ b/drivers/power/supply/qcom/step-chg-jeita.c
@@ -80,6 +80,7 @@
struct votable *fcc_votable;
struct votable *fv_votable;
struct votable *usb_icl_votable;
+ struct votable *rechg_vol_votable;
struct wakeup_source *step_chg_ws;
struct power_supply *batt_psy;
struct power_supply *bms_psy;
@@ -499,7 +500,9 @@
return (STEP_CHG_HYSTERISIS_DELAY_US - elapsed_us + 1000);
}
-#define JEITA_SUSPEND_HYST_UV 50000
+#define JEITA_SUSPEND_HYST_UV 200000
+#define JEITA_RECHG_HYST_UV 200000
+
static int handle_jeita(struct step_chg_info *chip)
{
union power_supply_propval pval = {0, };
@@ -561,6 +564,9 @@
if (rc < 0)
fv_uv = 0;
+ if (!chip->rechg_vol_votable)
+ chip->rechg_vol_votable = find_votable("RECHG_VOL");
+
chip->fv_votable = find_votable("FV");
if (!chip->fv_votable)
goto update_time;
@@ -597,6 +603,8 @@
set_jeita_fv:
vote(chip->fv_votable, JEITA_VOTER, fv_uv ? true : false, fv_uv);
+ vote(chip->rechg_vol_votable,
+ JEITA_VOTER, true, (fv_uv -JEITA_RECHG_HYST_UV));
update_time:
chip->jeita_last_update_time = ktime_get();
@@ -770,7 +778,7 @@
chip->step_chg_config->psy_prop = POWER_SUPPLY_PROP_VOLTAGE_NOW;
chip->step_chg_config->prop_name = "VBATT";
- chip->step_chg_config->hysteresis = 100000;
+ chip->step_chg_config->hysteresis = 0; /* 100000 */;
chip->jeita_fcc_config = devm_kzalloc(dev,
sizeof(struct jeita_fcc_cfg), GFP_KERNEL);
diff --git a/drivers/regulator/qpnp-lcdb-regulator.c b/drivers/regulator/qpnp-lcdb-regulator.c
old mode 100644
new mode 100755
index e3786e5..472ca6a
--- a/drivers/regulator/qpnp-lcdb-regulator.c
+++ b/drivers/regulator/qpnp-lcdb-regulator.c
@@ -12,6 +12,7 @@
*/
#define pr_fmt(fmt) "LCDB: %s: " fmt, __func__
+#define LCDB_PWRUP_PWRDN_CTL_REG 0x66
#include <linux/delay.h>
#include <linux/device.h>
@@ -2315,6 +2316,7 @@
int rc;
struct device_node *node;
struct qpnp_lcdb *lcdb;
+ u8 val = 0xF; // 0xF==1111==VSN delay 8ms; VSP delay 8ms
node = pdev->dev.of_node;
if (!node) {
@@ -2367,6 +2369,8 @@
lcdb->lcdb_enabled, lcdb->ldo.voltage_mv,
lcdb->ncp.voltage_mv, lcdb->bst.voltage_mv);
+ rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_PWRUP_PWRDN_CTL_REG , &val, 1);
+
return rc;
}
diff --git a/drivers/soc/qcom/msm_minidump.c b/drivers/soc/qcom/msm_minidump.c
index 309af6c..30b69c8 100644
--- a/drivers/soc/qcom/msm_minidump.c
+++ b/drivers/soc/qcom/msm_minidump.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018,2021, 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
@@ -221,6 +221,7 @@
int msm_minidump_add_region(const struct md_region *entry)
{
u32 entries;
+ u32 toc_init;
struct md_region *mdr;
if (validate_region(entry))
@@ -239,6 +240,19 @@
return -ENOMEM;
}
+ toc_init = 0;
+ if (minidump_table.md_ss_toc &&
+ (minidump_table.md_ss_toc->md_ss_enable_status ==
+ MD_SS_ENABLED)) {
+ toc_init = 1;
+ if (minidump_table.md_ss_toc->ss_region_count >=
+ MAX_NUM_ENTRIES) {
+ spin_unlock(&mdt_lock);
+ pr_err("Maximum regions in minidump table reached.\n");
+ return -ENOMEM;
+ }
+ }
+
mdr = &minidump_table.entry[entries];
strlcpy(mdr->name, entry->name, sizeof(mdr->name));
mdr->virt_addr = entry->virt_addr;
@@ -248,9 +262,7 @@
minidump_table.num_regions = entries + 1;
- if (minidump_table.md_ss_toc &&
- (minidump_table.md_ss_toc->md_ss_enable_status ==
- MD_SS_ENABLED))
+ if (toc_init)
md_update_ss_toc(entry);
else
pendings++;
diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
old mode 100644
new mode 100755
index 7dee607..c46234f
--- a/drivers/soc/qcom/socinfo.c
+++ b/drivers/soc/qcom/socinfo.c
@@ -2007,6 +2007,64 @@
}
}
+char ddr_vendor[32] = "";
+/* BOOT.BF.3.3.2\boot_images\core\api\boot\ddr_common.h */
+typedef enum
+{
+ RESERVED_0, /**< Reserved for future use. */
+ SAMSUNG, /**< Samsung. */
+ QIMONDA, /**< Qimonda. */
+ ELPIDA, /**< Elpida Memory, Inc. */
+ ETRON, /**< Etron Technology, Inc. */
+ NANYA, /**< Nanya Technology Corporation. */
+ HYNIX, /**< Hynix Semiconductor Inc. */
+ MOSEL, /**< Mosel Vitelic Corporation. */
+ WINBOND, /**< Winbond Electronics Corp. */
+ ESMT, /**< Elite Semiconductor Memory Technology Inc. */
+ RESERVED_1, /**< Reserved for future use. */
+ SPANSION, /**< Spansion Inc. */
+ SST, /**< Silicon Storage Technology, Inc. */
+ ZMOS, /**< ZMOS Technology, Inc. */
+ INTEL, /**< Intel Corporation. */
+ NUMONYX = 254, /**< Numonyx, acquired by Micron Technology, Inc. */
+ MICRON = 255, /**< Micron Technology, Inc. */
+ DDR_MANUFACTURES_MAX = 0x7FFFFFFF /**< Forces the enumerator to 32 bits. */
+} DDR_MANUFACTURES;
+
+void smem_get_ddr_manufacturer_id(unsigned char *buf)
+{
+ unsigned int *manufacturer_id;
+ unsigned int manufacturer_id_len = sizeof(manufacturer_id);
+
+ manufacturer_id = smem_get_entry(SMEM_ID_VENDOR2, &manufacturer_id_len, 0,
+ SMEM_ANY_HOST_FLAG);
+ if (manufacturer_id == NULL)
+ {
+ pr_err("[B]%s(%d): Failed to read SMEM_ID_VENDOR2\n", __func__, __LINE__);
+ }
+
+ switch(*manufacturer_id)
+ {
+ case SAMSUNG:
+ snprintf((char *)buf, 64, "SAMSUNG");
+ break;
+ case ELPIDA:
+ snprintf((char *)buf, 64, "ELPIDA");
+ break;
+ case HYNIX:
+ snprintf((char *)buf, 64, "HYNIX");
+ break;
+ case MICRON:
+ snprintf((char *)buf, 64, "MICRON");
+ break;
+ default:
+ snprintf((char *)buf, 64, "OTHERS");
+ break;
+ }
+
+ pr_err("[B]%s(%d): manufacturer_id=%d, %s\n", __func__, __LINE__, *manufacturer_id, buf);
+}
+
int __init socinfo_init(void)
{
static bool socinfo_init_done;
@@ -2036,6 +2094,10 @@
arch_read_hardware_id = msm_read_hardware_id;
socinfo_init_done = true;
+ memset(ddr_vendor, 0, sizeof(ddr_vendor));
+ smem_get_ddr_manufacturer_id((unsigned char *) ddr_vendor);
+ pr_err("[B]%s(%d): ddr_vendor=%s\n", __func__, __LINE__, ddr_vendor);
+
return 0;
}
subsys_initcall(socinfo_init);
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index 7fec28c..46decb1 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -1349,42 +1349,45 @@
static void *ion_dma_buf_kmap(struct dma_buf *dmabuf, unsigned long offset)
{
struct ion_buffer *buffer = dmabuf->priv;
-
- return buffer->vaddr + offset * PAGE_SIZE;
-}
-
-static void ion_dma_buf_kunmap(struct dma_buf *dmabuf, unsigned long offset,
- void *ptr)
-{
-}
-
-static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
- enum dma_data_direction direction)
-{
- struct ion_buffer *buffer = dmabuf->priv;
void *vaddr;
if (!buffer->heap->ops->map_kernel) {
pr_err("%s: map kernel is not implemented by this heap.\n",
__func__);
- return -ENODEV;
+ return ERR_PTR(-ENOTTY);
}
-
mutex_lock(&buffer->lock);
vaddr = ion_buffer_kmap_get(buffer);
mutex_unlock(&buffer->lock);
- return PTR_ERR_OR_ZERO(vaddr);
+
+ if (IS_ERR(vaddr))
+ return vaddr;
+
+ return vaddr + offset * PAGE_SIZE;
+}
+
+static void ion_dma_buf_kunmap(struct dma_buf *dmabuf, unsigned long offset,
+ void *ptr)
+{
+ struct ion_buffer *buffer = dmabuf->priv;
+
+ if (buffer->heap->ops->map_kernel) {
+ mutex_lock(&buffer->lock);
+ ion_buffer_kmap_put(buffer);
+ mutex_unlock(&buffer->lock);
+ }
+
+}
+
+static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
+ enum dma_data_direction direction)
+{
+ return 0;
}
static int ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf,
enum dma_data_direction direction)
{
- struct ion_buffer *buffer = dmabuf->priv;
-
- mutex_lock(&buffer->lock);
- ion_buffer_kmap_put(buffer);
- mutex_unlock(&buffer->lock);
-
return 0;
}
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 08e47de..d783342 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -544,8 +544,8 @@
put_pid(tty->session);
put_pid(tty->pgrp);
tty->pgrp = get_pid(task_pgrp(current));
- spin_unlock_irqrestore(&tty->ctrl_lock, flags);
tty->session = get_pid(task_session(current));
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
if (current->signal->tty) {
tty_debug(tty, "current tty %s not NULL!!\n",
current->signal->tty->name);
@@ -935,21 +935,24 @@
spin_lock_irq(¤t->sighand->siglock);
put_pid(current->signal->tty_old_pgrp);
current->signal->tty_old_pgrp = NULL;
-
tty = tty_kref_get(current->signal->tty);
+ spin_unlock_irq(¤t->sighand->siglock);
+
if (tty) {
unsigned long flags;
+
+ tty_lock(tty);
spin_lock_irqsave(&tty->ctrl_lock, flags);
put_pid(tty->session);
put_pid(tty->pgrp);
tty->session = NULL;
tty->pgrp = NULL;
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+ tty_unlock(tty);
tty_kref_put(tty);
} else
tty_debug_hangup(tty, "no current tty\n");
- spin_unlock_irq(¤t->sighand->siglock);
/* Now clear signal->tty under the lock */
read_lock(&tasklist_lock);
session_clear_tty(task_session(current));
@@ -2632,14 +2635,19 @@
return -ENOTTY;
if (retval)
return retval;
- if (!current->signal->tty ||
- (current->signal->tty != real_tty) ||
- (real_tty->session != task_session(current)))
- return -ENOTTY;
+
if (get_user(pgrp_nr, p))
return -EFAULT;
if (pgrp_nr < 0)
return -EINVAL;
+
+ spin_lock_irq(&real_tty->ctrl_lock);
+ if (!current->signal->tty ||
+ (current->signal->tty != real_tty) ||
+ (real_tty->session != task_session(current))) {
+ retval = -ENOTTY;
+ goto out_unlock_ctrl;
+ }
rcu_read_lock();
pgrp = find_vpid(pgrp_nr);
retval = -ESRCH;
@@ -2649,12 +2657,12 @@
if (session_of_pgrp(pgrp) != task_session(current))
goto out_unlock;
retval = 0;
- spin_lock_irq(&tty->ctrl_lock);
put_pid(real_tty->pgrp);
real_tty->pgrp = get_pid(pgrp);
- spin_unlock_irq(&tty->ctrl_lock);
out_unlock:
rcu_read_unlock();
+out_unlock_ctrl:
+ spin_unlock_irq(&real_tty->ctrl_lock);
return retval;
}
@@ -2666,21 +2674,31 @@
*
* Obtain the session id of the tty. If there is no session
* return an error.
- *
- * Locking: none. Reference to current->signal->tty is safe.
*/
static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
{
+ unsigned long flags;
+ pid_t sid;
+
/*
* (tty == real_tty) is a cheap way of
* testing if the tty is NOT a master pty.
*/
if (tty == real_tty && current->signal->tty != real_tty)
return -ENOTTY;
+
+ spin_lock_irqsave(&real_tty->ctrl_lock, flags);
if (!real_tty->session)
- return -ENOTTY;
- return put_user(pid_vnr(real_tty->session), p);
+ goto err;
+ sid = pid_vnr(real_tty->session);
+ spin_unlock_irqrestore(&real_tty->ctrl_lock, flags);
+
+ return put_user(sid, p);
+
+err:
+ spin_unlock_irqrestore(&real_tty->ctrl_lock, flags);
+ return -ENOTTY;
}
/**
@@ -3098,10 +3116,14 @@
struct task_struct *g, *p;
struct pid *session;
int i;
+ unsigned long flags;
if (!tty)
return;
- session = tty->session;
+
+ spin_lock_irqsave(&tty->ctrl_lock, flags);
+ session = get_pid(tty->session);
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
tty_ldisc_flush(tty);
@@ -3133,6 +3155,7 @@
task_unlock(p);
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
+ put_pid(session);
#endif
}
diff --git a/drivers/usb/gadget/function/f_cdev.c b/drivers/usb/gadget/function/f_cdev.c
index c9bd871..36ace639 100644
--- a/drivers/usb/gadget/function/f_cdev.c
+++ b/drivers/usb/gadget/function/f_cdev.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011, 2013-2021, The Linux Foundation. All rights reserved.
* Linux Foundation chooses to take subject only to the GPLv2 license terms,
* and distributes only under these terms.
*
@@ -95,7 +95,7 @@
struct f_cdev {
struct cdev fcdev_cdev;
- struct device *dev;
+ struct device dev;
unsigned int port_num;
char name[sizeof(DEVICE_NAME) + 2];
int minor;
@@ -887,13 +887,16 @@
opts = container_of(fi, struct f_cdev_opts, func_inst);
if (opts->port) {
- device_destroy(fcdev_classp, MKDEV(major, opts->port->minor));
- cdev_del(&opts->port->fcdev_cdev);
+ cdev_device_del(&opts->port->fcdev_cdev, &opts->port->dev);
+ mutex_lock(&chardev_ida_lock);
+ ida_simple_remove(&chardev_ida, opts->port->minor);
+ mutex_unlock(&chardev_ida_lock);
+ usb_cser_debugfs_exit();
+ put_device(&opts->port->dev);
}
+
usb_cser_chardev_deinit();
- usb_cser_debugfs_exit();
kfree(opts->func_name);
- kfree(opts->port);
kfree(opts);
}
@@ -1114,13 +1117,10 @@
struct f_cdev *port;
port = container_of(inode->i_cdev, struct f_cdev, fcdev_cdev);
- if (!port) {
- pr_err("Port is NULL.\n");
- return -EINVAL;
- }
-
- if (port && port->port_open) {
+ get_device(&port->dev);
+ if (port->port_open) {
pr_err("port is already opened.\n");
+ put_device(&port->dev);
return -EBUSY;
}
@@ -1130,6 +1130,7 @@
port->is_connected);
if (ret) {
pr_debug("open interrupted.\n");
+ put_device(&port->dev);
return ret;
}
@@ -1149,16 +1150,12 @@
struct f_cdev *port;
port = file->private_data;
- if (!port) {
- pr_err("port is NULL.\n");
- return -EINVAL;
- }
-
spin_lock_irqsave(&port->port_lock, flags);
port->port_open = false;
port->cbits_updated = false;
spin_unlock_irqrestore(&port->port_lock, flags);
pr_debug("port(%s)(%pK) is closed.\n", port->name, port);
+ put_device(&port->dev);
return 0;
}
@@ -1727,11 +1724,17 @@
debugfs_remove_recursive(debugfs.debugfs_root);
}
+static void cdev_device_release(struct device *dev)
+{
+ struct f_cdev *port = container_of(dev, struct f_cdev, dev);
+
+ pr_debug("Free cdev port(%d)\n", port->port_num);
+ kfree(port);
+}
+
static struct f_cdev *f_cdev_alloc(char *func_name, int portno)
{
int ret;
- dev_t dev;
- struct device *device;
struct f_cdev *port;
port = kzalloc(sizeof(struct f_cdev), GFP_KERNEL);
@@ -1781,27 +1784,24 @@
/* create char device */
cdev_init(&port->fcdev_cdev, &f_cdev_fops);
- dev = MKDEV(major, port->minor);
- ret = cdev_add(&port->fcdev_cdev, dev, 1);
+ device_initialize(&port->dev);
+ port->dev.class = fcdev_classp;
+ port->dev.parent = NULL;
+ port->dev.release = cdev_device_release;
+ port->dev.devt = MKDEV(major, port->minor);
+ dev_set_name(&port->dev, port->name);
+ ret = cdev_device_add(&port->fcdev_cdev, &port->dev);
if (ret) {
pr_err("Failed to add cdev for port(%s)\n", port->name);
goto err_cdev_add;
}
- device = device_create(fcdev_classp, NULL, dev, NULL, port->name);
- if (IS_ERR(device)) {
- ret = PTR_ERR(device);
- goto err_create_dev;
- }
-
usb_cser_debugfs_init(port);
pr_info("port_name:%s (%pK) portno:(%d)\n",
port->name, port, port->port_num);
return port;
-err_create_dev:
- cdev_del(&port->fcdev_cdev);
err_cdev_add:
destroy_workqueue(port->fcdev_wq);
err_get_ida:
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c
old mode 100644
new mode 100755
index 1164e6f..3fb7de9
--- a/drivers/video/fbdev/msm/mdss_dsi.c
+++ b/drivers/video/fbdev/msm/mdss_dsi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, 2021, 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
@@ -35,6 +35,9 @@
#include "mdss_debug.h"
#include "mdss_dsi_phy.h"
#include "mdss_dba_utils.h"
+#include "mdss_smmu.h"
+
+#include <linux/proc_fs.h>
#define XO_CLK_RATE 19200000
#define CMDLINE_DSI_CTL_NUM_STRING_LEN 2
@@ -410,6 +413,8 @@
int ret = 0;
struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
+ gpio_direction_output(64, 1);
+
if (pdata == NULL) {
pr_err("%s: Invalid input data\n", __func__);
return -EINVAL;
@@ -1338,6 +1343,8 @@
int ret = 0;
struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
struct mdss_panel_info *panel_info = NULL;
+ struct platform_device *pdev;
+ struct dsi_buf *tp;
if (pdata == NULL) {
pr_err("%s: Invalid input data\n", __func__);
@@ -1349,6 +1356,16 @@
panel_info = &ctrl_pdata->panel_data.panel_info;
+ pdev = mdss_res->pdev;
+ tp = &ctrl_pdata->tx_buf;
+ mdss_smmu_dma_free_coherent(&pdev->dev, SZ_4K, tp->start, tp->dmap,
+ ctrl_pdata->dma_addr, MDSS_IOMMU_DOMAIN_UNSECURE);
+ tp->end = NULL;
+ tp->size = 0;
+ ctrl_pdata->dma_addr = 0;
+ tp->start = NULL;
+ tp->dmap = 0;
+
pr_debug("%s+: ctrl=%pK ndx=%d power_state=%d\n",
__func__, ctrl_pdata, ctrl_pdata->ndx, power_state);
@@ -1517,6 +1534,8 @@
struct mipi_panel_info *mipi;
struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
int cur_power_state;
+ struct platform_device *pdev;
+ struct dsi_buf *tp;
if (pdata == NULL) {
pr_err("%s: Invalid input data\n", __func__);
@@ -1526,6 +1545,20 @@
ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
panel_data);
+ pdev = mdss_res->pdev;
+ tp = &ctrl_pdata->tx_buf;
+ if (!ctrl_pdata->mdss_util->iommu_attached())
+ pr_err("%s : iommu not attached\n", __func__);
+
+ ret = mdss_smmu_dma_alloc_coherent(&pdev->dev, SZ_4K, &tp->dmap,
+ &ctrl_pdata->dma_addr, (void *)&tp->start, GFP_KERNEL,
+ MDSS_IOMMU_DOMAIN_UNSECURE);
+ if (IS_ERR_VALUE((unsigned long)ret))
+ pr_err("%s : mdss_smmu_dma_alloc_coherent failed\n", __func__);
+
+ tp->end = tp->start + SZ_4K;
+ tp->size = SZ_4K;
+
if (ctrl_pdata->debugfs_info)
mdss_dsi_validate_debugfs_info(ctrl_pdata);
@@ -3268,6 +3301,77 @@
return rc;
}
+extern void seq_printf(struct seq_file *m, const char *f, ...);
+extern int single_open(struct file *, int (*)(struct seq_file *, void *), void *);
+extern ssize_t seq_read(struct file *, char __user *, size_t, loff_t *);
+extern loff_t seq_lseek(struct file *, loff_t, int);
+extern int single_release(struct inode *, struct file *);
+
+static int proc_lcm_vendor_show(struct seq_file *m, void *v)
+{
+ int lcm_id;
+
+ lcm_id = gpio_request(59, "lcm_id");
+
+ if(lcm_id == 1)
+ {
+ //For another's LCM module
+ seq_printf(m, "2nd LCM\n");
+ }
+ else
+ { //DJN's LCM module id is 0.
+ seq_printf(m, "DJN , HX83112B\n");
+ }
+
+ return 0;
+}
+
+static int proc_lcm_vendor_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, proc_lcm_vendor_show, NULL);
+}
+
+static const struct file_operations proc_lcm_vendor_fops = {
+ .open = proc_lcm_vendor_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+
+static int proc_lcm_revision_show(struct seq_file *m, void *v)
+{
+ int lcm_id;
+ extern int RDDID_HWINFO[3];
+
+ lcm_id = gpio_request(59, "lcm_id");
+
+ if(lcm_id == 1)
+ {
+ //For another's LCM module
+ seq_printf(m, "2nd Source not ready.\n");
+ }
+ else
+ { //DJN's LCM module id is 0.
+ seq_printf(m, "DJN , HX%x%x%x\n", RDDID_HWINFO[0],RDDID_HWINFO[1],RDDID_HWINFO[2]);
+ }
+
+ return 0;
+}
+
+static int proc_lcm_revision_fops_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, proc_lcm_revision_show, NULL);
+}
+
+static const struct file_operations proc_lcm_revision_fops = {
+ .open = proc_lcm_revision_fops_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+
static int mdss_dsi_ctrl_probe(struct platform_device *pdev)
{
int rc = 0;
@@ -3459,6 +3563,10 @@
mdss_dsi_debug_bus_init(mdss_dsi_res);
+ proc_create("lcm_vendor", 0, NULL, &proc_lcm_vendor_fops);
+
+ proc_create("lcm_revision", 0666, NULL, &proc_lcm_revision_fops);
+
return 0;
error_shadow_clk_deinit:
diff --git a/drivers/video/fbdev/msm/mdss_dsi_host.c b/drivers/video/fbdev/msm/mdss_dsi_host.c
index 25a2600..14f14ec 100644
--- a/drivers/video/fbdev/msm/mdss_dsi_host.c
+++ b/drivers/video/fbdev/msm/mdss_dsi_host.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, 2021, 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
@@ -121,7 +121,6 @@
mutex_init(&ctrl->cmd_mutex);
mutex_init(&ctrl->clk_lane_mutex);
mutex_init(&ctrl->cmdlist_mutex);
- mdss_dsi_buf_alloc(ctrl_dev, &ctrl->tx_buf, SZ_4K);
mdss_dsi_buf_alloc(ctrl_dev, &ctrl->rx_buf, SZ_4K);
mdss_dsi_buf_alloc(ctrl_dev, &ctrl->status_buf, SZ_4K);
ctrl->cmdlist_commit = mdss_dsi_cmdlist_commit;
@@ -2145,7 +2144,6 @@
struct dsi_buf *tp)
{
int len, ret = 0;
- int domain = MDSS_IOMMU_DOMAIN_UNSECURE;
char *bp;
struct mdss_dsi_ctrl_pdata *mctrl = NULL;
int ignored = 0; /* overflow ignored */
@@ -2155,20 +2153,6 @@
len = ALIGN(tp->len, 4);
ctrl->dma_size = ALIGN(tp->len, SZ_4K);
- ctrl->mdss_util->iommu_lock();
- if (ctrl->mdss_util->iommu_attached()) {
- ret = mdss_smmu_dsi_map_buffer(tp->dmap, domain, ctrl->dma_size,
- &(ctrl->dma_addr), tp->start, DMA_TO_DEVICE);
- if (IS_ERR_VALUE((unsigned long)ret)) {
- pr_err("unable to map dma memory to iommu(%d)\n", ret);
- ctrl->mdss_util->iommu_unlock();
- return -ENOMEM;
- }
- ctrl->dmap_iommu_map = true;
- } else {
- ctrl->dma_addr = tp->dmap;
- }
-
reinit_completion(&ctrl->dma_comp);
if (ctrl->panel_mode == DSI_VIDEO_MODE)
@@ -2177,7 +2161,7 @@
if (mdss_dsi_sync_wait_trigger(ctrl)) {
/* broadcast same cmd to other panel */
mctrl = mdss_dsi_get_other_ctrl(ctrl);
- if (mctrl && mctrl->dma_addr == 0) {
+ if (mctrl) {
if (ignored) {
/* mask out overflow isr */
mdss_dsi_set_reg(mctrl, 0x10c,
@@ -2229,6 +2213,7 @@
pr_warn("%s: dma tx done but irq not triggered\n",
__func__);
} else {
+ MDSS_XLOG(0x909, status);
ret = -ETIMEDOUT;
}
}
@@ -2245,19 +2230,6 @@
if (!(data & BIT(5)))
mdss_dsi_set_reg(mctrl, 0x10c, 0x0f0000, 0);
}
- if (mctrl->dmap_iommu_map) {
- mdss_smmu_dsi_unmap_buffer(mctrl->dma_addr, domain,
- mctrl->dma_size, DMA_TO_DEVICE);
- mctrl->dmap_iommu_map = false;
- }
- mctrl->dma_addr = 0;
- mctrl->dma_size = 0;
- }
-
- if (ctrl->dmap_iommu_map) {
- mdss_smmu_dsi_unmap_buffer(ctrl->dma_addr, domain,
- ctrl->dma_size, DMA_TO_DEVICE);
- ctrl->dmap_iommu_map = false;
}
if (ignored) {
@@ -2268,10 +2240,9 @@
if (!(data & BIT(5)))
mdss_dsi_set_reg(ctrl, 0x10c, 0x0f0000, 0);
}
- ctrl->dma_addr = 0;
- ctrl->dma_size = 0;
+ MDSS_XLOG(ret);
+
end:
- ctrl->mdss_util->iommu_unlock();
return ret;
}
diff --git a/drivers/video/fbdev/msm/mdss_dsi_panel.c b/drivers/video/fbdev/msm/mdss_dsi_panel.c
old mode 100644
new mode 100755
index 7d3009b..9bd501c
--- a/drivers/video/fbdev/msm/mdss_dsi_panel.c
+++ b/drivers/video/fbdev/msm/mdss_dsi_panel.c
@@ -212,17 +212,17 @@
mdss_dsi_cmdlist_put(ctrl, &cmdreq);
}
-
-static char led_pwm1[2] = {0x51, 0x0}; /* DTYPE_DCS_WRITE1 */
+static char led_pwm1[3] = {0x51, 0x00,0x00}; /* DTYPE_DCS_WRITE1 */
static struct dsi_cmd_desc backlight_cmd = {
- {DTYPE_DCS_WRITE1, 1, 0, 0, 1, sizeof(led_pwm1)},
- led_pwm1
+ {DTYPE_DCS_LWRITE, 1, 0, 0, 1, sizeof(led_pwm1)}, led_pwm1
};
static void mdss_dsi_panel_bklt_dcs(struct mdss_dsi_ctrl_pdata *ctrl, int level)
{
struct dcs_cmd_req cmdreq;
struct mdss_panel_info *pinfo;
+
+int para_1,para_2;
pinfo = &(ctrl->panel_data.panel_info);
if (pinfo->dcs_cmd_by_left) {
@@ -232,7 +232,13 @@
pr_debug("%s: level=%d\n", __func__, level);
- led_pwm1[1] = (unsigned char)level;
+ //led_pwm1[1] = (unsigned char)level;
+ para_1 = (level>>8)&0x0F;
+ para_2 = level&0xFF;
+
+ led_pwm1[1] = (unsigned char)para_1;
+ led_pwm1[2] = (unsigned char)para_2;
+
memset(&cmdreq, 0, sizeof(cmdreq));
cmdreq.cmds = &backlight_cmd;
@@ -523,6 +529,15 @@
gpio_free(ctrl_pdata->disp_en_gpio);
}
gpio_set_value((ctrl_pdata->rst_gpio), 0);
+
+ //Move "pull low TP reset pin" from mdss_dsi.c,
+ //it have to same with LCM reset pin pull low
+
+ //TP reset pin pull low with LCD reset pin at same time.
+ gpio_direction_output(64, 0);
+
+ msleep(1);
+
gpio_free(ctrl_pdata->rst_gpio);
if (gpio_is_valid(ctrl_pdata->mode_gpio))
gpio_free(ctrl_pdata->mode_gpio);
@@ -824,11 +839,18 @@
mdss_dsi_panel_dsc_pps_send(ctrl_pdata, &pdata->panel_info);
}
+static char RDDID[4] = {0x04, 0x00, 0x00, 0x00};
+static struct dsi_cmd_desc cmd_RDDID = {
+ {DTYPE_DCS_READ, 1, 0, 1, 5, sizeof(RDDID)}, RDDID};
+int RDDID_HWINFO[3];
+int RDDID_read_count =0;
+
static void mdss_dsi_panel_bl_ctrl(struct mdss_panel_data *pdata,
u32 bl_level)
{
struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
struct mdss_dsi_ctrl_pdata *sctrl = NULL;
+ struct dcs_cmd_req cmdreq2;
if (pdata == NULL) {
pr_err("%s: Invalid input data\n", __func__);
@@ -838,6 +860,28 @@
ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
panel_data);
+ if(RDDID_read_count==0){
+ memset(&cmdreq2, 0, sizeof(cmdreq2));
+ cmdreq2.cmds = &cmd_RDDID;
+ cmdreq2.cmds_cnt = 1;
+ cmdreq2.flags = CMD_REQ_COMMIT | CMD_REQ_RX;;
+ cmdreq2.rlen = 3;//return 3 values
+ cmdreq2.cb = NULL; /* call back */
+ cmdreq2.rbuf = ctrl_pdata->rx_buf.data;
+
+ mdss_dsi_cmdlist_put(ctrl_pdata, &cmdreq2);
+
+ if(ctrl_pdata->rx_buf.len>0){
+ RDDID_HWINFO[0]=(int)*(ctrl_pdata->rx_buf.data);
+ RDDID_HWINFO[1]=(int)*(ctrl_pdata->rx_buf.data+1);
+ RDDID_HWINFO[2]=(int)*(ctrl_pdata->rx_buf.data+2);
+ //pr_err("[Jialong] ctrl->rx_buf.data data =0x%x\n",*(ctrl_pdata->rx_buf.data));
+ RDDID_read_count++;
+ }
+ }
+
+ mdelay(1);
+
/*
* Some backlight controllers specify a minimum duty cycle
* for the backlight brightness. If the brightness is less
diff --git a/drivers/video/fbdev/msm/mdss_io_util.c b/drivers/video/fbdev/msm/mdss_io_util.c
old mode 100644
new mode 100755
index 2f70ad3..d3f3bf2
--- a/drivers/video/fbdev/msm/mdss_io_util.c
+++ b/drivers/video/fbdev/msm/mdss_io_util.c
@@ -286,6 +286,12 @@
goto vreg_set_opt_mode_fail;
}
rc = regulator_enable(in_vreg[i].vreg);
+
+ if(!strcmp(in_vreg[i].vreg_name,"vddio")){
+ msleep(10);
+ }
+
+
if (in_vreg[i].post_on_sleep && need_sleep)
usleep_range((in_vreg[i].post_on_sleep * 1000),
(in_vreg[i].post_on_sleep * 1000) + 10);
@@ -304,6 +310,11 @@
regulator_set_load(in_vreg[i].vreg,
in_vreg[i].load[DSS_REG_MODE_DISABLE]);
+ if(!strcmp(in_vreg[i].vreg_name,"vddio")){
+ msleep(10);
+ }
+
+
if (regulator_is_enabled(in_vreg[i].vreg))
regulator_disable(in_vreg[i].vreg);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
index ed98df6..d9fa4e9 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, 2021, 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
@@ -1499,6 +1499,11 @@
MDSS_XLOG(ctl->num, ctl->underrun_cnt);
if (!ctx->timegen_en) {
+ rc = mdss_iommu_ctrl(1);
+ if (IS_ERR_VALUE((unsigned long)rc)) {
+ pr_err("IOMMU attach failed\n");
+ return rc;
+ }
rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_LINK_READY, NULL,
CTL_INTF_EVENT_FLAG_DEFAULT);
if (rc) {
@@ -1521,12 +1526,6 @@
usecs_to_jiffies(VSYNC_TIMEOUT_US));
}
- rc = mdss_iommu_ctrl(1);
- if (IS_ERR_VALUE((unsigned long)rc)) {
- pr_err("IOMMU attach failed\n");
- return rc;
- }
-
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
mdss_mdp_irq_enable(MDSS_MDP_IRQ_TYPE_INTF_UNDER_RUN,
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 11c061b..af27a71 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1286,10 +1286,8 @@
*/
if (!for_part) {
ret = devcgroup_inode_permission(bdev->bd_inode, perm);
- if (ret != 0) {
- bdput(bdev);
+ if (ret != 0)
return ret;
- }
}
restart:
@@ -1361,8 +1359,10 @@
goto out_clear;
BUG_ON(for_part);
ret = __blkdev_get(whole, mode, 1);
- if (ret)
+ if (ret) {
+ bdput(whole);
goto out_clear;
+ }
bdev->bd_contains = whole;
bdev->bd_part = disk_get_part(disk, partno);
if (!(disk->flags & GENHD_FL_UP) ||
@@ -1416,7 +1416,6 @@
put_disk(disk);
module_put(owner);
out:
- bdput(bdev);
return ret;
}
@@ -1502,6 +1501,9 @@
bdput(whole);
}
+ if (res)
+ bdput(bdev);
+
return res;
}
EXPORT_SYMBOL(blkdev_get);
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index e76d0c3..4bcbab6 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -1749,9 +1749,11 @@
* not already there, and calling reverse_path_check()
* during ep_insert().
*/
- if (list_empty(&epi->ffd.file->f_tfile_llink))
- list_add(&epi->ffd.file->f_tfile_llink,
- &tfile_check_list);
+ if (list_empty(&epi->ffd.file->f_tfile_llink)) {
+ if (get_file_rcu(epi->ffd.file))
+ list_add(&epi->ffd.file->f_tfile_llink,
+ &tfile_check_list);
+ }
}
}
mutex_unlock(&ep->mtx);
@@ -1795,6 +1797,7 @@
file = list_first_entry(&tfile_check_list, struct file,
f_tfile_llink);
list_del_init(&file->f_tfile_llink);
+ fput(file);
}
INIT_LIST_HEAD(&tfile_check_list);
}
@@ -1945,13 +1948,13 @@
mutex_lock(&epmutex);
if (is_file_epoll(tf.file)) {
error = -ELOOP;
- if (ep_loop_check(ep, tf.file) != 0) {
- clear_tfile_check_list();
+ if (ep_loop_check(ep, tf.file) != 0)
goto error_tgt_fput;
- }
- } else
+ } else {
+ get_file(tf.file);
list_add(&tf.file->f_tfile_llink,
&tfile_check_list);
+ }
mutex_lock_nested(&ep->mtx, 0);
if (is_file_epoll(tf.file)) {
tep = tf.file->private_data;
@@ -1975,8 +1978,6 @@
error = ep_insert(ep, &epds, tf.file, fd, full_check);
} else
error = -EEXIST;
- if (full_check)
- clear_tfile_check_list();
break;
case EPOLL_CTL_DEL:
if (epi)
@@ -1999,8 +2000,10 @@
mutex_unlock(&ep->mtx);
error_tgt_fput:
- if (full_check)
+ if (full_check) {
+ clear_tfile_check_list();
mutex_unlock(&epmutex);
+ }
fdput(tf);
error_fput:
diff --git a/gen_headers_arm.bp b/gen_headers_arm.bp
index 230ca68..787f23b 100644
--- a/gen_headers_arm.bp
+++ b/gen_headers_arm.bp
@@ -474,6 +474,8 @@
"linux/qcota.h",
"linux/qg-profile.h",
"linux/qg.h",
+ "linux/qbg-profile.h",
+ "linux/qbg.h",
"linux/qnx4_fs.h",
"linux/qnxtypes.h",
"linux/qrng.h",
diff --git a/gen_headers_arm64.bp b/gen_headers_arm64.bp
index cc42a61..dd22a35 100644
--- a/gen_headers_arm64.bp
+++ b/gen_headers_arm64.bp
@@ -472,6 +472,8 @@
"linux/qcota.h",
"linux/qg-profile.h",
"linux/qg.h",
+ "linux/qbg-profile.h",
+ "linux/qbg.h",
"linux/qnx4_fs.h",
"linux/qnxtypes.h",
"linux/qrng.h",
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index fdde51a..5546672 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1554,6 +1554,18 @@
}
/**
+ * skb_queue_len_lockless - get queue length
+ * @list_: list to measure
+ *
+ * Return the length of an &sk_buff queue.
+ * This variant can be used in lockless contexts.
+ */
+static inline __u32 skb_queue_len_lockless(const struct sk_buff_head *list_)
+{
+ return READ_ONCE(list_->qlen);
+}
+
+/**
* __skb_queue_head_init - initialize non-spinlock portions of sk_buff_head
* @list: queue to initialize
*
@@ -1756,7 +1768,7 @@
{
struct sk_buff *next, *prev;
- list->qlen--;
+ WRITE_ONCE(list->qlen, list->qlen - 1);
next = skb->next;
prev = skb->prev;
skb->next = skb->prev = NULL;
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 31c9bbc..c67ef6f 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -293,6 +293,10 @@
struct termiox *termiox; /* May be NULL for unsupported */
char name[64];
struct pid *pgrp; /* Protected by ctrl lock */
+ /*
+ * Writes protected by both ctrl lock and legacy mutex, readers must use
+ * at least one of them.
+ */
struct pid *session;
unsigned long flags;
int count;
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index fd60ecc..79f2e1c 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -8,6 +8,7 @@
void unix_inflight(struct user_struct *user, struct file *fp);
void unix_notinflight(struct user_struct *user, struct file *fp);
+void unix_destruct_scm(struct sk_buff *skb);
void unix_gc(void);
void wait_for_unix_gc(void);
struct sock *unix_get_socket(struct file *filp);
diff --git a/include/uapi/linux/qbg-profile.h b/include/uapi/linux/qbg-profile.h
new file mode 100644
index 0000000..a30f4db
--- /dev/null
+++ b/include/uapi/linux/qbg-profile.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef __QBG_PROFILE_H__
+#define __QBG_PROFILE_H__
+
+#define MAX_BP_LUT_ROWS 35
+#define MAX_BP_LUT_COLS 8
+#define MAX_PROFILE_NAME_LENGTH 256
+
+enum profile_table_type {
+ CHARGE_TABLE = 0,
+ DISCHARGE_TABLE,
+};
+
+struct battery_data_table {
+ unsigned short int table[MAX_BP_LUT_ROWS][MAX_BP_LUT_COLS];
+ int unit_conv_factor[MAX_BP_LUT_COLS];
+ unsigned short int nrows;
+ unsigned short int ncols;
+};
+
+struct battery_config {
+ char bp_profile_name[MAX_PROFILE_NAME_LENGTH];
+ int bp_batt_id;
+ int capacity;
+ int bp_checksum;
+ int soh_range_high;
+ int soh_range_low;
+ int normal_impedance;
+ int aged_impedance;
+ int normal_capacity;
+ int aged_capacity;
+ int recharge_soc_delta;
+ int recharge_vflt_delta;
+ int recharge_iterm;
+};
+
+struct battery_profile_table {
+ enum profile_table_type table_type;
+ int table_index;
+ struct battery_data_table *table;
+};
+
+/* IOCTLs to query battery profile data */
+/* Battery configuration */
+#define BPIOCXBP \
+ _IOWR('B', 0x01, struct battery_config)
+/* Battery profile table */
+#define BPIOCXBPTABLE \
+ _IOWR('B', 0x02, struct battery_profile_table)
+
+#endif
diff --git a/include/uapi/linux/qbg.h b/include/uapi/linux/qbg.h
new file mode 100644
index 0000000..d8e335b
--- /dev/null
+++ b/include/uapi/linux/qbg.h
@@ -0,0 +1,179 @@
+/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef __QBG_H__
+#define __QBG_H__
+
+#define MAX_FIFO_COUNT 36
+#define QBG_MAX_STEP_CHG_ENTRIES 6
+
+enum QBG_STATE {
+ QBG_LPM,
+ QBG_MPM,
+ QBG_HPM,
+ QBG_FAST_CHAR,
+ QBG_PON_OCV,
+ QBG_STATE_MAX,
+};
+
+enum QBG_SDAM_DATA_OFFSET {
+ QBG_ACC0_OFFSET = 0,
+ QBG_ACC1_OFFSET = 2,
+ QBG_ACC2_OFFSET = 4,
+ QBG_TBAT_OFFSET = 6,
+ QBG_IBAT_OFFSET = 8,
+ QBG_VREF_OFFSET = 10,
+ QBG_DATA_TAG_OFFSET = 12,
+ QBG_QG_STS_OFFSET,
+ QBG_STS1_OFFSET,
+ QBG_STS2_OFFSET,
+ QBG_STS3_OFFSET,
+ QBG_ONE_FIFO_LENGTH,
+};
+
+enum qbg {
+ QBG_PARAM_SOC,
+ QBG_PARAM_BATT_SOC,
+ QBG_PARAM_SYS_SOC,
+ QBG_PARAM_ESR,
+ QBG_PARAM_OCV_UV,
+ QBG_PARAM_MAX_LOAD_NOW,
+ QBG_PARAM_MAX_LOAD_AVG,
+ QBG_PARAM_HOLD_SOC_100PCT,
+ QBG_PARAM_CHARGE_CYCLE_COUNT,
+ QBG_PARAM_LEARNED_CAPACITY,
+ QBG_PARAM_TTF_100MS,
+ QBG_PARAM_TTE_100MS,
+ QBG_PARAM_SOH,
+ QBG_PARAM_TBAT,
+ QBG_PARAM_SYS_SOC_HOLD_100PCT,
+ QBG_PARAM_JEITA_COOL_THRESHOLD,
+ QBG_PARAM_TOTAL_IMPEDANCE,
+ QBG_PARAM_ESSENTIAL_PARAM_REVID,
+ QBG_PARAM_FIFO_TIMESTAMP,
+ QBG_PARAM_MAX,
+};
+
+struct qbg_essential_params {
+ short int msoc;
+ short int cutoff_soc;
+ short int full_soc;
+ short int x0;
+ short int x1;
+ short int x2;
+ short int soh_r;
+ short int soh_c;
+ short int theta0;
+ short int theta1;
+ short int theta2;
+ short int i1full;
+ short int i2full;
+ short int i1cutoff;
+ short int i2cutoff;
+ short int syssoc;
+ int discharge_cycle_count;
+ int charge_cycle_count;
+ unsigned int rtc_time;
+ short int batt_therm;
+ unsigned short int ocv;
+} __attribute__ ((__packed__));
+
+struct fifo_data {
+ unsigned short int v1;
+ unsigned short int v2;
+ unsigned short int i;
+ unsigned short int tbat;
+ unsigned short int ibat;
+ unsigned short int vref;
+ char data_tag;
+ char qg_sts;
+ char sts1;
+ char sts2;
+ char sts3;
+} __attribute__ ((__packed__));
+
+struct k_fifo_data {
+ unsigned int v1;
+ unsigned int v2;
+ unsigned int i;
+ unsigned int tbat;
+ unsigned int ibat;
+ unsigned int vref;
+ unsigned int data_tag;
+ unsigned int qg_sts;
+ unsigned int sts1;
+ unsigned int sts2;
+ unsigned int sts3;
+} __attribute__ ((__packed__));
+
+struct qbg_config {
+ unsigned int batt_id;
+ unsigned int pon_ocv;
+ unsigned int pon_ibat;
+ unsigned int pon_tbat;
+ unsigned int pon_soc;
+ unsigned int float_volt_uv;
+ unsigned int fastchg_curr_ma;
+ unsigned int vbat_cutoff_mv;
+ unsigned int ibat_cutoff_ma;
+ unsigned int vph_min_mv;
+ unsigned int iterm_ma;
+ unsigned int rconn_mohm;
+ unsigned long current_time;
+ unsigned int sdam_batt_id;
+ unsigned int essential_param_revid;
+ unsigned long sample_time_us[QBG_STATE_MAX];
+} __attribute__ ((__packed__));
+
+struct qbg_param {
+ unsigned int data;
+ _Bool valid;
+};
+
+struct qbg_kernel_data {
+ unsigned int seq_no;
+ unsigned int fifo_time;
+ unsigned int fifo_count;
+ struct k_fifo_data fifo[MAX_FIFO_COUNT];
+ struct qbg_param param[QBG_PARAM_MAX];
+} __attribute__ ((__packed__));
+
+struct qbg_user_data {
+ struct qbg_param param[QBG_PARAM_MAX];
+} __attribute__ ((__packed__));
+
+struct range_data {
+ int low_threshold;
+ int high_threshold;
+ unsigned int value;
+} __attribute__ ((__packed__));
+
+struct ranges {
+ struct range_data data[QBG_MAX_STEP_CHG_ENTRIES];
+ unsigned char range_count;
+ _Bool valid;
+} __attribute__((__packed__));
+
+struct qbg_step_chg_jeita_params {
+ int jeita_full_fv_10nv;
+ int jeita_full_iterm_10na;
+ int jeita_warm_adc_value;
+ int jeita_cool_adc_value;
+ int battery_beta;
+ int battery_therm_kohm;
+ struct ranges step_fcc_cfg;
+ struct ranges jeita_fcc_cfg;
+ struct ranges jeita_fv_cfg;
+ unsigned char ttf_calc_mode;
+} __attribute__ ((__packed__));
+
+/* IOCTLs to read & write QBG config and essential params */
+#define QBGIOCXCFG _IOR('B', 0x01, struct qbg_config)
+#define QBGIOCXEPR _IOR('B', 0x02, struct qbg_essential_params)
+#define QBGIOCXEPW _IOWR('B', 0x03, struct qbg_essential_params)
+#define QBGIOCXSTEPCHGCFG \
+ _IOWR('B', 0x04, struct qbg_step_chg_jeita_params)
+
+#endif
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
old mode 100644
new mode 100755
index f3a22c9..47f88bb
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -66,6 +66,7 @@
#include <linux/kexec.h>
#include <linux/bpf.h>
#include <linux/mount.h>
+#include <soc/qcom/smem.h>
#include <asm/uaccess.h>
#include <asm/processor.h>
@@ -230,6 +231,8 @@
static struct ctl_table fs_table[];
static struct ctl_table debug_table[];
static struct ctl_table dev_table[];
+static struct ctl_table qpnp_power_on_table[];
+static struct ctl_table ddr_table[];
extern struct ctl_table random_table[];
#ifdef CONFIG_EPOLL
extern struct ctl_table epoll_table[];
@@ -267,6 +270,11 @@
.mode = 0555,
.child = dev_table,
},
+ {
+ .procname = "qpnp-power-on",
+ .mode = 0555,
+ .child = qpnp_power_on_table,
+ },
{ }
};
@@ -2089,6 +2097,38 @@
};
static struct ctl_table dev_table[] = {
+ {
+ .procname = "ddr",
+ .mode = 0555,
+ .child = ddr_table,
+ },
+ { }
+};
+static struct ctl_table qpnp_power_on_table[] = {
+ {
+ .procname = "pon_reason",
+ .data = &qpnp_pon_reason_extern,
+ .maxlen = sizeof(int),
+ .mode = 0444,
+ .proc_handler = proc_dointvec,
+ },
+ {
+ .procname = "poff_reason",
+ .data = &qpnp_poff_reason_extern,
+ .maxlen = sizeof(int),
+ .mode = 0444,
+ .proc_handler = proc_dointvec,
+ },
+ { }
+};
+static struct ctl_table ddr_table[] = {
+ {
+ .procname = "vendor",
+ .data = &ddr_vendor,
+ .maxlen = 32,
+ .mode = 0444,
+ .proc_handler = proc_dostring,
+ },
{ }
};
diff --git a/net/Makefile b/net/Makefile
index c84a347..83e91dc 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -16,7 +16,7 @@
obj-$(CONFIG_NETFILTER) += netfilter/
obj-$(CONFIG_INET) += ipv4/
obj-$(CONFIG_XFRM) += xfrm/
-obj-$(CONFIG_UNIX) += unix/
+obj-$(CONFIG_UNIX_SCM) += unix/
obj-$(CONFIG_NET) += ipv6/
obj-$(CONFIG_PACKET) += packet/
obj-$(CONFIG_NET_KEY) += key/
diff --git a/net/ipc_router/ipc_router_core.c b/net/ipc_router/ipc_router_core.c
old mode 100644
new mode 100755
index beca506..f68817e
--- a/net/ipc_router/ipc_router_core.c
+++ b/net/ipc_router/ipc_router_core.c
@@ -239,6 +239,10 @@
if (rport && rport->server) {
svcid = rport->server->name.service;
+ /* hold wakelock for thresh(proximity) algo sensor and
+ * OEM1(e.g: pick up gesture sensor) */
+ if (svcid == 277 || svcid == 287)
+ return false;
if (svcid == 400 || (svcid >= 256 && svcid <= 320))
return true;
}
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 5dab158..6b66f05 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -246,7 +246,7 @@
/**
* icmp_global_allow - Are we allowed to send one more ICMP message ?
*
- * Uses a token bucket to limit our ICMP messages to sysctl_icmp_msgs_per_sec.
+ * Uses a token bucket to limit our ICMP messages to ~sysctl_icmp_msgs_per_sec.
* Returns false if we reached the limit and can not send another packet.
* Note: called with BH disabled
*/
@@ -274,7 +274,10 @@
}
credit = min_t(u32, icmp_global.credit + incr, sysctl_icmp_msgs_burst);
if (credit) {
- credit--;
+ /* We want to use a credit of one in average, but need to randomize
+ * it for security reasons.
+ */
+ credit = max_t(int, credit - prandom_u32_max(3), 0);
rc = true;
}
WRITE_ONCE(icmp_global.credit, credit);
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
index f65d9363..29fe1e7 100644
--- a/net/netfilter/nf_conntrack_h323_main.c
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -1225,6 +1225,7 @@
{
.name = "Q.931",
.me = THIS_MODULE,
+ .data_len = sizeof(struct nf_ct_h323_master),
.tuple.src.l3num = AF_INET6,
.tuple.src.u.tcp.port = cpu_to_be16(Q931_PORT),
.tuple.dst.protonum = IPPROTO_TCP,
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index c72d59e..853abe3 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -714,6 +714,11 @@
rc = copied;
if (addr) {
+ /* There is an anonymous 2-byte hole after sq_family,
+ * make sure to clear it.
+ */
+ memset(addr, 0, sizeof(*addr));
+
addr->sq_family = AF_QIPCRTR;
addr->sq_node = le32_to_cpu(phdr->src_node_id);
addr->sq_port = le32_to_cpu(phdr->src_port_id);
diff --git a/net/unix/Kconfig b/net/unix/Kconfig
index 8b31ab8..3b9e450 100644
--- a/net/unix/Kconfig
+++ b/net/unix/Kconfig
@@ -19,6 +19,11 @@
Say Y unless you know what you are doing.
+config UNIX_SCM
+ bool
+ depends on UNIX
+ default y
+
config UNIX_DIAG
tristate "UNIX: socket monitoring interface"
depends on UNIX
diff --git a/net/unix/Makefile b/net/unix/Makefile
index b663c60..dc686c6 100644
--- a/net/unix/Makefile
+++ b/net/unix/Makefile
@@ -9,3 +9,5 @@
obj-$(CONFIG_UNIX_DIAG) += unix_diag.o
unix_diag-y := diag.o
+
+obj-$(CONFIG_UNIX_SCM) += scm.o
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index e7012a5..fa4f39e 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -118,6 +118,8 @@
#include <linux/security.h>
#include <linux/freezer.h>
+#include "scm.h"
+
struct hlist_head unix_socket_table[2 * UNIX_HASH_SIZE];
EXPORT_SYMBOL_GPL(unix_socket_table);
DEFINE_SPINLOCK(unix_table_lock);
@@ -191,11 +193,17 @@
return unix_peer(osk) == NULL || unix_our_peer(sk, osk);
}
-static inline int unix_recvq_full(struct sock const *sk)
+static inline int unix_recvq_full(const struct sock *sk)
{
return skb_queue_len(&sk->sk_receive_queue) > sk->sk_max_ack_backlog;
}
+static inline int unix_recvq_full_lockless(const struct sock *sk)
+{
+ return skb_queue_len_lockless(&sk->sk_receive_queue) >
+ READ_ONCE(sk->sk_max_ack_backlog);
+}
+
struct sock *unix_peer_get(struct sock *s)
{
struct sock *peer;
@@ -528,12 +536,14 @@
u->path.mnt = NULL;
state = sk->sk_state;
sk->sk_state = TCP_CLOSE;
+
+ skpair = unix_peer(sk);
+ unix_peer(sk) = NULL;
+
unix_state_unlock(sk);
wake_up_interruptible_all(&u->peer_wait);
- skpair = unix_peer(sk);
-
if (skpair != NULL) {
if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) {
unix_state_lock(skpair);
@@ -548,7 +558,6 @@
unix_dgram_peer_wake_disconnect(sk, skpair);
sock_put(skpair); /* It may now die */
- unix_peer(sk) = NULL;
}
/* Try to flush out this socket. Throw out buffers at least */
@@ -1498,78 +1507,51 @@
return err;
}
-static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb)
+static void unix_peek_fds(struct scm_cookie *scm, struct sk_buff *skb)
{
- int i;
-
- scm->fp = UNIXCB(skb).fp;
- UNIXCB(skb).fp = NULL;
-
- for (i = scm->fp->count-1; i >= 0; i--)
- unix_notinflight(scm->fp->user, scm->fp->fp[i]);
-}
-
-static void unix_destruct_scm(struct sk_buff *skb)
-{
- struct scm_cookie scm;
- memset(&scm, 0, sizeof(scm));
- scm.pid = UNIXCB(skb).pid;
- if (UNIXCB(skb).fp)
- unix_detach_fds(&scm, skb);
-
- /* Alas, it calls VFS */
- /* So fscking what? fput() had been SMP-safe since the last Summer */
- scm_destroy(&scm);
- sock_wfree(skb);
-}
-
-/*
- * The "user->unix_inflight" variable is protected by the garbage
- * collection lock, and we just read it locklessly here. If you go
- * over the limit, there might be a tiny race in actually noticing
- * it across threads. Tough.
- */
-static inline bool too_many_unix_fds(struct task_struct *p)
-{
- struct user_struct *user = current_user();
-
- if (unlikely(user->unix_inflight > task_rlimit(p, RLIMIT_NOFILE)))
- return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN);
- return false;
-}
-
-#define MAX_RECURSION_LEVEL 4
-
-static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
-{
- int i;
- unsigned char max_level = 0;
-
- if (too_many_unix_fds(current))
- return -ETOOMANYREFS;
-
- for (i = scm->fp->count - 1; i >= 0; i--) {
- struct sock *sk = unix_get_socket(scm->fp->fp[i]);
-
- if (sk)
- max_level = max(max_level,
- unix_sk(sk)->recursion_level);
- }
- if (unlikely(max_level > MAX_RECURSION_LEVEL))
- return -ETOOMANYREFS;
+ scm->fp = scm_fp_dup(UNIXCB(skb).fp);
/*
- * Need to duplicate file references for the sake of garbage
- * collection. Otherwise a socket in the fps might become a
- * candidate for GC while the skb is not yet queued.
+ * Garbage collection of unix sockets starts by selecting a set of
+ * candidate sockets which have reference only from being in flight
+ * (total_refs == inflight_refs). This condition is checked once during
+ * the candidate collection phase, and candidates are marked as such, so
+ * that non-candidates can later be ignored. While inflight_refs is
+ * protected by unix_gc_lock, total_refs (file count) is not, hence this
+ * is an instantaneous decision.
+ *
+ * Once a candidate, however, the socket must not be reinstalled into a
+ * file descriptor while the garbage collection is in progress.
+ *
+ * If the above conditions are met, then the directed graph of
+ * candidates (*) does not change while unix_gc_lock is held.
+ *
+ * Any operations that changes the file count through file descriptors
+ * (dup, close, sendmsg) does not change the graph since candidates are
+ * not installed in fds.
+ *
+ * Dequeing a candidate via recvmsg would install it into an fd, but
+ * that takes unix_gc_lock to decrement the inflight count, so it's
+ * serialized with garbage collection.
+ *
+ * MSG_PEEK is special in that it does not change the inflight count,
+ * yet does install the socket into an fd. The following lock/unlock
+ * pair is to ensure serialization with garbage collection. It must be
+ * done between incrementing the file count and installing the file into
+ * an fd.
+ *
+ * If garbage collection starts after the barrier provided by the
+ * lock/unlock, then it will see the elevated refcount and not mark this
+ * as a candidate. If a garbage collection is already in progress
+ * before the file count was incremented, then the lock/unlock pair will
+ * ensure that garbage collection is finished before progressing to
+ * installing the fd.
+ *
+ * (*) A -> B where B is on the queue of A or B is on the queue of C
+ * which is on the queue of listening socket A.
*/
- UNIXCB(skb).fp = scm_fp_dup(scm->fp);
- if (!UNIXCB(skb).fp)
- return -ENOMEM;
-
- for (i = scm->fp->count - 1; i >= 0; i--)
- unix_inflight(scm->fp->user, scm->fp->fp[i]);
- return max_level;
+ spin_lock(&unix_gc_lock);
+ spin_unlock(&unix_gc_lock);
}
static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds)
@@ -1793,7 +1775,8 @@
* - unix_peer(sk) == sk by time of get but disconnected before lock
*/
if (other != sk &&
- unlikely(unix_peer(other) != sk && unix_recvq_full(other))) {
+ unlikely(unix_peer(other) != sk &&
+ unix_recvq_full_lockless(other))) {
if (timeo) {
timeo = unix_wait_for_peer(other, timeo);
@@ -2204,7 +2187,7 @@
sk_peek_offset_fwd(sk, size);
if (UNIXCB(skb).fp)
- scm.fp = scm_fp_dup(UNIXCB(skb).fp);
+ unix_peek_fds(&scm, skb);
}
err = (flags & MSG_TRUNC) ? skb->len - skip : size;
@@ -2449,7 +2432,7 @@
/* It is questionable, see note in unix_dgram_recvmsg.
*/
if (UNIXCB(skb).fp)
- scm.fp = scm_fp_dup(UNIXCB(skb).fp);
+ unix_peek_fds(&scm, skb);
sk_peek_offset_fwd(sk, chunk);
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
index c36757e..8bbe1b8 100644
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -86,77 +86,13 @@
#include <net/scm.h>
#include <net/tcp_states.h>
+#include "scm.h"
+
/* Internal data structures and random procedures: */
-static LIST_HEAD(gc_inflight_list);
static LIST_HEAD(gc_candidates);
-static DEFINE_SPINLOCK(unix_gc_lock);
static DECLARE_WAIT_QUEUE_HEAD(unix_gc_wait);
-unsigned int unix_tot_inflight;
-
-struct sock *unix_get_socket(struct file *filp)
-{
- struct sock *u_sock = NULL;
- struct inode *inode = file_inode(filp);
-
- /* Socket ? */
- if (S_ISSOCK(inode->i_mode) && !(filp->f_mode & FMODE_PATH)) {
- struct socket *sock = SOCKET_I(inode);
- struct sock *s = sock->sk;
-
- /* PF_UNIX ? */
- if (s && sock->ops && sock->ops->family == PF_UNIX)
- u_sock = s;
- }
- return u_sock;
-}
-
-/* Keep the number of times in flight count for the file
- * descriptor if it is for an AF_UNIX socket.
- */
-
-void unix_inflight(struct user_struct *user, struct file *fp)
-{
- struct sock *s = unix_get_socket(fp);
-
- spin_lock(&unix_gc_lock);
-
- if (s) {
- struct unix_sock *u = unix_sk(s);
-
- if (atomic_long_inc_return(&u->inflight) == 1) {
- BUG_ON(!list_empty(&u->link));
- list_add_tail(&u->link, &gc_inflight_list);
- } else {
- BUG_ON(list_empty(&u->link));
- }
- unix_tot_inflight++;
- }
- user->unix_inflight++;
- spin_unlock(&unix_gc_lock);
-}
-
-void unix_notinflight(struct user_struct *user, struct file *fp)
-{
- struct sock *s = unix_get_socket(fp);
-
- spin_lock(&unix_gc_lock);
-
- if (s) {
- struct unix_sock *u = unix_sk(s);
-
- BUG_ON(!atomic_long_read(&u->inflight));
- BUG_ON(list_empty(&u->link));
-
- if (atomic_long_dec_and_test(&u->inflight))
- list_del_init(&u->link);
- unix_tot_inflight--;
- }
- user->unix_inflight--;
- spin_unlock(&unix_gc_lock);
-}
-
static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *),
struct sk_buff_head *hitlist)
{
diff --git a/net/unix/scm.c b/net/unix/scm.c
new file mode 100644
index 0000000..df8f636
--- /dev/null
+++ b/net/unix/scm.c
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/socket.h>
+#include <linux/net.h>
+#include <linux/fs.h>
+#include <net/af_unix.h>
+#include <net/scm.h>
+#include <linux/init.h>
+
+#include "scm.h"
+
+unsigned int unix_tot_inflight;
+EXPORT_SYMBOL(unix_tot_inflight);
+
+LIST_HEAD(gc_inflight_list);
+EXPORT_SYMBOL(gc_inflight_list);
+
+DEFINE_SPINLOCK(unix_gc_lock);
+EXPORT_SYMBOL(unix_gc_lock);
+
+struct sock *unix_get_socket(struct file *filp)
+{
+ struct sock *u_sock = NULL;
+ struct inode *inode = file_inode(filp);
+
+ /* Socket ? */
+ if (S_ISSOCK(inode->i_mode) && !(filp->f_mode & FMODE_PATH)) {
+ struct socket *sock = SOCKET_I(inode);
+ struct sock *s = sock->sk;
+
+ /* PF_UNIX ? */
+ if (s && sock->ops && sock->ops->family == PF_UNIX)
+ u_sock = s;
+ }
+ return u_sock;
+}
+EXPORT_SYMBOL(unix_get_socket);
+
+/* Keep the number of times in flight count for the file
+ * descriptor if it is for an AF_UNIX socket.
+ */
+void unix_inflight(struct user_struct *user, struct file *fp)
+{
+ struct sock *s = unix_get_socket(fp);
+
+ spin_lock(&unix_gc_lock);
+
+ if (s) {
+ struct unix_sock *u = unix_sk(s);
+
+ if (atomic_long_inc_return(&u->inflight) == 1) {
+ BUG_ON(!list_empty(&u->link));
+ list_add_tail(&u->link, &gc_inflight_list);
+ } else {
+ BUG_ON(list_empty(&u->link));
+ }
+ unix_tot_inflight++;
+ }
+ user->unix_inflight++;
+ spin_unlock(&unix_gc_lock);
+}
+
+void unix_notinflight(struct user_struct *user, struct file *fp)
+{
+ struct sock *s = unix_get_socket(fp);
+
+ spin_lock(&unix_gc_lock);
+
+ if (s) {
+ struct unix_sock *u = unix_sk(s);
+
+ BUG_ON(!atomic_long_read(&u->inflight));
+ BUG_ON(list_empty(&u->link));
+
+ if (atomic_long_dec_and_test(&u->inflight))
+ list_del_init(&u->link);
+ unix_tot_inflight--;
+ }
+ user->unix_inflight--;
+ spin_unlock(&unix_gc_lock);
+}
+
+/*
+ * The "user->unix_inflight" variable is protected by the garbage
+ * collection lock, and we just read it locklessly here. If you go
+ * over the limit, there might be a tiny race in actually noticing
+ * it across threads. Tough.
+ */
+static inline bool too_many_unix_fds(struct task_struct *p)
+{
+ struct user_struct *user = current_user();
+
+ if (unlikely(user->unix_inflight > task_rlimit(p, RLIMIT_NOFILE)))
+ return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN);
+ return false;
+}
+
+#define MAX_RECURSION_LEVEL 4
+
+int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
+{
+ int i;
+ unsigned char max_level = 0;
+
+ if (too_many_unix_fds(current))
+ return -ETOOMANYREFS;
+
+ for (i = scm->fp->count - 1; i >= 0; i--) {
+ struct sock *sk = unix_get_socket(scm->fp->fp[i]);
+
+ if (sk)
+ max_level = max(max_level,
+ unix_sk(sk)->recursion_level);
+ }
+ if (unlikely(max_level > MAX_RECURSION_LEVEL))
+ return -ETOOMANYREFS;
+
+ /*
+ * Need to duplicate file references for the sake of garbage
+ * collection. Otherwise a socket in the fps might become a
+ * candidate for GC while the skb is not yet queued.
+ */
+ UNIXCB(skb).fp = scm_fp_dup(scm->fp);
+ if (!UNIXCB(skb).fp)
+ return -ENOMEM;
+
+ for (i = scm->fp->count - 1; i >= 0; i--)
+ unix_inflight(scm->fp->user, scm->fp->fp[i]);
+ return max_level;
+}
+EXPORT_SYMBOL(unix_attach_fds);
+
+void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb)
+{
+ int i;
+
+ scm->fp = UNIXCB(skb).fp;
+ UNIXCB(skb).fp = NULL;
+
+ for (i = scm->fp->count-1; i >= 0; i--)
+ unix_notinflight(scm->fp->user, scm->fp->fp[i]);
+}
+EXPORT_SYMBOL(unix_detach_fds);
+
+void unix_destruct_scm(struct sk_buff *skb)
+{
+ struct scm_cookie scm;
+
+ memset(&scm, 0, sizeof(scm));
+ scm.pid = UNIXCB(skb).pid;
+ if (UNIXCB(skb).fp)
+ unix_detach_fds(&scm, skb);
+
+ /* Alas, it calls VFS */
+ /* So fscking what? fput() had been SMP-safe since the last Summer */
+ scm_destroy(&scm);
+ sock_wfree(skb);
+}
+EXPORT_SYMBOL(unix_destruct_scm);
diff --git a/net/unix/scm.h b/net/unix/scm.h
new file mode 100644
index 0000000..5a255a4
--- /dev/null
+++ b/net/unix/scm.h
@@ -0,0 +1,10 @@
+#ifndef NET_UNIX_SCM_H
+#define NET_UNIX_SCM_H
+
+extern struct list_head gc_inflight_list;
+extern spinlock_t unix_gc_lock;
+
+int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb);
+void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb);
+
+#endif
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
old mode 100644
new mode 100755
index b4c914c..49bfc81
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -1097,6 +1097,14 @@
help
Enables support for aw8896 series Smart PA.
+config SND_SMARTPA_AW8898
+ tristate "SoC Audio for awinic aw8898 series"
+ depends on I2C
+ help
+ This option enables support for aw8898 series Smart PA.
+
+source "sound/soc/codecs/tas2557/Kconfig"
+
config SND_SOC_TFA98XX
tristate "NXP Semiconductors TFA98XX amplifier"
depends on I2C
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
old mode 100644
new mode 100755
index cf30a19..5c4088f
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -447,3 +447,6 @@
obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
obj-$(CONFIG_SND_SOC_AW8896) += snd-soc-aw8896.o
obj-$(CONFIG_SND_SOC_TFA98XX) += snd-soc-tfa98xx.o
+#for AWINIC AW8898 Smart PA
+obj-y += aw/aw8898.o
+obj-$(CONFIG_SND_SOC_TAS2557) += tas2557/
diff --git a/sound/soc/codecs/aw/aw8898.c b/sound/soc/codecs/aw/aw8898.c
new file mode 100755
index 0000000..dc565ed
--- /dev/null
+++ b/sound/soc/codecs/aw/aw8898.c
@@ -0,0 +1,1612 @@
+/*
+ * aw8898.c aw8898 codec module
+ *
+ * Version: v1.1.3
+ *
+ * Copyright (c) 2018 AWINIC Technology CO., LTD
+ *
+ * Author: Nick Li <liweilei@awinic.com.cn>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the 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/i2c.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <linux/of_gpio.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
+#include <linux/i2c.h>
+#include <linux/debugfs.h>
+#include <linux/version.h>
+#include <linux/input.h>
+#include <linux/timer.h>
+#include <linux/workqueue.h>
+#include <linux/hrtimer.h>
+#include <linux/syscalls.h>
+#include <sound/tlv.h>
+#include "aw8898.h"
+#include "aw8898_reg.h"
+
+/******************************************************
+ *
+ * Marco
+ *
+ ******************************************************/
+#define AW8898_I2C_NAME "aw8898_smartpa"
+
+
+#define AW8898_VERSION "v1.1.3"
+
+#define AW8898_RATES SNDRV_PCM_RATE_8000_48000
+#define AW8898_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S24_LE | \
+ SNDRV_PCM_FMTBIT_S32_LE)
+
+//#define AWINIC_I2C_REGMAP
+
+#define AW_I2C_RETRIES 5
+#define AW_I2C_RETRY_DELAY 5 // 5ms
+#define AW_READ_CHIPID_RETRIES 5
+#define AW_READ_CHIPID_RETRY_DELAY 5
+
+static int aw8898_spk_control = 0;
+static int aw8898_rcv_control = 0;
+
+#define AW8898_MAX_FIRMWARE_LOAD_CNT 20
+static char *aw8898_cfg_name = "aw8898_cfg.bin";
+
+#ifdef AW8898_VBAT_MONITOR
+static int aw8898_vbat_monitor_start(struct aw8898 *aw8898);
+static int aw8898_vbat_monitor_stop(struct aw8898 *aw8898);
+#endif
+ /******************************************************
+ *
+ * aw8898 i2c write/read
+ *
+ ******************************************************/
+#ifndef AWINIC_I2C_REGMAP
+static int i2c_write(struct aw8898 *aw8898,
+ unsigned char addr, unsigned int reg_data)
+{
+ int ret = -1;
+ u8 wbuf[512] = {0};
+
+ struct i2c_msg msgs[] = {
+ {
+ .addr = aw8898->i2c->addr,
+ .flags = 0,
+ .len = 3,
+ .buf = wbuf,
+ },
+ };
+
+ wbuf[0] = addr;
+ wbuf[1] = (unsigned char)((reg_data & 0xff00)>>8);
+ wbuf[2] = (unsigned char)(reg_data & 0x00ff);
+
+ ret = i2c_transfer(aw8898->i2c->adapter, msgs, 1);
+ if (ret < 0) {
+ pr_err("%s: i2c write error: %d\n", __func__, ret);
+ }
+
+ return ret;
+}
+
+static int i2c_read(struct aw8898 *aw8898,
+ unsigned char addr, unsigned int *reg_data)
+{
+ int ret = -1;
+ unsigned char rbuf[512] = {0};
+ unsigned int get_data = 0;
+
+ struct i2c_msg msgs[] = {
+ {
+ .addr = aw8898->i2c->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = &addr,
+ },
+ {
+ .addr = aw8898->i2c->addr,
+ .flags = I2C_M_RD,
+ .len = 2,
+ .buf = rbuf,
+ },
+ };
+
+ ret = i2c_transfer(aw8898->i2c->adapter, msgs, 2);
+ if (ret < 0) {
+ pr_err("%s: i2c read error: %d\n", __func__, ret);
+ return ret;
+ }
+
+ get_data = (unsigned int)(rbuf[0] & 0x00ff);
+ get_data <<= 8;
+ get_data |= (unsigned int)rbuf[1];
+
+ *reg_data = get_data;
+
+ return ret;
+}
+#endif
+
+static int aw8898_i2c_write(struct aw8898 *aw8898,
+ unsigned char reg_addr, unsigned int reg_data)
+{
+ int ret = -1;
+ unsigned char cnt = 0;
+
+ while(cnt < AW_I2C_RETRIES) {
+#ifdef AWINIC_I2C_REGMAP
+ ret = regmap_write(aw8898->regmap, reg_addr, reg_data);
+ if(ret < 0) {
+ pr_err("%s: regmap_write cnt=%d error=%d\n", __func__, cnt, ret);
+ } else {
+ break;
+ }
+#else
+ ret = i2c_write(aw8898, reg_addr, reg_data);
+ if(ret < 0) {
+ pr_err("%s: i2c_write cnt=%d error=%d\n", __func__, cnt, ret);
+ } else {
+ break;
+ }
+#endif
+ cnt ++;
+ }
+
+ return ret;
+}
+
+static int aw8898_i2c_read(struct aw8898 *aw8898,
+ unsigned char reg_addr, unsigned int *reg_data)
+{
+ int ret = -1;
+ unsigned char cnt = 0;
+
+ while(cnt < AW_I2C_RETRIES) {
+#ifdef AWINIC_I2C_REGMAP
+ ret = regmap_read(aw8898->regmap, reg_addr, reg_data);
+ if(ret < 0) {
+ pr_err("%s: regmap_read cnt=%d error=%d\n", __func__, cnt, ret);
+ } else {
+ break;
+ }
+#else
+ ret = i2c_read(aw8898, reg_addr, reg_data);
+ if(ret < 0) {
+ pr_err("%s: i2c_read cnt=%d error=%d\n", __func__, cnt, ret);
+ } else {
+ break;
+ }
+#endif
+ cnt ++;
+ }
+
+ return ret;
+}
+
+static int aw8898_i2c_write_bits(struct aw8898 *aw8898,
+ unsigned char reg_addr, unsigned int mask, unsigned int reg_data)
+{
+ unsigned int reg_val;
+
+ aw8898_i2c_read(aw8898, reg_addr, ®_val);
+ reg_val &= mask;
+ reg_val |= reg_data;
+ aw8898_i2c_write(aw8898, reg_addr, reg_val);
+
+ return 0;
+}
+
+/******************************************************
+ *
+ * aw8898 control
+ *
+ ******************************************************/
+static void aw8898_run_mute(struct aw8898 *aw8898, bool mute)
+{
+ pr_debug("%s enter\n", __func__);
+
+ if(mute) {
+ aw8898_i2c_write_bits(aw8898, AW8898_REG_PWMCTRL,
+ AW8898_BIT_PWMCTRL_HMUTE_MASK, AW8898_BIT_PWMCTRL_HMUTE_ENABLE);
+ } else {
+ aw8898_i2c_write_bits(aw8898, AW8898_REG_PWMCTRL,
+ AW8898_BIT_PWMCTRL_HMUTE_MASK, AW8898_BIT_PWMCTRL_HMUTE_DISABLE);
+ }
+}
+
+static void aw8898_run_pwd(struct aw8898 *aw8898, bool pwd)
+{
+ pr_debug("%s enter\n", __func__);
+
+ if(pwd) {
+ aw8898_i2c_write_bits(aw8898, AW8898_REG_SYSCTRL,
+ AW8898_BIT_SYSCTRL_PW_MASK, AW8898_BIT_SYSCTRL_PW_PDN);
+ } else {
+ aw8898_i2c_write_bits(aw8898, AW8898_REG_SYSCTRL,
+ AW8898_BIT_SYSCTRL_PW_MASK, AW8898_BIT_SYSCTRL_PW_ACTIVE);
+ }
+}
+
+static void aw8898_spk_rcv_mode(struct aw8898 *aw8898)
+{
+ pr_debug("%s spk_rcv=%d\n", __func__, aw8898->spk_rcv_mode);
+
+ if(aw8898->spk_rcv_mode == AW8898_SPEAKER_MODE) {
+ aw8898_i2c_write_bits(aw8898, AW8898_REG_SYSCTRL,
+ AW8898_BIT_SYSCTRL_MODE_MASK, AW8898_BIT_SYSCTRL_SPK_MODE);
+ } else if(aw8898->spk_rcv_mode == AW8898_RECEIVER_MODE){
+ aw8898_i2c_write_bits(aw8898, AW8898_REG_SYSCTRL,
+ AW8898_BIT_SYSCTRL_MODE_MASK, AW8898_BIT_SYSCTRL_RCV_MODE);
+ } else {
+ }
+}
+
+
+static void aw8898_start(struct aw8898 *aw8898)
+{
+ unsigned int reg_val = 0;
+ unsigned int iis_check_max = 5;
+ unsigned int i = 0;
+
+ pr_debug("%s enter\n", __func__);
+
+ aw8898_run_pwd(aw8898, false);
+ msleep(2);
+ for(i=0; i<iis_check_max; i++) {
+ aw8898_i2c_read(aw8898, AW8898_REG_SYSST, ®_val);
+ if(reg_val & AW8898_BIT_SYSST_PLLS) {
+ aw8898_run_mute(aw8898, false);
+ pr_debug("%s iis signal check pass!\n", __func__);
+#ifdef AW8898_VBAT_MONITOR
+ aw8898_vbat_monitor_start(aw8898);
+#endif
+ return;
+ }
+ msleep(2);
+ }
+ aw8898_run_pwd(aw8898, true);
+ pr_err("%s: iis signal check error\n", __func__);
+}
+static void aw8898_stop(struct aw8898 *aw8898)
+{
+ pr_debug("%s enter\n", __func__);
+
+ aw8898_run_mute(aw8898, true);
+ aw8898_run_pwd(aw8898, true);
+#ifdef AW8898_VBAT_MONITOR
+ aw8898_vbat_monitor_stop(aw8898);
+#endif
+}
+
+static void aw8898_container_update(struct aw8898 *aw8898,
+ struct aw8898_container *aw8898_cont)
+{
+ int i = 0;
+ int reg_addr = 0;
+ int reg_val = 0;
+
+ pr_debug("%s enter\n", __func__);
+
+ for(i=0; i<aw8898_cont->len; i+=4) {
+ reg_addr = (aw8898_cont->data[i+1]<<8) + aw8898_cont->data[i+0];
+ reg_val = (aw8898_cont->data[i+3]<<8) + aw8898_cont->data[i+2];
+ pr_info("%s: reg=0x%04x, val = 0x%04x\n", __func__, reg_addr, reg_val);
+ aw8898_i2c_write(aw8898, (unsigned char)reg_addr, (unsigned int)reg_val);
+ }
+
+ pr_debug("%s exit\n", __func__);
+}
+
+static void aw8898_cfg_loaded(const struct firmware *cont, void *context)
+{
+ struct aw8898 *aw8898 = context;
+ struct aw8898_container *aw8898_cfg;
+ unsigned int i = 0;
+
+ if (!cont) {
+ pr_err("%s: failed to read %s\n", __func__, aw8898_cfg_name);
+ release_firmware(cont);
+ return;
+ }
+
+ pr_info("%s: loaded %s - size: %zu\n", __func__, aw8898_cfg_name,
+ cont ? cont->size : 0);
+
+ for(i=0; i<cont->size; i++) {
+ pr_info("%s: addr:0x%04x, data:0x%02x\n", __func__, i, *(cont->data+i));
+ }
+
+ aw8898_cfg = kzalloc(cont->size+sizeof(int), GFP_KERNEL);
+ if (!aw8898_cfg) {
+ release_firmware(cont);
+ pr_err("%s: error allocating memory\n", __func__);
+ return;
+ }
+ aw8898_cfg->len = cont->size;
+ memcpy(aw8898_cfg->data, cont->data, cont->size);
+ release_firmware(cont);
+
+ aw8898_container_update(aw8898, aw8898_cfg);
+
+ kfree(aw8898_cfg);
+
+ aw8898->init = 1;
+ pr_info("%s: cfg update complete\n", __func__);
+
+ aw8898_spk_rcv_mode(aw8898);
+ aw8898_start(aw8898);
+}
+
+static int aw8898_load_cfg(struct aw8898 *aw8898)
+{
+ pr_info("%s enter\n", __func__);
+
+ return request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
+ aw8898_cfg_name, aw8898->dev, GFP_KERNEL,
+ aw8898, aw8898_cfg_loaded);
+}
+
+static void aw8898_cold_start(struct aw8898 *aw8898)
+{
+ int ret = -1;
+
+ pr_info("%s enter\n", __func__);
+
+ ret = aw8898_load_cfg(aw8898);
+ if(ret) {
+ pr_err("%s: cfg loading requested failed: %d\n", __func__, ret);
+ }
+}
+
+static void aw8898_smartpa_cfg(struct aw8898 *aw8898, bool flag)
+{
+ pr_info("%s, flag = %d\n", __func__, flag);
+
+ if(flag == true) {
+ if(aw8898->init == 0) {
+ pr_info("%s, init = %d\n", __func__, aw8898->init);
+ aw8898_cold_start(aw8898);
+ } else {
+ aw8898_spk_rcv_mode(aw8898);
+ aw8898_start(aw8898);
+ }
+ } else {
+ aw8898_stop(aw8898);
+ }
+}
+
+/******************************************************
+ *
+ * kcontrol
+ *
+ ******************************************************/
+ static const char *const spk_function[] = { "Off", "On" };
+ static const char *const rcv_function[] = { "Off", "On" };
+ static const DECLARE_TLV_DB_SCALE(digital_gain,0,50,0);
+
+ struct soc_mixer_control aw8898_mixer ={
+ .reg = AW8898_REG_HAGCCFG7,
+ .shift = AW8898_VOL_REG_SHIFT,
+ .max = AW8898_VOLUME_MAX,
+ .min = AW8898_VOLUME_MIN,
+ };
+
+static int aw8898_volume_info(struct snd_kcontrol *kcontrol,struct snd_ctl_elem_info *uinfo)
+{
+ struct soc_mixer_control *mc = (struct soc_mixer_control*) kcontrol->private_value;
+
+ //set kcontrol info
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = mc->max - mc->min;
+ return 0;
+}
+
+static int aw8898_volume_get(struct snd_kcontrol *kcontrol,struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct aw8898 *aw8898 = snd_soc_codec_get_drvdata(codec);
+ unsigned int reg_val = 0;
+ unsigned int value = 0;
+ struct soc_mixer_control *mc = (struct soc_mixer_control*) kcontrol->private_value;
+
+ aw8898_i2c_read(aw8898, AW8898_REG_HAGCCFG7, ®_val);
+ ucontrol->value.integer.value[0] = (value >> mc->shift)\
+ &(AW8898_BIT_HAGCCFG7_VOL_MASK);
+ return 0;
+}
+
+static int aw8898_volume_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_soc_kcontrol_codec(kcontrol);
+ struct aw8898 *aw8898 = snd_soc_codec_get_drvdata(codec);
+ unsigned int value = 0;
+ unsigned int reg_value = 0;
+
+ //value is right
+ value = ucontrol->value.integer.value[0];
+ if(value > (mc->max-mc->min)|| value <0){
+ pr_err("%s:value over range \n",__func__);
+ return -1;
+ }
+
+ //smartpa have clk
+ aw8898_i2c_read(aw8898, AW8898_REG_SYSST, ®_value);
+ if(!(reg_value&AW8898_BIT_SYSST_PLLS)){
+ pr_err("%s: NO I2S CLK ,cat not write reg \n",__func__);
+ return 0;
+ }
+ //cal real value
+ value = value << mc->shift&AW8898_BIT_HAGCCFG7_VOL_MASK;
+ aw8898_i2c_read(aw8898, AW8898_REG_HAGCCFG7, ®_value);
+ value = value | (reg_value&0x00ff);
+
+ //write value
+ aw8898_i2c_write(aw8898, AW8898_REG_HAGCCFG7, value);
+
+ return 0;
+}
+
+static struct snd_kcontrol_new aw8898_volume = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "aw8898_rx_volume",
+ .access= SNDRV_CTL_ELEM_ACCESS_TLV_READ|SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .tlv.p = (digital_gain),
+ .info = aw8898_volume_info,
+ .get = aw8898_volume_get,
+ .put = aw8898_volume_put,
+ .private_value = (unsigned long)&aw8898_mixer,
+};
+
+static int aw8898_spk_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: aw8898_spk_control=%d\n", __func__, aw8898_spk_control);
+ ucontrol->value.integer.value[0] = aw8898_spk_control;
+ return 0;
+}
+
+static int aw8898_spk_set(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct aw8898 *aw8898 = snd_soc_codec_get_drvdata(codec);
+
+ pr_debug("%s: ucontrol->value.integer.value[0]=%ld\n ",
+ __func__, ucontrol->value.integer.value[0]);
+ if(ucontrol->value.integer.value[0] == aw8898_spk_control)
+ return 1;
+
+ aw8898_spk_control = ucontrol->value.integer.value[0];
+
+ aw8898->spk_rcv_mode = AW8898_SPEAKER_MODE;
+
+ aw8898_spk_rcv_mode(aw8898);
+
+ return 0;
+}
+
+static int aw8898_rcv_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: aw8898_rcv_control=%d\n", __func__, aw8898_rcv_control);
+ ucontrol->value.integer.value[0] = aw8898_rcv_control;
+ return 0;
+}
+static int aw8898_rcv_set(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct aw8898 *aw8898 = snd_soc_codec_get_drvdata(codec);
+ pr_debug("%s: ucontrol->value.integer.value[0]=%ld\n ",
+ __func__, ucontrol->value.integer.value[0]);
+ if(ucontrol->value.integer.value[0] == aw8898_rcv_control)
+ return 1;
+
+ aw8898_rcv_control = ucontrol->value.integer.value[0];
+
+ aw8898->spk_rcv_mode = AW8898_RECEIVER_MODE;
+
+ aw8898_spk_rcv_mode(aw8898);
+
+ return 0;
+}
+static const struct soc_enum aw8898_snd_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function),
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rcv_function), rcv_function),
+};
+
+static struct snd_kcontrol_new aw8898_controls[] = {
+ SOC_ENUM_EXT("aw8898_speaker_switch", aw8898_snd_enum[0],
+ aw8898_spk_get, aw8898_spk_set),
+ SOC_ENUM_EXT("aw8898_receiver_switch", aw8898_snd_enum[1],
+ aw8898_rcv_get, aw8898_rcv_set),
+};
+
+static void aw8898_add_codec_controls(struct aw8898 *aw8898)
+{
+ pr_info("%s enter\n", __func__);
+
+ snd_soc_add_codec_controls(aw8898->codec, aw8898_controls,
+ ARRAY_SIZE(aw8898_controls));
+
+ snd_soc_add_codec_controls(aw8898->codec, &aw8898_volume,1);
+}
+
+/******************************************************
+ *
+ * DAPM Widget & Route
+ *
+ ******************************************************/
+#if 0
+static struct snd_soc_dapm_widget aw8898_dapm_widgets_common[] = {
+ /* Stream widgets */
+ SND_SOC_DAPM_AIF_IN("AIF_IN", "AW89xx_AIF_Playback", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("AIF_OUT", "AW89xx_AIF_Capture", 0, SND_SOC_NOPM, 0, 0),
+
+ SND_SOC_DAPM_OUTPUT("OUTL"),
+ SND_SOC_DAPM_INPUT("AEC_Loopback"),
+};
+
+static const struct snd_soc_dapm_route aw8898_dapm_routes_common[] = {
+ { "OUTL", NULL, "AIF_IN" },
+ { "AIF_OUT", NULL, "AEC_Loopback" },
+};
+
+static void aw8898_add_widgets(struct aw8898 *aw8898)
+{
+ //struct snd_soc_dapm_context *dapm = &aw8898->codec->dapm;
+ struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(aw8898->codec);
+ struct snd_soc_dapm_widget *widgets;
+
+ pr_info("%s enter\n", __func__);
+ widgets = devm_kzalloc(&aw8898->i2c->dev,
+ sizeof(struct snd_soc_dapm_widget) *
+ ARRAY_SIZE(aw8898_dapm_widgets_common),
+ GFP_KERNEL);
+ if (!widgets)
+ return;
+
+ memcpy(widgets, aw8898_dapm_widgets_common,
+ sizeof(struct snd_soc_dapm_widget) *
+ ARRAY_SIZE(aw8898_dapm_widgets_common));
+
+ snd_soc_dapm_new_controls(dapm, widgets,
+ ARRAY_SIZE(aw8898_dapm_widgets_common));
+ snd_soc_dapm_add_routes(dapm, aw8898_dapm_routes_common,
+ ARRAY_SIZE(aw8898_dapm_routes_common));
+}
+#endif
+/******************************************************
+ *
+ * Digital Audio Interface
+ *
+ ******************************************************/
+static int aw8898_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct aw8898 *aw8898 = snd_soc_codec_get_drvdata(codec);
+
+ pr_info("%s: enter\n", __func__);
+ aw8898_run_pwd(aw8898, false);
+
+ return 0;
+}
+
+static int aw8898_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ //struct aw8898 *aw8898 = snd_soc_codec_get_drvdata(dai->codec);
+ struct snd_soc_codec *codec = dai->codec;
+
+ pr_info("%s: fmt=0x%x\n", __func__, fmt);
+
+ /* Supported mode: regular I2S, slave, or PDM */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
+ dev_err(codec->dev, "%s: invalid codec master mode\n", __func__);
+ return -EINVAL;
+ }
+ break;
+ default:
+ dev_err(codec->dev, "%s: unsupported DAI format %d\n", __func__,
+ fmt & SND_SOC_DAIFMT_FORMAT_MASK);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int aw8898_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct aw8898 *aw8898 = snd_soc_codec_get_drvdata(codec_dai->codec);
+
+ pr_info("%s: freq=%d\n", __func__, freq);
+
+ aw8898->sysclk = freq;
+ return 0;
+}
+
+static int aw8898_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 aw8898 *aw8898 = snd_soc_codec_get_drvdata(codec);
+ unsigned int rate = 0;
+ int reg_value = 0;
+ int width = 0;
+ /* Supported */
+
+ //get rate param
+ aw8898->rate=rate = params_rate(params);
+ pr_debug("%s: requested rate: %d, sample size: %d\n", __func__, rate,
+ snd_pcm_format_width(params_format(params)));
+ //match rate
+ switch(rate)
+ {
+ case 8000:
+ reg_value = AW8898_BIT_I2SCTRL_SR_8K;
+ break;
+ case 16000:
+ reg_value = AW8898_BIT_I2SCTRL_SR_16K;
+ break;
+ case 32000:
+ reg_value = AW8898_BIT_I2SCTRL_SR_32K;
+ break;
+ case 44100:
+ reg_value = AW8898_BIT_I2SCTRL_SR_44P1K;
+ break;
+ case 48000:
+ reg_value = AW8898_BIT_I2SCTRL_SR_48K;
+ break;
+ default:
+ reg_value = AW8898_BIT_I2SCTRL_SR_48K;
+ pr_err("%s: rate can not support\n", __func__);
+ break;
+ }
+ //set chip rate
+ if(-1 != reg_value){
+ aw8898_i2c_write_bits(aw8898, AW8898_REG_I2SCTRL,
+ AW8898_BIT_I2SCTRL_SR_MASK, reg_value);
+ }
+
+ //get bit width
+ width = params_width(params);
+ pr_debug("%s: width = %d \n",__func__,width);
+ switch(width)
+ {
+ case 16:
+ reg_value = AW8898_BIT_I2SCTRL_FMS_16BIT;
+ break;
+ case 20:
+ reg_value = AW8898_BIT_I2SCTRL_FMS_20BIT;
+ break;
+ case 24:
+ reg_value = AW8898_BIT_I2SCTRL_FMS_24BIT;
+ break;
+ case 32:
+ reg_value = AW8898_BIT_I2SCTRL_FMS_32BIT;
+ break;
+ default:
+ reg_value = AW8898_BIT_I2SCTRL_FMS_16BIT;
+ pr_err("%s: width can not support\n", __func__);
+ break;
+ }
+ //set width
+ if(-1 != reg_value){
+ aw8898_i2c_write_bits(aw8898, AW8898_REG_I2SCTRL,
+ AW8898_BIT_I2SCTRL_FMS_MASK, reg_value);
+ }
+
+ return 0;
+}
+
+static int aw8898_mute(struct snd_soc_dai *dai, int mute, int stream)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct aw8898 *aw8898 = snd_soc_codec_get_drvdata(codec);
+
+ pr_info("%s: mute state=%d\n", __func__, mute);
+
+ if (!(aw8898->flags & AW8898_FLAG_START_ON_MUTE))
+ return 0;
+
+ if (mute) {
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+ aw8898->pstream = 0;
+ else
+ aw8898->cstream = 0;
+ if (aw8898->pstream != 0 || aw8898->cstream != 0)
+ return 0;
+
+ mutex_lock(&aw8898->cfg_lock);
+ aw8898_smartpa_cfg(aw8898, false);
+ mutex_unlock(&aw8898->cfg_lock);
+ } else {
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+ aw8898->pstream = 1;
+ else
+ aw8898->cstream = 1;
+
+ mutex_lock(&aw8898->cfg_lock);
+ aw8898_smartpa_cfg(aw8898, true);
+ mutex_unlock(&aw8898->cfg_lock);
+ }
+
+ return 0;
+}
+
+static void aw8898_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct aw8898 *aw8898 = snd_soc_codec_get_drvdata(codec);
+
+ aw8898->rate = 0;
+ aw8898_run_pwd(aw8898, true);
+}
+
+static const struct snd_soc_dai_ops aw8898_dai_ops = {
+ .startup = aw8898_startup,
+ .set_fmt = aw8898_set_fmt,
+ .set_sysclk = aw8898_set_dai_sysclk,
+ .hw_params = aw8898_hw_params,
+ .mute_stream = aw8898_mute,
+ .shutdown = aw8898_shutdown,
+};
+
+static struct snd_soc_dai_driver aw8898_dai[] = {
+ {
+ .name = "aw8898-aif",
+ .id = 1,
+ .playback = {
+ .stream_name = "Speaker_Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = AW8898_RATES,
+ .formats = AW8898_FORMATS,
+ },
+ .capture = {
+ .stream_name = "Speaker_Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = AW8898_RATES,
+ .formats = AW8898_FORMATS,
+ },
+ .ops = &aw8898_dai_ops,
+ .symmetric_rates = 1,
+ .symmetric_channels = 1,
+ .symmetric_samplebits = 1,
+ },
+};
+
+/*****************************************************
+ *
+ * codec driver
+ *
+ *****************************************************/
+static int aw8898_probe(struct snd_soc_codec *codec)
+{
+ struct aw8898 *aw8898 = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
+
+ pr_info("%s enter\n", __func__);
+
+ aw8898->codec = codec;
+
+ //aw8898_add_widgets(aw8898);
+
+ aw8898_add_codec_controls(aw8898);
+
+ if (codec->dev->of_node)
+ dev_set_name(codec->dev, "%s", "aw8898_smartpa");
+
+ pr_info("%s exit\n", __func__);
+
+ return ret;
+}
+
+static int aw8898_remove(struct snd_soc_codec *codec)
+{
+ //struct aw8898 *aw8898 = snd_soc_codec_get_drvdata(codec);
+ pr_info("%s enter\n", __func__);
+
+ //aw8898_inputdev_unregister(aw8898);
+
+ return 0;
+}
+
+/*
+struct regmap *aw8898_get_regmap(struct device *dev)
+{
+ struct aw8898 *aw8898 = dev_get_drvdata(dev);
+
+ return aw8898->regmap;
+}
+*/
+
+static unsigned int aw8898_codec_read(struct snd_soc_codec *codec,unsigned int reg)
+{
+ struct aw8898 *aw8898=snd_soc_codec_get_drvdata(codec);
+ unsigned int value =0;
+ int ret;
+ pr_debug("%s:enter \n",__func__);
+
+ if(aw8898_reg_access[reg]®_RD_ACCESS){
+ ret=aw8898_i2c_read(aw8898,reg,&value);
+ if(ret<0){
+ pr_debug("%s: read register failed \n",__func__);
+ return ret;
+ }
+ }else{
+ pr_debug("%s:Register 0x%x NO read access\n",__func__,reg);
+ return -1;
+ }
+ return value;
+}
+
+static int aw8898_codec_write(struct snd_soc_codec *codec,unsigned int reg,unsigned int value)
+{
+ int ret ;
+ struct aw8898 *aw8898=snd_soc_codec_get_drvdata(codec);
+ pr_debug("%s:enter ,reg is 0x%x value is 0x%x\n",__func__,reg,value);
+
+ if(aw8898_reg_access[reg]®_WR_ACCESS){
+ ret=aw8898_i2c_write(aw8898,reg,value);
+ return ret;
+ }else{
+ pr_debug("%s: Register 0x%x NO write access \n",__func__,reg);
+ }
+
+ return -1;
+}
+/*
+static int aw8898_codec_readable(struct snd_soc_codec *codec,unsigned int reg)
+{
+ return aw8898_reg_access[reg]®_RD_ACCESS;
+}
+*/
+static struct snd_soc_codec_driver soc_codec_dev_aw8898 = {
+ .probe = aw8898_probe,
+ .remove = aw8898_remove,
+ //.get_regmap = aw8898_get_regmap,
+ .read = aw8898_codec_read,
+ .write= aw8898_codec_write,
+ .reg_cache_size= AW8898_REG_MAX,
+ .reg_word_size=2,
+};
+
+/*****************************************************
+ *
+ * regmap
+ *
+ *****************************************************/
+bool aw8898_writeable_register(struct device *dev, unsigned int reg)
+{
+ /* enable read access for all registers */
+ return 1;
+}
+
+bool aw8898_readable_register(struct device *dev, unsigned int reg)
+{
+ /* enable read access for all registers */
+ return 1;
+}
+
+bool aw8898_volatile_register(struct device *dev, unsigned int reg)
+{
+ /* enable read access for all registers */
+ return 1;
+}
+
+static const struct regmap_config aw8898_regmap = {
+ .reg_bits = 8,
+ .val_bits = 16,
+
+ .max_register = AW8898_MAX_REGISTER,
+ .writeable_reg = aw8898_writeable_register,
+ .readable_reg = aw8898_readable_register,
+ .volatile_reg = aw8898_volatile_register,
+ .cache_type = REGCACHE_RBTREE,
+};
+
+/******************************************************
+ *
+ * irq
+ *
+ ******************************************************/
+static void aw8898_interrupt_setup(struct aw8898 *aw8898)
+{
+ unsigned int reg_val;
+
+ pr_info("%s enter\n", __func__);
+
+ aw8898_i2c_read(aw8898, AW8898_REG_SYSINTM, ®_val);
+ reg_val &= (~AW8898_BIT_SYSINTM_PLLM);
+ reg_val &= (~AW8898_BIT_SYSINTM_OTHM);
+ reg_val &= (~AW8898_BIT_SYSINTM_OCDM);
+ aw8898_i2c_write(aw8898, AW8898_REG_SYSINTM, reg_val);
+}
+
+static void aw8898_interrupt_clear(struct aw8898 *aw8898)
+{
+ unsigned int reg_val = 0;
+
+ pr_info("%s enter\n", __func__);
+
+ aw8898_i2c_read(aw8898, AW8898_REG_SYSST, ®_val);
+ pr_info("%s: reg SYSST=0x%x\n", __func__, reg_val);
+
+ aw8898_i2c_read(aw8898, AW8898_REG_SYSINT, ®_val);
+ pr_info("%s: reg SYSINT=0x%x\n", __func__, reg_val);
+
+ aw8898_i2c_read(aw8898, AW8898_REG_SYSINTM, ®_val);
+ pr_info("%s: reg SYSINTM=0x%x\n", __func__, reg_val);
+}
+
+static irqreturn_t aw8898_irq(int irq, void *data)
+{
+ struct aw8898 *aw8898 = data;
+
+ pr_info("%s enter\n", __func__);
+
+ aw8898_interrupt_clear(aw8898);
+
+ pr_info("%s exit\n", __func__);
+
+ return IRQ_HANDLED;
+}
+
+/*****************************************************
+ *
+ * device tree
+ *
+ *****************************************************/
+static int aw8898_parse_dt(struct device *dev, struct aw8898 *aw8898,
+ struct device_node *np)
+{
+ aw8898->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0);
+ if (aw8898->reset_gpio < 0) {
+ dev_err(dev, "%s: no reset gpio provided, will not HW reset device\n", __func__);
+ return -1;
+ } else {
+ dev_info(dev, "%s: reset gpio provided ok\n", __func__);
+ }
+ aw8898->irq_gpio = of_get_named_gpio(np, "irq-gpio", 0);
+ if (aw8898->irq_gpio < 0) {
+ dev_info(dev, "%s: no irq gpio provided.\n", __func__);
+ } else {
+ dev_info(dev, "%s: irq gpio provided ok.\n", __func__);
+ }
+
+ return 0;
+}
+
+int aw8898_hw_reset(struct aw8898 *aw8898)
+{
+ pr_info("%s enter\n", __func__);
+
+ if (aw8898 && gpio_is_valid(aw8898->reset_gpio)) {
+ gpio_set_value_cansleep(aw8898->reset_gpio, 0);
+ msleep(1);
+ gpio_set_value_cansleep(aw8898->reset_gpio, 1);
+ msleep(1);
+ } else {
+ dev_err(aw8898->dev, "%s: failed\n", __func__);
+ }
+ return 0;
+}
+
+/*****************************************************
+ *
+ * check chip id
+ *
+ *****************************************************/
+int aw8898_read_chipid(struct aw8898 *aw8898)
+{
+ int ret = -1;
+ unsigned int cnt = 0;
+ unsigned int reg = 0;
+
+ while(cnt < AW_READ_CHIPID_RETRIES) {
+ ret = aw8898_i2c_read(aw8898, AW8898_REG_ID, ®);
+ if (ret < 0) {
+ dev_err(aw8898->dev, "%s: failed to read register AW8898_REG_ID: %d\n", __func__, ret);
+ return -EIO;
+ }
+ switch (reg) {
+ case 0x1702:
+ pr_info("%s aw8898 detected\n", __func__);
+ aw8898->flags |= AW8898_FLAG_SKIP_INTERRUPTS;
+ aw8898->flags |= AW8898_FLAG_START_ON_MUTE;
+ aw8898->chipid = AW8898_ID;
+ pr_info("%s aw8898->flags=0x%x\n", __func__, aw8898->flags);
+ return 0;
+ default:
+ pr_info("%s unsupported device revision (0x%x)\n", __func__, reg );
+ break;
+ }
+ cnt ++;
+
+ msleep(AW_READ_CHIPID_RETRY_DELAY);
+ }
+
+ return -EINVAL;
+}
+
+/*****************************************************
+ *
+ * vbat monitor
+ *
+ *****************************************************/
+#ifdef AW8898_VBAT_MONITOR
+static int aw8898_vbat_monitor_stop(struct aw8898 *aw8898)
+{
+ pr_info("%s enter\n", __func__);
+
+ if(hrtimer_active(&aw8898->vbat_monitor_timer)) {
+ pr_info("%s: cancel vbat monitor\n", __func__);
+ hrtimer_cancel(&aw8898->vbat_monitor_timer);
+ }
+ return 0;
+}
+
+static int aw8898_vbat_monitor_start(struct aw8898 *aw8898)
+{
+ int ram_timer_val = 30000;
+
+ pr_info("%s enter\n", __func__);
+
+ if(hrtimer_active(&aw8898->vbat_monitor_timer)) {
+ } else {
+ pr_info("%s: start vbat monitor\n", __func__);
+ hrtimer_start(&aw8898->vbat_monitor_timer,
+ ktime_set(ram_timer_val/1000, (ram_timer_val%1000)*1000000),
+ HRTIMER_MODE_REL);
+ }
+ return 0;
+}
+
+static enum hrtimer_restart aw8898_vbat_monitor_timer_func(struct hrtimer *timer)
+{
+ struct aw8898 *aw8898 = container_of(timer, struct aw8898, vbat_monitor_timer);
+
+ pr_info("%s enter\n", __func__);
+
+ schedule_work(&aw8898->vbat_monitor_work);
+
+ return HRTIMER_NORESTART;
+}
+
+static int aw8898_get_sys_battery_info(char *dev)
+{
+ int fd;
+ int eCheck;
+ int nReadSize;
+ char buf[64],*pvalue;
+ mm_segment_t oldfs;
+
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ fd = sys_open(dev, O_RDONLY, 0);
+ if (fd < 0) {
+ pr_err("%s: open fail dev:%s fd:%d\n", __func__, dev, fd);
+ set_fs(oldfs);
+ return fd;
+ }
+
+ nReadSize = sys_read(fd, buf, sizeof(buf) - 1);
+ pr_debug("%s: nReadSize:%d\n", __func__, nReadSize);
+
+ eCheck = simple_strtoul(buf,&pvalue,10);
+ pr_debug("%s: eCheck = %d\n", __func__, eCheck);
+
+ set_fs(oldfs);
+ sys_close(fd);
+
+ if (eCheck > 0)
+ return eCheck;
+ else
+ return 0;
+}
+
+static void aw8898_vbat_monitor_work_routine(struct work_struct *work)
+{
+ struct aw8898 *aw8898 = container_of(work, struct aw8898, vbat_monitor_work);
+ unsigned int reg_val = 0;
+ int sys_vbat_vol = 0;
+
+ pr_info("%s enter\n", __func__);
+
+ aw8898_i2c_read(aw8898, AW8898_REG_PWMCTRL, ®_val);
+ if((reg_val&AW8898_BIT_PWMCTRL_HMUTE_ENABLE) == AW8898_BIT_PWMCTRL_HMUTE_DISABLE) {
+ sys_vbat_vol = aw8898_get_sys_battery_info(SYS_BAT_DEV);
+ pr_info("%s: get sys battery = %d\n", __func__, sys_vbat_vol);
+ if((sys_vbat_vol < AW8898_SYS_VBAT_LIMIT) && (sys_vbat_vol > AW8898_SYS_VBAT_MIN)) {
+ aw8898_i2c_write_bits(aw8898, AW8898_REG_GENCTRL,
+ AW8898_BIT_GENCTRL_BST_ILIMIT_MASK, (aw8898->bst_ilimit<<4));
+ }
+ aw8898_vbat_monitor_start(aw8898);
+ }
+}
+
+static int aw8898_vbat_monitor_init(struct aw8898 *aw8898)
+{
+ pr_info("%s enter\n", __func__);
+
+ aw8898->bst_ilimit = 0x00;
+
+ hrtimer_init(&aw8898->vbat_monitor_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ aw8898->vbat_monitor_timer.function = aw8898_vbat_monitor_timer_func;
+ INIT_WORK(&aw8898->vbat_monitor_work, aw8898_vbat_monitor_work_routine);
+ return 0;
+}
+#endif
+/******************************************************
+ *
+ * sys bin attribute
+ *
+ *****************************************************/
+static ssize_t aw8898_reg_write(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t off, size_t count)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct aw8898 *aw8898 = dev_get_drvdata(dev);
+
+ if (count != 1) {
+ pr_info("invalid register address");
+ return -EINVAL;
+ }
+
+ aw8898->reg = buf[0];
+
+ return 1;
+}
+
+static ssize_t aw8898_rw_write(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t off, size_t count)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct aw8898 *aw8898 = dev_get_drvdata(dev);
+ u8 *data;
+ int ret;
+ int retries = AW_I2C_RETRIES;
+
+ data = kmalloc(count+1, GFP_KERNEL);
+ if (data == NULL) {
+ pr_err("can not allocate memory\n");
+ return -ENOMEM;
+ }
+
+ data[0] = aw8898->reg;
+ memcpy(&data[1], buf, count);
+
+ retry:
+ ret = i2c_master_send(aw8898->i2c, data, count+1);
+ if (ret < 0) {
+ pr_warn("i2c error, retries left: %d\n", retries);
+ if (retries) {
+ retries--;
+ msleep(AW_I2C_RETRY_DELAY);
+ goto retry;
+ }
+ }
+
+ kfree(data);
+ return ret;
+}
+
+static ssize_t aw8898_rw_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t off, size_t count)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct aw8898 *aw8898 = dev_get_drvdata(dev);
+ struct i2c_msg msgs[] = {
+ {
+ .addr = aw8898->i2c->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = &aw8898->reg,
+ },
+ {
+ .addr = aw8898->i2c->addr,
+ .flags = I2C_M_RD,
+ .len = count,
+ .buf = buf,
+ },
+ };
+ int ret;
+ int retries = AW_I2C_RETRIES;
+ retry:
+ ret = i2c_transfer(aw8898->i2c->adapter, msgs, ARRAY_SIZE(msgs));
+ if (ret < 0) {
+ pr_warn("i2c error, retries left: %d\n", retries);
+ if (retries) {
+ retries--;
+ msleep(AW_I2C_RETRY_DELAY);
+ goto retry;
+ }
+ return ret;
+ }
+ /* ret contains the number of i2c messages send */
+ return 1 + ((ret > 1) ? count : 0);
+}
+
+static struct bin_attribute dev_attr_rw = {
+ .attr = {
+ .name = "rw",
+ .mode = S_IRUSR | S_IWUSR,
+ },
+ .size = 0,
+ .read = aw8898_rw_read,
+ .write = aw8898_rw_write,
+};
+
+static struct bin_attribute dev_attr_regaddr = {
+ .attr = {
+ .name = "regaddr",
+ .mode = S_IWUSR,
+ },
+ .size = 0,
+ .read = NULL,
+ .write = aw8898_reg_write,
+};
+
+/******************************************************
+ *
+ * sys group attribute: reg
+ *
+ ******************************************************/
+static ssize_t aw8898_reg_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct aw8898 *aw8898 = dev_get_drvdata(dev);
+
+ unsigned int databuf[2] = {0};
+
+ if(2 == sscanf(buf, "%x %x", &databuf[0], &databuf[1])) {
+ aw8898_i2c_write(aw8898, databuf[0], databuf[1]);
+ }
+
+ return count;
+}
+
+static ssize_t aw8898_reg_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct aw8898 *aw8898 = dev_get_drvdata(dev);
+ ssize_t len = 0;
+ unsigned char i = 0;
+ unsigned int reg_val = 0;
+ for(i = 0; i < AW8898_REG_MAX; i ++) {
+ if(!(aw8898_reg_access[i]®_RD_ACCESS))
+ continue;
+ aw8898_i2c_read(aw8898, i, ®_val);
+ len += snprintf(buf+len, PAGE_SIZE-len, "reg:0x%02x=0x%04x \n", i, reg_val);
+ }
+ return len;
+}
+
+static ssize_t aw8898_spk_rcv_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct aw8898 *aw8898 = dev_get_drvdata(dev);
+
+ unsigned int databuf[2] = {0};
+
+ if(1 == sscanf(buf, "%d", &databuf[0])) {
+ aw8898->spk_rcv_mode = databuf[0];
+ }
+
+ return count;
+}
+
+static ssize_t aw8898_spk_rcv_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct aw8898 *aw8898 = dev_get_drvdata(dev);
+ ssize_t len = 0;
+ if(aw8898->spk_rcv_mode == AW8898_SPEAKER_MODE) {
+ len += snprintf(buf+len, PAGE_SIZE-len, "aw8898 spk_rcv: %d, speaker mode\n", aw8898->spk_rcv_mode);
+ } else if (aw8898->spk_rcv_mode == AW8898_RECEIVER_MODE) {
+ len += snprintf(buf+len, PAGE_SIZE-len, "aw8898 spk_rcv: %d, receiver mode\n", aw8898->spk_rcv_mode);
+ } else {
+ len += snprintf(buf+len, PAGE_SIZE-len, "aw8898 spk_rcv: %d, unknown mode\n", aw8898->spk_rcv_mode);
+ }
+
+ return len;
+}
+
+static ssize_t aw8898_bst_ilimit_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct aw8898 *aw8898 = dev_get_drvdata(dev);
+
+ unsigned int databuf[2] = {0};
+
+ if(1 == sscanf(buf, "%x", &databuf[0])) {
+ aw8898->bst_ilimit = databuf[0];
+ }
+
+ return count;
+}
+
+static ssize_t aw8898_bst_ilimit_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct aw8898 *aw8898 = dev_get_drvdata(dev);
+ ssize_t len = 0;
+
+ len += snprintf(buf+len, PAGE_SIZE-len, "aw8898 bst_ilimit=0x%02x\n", aw8898->bst_ilimit);
+
+ return len;
+}
+static DEVICE_ATTR(reg, S_IWUSR | S_IRUGO, aw8898_reg_show, aw8898_reg_store);
+static DEVICE_ATTR(spk_rcv, S_IWUSR | S_IRUGO, aw8898_spk_rcv_show, aw8898_spk_rcv_store);
+static DEVICE_ATTR(bst_ilimit, S_IWUSR | S_IRUGO, aw8898_bst_ilimit_show, aw8898_bst_ilimit_store);
+
+static struct attribute *aw8898_attributes[] = {
+ &dev_attr_reg.attr,
+ &dev_attr_spk_rcv.attr,
+ &dev_attr_bst_ilimit.attr,
+ NULL
+};
+
+static struct attribute_group aw8898_attribute_group = {
+ .attrs = aw8898_attributes
+};
+
+
+/******************************************************
+ *
+ * i2c driver
+ *
+ ******************************************************/
+static int aw8898_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+{
+ struct snd_soc_dai_driver *dai;
+ struct aw8898 *aw8898;
+ struct device_node *np = i2c->dev.of_node;
+ int irq_flags = 0;
+ int ret = -1;
+
+ pr_info("%s enter\n", __func__);
+
+ if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) {
+ dev_err(&i2c->dev, "check_functionality failed\n");
+ return -EIO;
+ }
+
+ aw8898 = devm_kzalloc(&i2c->dev, sizeof(struct aw8898), GFP_KERNEL);
+ if (aw8898 == NULL)
+ return -ENOMEM;
+
+ aw8898->dev = &i2c->dev;
+ aw8898->i2c = i2c;
+
+ /* aw8898 regmap */
+ aw8898->regmap = devm_regmap_init_i2c(i2c, &aw8898_regmap);
+ if (IS_ERR(aw8898->regmap)) {
+ ret = PTR_ERR(aw8898->regmap);
+ dev_err(&i2c->dev, "%s: failed to allocate register map: %d\n", __func__, ret);
+ goto err_regmap;
+ }
+
+ i2c_set_clientdata(i2c, aw8898);
+ mutex_init(&aw8898->cfg_lock);
+
+ /* aw8898 rst & int */
+ if (np) {
+ ret = aw8898_parse_dt(&i2c->dev, aw8898, np);
+ if (ret) {
+ dev_err(&i2c->dev, "%s: failed to parse device tree node\n", __func__);
+ goto err_parse_dt;
+ }
+ } else {
+ aw8898->reset_gpio = -1;
+ aw8898->irq_gpio = -1;
+ }
+
+ if (gpio_is_valid(aw8898->reset_gpio)) {
+ ret = devm_gpio_request_one(&i2c->dev, aw8898->reset_gpio,
+ GPIOF_OUT_INIT_LOW, "aw8898_rst");
+ if (ret){
+ dev_err(&i2c->dev, "%s: rst request failed\n", __func__);
+ goto err_gpio_request;
+ }
+ }
+
+ if (gpio_is_valid(aw8898->irq_gpio)) {
+ ret = devm_gpio_request_one(&i2c->dev, aw8898->irq_gpio,
+ GPIOF_DIR_IN, "aw8898_int");
+ if (ret){
+ dev_err(&i2c->dev, "%s: int request failed\n", __func__);
+ goto err_gpio_request;
+ }
+ }
+
+ /* hardware reset */
+ aw8898_hw_reset(aw8898);
+
+ /* aw8898 chip id */
+ ret = aw8898_read_chipid(aw8898);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "%s: aw8898_read_chipid failed ret=%d\n", __func__, ret);
+ goto err_id;
+ }
+
+ /* aw8898 device name */
+ if (i2c->dev.of_node) {
+ dev_set_name(&i2c->dev, "%s", "aw8898_smartpa");
+ } else {
+ dev_err(&i2c->dev, "%s failed to set device name: %d\n", __func__, ret);
+ }
+
+ /* register codec */
+ dai = devm_kzalloc(&i2c->dev, sizeof(aw8898_dai), GFP_KERNEL);
+ if (!dai) {
+ goto err_dai_kzalloc;
+ }
+ memcpy(dai, aw8898_dai, sizeof(aw8898_dai));
+ pr_info("%s dai->name(%s)\n", __func__, dai->name);
+
+ ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_aw8898,
+ dai, ARRAY_SIZE(aw8898_dai));
+ if (ret < 0) {
+ dev_err(&i2c->dev, "%s failed to register aw8898: %d\n", __func__, ret);
+ goto err_register_codec;
+ }
+
+ /* aw8898 irq */
+ if (gpio_is_valid(aw8898->irq_gpio) &&
+ !(aw8898->flags & AW8898_FLAG_SKIP_INTERRUPTS)) {
+ aw8898_interrupt_setup(aw8898);
+ /* register irq handler */
+ irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
+ ret = devm_request_threaded_irq(&i2c->dev,
+ gpio_to_irq(aw8898->irq_gpio),
+ NULL, aw8898_irq, irq_flags,
+ "aw8898", aw8898);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "failed to request IRQ %d: %d\n",
+ gpio_to_irq(aw8898->irq_gpio), ret);
+ goto err_irq;
+ }
+ } else {
+ dev_info(&i2c->dev, "%s skipping IRQ registration\n", __func__);
+ /* disable feature support if gpio was invalid */
+ aw8898->flags |= AW8898_FLAG_SKIP_INTERRUPTS;
+ }
+
+ /* Register the sysfs files for climax backdoor access */
+ ret = device_create_bin_file(&i2c->dev, &dev_attr_rw);
+ if (ret)
+ dev_info(&i2c->dev, "%s error creating sysfs files: rw\n", __func__);
+ ret = device_create_bin_file(&i2c->dev, &dev_attr_regaddr);
+ if (ret)
+ dev_info(&i2c->dev, "%s error creating sysfs files: regaddr\n", __func__);
+
+ dev_set_drvdata(&i2c->dev, aw8898);
+ ret = sysfs_create_group(&i2c->dev.kobj, &aw8898_attribute_group);
+ if (ret < 0) {
+ dev_info(&i2c->dev, "%s error creating sysfs attr files\n", __func__);
+ goto err_sysfs;
+ }
+
+#ifdef AW8898_VBAT_MONITOR
+ aw8898_vbat_monitor_init(aw8898);
+#endif
+ pr_info("%s probe completed successfully!\n", __func__);
+
+ return 0;
+
+err_sysfs:
+ device_remove_bin_file(&i2c->dev, &dev_attr_regaddr);
+ device_remove_bin_file(&i2c->dev, &dev_attr_rw);
+ devm_free_irq(&i2c->dev, gpio_to_irq(aw8898->irq_gpio), aw8898);
+err_irq:
+ snd_soc_unregister_codec(&i2c->dev);
+err_register_codec:
+ devm_kfree(&i2c->dev, dai);
+ dai = NULL;
+err_dai_kzalloc:
+err_id:
+ if (gpio_is_valid(aw8898->reset_gpio))
+ devm_gpio_free(&i2c->dev, aw8898->reset_gpio);
+ if (gpio_is_valid(aw8898->irq_gpio))
+ devm_gpio_free(&i2c->dev, aw8898->irq_gpio);
+err_gpio_request:
+err_parse_dt:
+err_regmap:
+ devm_kfree(&i2c->dev, aw8898);
+ aw8898 = NULL;
+ return ret;
+}
+
+static int aw8898_i2c_remove(struct i2c_client *i2c)
+{
+ struct aw8898 *aw8898 = i2c_get_clientdata(i2c);
+
+ pr_info("%s enter\n", __func__);
+
+ device_remove_bin_file(&i2c->dev, &dev_attr_regaddr);
+ device_remove_bin_file(&i2c->dev, &dev_attr_rw);
+ devm_free_irq(&i2c->dev, gpio_to_irq(aw8898->irq_gpio), aw8898);
+
+ snd_soc_unregister_codec(&i2c->dev);
+
+ if (gpio_is_valid(aw8898->irq_gpio))
+ devm_gpio_free(&i2c->dev, aw8898->irq_gpio);
+ if (gpio_is_valid(aw8898->reset_gpio))
+ devm_gpio_free(&i2c->dev, aw8898->reset_gpio);
+
+ return 0;
+}
+
+static const struct i2c_device_id aw8898_i2c_id[] = {
+ { AW8898_I2C_NAME, 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, aw8898_i2c_id);
+
+static struct of_device_id aw8898_dt_match[] = {
+ { .compatible = "awinic,aw8898_smartpa" },
+ { },
+};
+
+static struct i2c_driver aw8898_i2c_driver = {
+ .driver = {
+ .name = AW8898_I2C_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(aw8898_dt_match),
+ },
+ .probe = aw8898_i2c_probe,
+ .remove = aw8898_i2c_remove,
+ .id_table = aw8898_i2c_id,
+};
+
+
+static int __init aw8898_i2c_init(void)
+{
+ int ret = 0;
+
+ pr_info("aw8898 driver version %s\n", AW8898_VERSION);
+
+ ret = i2c_add_driver(&aw8898_i2c_driver);
+ if(ret){
+ pr_err("fail to add aw8898 device into i2c\n");
+ return ret;
+ }
+
+ return 0;
+}
+module_init(aw8898_i2c_init);
+
+
+static void __exit aw8898_i2c_exit(void)
+{
+ i2c_del_driver(&aw8898_i2c_driver);
+}
+module_exit(aw8898_i2c_exit);
+
+
+MODULE_DESCRIPTION("ASoC AW8898 Smart PA Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/aw/aw8898.h b/sound/soc/codecs/aw/aw8898.h
new file mode 100755
index 0000000..2042f5e
--- /dev/null
+++ b/sound/soc/codecs/aw/aw8898.h
@@ -0,0 +1,72 @@
+#ifndef _AW8898_H_
+#define _AW8898_H_
+
+
+/*
+ * i2c transaction on Linux limited to 64k
+ * (See Linux kernel documentation: Documentation/i2c/writing-clients)
+*/
+#define MAX_I2C_BUFFER_SIZE 65536
+
+#define AW8898_FLAG_START_ON_MUTE (1 << 0)
+#define AW8898_FLAG_SKIP_INTERRUPTS (1 << 1)
+#define AW8898_FLAG_SAAM_AVAILABLE (1 << 2)
+#define AW8898_FLAG_STEREO_DEVICE (1 << 3)
+#define AW8898_FLAG_MULTI_MIC_INPUTS (1 << 4)
+
+#define AW8898_NUM_RATES 9
+
+#define AW8898_MAX_REGISTER 0xff
+
+//#define AW8898_VBAT_MONITOR
+#ifdef AW8898_VBAT_MONITOR
+#define SYS_BAT_DEV "/sys/class/power_supply/battery/voltage_now"
+#define AW8898_SYS_VBAT_LIMIT 3600000
+#define AW8898_SYS_VBAT_MIN 3000000
+#endif
+enum aw8898_chipid{
+ AW8898_ID,
+};
+
+enum aw8898_mode_spk_rcv{
+ AW8898_SPEAKER_MODE = 0,
+ AW8898_RECEIVER_MODE = 1,
+};
+
+struct aw8898 {
+ struct regmap *regmap;
+ struct i2c_client *i2c;
+ struct snd_soc_codec *codec;
+ struct device *dev;
+ struct mutex cfg_lock;
+#ifdef AW8898_VBAT_MONITOR
+ struct hrtimer vbat_monitor_timer;
+ struct work_struct vbat_monitor_work;
+#endif
+ int sysclk;
+ int rate;
+ int pstream;
+ int cstream;
+
+ int reset_gpio;
+ int irq_gpio;
+
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *dbg_dir;
+#endif
+ u8 reg;
+
+ unsigned int flags;
+ unsigned int chipid;
+ unsigned int init;
+ unsigned int spk_rcv_mode;
+ unsigned int bst_ilimit;
+};
+
+struct aw8898_container{
+ int len;
+ unsigned char data[];
+};
+
+
+#endif
diff --git a/sound/soc/codecs/aw/aw8898_reg.h b/sound/soc/codecs/aw/aw8898_reg.h
new file mode 100755
index 0000000..c66927c
--- /dev/null
+++ b/sound/soc/codecs/aw/aw8898_reg.h
@@ -0,0 +1,448 @@
+#ifndef _AW8898_REG_H_
+#define _AW8898_REG_H_
+
+/********************************************
+ * Register List
+ *******************************************/
+#define AW8898_REG_ID 0x00
+#define AW8898_REG_SYSST 0x01
+#define AW8898_REG_SYSINT 0x02
+#define AW8898_REG_SYSINTM 0x03
+#define AW8898_REG_SYSCTRL 0x04
+#define AW8898_REG_I2SCTRL 0x05
+#define AW8898_REG_I2STXCFG 0x06
+#define AW8898_REG_PWMCTRL 0x08
+#define AW8898_REG_HAGCCFG1 0x09
+#define AW8898_REG_HAGCCFG2 0x0A
+#define AW8898_REG_HAGCCFG3 0x0B
+#define AW8898_REG_HAGCCFG4 0x0C
+#define AW8898_REG_HAGCCFG5 0x0D
+#define AW8898_REG_HAGCCFG6 0x0E
+#define AW8898_REG_HAGCCFG7 0x0F
+#define AW8898_REG_HAGCST 0x10
+#define AW8898_REG_DBGCTRL 0x20
+#define AW8898_REG_I2SCFG 0x21
+#define AW8898_REG_I2SSTAT 0x22
+#define AW8898_REG_I2SCAPCNT 0x23
+#define AW8898_REG_GENCTRL 0x60
+#define AW8898_REG_BSTCTRL1 0x61
+#define AW8898_REG_BSTCTRL2 0x62
+#define AW8898_REG_PLLCTRL1 0x63
+#define AW8898_REG_PLLCTRL2 0x64
+#define AW8898_REG_TESTCTRL 0x65
+#define AW8898_REG_AMPDBG1 0x66
+#define AW8898_REG_AMPDBG2 0x67
+#define AW8898_REG_BSTDBG1 0x68
+#define AW8898_REG_CDACTRL1 0x69
+#define AW8898_REG_CDACTRL2 0x6A
+#define AW8898_REG_TESTCTRL2 0x6B
+
+#define AW8898_REG_MAX 0x6F
+
+/********************************************
+ * Register Access
+ *******************************************/
+#define REG_NONE_ACCESS 0
+#define REG_RD_ACCESS 1 << 0
+#define REG_WR_ACCESS 1 << 1
+
+const unsigned char aw8898_reg_access[AW8898_REG_MAX]={
+ [AW8898_REG_ID ]= REG_RD_ACCESS,
+ [AW8898_REG_SYSST ]= REG_RD_ACCESS,
+ [AW8898_REG_SYSINT ]= REG_RD_ACCESS,
+ [AW8898_REG_SYSINTM ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_SYSCTRL ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_I2SCTRL ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_I2STXCFG ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_PWMCTRL ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_HAGCCFG1 ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_HAGCCFG2 ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_HAGCCFG3 ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_HAGCCFG4 ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_HAGCCFG5 ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_HAGCCFG6 ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_HAGCCFG7 ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_HAGCST ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_DBGCTRL ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_I2SCFG ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_I2SSTAT ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_I2SCAPCNT ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_GENCTRL ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_BSTCTRL1 ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_BSTCTRL2 ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_PLLCTRL1 ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_PLLCTRL2 ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_TESTCTRL ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_AMPDBG1 ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_AMPDBG2 ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_BSTDBG1 ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_CDACTRL1 ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_CDACTRL2 ]= REG_RD_ACCESS|REG_WR_ACCESS,
+ [AW8898_REG_TESTCTRL2 ]= REG_RD_ACCESS|REG_WR_ACCESS,
+};
+
+/******************************************************
+ * Register Detail
+ *****************************************************/
+// SYSST
+#define AW8898_BIT_SYSST_UVLOS ( 1<<14)
+#define AW8898_BIT_SYSST_ADPS ( 1<<13)
+#define AW8898_BIT_SYSST_DSPS ( 1<<12)
+#define AW8898_BIT_SYSST_BSTOCS ( 1<<11)
+#define AW8898_BIT_SYSST_OVPS ( 1<<10)
+#define AW8898_BIT_SYSST_BSTS ( 1<< 9)
+#define AW8898_BIT_SYSST_SWS ( 1<< 8)
+#define AW8898_BIT_SYSST_CLIPS ( 1<< 7)
+#define AW8898_BIT_SYSST_WDS ( 1<< 6)
+#define AW8898_BIT_SYSST_NOCLKS ( 1<< 5)
+#define AW8898_BIT_SYSST_CLKS ( 1<< 4)
+#define AW8898_BIT_SYSST_OCDS ( 1<< 3)
+#define AW8898_BIT_SYSST_OTLS ( 1<< 2)
+#define AW8898_BIT_SYSST_OTHS ( 1<< 1)
+#define AW8898_BIT_SYSST_PLLS ( 1<< 0)
+
+// SYSINT
+#define AW8898_BIT_SYSINT_UVLOI ( 1<<14)
+#define AW8898_BIT_SYSINT_ADPI ( 1<<13)
+#define AW8898_BIT_SYSINT_DSPI ( 1<<12)
+#define AW8898_BIT_SYSINT_BSTOCI ( 1<<11)
+#define AW8898_BIT_SYSINT_OVPI ( 1<<10)
+#define AW8898_BIT_SYSINT_BSTI ( 1<< 9)
+#define AW8898_BIT_SYSINT_SWI ( 1<< 8)
+#define AW8898_BIT_SYSINT_CLIPI ( 1<< 7)
+#define AW8898_BIT_SYSINT_WDI ( 1<< 6)
+#define AW8898_BIT_SYSINT_NOCLKI ( 1<< 5)
+#define AW8898_BIT_SYSINT_CLKI ( 1<< 4)
+#define AW8898_BIT_SYSINT_OCDI ( 1<< 3)
+#define AW8898_BIT_SYSINT_OTLI ( 1<< 2)
+#define AW8898_BIT_SYSINT_OTHI ( 1<< 1)
+#define AW8898_BIT_SYSINT_PLLI ( 1<< 0)
+
+// SYSINTM
+#define AW8898_BIT_SYSINTM_UVLOM ( 1<<14)
+#define AW8898_BIT_SYSINTM_ADPM ( 1<<13)
+#define AW8898_BIT_SYSINTM_DSPM ( 1<<12)
+#define AW8898_BIT_SYSINTM_BSTOCM ( 1<<11)
+#define AW8898_BIT_SYSINTM_OVPM ( 1<<10)
+#define AW8898_BIT_SYSINTM_BSTM ( 1<< 9)
+#define AW8898_BIT_SYSINTM_SWM ( 1<< 8)
+#define AW8898_BIT_SYSINTM_CLIPM ( 1<< 7)
+#define AW8898_BIT_SYSINTM_WDM ( 1<< 6)
+#define AW8898_BIT_SYSINTM_NOCLKM ( 1<< 5)
+#define AW8898_BIT_SYSINTM_CLKM ( 1<< 4)
+#define AW8898_BIT_SYSINTM_OCDM ( 1<< 3)
+#define AW8898_BIT_SYSINTM_OTLM ( 1<< 2)
+#define AW8898_BIT_SYSINTM_OTHM ( 1<< 1)
+#define AW8898_BIT_SYSINTM_PLLM ( 1<< 0)
+
+// SYSCTRL
+#define AW8898_BIT_SYSCTRL_INTMODE_MASK (~( 3<< 8))
+#define AW8898_BIT_SYSCTRL_INT_HIGH_PP ( 3<< 8)
+#define AW8898_BIT_SYSCTRL_INT_LOW_PP ( 2<< 8)
+#define AW8898_BIT_SYSCTRL_INT_HIGH_OD ( 1<< 8)
+#define AW8898_BIT_SYSCTRL_INT_LOW_OD ( 0<< 8)
+#define AW8898_BIT_SYSCTRL_MODE_MASK (~( 1<< 7))
+#define AW8898_BIT_SYSCTRL_RCV_MODE ( 1<< 7)
+#define AW8898_BIT_SYSCTRL_SPK_MODE ( 0<< 7)
+#define AW8898_BIT_SYSCTRL_I2SEN_MASK (~( 1<< 6))
+#define AW8898_BIT_SYSCTRL_I2S_ENABLE ( 1<< 6)
+#define AW8898_BIT_SYSCTRL_I2S_DISABLE ( 0<< 6)
+#define AW8898_BIT_SYSCTRL_WSINV_MASK (~( 1<< 5))
+#define AW8898_BIT_SYSCTRL_WS_INVERT ( 1<< 5)
+#define AW8898_BIT_SYSCTRL_WS_NO_INVERT ( 0<< 5)
+#define AW8898_BIT_SYSCTRL_BCKINV_MASK (~( 1<< 4))
+#define AW8898_BIT_SYSCTRL_BCK_INVERT ( 1<< 4)
+#define AW8898_BIT_SYSCTRL_BCK_NO_INVERT ( 0<< 4)
+#define AW8898_BIT_SYSCTRL_IPLL_MASK (~( 1<< 3))
+#define AW8898_BIT_SYSCTRL_PLL_WORD ( 1<< 3)
+#define AW8898_BIT_SYSCTRL_PLL_BIT ( 0<< 3)
+#define AW8898_BIT_SYSCTRL_DSPBY_MASK (~( 1<< 2))
+#define AW8898_BIT_SYSCTRL_DSP_BYPASS ( 1<< 2)
+#define AW8898_BIT_SYSCTRL_DSP_WORK ( 0<< 2)
+#define AW8898_BIT_SYSCTRL_CP_MASK (~( 1<< 1))
+#define AW8898_BIT_SYSCTRL_CP_PDN ( 1<< 1)
+#define AW8898_BIT_SYSCTRL_CP_ACTIVE ( 0<< 1)
+#define AW8898_BIT_SYSCTRL_PW_MASK (~( 1<< 0))
+#define AW8898_BIT_SYSCTRL_PW_PDN ( 1<< 0)
+#define AW8898_BIT_SYSCTRL_PW_ACTIVE ( 0<< 0)
+
+// I2SCTRL
+#define AW8898_BIT_I2SCTRL_INPLEV_MASK (~( 1<<13))
+#define AW8898_BIT_I2SCTRL_INPLEV_0DB ( 1<<13)
+#define AW8898_BIT_I2SCTRL_INPLEV_NEG_6DB ( 0<<13)
+#define AW8898_BIT_I2SCTRL_STEREO_MASK (~( 1<<12))
+#define AW8898_BIT_I2SCTRL_STEREO_ENABLE ( 1<<12)
+#define AW8898_BIT_I2SCTRL_STEREO_DISABLE ( 0<<12)
+#define AW8898_BIT_I2SCTRL_CHS_MASK (~( 3<<10))
+#define AW8898_BIT_I2SCTRL_CHS_MONO ( 3<<10)
+#define AW8898_BIT_I2SCTRL_CHS_RIGHT ( 2<<10)
+#define AW8898_BIT_I2SCTRL_CHS_LEFT ( 1<<10)
+#define AW8898_BIT_I2SCTRL_MD_MASK (~( 3<< 8))
+#define AW8898_BIT_I2SCTRL_MD_LSB ( 2<< 8)
+#define AW8898_BIT_I2SCTRL_MD_MSB ( 1<< 8)
+#define AW8898_BIT_I2SCTRL_MD_STD ( 0<< 8)
+#define AW8898_BIT_I2SCTRL_FMS_MASK (~( 3<< 6))
+#define AW8898_BIT_I2SCTRL_FMS_32BIT ( 3<< 6)
+#define AW8898_BIT_I2SCTRL_FMS_24BIT ( 2<< 6)
+#define AW8898_BIT_I2SCTRL_FMS_20BIT ( 1<< 6)
+#define AW8898_BIT_I2SCTRL_FMS_16BIT ( 0<< 6)
+#define AW8898_BIT_I2SCTRL_BCK_MASK (~( 3<< 4))
+#define AW8898_BIT_I2SCTRL_BCK_64FS ( 2<< 4)
+#define AW8898_BIT_I2SCTRL_BCK_48FS ( 1<< 4)
+#define AW8898_BIT_I2SCTRL_BCK_32FS ( 0<< 4)
+#define AW8898_BIT_I2SCTRL_SR_MASK (~(15<< 0))
+#define AW8898_BIT_I2SCTRL_SR_192K (10<< 0)
+#define AW8898_BIT_I2SCTRL_SR_96K ( 9<< 0)
+#define AW8898_BIT_I2SCTRL_SR_48K ( 8<< 0)
+#define AW8898_BIT_I2SCTRL_SR_44P1K ( 7<< 0)
+#define AW8898_BIT_I2SCTRL_SR_32K ( 6<< 0)
+#define AW8898_BIT_I2SCTRL_SR_24K ( 5<< 0)
+#define AW8898_BIT_I2SCTRL_SR_22K ( 4<< 0)
+#define AW8898_BIT_I2SCTRL_SR_16K ( 3<< 0)
+#define AW8898_BIT_I2SCTRL_SR_12K ( 2<< 0)
+#define AW8898_BIT_I2SCTRL_SR_11K ( 1<< 0)
+#define AW8898_BIT_I2SCTRL_SR_8K ( 0<< 0)
+
+
+// I2STXCFG
+#define AW8898_BIT_I2STXCFG_FSYNC_MASK (~( 1<<15))
+#define AW8898_BIT_I2STXCFG_FSYNC_BCK_CYCLE ( 1<<15)
+#define AW8898_BIT_I2STXCFG_FSYNC_ONE_SLOT ( 0<<15)
+#define AW8898_BIT_I2STXCFG_SLOT_NUM_MASK (~( 1<<14))
+#define AW8898_BIT_I2STXCFG_SLOT_NUM_4_TIMES ( 1<<14)
+#define AW8898_BIT_I2STXCFG_SLOT_NUM_2_TIMES ( 0<<14)
+#define AW8898_BIT_I2STXCFG_TX_SLOT_VLD_MASK (~(15<<12))
+#define AW8898_BIT_I2STXCFG_TX_SLOT_VLD_3 ( 3<<12)
+#define AW8898_BIT_I2STXCFG_TX_SLOT_VLD_2 ( 2<<12)
+#define AW8898_BIT_I2STXCFG_TX_SLOT_VLD_1 ( 1<<12)
+#define AW8898_BIT_I2STXCFG_TX_SLOT_VLD_0 ( 0<<12)
+#define AW8898_BIT_I2STXCFG_RX_SLOT_VLD_MASK (~(15<< 8))
+#define AW8898_BIT_I2STXCFG_RX_SLOT_VLD_3_2 (12<< 8)
+#define AW8898_BIT_I2STXCFG_RX_SLOT_VLD_3_1 (10<< 8)
+#define AW8898_BIT_I2STXCFG_RX_SLOT_VLD_3_0 ( 9<< 8)
+#define AW8898_BIT_I2STXCFG_RX_SLOT_VLD_2_1 ( 6<< 8)
+#define AW8898_BIT_I2STXCFG_RX_SLOT_VLD_2_0 ( 5<< 8)
+#define AW8898_BIT_I2STXCFG_RX_SLOT_VLD_1_0 ( 3<< 8)
+#define AW8898_BIT_I2STXCFG_RX_SLOT_VLD_3 ( 8<< 8)
+#define AW8898_BIT_I2STXCFG_RX_SLOT_VLD_2 ( 4<< 8)
+#define AW8898_BIT_I2STXCFG_RX_SLOT_VLD_1 ( 2<< 8)
+#define AW8898_BIT_I2STXCFG_RX_SLOT_VLD_0 ( 1<< 8)
+#define AW8898_BIT_I2STXCFG_DRVSTREN_MASK (~( 1<< 5))
+#define AW8898_BIT_I2STXCFG_DRVSTREN_8MA ( 1<< 5)
+#define AW8898_BIT_I2STXCFG_DRVSTREN_2MA ( 0<< 5)
+#define AW8898_BIT_I2STXCFG_DOHZ_MASK (~( 1<< 4))
+#define AW8898_BIT_I2STXCFG_DOHZ_HIZ ( 1<< 4)
+#define AW8898_BIT_I2STXCFG_DOHZ_GND ( 0<< 4)
+#define AW8898_BIT_I2STXCFG_DSEL_MASK (~( 3<< 2))
+#define AW8898_BIT_I2STXCFG_DSEL_DSP ( 2<< 2)
+#define AW8898_BIT_I2STXCFG_DSEL_GAIN ( 1<< 2)
+#define AW8898_BIT_I2STXCFG_DSEL_ZERO ( 0<< 2)
+#define AW8898_BIT_I2STXCFG_CHS_MASK (~( 1<< 1))
+#define AW8898_BIT_I2STXCFG_CHS_RIGHT ( 1<< 1)
+#define AW8898_BIT_I2STXCFG_CHS_LEFT ( 0<< 1)
+#define AW8898_BIT_I2STXCFG_TX_MASK (~( 1<< 0))
+#define AW8898_BIT_I2STXCFG_TX_ENABLE ( 1<< 0)
+#define AW8898_BIT_I2STXCFG_TX_DISABLE ( 0<< 0)
+
+// PWMCTRL
+#define AW8898_BIT_PWMCTRL_DSMZTH_MASK (~(15<<12))
+#define AW8898_BIT_PWMCTRL_DSMZTH_UNIT ( 1<<12)
+#define AW8898_BIT_PWMCTRL_PWMDELA_MASK (~(15<< 8))
+#define AW8898_BIT_PWMCTRL_PWMDELA_UNIT ( 1<< 8)
+#define AW8898_BIT_PWMCTRL_PWMDELB_MASK (~(15<< 4))
+#define AW8898_BIT_PWMCTRL_PWMDELB_UNIT ( 1<< 4)
+#define AW8898_BIT_PWMCTRL_PWMSH_MASK (~( 1<< 3))
+#define AW8898_BIT_PWMCTRL_PWMSH_TRIANGLE ( 1<< 3)
+#define AW8898_BIT_PWMCTRL_PWMSH_SAWTOOTH ( 0<< 3)
+#define AW8898_BIT_PWMCTRL_PWMRES_MASK (~( 1<< 2))
+#define AW8898_BIT_PWMCTRL_PWMRES_8BIT ( 1<< 2)
+#define AW8898_BIT_PWMCTRL_PWMRES_7BIT ( 0<< 2)
+#define AW8898_BIT_PWMCTRL_HDCCE_MASK (~( 1<< 1))
+#define AW8898_BIT_PWMCTRL_HDCCE_ENABLE ( 1<< 1)
+#define AW8898_BIT_PWMCTRL_HDCCE_DISABLE ( 0<< 1)
+#define AW8898_BIT_PWMCTRL_HMUTE_MASK (~( 1<< 0))
+#define AW8898_BIT_PWMCTRL_HMUTE_ENABLE ( 1<< 0)
+#define AW8898_BIT_PWMCTRL_HMUTE_DISABLE ( 0<< 0)
+
+// HAGCCFG1
+#define AW8898_BIT_HAGCCFG1_RVTH_MASK (~(255<<8))
+#define AW8898_BIT_HAGCCFG1_RVTH_UNIT ( 1<< 8)
+#define AW8898_BIT_HAGCCFG1_AVTH_MASK (~(255<<0))
+#define AW8898_BIT_HAGCCFG1_AVTH_UNIT ( 1<< 0)
+
+// HAGCCFG2
+#define AW8898_BIT_HAGCCFG2_ATTH_UNIT ( 1<< 0)
+
+// HAGCCFG3
+#define AW8898_BIT_HAGCCFG3_RTTH_UNIT ( 1<< 0)
+
+// HAGCCFG4
+#define AW8898_BIT_HAGCCFG4_MPD_MASK (~( 1<<14))
+#define AW8898_BIT_HAGCCFG4_MPD_ENABLE ( 1<<14)
+#define AW8898_BIT_HAGCCFG4_MPD_DISABLE ( 0<<14)
+#define AW8898_BIT_HAGCCFG4_MPD_TTH_MASK (~( 3<<12))
+#define AW8898_BIT_HAGCCFG4_MPD_TTH_0P047 ( 3<<12)
+#define AW8898_BIT_HAGCCFG4_MPD_TTH_0P032 ( 2<<12)
+#define AW8898_BIT_HAGCCFG4_MPD_TTH_0P016 ( 1<<12)
+#define AW8898_BIT_HAGCCFG4_MPD_TTH_0P008 ( 0<<12)
+#define AW8898_BIT_HAGCCFG4_MPD_RTH_MASK (~( 3<<10))
+#define AW8898_BIT_HAGCCFG4_MPD_RTH_0P047 ( 3<<10)
+#define AW8898_BIT_HAGCCFG4_MPD_RTH_0P032 ( 2<<10)
+#define AW8898_BIT_HAGCCFG4_MPD_RTH_0P016 ( 1<<10)
+#define AW8898_BIT_HAGCCFG4_MPD_RTH_0P008 ( 0<<10)
+#define AW8898_BIT_HAGCCFG4_MPD_ATH_MASK (~( 3<< 8))
+#define AW8898_BIT_HAGCCFG4_MPD_ATH_0P047 ( 3<< 8)
+#define AW8898_BIT_HAGCCFG4_MPD_ATH_0P032 ( 2<< 8)
+#define AW8898_BIT_HAGCCFG4_MPD_ATH_0P016 ( 1<< 8)
+#define AW8898_BIT_HAGCCFG4_MPD_ATH_0P008 ( 0<< 8)
+#define AW8898_BIT_HAGCCFG4_HOLDTH_MASK (~(255<< 0))
+
+// HAGCCFG5
+
+// HAGCCFG6
+
+// HAGCCFG7
+#define AW8898_BIT_HAGCCFG7_VOL_MASK (~(255< 8))
+#define AW8898_VOLUME_MAX (0)
+#define AW8898_VOLUME_MIN (-255)
+#define AW8898_VOL_REG_SHIFT (8)
+
+// HAGCST
+#define AW8898_BIT_BSTVOUT_ST_10P25V (15<< 0)
+#define AW8898_BIT_BSTVOUT_ST_10V (14<< 0)
+#define AW8898_BIT_BSTVOUT_ST_9P75V (13<< 0)
+#define AW8898_BIT_BSTVOUT_ST_9P5V (12<< 0)
+#define AW8898_BIT_BSTVOUT_ST_9P25V (11<< 0)
+#define AW8898_BIT_BSTVOUT_ST_9V (10<< 0)
+#define AW8898_BIT_BSTVOUT_ST_8P75V ( 9<< 0)
+#define AW8898_BIT_BSTVOUT_ST_8P5V ( 8<< 0)
+#define AW8898_BIT_BSTVOUT_ST_8P25V ( 7<< 0)
+#define AW8898_BIT_BSTVOUT_ST_8V ( 6<< 0)
+#define AW8898_BIT_BSTVOUT_ST_7P75V ( 5<< 0)
+#define AW8898_BIT_BSTVOUT_ST_7P5V ( 4<< 0)
+#define AW8898_BIT_BSTVOUT_ST_7P25V ( 3<< 0)
+#define AW8898_BIT_BSTVOUT_ST_7V ( 2<< 0)
+#define AW8898_BIT_BSTVOUT_ST_6P75V ( 1<< 0)
+#define AW8898_BIT_BSTVOUT_ST_6P5V ( 0<< 0)
+
+// DBGCTRL
+#define AW8898_BIT_DBGCTRL_LPBK_FAR_MASK (~( 1<<15))
+#define AW8898_BIT_DBGCTRL_LPBK_FAR_ENABLE ( 1<<15)
+#define AW8898_BIT_DBGCTRL_LPBK_FAR_DISABLE ( 0<<15)
+#define AW8898_BIT_DBGCTRL_LPBK_NEAR_MASK (~( 1<<14))
+#define AW8898_BIT_DBGCTRL_LPBK_NEAR_ENABLE ( 1<<14)
+#define AW8898_BIT_DBGCTRL_LPBK_NEAR_DISABLE ( 0<<14)
+#define AW8898_BIT_DBGCTRL_PDUVL_MASK (~( 1<<13))
+#define AW8898_BIT_DBGCTRL_PDUVL_DISABLE ( 1<<13)
+#define AW8898_BIT_DBGCTRL_PDUVL_ENABLE ( 0<<13)
+#define AW8898_BIT_DBGCTRL_MUTE_MASK (~( 1<<12))
+#define AW8898_BIT_DBGCTRL_MUTE_NO_AUTO ( 1<<12)
+#define AW8898_BIT_DBGCTRL_MUTE_AUTO ( 0<<12)
+#define AW8898_BIT_DBGCTRL_NOCLK_RESET_MASK (~( 1<<11))
+#define AW8898_BIT_DBGCTRL_NOCLK_NO_RESET ( 1<<11)
+#define AW8898_BIT_DBGCTRL_NOCLK_RESET ( 0<<11)
+#define AW8898_BIT_DBGCTRL_PLL_UNLOCK_RESET_MASK (~( 1<<10))
+#define AW8898_BIT_DBGCTRL_PLL_UNLOCK_NO_RESET ( 1<<10)
+#define AW8898_BIT_DBGCTRL_PLL_UNLOCK_RESET ( 0<<10)
+#define AW8898_BIT_DBGCTRL_CLKMD_MASK (~( 1<< 9))
+#define AW8898_BIT_DBGCTRL_CLKMD_HALF ( 1<< 9)
+#define AW8898_BIT_DBGCTRL_CLKMD_NORMAL ( 0<< 9)
+#define AW8898_BIT_DBGCTRL_OSCPD_MASK (~( 1<< 8))
+#define AW8898_BIT_DBGCTRL_OSCPD_ENABLE ( 1<< 8)
+#define AW8898_BIT_DBGCTRL_OSCPD_DISABLE ( 0<< 8)
+#define AW8898_BIT_DBGCTRL_AMPPD_MASK (~( 1<< 7))
+#define AW8898_BIT_DBGCTRL_AMPPD_PDN ( 1<< 7)
+#define AW8898_BIT_DBGCTRL_AMPPD_ACTIVE ( 0<< 7)
+#define AW8898_BIT_DBGCTRL_PLLPD_MASK (~( 1<< 6))
+#define AW8898_BIT_DBGCTRL_PLLPD_PDN ( 1<< 6)
+#define AW8898_BIT_DBGCTRL_PLLPD_ACTIVE ( 0<< 6)
+#define AW8898_BIT_DBGCTRL_I2SRST_MASK (~( 1<< 5))
+#define AW8898_BIT_DBGCTRL_I2SRST_RESET ( 1<< 5)
+#define AW8898_BIT_DBGCTRL_I2SRST_WORK ( 0<< 5)
+#define AW8898_BIT_DBGCTRL_SYSRST_MASK (~( 1<< 4))
+#define AW8898_BIT_DBGCTRL_SYSRST_RESET ( 1<< 4)
+#define AW8898_BIT_DBGCTRL_SYSRST_WORK ( 0<< 4)
+#define AW8898_BIT_DBGCTRL_SYSCE_MASK (~( 1<< 0))
+#define AW8898_BIT_DBGCTRL_SYSCE_ENABLE ( 1<< 0)
+#define AW8898_BIT_DBGCTRL_SYSCE_DISABLE ( 0<< 0)
+
+
+// I2SCFG
+#define AW8898_BIT_I2SCFG_I2SRX_MASK (~( 1<< 0))
+#define AW8898_BIT_I2SCFG_I2SRX_ENABLE ( 1<< 0)
+#define AW8898_BIT_I2SCFG_I2SRX_DISABLE ( 0<< 0)
+
+// I2SSAT
+#define AW8898_BIT_I2SSAT_DPSTAT ( 1<< 2)
+#define AW8898_BIT_I2SSAT_I2SROVS ( 1<< 1)
+#define AW8898_BIT_I2SSAT_I2STOVS ( 1<< 0)
+
+// GENCTRL
+#define AW8898_BIT_GENCTRL_BURST_PEAK_MASK (~( 3<<14))
+#define AW8898_BIT_GENCTRL_BURST_PEAK_200MA ( 3<<14)
+#define AW8898_BIT_GENCTRL_BURST_PEAK_160MA ( 2<<14)
+#define AW8898_BIT_GENCTRL_BURST_PEAK_100MA ( 1<<14)
+#define AW8898_BIT_GENCTRL_BURST_PEAK_130MA ( 0<<14)
+#define AW8898_BIT_GENCTRL_BST_TDEG2_MASK (~( 7<< 9))
+#define AW8898_BIT_GENCTRL_BST_TDEG2_2P7S ( 7<< 9)
+#define AW8898_BIT_GENCTRL_BST_TDEG2_1P3S ( 6<< 9)
+#define AW8898_BIT_GENCTRL_BST_TDEG2_672MS ( 5<< 9)
+#define AW8898_BIT_GENCTRL_BST_TDEG2_336MS ( 4<< 9)
+#define AW8898_BIT_GENCTRL_BST_TDEG2_168MS ( 3<< 9)
+#define AW8898_BIT_GENCTRL_BST_TDEG2_84MS ( 2<< 9)
+#define AW8898_BIT_GENCTRL_BST_TDEG2_42MS ( 1<< 9)
+#define AW8898_BIT_GENCTRL_BST_TDEG2_21MS ( 0<< 9)
+#define AW8898_BIT_GENCTRL_BST_OCAP_MASK (~( 1<< 8))
+#define AW8898_BIT_GENCTRL_BST_OCAP_SLOW ( 1<< 8)
+#define AW8898_BIT_GENCTRL_BST_OCAP_FAST ( 0<< 8)
+#define AW8898_BIT_GENCTRL_BST_EN_MASK (~( 1<< 7))
+#define AW8898_BIT_GENCTRL_BST_ENABLE ( 1<< 7)
+#define AW8898_BIT_GENCTRL_BST_DISABLE ( 0<< 7)
+#define AW8898_BIT_GENCTRL_BST_ILIMIT_MASK (~( 7<< 4))
+#define AW8898_BIT_GENCTRL_BST_ILIMIT_4P5A ( 7<< 4)
+#define AW8898_BIT_GENCTRL_BST_ILIMIT_4P25A ( 6<< 4)
+#define AW8898_BIT_GENCTRL_BST_ILIMIT_4A ( 5<< 4)
+#define AW8898_BIT_GENCTRL_BST_ILIMIT_3P75A ( 4<< 4)
+#define AW8898_BIT_GENCTRL_BST_ILIMIT_3P5A ( 3<< 4)
+#define AW8898_BIT_GENCTRL_BST_ILIMIT_3P25A ( 2<< 4)
+#define AW8898_BIT_GENCTRL_BST_ILIMIT_3A ( 1<< 4)
+#define AW8898_BIT_GENCTRL_BST_ILIMIT_2P75A ( 0<< 4)
+#define AW8898_BIT_GENCTRL_BST_VOUT_MASK (~(15<< 0))
+#define AW8898_BIT_GENCTRL_BST_VOUT_10P25V (15<< 0)
+#define AW8898_BIT_GENCTRL_BST_VOUT_10V (14<< 0)
+#define AW8898_BIT_GENCTRL_BST_VOUT_9P75V (13<< 0)
+#define AW8898_BIT_GENCTRL_BST_VOUT_9P5V (12<< 0)
+#define AW8898_BIT_GENCTRL_BST_VOUT_9P25V (11<< 0)
+#define AW8898_BIT_GENCTRL_BST_VOUT_9V (10<< 0)
+#define AW8898_BIT_GENCTRL_BST_VOUT_8P75V ( 9<< 0)
+#define AW8898_BIT_GENCTRL_BST_VOUT_8P5V ( 8<< 0)
+#define AW8898_BIT_GENCTRL_BST_VOUT_8P25V ( 7<< 0)
+#define AW8898_BIT_GENCTRL_BST_VOUT_8V ( 6<< 0)
+#define AW8898_BIT_GENCTRL_BST_VOUT_7P75V ( 5<< 0)
+#define AW8898_BIT_GENCTRL_BST_VOUT_7P5V ( 4<< 0)
+#define AW8898_BIT_GENCTRL_BST_VOUT_7P25V ( 3<< 0)
+#define AW8898_BIT_GENCTRL_BST_VOUT_7V ( 2<< 0)
+#define AW8898_BIT_GENCTRL_BST_VOUT_6P75V ( 1<< 0)
+#define AW8898_BIT_GENCTRL_BST_VOUT_6P5V ( 0<< 0)
+
+// BSTCTRL1
+#define AW8898_BIT_BSTCTRL1_RTH_MASK (~(64<< 8))
+#define AW8898_BIT_BSTCTRL1_ATH_MASK (~(64<< 0))
+
+// BSTCTRL2
+#define AW8898_BIT_BST_MODE_MASK (~( 7<< 3))
+#define AW8898_BIT_BST_MODE_SMART_BOOST ( 6<< 3)
+#define AW8898_BIT_BST_MODE_ADAPT_BOOST ( 5<< 3)
+#define AW8898_BIT_BST_MODE_FORCE_BOOST ( 1<< 3)
+#define AW8898_BIT_BST_MODE_TRANSP_BOOST ( 0<< 3)
+#define AW8898_BIT_BST_TDEG_MASK (~( 7<< 0))
+#define AW8898_BIT_BST_TDEG_2P7S ( 7<< 0)
+#define AW8898_BIT_BST_TDEG_1P3S ( 6<< 0)
+#define AW8898_BIT_BST_TDEG_672MS ( 5<< 0)
+#define AW8898_BIT_BST_TDEG_336MS ( 4<< 0)
+#define AW8898_BIT_BST_TDEG_168MS ( 3<< 0)
+#define AW8898_BIT_BST_TDEG_84MS ( 2<< 0)
+#define AW8898_BIT_BST_TDEG_42MS ( 1<< 0)
+#define AW8898_BIT_BST_TDEG_21MS ( 0<< 0)
+
+#endif
diff --git a/sound/soc/codecs/tas2557/Kconfig b/sound/soc/codecs/tas2557/Kconfig
new file mode 100755
index 0000000..acbdfcb
--- /dev/null
+++ b/sound/soc/codecs/tas2557/Kconfig
@@ -0,0 +1,15 @@
+
+menuconfig SND_SOC_TAS2557
+ tristate "Texas Instruments TAS2557 SmartAmp(R)"
+
+if SND_SOC_TAS2557
+config TAS2557_REGMAP
+ bool "Use of RegMap API"
+
+config TAS2557_CODEC
+ bool "Codec Driver support"
+
+config TAS2557_MISC
+ bool "Misc Driver support"
+
+endif # SND_SOC_TAS2557
diff --git a/sound/soc/codecs/tas2557/Makefile b/sound/soc/codecs/tas2557/Makefile
new file mode 100755
index 0000000..1287372
--- /dev/null
+++ b/sound/soc/codecs/tas2557/Makefile
@@ -0,0 +1,2 @@
+snd-soc-tas2557-objs := tas2557-core.o tas2557-regmap.o tas2557-codec.o tas2557-misc.o tiload.o
+obj-$(CONFIG_SND_SOC_TAS2557) += snd-soc-tas2557.o
diff --git a/sound/soc/codecs/tas2557/tas2557-codec.c b/sound/soc/codecs/tas2557/tas2557-codec.c
new file mode 100755
index 0000000..cf9c419
--- /dev/null
+++ b/sound/soc/codecs/tas2557/tas2557-codec.c
@@ -0,0 +1,634 @@
+/*
+** =============================================================================
+** Copyright (c) 2016 Texas Instruments Inc.
+**
+** This program is free software; you can redistribute it and/or modify it under
+** the terms of the GNU General Public License as published by the Free Software
+** Foundation; version 2.
+**
+** This program is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+**
+** File:
+** tas2557-codec.c
+**
+** Description:
+** ALSA SoC driver for Texas Instruments TAS2557 High Performance 4W Smart Amplifier
+**
+** =============================================================================
+*/
+
+#ifdef CONFIG_TAS2557_CODEC
+
+#define DEBUG
+#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/gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/firmware.h>
+#include <linux/regmap.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/slab.h>
+#include <linux/syscalls.h>
+#include <linux/fcntl.h>
+#include <linux/uaccess.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 "tas2557-core.h"
+#include "tas2557-codec.h"
+
+#define KCONTROL_CODEC
+
+static unsigned int tas2557_codec_read(struct snd_soc_codec *pCodec,
+ unsigned int nRegister)
+{
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec);
+ int ret = 0;
+ unsigned int Value = 0;
+
+ mutex_lock(&pTAS2557->codec_lock);
+
+ ret = pTAS2557->read(pTAS2557, nRegister, &Value);
+ if (ret < 0)
+ dev_err(pTAS2557->dev, "%s, %d, ERROR happen=%d\n", __func__,
+ __LINE__, ret);
+ else
+ ret = Value;
+
+ mutex_unlock(&pTAS2557->codec_lock);
+ return ret;
+}
+
+static int tas2557_codec_write(struct snd_soc_codec *pCodec, unsigned int nRegister,
+ unsigned int nValue)
+{
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec);
+ int ret = 0;
+
+ mutex_lock(&pTAS2557->codec_lock);
+
+ ret = pTAS2557->write(pTAS2557, nRegister, nValue);
+
+ mutex_unlock(&pTAS2557->codec_lock);
+ return ret;
+}
+
+static int tas2557_codec_suspend(struct snd_soc_codec *pCodec)
+{
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec);
+ int ret = 0;
+
+ mutex_lock(&pTAS2557->codec_lock);
+
+ dev_dbg(pTAS2557->dev, "%s\n", __func__);
+ pTAS2557->runtime_suspend(pTAS2557);
+
+ mutex_unlock(&pTAS2557->codec_lock);
+ return ret;
+}
+
+static int tas2557_codec_resume(struct snd_soc_codec *pCodec)
+{
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec);
+ int ret = 0;
+
+ mutex_lock(&pTAS2557->codec_lock);
+
+ dev_dbg(pTAS2557->dev, "%s\n", __func__);
+ pTAS2557->runtime_resume(pTAS2557);
+
+ mutex_unlock(&pTAS2557->codec_lock);
+ return ret;
+}
+
+static const struct snd_soc_dapm_widget tas2557_dapm_widgets[] = {
+ SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("ASI2", "ASI2 Playback", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("ASIM", "ASIM Playback", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0),
+
+ SND_SOC_DAPM_OUT_DRV("ClassD", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_SUPPLY("PLL", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("NDivider", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_OUTPUT("OUT")
+};
+
+static const struct snd_soc_dapm_route tas2557_audio_map[] = {
+ {"DAC", NULL, "ASI1"},
+ {"DAC", NULL, "ASI2"},
+ {"DAC", NULL, "ASIM"},
+ {"ClassD", NULL, "DAC"},
+ {"OUT", NULL, "ClassD"},
+ {"DAC", NULL, "PLL"},
+ {"DAC", NULL, "NDivider"},
+};
+
+static int tas2557_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
+
+ dev_dbg(pTAS2557->dev, "%s\n", __func__);
+ return 0;
+}
+
+static void tas2557_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
+
+ dev_dbg(pTAS2557->dev, "%s\n", __func__);
+}
+
+static int tas2557_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
+
+ mutex_lock(&pTAS2557->codec_lock);
+
+ dev_dbg(pTAS2557->dev, "%s\n", __func__);
+ tas2557_enable(pTAS2557, !mute);
+
+ mutex_unlock(&pTAS2557->codec_lock);
+ return 0;
+}
+
+static int tas2557_set_dai_sysclk(struct snd_soc_dai *pDAI,
+ int nClkID, unsigned int nFreqency, int nDir)
+{
+ struct snd_soc_codec *pCodec = pDAI->codec;
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec);
+
+ dev_dbg(pTAS2557->dev, "tas2557_set_dai_sysclk: freq = %u\n", nFreqency);
+
+ return 0;
+}
+
+static int tas2557_hw_params(struct snd_pcm_substream *pSubstream,
+ struct snd_pcm_hw_params *pParams, struct snd_soc_dai *pDAI)
+{
+ struct snd_soc_codec *pCodec = pDAI->codec;
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec);
+
+ mutex_lock(&pTAS2557->codec_lock);
+
+ dev_dbg(pTAS2557->dev, "%s\n", __func__);
+/* do bit rate setting during platform data */
+/* tas2557_set_bit_rate(pTAS2557, channel_both, snd_pcm_format_width(params_format(pParams))); */
+ tas2557_set_sampling_rate(pTAS2557, params_rate(pParams));
+
+ mutex_unlock(&pTAS2557->codec_lock);
+ return 0;
+}
+
+static int tas2557_set_dai_fmt(struct snd_soc_dai *pDAI, unsigned int nFormat)
+{
+ struct snd_soc_codec *codec = pDAI->codec;
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
+
+ dev_dbg(pTAS2557->dev, "%s\n", __func__);
+ return 0;
+}
+
+static int tas2557_prepare(struct snd_pcm_substream *pSubstream,
+ struct snd_soc_dai *pDAI)
+{
+ struct snd_soc_codec *codec = pDAI->codec;
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
+
+ dev_dbg(pTAS2557->dev, "%s\n", __func__);
+ return 0;
+}
+
+static int tas2557_set_bias_level(struct snd_soc_codec *pCodec,
+ enum snd_soc_bias_level eLevel)
+{
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec);
+
+ dev_dbg(pTAS2557->dev, "%s: %d\n", __func__, eLevel);
+ return 0;
+}
+
+static int tas2557_codec_probe(struct snd_soc_codec *pCodec)
+{
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec);
+
+ dev_dbg(pTAS2557->dev, "%s\n", __func__);
+ return 0;
+}
+
+static int tas2557_codec_remove(struct snd_soc_codec *pCodec)
+{
+ return 0;
+}
+
+static int tas2557_power_ctrl_get(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pValue)
+{
+#ifdef KCONTROL_CODEC
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
+#else
+ struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
+#endif
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
+
+ mutex_lock(&pTAS2557->codec_lock);
+
+ pValue->value.integer.value[0] = pTAS2557->mbPowerUp;
+ dev_dbg(pTAS2557->dev, "tas2557_power_ctrl_get = %d\n",
+ pTAS2557->mbPowerUp);
+
+ mutex_unlock(&pTAS2557->codec_lock);
+ return 0;
+}
+
+static int tas2557_power_ctrl_put(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pValue)
+{
+#ifdef KCONTROL_CODEC
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
+#else
+ struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
+#endif
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
+
+ int nPowerOn = pValue->value.integer.value[0];
+
+ mutex_lock(&pTAS2557->codec_lock);
+
+ dev_dbg(pTAS2557->dev, "tas2557_power_ctrl_put = %d\n", nPowerOn);
+ tas2557_enable(pTAS2557, (nPowerOn != 0));
+
+ mutex_unlock(&pTAS2557->codec_lock);
+ return 0;
+}
+
+static int tas2557_fs_get(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pValue)
+{
+#ifdef KCONTROL_CODEC
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
+#else
+ struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
+#endif
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
+ int nFS = 48000;
+
+ mutex_lock(&pTAS2557->codec_lock);
+
+ if (pTAS2557->mpFirmware->mnConfigurations)
+ nFS = pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration].mnSamplingRate;
+ pValue->value.integer.value[0] = nFS;
+ dev_dbg(pTAS2557->dev, "tas2557_fs_get = %d\n", nFS);
+
+ mutex_unlock(&pTAS2557->codec_lock);
+ return 0;
+}
+
+static int tas2557_fs_put(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pValue)
+{
+#ifdef KCONTROL_CODEC
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
+#else
+ struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
+#endif
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
+ int nFS = pValue->value.integer.value[0];
+
+ mutex_lock(&pTAS2557->codec_lock);
+
+ dev_info(pTAS2557->dev, "tas2557_fs_put = %d\n", nFS);
+ ret = tas2557_set_sampling_rate(pTAS2557, nFS);
+
+ mutex_unlock(&pTAS2557->codec_lock);
+ return ret;
+}
+
+static int tas2557_Cali_get(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pValue)
+{
+#ifdef KCONTROL_CODEC
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
+#else
+ struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
+#endif
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
+ bool ret = 0;
+ int prm_r0 = 0;
+
+ mutex_lock(&pTAS2557->codec_lock);
+
+ ret = tas2557_get_Cali_prm_r0(pTAS2557, &prm_r0);
+ if (ret)
+ pValue->value.integer.value[0] = prm_r0;
+
+
+ mutex_unlock(&pTAS2557->codec_lock);
+ return 0;
+}
+
+static int tas2557_program_get(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pValue)
+{
+#ifdef KCONTROL_CODEC
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
+#else
+ struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
+#endif
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
+
+ mutex_lock(&pTAS2557->codec_lock);
+
+ pValue->value.integer.value[0] = pTAS2557->mnCurrentProgram;
+ dev_dbg(pTAS2557->dev, "tas2557_program_get = %d\n",
+ pTAS2557->mnCurrentProgram);
+
+ mutex_unlock(&pTAS2557->codec_lock);
+ return 0;
+}
+
+static int tas2557_program_put(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pValue)
+{
+#ifdef KCONTROL_CODEC
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
+#else
+ struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
+#endif
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
+ unsigned int nProgram = pValue->value.integer.value[0];
+ int ret = 0, nConfiguration = -1;
+
+ mutex_lock(&pTAS2557->codec_lock);
+
+ if (nProgram == pTAS2557->mnCurrentProgram)
+ nConfiguration = pTAS2557->mnCurrentConfiguration;
+ ret = tas2557_set_program(pTAS2557, nProgram, nConfiguration);
+
+ mutex_unlock(&pTAS2557->codec_lock);
+ return ret;
+}
+
+static int tas2557_configuration_get(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pValue)
+{
+#ifdef KCONTROL_CODEC
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
+#else
+ struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
+#endif
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
+
+ mutex_lock(&pTAS2557->codec_lock);
+
+ pValue->value.integer.value[0] = pTAS2557->mnCurrentConfiguration;
+ dev_dbg(pTAS2557->dev, "tas2557_configuration_get = %d\n",
+ pTAS2557->mnCurrentConfiguration);
+
+ mutex_unlock(&pTAS2557->codec_lock);
+ return 0;
+}
+
+static int tas2557_configuration_put(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pValue)
+{
+#ifdef KCONTROL_CODEC
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
+#else
+ struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
+#endif
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
+ unsigned int nConfiguration = pValue->value.integer.value[0];
+ int ret = 0;
+
+ mutex_lock(&pTAS2557->codec_lock);
+
+ dev_info(pTAS2557->dev, "%s = %d\n", __func__, nConfiguration);
+ ret = tas2557_set_config(pTAS2557, nConfiguration);
+
+ mutex_unlock(&pTAS2557->codec_lock);
+ return ret;
+}
+
+static int tas2557_calibration_get(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pValue)
+{
+#ifdef KCONTROL_CODEC
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
+#else
+ struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
+#endif
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
+
+ mutex_lock(&pTAS2557->codec_lock);
+
+ pValue->value.integer.value[0] = pTAS2557->mnCurrentCalibration;
+ dev_info(pTAS2557->dev,
+ "tas2557_calibration_get = %d\n",
+ pTAS2557->mnCurrentCalibration);
+
+ mutex_unlock(&pTAS2557->codec_lock);
+ return 0;
+}
+
+static int tas2557_calibration_put(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pValue)
+{
+#ifdef KCONTROL_CODEC
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
+#else
+ struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
+#endif
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
+ unsigned int nCalibration = pValue->value.integer.value[0];
+ int ret = 0;
+
+ mutex_lock(&pTAS2557->codec_lock);
+
+ ret = tas2557_set_calibration(pTAS2557, nCalibration);
+
+ mutex_unlock(&pTAS2557->codec_lock);
+ return ret;
+}
+
+static const char * const classd_edge_text[] = {
+ "0 (50ns)",
+ "1 (40ns)",
+ "2 (29ns)",
+ "3 (25ns)",
+ "4 (14ns)",
+ "5 (13ns)",
+ "6 (12ns)",
+ "7 (11ns)",
+};
+
+static const struct soc_enum classd_edge_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(classd_edge_text), classd_edge_text),
+};
+
+static int tas2557_edge_get(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pValue)
+{
+#ifdef KCONTROL_CODEC
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
+#else
+ struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
+#endif
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
+ mutex_lock(&pTAS2557->codec_lock);
+
+ pValue->value.integer.value[0] = pTAS2557->mnEdge;
+
+ mutex_unlock(&pTAS2557->codec_lock);
+ return 0;
+}
+static int tas2557_edge_put(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pValue)
+{
+#ifdef KCONTROL_CODEC
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
+#else
+ struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
+#endif
+ struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
+ unsigned int edge = pValue->value.integer.value[0];
+
+ mutex_lock(&pTAS2557->codec_lock);
+
+ dev_dbg(pTAS2557->dev, "%s, edge %d\n", __func__, edge);
+ pTAS2557->mnEdge = pValue->value.integer.value[0];
+ tas2557_update_edge(pTAS2557);
+
+ mutex_unlock(&pTAS2557->codec_lock);
+ return 0;
+}
+
+static const struct snd_kcontrol_new tas2557_snd_controls[] = {
+ SOC_SINGLE_EXT("PowerCtrl", SND_SOC_NOPM, 0, 0x0001, 0,
+ tas2557_power_ctrl_get, tas2557_power_ctrl_put),
+ SOC_SINGLE_EXT("Program", SND_SOC_NOPM, 0, 0x00FF, 0, tas2557_program_get,
+ tas2557_program_put),
+ SOC_SINGLE_EXT("Configuration", SND_SOC_NOPM, 0, 0x00FF, 0,
+ tas2557_configuration_get, tas2557_configuration_put),
+ SOC_SINGLE_EXT("FS", SND_SOC_NOPM, 8000, 48000, 0,
+ tas2557_fs_get, tas2557_fs_put),
+ SOC_SINGLE_EXT("Get Cali_Re", SND_SOC_NOPM, 0, 0x7f000000, 0,
+ tas2557_Cali_get, NULL),
+ SOC_SINGLE_EXT("Calibration", SND_SOC_NOPM, 0, 0x00FF, 0,
+ tas2557_calibration_get, tas2557_calibration_put),
+ SOC_ENUM_EXT("TAS2557 ClassD Edge", classd_edge_enum[0],
+ tas2557_edge_get, tas2557_edge_put),
+};
+
+static struct snd_soc_codec_driver soc_codec_driver_tas2557 = {
+ .probe = tas2557_codec_probe,
+ .remove = tas2557_codec_remove,
+ .read = tas2557_codec_read,
+ .write = tas2557_codec_write,
+ .suspend = tas2557_codec_suspend,
+ .resume = tas2557_codec_resume,
+ .set_bias_level = tas2557_set_bias_level,
+ .idle_bias_off = true,
+ .component_driver = {
+ .controls = tas2557_snd_controls,
+ .num_controls = ARRAY_SIZE(tas2557_snd_controls),
+ .dapm_widgets = tas2557_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(tas2557_dapm_widgets),
+ .dapm_routes = tas2557_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(tas2557_audio_map),
+ },
+};
+
+static struct snd_soc_dai_ops tas2557_dai_ops = {
+ .startup = tas2557_startup,
+ .shutdown = tas2557_shutdown,
+ .digital_mute = tas2557_mute,
+ .hw_params = tas2557_hw_params,
+ .prepare = tas2557_prepare,
+ .set_sysclk = tas2557_set_dai_sysclk,
+ .set_fmt = tas2557_set_dai_fmt,
+};
+
+#define TAS2557_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+static struct snd_soc_dai_driver tas2557_dai_driver[] = {
+ {
+ .name = "tas2557 ASI1",
+ .id = 0,
+ .playback = {
+ .stream_name = "ASI1 Playback",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_192000,
+ .formats = TAS2557_FORMATS,
+ },
+ .ops = &tas2557_dai_ops,
+ .symmetric_rates = 1,
+ },
+ {
+ .name = "tas2557 ASI2",
+ .id = 1,
+ .playback = {
+ .stream_name = "ASI2 Playback",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_192000,
+ .formats = TAS2557_FORMATS,
+ },
+ .ops = &tas2557_dai_ops,
+ .symmetric_rates = 1,
+ },
+ {
+ .name = "tas2557 ASIM",
+ .id = 2,
+ .playback = {
+ .stream_name = "ASIM Playback",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_192000,
+ .formats = TAS2557_FORMATS,
+ },
+ .ops = &tas2557_dai_ops,
+ .symmetric_rates = 1,
+ },
+};
+
+int tas2557_register_codec(struct tas2557_priv *pTAS2557)
+{
+ int nResult = 0;
+
+ dev_info(pTAS2557->dev, "%s, enter\n", __func__);
+ nResult = snd_soc_register_codec(pTAS2557->dev,
+ &soc_codec_driver_tas2557,
+ tas2557_dai_driver, ARRAY_SIZE(tas2557_dai_driver));
+ return nResult;
+}
+
+int tas2557_deregister_codec(struct tas2557_priv *pTAS2557)
+{
+ snd_soc_unregister_codec(pTAS2557->dev);
+ return 0;
+}
+
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_DESCRIPTION("TAS2557 ALSA SOC Smart Amplifier driver");
+MODULE_LICENSE("GPL v2");
+#endif
diff --git a/sound/soc/codecs/tas2557/tas2557-codec.h b/sound/soc/codecs/tas2557/tas2557-codec.h
new file mode 100755
index 0000000..8e20270
--- /dev/null
+++ b/sound/soc/codecs/tas2557/tas2557-codec.h
@@ -0,0 +1,30 @@
+/*
+** =============================================================================
+** Copyright (c) 2016 Texas Instruments Inc.
+**
+** This program is free software; you can redistribute it and/or modify it under
+** the terms of the GNU General Public License as published by the Free Software
+** Foundation; version 2.
+**
+** This program is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+**
+** File:
+** tas2557-codec.h
+**
+** Description:
+** header file for tas2557-codec.c
+**
+** =============================================================================
+*/
+
+#ifndef _TAS2557_CODEC_H
+#define _TAS2557_CODEC_H
+
+#include "tas2557.h"
+
+int tas2557_register_codec(struct tas2557_priv *pTAS2557);
+int tas2557_deregister_codec(struct tas2557_priv *pTAS2557);
+
+#endif /* _TAS2557_CODEC_H */
diff --git a/sound/soc/codecs/tas2557/tas2557-core.c b/sound/soc/codecs/tas2557/tas2557-core.c
new file mode 100755
index 0000000..c5349d38
--- /dev/null
+++ b/sound/soc/codecs/tas2557/tas2557-core.c
@@ -0,0 +1,2117 @@
+/*
+** =============================================================================
+** Copyright (c) 2016 Texas Instruments Inc.
+**
+** This program is free software; you can redistribute it and/or modify it under
+** the terms of the GNU General Public License as published by the Free Software
+** Foundation; version 2.
+**
+** This program is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+**
+** File:
+** tas2557-core.c
+**
+** Description:
+** TAS2557 common functions for Android Linux
+**
+** =============================================================================
+*/
+
+#define DEBUG
+#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/gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/firmware.h>
+#include <linux/regmap.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/slab.h>
+#include <linux/syscalls.h>
+#include <linux/fcntl.h>
+#include <linux/uaccess.h>
+#include <linux/crc8.h>
+
+#include "tas2557.h"
+#include "tas2557-core.h"
+
+#define PPC_DRIVER_CRCCHK 0x00000200
+#define PPC_DRIVER_CONFDEV 0x00000300
+#define PPC_DRIVER_MTPLLSRC 0x00000400
+#define PPC_DRIVER_CFGDEV_NONCRC 0x00000101
+
+#define TAS2557_CAL_NAME "/mnt/vendor/persist/tas2557_cal.bin"
+#define RESTART_MAX 3
+
+static int tas2557_load_calibration(struct tas2557_priv *pTAS2557,
+ char *pFileName);
+static int tas2557_load_data(struct tas2557_priv *pTAS2557, struct TData *pData,
+ unsigned int nType);
+static void tas2557_clear_firmware(struct TFirmware *pFirmware);
+static int tas2557_load_block(struct tas2557_priv *pTAS2557, struct TBlock *pBlock);
+static int tas2557_load_configuration(struct tas2557_priv *pTAS2557,
+ unsigned int nConfiguration, bool bLoadSame);
+
+#define TAS2557_UDELAY 0xFFFFFFFE
+#define TAS2557_MDELAY 0xFFFFFFFD
+
+#define TAS2557_BLOCK_PLL 0x00
+#define TAS2557_BLOCK_PGM_ALL 0x0d
+#define TAS2557_BLOCK_PGM_DEV_A 0x01
+#define TAS2557_BLOCK_PGM_DEV_B 0x08
+#define TAS2557_BLOCK_CFG_COEFF_DEV_A 0x03
+#define TAS2557_BLOCK_CFG_COEFF_DEV_B 0x0a
+#define TAS2557_BLOCK_CFG_PRE_DEV_A 0x04
+#define TAS2557_BLOCK_CFG_PRE_DEV_B 0x0b
+#define TAS2557_BLOCK_CFG_POST 0x05
+#define TAS2557_BLOCK_CFG_POST_POWER 0x06
+
+static unsigned int p_tas2557_default_data[] = {
+ TAS2557_SAR_ADC2_REG, 0x05, /* enable SAR ADC */
+ TAS2557_CLK_ERR_CTRL2, 0x21, /*clk1:clock hysteresis, 0.34ms; clock halt, 22ms*/
+ TAS2557_CLK_ERR_CTRL3, 0x21, /*clk2: rampDown 15dB/us, clock hysteresis, 10.66us; clock halt, 22ms */
+ TAS2557_SAFE_GUARD_REG, TAS2557_SAFE_GUARD_PATTERN, /* safe guard */
+ 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+static unsigned int p_tas2557_irq_config[] = {
+ TAS2557_CLK_HALT_REG, 0x71, /* enable clk halt detect2 interrupt */
+ TAS2557_INT_GEN1_REG, 0x11, /* enable spk OC and OV */
+ TAS2557_INT_GEN2_REG, 0x11, /* enable clk err1 and die OT */
+ TAS2557_INT_GEN3_REG, 0x11, /* enable clk err2 and brownout */
+ TAS2557_INT_GEN4_REG, 0x01, /* disable SAR, enable clk halt */
+ TAS2557_GPIO4_PIN_REG, 0x07, /* set GPIO4 as int1, default */
+ TAS2557_INT_MODE_REG, 0x80, /* active high until INT_STICKY_1 and INT_STICKY_2 are read to be cleared. */
+ 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+static unsigned int p_tas2557_startup_data[] = {
+ TAS2557_GPI_PIN_REG, 0x15, /* enable DIN, MCLK, CCI */
+ TAS2557_GPIO1_PIN_REG, 0x01, /* enable BCLK */
+ TAS2557_GPIO2_PIN_REG, 0x01, /* enable WCLK */
+ TAS2557_POWER_CTRL2_REG, 0xA0, /* Class-D, Boost power up */
+ TAS2557_POWER_CTRL2_REG, 0xA3, /* Class-D, Boost, IV sense power up */
+ TAS2557_POWER_CTRL1_REG, 0xF8, /* PLL, DSP, clock dividers power up */
+ TAS2557_UDELAY, 2000, /* delay */
+ TAS2557_CLK_ERR_CTRL, 0x2b, /* enable clock error detection */
+ 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+static unsigned int p_tas2557_unmute_data[] = {
+ TAS2557_MUTE_REG, 0x00, /* unmute */
+ TAS2557_SOFT_MUTE_REG, 0x00, /* soft unmute */
+ 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+static unsigned int p_tas2557_shutdown_data[] = {
+ TAS2557_CLK_ERR_CTRL, 0x00, /* disable clock error detection */
+ TAS2557_SOFT_MUTE_REG, 0x01, /* soft mute */
+ TAS2557_UDELAY, 10000, /* delay 10ms */
+ TAS2557_MUTE_REG, 0x03, /* mute */
+ TAS2557_POWER_CTRL1_REG, 0x60, /* DSP power down */
+ TAS2557_UDELAY, 2000, /* delay 2ms */
+ TAS2557_POWER_CTRL2_REG, 0x00, /* Class-D, Boost power down */
+ TAS2557_POWER_CTRL1_REG, 0x00, /* all power down */
+ TAS2557_GPIO1_PIN_REG, 0x00, /* disable BCLK */
+ TAS2557_GPIO2_PIN_REG, 0x00, /* disable WCLK */
+ TAS2557_GPI_PIN_REG, 0x00, /* disable DIN, MCLK, CCI */
+ 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+static int tas2557_dev_load_data(struct tas2557_priv *pTAS2557,
+ unsigned int *pData)
+{
+ int ret = 0;
+ unsigned int n = 0;
+ unsigned int nRegister;
+ unsigned int nData;
+
+ do {
+ nRegister = pData[n * 2];
+ nData = pData[n * 2 + 1];
+ if (nRegister == TAS2557_UDELAY)
+ udelay(nData);
+ else if (nRegister != 0xFFFFFFFF) {
+ ret = pTAS2557->write(pTAS2557, nRegister, nData);
+ if (ret < 0)
+ break;
+ }
+ n++;
+ } while (nRegister != 0xFFFFFFFF);
+ return ret;
+}
+
+int tas2557_configIRQ(struct tas2557_priv *pTAS2557)
+{
+ return tas2557_dev_load_data(pTAS2557, p_tas2557_irq_config);
+}
+
+int tas2557_set_bit_rate(struct tas2557_priv *pTAS2557, unsigned int nBitRate)
+{
+ int ret = 0, n = -1;
+
+ dev_dbg(pTAS2557->dev, "tas2557_set_bit_rate: nBitRate = %d\n", nBitRate);
+
+ switch (nBitRate) {
+ case 16:
+ n = 0;
+ break;
+ case 20:
+ n = 1;
+ break;
+ case 24:
+ n = 2;
+ break;
+ case 32:
+ n = 3;
+ break;
+ }
+
+ if (n >= 0)
+ ret = pTAS2557->update_bits(pTAS2557, TAS2557_ASI1_DAC_FORMAT_REG, 0x18, n<<3);
+ return ret;
+}
+
+int tas2557_get_bit_rate(struct tas2557_priv *pTAS2557, unsigned char *pBitRate)
+{
+ int ret = 0;
+ unsigned int nValue = 0;
+ unsigned char bitRate;
+
+ ret = pTAS2557->read(pTAS2557, TAS2557_ASI1_DAC_FORMAT_REG, &nValue);
+ if (ret >= 0) {
+ bitRate = (nValue&0x18)>>3;
+ if (bitRate == 0)
+ bitRate = 16;
+ else if (bitRate == 1)
+ bitRate = 20;
+ else if (bitRate == 2)
+ bitRate = 24;
+ else if (bitRate == 3)
+ bitRate = 32;
+ *pBitRate = bitRate;
+ }
+
+ return ret;
+}
+
+int tas2557_get_DAC_gain(struct tas2557_priv *pTAS2557, unsigned char *pnGain)
+{
+ int ret = 0;
+ unsigned int nValue = 0;
+
+ ret = pTAS2557->read(pTAS2557, TAS2557_SPK_CTRL_REG, &nValue);
+ if (ret >= 0)
+ *pnGain = ((nValue&TAS2557_DAC_GAIN_MASK)>>TAS2557_DAC_GAIN_SHIFT);
+
+ return ret;
+}
+
+int tas2557_set_DAC_gain(struct tas2557_priv *pTAS2557, unsigned int nGain)
+{
+ int ret = 0;
+
+ ret = pTAS2557->update_bits(pTAS2557, TAS2557_SPK_CTRL_REG, TAS2557_DAC_GAIN_MASK,
+ (nGain<<TAS2557_DAC_GAIN_SHIFT));
+ return ret;
+}
+
+/*
+* die temperature calculation:
+* DieTemp = readout / 2^23
+*/
+int tas2557_get_die_temperature(struct tas2557_priv *pTAS2557, int *pTemperature)
+{
+ int nResult = 0;
+ unsigned char nBuf[4];
+ int temp;
+
+ if (!pTAS2557->mpFirmware->mnConfigurations) {
+ dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__);
+ goto end;
+ }
+
+ if (!pTAS2557->mbPowerUp) {
+ dev_err(pTAS2557->dev, "%s, device not powered on\n", __func__);
+ goto end;
+ }
+
+ nResult = pTAS2557->bulk_read(pTAS2557, TAS2557_DIE_TEMP_REG, nBuf, 4);
+ if (nResult >= 0) {
+ temp = ((int)nBuf[0] << 24) | ((int)nBuf[1] << 16) | ((int)nBuf[2] << 8) | nBuf[3];
+ *pTemperature = temp;
+ }
+
+end:
+
+ return nResult;
+}
+
+int tas2557_load_platdata(struct tas2557_priv *pTAS2557)
+{
+ int nResult = 0;
+
+ if (gpio_is_valid(pTAS2557->mnGpioINT)) {
+ nResult = tas2557_configIRQ(pTAS2557);
+ if (nResult < 0)
+ goto end;
+ }
+
+ nResult = tas2557_set_bit_rate(pTAS2557, pTAS2557->mnI2SBits);
+
+end:
+
+ return nResult;
+}
+
+int tas2557_load_default(struct tas2557_priv *pTAS2557)
+{
+ int nResult = 0;
+
+ nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_default_data);
+ if (nResult < 0)
+ goto end;
+
+ nResult = tas2557_load_platdata(pTAS2557);
+ if (nResult < 0)
+ goto end;
+
+ /* enable DOUT tri-state for extra BCLKs */
+ nResult = pTAS2557->update_bits(pTAS2557, TAS2557_ASI1_DAC_FORMAT_REG, 0x01, 0x01);
+end:
+
+ return nResult;
+}
+
+static void failsafe(struct tas2557_priv *pTAS2557)
+{
+ int ret;
+
+ dev_err(pTAS2557->dev, "%s\n", __func__);
+ pTAS2557->mnErrCode |= ERROR_FAILSAFE;
+ if (hrtimer_active(&pTAS2557->mtimer))
+ hrtimer_cancel(&pTAS2557->mtimer);
+
+ if(pTAS2557->mnRestart < RESTART_MAX)
+ {
+ pTAS2557->mnRestart ++;
+ msleep(100);
+ dev_err(pTAS2557->dev, "I2C COMM error, restart SmartAmp.\n");
+ schedule_delayed_work(&pTAS2557->irq_work, msecs_to_jiffies(100));
+ return;
+ }
+ pTAS2557->enableIRQ(pTAS2557, false, false);
+ ret = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
+ if (ret < 0)
+ dev_dbg(pTAS2557->dev, "failed load shutdown\n");
+
+ pTAS2557->mbPowerUp = false;
+ pTAS2557->hw_reset(pTAS2557);
+ ret = pTAS2557->write(pTAS2557, TAS2557_SW_RESET_REG, 0x01);
+ if (ret < 0)
+ dev_dbg(pTAS2557->dev, "failed sw reset\n");
+
+ udelay(1000);
+ ret = pTAS2557->write(pTAS2557, TAS2557_SPK_CTRL_REG, 0x04);
+ if (ret < 0)
+ dev_dbg(pTAS2557->dev, "failed in spk ctrl\n");
+ if (pTAS2557->mpFirmware != NULL)
+ tas2557_clear_firmware(pTAS2557->mpFirmware);
+
+ pTAS2557->mpFirmware->mnPrograms = 0;
+}
+
+int tas2557_checkPLL(struct tas2557_priv *pTAS2557)
+{
+ int nResult = 0;
+/*
+* TO DO
+*/
+
+ return nResult;
+}
+
+/*
+* tas2557_load_coefficient
+*/
+static int tas2557_load_coefficient(struct tas2557_priv *pTAS2557,
+ int nPrevConfig, int nNewConfig, bool bPowerOn)
+{
+ int nResult = 0;
+ struct TPLL *pPLL;
+ struct TProgram *pProgram;
+ struct TConfiguration *pPrevConfiguration;
+ struct TConfiguration *pNewConfiguration;
+ bool bRestorePower = false;
+
+ if (!pTAS2557->mpFirmware->mnConfigurations) {
+ dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__);
+ goto end;
+ }
+
+ if (nNewConfig >= pTAS2557->mpFirmware->mnConfigurations) {
+ dev_err(pTAS2557->dev, "%s, invalid configuration New=%d, total=%d\n",
+ __func__, nNewConfig, pTAS2557->mpFirmware->mnConfigurations);
+ goto end;
+ }
+
+ if (nPrevConfig < 0)
+ pPrevConfiguration = NULL;
+ else if (nPrevConfig == nNewConfig) {
+ dev_dbg(pTAS2557->dev, "%s, config [%d] already loaded\n",
+ __func__, nNewConfig);
+ goto end;
+ } else
+ pPrevConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[nPrevConfig]);
+
+ pNewConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[nNewConfig]);
+ pTAS2557->mnCurrentConfiguration = nNewConfig;
+ if (pPrevConfiguration) {
+ if (pPrevConfiguration->mnPLL == pNewConfiguration->mnPLL) {
+ dev_dbg(pTAS2557->dev, "%s, PLL same\n", __func__);
+ goto prog_coefficient;
+ }
+ }
+
+ pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]);
+ if (bPowerOn) {
+ dev_dbg(pTAS2557->dev, "%s, power down to load new PLL\n", __func__);
+ if (hrtimer_active(&pTAS2557->mtimer))
+ hrtimer_cancel(&pTAS2557->mtimer);
+
+ if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE)
+ pTAS2557->enableIRQ(pTAS2557, false, false);
+
+ nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
+ if (nResult < 0)
+ goto end;
+ bRestorePower = true;
+ }
+
+ /* load PLL */
+ pPLL = &(pTAS2557->mpFirmware->mpPLLs[pNewConfiguration->mnPLL]);
+ dev_dbg(pTAS2557->dev, "load PLL: %s block for Configuration %s\n",
+ pPLL->mpName, pNewConfiguration->mpName);
+ nResult = tas2557_load_block(pTAS2557, &(pPLL->mBlock));
+ if (nResult < 0)
+ goto end;
+ pTAS2557->mnCurrentSampleRate = pNewConfiguration->mnSamplingRate;
+
+ dev_dbg(pTAS2557->dev, "load configuration %s conefficient pre block\n",
+ pNewConfiguration->mpName);
+ nResult = tas2557_load_data(pTAS2557, &(pNewConfiguration->mData), TAS2557_BLOCK_CFG_PRE_DEV_A);
+ if (nResult < 0)
+ goto end;
+
+prog_coefficient:
+ dev_dbg(pTAS2557->dev, "load new configuration: %s, coeff block data\n",
+ pNewConfiguration->mpName);
+ nResult = tas2557_load_data(pTAS2557, &(pNewConfiguration->mData),
+ TAS2557_BLOCK_CFG_COEFF_DEV_A);
+ if (nResult < 0)
+ goto end;
+
+ if (pTAS2557->mpCalFirmware->mnCalibrations) {
+ nResult = tas2557_set_calibration(pTAS2557, pTAS2557->mnCurrentCalibration);
+ if (nResult < 0)
+ goto end;
+ }
+
+ if (bRestorePower) {
+ pTAS2557->clearIRQ(pTAS2557);
+ dev_dbg(pTAS2557->dev, "device powered up, load startup\n");
+ nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_startup_data);
+ if (nResult < 0)
+ goto end;
+ if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
+ nResult = tas2557_checkPLL(pTAS2557);
+ if (nResult < 0) {
+ nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
+ pTAS2557->mbPowerUp = false;
+ goto end;
+ }
+ }
+ dev_dbg(pTAS2557->dev,
+ "device powered up, load unmute\n");
+ nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_unmute_data);
+ if (nResult < 0)
+ goto end;
+ if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
+ pTAS2557->enableIRQ(pTAS2557, true, true);
+ if (!hrtimer_active(&pTAS2557->mtimer)) {
+ pTAS2557->mnDieTvReadCounter = 0;
+ hrtimer_start(&pTAS2557->mtimer,
+ ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
+ }
+ }
+ }
+end:
+
+ pTAS2557->mnNewConfiguration = pTAS2557->mnCurrentConfiguration;
+ return nResult;
+}
+
+int tas2557_update_edge(struct tas2557_priv *pTAS2557)
+{
+ int nResult = 0;
+ dev_dbg(pTAS2557->dev,
+ "%s, edge: %d\n",
+ __func__, pTAS2557->mnEdge);
+
+ nResult = pTAS2557->update_bits(pTAS2557, TAS2557_SPK_CTRL_REG, 0x7, pTAS2557->mnEdge);
+
+ return nResult;
+}
+
+int tas2557_enable(struct tas2557_priv *pTAS2557, bool bEnable)
+{
+ int nResult = 0;
+ unsigned int nValue;
+ const char *pFWName;
+ struct TProgram *pProgram;
+
+ dev_dbg(pTAS2557->dev, "Enable: %d\n", bEnable);
+
+ if ((pTAS2557->mpFirmware->mnPrograms == 0)
+ || (pTAS2557->mpFirmware->mnConfigurations == 0)) {
+ dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__);
+ /*Load firmware*/
+ if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P1) {
+ dev_info(pTAS2557->dev, "PG2.1 Silicon found\n");
+ pFWName = TAS2557_FW_NAME;
+ } else if (pTAS2557->mnPGID == TAS2557_PG_VERSION_1P0) {
+ dev_info(pTAS2557->dev, "PG1.0 Silicon found\n");
+ pFWName = TAS2557_PG1P0_FW_NAME;
+ } else {
+ nResult = -ENOTSUPP;
+ dev_info(pTAS2557->dev, "unsupport Silicon 0x%x\n", pTAS2557->mnPGID);
+ goto end;
+ }
+ nResult = request_firmware_nowait(THIS_MODULE, 1, pFWName,
+ pTAS2557->dev, GFP_KERNEL, pTAS2557, tas2557_fw_ready);
+ if(nResult < 0)
+ goto end;
+ dev_err(pTAS2557->dev, "%s, firmware is loaded\n", __func__);
+ }
+
+ /* check safe guard*/
+ nResult = pTAS2557->read(pTAS2557, TAS2557_SAFE_GUARD_REG, &nValue);
+ if (nResult < 0)
+ goto end;
+ if ((nValue&0xff) != TAS2557_SAFE_GUARD_PATTERN) {
+ dev_err(pTAS2557->dev, "ERROR safe guard failure!\n");
+ nResult = -EPIPE;
+ pTAS2557->mnErrCode = ERROR_SAFE_GUARD;
+ pTAS2557->mbPowerUp = true;
+ goto end;
+ }
+
+ pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]);
+ if (bEnable) {
+ if (!pTAS2557->mbPowerUp) {
+ if (!pTAS2557->mbCalibrationLoaded) {
+ tas2557_set_calibration(pTAS2557, 0xFF);
+ pTAS2557->mbCalibrationLoaded = true;
+ }
+
+ if (pTAS2557->mbLoadConfigurationPrePowerUp) {
+ dev_dbg(pTAS2557->dev, "load coefficient before power\n");
+ pTAS2557->mbLoadConfigurationPrePowerUp = false;
+ nResult = tas2557_load_coefficient(pTAS2557,
+ pTAS2557->mnCurrentConfiguration, pTAS2557->mnNewConfiguration, false);
+ if (nResult < 0)
+ goto end;
+ }
+
+ pTAS2557->clearIRQ(pTAS2557);
+ /* power on device */
+ dev_dbg(pTAS2557->dev, "Enable: load startup sequence\n");
+ nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_startup_data);
+ if (nResult < 0)
+ goto end;
+ if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
+ nResult = tas2557_checkPLL(pTAS2557);
+ if (nResult < 0) {
+ nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
+ goto end;
+ }
+ }
+ dev_dbg(pTAS2557->dev, "Enable: load unmute sequence\n");
+ nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_unmute_data);
+ if (nResult < 0)
+ goto end;
+
+ pTAS2557->mbPowerUp = true;
+
+ tas2557_get_die_temperature(pTAS2557, &nValue);
+ if(nValue == 0x80000000)
+ {
+ dev_err(pTAS2557->dev, "%s, thermal sensor is wrong, mute output\n", __func__);
+ nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
+ pTAS2557->mbPowerUp = false;
+ goto end;
+ }
+
+ if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
+ /* turn on IRQ */
+ pTAS2557->enableIRQ(pTAS2557, true, true);
+ if (!hrtimer_active(&pTAS2557->mtimer)) {
+ pTAS2557->mnDieTvReadCounter = 0;
+ hrtimer_start(&pTAS2557->mtimer,
+ ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
+ }
+ }
+ pTAS2557->mnRestart = 0;
+ }
+ } else {
+ if (pTAS2557->mbPowerUp) {
+ if (hrtimer_active(&pTAS2557->mtimer))
+ hrtimer_cancel(&pTAS2557->mtimer);
+
+ dev_dbg(pTAS2557->dev, "Enable: load shutdown sequence\n");
+ if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
+ /* turn off IRQ */
+ pTAS2557->enableIRQ(pTAS2557, false, false);
+ }
+ nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
+ if (nResult < 0)
+ goto end;
+
+ pTAS2557->mbPowerUp = false;
+ pTAS2557->mnRestart = 0;
+ }
+ }
+
+ nResult = 0;
+
+end:
+ if (nResult < 0) {
+ if (pTAS2557->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK | ERROR_SAFE_GUARD))
+ failsafe(pTAS2557);
+ }
+
+ return nResult;
+}
+
+int tas2557_set_sampling_rate(struct tas2557_priv *pTAS2557, unsigned int nSamplingRate)
+{
+ int nResult = 0;
+ struct TConfiguration *pConfiguration;
+ unsigned int nConfiguration;
+
+ dev_dbg(pTAS2557->dev, "tas2557_setup_clocks: nSamplingRate = %d [Hz]\n",
+ nSamplingRate);
+
+ if ((!pTAS2557->mpFirmware->mpPrograms) ||
+ (!pTAS2557->mpFirmware->mpConfigurations)) {
+ dev_err(pTAS2557->dev, "Firmware not loaded\n");
+ nResult = -EINVAL;
+ goto end;
+ }
+
+ pConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration]);
+ if (pConfiguration->mnSamplingRate == nSamplingRate) {
+ dev_info(pTAS2557->dev, "Sampling rate for current configuration matches: %d\n",
+ nSamplingRate);
+ nResult = 0;
+ goto end;
+ }
+
+ for (nConfiguration = 0;
+ nConfiguration < pTAS2557->mpFirmware->mnConfigurations;
+ nConfiguration++) {
+ pConfiguration =
+ &(pTAS2557->mpFirmware->mpConfigurations[nConfiguration]);
+ if ((pConfiguration->mnSamplingRate == nSamplingRate)
+ && (pConfiguration->mnProgram == pTAS2557->mnCurrentProgram)) {
+ dev_info(pTAS2557->dev,
+ "Found configuration: %s, with compatible sampling rate %d\n",
+ pConfiguration->mpName, nSamplingRate);
+ nResult = tas2557_load_configuration(pTAS2557, nConfiguration, false);
+ goto end;
+ }
+ }
+
+ dev_err(pTAS2557->dev, "Cannot find a configuration that supports sampling rate: %d\n",
+ nSamplingRate);
+
+end:
+
+ return nResult;
+}
+
+static void fw_print_header(struct tas2557_priv *pTAS2557, struct TFirmware *pFirmware)
+{
+ dev_info(pTAS2557->dev, "FW Size = %d", pFirmware->mnFWSize);
+ dev_info(pTAS2557->dev, "Checksum = 0x%04X", pFirmware->mnChecksum);
+ dev_info(pTAS2557->dev, "PPC Version = 0x%04X", pFirmware->mnPPCVersion);
+ dev_info(pTAS2557->dev, "FW Version = 0x%04X", pFirmware->mnFWVersion);
+ dev_info(pTAS2557->dev, "Driver Version= 0x%04X", pFirmware->mnDriverVersion);
+ dev_info(pTAS2557->dev, "Timestamp = %d", pFirmware->mnTimeStamp);
+ dev_info(pTAS2557->dev, "DDC Name = %s", pFirmware->mpDDCName);
+ dev_info(pTAS2557->dev, "Description = %s", pFirmware->mpDescription);
+}
+
+inline unsigned int fw_convert_number(unsigned char *pData)
+{
+ return pData[3] + (pData[2] << 8) + (pData[1] << 16) + (pData[0] << 24);
+}
+
+static int fw_parse_header(struct tas2557_priv *pTAS2557,
+ struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize)
+{
+ unsigned char *pDataStart = pData;
+ unsigned int n;
+ unsigned char pMagicNumber[] = { 0x35, 0x35, 0x35, 0x32 };
+
+ if (nSize < 104) {
+ dev_err(pTAS2557->dev, "Firmware: Header too short");
+ return -EINVAL;
+ }
+
+ if (memcmp(pData, pMagicNumber, 4)) {
+ dev_err(pTAS2557->dev, "Firmware: Magic number doesn't match");
+ return -EINVAL;
+ }
+ pData += 4;
+
+ pFirmware->mnFWSize = fw_convert_number(pData);
+ pData += 4;
+
+ pFirmware->mnChecksum = fw_convert_number(pData);
+ pData += 4;
+
+ pFirmware->mnPPCVersion = fw_convert_number(pData);
+ pData += 4;
+
+ pFirmware->mnFWVersion = fw_convert_number(pData);
+ pData += 4;
+
+ pFirmware->mnDriverVersion = fw_convert_number(pData);
+ pData += 4;
+
+ pFirmware->mnTimeStamp = fw_convert_number(pData);
+ pData += 4;
+
+ memcpy(pFirmware->mpDDCName, pData, 64);
+ pData += 64;
+
+ n = strlen(pData);
+ pFirmware->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
+ pData += n + 1;
+ if ((pData - pDataStart) >= nSize) {
+ dev_err(pTAS2557->dev, "Firmware: Header too short after DDC description");
+ return -EINVAL;
+ }
+
+ pFirmware->mnDeviceFamily = fw_convert_number(pData);
+ pData += 4;
+ if (pFirmware->mnDeviceFamily != 0) {
+ dev_err(pTAS2557->dev,
+ "deviceFamily %d, not TAS device", pFirmware->mnDeviceFamily);
+ return -EINVAL;
+ }
+
+ pFirmware->mnDevice = fw_convert_number(pData);
+ pData += 4;
+
+ if (pFirmware->mnDevice != 2) {
+ dev_err(pTAS2557->dev,
+ "device %d, not TAS2557 Dual Mono", pFirmware->mnDevice);
+ return -EINVAL;
+ }
+
+ fw_print_header(pTAS2557, pFirmware);
+ return pData - pDataStart;
+}
+
+static int fw_parse_block_data(struct tas2557_priv *pTAS2557, struct TFirmware *pFirmware,
+ struct TBlock *pBlock, unsigned char *pData)
+{
+ unsigned char *pDataStart = pData;
+ unsigned int n;
+
+ pBlock->mnType = fw_convert_number(pData);
+ pData += 4;
+
+ if (pFirmware->mnDriverVersion >= PPC_DRIVER_CRCCHK) {
+ pBlock->mbPChkSumPresent = pData[0];
+ pData++;
+
+ pBlock->mnPChkSum = pData[0];
+ pData++;
+
+ pBlock->mbYChkSumPresent = pData[0];
+ pData++;
+
+ pBlock->mnYChkSum = pData[0];
+ pData++;
+ } else {
+ pBlock->mbPChkSumPresent = 0;
+ pBlock->mbYChkSumPresent = 0;
+ }
+
+ pBlock->mnCommands = fw_convert_number(pData);
+ pData += 4;
+
+ n = pBlock->mnCommands * 4;
+ pBlock->mpData = kmemdup(pData, n, GFP_KERNEL);
+ pData += n;
+ return pData - pDataStart;
+}
+
+static int fw_parse_data(struct tas2557_priv *pTAS2557, struct TFirmware *pFirmware,
+ struct TData *pImageData, unsigned char *pData)
+{
+ unsigned char *pDataStart = pData;
+ unsigned int nBlock;
+ unsigned int n;
+
+ memcpy(pImageData->mpName, pData, 64);
+ pData += 64;
+
+ n = strlen(pData);
+ pImageData->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
+ pData += n + 1;
+
+ pImageData->mnBlocks = (pData[0] << 8) + pData[1];
+ pData += 2;
+
+ pImageData->mpBlocks =
+ kmalloc(sizeof(struct TBlock) * pImageData->mnBlocks, GFP_KERNEL);
+ if(pImageData->mpBlocks == NULL)
+ {
+ dev_dbg(pTAS2557->dev, "failed malloc blocks mem\n");
+ goto end;
+ }
+
+ for (nBlock = 0; nBlock < pImageData->mnBlocks; nBlock++) {
+ n = fw_parse_block_data(pTAS2557, pFirmware,
+ &(pImageData->mpBlocks[nBlock]), pData);
+ pData += n;
+ }
+
+end:
+ return pData - pDataStart;
+}
+
+static int fw_parse_pll_data(struct tas2557_priv *pTAS2557,
+ struct TFirmware *pFirmware, unsigned char *pData)
+{
+ unsigned char *pDataStart = pData;
+ unsigned int n;
+ unsigned int nPLL;
+ struct TPLL *pPLL;
+
+ pFirmware->mnPLLs = (pData[0] << 8) + pData[1];
+ pData += 2;
+
+ if (pFirmware->mnPLLs == 0)
+ goto end;
+
+ pFirmware->mpPLLs = kmalloc_array(pFirmware->mnPLLs, sizeof(struct TPLL), GFP_KERNEL);
+ for (nPLL = 0; nPLL < pFirmware->mnPLLs; nPLL++) {
+ pPLL = &(pFirmware->mpPLLs[nPLL]);
+
+ memcpy(pPLL->mpName, pData, 64);
+ pData += 64;
+
+ n = strlen(pData);
+ pPLL->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
+ pData += n + 1;
+
+ n = fw_parse_block_data(pTAS2557, pFirmware, &(pPLL->mBlock), pData);
+ pData += n;
+ }
+
+end:
+ return pData - pDataStart;
+}
+
+static int fw_parse_program_data(struct tas2557_priv *pTAS2557,
+ struct TFirmware *pFirmware, unsigned char *pData)
+{
+ unsigned char *pDataStart = pData;
+ unsigned int n;
+ unsigned int nProgram;
+ struct TProgram *pProgram;
+
+ pFirmware->mnPrograms = (pData[0] << 8) + pData[1];
+ pData += 2;
+
+ if (pFirmware->mnPrograms == 0)
+ goto end;
+
+ pFirmware->mpPrograms =
+ kmalloc(sizeof(struct TProgram) * pFirmware->mnPrograms, GFP_KERNEL);
+ if(pFirmware->mpPrograms == NULL)
+ {
+ dev_dbg(pTAS2557->dev, "failed malloc program mem\n");
+ goto end;
+ }
+
+ for (nProgram = 0; nProgram < pFirmware->mnPrograms; nProgram++) {
+ pProgram = &(pFirmware->mpPrograms[nProgram]);
+ memcpy(pProgram->mpName, pData, 64);
+ pData += 64;
+
+ n = strlen(pData);
+ pProgram->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
+ pData += n + 1;
+
+ pProgram->mnAppMode = pData[0];
+ pData++;
+
+ pProgram->mnBoost = (pData[0] << 8) + pData[1];
+ pData += 2;
+
+ n = fw_parse_data(pTAS2557, pFirmware, &(pProgram->mData), pData);
+ pData += n;
+ }
+
+end:
+
+ return pData - pDataStart;
+}
+
+static int fw_parse_configuration_data(struct tas2557_priv *pTAS2557,
+ struct TFirmware *pFirmware, unsigned char *pData)
+{
+ unsigned char *pDataStart = pData;
+ unsigned int n;
+ unsigned int nConfiguration;
+ struct TConfiguration *pConfiguration;
+
+ pFirmware->mnConfigurations = (pData[0] << 8) + pData[1];
+ pData += 2;
+
+ if (pFirmware->mnConfigurations == 0)
+ goto end;
+
+ pFirmware->mpConfigurations =
+ kmalloc(sizeof(struct TConfiguration) * pFirmware->mnConfigurations,
+ GFP_KERNEL);
+ if(pFirmware->mpConfigurations == NULL)
+ {
+ dev_dbg(pTAS2557->dev, "failed malloc configuration mem\n");
+ goto end;
+ }
+
+ for (nConfiguration = 0; nConfiguration < pFirmware->mnConfigurations;
+ nConfiguration++) {
+ pConfiguration = &(pFirmware->mpConfigurations[nConfiguration]);
+ memcpy(pConfiguration->mpName, pData, 64);
+ pData += 64;
+
+ n = strlen(pData);
+ pConfiguration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
+ pData += n + 1;
+
+ if ((pFirmware->mnDriverVersion >= PPC_DRIVER_CONFDEV)
+ || ((pFirmware->mnDriverVersion >= PPC_DRIVER_CFGDEV_NONCRC)
+ && (pFirmware->mnDriverVersion < PPC_DRIVER_CRCCHK))) {
+ pConfiguration->mnDevices = (pData[0] << 8) + pData[1];
+ pData += 2;
+ } else
+ pConfiguration->mnDevices = 1;
+
+ pConfiguration->mnProgram = pData[0];
+ pData++;
+
+ pConfiguration->mnPLL = pData[0];
+ pData++;
+
+ pConfiguration->mnSamplingRate = fw_convert_number(pData);
+ pData += 4;
+
+ if (pFirmware->mnDriverVersion >= PPC_DRIVER_MTPLLSRC) {
+ pConfiguration->mnPLLSrc = pData[0];
+ pData++;
+
+ pConfiguration->mnPLLSrcRate = fw_convert_number(pData);
+ pData += 4;
+ }
+
+ n = fw_parse_data(pTAS2557, pFirmware, &(pConfiguration->mData), pData);
+ pData += n;
+ }
+
+end:
+
+ return pData - pDataStart;
+}
+
+int fw_parse_calibration_data(struct tas2557_priv *pTAS2557,
+ struct TFirmware *pFirmware, unsigned char *pData)
+{
+ unsigned char *pDataStart = pData;
+ unsigned int n;
+ unsigned int nCalibration;
+ struct TCalibration *pCalibration;
+
+ pFirmware->mnCalibrations = (pData[0] << 8) + pData[1];
+ pData += 2;
+
+ if (pFirmware->mnCalibrations == 0)
+ goto end;
+
+ pFirmware->mpCalibrations =
+ kmalloc(sizeof(struct TCalibration) * pFirmware->mnCalibrations, GFP_KERNEL);
+ if(pFirmware->mpCalibrations == NULL)
+ {
+ dev_err(pTAS2557->dev, "failed to malloc calibration mem\n");
+ goto end;
+ }
+
+ for (nCalibration = 0;
+ nCalibration < pFirmware->mnCalibrations;
+ nCalibration++) {
+ pCalibration = &(pFirmware->mpCalibrations[nCalibration]);
+ memcpy(pCalibration->mpName, pData, 64);
+ pData += 64;
+
+ n = strlen(pData);
+ pCalibration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
+ pData += n + 1;
+
+ pCalibration->mnProgram = pData[0];
+ pData++;
+
+ pCalibration->mnConfiguration = pData[0];
+ pData++;
+
+ n = fw_parse_data(pTAS2557, pFirmware, &(pCalibration->mData), pData);
+ pData += n;
+ }
+
+end:
+
+ return pData - pDataStart;
+}
+
+static int fw_parse(struct tas2557_priv *pTAS2557,
+ struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize)
+{
+ int nPosition = 0;
+
+ nPosition = fw_parse_header(pTAS2557, pFirmware, pData, nSize);
+ if (nPosition < 0) {
+ dev_err(pTAS2557->dev, "Firmware: Wrong Header");
+ return -EINVAL;
+ }
+
+ if (nPosition >= nSize) {
+ dev_err(pTAS2557->dev, "Firmware: Too short");
+ return -EINVAL;
+ }
+
+ pData += nPosition;
+ nSize -= nPosition;
+ nPosition = 0;
+
+ nPosition = fw_parse_pll_data(pTAS2557, pFirmware, pData);
+
+ pData += nPosition;
+ nSize -= nPosition;
+ nPosition = 0;
+
+ nPosition = fw_parse_program_data(pTAS2557, pFirmware, pData);
+
+ pData += nPosition;
+ nSize -= nPosition;
+ nPosition = 0;
+
+ nPosition = fw_parse_configuration_data(pTAS2557, pFirmware, pData);
+
+ pData += nPosition;
+ nSize -= nPosition;
+ nPosition = 0;
+
+ if (nSize > 64)
+ nPosition = fw_parse_calibration_data(pTAS2557, pFirmware, pData);
+ return 0;
+}
+
+
+static const unsigned char crc8_lookup_table[CRC8_TABLE_SIZE] = {
+0x00, 0x4D, 0x9A, 0xD7, 0x79, 0x34, 0xE3, 0xAE, 0xF2, 0xBF, 0x68, 0x25, 0x8B, 0xC6, 0x11, 0x5C,
+0xA9, 0xE4, 0x33, 0x7E, 0xD0, 0x9D, 0x4A, 0x07, 0x5B, 0x16, 0xC1, 0x8C, 0x22, 0x6F, 0xB8, 0xF5,
+0x1F, 0x52, 0x85, 0xC8, 0x66, 0x2B, 0xFC, 0xB1, 0xED, 0xA0, 0x77, 0x3A, 0x94, 0xD9, 0x0E, 0x43,
+0xB6, 0xFB, 0x2C, 0x61, 0xCF, 0x82, 0x55, 0x18, 0x44, 0x09, 0xDE, 0x93, 0x3D, 0x70, 0xA7, 0xEA,
+0x3E, 0x73, 0xA4, 0xE9, 0x47, 0x0A, 0xDD, 0x90, 0xCC, 0x81, 0x56, 0x1B, 0xB5, 0xF8, 0x2F, 0x62,
+0x97, 0xDA, 0x0D, 0x40, 0xEE, 0xA3, 0x74, 0x39, 0x65, 0x28, 0xFF, 0xB2, 0x1C, 0x51, 0x86, 0xCB,
+0x21, 0x6C, 0xBB, 0xF6, 0x58, 0x15, 0xC2, 0x8F, 0xD3, 0x9E, 0x49, 0x04, 0xAA, 0xE7, 0x30, 0x7D,
+0x88, 0xC5, 0x12, 0x5F, 0xF1, 0xBC, 0x6B, 0x26, 0x7A, 0x37, 0xE0, 0xAD, 0x03, 0x4E, 0x99, 0xD4,
+0x7C, 0x31, 0xE6, 0xAB, 0x05, 0x48, 0x9F, 0xD2, 0x8E, 0xC3, 0x14, 0x59, 0xF7, 0xBA, 0x6D, 0x20,
+0xD5, 0x98, 0x4F, 0x02, 0xAC, 0xE1, 0x36, 0x7B, 0x27, 0x6A, 0xBD, 0xF0, 0x5E, 0x13, 0xC4, 0x89,
+0x63, 0x2E, 0xF9, 0xB4, 0x1A, 0x57, 0x80, 0xCD, 0x91, 0xDC, 0x0B, 0x46, 0xE8, 0xA5, 0x72, 0x3F,
+0xCA, 0x87, 0x50, 0x1D, 0xB3, 0xFE, 0x29, 0x64, 0x38, 0x75, 0xA2, 0xEF, 0x41, 0x0C, 0xDB, 0x96,
+0x42, 0x0F, 0xD8, 0x95, 0x3B, 0x76, 0xA1, 0xEC, 0xB0, 0xFD, 0x2A, 0x67, 0xC9, 0x84, 0x53, 0x1E,
+0xEB, 0xA6, 0x71, 0x3C, 0x92, 0xDF, 0x08, 0x45, 0x19, 0x54, 0x83, 0xCE, 0x60, 0x2D, 0xFA, 0xB7,
+0x5D, 0x10, 0xC7, 0x8A, 0x24, 0x69, 0xBE, 0xF3, 0xAF, 0xE2, 0x35, 0x78, 0xD6, 0x9B, 0x4C, 0x01,
+0xF4, 0xB9, 0x6E, 0x23, 0x8D, 0xC0, 0x17, 0x5A, 0x06, 0x4B, 0x9C, 0xD1, 0x7F, 0x32, 0xE5, 0xA8
+};
+
+static int isInPageYRAM(struct tas2557_priv *pTAS2557, struct TYCRC *pCRCData,
+ unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
+{
+ int nResult = 0;
+
+ if (nBook == TAS2557_YRAM_BOOK1) {
+ if (nPage == TAS2557_YRAM1_PAGE) {
+ if (nReg >= TAS2557_YRAM1_START_REG) {
+ pCRCData->mnOffset = nReg;
+ pCRCData->mnLen = len;
+ nResult = 1;
+ } else if ((nReg + len) > TAS2557_YRAM1_START_REG) {
+ pCRCData->mnOffset = TAS2557_YRAM1_START_REG;
+ pCRCData->mnLen = len - (TAS2557_YRAM1_START_REG - nReg);
+ nResult = 1;
+ } else
+ nResult = 0;
+ } else if (nPage == TAS2557_YRAM3_PAGE) {
+ if (nReg > TAS2557_YRAM3_END_REG) {
+ nResult = 0;
+ } else if (nReg >= TAS2557_YRAM3_START_REG) {
+ if ((nReg + len) > TAS2557_YRAM3_END_REG) {
+ pCRCData->mnOffset = nReg;
+ pCRCData->mnLen = TAS2557_YRAM3_END_REG - nReg + 1;
+ nResult = 1;
+ } else {
+ pCRCData->mnOffset = nReg;
+ pCRCData->mnLen = len;
+ nResult = 1;
+ }
+ } else {
+ if ((nReg + (len - 1)) < TAS2557_YRAM3_START_REG)
+ nResult = 0;
+ else {
+ pCRCData->mnOffset = TAS2557_YRAM3_START_REG;
+ pCRCData->mnLen = len - (TAS2557_YRAM3_START_REG - nReg);
+ nResult = 1;
+ }
+ }
+ }
+ } else if (nBook == TAS2557_YRAM_BOOK2) {
+ if (nPage == TAS2557_YRAM5_PAGE) {
+ if (nReg > TAS2557_YRAM5_END_REG) {
+ nResult = 0;
+ } else if (nReg >= TAS2557_YRAM5_START_REG) {
+ if ((nReg + len) > TAS2557_YRAM5_END_REG) {
+ pCRCData->mnOffset = nReg;
+ pCRCData->mnLen = TAS2557_YRAM5_END_REG - nReg + 1;
+ nResult = 1;
+ } else {
+ pCRCData->mnOffset = nReg;
+ pCRCData->mnLen = len;
+ nResult = 1;
+ }
+ } else {
+ if ((nReg + (len - 1)) < TAS2557_YRAM5_START_REG)
+ nResult = 0;
+ else {
+ pCRCData->mnOffset = TAS2557_YRAM5_START_REG;
+ pCRCData->mnLen = len - (TAS2557_YRAM5_START_REG - nReg);
+ nResult = 1;
+ }
+ }
+ }
+ } else
+ nResult = 0;
+
+ return nResult;
+}
+
+static int isInBlockYRAM(struct tas2557_priv *pTAS2557, struct TYCRC *pCRCData,
+ unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
+{
+ int nResult;
+
+ if (nBook == TAS2557_YRAM_BOOK1) {
+ if (nPage < TAS2557_YRAM2_START_PAGE)
+ nResult = 0;
+ else if (nPage <= TAS2557_YRAM2_END_PAGE) {
+ if (nReg > TAS2557_YRAM2_END_REG)
+ nResult = 0;
+ else if (nReg >= TAS2557_YRAM2_START_REG) {
+ pCRCData->mnOffset = nReg;
+ pCRCData->mnLen = len;
+ nResult = 1;
+ } else {
+ if ((nReg + (len - 1)) < TAS2557_YRAM2_START_REG)
+ nResult = 0;
+ else {
+ pCRCData->mnOffset = TAS2557_YRAM2_START_REG;
+ pCRCData->mnLen = nReg + len - TAS2557_YRAM2_START_REG;
+ nResult = 1;
+ }
+ }
+ } else
+ nResult = 0;
+ } else if (nBook == TAS2557_YRAM_BOOK2) {
+ if (nPage < TAS2557_YRAM4_START_PAGE)
+ nResult = 0;
+ else if (nPage <= TAS2557_YRAM4_END_PAGE) {
+ if (nReg > TAS2557_YRAM2_END_REG)
+ nResult = 0;
+ else if (nReg >= TAS2557_YRAM2_START_REG) {
+ pCRCData->mnOffset = nReg;
+ pCRCData->mnLen = len;
+ nResult = 1;
+ } else {
+ if ((nReg + (len - 1)) < TAS2557_YRAM2_START_REG)
+ nResult = 0;
+ else {
+ pCRCData->mnOffset = TAS2557_YRAM2_START_REG;
+ pCRCData->mnLen = nReg + len - TAS2557_YRAM2_START_REG;
+ nResult = 1;
+ }
+ }
+ } else
+ nResult = 0;
+ } else
+ nResult = 0;
+
+ return nResult;
+}
+
+
+static int isYRAM(struct tas2557_priv *pTAS2557, struct TYCRC *pCRCData,
+ unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
+{
+ int nResult;
+
+ nResult = isInPageYRAM(pTAS2557, pCRCData, nBook, nPage, nReg, len);
+
+ if (nResult == 0)
+ nResult = isInBlockYRAM(pTAS2557, pCRCData, nBook, nPage, nReg, len);
+
+ return nResult;
+}
+
+/*
+ * crc8 - calculate a crc8 over the given input data.
+ *
+ * table: crc table used for calculation.
+ * pdata: pointer to data buffer.
+ * nbytes: number of bytes in data buffer.
+ * crc: previous returned crc8 value.
+ */
+static u8 ti_crc8(const u8 table[CRC8_TABLE_SIZE], u8 *pdata, size_t nbytes, u8 crc)
+{
+ /* loop over the buffer data */
+ while (nbytes-- > 0)
+ crc = table[(crc ^ *pdata++) & 0xff];
+
+ return crc;
+}
+
+static int doSingleRegCheckSum(struct tas2557_priv *pTAS2557,
+ unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char nValue)
+{
+ int nResult = 0;
+ struct TYCRC sCRCData;
+ unsigned int nData1 = 0;
+
+ if ((nBook == TAS2557_BOOK_ID(TAS2557_SA_COEFF_SWAP_REG))
+ && (nPage == TAS2557_PAGE_ID(TAS2557_SA_COEFF_SWAP_REG))
+ && (nReg >= TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG))
+ && (nReg <= (TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG) + 4))) {
+ /* DSP swap command, pass */
+ nResult = 0;
+ goto end;
+ }
+
+ nResult = isYRAM(pTAS2557, &sCRCData, nBook, nPage, nReg, 1);
+ if (nResult == 1) {
+ nResult = pTAS2557->read(pTAS2557, TAS2557_REG(nBook, nPage, nReg), &nData1);
+ if (nResult < 0)
+ goto end;
+
+ if (nData1 != nValue) {
+ dev_err(pTAS2557->dev, "error2 (line %d),B[0x%x]P[0x%x]R[0x%x] W[0x%x], R[0x%x]\n",
+ __LINE__, nBook, nPage, nReg, nValue, nData1);
+ nResult = -EAGAIN;
+ goto end;
+ }
+
+ nResult = ti_crc8(crc8_lookup_table, &nValue, 1, 0);
+ }
+
+end:
+
+ return nResult;
+}
+
+static int doMultiRegCheckSum(struct tas2557_priv *pTAS2557,
+ unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned int len)
+{
+ int nResult = 0, i;
+ unsigned char nCRCChkSum = 0;
+ unsigned char nBuf1[128];
+ struct TYCRC TCRCData;
+
+ if ((nReg + len-1) > 127) {
+ nResult = -EINVAL;
+ dev_err(pTAS2557->dev, "firmware error\n");
+ goto end;
+ }
+
+ if ((nBook == TAS2557_BOOK_ID(TAS2557_SA_COEFF_SWAP_REG))
+ && (nPage == TAS2557_PAGE_ID(TAS2557_SA_COEFF_SWAP_REG))
+ && (nReg == TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG))
+ && (len == 4)) {
+ /* DSP swap command, pass */
+ nResult = 0;
+ goto end;
+ }
+
+ nResult = isYRAM(pTAS2557, &TCRCData, nBook, nPage, nReg, len);
+ if (nResult == 1) {
+ if (len == 1) {
+ dev_err(pTAS2557->dev, "firmware error\n");
+ nResult = -EINVAL;
+ goto end;
+ } else {
+ nResult = pTAS2557->bulk_read(pTAS2557, TAS2557_REG(nBook, nPage, TCRCData.mnOffset), nBuf1, TCRCData.mnLen);
+ if (nResult < 0)
+ goto end;
+
+ for (i = 0; i < TCRCData.mnLen; i++) {
+ if ((nBook == TAS2557_BOOK_ID(TAS2557_SA_COEFF_SWAP_REG))
+ && (nPage == TAS2557_PAGE_ID(TAS2557_SA_COEFF_SWAP_REG))
+ && ((i + TCRCData.mnOffset)
+ >= TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG))
+ && ((i + TCRCData.mnOffset)
+ <= (TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG) + 4))) {
+ /* DSP swap command, bypass */
+ continue;
+ } else
+ nCRCChkSum += ti_crc8(crc8_lookup_table, &nBuf1[i], 1, 0);
+ }
+
+ nResult = nCRCChkSum;
+ }
+ }
+
+end:
+
+ return nResult;
+}
+
+static int tas2557_load_block(struct tas2557_priv *pTAS2557, struct TBlock *pBlock)
+{
+ int nResult = 0;
+ unsigned int nCommand = 0;
+ unsigned char nBook;
+ unsigned char nPage;
+ unsigned char nOffset;
+ unsigned char nData;
+ unsigned int nLength;
+ unsigned int nSleep;
+ unsigned char nCRCChkSum = 0;
+ unsigned int nValue1;
+ int nRetry = 6;
+ unsigned char *pData = pBlock->mpData;
+
+ dev_dbg(pTAS2557->dev, "TAS2557 load block: Type = %d, commands = %d\n",
+ pBlock->mnType, pBlock->mnCommands);
+start:
+ if (pBlock->mbPChkSumPresent) {
+ nResult = pTAS2557->write(pTAS2557, TAS2557_CRC_RESET_REG, 1);
+ if (nResult < 0)
+ goto end;
+ }
+
+ if (pBlock->mbYChkSumPresent)
+ nCRCChkSum = 0;
+
+ nCommand = 0;
+
+ while (nCommand < pBlock->mnCommands) {
+ pData = pBlock->mpData + nCommand * 4;
+
+ nBook = pData[0];
+ nPage = pData[1];
+ nOffset = pData[2];
+ nData = pData[3];
+
+ nCommand++;
+
+ if (nOffset <= 0x7F) {
+ nResult = pTAS2557->write(pTAS2557, TAS2557_REG(nBook, nPage, nOffset), nData);
+ if (nResult < 0)
+ goto end;
+ if (pBlock->mbYChkSumPresent) {
+ nResult = doSingleRegCheckSum(pTAS2557, nBook, nPage, nOffset, nData);
+ if (nResult < 0)
+ goto check;
+ nCRCChkSum += (unsigned char)nResult;
+ }
+ } else if (nOffset == 0x81) {
+ nSleep = (nBook << 8) + nPage;
+ msleep(nSleep);
+ } else if (nOffset == 0x85) {
+ pData += 4;
+ nLength = (nBook << 8) + nPage;
+ nBook = pData[0];
+ nPage = pData[1];
+ nOffset = pData[2];
+ if (nLength > 1) {
+ nResult = pTAS2557->bulk_write(pTAS2557, TAS2557_REG(nBook, nPage, nOffset), pData + 3, nLength);
+ if (nResult < 0)
+ goto end;
+ if (pBlock->mbYChkSumPresent) {
+ nResult = doMultiRegCheckSum(pTAS2557, nBook, nPage, nOffset, nLength);
+ if (nResult < 0)
+ goto check;
+ nCRCChkSum += (unsigned char)nResult;
+ }
+ } else {
+ nResult = pTAS2557->write(pTAS2557, TAS2557_REG(nBook, nPage, nOffset), pData[3]);
+ if (nResult < 0)
+ goto end;
+ if (pBlock->mbYChkSumPresent) {
+ nResult = doSingleRegCheckSum(pTAS2557, nBook, nPage, nOffset, pData[3]);
+ if (nResult < 0)
+ goto check;
+ nCRCChkSum += (unsigned char)nResult;
+ }
+ }
+
+ nCommand++;
+
+ if (nLength >= 2)
+ nCommand += ((nLength - 2) / 4) + 1;
+ }
+ }
+ if (pBlock->mbPChkSumPresent) {
+ nResult = pTAS2557->read(pTAS2557, TAS2557_CRC_CHECKSUM_REG, &nValue1);
+ if (nResult < 0)
+ goto end;
+ if ((nValue1&0xff) != pBlock->mnPChkSum) {
+ dev_err(pTAS2557->dev, "Block PChkSum Error: FW = 0x%x, Reg = 0x%x\n",
+ pBlock->mnPChkSum, (nValue1&0xff));
+ nResult = -EAGAIN;
+ pTAS2557->mnErrCode |= ERROR_PRAM_CRCCHK;
+ goto check;
+ }
+
+ nResult = 0;
+ pTAS2557->mnErrCode &= ~ERROR_PRAM_CRCCHK;
+ dev_dbg(pTAS2557->dev, "Block[0x%x] PChkSum match\n", pBlock->mnType);
+ }
+
+ if (pBlock->mbYChkSumPresent) {
+ if (nCRCChkSum != pBlock->mnYChkSum) {
+ dev_err(pTAS2557->dev, "Block YChkSum Error: FW = 0x%x, YCRC = 0x%x\n",
+ pBlock->mnYChkSum, nCRCChkSum);
+ nResult = -EAGAIN;
+ pTAS2557->mnErrCode |= ERROR_YRAM_CRCCHK;
+ goto check;
+ }
+ pTAS2557->mnErrCode &= ~ERROR_YRAM_CRCCHK;
+ nResult = 0;
+ dev_dbg(pTAS2557->dev, "Block[0x%x] YChkSum match\n", pBlock->mnType);
+ }
+
+check:
+ if (nResult == -EAGAIN) {
+ nRetry--;
+ if (nRetry > 0)
+ goto start;
+ }
+
+end:
+ if (nResult < 0) {
+ dev_err(pTAS2557->dev, "Block (%d) load error\n",
+ pBlock->mnType);
+ }
+ return nResult;
+}
+
+static int tas2557_load_data(struct tas2557_priv *pTAS2557, struct TData *pData, unsigned int nType)
+{
+ int nResult = 0;
+ unsigned int nBlock;
+ struct TBlock *pBlock;
+
+ dev_dbg(pTAS2557->dev,
+ "TAS2557 load data: %s, Blocks = %d, Block Type = %d\n", pData->mpName, pData->mnBlocks, nType);
+
+ for (nBlock = 0; nBlock < pData->mnBlocks; nBlock++) {
+ pBlock = &(pData->mpBlocks[nBlock]);
+ if (pBlock->mnType == nType) {
+ nResult = tas2557_load_block(pTAS2557, pBlock);
+ if (nResult < 0)
+ break;
+ }
+ }
+
+ return nResult;
+}
+
+static int tas2557_load_configuration(struct tas2557_priv *pTAS2557,
+ unsigned int nConfiguration, bool bLoadSame)
+{
+ int nResult = 0;
+ struct TConfiguration *pCurrentConfiguration = NULL;
+ struct TConfiguration *pNewConfiguration = NULL;
+
+ dev_dbg(pTAS2557->dev, "%s: %d\n", __func__, nConfiguration);
+
+ if ((!pTAS2557->mpFirmware->mpPrograms) ||
+ (!pTAS2557->mpFirmware->mpConfigurations)) {
+ dev_err(pTAS2557->dev, "Firmware not loaded\n");
+ nResult = 0;
+ goto end;
+ }
+
+ if (nConfiguration >= pTAS2557->mpFirmware->mnConfigurations) {
+ dev_err(pTAS2557->dev, "Configuration %d doesn't exist\n",
+ nConfiguration);
+ nResult = 0;
+ goto end;
+ }
+
+ if ((!pTAS2557->mbLoadConfigurationPrePowerUp)
+ && (nConfiguration == pTAS2557->mnCurrentConfiguration)
+ && (!bLoadSame)) {
+ dev_info(pTAS2557->dev, "Configuration %d is already loaded\n",
+ nConfiguration);
+ nResult = 0;
+ goto end;
+ }
+
+ pCurrentConfiguration =
+ &(pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration]);
+ pNewConfiguration =
+ &(pTAS2557->mpFirmware->mpConfigurations[nConfiguration]);
+ if (pNewConfiguration->mnProgram != pCurrentConfiguration->mnProgram) {
+ dev_err(pTAS2557->dev, "Configuration %d, %s doesn't share the same program as current %d\n",
+ nConfiguration, pNewConfiguration->mpName, pCurrentConfiguration->mnProgram);
+ nResult = 0;
+ goto end;
+ }
+
+ if (pNewConfiguration->mnPLL >= pTAS2557->mpFirmware->mnPLLs) {
+ dev_err(pTAS2557->dev, "Configuration %d, %s doesn't have a valid PLL index %d\n",
+ nConfiguration, pNewConfiguration->mpName, pNewConfiguration->mnPLL);
+ nResult = 0;
+ goto end;
+ }
+
+ if (pTAS2557->mbPowerUp) {
+ pTAS2557->mbLoadConfigurationPrePowerUp = false;
+ nResult = tas2557_load_coefficient(pTAS2557, pTAS2557->mnCurrentConfiguration, nConfiguration, true);
+ } else {
+ dev_dbg(pTAS2557->dev,
+ "TAS2557 was powered down, will load coefficient when power up\n");
+ pTAS2557->mbLoadConfigurationPrePowerUp = true;
+ pTAS2557->mnNewConfiguration = nConfiguration;
+ }
+
+end:
+
+ if (nResult < 0) {
+ if (pTAS2557->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK))
+ failsafe(pTAS2557);
+ }
+
+ return nResult;
+}
+
+int tas2557_set_config(struct tas2557_priv *pTAS2557, int config)
+{
+ struct TConfiguration *pConfiguration;
+ struct TProgram *pProgram;
+ unsigned int nProgram = pTAS2557->mnCurrentProgram;
+ unsigned int nConfiguration = config;
+ int nResult = 0;
+
+ if ((!pTAS2557->mpFirmware->mpPrograms) ||
+ (!pTAS2557->mpFirmware->mpConfigurations)) {
+ dev_err(pTAS2557->dev, "Firmware not loaded\n");
+ nResult = -EINVAL;
+ goto end;
+ }
+
+ if (nConfiguration >= pTAS2557->mpFirmware->mnConfigurations) {
+ dev_err(pTAS2557->dev, "Configuration %d doesn't exist\n",
+ nConfiguration);
+ nResult = -EINVAL;
+ goto end;
+ }
+
+ pConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[nConfiguration]);
+ pProgram = &(pTAS2557->mpFirmware->mpPrograms[nProgram]);
+
+ if (nProgram != pConfiguration->mnProgram) {
+ dev_err(pTAS2557->dev,
+ "Configuration %d, %s with Program %d isn't compatible with existing Program %d, %s\n",
+ nConfiguration, pConfiguration->mpName, pConfiguration->mnProgram,
+ nProgram, pProgram->mpName);
+ nResult = -EINVAL;
+ goto end;
+ }
+
+ nResult = tas2557_load_configuration(pTAS2557, nConfiguration, false);
+
+end:
+
+ return nResult;
+}
+
+void tas2557_clear_firmware(struct TFirmware *pFirmware)
+{
+ unsigned int n, nn;
+
+ if (!pFirmware)
+ return;
+
+ kfree(pFirmware->mpDescription);
+
+ if (pFirmware->mpPLLs != NULL) {
+ for (n = 0; n < pFirmware->mnPLLs; n++) {
+ kfree(pFirmware->mpPLLs[n].mpDescription);
+ kfree(pFirmware->mpPLLs[n].mBlock.mpData);
+ }
+ kfree(pFirmware->mpPLLs);
+ }
+
+ if (pFirmware->mpPrograms != NULL) {
+ for (n = 0; n < pFirmware->mnPrograms; n++) {
+ kfree(pFirmware->mpPrograms[n].mpDescription);
+ kfree(pFirmware->mpPrograms[n].mData.mpDescription);
+ for (nn = 0; nn < pFirmware->mpPrograms[n].mData.mnBlocks; nn++)
+ kfree(pFirmware->mpPrograms[n].mData.mpBlocks[nn].mpData);
+ kfree(pFirmware->mpPrograms[n].mData.mpBlocks);
+ }
+ kfree(pFirmware->mpPrograms);
+ }
+
+ if (pFirmware->mpConfigurations != NULL) {
+ for (n = 0; n < pFirmware->mnConfigurations; n++) {
+ kfree(pFirmware->mpConfigurations[n].mpDescription);
+ kfree(pFirmware->mpConfigurations[n].mData.mpDescription);
+ for (nn = 0; nn < pFirmware->mpConfigurations[n].mData.mnBlocks; nn++)
+ kfree(pFirmware->mpConfigurations[n].mData.mpBlocks[nn].mpData);
+ kfree(pFirmware->mpConfigurations[n].mData.mpBlocks);
+ }
+ kfree(pFirmware->mpConfigurations);
+ }
+
+ if (pFirmware->mpCalibrations != NULL) {
+ for (n = 0; n < pFirmware->mnCalibrations; n++) {
+ kfree(pFirmware->mpCalibrations[n].mpDescription);
+ kfree(pFirmware->mpCalibrations[n].mData.mpDescription);
+ for (nn = 0; nn < pFirmware->mpCalibrations[n].mData.mnBlocks; nn++)
+ kfree(pFirmware->mpCalibrations[n].mData.mpBlocks[nn].mpData);
+ kfree(pFirmware->mpCalibrations[n].mData.mpBlocks);
+ }
+ kfree(pFirmware->mpCalibrations);
+ }
+
+ memset(pFirmware, 0x00, sizeof(struct TFirmware));
+}
+
+static int tas2557_load_calibration(struct tas2557_priv *pTAS2557, char *pFileName)
+{
+ int nResult = 0;
+
+ int nFile;
+ mm_segment_t fs;
+ unsigned char pBuffer[1000];
+ int nSize = 0;
+
+ dev_dbg(pTAS2557->dev, "%s:\n", __func__);
+
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+ nFile = sys_open(pFileName, O_RDONLY, 0);
+
+ dev_info(pTAS2557->dev, "TAS2557 calibration file = %s, handle = %d\n",
+ pFileName, nFile);
+
+ if (nFile >= 0) {
+ nSize = sys_read(nFile, pBuffer, 1000);
+ sys_close(nFile);
+ } else {
+ dev_err(pTAS2557->dev, "TAS2557 cannot open calibration file: %s\n",
+ pFileName);
+ }
+
+ set_fs(fs);
+
+ if (!nSize)
+ goto end;
+
+ tas2557_clear_firmware(pTAS2557->mpCalFirmware);
+ dev_info(pTAS2557->dev, "TAS2557 calibration file size = %d\n", nSize);
+ nResult = fw_parse(pTAS2557, pTAS2557->mpCalFirmware, pBuffer, nSize);
+
+ if (nResult)
+ dev_err(pTAS2557->dev, "TAS2557 calibration file is corrupt\n");
+ else
+ dev_info(pTAS2557->dev, "TAS2557 calibration: %d calibrations\n",
+ pTAS2557->mpCalFirmware->mnCalibrations);
+end:
+
+ return nResult;
+}
+
+static bool tas2557_get_coefficient_in_block(struct tas2557_priv *pTAS2557,
+ struct TBlock *pBlock, int nReg, int *pnValue)
+{
+ int nCoefficient = 0;
+ bool bFound = false;
+ unsigned char *pCommands;
+ int nBook, nPage, nOffset, len;
+ int i, n;
+
+ pCommands = pBlock->mpData;
+ for (i = 0 ; i < pBlock->mnCommands;) {
+ nBook = pCommands[4 * i + 0];
+ nPage = pCommands[4 * i + 1];
+ nOffset = pCommands[4 * i + 2];
+ if ((nOffset < 0x7f) || (nOffset == 0x81))
+ i++;
+ else if (nOffset == 0x85) {
+ len = ((int)nBook << 8) | nPage;
+ nBook = pCommands[4 * i + 4];
+ nPage = pCommands[4 * i + 5];
+ nOffset = pCommands[4 * i + 6];
+ n = 4 * i + 7;
+ i += 2;
+ i += ((len - 1) / 4);
+ if ((len - 1) % 4)
+ i++;
+ if ((nBook != TAS2557_BOOK_ID(nReg))
+ || (nPage != TAS2557_PAGE_ID(nReg)))
+ continue;
+ if (nOffset > TAS2557_PAGE_REG(nReg))
+ continue;
+ if ((len + nOffset) >= (TAS2557_PAGE_REG(nReg) + 4)) {
+ n += (TAS2557_PAGE_REG(nReg) - nOffset);
+ nCoefficient = ((int)pCommands[n] << 24)
+ | ((int)pCommands[n + 1] << 16)
+ | ((int)pCommands[n + 2] << 8)
+ | (int)pCommands[n + 3];
+ bFound = true;
+ break;
+ }
+ } else {
+ dev_err(pTAS2557->dev, "%s, format error %d\n", __func__, nOffset);
+ break;
+ }
+ }
+
+ if (bFound) {
+ *pnValue = nCoefficient;
+ dev_dbg(pTAS2557->dev, "%s, B[0x%x]P[0x%x]R[0x%x]=0x%x\n", __func__,
+ TAS2557_BOOK_ID(nReg), TAS2557_PAGE_ID(nReg), TAS2557_PAGE_REG(nReg),
+ nCoefficient);
+ }
+
+ return bFound;
+}
+
+static bool tas2557_get_coefficient_in_data(struct tas2557_priv *pTAS2557,
+ struct TData *pData, int blockType, int nReg, int *pnValue)
+{
+ bool bFound = false;
+ struct TBlock *pBlock;
+ int i;
+
+ for (i = 0; i < pData->mnBlocks; i++) {
+ pBlock = &(pData->mpBlocks[i]);
+ if (pBlock->mnType == blockType) {
+ bFound = tas2557_get_coefficient_in_block(pTAS2557,
+ pBlock, nReg, pnValue);
+ if (bFound)
+ break;
+ }
+ }
+
+ return bFound;
+}
+
+static bool tas2557_find_Tmax_in_configuration(struct tas2557_priv *pTAS2557,
+ struct TConfiguration *pConfiguration, int *pnTMax)
+{
+ struct TData *pData;
+ bool bFound = false;
+ int nBlockType, nReg, nCoefficient;
+
+ if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P1)
+ nReg = TAS2557_PG2P1_CALI_T_REG;
+ else
+ nReg = TAS2557_PG1P0_CALI_T_REG;
+
+ nBlockType = TAS2557_BLOCK_CFG_COEFF_DEV_A;
+
+ pData = &(pConfiguration->mData);
+ bFound = tas2557_get_coefficient_in_data(pTAS2557, pData, nBlockType, nReg, &nCoefficient);
+ if (bFound)
+ *pnTMax = nCoefficient;
+
+ return bFound;
+}
+
+void tas2557_fw_ready(const struct firmware *pFW, void *pContext)
+{
+ struct tas2557_priv *pTAS2557 = (struct tas2557_priv *) pContext;
+ int nResult;
+ unsigned int nProgram = 0;
+ unsigned int nSampleRate = 0;
+
+#ifdef CONFIG_TAS2557_CODEC
+ mutex_lock(&pTAS2557->codec_lock);
+#endif
+
+#ifdef CONFIG_TAS2557_MISC
+ mutex_lock(&pTAS2557->file_lock);
+#endif
+
+ dev_info(pTAS2557->dev, "%s:\n", __func__);
+
+ if (unlikely(!pFW) || unlikely(!pFW->data)) {
+ dev_err(pTAS2557->dev, "%s firmware is not loaded.\n",
+ TAS2557_FW_NAME);
+ goto end;
+ }
+
+ if (pTAS2557->mpFirmware->mpConfigurations) {
+ nProgram = pTAS2557->mnCurrentProgram;
+ nSampleRate = pTAS2557->mnCurrentSampleRate;
+ dev_dbg(pTAS2557->dev, "clear current firmware\n");
+ tas2557_clear_firmware(pTAS2557->mpFirmware);
+ }
+
+ nResult = fw_parse(pTAS2557, pTAS2557->mpFirmware, (unsigned char *)(pFW->data), pFW->size);
+ release_firmware(pFW);
+ if (nResult < 0) {
+ dev_err(pTAS2557->dev, "firmware is corrupt\n");
+ goto end;
+ }
+
+ if (!pTAS2557->mpFirmware->mnPrograms) {
+ dev_err(pTAS2557->dev, "firmware contains no programs\n");
+ nResult = -EINVAL;
+ goto end;
+ }
+
+ if (!pTAS2557->mpFirmware->mnConfigurations) {
+ dev_err(pTAS2557->dev, "firmware contains no configurations\n");
+ nResult = -EINVAL;
+ goto end;
+ }
+
+ if (nProgram >= pTAS2557->mpFirmware->mnPrograms) {
+ dev_info(pTAS2557->dev,
+ "no previous program, set to default\n");
+ nProgram = 0;
+ }
+
+ pTAS2557->mnCurrentSampleRate = nSampleRate;
+ nResult = tas2557_set_program(pTAS2557, nProgram, -1);
+end:
+
+#ifdef CONFIG_TAS2557_CODEC
+ mutex_unlock(&pTAS2557->codec_lock);
+#endif
+
+#ifdef CONFIG_TAS2557_MISC
+ mutex_unlock(&pTAS2557->file_lock);
+#endif
+}
+
+int tas2557_set_program(struct tas2557_priv *pTAS2557,
+ unsigned int nProgram, int nConfig)
+{
+ struct TProgram *pProgram;
+ unsigned int nConfiguration = 0;
+ unsigned int nSampleRate = 0;
+ unsigned char nGain;
+ bool bFound = false;
+ int nResult = 0;
+
+ if ((!pTAS2557->mpFirmware->mpPrograms) ||
+ (!pTAS2557->mpFirmware->mpConfigurations)) {
+ dev_err(pTAS2557->dev, "Firmware not loaded\n");
+ nResult = 0;
+ goto end;
+ }
+
+ if (nProgram >= pTAS2557->mpFirmware->mnPrograms) {
+ dev_err(pTAS2557->dev, "TAS2557: Program %d doesn't exist\n",
+ nProgram);
+ nResult = 0;
+ goto end;
+ }
+
+ if (nConfig < 0) {
+ nConfiguration = 0;
+ nSampleRate = pTAS2557->mnCurrentSampleRate;
+ while (!bFound && (nConfiguration < pTAS2557->mpFirmware->mnConfigurations)) {
+ if (pTAS2557->mpFirmware->mpConfigurations[nConfiguration].mnProgram == nProgram) {
+ if (nSampleRate == 0) {
+ bFound = true;
+ dev_info(pTAS2557->dev, "find default configuration %d\n", nConfiguration);
+ } else if (nSampleRate == pTAS2557->mpFirmware->mpConfigurations[nConfiguration].mnSamplingRate) {
+ bFound = true;
+ dev_info(pTAS2557->dev, "find matching configuration %d\n", nConfiguration);
+ } else {
+ nConfiguration++;
+ }
+ } else {
+ nConfiguration++;
+ }
+ }
+ if (!bFound) {
+ dev_err(pTAS2557->dev,
+ "Program %d, no valid configuration found for sample rate %d, ignore\n",
+ nProgram, nSampleRate);
+ nResult = 0;
+ goto end;
+ }
+ } else {
+ if (pTAS2557->mpFirmware->mpConfigurations[nConfig].mnProgram != nProgram) {
+ dev_err(pTAS2557->dev, "%s, configuration program doesn't match\n", __func__);
+ nResult = 0;
+ goto end;
+ }
+ nConfiguration = nConfig;
+ }
+
+ pProgram = &(pTAS2557->mpFirmware->mpPrograms[nProgram]);
+ if (pTAS2557->mbPowerUp) {
+ dev_info(pTAS2557->dev,
+ "device powered up, power down to load program %d (%s)\n",
+ nProgram, pProgram->mpName);
+ if (hrtimer_active(&pTAS2557->mtimer))
+ hrtimer_cancel(&pTAS2557->mtimer);
+
+ if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE)
+ pTAS2557->enableIRQ(pTAS2557, false, false);
+
+ nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
+ if (nResult < 0)
+ goto end;
+ }
+
+ pTAS2557->hw_reset(pTAS2557);
+ nResult = pTAS2557->write(pTAS2557, TAS2557_SW_RESET_REG, 0x01);
+ if (nResult < 0)
+ goto end;
+ msleep(1);
+ nResult = tas2557_load_default(pTAS2557);
+ if (nResult < 0)
+ goto end;
+
+ dev_info(pTAS2557->dev, "load program %d (%s)\n", nProgram, pProgram->mpName);
+ nResult = tas2557_load_data(pTAS2557, &(pProgram->mData), TAS2557_BLOCK_PGM_DEV_A);
+ if (nResult < 0)
+ goto end;
+ pTAS2557->mnCurrentProgram = nProgram;
+
+ nResult = tas2557_get_DAC_gain(pTAS2557, &nGain);
+ if (nResult < 0)
+ goto end;
+ pTAS2557->mnDevGain = nGain;
+ pTAS2557->mnDevCurrentGain = nGain;
+
+ nResult = tas2557_load_coefficient(pTAS2557, -1, nConfiguration, false);
+ if (nResult < 0)
+ goto end;
+
+ tas2557_update_edge(pTAS2557);
+
+ if (pTAS2557->mbPowerUp) {
+ pTAS2557->clearIRQ(pTAS2557);
+ dev_dbg(pTAS2557->dev, "device powered up, load startup\n");
+ nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_startup_data);
+ if (nResult < 0)
+ goto end;
+ if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
+ nResult = tas2557_checkPLL(pTAS2557);
+ if (nResult < 0) {
+ nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
+ pTAS2557->mbPowerUp = false;
+ goto end;
+ }
+ }
+ dev_dbg(pTAS2557->dev, "device powered up, load unmute\n");
+ nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_unmute_data);
+ if (nResult < 0)
+ goto end;
+
+ if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
+ pTAS2557->enableIRQ(pTAS2557, true, true);
+ if (!hrtimer_active(&pTAS2557->mtimer)) {
+ pTAS2557->mnDieTvReadCounter = 0;
+ hrtimer_start(&pTAS2557->mtimer,
+ ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
+ }
+ }
+ }
+
+end:
+
+ if (nResult < 0) {
+ if (pTAS2557->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK))
+ failsafe(pTAS2557);
+ }
+ return nResult;
+}
+
+int tas2557_set_calibration(struct tas2557_priv *pTAS2557, int nCalibration)
+{
+ struct TCalibration *pCalibration = NULL;
+ struct TConfiguration *pConfiguration;
+ struct TProgram *pProgram;
+ int nTmax = 0;
+ bool bFound = false;
+ int nResult = 0;
+
+ if ((!pTAS2557->mpFirmware->mpPrograms)
+ || (!pTAS2557->mpFirmware->mpConfigurations)) {
+ dev_err(pTAS2557->dev, "Firmware not loaded\n\r");
+ nResult = 0;
+ goto end;
+ }
+
+ if (nCalibration == 0x00FF) {
+ nResult = tas2557_load_calibration(pTAS2557, TAS2557_CAL_NAME);
+ if (nResult < 0) {
+ dev_info(pTAS2557->dev, "load new calibration file %s fail %d\n",
+ TAS2557_CAL_NAME, nResult);
+ goto end;
+ }
+ nCalibration = 0;
+ }
+
+ if (nCalibration >= pTAS2557->mpCalFirmware->mnCalibrations) {
+ dev_err(pTAS2557->dev,
+ "Calibration %d doesn't exist\n", nCalibration);
+ nResult = 0;
+ goto end;
+ }
+
+ pTAS2557->mnCurrentCalibration = nCalibration;
+ if (pTAS2557->mbLoadConfigurationPrePowerUp)
+ goto end;
+
+ pCalibration = &(pTAS2557->mpCalFirmware->mpCalibrations[nCalibration]);
+ pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]);
+ pConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration]);
+ if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
+ if (pTAS2557->mbBypassTMax) {
+ bFound = tas2557_find_Tmax_in_configuration(pTAS2557, pConfiguration, &nTmax);
+ if (bFound && (nTmax == TAS2557_COEFFICIENT_TMAX)) {
+ dev_dbg(pTAS2557->dev, "%s, config[%s] bypass load calibration\n",
+ __func__, pConfiguration->mpName);
+ goto end;
+ }
+ }
+
+ dev_dbg(pTAS2557->dev, "%s, load calibration\n", __func__);
+ nResult = tas2557_load_data(pTAS2557, &(pCalibration->mData), TAS2557_BLOCK_CFG_COEFF_DEV_A);
+ if (nResult < 0)
+ goto end;
+ }
+
+end:
+ if (nResult < 0) {
+ tas2557_clear_firmware(pTAS2557->mpCalFirmware);
+ nResult = tas2557_set_program(pTAS2557, pTAS2557->mnCurrentProgram, pTAS2557->mnCurrentConfiguration);
+ }
+
+ return nResult;
+}
+
+bool tas2557_get_Cali_prm_r0(struct tas2557_priv *pTAS2557, int *prm_r0)
+{
+ struct TCalibration *pCalibration;
+ struct TData *pData;
+ int nReg;
+ int nCali_Re;
+ bool bFound = false;
+ int nBlockType;
+
+ if (!pTAS2557->mpCalFirmware->mnCalibrations) {
+ dev_err(pTAS2557->dev, "%s, no calibration data\n", __func__);
+ goto end;
+ }
+
+ if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P1)
+ nReg = TAS2557_PG2P1_CALI_R0_REG;
+ else
+ nReg = TAS2557_PG1P0_CALI_R0_REG;
+
+ nBlockType = TAS2557_BLOCK_CFG_COEFF_DEV_A;
+
+ pCalibration = &(pTAS2557->mpCalFirmware->mpCalibrations[pTAS2557->mnCurrentCalibration]);
+ pData = &(pCalibration->mData);
+
+ bFound = tas2557_get_coefficient_in_data(pTAS2557, pData, nBlockType, nReg, &nCali_Re);
+
+end:
+
+ if (bFound)
+ *prm_r0 = nCali_Re;
+
+ return bFound;
+}
+
+int tas2557_parse_dt(struct device *dev, struct tas2557_priv *pTAS2557)
+{
+ struct device_node *np = dev->of_node;
+ int rc = 0, ret = 0;
+ unsigned int value;
+
+ pTAS2557->mnResetGPIO = of_get_named_gpio(np, "ti,cdc-reset-gpio", 0);
+ if (!gpio_is_valid(pTAS2557->mnResetGPIO)) {
+ dev_err(pTAS2557->dev, "Looking up %s property in node %s failed %d\n",
+ "ti,cdc-reset-gpio", np->full_name,
+ pTAS2557->mnResetGPIO);
+ ret = -EINVAL;
+ goto end;
+ } else
+ dev_dbg(pTAS2557->dev, "ti,cdc-reset-gpio=%d\n", pTAS2557->mnResetGPIO);
+
+ pTAS2557->mnGpioINT = of_get_named_gpio(np, "ti,irq-gpio", 0);
+ if (!gpio_is_valid(pTAS2557->mnGpioINT))
+ dev_err(pTAS2557->dev, "Looking up %s property in node %s failed %d\n",
+ "ti,irq-gpio", np->full_name,
+ pTAS2557->mnGpioINT);
+
+
+ rc = of_property_read_u32(np, "ti,i2s-bits", &value);
+ if (rc)
+ dev_err(pTAS2557->dev, "Looking up %s property in node %s failed %d\n",
+ "ti,i2s-bits", np->full_name, rc);
+ else
+ pTAS2557->mnI2SBits = value;
+
+ rc = of_property_read_u32(np, "ti,bypass-tmax", &value);
+ if (rc)
+ dev_err(pTAS2557->dev, "Looking up %s property in node %s failed %d\n",
+ "ti,bypass-tmax", np->full_name, rc);
+ else
+ pTAS2557->mbBypassTMax = (value > 0);
+
+end:
+
+ return ret;
+}
+
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_DESCRIPTION("TAS2557 common functions for Android Linux");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/tas2557/tas2557-core.h b/sound/soc/codecs/tas2557/tas2557-core.h
new file mode 100755
index 0000000..cb46eee
--- /dev/null
+++ b/sound/soc/codecs/tas2557/tas2557-core.h
@@ -0,0 +1,79 @@
+/*
+** =============================================================================
+** Copyright (c) 2016 Texas Instruments Inc.
+**
+** This program is free software; you can redistribute it and/or modify it under
+** the terms of the GNU General Public License as published by the Free Software
+** Foundation; version 2.
+**
+** This program is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+**
+** File:
+** tas2557-core.h
+**
+** Description:
+** header file for tas2557-core.c
+**
+** =============================================================================
+*/
+
+#ifndef _TAS2557_CORE_H
+#define _TAS2557_CORE_H
+
+#include "tas2557.h"
+
+#define TAS2557_YRAM_BOOK1 140
+
+#define TAS2557_YRAM1_PAGE 42
+#define TAS2557_YRAM1_START_REG 88
+#define TAS2557_YRAM1_END_REG 127
+
+#define TAS2557_YRAM2_START_PAGE 43
+#define TAS2557_YRAM2_END_PAGE 49
+#define TAS2557_YRAM2_START_REG 8
+#define TAS2557_YRAM2_END_REG 127
+
+#define TAS2557_YRAM3_PAGE 50
+#define TAS2557_YRAM3_START_REG 8
+#define TAS2557_YRAM3_END_REG 27
+
+/* should not include B0_P53_R44-R47 */
+#define TAS2557_YRAM_BOOK2 0
+#define TAS2557_YRAM4_START_PAGE 50
+#define TAS2557_YRAM4_END_PAGE 60
+#define TAS2557_YRAM4_START_REG 8
+#define TAS2557_YRAM4_END_REG 127
+
+#define TAS2557_YRAM5_PAGE 61
+#define TAS2557_YRAM5_START_REG 8
+#define TAS2557_YRAM5_END_REG 27
+
+#define TAS2557_COEFFICIENT_TMAX 0x7fffffff
+#define TAS2557_SAFE_GUARD_PATTERN 0x5a
+#define LOW_TEMPERATURE_CHECK_PERIOD 5000 /* 5 second */
+
+struct TYCRC {
+ unsigned char mnOffset;
+ unsigned char mnLen;
+};
+
+int tas2557_enable(struct tas2557_priv *pTAS2557, bool bEnable);
+int tas2557_SA_DevChnSetup(struct tas2557_priv *pTAS2557, unsigned int mode);
+int tas2557_get_die_temperature(struct tas2557_priv *pTAS2557, int *pTemperature);
+int tas2557_set_sampling_rate(struct tas2557_priv *pTAS2557, unsigned int nSamplingRate);
+int tas2557_set_bit_rate(struct tas2557_priv *pTAS2557, unsigned int nBitRate);
+int tas2557_get_bit_rate(struct tas2557_priv *pTAS2557, unsigned char *pBitRate);
+int tas2557_set_config(struct tas2557_priv *pTAS2557, int config);
+void tas2557_fw_ready(const struct firmware *pFW, void *pContext);
+bool tas2557_get_Cali_prm_r0(struct tas2557_priv *pTAS2557, int *prm_r0);
+int tas2557_set_program(struct tas2557_priv *pTAS2557, unsigned int nProgram, int nConfig);
+int tas2557_set_calibration(struct tas2557_priv *pTAS2557, int nCalibration);
+int tas2557_load_default(struct tas2557_priv *pTAS2557);
+int tas2557_parse_dt(struct device *dev, struct tas2557_priv *pTAS2557);
+int tas2557_get_DAC_gain(struct tas2557_priv *pTAS2557, unsigned char *pnGain);
+int tas2557_set_DAC_gain(struct tas2557_priv *pTAS2557, unsigned int nGain);
+int tas2557_configIRQ(struct tas2557_priv *pTAS2557);
+int tas2557_update_edge(struct tas2557_priv *pTAS2557);
+#endif /* _TAS2557_CORE_H */
diff --git a/sound/soc/codecs/tas2557/tas2557-misc.c b/sound/soc/codecs/tas2557/tas2557-misc.c
new file mode 100755
index 0000000..da19d41
--- /dev/null
+++ b/sound/soc/codecs/tas2557/tas2557-misc.c
@@ -0,0 +1,595 @@
+/*
+** =============================================================================
+** Copyright (c) 2016 Texas Instruments Inc.
+**
+** This program is free software; you can redistribute it and/or modify it under
+** the terms of the GNU General Public License as published by the Free Software
+** Foundation; version 2.
+**
+** This program is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+**
+** File:
+** tas2557-misc.c
+**
+** Description:
+** misc driver for Texas Instruments TAS2557 High Performance 4W Smart Amplifier
+**
+** =============================================================================
+*/
+
+#ifdef CONFIG_TAS2557_MISC
+
+#define DEBUG
+#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/gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/firmware.h>
+#include <linux/regmap.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/slab.h>
+#include <linux/syscalls.h>
+#include <linux/fcntl.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+
+#include "tas2557.h"
+#include "tas2557-core.h"
+#include "tas2557-misc.h"
+#include <linux/dma-mapping.h>
+
+static int g_logEnable = 1;
+static struct tas2557_priv *g_tas2557;
+
+static int tas2557_file_open(struct inode *inode, struct file *file)
+{
+ struct tas2557_priv *pTAS2557 = g_tas2557;
+
+ if (!try_module_get(THIS_MODULE))
+ return -ENODEV;
+
+ file->private_data = (void *)pTAS2557;
+ if (g_logEnable)
+ dev_info(pTAS2557->dev, "%s\n", __func__);
+ return 0;
+}
+
+static int tas2557_file_release(struct inode *inode, struct file *file)
+{
+ struct tas2557_priv *pTAS2557 = (struct tas2557_priv *)file->private_data;
+
+ if (g_logEnable)
+ dev_info(pTAS2557->dev, "%s\n", __func__);
+ file->private_data = (void *)NULL;
+ module_put(THIS_MODULE);
+
+ return 0;
+}
+
+static ssize_t tas2557_file_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+{
+ struct tas2557_priv *pTAS2557 = (struct tas2557_priv *)file->private_data;
+ int ret = 0;
+ unsigned int nValue = 0;
+ unsigned char value = 0;
+ unsigned char *p_kBuf = NULL;
+
+ mutex_lock(&pTAS2557->file_lock);
+
+ switch (pTAS2557->mnDBGCmd) {
+ case TIAUDIO_CMD_REG_READ: {
+ if (g_logEnable)
+ dev_info(pTAS2557->dev, "TIAUDIO_CMD_REG_READ: current_reg = 0x%x, count=%d\n",
+ pTAS2557->mnCurrentReg, (int)count);
+ if (count == 1) {
+ ret = pTAS2557->read(pTAS2557, pTAS2557->mnCurrentReg, &nValue);
+ if (ret < 0)
+ break;
+
+ value = (u8)nValue;
+ if (g_logEnable)
+ dev_info(pTAS2557->dev, "TIAUDIO_CMD_REG_READ: nValue=0x%x, value=0x%x\n", nValue, value);
+ ret = copy_to_user(buf, &value, 1);
+ if (ret != 0) {
+ /* Failed to copy all the data, exit */
+ dev_err(pTAS2557->dev, "copy to user fail %d\n", ret);
+ }
+ } else if (count > 1) {
+ p_kBuf = kzalloc(count, GFP_KERNEL);
+ if (p_kBuf != NULL) {
+ ret = pTAS2557->bulk_read(pTAS2557, pTAS2557->mnCurrentReg, p_kBuf, count);
+ if (ret < 0)
+ break;
+ ret = copy_to_user(buf, p_kBuf, count);
+ if (ret != 0) {
+ /* Failed to copy all the data, exit */
+ dev_err(pTAS2557->dev, "copy to user fail %d\n", ret);
+ }
+ kfree(p_kBuf);
+ } else
+ dev_err(pTAS2557->dev, "read no mem\n");
+ }
+ }
+ break;
+
+ case TIAUDIO_CMD_PROGRAM: {
+ if ((pTAS2557->mpFirmware->mnConfigurations > 0)
+ && (pTAS2557->mpFirmware->mnPrograms > 0)) {
+ if (g_logEnable)
+ dev_info(pTAS2557->dev, "TIAUDIO_CMD_PROGRAM: count = %d\n", (int)count);
+
+ if (count == PROGRAM_BUF_SIZE) {
+ p_kBuf = kzalloc(count, GFP_KERNEL);
+ if (p_kBuf != NULL) {
+ struct TProgram *pProgram =
+ &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]);
+ p_kBuf[0] = pTAS2557->mpFirmware->mnPrograms;
+ p_kBuf[1] = pTAS2557->mnCurrentProgram;
+ p_kBuf[2] = pProgram->mnAppMode;
+ p_kBuf[3] = (pProgram->mnBoost&0xff00)>>8;
+ p_kBuf[4] = (pProgram->mnBoost&0x00ff);
+ memcpy(&p_kBuf[5], pProgram->mpName, FW_NAME_SIZE);
+ strlcpy(&p_kBuf[5+FW_NAME_SIZE], pProgram->mpDescription, strlen(pProgram->mpDescription) + 1);
+ ret = copy_to_user(buf, p_kBuf, count);
+ if (ret != 0) {
+ /* Failed to copy all the data, exit */
+ dev_err(pTAS2557->dev, "copy to user fail %d\n", ret);
+ }
+ kfree(p_kBuf);
+ } else
+ dev_err(pTAS2557->dev, "read no mem\n");
+ } else
+ dev_err(pTAS2557->dev, "read buffer not sufficient\n");
+ } else
+ dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__);
+ }
+ break;
+
+ case TIAUDIO_CMD_CONFIGURATION: {
+ if ((pTAS2557->mpFirmware->mnConfigurations > 0)
+ && (pTAS2557->mpFirmware->mnPrograms > 0)) {
+ if (g_logEnable)
+ dev_info(pTAS2557->dev, "TIAUDIO_CMD_CONFIGURATION: count = %d\n", (int)count);
+ if (count == CONFIGURATION_BUF_SIZE) {
+ p_kBuf = kzalloc(count, GFP_KERNEL);
+ if (p_kBuf != NULL) {
+ struct TConfiguration *pConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration]);
+
+ p_kBuf[0] = pTAS2557->mpFirmware->mnConfigurations;
+ p_kBuf[1] = pTAS2557->mnCurrentConfiguration;
+ memcpy(&p_kBuf[2], pConfiguration->mpName, FW_NAME_SIZE);
+ p_kBuf[2+FW_NAME_SIZE] = pConfiguration->mnProgram;
+ p_kBuf[3+FW_NAME_SIZE] = pConfiguration->mnPLL;
+ p_kBuf[4+FW_NAME_SIZE] = (pConfiguration->mnSamplingRate&0x000000ff);
+ p_kBuf[5+FW_NAME_SIZE] = ((pConfiguration->mnSamplingRate&0x0000ff00)>>8);
+ p_kBuf[6+FW_NAME_SIZE] = ((pConfiguration->mnSamplingRate&0x00ff0000)>>16);
+ p_kBuf[7+FW_NAME_SIZE] = ((pConfiguration->mnSamplingRate&0xff000000)>>24);
+ strlcpy(&p_kBuf[8+FW_NAME_SIZE], pConfiguration->mpDescription, strlen(pConfiguration->mpDescription)+1);
+ ret = copy_to_user(buf, p_kBuf, count);
+ if (ret != 0) {
+ /* Failed to copy all the data, exit */
+ dev_err(pTAS2557->dev, "copy to user fail %d\n", ret);
+ }
+ kfree(p_kBuf);
+ } else
+ dev_err(pTAS2557->dev, "read no mem\n");
+ } else
+ dev_err(pTAS2557->dev, "read buffer not sufficient\n");
+ } else
+ dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__);
+ }
+ break;
+
+ case TIAUDIO_CMD_FW_TIMESTAMP: {
+ if (g_logEnable)
+ dev_info(pTAS2557->dev, "TIAUDIO_CMD_FW_TIMESTAMP: count = %d\n", (int)count);
+
+ if (count == 4) {
+ p_kBuf = kzalloc(count, GFP_KERNEL);
+ if (p_kBuf != NULL) {
+ p_kBuf[0] = (pTAS2557->mpFirmware->mnTimeStamp&0x000000ff);
+ p_kBuf[1] = ((pTAS2557->mpFirmware->mnTimeStamp&0x0000ff00)>>8);
+ p_kBuf[2] = ((pTAS2557->mpFirmware->mnTimeStamp&0x00ff0000)>>16);
+ p_kBuf[3] = ((pTAS2557->mpFirmware->mnTimeStamp&0xff000000)>>24);
+ ret = copy_to_user(buf, p_kBuf, count);
+ if (ret != 0) {
+ /* Failed to copy all the data, exit */
+ dev_err(pTAS2557->dev, "copy to user fail %d\n", ret);
+ }
+ kfree(p_kBuf);
+ } else
+ dev_err(pTAS2557->dev, "read no mem\n");
+ }
+ }
+ break;
+
+ case TIAUDIO_CMD_CALIBRATION: {
+ if (g_logEnable)
+ dev_info(pTAS2557->dev, "TIAUDIO_CMD_CALIBRATION: count = %d\n", (int)count);
+
+ if (count == 1) {
+ unsigned char curCal = pTAS2557->mnCurrentCalibration;
+
+ ret = copy_to_user(buf, &curCal, 1);
+ if (ret != 0) {
+ /* Failed to copy all the data, exit */
+ dev_err(pTAS2557->dev, "copy to user fail %d\n", ret);
+ }
+ }
+ }
+ break;
+
+ case TIAUDIO_CMD_SAMPLERATE: {
+ if (g_logEnable)
+ dev_info(pTAS2557->dev, "TIAUDIO_CMD_SAMPLERATE: count = %d\n", (int)count);
+ if (count == 4) {
+ p_kBuf = kzalloc(count, GFP_KERNEL);
+ if (p_kBuf != NULL) {
+ struct TConfiguration *pConfiguration =
+ &(pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration]);
+
+ p_kBuf[0] = (pConfiguration->mnSamplingRate&0x000000ff);
+ p_kBuf[1] = ((pConfiguration->mnSamplingRate&0x0000ff00)>>8);
+ p_kBuf[2] = ((pConfiguration->mnSamplingRate&0x00ff0000)>>16);
+ p_kBuf[3] = ((pConfiguration->mnSamplingRate&0xff000000)>>24);
+
+ ret = copy_to_user(buf, p_kBuf, count);
+ if (ret != 0) {
+ /* Failed to copy all the data, exit */
+ dev_err(pTAS2557->dev, "copy to user fail %d\n", ret);
+ }
+
+ kfree(p_kBuf);
+ } else
+ dev_err(pTAS2557->dev, "read no mem\n");
+ }
+ }
+ break;
+
+ case TIAUDIO_CMD_BITRATE: {
+ if (g_logEnable)
+ dev_info(pTAS2557->dev,
+ "TIAUDIO_CMD_BITRATE: count = %d\n", (int)count);
+
+ if (count == 1) {
+ unsigned char bitRate = 0;
+ ret = tas2557_get_bit_rate(pTAS2557, &bitRate);
+ if (ret >= 0) {
+ ret = copy_to_user(buf, &bitRate, 1);
+ if (ret != 0) {
+ /* Failed to copy all the data, exit */
+ dev_err(pTAS2557->dev, "copy to user fail %d\n", ret);
+ }
+ }
+ }
+ }
+ break;
+
+ case TIAUDIO_CMD_DACVOLUME: {
+ if (g_logEnable)
+ dev_info(pTAS2557->dev, "TIAUDIO_CMD_DACVOLUME: count = %d\n", (int)count);
+
+ if (count == 1) {
+ unsigned char volume = 0;
+
+ ret = tas2557_get_DAC_gain(pTAS2557, &volume);
+ if (ret >= 0) {
+ ret = copy_to_user(buf, &volume, 1);
+ if (ret != 0) {
+ /* Failed to copy all the data, exit */
+ dev_err(pTAS2557->dev, "copy to user fail %d\n", ret);
+ }
+ }
+ }
+ }
+ break;
+ }
+ pTAS2557->mnDBGCmd = 0;
+
+ mutex_unlock(&pTAS2557->file_lock);
+ return count;
+}
+
+static ssize_t tas2557_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+{
+ struct tas2557_priv *pTAS2557 = (struct tas2557_priv *)file->private_data;
+ int ret = 0;
+ unsigned char *p_kBuf = NULL;
+ unsigned int reg = 0;
+ unsigned int len = 0;
+
+ mutex_lock(&pTAS2557->file_lock);
+
+ p_kBuf = kzalloc(count, GFP_KERNEL);
+ if (p_kBuf == NULL) {
+ dev_err(pTAS2557->dev, "write no mem\n");
+ goto err;
+ }
+
+ ret = copy_from_user(p_kBuf, buf, count);
+ if (ret != 0) {
+ dev_err(pTAS2557->dev, "copy_from_user failed.\n");
+ goto err;
+ }
+
+ pTAS2557->mnDBGCmd = p_kBuf[0];
+ switch (pTAS2557->mnDBGCmd) {
+ case TIAUDIO_CMD_REG_WITE:
+ if (count > 5) {
+ reg = ((unsigned int)p_kBuf[1] << 24)
+ + ((unsigned int)p_kBuf[2] << 16)
+ + ((unsigned int)p_kBuf[3] << 8)
+ + (unsigned int)p_kBuf[4];
+ len = count - 5;
+ if (len == 1) {
+ ret = pTAS2557->write(pTAS2557, reg, p_kBuf[5]);
+ if (g_logEnable)
+ dev_info(pTAS2557->dev, "TIAUDIO_CMD_REG_WITE, Reg=0x%x, Val=0x%x\n", reg, p_kBuf[5]);
+ } else
+ ret = pTAS2557->bulk_write(pTAS2557, reg, &p_kBuf[5], len);
+ } else
+ dev_err(pTAS2557->dev, "%s, write len fail, count=%d.\n", __func__, (int)count);
+ pTAS2557->mnDBGCmd = 0;
+ break;
+
+ case TIAUDIO_CMD_REG_READ:
+ if (count == 5) {
+ pTAS2557->mnCurrentReg = ((unsigned int)p_kBuf[1] << 24)
+ + ((unsigned int)p_kBuf[2] << 16)
+ + ((unsigned int)p_kBuf[3] << 8)
+ + (unsigned int)p_kBuf[4];
+ if (g_logEnable)
+ dev_info(pTAS2557->dev, "TIAUDIO_CMD_REG_READ whole=0x%x\n", pTAS2557->mnCurrentReg);
+ } else
+ dev_err(pTAS2557->dev, "read len fail.\n");
+ break;
+
+ case TIAUDIO_CMD_DEBUG_ON:
+ if (count == 2)
+ g_logEnable = p_kBuf[1];
+
+ pTAS2557->mnDBGCmd = 0;
+ break;
+
+ case TIAUDIO_CMD_PROGRAM:
+ {
+ if (count == 2) {
+ if ((pTAS2557->mpFirmware->mnConfigurations > 0)
+ && (pTAS2557->mpFirmware->mnPrograms > 0)) {
+ int config = -1;
+
+ if (p_kBuf[1] == pTAS2557->mnCurrentProgram)
+ config = pTAS2557->mnCurrentConfiguration;
+ if (g_logEnable)
+ dev_info(pTAS2557->dev, "TIAUDIO_CMD_PROGRAM, set to %d, cfg=%d\n", p_kBuf[1], config);
+ tas2557_set_program(pTAS2557, p_kBuf[1], config);
+ pTAS2557->mnDBGCmd = 0;
+ } else
+ dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__);
+ }
+ }
+ break;
+
+ case TIAUDIO_CMD_CONFIGURATION:
+ {
+ if (count == 2) {
+ if ((pTAS2557->mpFirmware->mnConfigurations > 0)
+ && (pTAS2557->mpFirmware->mnPrograms > 0)) {
+ if (g_logEnable)
+ dev_info(pTAS2557->dev, "TIAUDIO_CMD_CONFIGURATION, set to %d\n", p_kBuf[1]);
+ tas2557_set_config(pTAS2557, p_kBuf[1]);
+ pTAS2557->mnDBGCmd = 0;
+ } else
+ dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__);
+ }
+ }
+ break;
+
+ case TIAUDIO_CMD_FW_TIMESTAMP:
+ /*let go*/
+ break;
+
+ case TIAUDIO_CMD_CALIBRATION:
+ {
+ if (count == 2) {
+ if ((pTAS2557->mpFirmware->mnConfigurations > 0)
+ && (pTAS2557->mpFirmware->mnPrograms > 0)) {
+ if (g_logEnable)
+ dev_info(pTAS2557->dev, "TIAUDIO_CMD_CALIBRATION, set to %d\n", p_kBuf[1]);
+ tas2557_set_calibration(pTAS2557, p_kBuf[1]);
+ pTAS2557->mnDBGCmd = 0;
+ }
+ }
+ }
+ break;
+
+ case TIAUDIO_CMD_SAMPLERATE:
+ if (count == 5) {
+ unsigned int nSampleRate = ((unsigned int)p_kBuf[1] << 24) +
+ ((unsigned int)p_kBuf[2] << 16) +
+ ((unsigned int)p_kBuf[3] << 8) +
+ (unsigned int)p_kBuf[4];
+ if (g_logEnable)
+ dev_info(pTAS2557->dev, "TIAUDIO_CMD_SAMPLERATE, set to %d\n", nSampleRate);
+
+ tas2557_set_sampling_rate(pTAS2557, nSampleRate);
+ }
+ break;
+
+ case TIAUDIO_CMD_BITRATE:
+ if (count == 2) {
+ if (g_logEnable)
+ dev_info(pTAS2557->dev, "TIAUDIO_CMD_BITRATE, set to %d\n", p_kBuf[1]);
+
+ tas2557_set_bit_rate(pTAS2557, p_kBuf[1]);
+ }
+ break;
+
+ case TIAUDIO_CMD_DACVOLUME:
+ if (count == 2) {
+ unsigned char volume;
+
+ volume = (p_kBuf[1] & 0x0f);
+ if (g_logEnable)
+ dev_info(pTAS2557->dev, "TIAUDIO_CMD_DACVOLUME, set to %d\n", volume);
+
+ ret = tas2557_set_DAC_gain(pTAS2557, volume);
+ if (ret < 0)
+ goto err;
+ }
+ break;
+
+ case TIAUDIO_CMD_SPEAKER:
+ if (count == 2) {
+ if (g_logEnable)
+ dev_info(pTAS2557->dev, "TIAUDIO_CMD_SPEAKER, set to %d\n", p_kBuf[1]);
+ tas2557_enable(pTAS2557, (p_kBuf[1] > 0));
+ }
+ break;
+
+ case TIAUDIO_CMD_FW_RELOAD:
+ if (count == 1) {
+ const char *pFWName;
+ if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P1)
+ pFWName = TAS2557_FW_NAME;
+ else if (pTAS2557->mnPGID == TAS2557_PG_VERSION_1P0)
+ pFWName = TAS2557_PG1P0_FW_NAME;
+ else
+ break;
+
+ ret = request_firmware_nowait(THIS_MODULE, 1, pFWName,
+ pTAS2557->dev, GFP_KERNEL, pTAS2557, tas2557_fw_ready);
+
+ if (g_logEnable)
+ dev_info(pTAS2557->dev, "TIAUDIO_CMD_FW_RELOAD: ret = %d\n", ret);
+ }
+ break;
+
+ default:
+ pTAS2557->mnDBGCmd = 0;
+ break;
+ }
+
+err:
+ if (p_kBuf != NULL)
+ kfree(p_kBuf);
+
+ mutex_unlock(&pTAS2557->file_lock);
+
+ return count;
+}
+
+static long tas2557_file_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct tas2557_priv *pTAS2557 = file->private_data;
+ int ret = 0;
+
+ mutex_lock(&pTAS2557->file_lock);
+
+ switch (cmd) {
+ case SMARTPA_SPK_DAC_VOLUME:
+ {
+ }
+ break;
+
+ case SMARTPA_SPK_POWER_ON:
+ {
+ tas2557_enable(pTAS2557, true);
+ }
+ break;
+
+ case SMARTPA_SPK_POWER_OFF:
+ {
+ tas2557_enable(pTAS2557, false);
+ }
+ break;
+
+ case SMARTPA_SPK_SWITCH_PROGRAM:
+ {
+ if ((pTAS2557->mpFirmware->mnConfigurations > 0)
+ && (pTAS2557->mpFirmware->mnPrograms > 0))
+ tas2557_set_program(pTAS2557, arg, -1);
+ }
+ break;
+
+ case SMARTPA_SPK_SWITCH_CONFIGURATION:
+ {
+ if ((pTAS2557->mpFirmware->mnConfigurations > 0)
+ && (pTAS2557->mpFirmware->mnPrograms > 0))
+ tas2557_set_config(pTAS2557, arg);
+ }
+ break;
+
+ case SMARTPA_SPK_SWITCH_CALIBRATION:
+ {
+ if ((pTAS2557->mpFirmware->mnConfigurations > 0)
+ && (pTAS2557->mpFirmware->mnPrograms > 0))
+ tas2557_set_calibration(pTAS2557, arg);
+ }
+ break;
+
+ case SMARTPA_SPK_SET_SAMPLERATE:
+ {
+ tas2557_set_sampling_rate(pTAS2557, arg);
+ }
+ break;
+
+ case SMARTPA_SPK_SET_BITRATE:
+ {
+ tas2557_set_bit_rate(pTAS2557, arg);
+ }
+ break;
+ }
+
+ mutex_unlock(&pTAS2557->file_lock);
+ return ret;
+}
+
+static const struct file_operations fops = {
+ .owner = THIS_MODULE,
+ .read = tas2557_file_read,
+ .write = tas2557_file_write,
+ .unlocked_ioctl = tas2557_file_unlocked_ioctl,
+ .open = tas2557_file_open,
+ .release = tas2557_file_release,
+};
+
+#define MODULE_NAME "tas2557"
+static struct miscdevice tas2557_misc = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = MODULE_NAME,
+ .fops = &fops,
+};
+
+int tas2557_register_misc(struct tas2557_priv *pTAS2557)
+{
+ int ret = 0;
+
+ g_tas2557 = pTAS2557;
+
+ ret = misc_register(&tas2557_misc);
+ if (ret)
+ dev_err(pTAS2557->dev, "TAS2557 misc fail: %d\n", ret);
+
+ dev_info(pTAS2557->dev, "%s, leave\n", __func__);
+
+ return ret;
+}
+
+int tas2557_deregister_misc(struct tas2557_priv *pTAS2557)
+{
+ misc_deregister(&tas2557_misc);
+ return 0;
+}
+
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_DESCRIPTION("TAS2557 Misc Smart Amplifier driver");
+MODULE_LICENSE("GPL v2");
+#endif
diff --git a/sound/soc/codecs/tas2557/tas2557-misc.h b/sound/soc/codecs/tas2557/tas2557-misc.h
new file mode 100755
index 0000000..38bfa64
--- /dev/null
+++ b/sound/soc/codecs/tas2557/tas2557-misc.h
@@ -0,0 +1,57 @@
+/*
+** =============================================================================
+** Copyright (c) 2016 Texas Instruments Inc.
+**
+** This program is free software; you can redistribute it and/or modify it under
+** the terms of the GNU General Public License as published by the Free Software
+** Foundation; version 2.
+**
+** This program is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+**
+** File:
+** tas2557-misc.h
+**
+** Description:
+** header file for tas2557-misc.c
+**
+** =============================================================================
+*/
+
+#ifndef _TAS2557_MISC_H
+#define _TAS2557_MISC_H
+
+#define FW_NAME_SIZE 64
+#define FW_DESCRIPTION_SIZE 256
+#define PROGRAM_BUF_SIZE (5 + FW_NAME_SIZE + FW_DESCRIPTION_SIZE)
+#define CONFIGURATION_BUF_SIZE (8 + FW_NAME_SIZE + FW_DESCRIPTION_SIZE)
+
+#define TIAUDIO_CMD_REG_WITE 1
+#define TIAUDIO_CMD_REG_READ 2
+#define TIAUDIO_CMD_DEBUG_ON 3
+#define TIAUDIO_CMD_PROGRAM 4
+#define TIAUDIO_CMD_CONFIGURATION 5
+#define TIAUDIO_CMD_FW_TIMESTAMP 6
+#define TIAUDIO_CMD_CALIBRATION 7
+#define TIAUDIO_CMD_SAMPLERATE 8
+#define TIAUDIO_CMD_BITRATE 9
+#define TIAUDIO_CMD_DACVOLUME 10
+#define TIAUDIO_CMD_SPEAKER 11
+#define TIAUDIO_CMD_FW_RELOAD 12
+
+#define TAS2557_MAGIC_NUMBER 0x3537 /* '2557' */
+
+#define SMARTPA_SPK_DAC_VOLUME _IOWR(TAS2557_MAGIC_NUMBER, 1, unsigned long)
+#define SMARTPA_SPK_POWER_ON _IOWR(TAS2557_MAGIC_NUMBER, 2, unsigned long)
+#define SMARTPA_SPK_POWER_OFF _IOWR(TAS2557_MAGIC_NUMBER, 3, unsigned long)
+#define SMARTPA_SPK_SWITCH_PROGRAM _IOWR(TAS2557_MAGIC_NUMBER, 4, unsigned long)
+#define SMARTPA_SPK_SWITCH_CONFIGURATION _IOWR(TAS2557_MAGIC_NUMBER, 5, unsigned long)
+#define SMARTPA_SPK_SWITCH_CALIBRATION _IOWR(TAS2557_MAGIC_NUMBER, 6, unsigned long)
+#define SMARTPA_SPK_SET_SAMPLERATE _IOWR(TAS2557_MAGIC_NUMBER, 7, unsigned long)
+#define SMARTPA_SPK_SET_BITRATE _IOWR(TAS2557_MAGIC_NUMBER, 8, unsigned long)
+
+int tas2557_register_misc(struct tas2557_priv *pTAS2557);
+int tas2557_deregister_misc(struct tas2557_priv *pTAS2557);
+
+#endif /* _TAS2557_MISC_H */
diff --git a/sound/soc/codecs/tas2557/tas2557-regmap.c b/sound/soc/codecs/tas2557/tas2557-regmap.c
new file mode 100755
index 0000000..63ba6e5
--- /dev/null
+++ b/sound/soc/codecs/tas2557/tas2557-regmap.c
@@ -0,0 +1,904 @@
+/*
+** =============================================================================
+** Copyright (c) 2016 Texas Instruments Inc.
+**
+** This program is free software; you can redistribute it and/or modify it under
+** the terms of the GNU General Public License as published by the Free Software
+** Foundation; version 2.
+**
+** This program is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+**
+** File:
+** tas2557-regmap.c
+**
+** Description:
+** I2C driver with regmap for Texas Instruments TAS2557 High Performance 4W Smart Amplifier
+**
+** =============================================================================
+*/
+
+#ifdef CONFIG_TAS2557_REGMAP
+
+#define DEBUG
+#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/gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/firmware.h>
+#include <linux/regmap.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/slab.h>
+#include <linux/syscalls.h>
+#include <linux/fcntl.h>
+#include <linux/uaccess.h>
+#include <linux/interrupt.h>
+#include "tas2557.h"
+#include "tas2557-core.h"
+
+#ifdef CONFIG_TAS2557_CODEC
+#include "tas2557-codec.h"
+#endif
+
+#ifdef CONFIG_TAS2557_MISC
+#include "tas2557-misc.h"
+#endif
+
+#define ENABLE_TILOAD
+#ifdef ENABLE_TILOAD
+#include "tiload.h"
+#endif
+
+#define LOW_TEMPERATURE_GAIN 6
+#define LOW_TEMPERATURE_COUNTER 12
+
+static int tas2557_change_book_page(
+ struct tas2557_priv *pTAS2557,
+ unsigned char nBook,
+ unsigned char nPage)
+{
+ int nResult = 0;
+
+ if ((pTAS2557->mnCurrentBook == nBook)
+ && pTAS2557->mnCurrentPage == nPage)
+ goto end;
+
+ if (pTAS2557->mnCurrentBook != nBook) {
+ nResult = regmap_write(pTAS2557->mpRegmap, TAS2557_BOOKCTL_PAGE, 0);
+ if (nResult < 0) {
+ dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n",
+ __func__, __LINE__, nResult);
+ goto end;
+ }
+ pTAS2557->mnCurrentPage = 0;
+ nResult = regmap_write(pTAS2557->mpRegmap, TAS2557_BOOKCTL_REG, nBook);
+ if (nResult < 0) {
+ dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n",
+ __func__, __LINE__, nResult);
+ goto end;
+ }
+ pTAS2557->mnCurrentBook = nBook;
+ if (nPage != 0) {
+ nResult = regmap_write(pTAS2557->mpRegmap, TAS2557_BOOKCTL_PAGE, nPage);
+ if (nResult < 0) {
+ dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n",
+ __func__, __LINE__, nResult);
+ goto end;
+ }
+ pTAS2557->mnCurrentPage = nPage;
+ }
+ } else if (pTAS2557->mnCurrentPage != nPage) {
+ nResult = regmap_write(pTAS2557->mpRegmap, TAS2557_BOOKCTL_PAGE, nPage);
+ if (nResult < 0) {
+ dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n",
+ __func__, __LINE__, nResult);
+ goto end;
+ }
+ pTAS2557->mnCurrentPage = nPage;
+ }
+
+end:
+ if (nResult < 0)
+ pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM;
+ else
+ pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM;
+
+ return nResult;
+}
+
+static int tas2557_dev_read(
+ struct tas2557_priv *pTAS2557,
+ unsigned int nRegister,
+ unsigned int *pValue)
+{
+ int nResult = 0;
+ unsigned int Value = 0;
+
+ mutex_lock(&pTAS2557->dev_lock);
+ if (pTAS2557->mbTILoadActive) {
+ if (!(nRegister & 0x80000000))
+ goto end; /* let only reads from TILoad pass. */
+ nRegister &= ~0x80000000;
+ dev_dbg(pTAS2557->dev, "TiLoad R REG B[%d]P[%d]R[%d]\n",
+ TAS2557_BOOK_ID(nRegister),
+ TAS2557_PAGE_ID(nRegister),
+ TAS2557_PAGE_REG(nRegister));
+ }
+
+ nResult = tas2557_change_book_page(pTAS2557,
+ TAS2557_BOOK_ID(nRegister),
+ TAS2557_PAGE_ID(nRegister));
+ if (nResult >= 0) {
+ nResult = regmap_read(pTAS2557->mpRegmap, TAS2557_PAGE_REG(nRegister), &Value);
+ if (nResult < 0) {
+ dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n",
+ __func__, __LINE__, nResult);
+ pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM;
+ goto end;
+ } else
+ pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM;
+ *pValue = Value;
+ }
+end:
+
+ mutex_unlock(&pTAS2557->dev_lock);
+ return nResult;
+}
+
+static int tas2557_dev_write(
+ struct tas2557_priv *pTAS2557,
+ unsigned int nRegister,
+ unsigned int nValue)
+{
+ int nResult = 0;
+
+ mutex_lock(&pTAS2557->dev_lock);
+ if ((nRegister == 0xAFFEAFFE) && (nValue == 0xBABEBABE)) {
+ pTAS2557->mbTILoadActive = true;
+ goto end;
+ }
+
+ if ((nRegister == 0xBABEBABE) && (nValue == 0xAFFEAFFE)) {
+ pTAS2557->mbTILoadActive = false;
+ goto end;
+ }
+
+ if (pTAS2557->mbTILoadActive) {
+ if (!(nRegister & 0x80000000))
+ goto end;/* let only writes from TILoad pass. */
+ nRegister &= ~0x80000000;
+
+ dev_dbg(pTAS2557->dev, "TiLoad W REG B[%d]P[%d]R[%d] =0x%x\n",
+ TAS2557_BOOK_ID(nRegister),
+ TAS2557_PAGE_ID(nRegister),
+ TAS2557_PAGE_REG(nRegister),
+ nValue);
+ }
+
+ nResult = tas2557_change_book_page(pTAS2557,
+ TAS2557_BOOK_ID(nRegister),
+ TAS2557_PAGE_ID(nRegister));
+ if (nResult >= 0) {
+ nResult = regmap_write(pTAS2557->mpRegmap, TAS2557_PAGE_REG(nRegister), nValue);
+ if (nResult < 0) {
+ dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n",
+ __func__, __LINE__, nResult);
+ pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM;
+ } else
+ pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM;
+ }
+
+end:
+
+ mutex_unlock(&pTAS2557->dev_lock);
+
+ return nResult;
+}
+
+static int tas2557_dev_bulk_read(
+ struct tas2557_priv *pTAS2557,
+ unsigned int nRegister,
+ u8 *pData,
+ unsigned int nLength)
+{
+ int nResult = 0;
+
+ mutex_lock(&pTAS2557->dev_lock);
+ if (pTAS2557->mbTILoadActive) {
+ if (!(nRegister & 0x80000000))
+ goto end; /* let only writes from TILoad pass. */
+
+ nRegister &= ~0x80000000;
+ dev_dbg(pTAS2557->dev, "TiLoad BR REG B[%d]P[%d]R[%d], count=%d\n",
+ TAS2557_BOOK_ID(nRegister),
+ TAS2557_PAGE_ID(nRegister),
+ TAS2557_PAGE_REG(nRegister),
+ nLength);
+ }
+
+ nResult = tas2557_change_book_page(pTAS2557,
+ TAS2557_BOOK_ID(nRegister),
+ TAS2557_PAGE_ID(nRegister));
+ if (nResult >= 0) {
+ nResult = regmap_bulk_read(pTAS2557->mpRegmap, TAS2557_PAGE_REG(nRegister), pData, nLength);
+ if (nResult < 0) {
+ dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n",
+ __func__, __LINE__, nResult);
+ pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM;
+ } else
+ pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM;
+ }
+
+end:
+
+ mutex_unlock(&pTAS2557->dev_lock);
+ return nResult;
+}
+
+static int tas2557_dev_bulk_write(
+ struct tas2557_priv *pTAS2557,
+ unsigned int nRegister,
+ u8 *pData,
+ unsigned int nLength)
+{
+ int nResult = 0;
+
+ mutex_lock(&pTAS2557->dev_lock);
+ if (pTAS2557->mbTILoadActive) {
+ if (!(nRegister & 0x80000000))
+ goto end; /* let only writes from TILoad pass. */
+
+ nRegister &= ~0x80000000;
+
+ dev_dbg(pTAS2557->dev, "TiLoad BW REG B[%d]P[%d]R[%d], count=%d\n",
+ TAS2557_BOOK_ID(nRegister),
+ TAS2557_PAGE_ID(nRegister),
+ TAS2557_PAGE_REG(nRegister),
+ nLength);
+ }
+
+ nResult = tas2557_change_book_page( pTAS2557,
+ TAS2557_BOOK_ID(nRegister),
+ TAS2557_PAGE_ID(nRegister));
+ if (nResult >= 0) {
+ nResult = regmap_bulk_write(pTAS2557->mpRegmap, TAS2557_PAGE_REG(nRegister), pData, nLength);
+ if (nResult < 0) {
+ dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n",
+ __func__, __LINE__, nResult);
+ pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM;
+ } else
+ pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM;
+ }
+
+end:
+
+ mutex_unlock(&pTAS2557->dev_lock);
+ return nResult;
+}
+
+static int tas2557_dev_update_bits(
+ struct tas2557_priv *pTAS2557,
+ unsigned int nRegister,
+ unsigned int nMask,
+ unsigned int nValue)
+{
+ int nResult = 0;
+
+ mutex_lock(&pTAS2557->dev_lock);
+
+ if (pTAS2557->mbTILoadActive) {
+ if (!(nRegister & 0x80000000))
+ goto end; /* let only writes from TILoad pass. */
+
+ nRegister &= ~0x80000000;
+ dev_dbg(pTAS2557->dev, "TiLoad SB REG B[%d]P[%d]R[%d], mask=0x%x, value=0x%x\n",
+ TAS2557_BOOK_ID(nRegister),
+ TAS2557_PAGE_ID(nRegister),
+ TAS2557_PAGE_REG(nRegister),
+ nMask, nValue);
+ }
+
+ nResult = tas2557_change_book_page( pTAS2557,
+ TAS2557_BOOK_ID(nRegister),
+ TAS2557_PAGE_ID(nRegister));
+ if (nResult >= 0) {
+ nResult = regmap_update_bits(pTAS2557->mpRegmap, TAS2557_PAGE_REG(nRegister), nMask, nValue);
+ if (nResult < 0) {
+ dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n",
+ __func__, __LINE__, nResult);
+ pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM;
+ } else
+ pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM;
+ }
+
+end:
+ mutex_unlock(&pTAS2557->dev_lock);
+ return nResult;
+}
+
+void tas2557_clearIRQ(struct tas2557_priv *pTAS2557)
+{
+ unsigned int nValue;
+ int nResult = 0;
+
+ nResult = pTAS2557->read(pTAS2557, TAS2557_FLAGS_1, &nValue);
+ if (nResult >= 0)
+ pTAS2557->read(pTAS2557, TAS2557_FLAGS_2, &nValue);
+
+}
+
+
+void tas2557_enableIRQ(struct tas2557_priv *pTAS2557, bool enable, bool startup_chk)
+{
+ if (enable) {
+ if (!pTAS2557->mbIRQEnable) {
+ if (gpio_is_valid(pTAS2557->mnGpioINT)) {
+ enable_irq(pTAS2557->mnIRQ);
+ if (startup_chk) {
+ /* check after 10 ms */
+ schedule_delayed_work(&pTAS2557->irq_work, msecs_to_jiffies(10));
+ }
+ pTAS2557->mbIRQEnable = true;
+ }
+ }
+ } else {
+ if (gpio_is_valid(pTAS2557->mnGpioINT))
+ disable_irq_nosync(pTAS2557->mnIRQ);
+ pTAS2557->mbIRQEnable = false;
+ }
+}
+
+static void tas2557_hw_reset(struct tas2557_priv *pTAS2557)
+{
+ if (gpio_is_valid(pTAS2557->mnResetGPIO)) {
+ gpio_direction_output(pTAS2557->mnResetGPIO, 0);
+ msleep(5);
+ gpio_direction_output(pTAS2557->mnResetGPIO, 1);
+ msleep(2);
+ }
+
+ pTAS2557->mnCurrentBook = -1;
+ pTAS2557->mnCurrentPage = -1;
+ if (pTAS2557->mnErrCode)
+ dev_info(pTAS2557->dev, "before reset, ErrCode=0x%x\n", pTAS2557->mnErrCode);
+ pTAS2557->mnErrCode = 0;
+}
+
+static void irq_work_routine(struct work_struct *work)
+{
+ int nResult = 0;
+ unsigned int nDevInt1Status = 0, nDevInt2Status = 0;
+ unsigned int nDevPowerUpFlag = 0;
+ int nCounter = 2;
+ struct tas2557_priv *pTAS2557 =
+ container_of(work, struct tas2557_priv, irq_work.work);
+
+#ifdef CONFIG_TAS2557_CODEC
+ mutex_lock(&pTAS2557->codec_lock);
+#endif
+
+#ifdef CONFIG_TAS2557_MISC
+ mutex_lock(&pTAS2557->file_lock);
+#endif
+
+ if(pTAS2557->mnErrCode & ERROR_FAILSAFE)
+ goto program;
+
+ if (pTAS2557->mbRuntimeSuspend) {
+ dev_info(pTAS2557->dev, "%s, Runtime Suspended\n", __func__);
+ goto end;
+ }
+
+ if (!pTAS2557->mbPowerUp) {
+ dev_info(pTAS2557->dev, "%s, device not powered\n", __func__);
+ goto end;
+ }
+
+ if ((!pTAS2557->mpFirmware->mnConfigurations)
+ || (!pTAS2557->mpFirmware->mnPrograms)) {
+ dev_info(pTAS2557->dev, "%s, firmware not loaded\n", __func__);
+ goto end;
+ }
+ nResult = tas2557_dev_write(pTAS2557, TAS2557_GPIO4_PIN_REG, 0x00);
+ if (nResult < 0)
+ goto program;
+ nResult = tas2557_dev_read(pTAS2557, TAS2557_FLAGS_1, &nDevInt1Status);
+ if (nResult >= 0)
+ nResult = tas2557_dev_read(pTAS2557, TAS2557_FLAGS_2, &nDevInt2Status);
+ if (nResult < 0)
+ goto program;
+
+ if (((nDevInt1Status & 0xfc) != 0) || ((nDevInt2Status & 0x0c) != 0)) {
+ /* in case of INT_OC, INT_UV, INT_OT, INT_BO, INT_CL, INT_CLK1, INT_CLK2 */
+ dev_err(pTAS2557->dev, "critical error: 0x%x, 0x%x\n", nDevInt1Status, nDevInt2Status);
+ if (nDevInt1Status & 0x80) {
+ pTAS2557->mnErrCode |= ERROR_OVER_CURRENT;
+ dev_err(pTAS2557->dev, "DEVA SPK over current!\n");
+ } else
+ pTAS2557->mnErrCode &= ~ERROR_OVER_CURRENT;
+
+ if (nDevInt1Status & 0x40) {
+ pTAS2557->mnErrCode |= ERROR_UNDER_VOLTAGE;
+ dev_err(pTAS2557->dev, "DEVA SPK under voltage!\n");
+ } else
+ pTAS2557->mnErrCode &= ~ERROR_UNDER_VOLTAGE;
+
+ if (nDevInt1Status & 0x20) {
+ pTAS2557->mnErrCode |= ERROR_CLK_HALT;
+ dev_err(pTAS2557->dev, "DEVA clk halted!\n");
+ } else
+ pTAS2557->mnErrCode &= ~ERROR_CLK_HALT;
+
+ if (nDevInt1Status & 0x10) {
+ pTAS2557->mnErrCode |= ERROR_DIE_OVERTEMP;
+ dev_err(pTAS2557->dev, "DEVA die over temperature!\n");
+ } else
+ pTAS2557->mnErrCode &= ~ERROR_DIE_OVERTEMP;
+
+ if (nDevInt1Status & 0x08) {
+ pTAS2557->mnErrCode |= ERROR_BROWNOUT;
+ dev_err(pTAS2557->dev, "DEVA brownout!\n");
+ } else
+ pTAS2557->mnErrCode &= ~ERROR_BROWNOUT;
+
+ if (nDevInt1Status & 0x04) {
+ pTAS2557->mnErrCode |= ERROR_CLK_LOST;
+ dev_err(pTAS2557->dev, "DEVA clock lost!\n");
+ } else
+ pTAS2557->mnErrCode &= ~ERROR_CLK_LOST;
+
+ if (nDevInt2Status & 0x08) {
+ pTAS2557->mnErrCode |= ERROR_CLK_DET1;
+ dev_err(pTAS2557->dev, "DEVA clk detection 1!\n");
+ } else
+ pTAS2557->mnErrCode &= ~ERROR_CLK_DET1;
+
+ if (nDevInt2Status & 0x04) {
+ pTAS2557->mnErrCode |= ERROR_CLK_DET2;
+ dev_err(pTAS2557->dev, "DEVA clk detection 2!\n");
+ } else
+ pTAS2557->mnErrCode &= ~ERROR_CLK_DET2;
+
+ goto program;
+ } else {
+ dev_dbg(pTAS2557->dev, "IRQ Status: 0x%x, 0x%x\n", nDevInt1Status, nDevInt2Status);
+ nCounter = 2;
+ while (nCounter > 0) {
+ nResult = tas2557_dev_read(pTAS2557, TAS2557_POWER_UP_FLAG_REG, &nDevPowerUpFlag);
+ if (nResult < 0)
+ goto program;
+ if ((nDevPowerUpFlag & 0xc0) == 0xc0)
+ break;
+ nCounter--;
+ if (nCounter > 0) {
+ /* in case check pow status just after power on TAS2557 */
+ dev_dbg(pTAS2557->dev, "PowSts: 0x%x, check again after 10ms\n",
+ nDevPowerUpFlag);
+ msleep(10);
+ }
+ }
+ if ((nDevPowerUpFlag & 0xc0) != 0xc0) {
+ dev_err(pTAS2557->dev, "%s, Critical ERROR B[%d]_P[%d]_R[%d]= 0x%x\n",
+ __func__,
+ TAS2557_BOOK_ID(TAS2557_POWER_UP_FLAG_REG),
+ TAS2557_PAGE_ID(TAS2557_POWER_UP_FLAG_REG),
+ TAS2557_PAGE_REG(TAS2557_POWER_UP_FLAG_REG),
+ nDevPowerUpFlag);
+ pTAS2557->mnErrCode |= ERROR_CLASSD_PWR;
+ goto program;
+ }
+ pTAS2557->mnErrCode &= ~ERROR_CLASSD_PWR;
+
+ dev_dbg(pTAS2557->dev, "%s: INT1=0x%x, INT2=0x%x; PowerUpFlag=0x%x\n",
+ __func__, nDevInt1Status, nDevInt2Status, nDevPowerUpFlag);
+ goto end;
+ }
+
+program:
+ /* hardware reset and reload */
+ nResult = -1;
+ tas2557_set_program(pTAS2557, pTAS2557->mnCurrentProgram, pTAS2557->mnCurrentConfiguration);
+
+end:
+ if (nResult >= 0) {
+ tas2557_dev_write(pTAS2557, TAS2557_GPIO4_PIN_REG, 0x07);
+ tas2557_enableIRQ(pTAS2557, true, false);
+ }
+#ifdef CONFIG_TAS2557_MISC
+ mutex_unlock(&pTAS2557->file_lock);
+#endif
+
+#ifdef CONFIG_TAS2557_CODEC
+ mutex_unlock(&pTAS2557->codec_lock);
+#endif
+}
+
+static irqreturn_t tas2557_irq_handler(int irq, void *dev_id)
+{
+ struct tas2557_priv *pTAS2557 = (struct tas2557_priv *)dev_id;
+
+ tas2557_enableIRQ(pTAS2557, false, false);
+ /* get IRQ status after 100 ms */
+ schedule_delayed_work(&pTAS2557->irq_work, msecs_to_jiffies(100));
+ return IRQ_HANDLED;
+}
+
+static enum hrtimer_restart temperature_timer_func(struct hrtimer *timer)
+{
+ struct tas2557_priv *pTAS2557 = container_of(timer, struct tas2557_priv, mtimer);
+
+ if (pTAS2557->mbPowerUp) {
+ schedule_work(&pTAS2557->mtimerwork);
+ if (gpio_is_valid(pTAS2557->mnGpioINT)) {
+ tas2557_enableIRQ(pTAS2557, false, false);
+ schedule_delayed_work(&pTAS2557->irq_work, msecs_to_jiffies(1));
+ }
+ }
+ return HRTIMER_NORESTART;
+}
+
+static void timer_work_routine(struct work_struct *work)
+{
+ struct tas2557_priv *pTAS2557 = container_of(work, struct tas2557_priv, mtimerwork);
+ int nResult, nActTemp;
+ int nTemp = 0;
+ struct TProgram *pProgram;
+ static int nAvg;
+
+#ifdef CONFIG_TAS2557_CODEC
+ mutex_lock(&pTAS2557->codec_lock);
+#endif
+
+#ifdef CONFIG_TAS2557_MISC
+ mutex_lock(&pTAS2557->file_lock);
+#endif
+
+ if (pTAS2557->mbRuntimeSuspend) {
+ dev_info(pTAS2557->dev, "%s, Runtime Suspended\n", __func__);
+ goto end;
+ }
+
+ if (!pTAS2557->mpFirmware->mnConfigurations) {
+ dev_info(pTAS2557->dev, "%s, firmware not loaded\n", __func__);
+ goto end;
+ }
+
+ pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]);
+ if (!pTAS2557->mbPowerUp
+ || (pProgram->mnAppMode != TAS2557_APP_TUNINGMODE)) {
+ dev_info(pTAS2557->dev, "%s, pass, Pow=%d, program=%s\n",
+ __func__, pTAS2557->mbPowerUp, pProgram->mpName);
+ goto end;
+ }
+
+ nResult = tas2557_get_die_temperature(pTAS2557, &nTemp);
+ if (nResult >= 0) {
+ nActTemp = (int)(nTemp >> 23);
+ dev_dbg(pTAS2557->dev, "Die=0x%x, degree=%d\n", nTemp, nActTemp);
+ if (!pTAS2557->mnDieTvReadCounter)
+ nAvg = 0;
+ pTAS2557->mnDieTvReadCounter++;
+ nAvg += nActTemp;
+ if (!(pTAS2557->mnDieTvReadCounter % LOW_TEMPERATURE_COUNTER)) {
+ nAvg /= LOW_TEMPERATURE_COUNTER;
+ dev_dbg(pTAS2557->dev, "check : avg=%d\n", nAvg);
+ if (nAvg < -6) {
+ /* if Die temperature is below -6 degree C */
+ if (pTAS2557->mnDevCurrentGain != LOW_TEMPERATURE_GAIN) {
+ nResult = tas2557_set_DAC_gain(pTAS2557, LOW_TEMPERATURE_GAIN);
+ if (nResult < 0)
+ goto end;
+ pTAS2557->mnDevCurrentGain = LOW_TEMPERATURE_GAIN;
+ dev_dbg(pTAS2557->dev, "LOW Temp: set gain to %d\n", LOW_TEMPERATURE_GAIN);
+ }
+ } else if (nAvg > 5) {
+ /* if Die temperature is above 5 degree C */
+ if (pTAS2557->mnDevCurrentGain != pTAS2557->mnDevGain) {
+ nResult = tas2557_set_DAC_gain(pTAS2557, pTAS2557->mnDevGain);
+ if (nResult < 0)
+ goto end;
+ pTAS2557->mnDevCurrentGain = pTAS2557->mnDevGain;
+ dev_dbg(pTAS2557->dev, "LOW Temp: set gain to original\n");
+ }
+ }
+ nAvg = 0;
+ }
+
+ if (pTAS2557->mbPowerUp)
+ hrtimer_start(&pTAS2557->mtimer,
+ ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
+ }
+
+end:
+
+#ifdef CONFIG_TAS2557_MISC
+ mutex_unlock(&pTAS2557->file_lock);
+#endif
+
+#ifdef CONFIG_TAS2557_CODEC
+ mutex_unlock(&pTAS2557->codec_lock);
+#endif
+}
+
+static int tas2557_runtime_suspend(struct tas2557_priv *pTAS2557)
+{
+ dev_dbg(pTAS2557->dev, "%s\n", __func__);
+
+ pTAS2557->mbRuntimeSuspend = true;
+
+ if (hrtimer_active(&pTAS2557->mtimer)) {
+ dev_dbg(pTAS2557->dev, "cancel die temp timer\n");
+ hrtimer_cancel(&pTAS2557->mtimer);
+ }
+ if (work_pending(&pTAS2557->mtimerwork)) {
+ dev_dbg(pTAS2557->dev, "cancel timer work\n");
+ cancel_work_sync(&pTAS2557->mtimerwork);
+ }
+ if (gpio_is_valid(pTAS2557->mnGpioINT)) {
+ if (delayed_work_pending(&pTAS2557->irq_work)) {
+ dev_dbg(pTAS2557->dev, "cancel IRQ work\n");
+ cancel_delayed_work_sync(&pTAS2557->irq_work);
+ }
+ }
+
+ return 0;
+}
+
+static int tas2557_runtime_resume(struct tas2557_priv *pTAS2557)
+{
+ struct TProgram *pProgram;
+
+ dev_dbg(pTAS2557->dev, "%s\n", __func__);
+ if (!pTAS2557->mpFirmware->mpPrograms) {
+ dev_dbg(pTAS2557->dev, "%s, firmware not loaded\n", __func__);
+ goto end;
+ }
+
+ if (pTAS2557->mnCurrentProgram >= pTAS2557->mpFirmware->mnPrograms) {
+ dev_err(pTAS2557->dev, "%s, firmware corrupted\n", __func__);
+ goto end;
+ }
+
+ pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]);
+ if (pTAS2557->mbPowerUp && (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE)) {
+ if (!hrtimer_active(&pTAS2557->mtimer)) {
+ dev_dbg(pTAS2557->dev, "%s, start Die Temp check timer\n", __func__);
+ pTAS2557->mnDieTvReadCounter = 0;
+ hrtimer_start(&pTAS2557->mtimer,
+ ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
+ }
+ }
+
+ pTAS2557->mbRuntimeSuspend = false;
+end:
+
+ return 0;
+}
+
+static bool tas2557_volatile(struct device *pDev, unsigned int nRegister)
+{
+ return true;
+}
+
+static bool tas2557_writeable(struct device *pDev, unsigned int nRegister)
+{
+ return true;
+}
+
+static const struct regmap_config tas2557_i2c_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .writeable_reg = tas2557_writeable,
+ .volatile_reg = tas2557_volatile,
+ .cache_type = REGCACHE_NONE,
+ .max_register = 128,
+};
+
+/* tas2557_i2c_probe :
+* platform dependent
+* should implement hardware reset functionality
+*/
+static int tas2557_i2c_probe(struct i2c_client *pClient,
+ const struct i2c_device_id *pID)
+{
+ struct tas2557_priv *pTAS2557;
+ int nResult = 0;
+ unsigned int nValue = 0;
+ const char *pFWName;
+
+ dev_info(&pClient->dev, "%s enter\n", __func__);
+
+ pTAS2557 = devm_kzalloc(&pClient->dev, sizeof(struct tas2557_priv), GFP_KERNEL);
+ if (!pTAS2557) {
+ nResult = -ENOMEM;
+ goto err;
+ }
+
+ pTAS2557->dev = &pClient->dev;
+ i2c_set_clientdata(pClient, pTAS2557);
+ dev_set_drvdata(&pClient->dev, pTAS2557);
+
+ pTAS2557->mpRegmap = devm_regmap_init_i2c(pClient, &tas2557_i2c_regmap);
+ if (IS_ERR(pTAS2557->mpRegmap)) {
+ nResult = PTR_ERR(pTAS2557->mpRegmap);
+ dev_err(&pClient->dev, "Failed to allocate register map: %d\n",
+ nResult);
+ goto err;
+ }
+
+ if (pClient->dev.of_node)
+ tas2557_parse_dt(&pClient->dev, pTAS2557);
+
+ if (gpio_is_valid(pTAS2557->mnResetGPIO)) {
+ nResult = gpio_request(pTAS2557->mnResetGPIO, "TAS2557-RESET");
+ if (nResult < 0) {
+ dev_err(pTAS2557->dev, "%s: GPIO %d request error\n",
+ __func__, pTAS2557->mnResetGPIO);
+ goto err;
+ }
+ tas2557_hw_reset(pTAS2557);
+ }
+
+ pTAS2557->read = tas2557_dev_read;
+ pTAS2557->write = tas2557_dev_write;
+ pTAS2557->bulk_read = tas2557_dev_bulk_read;
+ pTAS2557->bulk_write = tas2557_dev_bulk_write;
+ pTAS2557->update_bits = tas2557_dev_update_bits;
+ pTAS2557->enableIRQ = tas2557_enableIRQ;
+ pTAS2557->clearIRQ = tas2557_clearIRQ;
+ pTAS2557->set_config = tas2557_set_config;
+ pTAS2557->set_calibration = tas2557_set_calibration;
+ pTAS2557->hw_reset = tas2557_hw_reset;
+ pTAS2557->runtime_suspend = tas2557_runtime_suspend;
+ pTAS2557->runtime_resume = tas2557_runtime_resume;
+ pTAS2557->mnRestart = 0;
+ pTAS2557->mnEdge = 4;
+
+ mutex_init(&pTAS2557->dev_lock);
+
+ /* Reset the chip */
+ nResult = tas2557_dev_write(pTAS2557, TAS2557_SW_RESET_REG, 0x01);
+ if (nResult < 0) {
+ dev_err(&pClient->dev, "I2c fail, %d\n", nResult);
+ goto err;
+ }
+
+ msleep(1);
+ tas2557_dev_read(pTAS2557, TAS2557_REV_PGID_REG, &nValue);
+ pTAS2557->mnPGID = nValue;
+ if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P1) {
+ dev_info(pTAS2557->dev, "PG2.1 Silicon found\n");
+ pFWName = TAS2557_FW_NAME;
+ } else if (pTAS2557->mnPGID == TAS2557_PG_VERSION_1P0) {
+ dev_info(pTAS2557->dev, "PG1.0 Silicon found\n");
+ pFWName = TAS2557_PG1P0_FW_NAME;
+ } else {
+ nResult = -ENOTSUPP;
+ dev_info(pTAS2557->dev, "unsupport Silicon 0x%x\n", pTAS2557->mnPGID);
+ goto err;
+ }
+
+ if (gpio_is_valid(pTAS2557->mnGpioINT)) {
+ nResult = gpio_request(pTAS2557->mnGpioINT, "TAS2557-IRQ");
+ if (nResult < 0) {
+ dev_err(pTAS2557->dev,
+ "%s: GPIO %d request INT error\n",
+ __func__, pTAS2557->mnGpioINT);
+ goto err;
+ }
+
+ gpio_direction_input(pTAS2557->mnGpioINT);
+ pTAS2557->mnIRQ = gpio_to_irq(pTAS2557->mnGpioINT);
+ dev_dbg(pTAS2557->dev, "irq = %d\n", pTAS2557->mnIRQ);
+ INIT_DELAYED_WORK(&pTAS2557->irq_work, irq_work_routine);
+ nResult = request_threaded_irq(pTAS2557->mnIRQ, tas2557_irq_handler,
+ NULL, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+ pClient->name, pTAS2557);
+ if (nResult < 0) {
+ dev_err(pTAS2557->dev,
+ "request_irq failed, %d\n", nResult);
+ goto err;
+ }
+ disable_irq_nosync(pTAS2557->mnIRQ);
+ }
+
+ pTAS2557->mpFirmware = devm_kzalloc(&pClient->dev, sizeof(struct TFirmware), GFP_KERNEL);
+ if (!pTAS2557->mpFirmware) {
+ nResult = -ENOMEM;
+ goto err;
+ }
+
+ pTAS2557->mpCalFirmware = devm_kzalloc(&pClient->dev, sizeof(struct TFirmware), GFP_KERNEL);
+ if (!pTAS2557->mpCalFirmware) {
+ nResult = -ENOMEM;
+ goto err;
+ }
+
+#ifdef CONFIG_TAS2557_CODEC
+ mutex_init(&pTAS2557->codec_lock);
+ tas2557_register_codec(pTAS2557);
+#endif
+
+#ifdef CONFIG_TAS2557_MISC
+ mutex_init(&pTAS2557->file_lock);
+ tas2557_register_misc(pTAS2557);
+#endif
+
+#ifdef ENABLE_TILOAD
+ tiload_driver_init(pTAS2557);
+#endif
+
+ hrtimer_init(&pTAS2557->mtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ pTAS2557->mtimer.function = temperature_timer_func;
+ INIT_WORK(&pTAS2557->mtimerwork, timer_work_routine);
+
+ nResult = request_firmware_nowait(THIS_MODULE, 1, pFWName,
+ pTAS2557->dev, GFP_KERNEL, pTAS2557, tas2557_fw_ready);
+
+err:
+
+ return nResult;
+}
+
+static int tas2557_i2c_remove(struct i2c_client *pClient)
+{
+ struct tas2557_priv *pTAS2557 = i2c_get_clientdata(pClient);
+
+ dev_info(pTAS2557->dev, "%s\n", __func__);
+
+#ifdef CONFIG_TAS2557_CODEC
+ tas2557_deregister_codec(pTAS2557);
+ mutex_destroy(&pTAS2557->codec_lock);
+#endif
+
+#ifdef CONFIG_TAS2557_MISC
+ tas2557_deregister_misc(pTAS2557);
+ mutex_destroy(&pTAS2557->file_lock);
+#endif
+
+ mutex_destroy(&pTAS2557->dev_lock);
+ return 0;
+}
+
+static const struct i2c_device_id tas2557_i2c_id[] = {
+ {"tas2557", 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, tas2557_i2c_id);
+
+#if defined(CONFIG_OF)
+static const struct of_device_id tas2557_of_match[] = {
+ {.compatible = "ti,tas2557"},
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, tas2557_of_match);
+#endif
+
+static struct i2c_driver tas2557_i2c_driver = {
+ .driver = {
+ .name = "tas2557",
+ .owner = THIS_MODULE,
+#if defined(CONFIG_OF)
+ .of_match_table = of_match_ptr(tas2557_of_match),
+#endif
+ },
+ .probe = tas2557_i2c_probe,
+ .remove = tas2557_i2c_remove,
+ .id_table = tas2557_i2c_id,
+};
+
+module_i2c_driver(tas2557_i2c_driver);
+
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_DESCRIPTION("TAS2557 I2C Smart Amplifier driver");
+MODULE_LICENSE("GPL v2");
+
+#endif
diff --git a/sound/soc/codecs/tas2557/tas2557.h b/sound/soc/codecs/tas2557/tas2557.h
new file mode 100755
index 0000000..a45c4ec
--- /dev/null
+++ b/sound/soc/codecs/tas2557/tas2557.h
@@ -0,0 +1,489 @@
+/*
+** =============================================================================
+** Copyright (c) 2016 Texas Instruments Inc.
+**
+** This program is free software; you can redistribute it and/or modify it under
+** the terms of the GNU General Public License as published by the Free Software
+** Foundation; version 2.
+**
+** This program is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+**
+** File:
+** tas2557.h
+**
+** Description:
+** definitions and data structures for TAS2557 Android Linux driver
+**
+** =============================================================================
+*/
+
+#ifndef _TAS2557_H
+#define _TAS2557_H
+
+#include <linux/regmap.h>
+#include <linux/workqueue.h>
+#include <linux/timer.h>
+
+/* Page Control Register */
+#define TAS2557_PAGECTL_REG 0
+
+/* Book Control Register (available in page0 of each book) */
+#define TAS2557_BOOKCTL_PAGE 0
+#define TAS2557_BOOKCTL_REG 127
+
+/* 0000 0000 0BBB BBBB BPPP PPPP PRRR RRRR */
+
+#define TAS2557_REG(book, page, reg) ((((unsigned int)book * 256 * 128) + \
+ ((unsigned int)page * 128)) + reg)
+
+#define TAS2557_BOOK_ID(reg) ((unsigned char)(reg / (256 * 128)))
+#define TAS2557_PAGE_ID(reg) ((unsigned char)((reg % (256 * 128)) / 128))
+#define TAS2557_BOOK_REG(reg) ((unsigned char)(reg % (256 * 128)))
+#define TAS2557_PAGE_REG(reg) ((unsigned char)((reg % (256 * 128)) % 128))
+
+/* Book0, Page0 registers */
+#define TAS2557_SW_RESET_REG TAS2557_REG(0, 0, 1)
+
+#define TAS2557_REV_PGID_REG TAS2557_REG(0, 0, 3)
+#define TAS2557_PG_VERSION_1P0 0x80
+#define TAS2557_PG_VERSION_2P0 0x90
+#define TAS2557_PG_VERSION_2P1 0xa0
+
+#define TAS2557_POWER_CTRL1_REG TAS2557_REG(0, 0, 4)
+#define TAS2557_POWER_CTRL2_REG TAS2557_REG(0, 0, 5)
+
+#define TAS2557_SPK_CTRL_REG TAS2557_REG(0, 0, 6)
+/* B0P0R6 - TAS2557_SPK_CTRL_REG */
+#define TAS2557_DAC_GAIN_MASK (0xf << 3)
+#define TAS2557_DAC_GAIN_SHIFT 0x03
+
+#define TAS2557_MUTE_REG TAS2557_REG(0, 0, 7)
+#define TAS2557_SNS_CTRL_REG TAS2557_REG(0, 0, 8)
+#define TAS2557_ADC_INPUT_SEL_REG TAS2557_REG(0, 0, 9)
+#define TAS2557_DBOOST_CTL_REG TAS2557_REG(0, 0, 10)
+#define TAS2557_NONAME11_REG TAS2557_REG(0, 0, 11)
+#define TAS2557_NONAME12_REG TAS2557_REG(0, 0, 12)
+#define TAS2557_NONAME13_REG TAS2557_REG(0, 0, 13)
+#define TAS2557_NONAME14_REG TAS2557_REG(0, 0, 14)
+#define TAS2557_NONAME15_REG TAS2557_REG(0, 0, 15)
+#define TAS2557_NONAME16_REG TAS2557_REG(0, 0, 16)
+#define TAS2557_NONAME17_REG TAS2557_REG(0, 0, 17)
+#define TAS2557_NONAME18_REG TAS2557_REG(0, 0, 18)
+#define TAS2557_SAR_SAMPLING_TIME_REG TAS2557_REG(0, 0, 19)
+#define TAS2557_SAR_ADC1_REG TAS2557_REG(0, 0, 20)
+#define TAS2557_SAR_ADC2_REG TAS2557_REG(0, 0, 21) /* B0_P0_R0x15*/
+#define TAS2557_CRC_CHECKSUM_REG TAS2557_REG(0, 0, 32)
+#define TAS2557_CRC_RESET_REG TAS2557_REG(0, 0, 33)
+#define TAS2557_DSP_MODE_SELECT_REG TAS2557_REG(0, 0, 34)
+#define TAS2557_SAFE_GUARD_REG TAS2557_REG(0, 0, 37)
+#define TAS2557_ASI_CTL1_REG TAS2557_REG(0, 0, 42)
+#define TAS2557_CLK_ERR_CTRL TAS2557_REG(0, 0, 44) /* B0_P0_R0x2c*/
+#define TAS2557_CLK_ERR_CTRL2 TAS2557_REG(0, 0, 45) /* B0_P0_R0x2d*/
+#define TAS2557_CLK_ERR_CTRL3 TAS2557_REG(0, 0, 46) /* B0_P0_R0x2e*/
+#define TAS2557_DBOOST_CFG_REG TAS2557_REG(0, 0, 52)
+#define TAS2557_POWER_UP_FLAG_REG TAS2557_REG(0, 0, 100)
+#define TAS2557_FLAGS_1 TAS2557_REG(0, 0, 104) /* B0_P0_R0x68*/
+#define TAS2557_FLAGS_2 TAS2557_REG(0, 0, 108) /* B0_P0_R0x6c*/
+
+/* Book0, Page1 registers */
+#define TAS2557_ASI1_DAC_FORMAT_REG TAS2557_REG(0, 1, 1)
+#define TAS2557_ASI1_ADC_FORMAT_REG TAS2557_REG(0, 1, 2)
+#define TAS2557_ASI1_OFFSET1_REG TAS2557_REG(0, 1, 3)
+#define TAS2557_ASI1_ADC_PATH_REG TAS2557_REG(0, 1, 7)
+#define TAS2557_ASI1_DAC_BCLK_REG TAS2557_REG(0, 1, 8)
+#define TAS2557_ASI1_DAC_WCLK_REG TAS2557_REG(0, 1, 9)
+#define TAS2557_ASI1_ADC_BCLK_REG TAS2557_REG(0, 1, 10)
+#define TAS2557_ASI1_ADC_WCLK_REG TAS2557_REG(0, 1, 11)
+#define TAS2557_ASI1_DIN_DOUT_MUX_REG TAS2557_REG(0, 1, 12)
+#define TAS2557_ASI1_BDIV_CLK_SEL_REG TAS2557_REG(0, 1, 13)
+#define TAS2557_ASI1_BDIV_CLK_RATIO_REG TAS2557_REG(0, 1, 14)
+#define TAS2557_ASI1_WDIV_CLK_RATIO_REG TAS2557_REG(0, 1, 15)
+#define TAS2557_ASI1_DAC_CLKOUT_REG TAS2557_REG(0, 1, 16)
+#define TAS2557_ASI1_ADC_CLKOUT_REG TAS2557_REG(0, 1, 17)
+#define TAS2557_ASI2_DAC_FORMAT_REG TAS2557_REG(0, 1, 21)
+#define TAS2557_ASI2_ADC_FORMAT_REG TAS2557_REG(0, 1, 22)
+#define TAS2557_ASI2_OFFSET1_REG TAS2557_REG(0, 1, 23)
+#define TAS2557_ASI2_ADC_PATH_REG TAS2557_REG(0, 1, 27)
+#define TAS2557_ASI2_DAC_BCLK_REG TAS2557_REG(0, 1, 28)
+#define TAS2557_ASI2_DAC_WCLK_REG TAS2557_REG(0, 1, 29)
+#define TAS2557_ASI2_ADC_BCLK_REG TAS2557_REG(0, 1, 30)
+#define TAS2557_ASI2_ADC_WCLK_REG TAS2557_REG(0, 1, 31)
+#define TAS2557_ASI2_DIN_DOUT_MUX_REG TAS2557_REG(0, 1, 32)
+#define TAS2557_ASI2_BDIV_CLK_SEL_REG TAS2557_REG(0, 1, 33)
+#define TAS2557_ASI2_BDIV_CLK_RATIO_REG TAS2557_REG(0, 1, 34)
+#define TAS2557_ASI2_WDIV_CLK_RATIO_REG TAS2557_REG(0, 1, 35)
+#define TAS2557_ASI2_DAC_CLKOUT_REG TAS2557_REG(0, 1, 36)
+#define TAS2557_ASI2_ADC_CLKOUT_REG TAS2557_REG(0, 1, 37)
+#define TAS2557_GPIO1_PIN_REG TAS2557_REG(0, 1, 61) /*B0_P1_R0x3d */
+#define TAS2557_GPIO2_PIN_REG TAS2557_REG(0, 1, 62) /*B0_P1_R0x3e */
+#define TAS2557_GPIO3_PIN_REG TAS2557_REG(0, 1, 63) /*B0_P1_R0x3f */
+#define TAS2557_GPIO4_PIN_REG TAS2557_REG(0, 1, 64) /*B0_P1_R0x40 */
+#define TAS2557_GPIO5_PIN_REG TAS2557_REG(0, 1, 65)
+#define TAS2557_GPIO6_PIN_REG TAS2557_REG(0, 1, 66)
+#define TAS2557_GPIO7_PIN_REG TAS2557_REG(0, 1, 67)
+#define TAS2557_GPIO8_PIN_REG TAS2557_REG(0, 1, 68)
+#define TAS2557_GPIO9_PIN_REG TAS2557_REG(0, 1, 69)
+#define TAS2557_GPIO10_PIN_REG TAS2557_REG(0, 1, 70)
+#define TAS2557_GPI_PIN_REG TAS2557_REG(0, 1, 77) /*B0_P1_R0x4d */
+#define TAS2557_GPIO_HIZ_CTRL1_REG TAS2557_REG(0, 1, 79)
+#define TAS2557_GPIO_HIZ_CTRL2_REG TAS2557_REG(0, 1, 80) /*B0_P1_R0x50 */
+#define TAS2557_GPIO_HIZ_CTRL3_REG TAS2557_REG(0, 1, 81)
+#define TAS2557_GPIO_HIZ_CTRL4_REG TAS2557_REG(0, 1, 82)
+#define TAS2557_GPIO_HIZ_CTRL5_REG TAS2557_REG(0, 1, 83)
+#define TAS2557_BIT_BANG_CTRL_REG TAS2557_REG(0, 1, 87)
+#define TAS2557_BIT_BANG_OUT1_REG TAS2557_REG(0, 1, 88)
+#define TAS2557_BIT_BANG_OUT2_REG TAS2557_REG(0, 1, 89)
+#define TAS2557_BIT_BANG_IN1_REG TAS2557_REG(0, 1, 90)
+#define TAS2557_BIT_BANG_IN2_REG TAS2557_REG(0, 1, 91)
+#define TAS2557_BIT_BANG_IN3_REG TAS2557_REG(0, 1, 92)
+#define TAS2557_PDM_IN_CLK_REG TAS2557_REG(0, 1, 94)
+#define TAS2557_PDM_IN_PIN_REG TAS2557_REG(0, 1, 95)
+#define TAS2557_ASIM_IFACE1_REG TAS2557_REG(0, 1, 98)
+#define TAS2557_ASIM_FORMAT_REG TAS2557_REG(0, 1, 99)
+#define TAS2557_ASIM_IFACE3_REG TAS2557_REG(0, 1, 100)
+#define TAS2557_ASIM_IFACE4_REG TAS2557_REG(0, 1, 101)
+#define TAS2557_ASIM_IFACE5_REG TAS2557_REG(0, 1, 102)
+#define TAS2557_ASIM_IFACE6_REG TAS2557_REG(0, 1, 103)
+#define TAS2557_ASIM_IFACE7_REG TAS2557_REG(0, 1, 104)
+#define TAS2557_ASIM_IFACE8_REG TAS2557_REG(0, 1, 105)
+#define TAS2557_CLK_HALT_REG TAS2557_REG(0, 1, 106) /* B0_P1_R0x6a */
+#define TAS2557_INT_GEN1_REG TAS2557_REG(0, 1, 108) /* B0_P1_R0x6c */
+#define TAS2557_INT_GEN2_REG TAS2557_REG(0, 1, 109) /* B0_P1_R0x6d */
+#define TAS2557_INT_GEN3_REG TAS2557_REG(0, 1, 110) /* B0_P1_R0x6e */
+#define TAS2557_INT_GEN4_REG TAS2557_REG(0, 1, 111) /* B0_P1_R0x6f */
+#define TAS2557_INT_MODE_REG TAS2557_REG(0, 1, 114) /* B0_P1_R0x72 */
+#define TAS2557_MAIN_CLKIN_REG TAS2557_REG(0, 1, 115)
+#define TAS2557_PLL_CLKIN_REG TAS2557_REG(0, 1, 116)
+#define TAS2557_CLKOUT_MUX_REG TAS2557_REG(0, 1, 117)
+#define TAS2557_CLKOUT_CDIV_REG TAS2557_REG(0, 1, 118)
+#define TAS2557_HACK_GP01_REG TAS2557_REG(0, 1, 122)
+
+#define TAS2557_HACK01_REG TAS2557_REG(0, 2, 10)
+
+#define TAS2557_ISENSE_THRESHOLD TAS2557_REG(0, 50, 104)
+#define TAS2557_BOOSTON_EFFICIENCY TAS2557_REG(0, 51, 16)
+#define TAS2557_BOOSTOFF_EFFICIENCY TAS2557_REG(0, 51, 20)
+#define TAS2557_BOOST_HEADROOM TAS2557_REG(0, 51, 24)
+#define TAS2557_THERMAL_FOLDBACK_REG TAS2557_REG(0, 51, 100)
+
+#define TAS2557_SA_PG2P1_CHL_CTRL_REG TAS2557_REG(0, 53, 20) /* B0_P0x35_R0x14 */
+#define TAS2557_SA_COEFF_SWAP_REG TAS2557_REG(0, 53, 44) /* B0_P0x35_R0x2c */
+
+#define TAS2557_SA_PG1P0_CHL_CTRL_REG TAS2557_REG(0, 58, 120) /* B0_P0x3a_R0x78 */
+
+#define TAS2557_TEST_MODE_REG TAS2557_REG(0, 253, 13) /* B0_P0xfd_R0x0d */
+#define TAS2557_BROADCAST_REG TAS2557_REG(0, 253, 54) /* B0_P0xfd_R0x36 */
+#define TAS2557_CRYPTIC_REG TAS2557_REG(0, 253, 71)
+#define TAS2557_PG2P1_CALI_R0_REG TAS2557_REG(0x8c, 0x2f, 0x40)
+#define TAS2557_PG1P0_CALI_R0_REG TAS2557_REG(0x8c, 0x2f, 0x28)
+#define TAS2557_PG2P1_CALI_T_REG TAS2557_REG(0x8c, 0x30, 0x20)
+#define TAS2557_PG1P0_CALI_T_REG TAS2557_REG(0x8c, 0x30, 0x08)
+
+#define TAS2557_DAC_INTERPOL_REG TAS2557_REG(100, 0, 1)
+#define TAS2557_SOFT_MUTE_REG TAS2557_REG(100, 0, 7)
+#define TAS2557_PLL_P_VAL_REG TAS2557_REG(100, 0, 27)
+#define TAS2557_PLL_J_VAL_REG TAS2557_REG(100, 0, 28)
+#define TAS2557_PLL_D_VAL_MSB_REG TAS2557_REG(100, 0, 29)
+#define TAS2557_PLL_D_VAL_LSB_REG TAS2557_REG(100, 0, 30)
+#define TAS2557_CLK_MISC_REG TAS2557_REG(100, 0, 31)
+#define TAS2557_PLL_N_VAL_REG TAS2557_REG(100, 0, 32)
+#define TAS2557_DAC_MADC_VAL_REG TAS2557_REG(100, 0, 33)
+#define TAS2557_ISENSE_DIV_REG TAS2557_REG(100, 0, 42)
+#define TAS2557_RAMP_CLK_DIV_MSB_REG TAS2557_REG(100, 0, 43)
+#define TAS2557_RAMP_CLK_DIV_LSB_REG TAS2557_REG(100, 0, 44)
+
+#define TAS2557_DIE_TEMP_REG TAS2557_REG(130, 2, 124) /* B0x82_P0x02_R0x7C */
+
+/* Bits */
+/* B0P0R4 - TAS2557_POWER_CTRL1_REG */
+#define TAS2557_SW_SHUTDOWN (0x1 << 0)
+#define TAS2557_MADC_POWER_UP (0x1 << 3)
+#define TAS2557_MDAC_POWER_UP (0x1 << 4)
+#define TAS2557_NDIV_POWER_UP (0x1 << 5)
+#define TAS2557_PLL_POWER_UP (0x1 << 6)
+#define TAS2557_DSP_POWER_UP (0x1 << 7)
+
+/* B0P0R5 - TAS2557_POWER_CTRL2_REG */
+#define TAS2557_VSENSE_ENABLE (0x1 << 0)
+#define TAS2557_ISENSE_ENABLE (0x1 << 1)
+#define TAS2557_BOOST_ENABLE (0x1 << 5)
+#define TAS2557_CLASSD_ENABLE (0x1 << 7)
+
+/* B0P0R7 - TAS2557_MUTE_REG */
+#define TAS2557_CLASSD_MUTE (0x1 << 0)
+#define TAS2557_ISENSE_MUTE (0x1 << 1)
+
+/* B0P253R13 - TAS2557_TEST_MODE_REG */
+#define TAS2557_TEST_MODE_ENABLE (13)
+#define TAS2557_TEST_MODE_MASK (0xf << 0)
+
+/* B0P253R71 - TAS2557_CRYPTIC_REG */
+#define TAS2557_OSC_TRIM_CAP(x) ((x & 0x3f) << 0)
+#define TAS2557_DISABLE_ENCRYPTION (0x1 << 6)
+#define TAS2557_SL_COMP (0x1 << 7)
+
+/* B0P1R115/6 - TAS2557_MAIN/PLL_CLKIN_REG */
+#define TAS2557_XXX_CLKIN_GPIO1 (0)
+#define TAS2557_XXX_CLKIN_GPIO2 (1)
+#define TAS2557_XXX_CLKIN_GPIO3 (2)
+#define TAS2557_XXX_CLKIN_GPIO4 (3)
+#define TAS2557_XXX_CLKIN_GPIO5 (4)
+#define TAS2557_XXX_CLKIN_GPIO6 (5)
+#define TAS2557_XXX_CLKIN_GPIO7 (6)
+#define TAS2557_XXX_CLKIN_GPIO8 (7)
+#define TAS2557_XXX_CLKIN_GPIO9 (8)
+#define TAS2557_XXX_CLKIN_GPIO10 (9)
+#define TAS2557_XXX_CLKIN_GPI1 (12)
+#define TAS2557_XXX_CLKIN_GPI2 (13)
+#define TAS2557_XXX_CLKIN_GPI3 (14)
+#define TAS2557_NDIV_CLKIN_PLL (15)
+#define TAS2557_PLL_CLKIN_INT_OSC (15)
+
+#define TAS2557_MCLK_CLKIN_SRC_GPIO1 (0)
+#define TAS2557_MCLK_CLKIN_SRC_GPIO2 (1)
+#define TAS2557_MCLK_CLKIN_SRC_GPIO3 (2)
+#define TAS2557_MCLK_CLKIN_SRC_GPIO4 (3)
+#define TAS2557_MCLK_CLKIN_SRC_GPIO5 (4)
+#define TAS2557_MCLK_CLKIN_SRC_GPIO6 (5)
+#define TAS2557_MCLK_CLKIN_SRC_GPIO7 (6)
+#define TAS2557_MCLK_CLKIN_SRC_GPIO8 (7)
+#define TAS2557_MCLK_CLKIN_SRC_GPIO9 (8)
+#define TAS2557_MCLK_CLKIN_SRC_GPIO10 (9)
+#define TAS2557_MCLK_CLKIN_SRC_GPI1 (12)
+#define TAS2557_MCLK_CLKIN_SRC_GPI2 (13)
+#define TAS2557_MCLK_CLKIN_SRC_GPI3 (14)
+
+#define TAS2557_FORMAT_I2S (0x0 << 5)
+#define TAS2557_FORMAT_DSP (0x1 << 5)
+#define TAS2557_FORMAT_RIGHT_J (0x2 << 5)
+#define TAS2557_FORMAT_LEFT_J (0x3 << 5)
+#define TAS2557_FORMAT_MONO_PCM (0x4 << 5)
+#define TAS2557_FORMAT_MASK (0x7 << 5)
+
+#define TAS2557_WORDLENGTH_16BIT (0x0 << 3)
+#define TAS2557_WORDLENGTH_20BIT (0x1 << 3)
+#define TAS2557_WORDLENGTH_24BIT (0x2 << 3)
+#define TAS2557_WORDLENGTH_32BIT (0x3 << 3)
+#define TAS2557_WORDLENGTH_MASK TAS2557_WORDLENGTH_32BIT
+
+/* B100P0R7 - TAS2557_SOFT_MUTE_REG */
+#define TAS2557_PDM_SOFT_MUTE (0x1 << 0)
+#define TAS2557_VSENSE_SOFT_MUTE (0x1 << 1)
+#define TAS2557_ISENSE_SOFT_MUTE (0x1 << 2)
+#define TAS2557_CLASSD_SOFT_MUTE (0x1 << 3)
+
+/* B100P0R27 - TAS2557_PLL_P_VAL_REG */
+#define TAS2557_PLL_P_VAL_MASK (0x3f << 0)
+
+/* B100P0R28 - TAS2557_PLL_J_VAL_REG */
+#define TAS2557_PLL_J_VAL_MASK ((unsigned int) (0x7f << 0))
+#define TAS2557_PLL_J_VAL_MASKX 0x00
+
+/* B100P0R29-30 - TAS2557_PLL_D_VAL_MSB/LSB_REG */
+#define TAS2557_PLL_D_MSB_VAL(x) ((x >> 8) & 0x3f)
+#define TAS2557_PLL_D_LSB_VAL(x) (x & 0xff)
+
+/* B100P0R31 - TAS2557_CLK_MISC_REG */
+#define TAS2557_DSP_CLK_FROM_PLL (0x1 << 5)
+
+#define TAS2557_FW_NAME "tas2557_uCDSP.bin"
+#define TAS2557_PG1P0_FW_NAME "tas2557_pg1p0_uCDSP.bin"
+
+#define TAS2557_APP_ROM1MODE 0
+#define TAS2557_APP_ROM2MODE 1
+#define TAS2557_APP_TUNINGMODE 2
+#define TAS2557_APP_ROM1_96KHZ 3
+#define TAS2557_APP_ROM2_96KHZ 4
+#define TAS2557_APP_RAMMODE 5
+
+#define TAS2557_BOOST_OFF 0
+#define TAS2557_BOOST_DEVA 1
+#define TAS2557_BOOST_DEVB 2
+#define TAS2557_BOOST_BOTH 3
+
+#define ERROR_NONE 0x00000000
+#define ERROR_PLL_ABSENT 0x00000001
+#define ERROR_DEVA_I2C_COMM 0x00000002
+#define ERROR_PRAM_CRCCHK 0x00000008
+#define ERROR_YRAM_CRCCHK 0x00000010
+#define ERROR_CLK_DET2 0x00000020
+#define ERROR_CLK_DET1 0x00000040
+#define ERROR_CLK_LOST 0x00000080
+#define ERROR_BROWNOUT 0x00000100
+#define ERROR_DIE_OVERTEMP 0x00000200
+#define ERROR_CLK_HALT 0x00000400
+#define ERROR_UNDER_VOLTAGE 0x00000800
+#define ERROR_OVER_CURRENT 0x00001000
+#define ERROR_CLASSD_PWR 0x00002000
+#define ERROR_SAFE_GUARD 0x00004000
+#define ERROR_FAILSAFE 0x40000000
+
+struct TBlock {
+ unsigned int mnType;
+ unsigned char mbPChkSumPresent;
+ unsigned char mnPChkSum;
+ unsigned char mbYChkSumPresent;
+ unsigned char mnYChkSum;
+ unsigned int mnCommands;
+ unsigned char *mpData;
+};
+
+struct TData {
+ char mpName[64];
+ char *mpDescription;
+ unsigned int mnBlocks;
+ struct TBlock *mpBlocks;
+};
+
+struct TProgram {
+ char mpName[64];
+ char *mpDescription;
+ unsigned char mnAppMode;
+ unsigned short mnBoost;
+ struct TData mData;
+};
+
+struct TPLL {
+ char mpName[64];
+ char *mpDescription;
+ struct TBlock mBlock;
+};
+
+struct TConfiguration {
+ char mpName[64];
+ char *mpDescription;
+ unsigned int mnDevices;
+ unsigned int mnProgram;
+ unsigned int mnPLL;
+ unsigned int mnSamplingRate;
+ unsigned char mnPLLSrc;
+ unsigned int mnPLLSrcRate;
+ struct TData mData;
+};
+
+struct TCalibration {
+ char mpName[64];
+ char *mpDescription;
+ unsigned int mnProgram;
+ unsigned int mnConfiguration;
+ struct TData mData;
+};
+
+struct TFirmware {
+ unsigned int mnFWSize;
+ unsigned int mnChecksum;
+ unsigned int mnPPCVersion;
+ unsigned int mnFWVersion;
+ unsigned int mnDriverVersion;
+ unsigned int mnTimeStamp;
+ char mpDDCName[64];
+ char *mpDescription;
+ unsigned int mnDeviceFamily;
+ unsigned int mnDevice;
+ unsigned int mnPLLs;
+ struct TPLL *mpPLLs;
+ unsigned int mnPrograms;
+ struct TProgram *mpPrograms;
+ unsigned int mnConfigurations;
+ struct TConfiguration *mpConfigurations;
+ unsigned int mnCalibrations;
+ struct TCalibration *mpCalibrations;
+};
+
+struct tas2557_register {
+ int book;
+ int page;
+ int reg;
+};
+
+struct tas2557_priv {
+ struct device *dev;
+ struct regmap *mpRegmap;
+ int mnPGID;
+ int mnResetGPIO;
+ struct mutex dev_lock;
+ struct TFirmware *mpFirmware;
+ struct TFirmware *mpCalFirmware;
+ unsigned int mnCurrentProgram;
+ unsigned int mnCurrentSampleRate;
+ unsigned int mnNewConfiguration;
+ unsigned int mnCurrentConfiguration;
+ unsigned int mnCurrentCalibration;
+ unsigned char mnCurrentBook;
+ unsigned char mnCurrentPage;
+ bool mbTILoadActive;
+ bool mbPowerUp;
+ bool mbLoadConfigurationPrePowerUp;
+ bool mbLoadCalibrationPostPowerUp;
+ bool mbCalibrationLoaded;
+ int (*read)(struct tas2557_priv *pTAS2557,
+ unsigned int reg,
+ unsigned int *pValue);
+ int (*write)(struct tas2557_priv *pTAS2557,
+ unsigned int reg,
+ unsigned int Value);
+ int (*bulk_read)(struct tas2557_priv *pTAS2557,
+ unsigned int reg,
+ unsigned char *pData,
+ unsigned int len);
+ int (*bulk_write)(struct tas2557_priv *pTAS2557,
+ unsigned int reg,
+ unsigned char *pData,
+ unsigned int len);
+ int (*update_bits)(struct tas2557_priv *pTAS2557,
+ unsigned int reg,
+ unsigned int mask,
+ unsigned int value);
+ int (*set_config)(struct tas2557_priv *pTAS2557,
+ int config);
+ int (*set_calibration)(struct tas2557_priv *pTAS2557,
+ int calibration);
+ void (*clearIRQ)(struct tas2557_priv *pTAS2557);
+ void (*enableIRQ)(struct tas2557_priv *pTAS2557, bool enable, bool startup_chk);
+ void (*hw_reset)(struct tas2557_priv *pTAS2557);
+ /* device is working, but system is suspended */
+ int (*runtime_suspend)(struct tas2557_priv *pTAS2557);
+ int (*runtime_resume)(struct tas2557_priv *pTAS2557);
+
+ int mnGpioINT;
+ struct delayed_work irq_work;
+ unsigned int mnIRQ;
+ bool mbIRQEnable;
+ unsigned char mnI2SBits;
+
+
+ /* for low temperature check */
+ unsigned int mnDevGain;
+ unsigned int mnDevCurrentGain;
+ unsigned int mnDieTvReadCounter;
+ struct hrtimer mtimer;
+ struct work_struct mtimerwork;
+
+ /* device is working, but system is suspended */
+ bool mbRuntimeSuspend;
+
+ unsigned int mnErrCode;
+ unsigned int mnRestart;
+
+ /* for configurations with maximum TLimit 0x7fffffff,
+ * bypass calibration update, usually used in factory test
+ */
+ bool mbBypassTMax;
+
+ unsigned int mnEdge;
+
+#ifdef CONFIG_TAS2557_CODEC
+ struct mutex codec_lock;
+#endif
+
+#ifdef CONFIG_TAS2557_MISC
+ int mnDBGCmd;
+ int mnCurrentReg;
+ struct mutex file_lock;
+#endif
+
+};
+
+#endif /* _TAS2557_H */
diff --git a/sound/soc/codecs/tas2557/tiload.c b/sound/soc/codecs/tas2557/tiload.c
new file mode 100755
index 0000000..1719bc4
--- /dev/null
+++ b/sound/soc/codecs/tas2557/tiload.c
@@ -0,0 +1,409 @@
+/*
+** =============================================================================
+** Copyright (c) 2016 Texas Instruments Inc.
+**
+** This program is free software; you can redistribute it and/or modify it under
+** the terms of the GNU General Public License as published by the Free Software
+** Foundation; version 2.
+**
+** This program is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+**
+** File:
+** tiload.c
+**
+** Description:
+** utility for TAS2557 Android in-system tuning
+**
+** =============================================================================
+*/
+
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/kdev_t.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/uaccess.h>
+
+#include "tiload.h"
+
+/* enable debug prints in the driver */
+#define DEBUG
+
+static struct cdev *tiload_cdev;
+static int tiload_major; /* Dynamic allocation of Mjr No. */
+static int tiload_opened; /* Dynamic allocation of Mjr No. */
+static struct tas2557_priv *g_TAS2557;
+struct class *tiload_class;
+static unsigned int magic_num;
+
+static char gPage;
+static char gBook;
+/******************************** Debug section *****************************/
+
+
+/*----------------------------------------------------------------------------
+ * Function : tiload_open
+ *
+ * Purpose : open method for tiload programming interface
+ *----------------------------------------------------------------------------
+ */
+static int tiload_open(struct inode *in, struct file *filp)
+{
+ struct tas2557_priv *pTAS2557 = g_TAS2557;
+
+ dev_info(pTAS2557->dev, "%s\n", __func__);
+
+ if (tiload_opened) {
+ dev_info(pTAS2557->dev, "%s device is already opened\n", "tiload");
+ return -EINVAL;
+ }
+ filp->private_data = (void *)pTAS2557;
+ tiload_opened++;
+ return 0;
+}
+
+/*----------------------------------------------------------------------------
+ * Function : tiload_release
+ *
+ * Purpose : close method for tiload programming interface
+ *----------------------------------------------------------------------------
+ */
+static int tiload_release(struct inode *in, struct file *filp)
+{
+ struct tas2557_priv *pTAS2557 = (struct tas2557_priv *)filp->private_data;
+
+ dev_info(pTAS2557->dev, "%s\n", __func__);
+ filp->private_data = NULL;
+ tiload_opened--;
+ return 0;
+}
+
+#define MAX_LENGTH 128
+/*----------------------------------------------------------------------------
+ * Function : tiload_read
+ *
+ * Purpose : read from codec
+ *----------------------------------------------------------------------------
+ */
+static ssize_t tiload_read(struct file *filp, char __user *buf,
+ size_t count, loff_t *offset)
+{
+ struct tas2557_priv *pTAS2557 = (struct tas2557_priv *)filp->private_data;
+ static char rd_data[MAX_LENGTH + 1];
+ unsigned int nCompositeRegister = 0, Value = 0;
+ char reg_addr;
+ size_t size;
+ int ret = 0;
+#ifdef DEBUG
+ /* int i; */
+#endif
+
+ dev_info(pTAS2557->dev, "%s\n", __func__);
+ if (count > MAX_LENGTH) {
+ dev_err(pTAS2557->dev, "Max %d bytes can be read\n", MAX_LENGTH);
+ return -EINVAL;
+ }
+
+ /* copy register address from user space */
+ size = copy_from_user(®_addr, buf, 1);
+ if (size != 0) {
+ dev_err(pTAS2557->dev, "read: copy_from_user failure\n");
+ return -EINVAL;
+ }
+
+ size = count;
+
+ nCompositeRegister = BPR_REG(gBook, gPage, reg_addr);
+ if (count == 1) {
+ ret =
+ pTAS2557->read(pTAS2557, 0x80000000 | nCompositeRegister, &Value);
+ if (ret >= 0)
+ rd_data[0] = (char) Value;
+ } else if (count > 1) {
+ ret =
+ pTAS2557->bulk_read(pTAS2557, 0x80000000 | nCompositeRegister,
+ rd_data, size);
+ }
+ if (ret < 0)
+ dev_err(pTAS2557->dev, "%s, %d, ret=%d, count=%zu error happen!\n",
+ __func__, __LINE__, ret, count);
+
+#ifdef DEBUG
+ dev_info(pTAS2557->dev, "read size = %d, reg_addr= %x , count = %d\n",
+ (int) size, reg_addr, (int) count);
+/* for (i = 0; i < (int) size; i++) {
+* dev_dbg(pTAS2557->dev, "rd_data[%d]=%x\n", i, rd_data[i]);
+* }
+*/
+#endif
+ if (size != count)
+ dev_err(pTAS2557->dev, "read %d registers from the codec\n", (int) size);
+
+ if (copy_to_user(buf, rd_data, size) != 0) {
+ dev_err(pTAS2557->dev, "copy_to_user failed\n");
+ return -EINVAL;
+ }
+
+ return size;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * Function : tiload_write
+ *
+ * Purpose : write to codec
+ *----------------------------------------------------------------------------
+ */
+static ssize_t tiload_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *offset)
+{
+ struct tas2557_priv *pTAS2557 = (struct tas2557_priv *)filp->private_data;
+ static char wr_data[MAX_LENGTH + 1];
+ char *pData = wr_data;
+ size_t size;
+ unsigned int nCompositeRegister = 0;
+ unsigned int nRegister;
+ int ret = 0;
+#ifdef DEBUG
+ /* int i; */
+#endif
+ dev_info(pTAS2557->dev, "%s\n", __func__);
+
+ if (count > MAX_LENGTH) {
+ dev_err(pTAS2557->dev, "Max %d bytes can be read\n", MAX_LENGTH);
+ return -EINVAL;
+ }
+
+ /* copy buffer from user space */
+ size = copy_from_user(wr_data, buf, count);
+ if (size != 0) {
+ dev_err(pTAS2557->dev, "copy_from_user failure %d\n", (int) size);
+ return -EINVAL;
+ }
+#ifdef DEBUG
+ dev_info(pTAS2557->dev, "write size = %zu\n", count);
+/* for (i = 0; i < (int) count; i++) {
+* dev_info(pTAS2557->dev, "wr_data[%d]=%x\n", i, wr_data[i]);
+* }
+*/
+#endif
+ nRegister = wr_data[0];
+ size = count;
+ if ((nRegister == 127) && (gPage == 0)) {
+ gBook = wr_data[1];
+ return size;
+ }
+
+ if (nRegister == 0) {
+ gPage = wr_data[1];
+ pData++;
+ count--;
+ }
+
+ nCompositeRegister = BPR_REG(gBook, gPage, nRegister);
+ if (count == 2) {
+ ret =
+ pTAS2557->write(pTAS2557, 0x80000000 | nCompositeRegister,
+ pData[1]);
+ } else if (count > 2) {
+ ret =
+ pTAS2557->bulk_write(pTAS2557, 0x80000000 | nCompositeRegister,
+ &pData[1], count - 1);
+ }
+
+ if (ret < 0)
+ dev_err(pTAS2557->dev, "%s, %d, ret=%d, count=%zu, ERROR Happen\n", __func__,
+ __LINE__, ret, count);
+
+ return size;
+}
+
+static void tiload_route_IO(struct tas2557_priv *pTAS2557, unsigned int bLock)
+{
+ if (bLock)
+ pTAS2557->write(pTAS2557, 0xAFFEAFFE, 0xBABEBABE);
+ else
+ pTAS2557->write(pTAS2557, 0xBABEBABE, 0xAFFEAFFE);
+}
+
+static long tiload_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ struct tas2557_priv *pTAS2557 = (struct tas2557_priv *)filp->private_data;
+ long num = 0;
+ void __user *argp = (void __user *) arg;
+ int val;
+ struct BPR bpr;
+
+ dev_info(pTAS2557->dev, "%s, cmd=0x%x\n", __func__, cmd);
+/* if (_IOC_TYPE(cmd) != TILOAD_IOC_MAGIC)
+ * return -ENOTTY;
+ */
+
+ switch (cmd) {
+ case TILOAD_IOMAGICNUM_GET:
+ num = copy_to_user(argp, &magic_num, sizeof(int));
+ break;
+ case TILOAD_IOMAGICNUM_SET:
+ num = copy_from_user(&magic_num, argp, sizeof(int));
+ dev_info(pTAS2557->dev, "TILOAD_IOMAGICNUM_SET\n");
+ tiload_route_IO(pTAS2557, magic_num);
+ break;
+ case TILOAD_BPR_READ:
+ break;
+ case TILOAD_BPR_WRITE:
+ num = copy_from_user(&bpr, argp, sizeof(struct BPR));
+ dev_info(pTAS2557->dev, "TILOAD_BPR_WRITE: 0x%02X, 0x%02X, 0x%02X\n\r", bpr.nBook,
+ bpr.nPage, bpr.nRegister);
+ break;
+ case TILOAD_IOCTL_SET_CHL:
+ break;
+ case TILOAD_IOCTL_SET_CONFIG:
+ num = copy_from_user(&val, argp, sizeof(val));
+ pTAS2557->set_config(pTAS2557, val);
+ break;
+ case TILOAD_IOCTL_SET_CALIBRATION:
+ num = copy_from_user(&val, argp, sizeof(val));
+ pTAS2557->set_calibration(pTAS2557, val);
+ break;
+ default:
+ break;
+ }
+ return num;
+}
+
+#ifdef CONFIG_COMPAT
+static long tiload_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ struct tas2557_priv *pTAS2557 = (struct tas2557_priv *)filp->private_data;
+ long nResult = 0;
+
+ switch (cmd) {
+ case TILOAD_COMPAT_IOMAGICNUM_GET:
+ dev_info(pTAS2557->dev, "%s, TILOAD_COMPAT_IOMAGICNUM_GET=0x%x\n",
+ __func__, cmd);
+ nResult = tiload_ioctl(filp, TILOAD_IOMAGICNUM_GET,
+ (unsigned long) compat_ptr(arg));
+ break;
+
+ case TILOAD_COMPAT_IOMAGICNUM_SET:
+ dev_info(pTAS2557->dev, "%s, TILOAD_COMPAT_IOMAGICNUM_SET=0x%x\n",
+ __func__, cmd);
+ nResult = tiload_ioctl(filp, TILOAD_IOMAGICNUM_SET,
+ (unsigned long) compat_ptr(arg));
+ break;
+
+ case TILOAD_COMPAT_BPR_READ:
+ dev_info(pTAS2557->dev, "%s, TILOAD_COMPAT_BPR_READ=0x%x\n",
+ __func__, cmd);
+ nResult = tiload_ioctl(filp, TILOAD_BPR_READ,
+ (unsigned long) compat_ptr(arg));
+ break;
+
+ case TILOAD_COMPAT_BPR_WRITE:
+ dev_info(pTAS2557->dev, "%s, TILOAD_COMPAT_BPR_WRITE=0x%x\n",
+ __func__, cmd);
+ nResult = tiload_ioctl(filp, TILOAD_BPR_WRITE,
+ (unsigned long) compat_ptr(arg));
+ break;
+
+ case TILOAD_COMPAT_IOCTL_SET_CHL:
+ dev_info(pTAS2557->dev, "%s, TILOAD_COMPAT_IOCTL_SET_CHL=0x%x\n",
+ __func__, cmd);
+ nResult = tiload_ioctl(filp, TILOAD_IOCTL_SET_CHL,
+ (unsigned long) compat_ptr(arg));
+ break;
+
+ case TILOAD_COMPAT_IOCTL_SET_CONFIG:
+ dev_info(pTAS2557->dev, "%s, TILOAD_COMPAT_IOCTL_SET_CONFIG=0x%x\n",
+ __func__, cmd);
+ nResult = tiload_ioctl(filp, TILOAD_IOCTL_SET_CONFIG,
+ (unsigned long) compat_ptr(arg));
+ break;
+
+ case TILOAD_COMPAT_IOCTL_SET_CALIBRATION:
+ dev_info(pTAS2557->dev, "%s, TILOAD_COMPAT_IOCTL_SET_CALIBRATION=0x%x\n",
+ __func__, cmd);
+ nResult = tiload_ioctl(filp, TILOAD_IOCTL_SET_CALIBRATION,
+ (unsigned long) compat_ptr(arg));
+ break;
+
+ default:
+ dev_err(pTAS2557->dev, "%s, unsupport compat ioctl=0x%x\n",
+ __func__, cmd);
+ break;
+ }
+
+ return nResult;
+}
+#endif
+
+/*********** File operations structure for tiload *************/
+static const struct file_operations tiload_fops = {
+ .owner = THIS_MODULE,
+ .open = tiload_open,
+ .release = tiload_release,
+ .read = tiload_read,
+ .write = tiload_write,
+ .unlocked_ioctl = tiload_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = tiload_compat_ioctl,
+#endif
+};
+
+/*----------------------------------------------------------------------------
+ * Function : tiload_driver_init
+ *
+ * Purpose : Register a char driver for dynamic tiload programming
+ *----------------------------------------------------------------------------
+ */
+int tiload_driver_init(struct tas2557_priv *pTAS2557)
+{
+ int result;
+ dev_t dev = MKDEV(tiload_major, 0);
+
+ g_TAS2557 = pTAS2557;
+
+ dev_info(pTAS2557->dev, "%s\n", __func__);
+
+ result = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME);
+ if (result < 0) {
+ dev_err(pTAS2557->dev, "cannot allocate major number %d\n", tiload_major);
+ return result;
+ }
+ tiload_class = class_create(THIS_MODULE, DEVICE_NAME);
+ tiload_major = MAJOR(dev);
+ dev_info(pTAS2557->dev, "allocated Major Number: %d\n", tiload_major);
+
+ tiload_cdev = cdev_alloc();
+ cdev_init(tiload_cdev, &tiload_fops);
+ tiload_cdev->owner = THIS_MODULE;
+ tiload_cdev->ops = &tiload_fops;
+
+ if (device_create(tiload_class, NULL, dev, NULL, "tiload_node") == NULL)
+ dev_err(pTAS2557->dev, "Device creation failed\n");
+
+ if (cdev_add(tiload_cdev, dev, 1) < 0) {
+ dev_err(pTAS2557->dev, "tiload_driver: cdev_add failed\n");
+ unregister_chrdev_region(dev, 1);
+ tiload_cdev = NULL;
+ return 1;
+ }
+ dev_info(pTAS2557->dev, "Registered TiLoad driver, Major number: %d\n", tiload_major);
+ /* class_device_create(tiload_class, NULL, dev, NULL, DEVICE_NAME, 0); */
+ return 0;
+}
+
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_DESCRIPTION("Utility for TAS2557 Android in-system tuning");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/tas2557/tiload.h b/sound/soc/codecs/tas2557/tiload.h
new file mode 100755
index 0000000..7468acf
--- /dev/null
+++ b/sound/soc/codecs/tas2557/tiload.h
@@ -0,0 +1,65 @@
+/*
+** =============================================================================
+** Copyright (c) 2016 Texas Instruments Inc.
+**
+** This program is free software; you can redistribute it and/or modify it under
+** the terms of the GNU General Public License as published by the Free Software
+** Foundation; version 2.
+**
+** This program is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+**
+** File:
+** tiload.h
+**
+** Description:
+** header file for tiload.c
+**
+** =============================================================================
+*/
+
+#ifndef _TILOAD_H
+#define _TILOAD_H
+
+#ifdef CONFIG_COMPAT
+#include <linux/compat.h>
+#endif
+
+#include "tas2557.h"
+
+#define BPR_REG(book, page, reg) (((book * 256 * 128) + \
+ (page * 128)) + reg)
+
+/* typedefs required for the included header files */
+struct BPR {
+ unsigned char nBook;
+ unsigned char nPage;
+ unsigned char nRegister;
+};
+
+/* defines */
+#define DEVICE_NAME "tiload_node"
+
+#define TILOAD_IOC_MAGIC 0xE0
+#define TILOAD_IOMAGICNUM_GET _IOR(TILOAD_IOC_MAGIC, 1, int)
+#define TILOAD_IOMAGICNUM_SET _IOW(TILOAD_IOC_MAGIC, 2, int)
+#define TILOAD_BPR_READ _IOR(TILOAD_IOC_MAGIC, 3, struct BPR)
+#define TILOAD_BPR_WRITE _IOW(TILOAD_IOC_MAGIC, 4, struct BPR)
+#define TILOAD_IOCTL_SET_CHL _IOW(TILOAD_IOC_MAGIC, 5, int)
+#define TILOAD_IOCTL_SET_CONFIG _IOW(TILOAD_IOC_MAGIC, 6, int)
+#define TILOAD_IOCTL_SET_CALIBRATION _IOW(TILOAD_IOC_MAGIC, 7, int)
+
+#ifdef CONFIG_COMPAT
+#define TILOAD_COMPAT_IOMAGICNUM_GET _IOR(TILOAD_IOC_MAGIC, 1, compat_int_t)
+#define TILOAD_COMPAT_IOMAGICNUM_SET _IOW(TILOAD_IOC_MAGIC, 2, compat_int_t)
+#define TILOAD_COMPAT_BPR_READ _IOR(TILOAD_IOC_MAGIC, 3, struct BPR)
+#define TILOAD_COMPAT_BPR_WRITE _IOW(TILOAD_IOC_MAGIC, 4, struct BPR)
+#define TILOAD_COMPAT_IOCTL_SET_CHL _IOW(TILOAD_IOC_MAGIC, 5, compat_int_t)
+#define TILOAD_COMPAT_IOCTL_SET_CONFIG _IOW(TILOAD_IOC_MAGIC, 6, compat_int_t)
+#define TILOAD_COMPAT_IOCTL_SET_CALIBRATION _IOW(TILOAD_IOC_MAGIC, 7, compat_int_t)
+#endif
+
+int tiload_driver_init(struct tas2557_priv *pTAS2557);
+
+#endif